在栈上为execve创建一个arg数组

nem*_*666 2 assembly x86-64 shellcode

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

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

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

我不太明白如何建立三个论点。据我所知,第一个参数进入RDI,第二个进入RSI,第三个进入RDX。我相信设置第一个就足够了

    push 0x736c2f2f         ;sl//
    push 0x6e69622f         ;nib/
    mov rdi, rsp
Run Code Online (Sandbox Code Playgroud)

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

    xor r11, r11
    mov rdx, r11
Run Code Online (Sandbox Code Playgroud)

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

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

prl*_*prl 5

您可以将argv数组放入堆栈并将其地址加载到rsi. 的第一个成员argv是指向程序名称的指针,因此我们可以使用加载到 中的相同地址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.
Run Code Online (Sandbox Code Playgroud)

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

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

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

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.
Run Code Online (Sandbox Code Playgroud)

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

  • 请为此代码提供一些上下文或注释,以使其更有用。 (3认同)