大多数时候,我们研究的是如何阅读源代码。但在一些情况下,比如源代码不公开 或得到源代码的代价很高的情况下,我们又不得不需要了解程序的行为,这 时阅读二进制文件就非常重要。假设现在有一个二进制可执行文件,我们木有源代码,但要了解它的实现,这里仅简单列出一些常用的工具。 阅读方式可分为两个方面:静态阅读和动态阅读。

静态阅读

首先,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) disass addr
或者
(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/

参考:

http://blog.csdn.net/ariesjzj/article/details/7689120

Linux二进制代码的阅读的更多相关文章

  1. 关于linux上pdf阅读器

    今天也是倒腾linux 上pdf阅读器好久. 1.okular是挺好的,但是却太大了,好多功能,我没有细看.我简单的打开了几个pdf文件,发现加载速度还是太慢了.所以基于种种,我给卸载掉了. 安装直接 ...

  2. Linux协议栈代码阅读笔记(二)网络接口的配置

    Linux协议栈代码阅读笔记(二)网络接口的配置 (基于linux-2.6.11) (一)用户态通过C库函数ioctl进行网络接口的配置 例如,知名的ifconfig程序,就是通过C库函数sys_io ...

  3. [置顶] Linux协议栈代码阅读笔记(一)

    Linux协议栈代码阅读笔记(一) (基于linux-2.6.21.7) (一)用户态通过诸如下面的C库函数访问协议栈服务 int socket(int domain, int type, int p ...

  4. Linux版EPUB阅读器

    Linux版EPUB阅读器 如果说用平板电脑看书尚属主流的话,那么在电脑上读书就非常少见了.专注阅读16世纪的书是非常困难的了,没人希望后台蹦出QQ聊天窗口.但是如果你非要在电脑上打开电子书的话,那么 ...

  5. Linux下如何阅读开源项目

    标签(空格分隔): code SLAM是一个大型的项目,而且通常都是基于linux平台的.对于大部分没有linux经验的人来说,如何在linux下拥有vs代码阅读体验就非常重要了.这篇博客就简答的介绍 ...

  6. Linux 源码阅读 进程管理

    Linux 源码阅读 进程管理 版本:2.6.24 1.准备知识 1.1 Linux系统中,进程是最小的调度单位: 1.2 PCB数据结构:task_struct (Location:linux-2. ...

  7. [置顶] Linux协议栈代码阅读笔记(二)网络接口的配置

    Linux协议栈代码阅读笔记(二)网络接口的配置 (基于linux-2.6.11) (一)用户态通过C库函数ioctl进行网络接口的配置 例如,知名的ifconfig程序,就是通过C库函数sys_io ...

  8. 转载~Linux 平台下阅读源码的工具

    Linux 平台下阅读源码的工具 前言 看源代码是一个程序员必须经历的事情,也是可以提升能力的一个捷径.个人认为: 要完全掌握一个软件的方法只有阅读源码在Windows下有sourceinsight这 ...

  9. Linux下pdf阅读器推荐

    由于需要在pdf文件上做标记,所以自带的文档查看器根本满足了需求,之前去网上查了查,Okular评价挺高,就安装了一个,确实能基本满足我的需求,但是 1.界面感觉还是不太友好,书签栏一直在那. 2.而 ...

随机推荐

  1. JDK版本Java SE、Java EE、Java ME的区别

    想在win7 X64上搭建JAVA开发环境来着(只是尝试下),打开JAVA 官网下载JDK,发现好多版本懵了,百度了下找到这些版本的区别,故有了下文 1.JAVA SE Java2平台标准版(Java ...

  2. C# lamda表达式

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  3. bzoj 4568 [SCOI 2016] 幸运数字

    题目大意 给定一棵\(n\)个点的树,每个点有权值 \(q\)次询问树上路径中 每个点权值可选可不选的最大异或和 \(n\le 2*10^4,q\le 2*10^5,val[i]\le 2^{60}\ ...

  4. [洛谷P3550][POI2013]TAK-Taxis

    题目大意:一条路上有三个点,$0$为起始位置,$d$为总部,$m$为家.有$n$辆车,每辆车最多行驶$x_i$,都从$d$出发,可以在任意位置结束,问最少几辆车可以到家. 题解:贪心,发现当人在$[0 ...

  5. [洛谷P4847]银河英雄传说V2

    题目大意:有$n(n\leqslant2\times10^5)$个序列,有$m(m\leqslant2\times10^5)$个操作,分三种: 1. $M\;x\;y:$把$x$所在的序列放在$y$所 ...

  6. [洛谷P4111][HEOI2015]小Z的房间

    题目大意:有一个$n\times m$的房间,一些位置是房间,另一些位置是柱子,相邻两个房间之间有墙,问有多少种方案可以打通一些墙把所有房间连成一棵树,柱子不可以打通 题解:矩阵树定理,把房间当点,墙 ...

  7. 122. Best Time to Buy and Sell Stock II (Array)

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  8. 【BZOJ5301】【CQOI2018】异或序列(莫队)

    [BZOJ5301][CQOI2018]异或序列(莫队) 题面 BZOJ 洛谷 Description 已知一个长度为 n 的整数数列 a[1],a[2],-,a[n] ,给定查询参数 l.r ,问在 ...

  9. BZOJ4517 & 洛谷4071:[SDOI2016]排列计数——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4517 https://www.luogu.org/problemnew/show/P4071 求有 ...

  10. HDOJ.1075 What Are You Talking About(map)

    What Are You Talking About 点我跳转到题面 点我一起学习STL-MAP 题意分析 首先第一组START-END给出翻译的字典,第二组START-END给出一句话,查找里面出现 ...