我是调试新手。我看过这段代码,指出该代码在执行时会产生一个shell提示。

0:  31 c0                   xor    eax,eax
2:  50                      push   eax
3:  68 2f 2f 73 68          push   0x68732f2f
8:  68 2f 62 69 6e          push   0x6e69622f
d:  89 e3                   mov    ebx,esp
f:  50                      push   eax
10: 53                      push   ebx
11: 89 e1                   mov    ecx,esp
13: b0 0b                   mov    al,0xb
15: cd 80                   int    0x80


请在这里清楚说明寄存器和存储器中实际发生的情况。

最佳答案

; Push 0 onto the stack
xor    eax,eax      ; a classic x86 optimization trick to clear/zero a register
push   eax          ; push that zeroed register onto the stack

; Push two constant values onto the stack
push   0x68732f2f   ; 0x68732f2f == 1,752,379,183
push   0x6e69622f   ; 0x6e69622f == 1,852,400,175

; Save the current value of the stack pointer (ESP) in the EBX register.
mov    ebx,esp

; Push another 0 onto the stack (remember, EAX still contains 0).
push   eax

; Push the value of the previous stack pointer onto the stack.
; (This is the same as pushing ESP+4, since the previous PUSH instruction
;  implicitly decremented the stack pointer by 32 bits.)
push   ebx

; Save the current value of the stack pointer (ESP) in the ECX register.
; (Presumably, it is either used again later in the function, or the interrupt
;  that we're about to call requires some input value to be passed in ECX.)
mov    ecx,esp




现在,堆栈如下所示(在x86上,堆栈向下增长,因此最旧的值在顶部):

╔═════════════════╗           direction of growth
║        0        ║                   |
╠═════════════════╣                   |
║    0x68732F2F   ║                   V
╠═════════════════╣
║    0x6E69622F   ║ <----
╠═════════════════╣     |
║        0        ║     |
╠═════════════════╣     |
║ pointer to ...  ║  ----
╚═════════════════╝            (lowest address)




; Place the value 0xB (11) in the AL register, which is the bottom 8 bits of EAX.
; The value in EAX specifies the sub-function to be executed when the interrupt is raised.
; (Note that setting only the bottom 8 bits is safe because we already zeroed EAX.)
mov    al,0xb

; Raise an interrupt, passing control to interrupt vector 0x80.
; On Unix systems, this is how you make a system call.
; This is why we went through all the trouble of pushing those values onto
; the stack: this is how parameters are passed through to the system call.
int    0x80


不是Unix专家,我必须查找系统调用号(在本例中为0xB)以查看其作用。原来,0xB映射到sys_execve,它执行指定的二进制文件。它希望在EBX中执行指向文件的指针,在ECX中执行指向命令行参数的指针,并在EDX中执行指向环境块的指针。回想一下,在前面的代码中,这些寄存器都被初始化为包含指向堆栈中各个位置的指针。

10-04 14:36