在Ubuntu中使用-m32选项编译32位和64位C代码的区别

时间:2017-06-18 13:31:10

标签: ubuntu gcc nasm 32bit-64bit buffer-overflow

这里我试图缓冲溢出一个非常简单的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:对不起问题的长度,我别无选择。提前谢谢。

0 个答案:

没有答案