这里我试图缓冲溢出一个非常简单的C代码:
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[]) {
/* [1] */ char buf[256];
/* [2] */ strcpy(buf,argv[1]);
/* [3] */ printf("Input:%s\n",buf);
return 0;
}`
在我的Ubuntu 16.04 64位虚拟机上,我使用以下命令编译它(我在编译之前禁用了ASLR):
gcc -g -fno-stack-protector -z execstack -o vuln vuln.c -m32
结果汇编代码是:
0x0804843b <+0>: lea 0x4(%esp),%ecx
0x0804843f <+4>: and $0xfffffff0,%esp
0x08048442 <+7>: pushl -0x4(%ecx)
0x08048445 <+10>: push %ebp
0x08048446 <+11>: mov %esp,%ebp
0x08048448 <+13>: push %ecx
0x08048449 <+14>: sub $0x104,%esp
0x0804844f <+20>: mov %ecx,%eax
0x08048451 <+22>: mov 0x4(%eax),%eax
0x08048454 <+25>: add $0x4,%eax
0x08048457 <+28>: mov (%eax),%eax
0x08048459 <+30>: sub $0x8,%esp
0x0804845c <+33>: push %eax
0x0804845d <+34>: lea -0x108(%ebp),%eax
0x08048463 <+40>: push %eax
0x08048464 <+41>: call 0x8048310 <strcpy@plt>
0x08048469 <+46>: add $0x10,%esp
0x0804846c <+49>: sub $0x8,%esp
0x0804846f <+52>: lea -0x108(%ebp),%eax
0x08048475 <+58>: push %eax
0x08048476 <+59>: push $0x8048510
0x0804847b <+64>: call 0x8048300 <printf@plt>
0x08048480 <+69>: add $0x10,%esp
0x08048483 <+72>: mov $0x0,%eax
0x08048488 <+77>: mov -0x4(%ebp),%ecx
0x0804848b <+80>: leave
0x0804848c <+81>: lea -0x4(%ecx),%esp
0x0804848f <+84>: ret
不幸的是,在OS为Ubuntu 12.04(x86)的教程中,它生成了不同的代码:
0x08048414 <+0>: push %ebp //backup caller's ebp
0x08048415 <+1>: mov %esp,%ebp //set callee's ebp to esp
0x08048417 <+3>: and $0xfffffff0,%esp //stack alignment
0x0804841a <+6>: sub $0x110,%esp //stack space for local variables
0x08048420 <+12>: mov 0xc(%ebp),%eax //eax = argv
0x08048423 <+15>: add $0x4,%eax //eax = &argv[1]
0x08048426 <+18>: mov (%eax),%eax //eax = argv[1]
0x08048428 <+20>: mov %eax,0x4(%esp) //strcpy arg2
0x0804842c <+24>: lea 0x10(%esp),%eax //eax = 'buf'
0x08048430 <+28>: mov %eax,(%esp) //strcpy arg1
0x08048433 <+31>: call 0x8048330 <strcpy@plt> //call strcpy
0x08048438 <+36>: mov $0x8048530,%eax //eax = format str "Input:%s\n"
0x0804843d <+41>: lea 0x10(%esp),%edx //edx = buf
0x08048441 <+45>: mov %edx,0x4(%esp) //printf arg2
0x08048445 <+49>: mov %eax,(%esp) //printf arg1
0x08048448 <+52>: call 0x8048320 <printf@plt> //call printf
0x0804844d <+57>: mov $0x0,%eax //return value 0
//Function Epilogue
0x08048452 <+62>: leave //mov ebp, esp; pop ebp;
0x08048453 <+63>: ret //return
为什么在序言和结语中存在如此巨大的差异?任何文件和解释表示赞赏。
正如我所尝试的那样,溢出前asm代码并没有产生任何结果。这是因为新版Ubuntu的一些安全功能吗? P.s:对不起问题的长度,我别无选择。提前谢谢。