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\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的具体过程:
参考: 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:汇编我已经忘得差不多了。
参考
反馈与建议
- 微博:@AnSwEr不是答案
- github:AnSwErYWJ
- 博客:AnSwEr不是答案的专栏
Linux下C程序的反汇编【转】的更多相关文章
- Linux下C程序的编辑,编译和运行以及调试
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html 内部邀请码:C8E245J (不写邀请码,没有现金送) 国 ...
- linux下c程序调用reboot函数实现直接重启【转】
转自:http://www.blog.chinaunix.net/uid-20564848-id-73878.html linux下c程序调用reboot函数实现直接重启 当然你也可以直接调用syst ...
- 位图文件(BMP)格式以及Linux下C程序实现(转)
源:位图文件(BMP)格式以及Linux下C程序实现 说到图片,位图(Bitmap)当然是最简单的,它是Windows显示图片的基本格式,其文件扩展名为*.BMP.由于没有经过任何的压缩,故BMP图 ...
- Linux下C程序内存泄露检测
在linux下些C语言程序,最大的问题就是没有一个好的编程IDE,当然想kdevelop等工具都相当的强大,但我还是习惯使用kdevelop工具,由于没有一个习惯的编程IDE,内存检测也就成了在lin ...
- Linux下C程序的内存映像
2.Linux下C程序的内存映像 2.1. 代码段.只读数据段(1)对应着程序中的代码(函数),代码段在Linux中又叫文本段(.text)(2)只读数据段就是在程序运行期间只能读不能写的数据,con ...
- 【转】Linux下进程/程序网络带宽占用情况查看工具 -- NetHogs
http://www.cnblogs.com/carbon3/p/5930803.html 之前VPS侦探曾经介绍过流量带宽相关的工具如:iftop.vnstat,这几个都是统计和监控网卡流量的.但是 ...
- linux下c程序的链接、装载和库(1)
读完<程序员的自我修养--链接.装载和库>相关章节,想来总结一下,若有错误,请指正,多谢. 1. 什么叫目标文件? 你的工程里有很多xxx.c这样的源文件,这些文件是文本文件,只有人能够认 ...
- Linux下修改默认字符集--->解决Linux下Java程序种中文文件夹file.isDirectory()判断失败的问题
一.问题描述: 一个项目中为了生成树状目录,调用了file.listFiles()方法,然后利用file.isDirectory()方法判断是否为目录,该程序在windows下运行无问题,在Linux ...
- Linux下常用程序的代理服务器(proxy)配置
Linux下有很多程序都只有命令行接口,对于这类程序,它们通过代理服务器(proxy)访问网络的方式也不尽相同.在本文中Easwy总结了一些常用Linux程序配置代理服务器的方法. [ 通用代理服务器 ...
随机推荐
- js模块化的总结
从前端打包的历史谈起 在很长的一段前端历史里,是不存在打包这个说法的.那个时候页面基本是纯静态的或者服务端输出的, 没有 AJAX,也没有 jQuery.Google 推出 Gmail 的时候(200 ...
- python模拟浏览器爬取数据
爬虫新手大坑:爬取数据的时候一定要设置header伪装成浏览器!!!! 在爬取某财经网站数据时由于没有设置Header信息,直接被封掉了ip 后来设置了Accept.Connection.User-A ...
- NAT alg 和 ASPF
NAT alg 和 ASPF 参考:https://handbye.cn/719.html 来源:https://www.jianshu.com/p/8a8eb36eef7d NAT的部署已经在企业网 ...
- 初次使用http打不开页面,使用https打开过后使用http协议又能正常访问
http协议为什么打不开https站点 在访问一个https的站点,比如 https://www.aaa.com,首次访问时,访问的地址是 http://www.aaa.com,(不加S),出现的是网 ...
- 域hash值破解的总结经验
1.vsssown.vbs拷贝域数据库: 1.1上传vssown.vbs文件 上传cscript.exe和vssown.vbs到域服务器上 1.2创建快照 reg query HKEY_LOCAL_M ...
- Java入门:构造方法
什么是构造方法 类体中有两大形式的成员,其中一个是成员方法(另一个就是成员变量啦~).成员方法又分两种,一种是普通成员方法,另一种是构造方法(有的资料中也称之为构造函数). 所谓构造方法,就是这个类在 ...
- PythonCodingRule简略
- gulp+webpack配置
转自:https://www.jianshu.com/p/2549c793bb27 gulp gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器:她不仅能对网站资源进行优化,而且在开 ...
- KVM管理概述
一.使用QEMU管理虚拟机 1.KVM指南 https://activedoc.opensuse.org/book/opensuse-virtualization-with-kvm/part-iii- ...
- CALayer属性:position和anchorPoint
一.position和anchorPoint 1.简单介绍 CALayer有2个非常重要的属性:position和anchorPoint @property CGPoint position; 用来设 ...