博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux下C程序的反汇编【转】
阅读量:6323 次
发布时间:2019-06-22

本文共 4195 字,大约阅读时间需要 13 分钟。

转自:

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

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
int i = 1; int main(void) { ++i; printf("%d\n",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\n" .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的具体过程:

参考:

编译阶段 命令 截断后的产物
    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.cobjdump -s -d main.o > main.o.txt
  • 1
  • 2

查看汇编文件:

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 
: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # a
a: 83 c0 01 add $0x1,%eax d: 89 05 00 00 00 00 mov %eax,0x0(%rip) # 13
13: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 19
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
2a: b8 00 00 00 00 mov $0x0,%eax 2f: 5d pop %rbp 30: c3 retq

 

可执行文件

反汇编:

gcc -o main main.cobjdump -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 
: 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
: 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:汇编我已经忘得差不多了。

参考

反馈与建议

  • 微博:
  • github:
  • 博客:
版权声明:本文为博主原创文章,未经博主允许不得转载。 http://blog.csdn.net/u011192270/article/details/50224267
你可能感兴趣的文章
Python正则表达式(regular expression)简介-re模块
查看>>
Xamarin改写安卓Residemenu控件
查看>>
Error: Error setting TTL index on collection : sessions
查看>>
你好,C++(24)好大一个箱子!5.1.1 函数的声明和定义
查看>>
git总结一、工作中常用基础命令
查看>>
Sprint 3计划
查看>>
(三)策略模式-C++实现
查看>>
meta标签大全
查看>>
常用的签名方式
查看>>
iOS UICollectionView高级用法(长按自由移动cell)-新
查看>>
XML文件基础,DTD校验文件编写,Schema文件的简单使用
查看>>
kibana简单使用——elaticsearch的文档,索引的CRUD操作
查看>>
PHP程序员最易犯10种错误
查看>>
使用Apktools反编译apk应用
查看>>
E1. Median on Segments (Permutations Edition)
查看>>
VC查找网页源码指定内容
查看>>
数据结构练手03 栈和队列的线性表示
查看>>
RedisTemplate访问Redis数据结构(介绍和常用命令)
查看>>
九九乘法表(小学二年级)
查看>>
Spirng+SpringMVC+Maven+Mybatis+MySQL项目搭建(转)
查看>>