Linux二进制代码的阅读
大多数时候,我们研究的是如何阅读源代码。但在一些情况下,比如源代码不公开 或得到源代码的代价很高的情况下,我们又不得不需要了解程序的行为,这 时阅读二进制文件就非常重要。假设现在有一个二进制可执行文件,我们木有源代码,但要了解它的实现,这里仅简单列出一些常用的工具。 阅读方式可分为两个方面:静态阅读和动态阅读。
静态阅读
首先,file命
令可以查看可执行文件的大体信息。比如是哪种格式的,哪个体系结构的,有没有调试信息等。这些决定了需要用哪个版本的工具进行进一
步查看。比如如果是arm体系的可执行文件就可用arm
toolchain里的工具,如arm-eabi-objdump,arm-eabi-gdb等。
众所周知,GNU Binutils提供了一系列解析和操作二进制文件的工具,最常用的如objdump,其最主要的功能之一是反汇编:
objdump -d libxxx.so
其它常用选项包括:
-x 打印所有头信息
-s 打印所有段的内容
-S 将反汇编和源代码一起打印
-r 打印重定位表
-R 打印动态重定位表
-D 打印所有段,即不止代码段
-t 打印符号表,和nm的功能类似,但格式不一样
-T 只打印动态链接的符号表项
等等。
readelf命令主要用于查看elf文件的元信息(如段信息等)。如查看可执行文件的头信息:
readelf -h libxxx.so
其它常用选项包括:
-s 打印符号表
-r 打印重定位表
-l 打印装载属性
-S 打印段表
等等。
除了以上两个用得最多的,其它一些辅助工具有时也必不可少:
nm 打印符号表
c++filt 把c++符号unmangle
strip 把调试信息删除
strings 看文件中的字符串
ldd: 查看依赖关系
等等
动态阅读
要了解可程序的行为,最可靠的还是看二进制文件跑起来时的样子。很多时候,由于运行环境复杂,特别是多线程情况下,动态阅读能发现很多静态阅读所不可能发现的东西。
首先,在/proc/pid(pid为进程号)下记录了二进制文件跑起来后的很多信息,如通过/proc/pid/maps可以知道该程序链接了哪些库,
分别被加载在了什么地方(这样,知道了错误地址,理论上就可以找到相应库的对应反汇编代码。),/proc/pid/mem是进程所用的内存镜像,
/proc/pid/stat则记录了中断统计信息等。/proc/pid/cmdline则记录了启动程序的命令行。
其次,通过trace(strace,lstrace)可以看程序有哪些系统调用。strace用于跟踪系统调用,ltrace用于跟踪动态库调用。
如对于在/proc/pid/maps中看到的一些匿名内存映射,想要看它们是在什么时候或是在哪被创建可以用:
strace -f -p 3742 -e trace=mmap2,open,mprotect |tee tmp.trace
其中3742为进程ID。这里只过滤出关于内存映射的函数。
最后,指令级动态阅读的神器还属gdb。
在gdb中查看寄存器信息可用:
(gdb) i r
在调试过程中打印出反汇编代码可用
或者
(gdb) x/10i addr
然后就可以和objdump出来的反汇编结合着看了。如GOT表之类的信息在静态阅读时是无意义的,只有这时才能看。
各种break point能让我们迅速定位到我们关注的地方:
watch point 在指定数据被访问时程序停止。
break point 在指定代码被执行时程序停止。 因为很多时候库不带symbol,所以得直接设在地址上 break *addr。
catch point 在指定事件发生时程序停止,如进程创建,动态链接库加载及异常。
条件断点有时很有用:break ... if <condition>,但这玩意一旦设上不是一般的慢啊。。。
gdb中的bt和info frame命令常用来看堆栈信息和函数调用关系。但有时因为bug栈被写坏了,但如果不是被写得很坏,查看栈的内容常通常能找到一些线索:
(gdb) x/40x $sp
该命令是查看$sp指向区域的40个byte的内存内容。该命令也可用来查看任意指定地址的内存内容。
关于gdb常用的功能:http://wiki.ubuntu.org.cn/%E7%94%A8GDB%E8%B0%83%E8%AF%95%E7%A8%8B%E5%BA%8F
其它的一些gdb使用备忘:http://blog.csdn.net/ariesjzj/article/details/6913671
一些相关资料
http://www.linuxforums.org/articles/understanding-elf-using-readelf-and-objdump_125.html
http://bbs.chinaunix.net/thread-1972423-1-1.html
elfutils-0.148: http://www.linux.it/~rubini/docs/binfmt/binfmt.html
GNU binutils & libbfd: http://www.gnu.org/software/binutils/
参考:
Linux二进制代码的阅读的更多相关文章
- 关于linux上pdf阅读器
今天也是倒腾linux 上pdf阅读器好久. 1.okular是挺好的,但是却太大了,好多功能,我没有细看.我简单的打开了几个pdf文件,发现加载速度还是太慢了.所以基于种种,我给卸载掉了. 安装直接 ...
- Linux协议栈代码阅读笔记(二)网络接口的配置
Linux协议栈代码阅读笔记(二)网络接口的配置 (基于linux-2.6.11) (一)用户态通过C库函数ioctl进行网络接口的配置 例如,知名的ifconfig程序,就是通过C库函数sys_io ...
- [置顶] Linux协议栈代码阅读笔记(一)
Linux协议栈代码阅读笔记(一) (基于linux-2.6.21.7) (一)用户态通过诸如下面的C库函数访问协议栈服务 int socket(int domain, int type, int p ...
- Linux版EPUB阅读器
Linux版EPUB阅读器 如果说用平板电脑看书尚属主流的话,那么在电脑上读书就非常少见了.专注阅读16世纪的书是非常困难的了,没人希望后台蹦出QQ聊天窗口.但是如果你非要在电脑上打开电子书的话,那么 ...
- Linux下如何阅读开源项目
标签(空格分隔): code SLAM是一个大型的项目,而且通常都是基于linux平台的.对于大部分没有linux经验的人来说,如何在linux下拥有vs代码阅读体验就非常重要了.这篇博客就简答的介绍 ...
- Linux 源码阅读 进程管理
Linux 源码阅读 进程管理 版本:2.6.24 1.准备知识 1.1 Linux系统中,进程是最小的调度单位: 1.2 PCB数据结构:task_struct (Location:linux-2. ...
- [置顶] Linux协议栈代码阅读笔记(二)网络接口的配置
Linux协议栈代码阅读笔记(二)网络接口的配置 (基于linux-2.6.11) (一)用户态通过C库函数ioctl进行网络接口的配置 例如,知名的ifconfig程序,就是通过C库函数sys_io ...
- 转载~Linux 平台下阅读源码的工具
Linux 平台下阅读源码的工具 前言 看源代码是一个程序员必须经历的事情,也是可以提升能力的一个捷径.个人认为: 要完全掌握一个软件的方法只有阅读源码在Windows下有sourceinsight这 ...
- Linux下pdf阅读器推荐
由于需要在pdf文件上做标记,所以自带的文档查看器根本满足了需求,之前去网上查了查,Okular评价挺高,就安装了一个,确实能基本满足我的需求,但是 1.界面感觉还是不太友好,书签栏一直在那. 2.而 ...
随机推荐
- Python运算符与编码
阅读目录 while 循环 运算符 编码的问题 单位转换 整数 布尔值 while 循环 在生活中,我们遇到过循环的事情吧?比如循环听歌.在程序中,也是存才的,这就是流程控制语句 while 1.基本 ...
- sql语句中的insert 和 insert into 的区别?into有什么用?
insert into tableName values(........) insert tableName (字段名1,字段名2,...)values(......)看语句结构就知道区别了 .in ...
- WPF文件和文件夹的操作
1.对文件的操作 private void button_chose_Click(object sender, RoutedEventArgs e) { var openFileDialog = ne ...
- 在js中对日期的加减法
以在某个日期上加减天数来说,其实只要调用Date对象的setDate()函数就可以了,对月份来说,使用setMonth(),具体方法如下: function addDate(date, da ...
- VS2017常用快快捷键
VS2017常用快快捷键 VS中代码对齐等快捷键 在VS中,选定代码后,按Ctrl+K+F组合键,可以自动进行代码对齐. 注意:要先按下Ctrl和K,再按下F,因为Ctrl ...
- 【刷题】BZOJ 2179 FFT快速傅立叶
Description 给出两个n位10进制整数x和y,你需要计算x*y. Input 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. Output 输出 ...
- POJ1273:Drainage Ditches——题解
http://poj.org/problem?id=1273 题目大意: n点m边网络流,求1-n最大流. —————————————— 网络流板子,切了. #include <cstdio&g ...
- ZOJ1081:Points Within——题解
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1081 题目大意:给定一个点数为 n 的多边形,点按照顺序给出,再给出 m ...
- BZOJ1022 [SHOI2008]小约翰的游戏John 【博弈论】
1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3014 Solved: 1914 [Submi ...
- bzoj1052: [HAOI2007]覆盖问题(二分+构造)
貌似又写出了常数挺优(至少不劣)的代码>v< 930+人AC #49 写了个O(nlogn)貌似比一些人O(n)还快2333333 这题还是先二分答案,check比较麻烦 显然正方形一定以 ...