zoukankan      html  css  js  c++  java
  • Linux下C程序的反汇编【转】

    转自:http://blog.csdn.net/u011192270/article/details/50224267

    前言:本文主要介绍几种反汇编的方法。

    gcc

    gcc的完整编译过程大致为:预处理->编译->汇编->链接

    前三个步骤分别对应了-E、-S、-c三个选项。

    今天我要介绍的第一种方法就是使用-S这个选项。

    源程序main.c:

    /*************************************************************************
        > File Name: main.c
        > Author: AnSwEr
        > Mail: 1045837697@qq.com
        > Created Time: 2015年12月08日 星期二 20时06分19秒
     ************************************************************************/
    
    #include<stdio.h>
    int i = 1;
    int main(void)
    {
        ++i;
        printf("%d
    ",i);
        return 0;
    }

    执行以下命令:

    gcc -S -o main.s main.c

    查看汇编源程序main.s:

        .file   "main.c"
        .globl  i
        .data
        .align 4
        .type   i, @object
        .size   i, 4
    i:
        .long   1
        .section    .rodata
    .LC0:
        .string "%d
    "
        .text
        .globl  main
        .type   main, @function
    main:
    .LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movl    i(%rip), %eax
        addl    $1, %eax
        movl    %eax, i(%rip)
        movl    i(%rip), %eax
        movl    %eax, %esi
        movl    $.LC0, %edi
        movl    $0, %eax
        call    printf
        movl    $0, %eax
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
    .LFE0:
        .size   main, .-main
        .ident  "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
        .section    .note.GNU-stack,"",@progbits

     

    哈哈,大家看是不是成功了?至于汇编程序的具体解释则不在本文的讨论范畴。

    最后介绍一下gcc的具体过程:
    参考: https://github.com/1184893257/simplelinux/blob/master/gcc.md#top

    编译阶段命令截断后的产物
        C源程序
    预处理 gcc -E 替换了宏的C源程序(没有了#define,#include…), 删除了注释
    编译 gcc -S 汇编源程序
    汇编 gcc -c 目标文件,二进制文件, 允许有不在此文件中的外部变量、函数
    链接 gcc 可执行程序,一般由多个目标文件或库链接而成, 二进制文件,所有变量、函数都必须找得到

    objdump

    objdump是linux下一款反汇编工具,能够反汇编目标文件、可执行文件。

    主要选项:

    objdump -f 
    显示文件头信息
    
    objdump -d 
    反汇编需要执行指令的那些section
    
    objdump -D 
    与-d类似,但反汇编中的所有section
    
    objdump -h 
    显示Section Header信息
    
    objdump -x 
    显示全部Header信息
    
    objdump -s 
    将所有段的内容以十六进制的方式打印出来

    目标文件

    反汇编:

    gcc -c -o main.o main.c
    objdump -s -d main.o > main.o.txt
    • 1
    • 2

    查看汇编文件:

    
    main.o:     文件格式 elf64-x86-64
    
    Contents of section .text:
     0000 554889e5 8b050000 000083c0 01890500  UH..............
     0010 0000008b 05000000 0089c6bf 00000000  ................
     0020 b8000000 00e80000 0000b800 0000005d  ...............]
     0030 c3                                   .               
    Contents of section .data:
     0000 01000000                             ....            
    Contents of section .rodata:
     0000 25640a00                             %d..            
    Contents of section .comment:
     0000 00474343 3a202855 62756e74 7520342e  .GCC: (Ubuntu 4.
     0010 382e322d 31397562 756e7475 31292034  8.2-19ubuntu1) 4
     0020 2e382e32 00                          .8.2.           
    Contents of section .eh_frame:
     0000 14000000 00000000 017a5200 01781001  .........zR..x..
     0010 1b0c0708 90010000 1c000000 1c000000  ................
     0020 00000000 31000000 00410e10 8602430d  ....1....A....C.
     0030 066c0c07 08000000                    .l......        
    
    Disassembly of section .text:
    
    0000000000000000 <main>:
       0:   55                      push   %rbp
       1:   48 89 e5                mov    %rsp,%rbp
       4:   8b 05 00 00 00 00       mov    0x0(%rip),%eax        # a <main+0xa>
       a:   83 c0 01                add    $0x1,%eax
       d:   89 05 00 00 00 00       mov    %eax,0x0(%rip)        # 13 <main+0x13>
      13:   8b 05 00 00 00 00       mov    0x0(%rip),%eax        # 19 <main+0x19>
      19:   89 c6                   mov    %eax,%esi
      1b:   bf 00 00 00 00          mov    $0x0,%edi
      20:   b8 00 00 00 00          mov    $0x0,%eax
      25:   e8 00 00 00 00          callq  2a <main+0x2a>
      2a:   b8 00 00 00 00          mov    $0x0,%eax
      2f:   5d                      pop    %rbp
      30:   c3                      retq   

    可执行文件

    反汇编:

    gcc -o main main.c
    objdump -s -d main > main.txt

    查看汇编文件(由于文件较大,只取部分展示):

    Disassembly of section .init:
    
    00000000004003e0 <_init>:
      4003e0:   48 83 ec 08             sub    $0x8,%rsp
      4003e4:   48 8b 05 0d 0c 20 00    mov    0x200c0d(%rip),%rax        # 600ff8 <_DYNAMIC+0x1d0>
      4003eb:   48 85 c0                test   %rax,%rax
      4003ee:   74 05                   je     4003f5 <_init+0x15>
      4003f0:   e8 3b 00 00 00          callq  400430 <__gmon_start__@plt>
      4003f5:   48 83 c4 08             add    $0x8,%rsp
      4003f9:   c3                      retq   
    
    Disassembly of section .plt:
    
    0000000000400400 <printf@plt-0x10>:
      400400:   ff 35 02 0c 20 00       pushq  0x200c02(%rip)        # 601008 <_GLOBAL_OFFSET_TABLE_+0x8>
      400406:   ff 25 04 0c 20 00       jmpq   *0x200c04(%rip)        # 601010 <_GLOBAL_OFFSET_TABLE_+0x10>
      40040c:   0f 1f 40 00             nopl   0x0(%rax)
    
    0000000000400410 <printf@plt>:
      400410:   ff 25 02 0c 20 00       jmpq   *0x200c02(%rip)        # 601018 <_GLOBAL_OFFSET_TABLE_+0x18>
      400416:   68 00 00 00 00          pushq  $0x0
      40041b:   e9 e0 ff ff ff          jmpq   400400 <_init+0x20>

     

    linux 下目标文件(默认扩展名是.o)和可执行文件都是 ELF 格式(文件内容按照一定格式进行组织)的二进制文件; 类似的,Windows 下 VISUAL C++ 编译出来的目标文件 (扩展名是.obj)采用 COFF 格式,而可执行文件 (扩展名是.exe)采用 PE 格式, ELF 和 PE 都是从 COFF 发展而来的。

    因为 linux 下目标文件和可执行文件的内容格式是一样的, 所以 objdump 既可以反汇编可执行文件也可以反汇编目标文件。

    总结

    掌握了反汇编的方法,当你的程序遇到一些未知的变量错误等,可以直接反汇编来查看汇编代码,一切一目了然。PS:汇编我已经忘得差不多了。

    参考

    1. https://github.com/1184893257/simplelinux

    反馈与建议

    版权声明:本文为博主原创文章,未经博主允许不得转载。 http://blog.csdn.net/u011192270/article/details/50224267
  • 相关阅读:
    【嵌入式linux】(第三步):安装串口终端 (ubuntu安装minicom串口终端)
    vim常用命令总结
    usb调试
    查找当前文件夹内容
    Android SDK开发包国内下载地址
    ubuntu下svn使用指南
    Ubuntu vim显示行号语法高亮自动缩进
    android_handler(一)
    HDU 1241 Oil Deposits (DFS)
    计划
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/8547950.html
Copyright © 2011-2022 走看看