在栈上为execve创建一个arg数组 [英] Create an arg array for execve on the stack

查看:31
本文介绍了在栈上为execve创建一个arg数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个汇编程序,通过 EXECVE(系统调用 #0x3C)程序/bin/ls 和 -al 开关执行.

I want to write an assembly program that executes via EXECVE (syscall #0x3C) the program /bin/ls with the switches -al.

手册页 (man 2 execve) 指出调用需要三个值:

The man page (man 2 execve) states that the call requires three values:

int execve(const char *filename, char *const argv[], char *const envp[]);

我不太明白如何构建这三个参数.据我所知,第一个参数进入RDI,第二个进入RSI,第三个进入RDX.我相信设置第一个就够了

I don't quite understand how to build the three arguments. As far as I know, the first argument goes into RDI, the second into RSI, and the third into RDX. I believe that to set up the first one, it suffices doing

    push 0x736c2f2f         ;sl//
    push 0x6e69622f         ;nib/
    mov rdi, rsp

对于第三个,事情很简单:

For the third one, the thing is quite easy:

    xor r11, r11
    mov rdx, r11

我的问题是我不知道如何构建第二个参数,它应该是一个包含 ['/bin//ls', '-aal']

My problem is that I don't know how to build the second argument, which should be an array containing ['/bin//ls', '-aal']

我需要为 x86-64 编写它,所以请不要 int 0x80 建议.

I need to write it for x86-64, so please no int 0x80 suggestions.

推荐答案

您可以将 argv 数组放入堆栈并将其地址加载到 rsi 中.argv 的第一个成员是指向程序名称的指针,因此我们可以使用加载到 rdi 中的相同地址.

You can put the argv array onto the stack and load the address of it into rsi. The first member of argv is a pointer to the program name, so we can use the same address that we load into rdi.

xor edx, edx        ; Load NULL to be used both as the third
                    ; parameter to execve as well as
                    ; to push 0 onto the stack later.
push "-aal"         ; Put second argument string onto the stack.
mov rax, rsp        ; Load the address of the second argument.
mov rcx, "/bin//ls" ; Load the file name string
push rdx            ; and place a null character
push rcx            ; and the string onto the stack.
mov rdi, rsp        ; Load the address of "/bin//ls". This is
                    ; used as both the first member of argv
                    ; and as the first parameter to execve.

; Now create argv.
push rdx            ; argv must be terminated by a NULL pointer.
push rax            ; Second arg is a pointer to "-aal".
push rdi            ; First arg is a pointer to "/bin//ls"
mov rsi, rsp        ; Load the address of argv into the second
                    ; parameter to execve.

这也纠正了问题中代码的其他几个问题.它对文件名使用 8 字节推送,因为 x86-64 不支持 4 字节推送,并且它确保文件名具有空终止符.

This also corrects a couple of other problems with the code in the question. It uses an 8-byte push for the file name, since x86-64 doesn't support 4-byte push, and it makes sure that the file name has a null terminator.

此代码确实使用 64 位推送和 4 字节立即数推送-aal",因为字符串适合 4 个字节.这也使它在代码中不需要空字节的情况下以空值终止.

This code does use a 64-bit push with a 4-byte immediate to push "-aal" since the string fits in 4 bytes. This also makes it null terminated without needing a null byte in the code.

我在问题中使用了双字符的字符串以避免代码中出现空字节,但我的偏好是这样的:

I used strings with doubled characters as they are in the question to avoid null bytes in the code, but my preference would be this:

mov ecx, "X-al"     ; Load second argument string,
shr ecx, 8          ; shift out the dummy character,
push rcx            ; and write the string to the stack.
mov rax, rsp        ; Load the address of the second argument.
mov rcx, "X/bin/ls" ; Load file name string,
shr rcx, 8          ; shift out the dummy character,
push rcx            ; and write the string onto the stack.

请注意,文件名字符串通过移位获得了一个空终止符,避免了额外的推送.此模式适用于无法使用双字符的字符串,也适用于较短的字符串.

Note that the file name string gets a null terminator via the shift, avoiding the extra push. This pattern works with strings where a doubled character wouldn't work, and it can be used with shorter strings, too.

这篇关于在栈上为execve创建一个arg数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆