通过寄存器将参数传递给 execve(2)

Passing arguments to execve(2) via registers

我写了一个简短的程序来执行 bash 使用 execve(2)

my_prog.c

int main(){
    execve(Argument_1,Argument_2,NULL);
}

这里是execve(2)的反汇编[为简单起见忽略主程序集]

(gdb) disassemble execve
Dump of assembler code for function execve:
   0xf7ea77e0 <+0>:     push   ebx
   0xf7ea77e1 <+1>:     mov    edx,DWORD PTR [esp+0x10]
   0xf7ea77e5 <+5>:     mov    ecx,DWORD PTR [esp+0xc]
   0xf7ea77e9 <+9>:     mov    ebx,DWORD PTR [esp+0x8]
   0xf7ea77ed <+13>:    mov    eax,0xb
   0xf7ea77f2 <+18>:    call   DWORD PTR gs:0x10
   0xf7ea77f9 <+25>:    pop    ebx
   0xf7ea77fa <+26>:    cmp    eax,0xfffff001
   0xf7ea77ff <+31>:    jae    0xf7e0f730
   0xf7ea7805 <+37>:    ret

我在以下寄存器中找到了 execv(2) 的参数

eax --> index of execve(2) in syscall table
ebx --> Argument_2
ecx --> Argument_3

和Argument_1在栈顶

(gdb) x/xw $esp
0xffffce00:     0x080484ea
(gdb) x/s 0x080484ea
0x80484ea:      "/bin/bash"  <--- Argument_1

edx 包含 0x080484ab

(gdb) x/xw 0x080484ab
0x80484ab <__libc_csu_init+75>: 0x8301c783
(gdb) x/xw 0x8301c783
0x8301c783:     Cannot access memory at address 0x8301c783

我在 linux-intel(x86) 系统上,所以我假设 execve(2) 的所有参数都应该通过寄存器传递,但我 找不到 Argument_1 在任何寄存器 中,尽管它存在于堆栈中。

I'm stopped at the first instruction of execve module.

execve 不是 "module",它是一个 libc 函数,它将参数加载到寄存器中,然后执行实际的系统调用。

i couldn't found Argument_1 in any register

如果您在地址 0xf7ea77f2 处停止指令,您

但是您在进入 C 函数时就停止了 execve,所以参数是 C 函数期望的地方。在 i*86 上,参数在堆栈上传递,因此您可以在其中找到它们:x/3wx $esp 是您想要的(在程序的那个点)。