ECX堆栈寄存器在汇编代码转储中的作用

ECX堆栈寄存器在汇编代码转储中的作用,c,assembly,x86,memory-alignment,stack-pointer,C,Assembly,X86,Memory Alignment,Stack Pointer,GCC版本:6.5.0 操作系统:Ubuntu 16.04 GDB版本:7.11.1 我参考的教程显示了以下汇编代码: Dump of assembler code for function main: 0x0804840b <+0>: lea 0x4(%esp),%ecx 0x0804840f <+4>: and $0xfffffff0,%esp 0x08048412 <+7>: pushl -0x4(

GCC版本:6.5.0
操作系统:Ubuntu 16.04
GDB版本:7.11.1

我参考的教程显示了以下汇编代码:

Dump of assembler code for function main:
   0x0804840b <+0>:     lea    0x4(%esp),%ecx
   0x0804840f <+4>:     and    $0xfffffff0,%esp
   0x08048412 <+7>:     pushl  -0x4(%ecx)
   0x08048415 <+10>:    push   %ebp
   0x08048416 <+11>:    mov    %esp,%ebp
   0x08048418 <+13>:    push   %ecx
   0x08048419 <+14>:    sub    $0x204,%esp
   0x0804841f <+20>:    mov    %ecx,%eax
   0x08048421 <+22>:    mov    0x4(%eax),%eax
   0x08048424 <+25>:    add    $0x4,%eax
   0x08048427 <+28>:    mov    (%eax),%eax
   0x08048429 <+30>:    sub    $0x8,%esp
   0x0804842c <+33>:    push   %eax
   0x0804842d <+34>:    lea    -0x1fc(%ebp),%eax
   0x08048433 <+40>:    push   %eax
   0x08048434 <+41>:    call   0x80482e0 <strcpy@plt>
   0x08048439 <+46>:    add    $0x10,%esp
   0x0804843c <+49>:    mov    $0x0,%eax
   0x08048441 <+54>:    mov    -0x4(%ebp),%ecx
   0x08048444 <+57>:    leave  
   0x08048445 <+58>:    lea    -0x4(%ecx),%esp
   0x08048448 <+61>:    ret
End of assembler dump.
主函数的汇编程序代码转储: 0x080483fb:推送%ebp 0x080483fc:mov%esp,%ebp 0x080483fe:子$0x1f4,%esp 0x08048404:mov 0xc(%ebp),%eax 0x08048407:添加$0x4,%eax 0x0804840a:mov(%eax),%eax 0x0804840c:推送%eax 0x0804840d:lea-0x1f4(%ebp),%eax 0x08048413:推送%eax 0x08048414:调用0x80482d0 0x08048419:添加$0x8,%esp 0x0804841c:mov$0x0,%eax 0x08048421:离开 0x08048422:ret 汇编程序转储结束。 我有以下问题:
如何获得教程中提到的完全相同的汇编代码转储?
输出中的差异似乎是由于
ecx
寄存器造成的。该寄存器的作用是什么?为什么它不是教程汇编代码的一部分?
在main函数中,我构造了大小为
500
的缓冲区数组,它是十六进制的
1f4
,这就是为什么本教程的汇编代码是从esp寄存器中减去
1f4
,而我的汇编代码是从十进制的
204
中减去
516
。我无法理解这一点


编辑:如注释中所述,如果我将
-mprefered stack boundary=2
添加到编译器标志中,则得到与教程相同的汇编代码。为什么?

是否
-mprefered stack boundary=2
使其更像本教程?如果是这样,这似乎与SysV i386 ABI从4字节更改为16字节堆栈对齐要求有关?他们说他们使用了什么编译器开关?如果你不知道,那么这将是无休止的修补,就像试图得到一个蛋糕配方,以精确匹配其他人的蛋糕到最细微的细节。@RaymondChen他已经设法通过添加
-mprefered stack boundary=2
获得了精确匹配。问题是为什么他需要使用这个标志,而教程没有。我猜你正在使用,他们确实说他们是用
gcc-fno stack protector-z execstack-mprefered stack boundary=2-g-o vuln vuln.c
编译的。你可能忽略了那一段。他们没有说明他们使用的是什么版本的gcc,但鉴于这篇文章是在2016年12月撰写的,他们不太可能使用2018年10月发布的6.5.0。(如果他们这样做了,那么他们应该利用时间机器做更重要的事情。)
Dump of assembler code for function main:
   0x0804840b <+0>:     lea    0x4(%esp),%ecx
   0x0804840f <+4>:     and    $0xfffffff0,%esp
   0x08048412 <+7>:     pushl  -0x4(%ecx)
   0x08048415 <+10>:    push   %ebp
   0x08048416 <+11>:    mov    %esp,%ebp
   0x08048418 <+13>:    push   %ecx
   0x08048419 <+14>:    sub    $0x204,%esp
   0x0804841f <+20>:    mov    %ecx,%eax
   0x08048421 <+22>:    mov    0x4(%eax),%eax
   0x08048424 <+25>:    add    $0x4,%eax
   0x08048427 <+28>:    mov    (%eax),%eax
   0x08048429 <+30>:    sub    $0x8,%esp
   0x0804842c <+33>:    push   %eax
   0x0804842d <+34>:    lea    -0x1fc(%ebp),%eax
   0x08048433 <+40>:    push   %eax
   0x08048434 <+41>:    call   0x80482e0 <strcpy@plt>
   0x08048439 <+46>:    add    $0x10,%esp
   0x0804843c <+49>:    mov    $0x0,%eax
   0x08048441 <+54>:    mov    -0x4(%ebp),%ecx
   0x08048444 <+57>:    leave  
   0x08048445 <+58>:    lea    -0x4(%ecx),%esp
   0x08048448 <+61>:    ret
End of assembler dump.
Dump of assembler code for function main:
   0x080483fb <+0>:     push   %ebp
   0x080483fc <+1>:     mov    %esp,%ebp
   0x080483fe <+3>:     sub    $0x1f4,%esp
   0x08048404 <+9>:     mov    0xc(%ebp),%eax
   0x08048407 <+12>:    add    $0x4,%eax
   0x0804840a <+15>:    mov    (%eax),%eax
   0x0804840c <+17>:    push   %eax
   0x0804840d <+18>:    lea    -0x1f4(%ebp),%eax
   0x08048413 <+24>:    push   %eax
   0x08048414 <+25>:    call   0x80482d0 <strcpy@plt>
   0x08048419 <+30>:    add    $0x8,%esp
   0x0804841c <+33>:    mov    $0x0,%eax
   0x08048421 <+38>:    leave
   0x08048422 <+39>:    ret
End of assembler dump.