Linux下C程序的反汇编【转】

admin 2025年2月13日10:32:09评论9 views字数 3840阅读12分48秒阅读模式

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

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

gcc

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

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

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

源程序main.c:

/*************************************************************************    > File Name: main.c    > Author: AnSwEr    > Mail: [email protected]    > Created Time: 2015年12月08日 星期二 20时06分19秒 ************************************************************************/#include<stdio.h>int i = 1;int main(void){    ++i;    printf("%dn",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, 4i:    .long   1    .section    .rodata.LC0:    .string "%dn"    .text    .globl  main    .type   main, @functionmain:.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 反汇编需要执行指令的那些sectionobjdump -D 与-d类似,但反汇编中的所有sectionobjdump -h 显示Section Header信息objdump -x 显示全部Header信息objdump -s 将所有段的内容以十六进制的方式打印出来

目标文件

反汇编:

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

查看汇编文件:

main.o:文件格式 elf64-x86-64Contents 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

反馈与建议

  • 微博:@AnSwEr不是答案

  • github:AnSwErYWJ

  • 博客:AnSwEr不是答案的专栏

版权声明:本文为博主原创文章,未经博主允许不得转载。http://blog.csdn.net/u011192270/article/details/50224267

【作者】sky

【出处】http://www.cnblogs.com/sky-heaven/

Linux下C程序的反汇编【转】

原文始发于微信公众号(汇编语言):Linux下C程序的反汇编【转】

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月13日10:32:09
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Linux下C程序的反汇编【转】https://cn-sec.com/archives/1071905.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息