01 总览
编译阶段
- nm 获取二进制文件包含的符号信息
- strings 获取二进制文件包含的字符串常量
- strip 去除二进制文件包含的符号
- readelf 显示目标文件详细信息
- objdump 尽可能反汇编出源代码
- addr2line 根据地址查找代码行
运行阶段
- gdb 强大的调试工具
- ldd 显示程序需要使用的动态库和实际使用的动态库
- strace 跟踪程序当前的系统调用
- ltrace 跟踪程序当前的库函数
- time 查看程序执行时间、用户态时间、内核态时间
- gprof 显示用户态各函数执行时间
- valgrind 检查内存错误
- mtrace 检查内存错误
其他
- proc文件系统
- 系统日志
02 编译阶段
nm(获取二进制文件里面包含的符号)
符号:函数、变量
参数:
- -C 把C++函数签名转为可读形式
- -A 列出符号名的时候同时显示来自于哪个文件。
- -a 列出所有符号(这将会把调试符号也列出来。默认状态下调试符号不会被列出)
- -l 列出符号在源代码中对应的行号(指定这个参数后,nm将利用调试信息找出文件名以及符号的行号。对于一个已定义符号,将会找出这个符号定义的行号,对于未定义符号,显示为空)
- -n 根据符号的地址来排序(默认是按符号名称的字母顺序排序的)
- -u 只列出未定义符号
strings(获取二进制文件里面的字符串常量)
功能:
获取二进制文件里面的字符串常量
用途:
比较重要的是检查KEY泄露
eg:strings <your_proc> | grep '^.{16}$'
查找<your_proc>中是否存在一行有16个字符的行,并显示出来。
选项:
- -a 不只是扫描目标文件初始化和装载段, 而是扫描整个文件。
- -f 在显示字符串之前先显示文件名。
- -n min-len打印至少min-len字符长的字符串.默认的是4。
#strings /lib/tls/libc.so.6 | grep GLIBC
GLIBC_2.0
GLIBC_2.1
GLIBC_2.1.1……
这样就能看到glibc支持的版本。
strip(去除二进制文件里面包含的符号)
用途:
可执行程序减肥(通常只在已经调试和测试过的生成模块上,因为不能调试了)
反编译、反跟踪
readelf(显示目标文件详细信息)
nm 程序可用于列举符号及其类型和值,但是,要更仔细地研究目标文件中这些命名段的内容,需要使用功能更强大的工具。其中两种功能强大的工具是objdump和readelf。
readelf工具使用来显示一个或多个ELF格式文件信息的GNU工具。使用不同的参数可以查看ELF文件不同的的信息。
readelf <option> <elffile>
- -a 显示所有ELF文件的信息
- -h 显示ELF文件的文件头
- -l 显示程序头(program-header)和程序段(segment)和段下面的节
- -S 显示较为详细的节信息(section)
- -s 显示符号信息,
- -n 显示标识信息(如果有)
- -r 显示重定位信息(如果有)
- -u 显示展开函数信息(如果有)
- -d 显示动态节信息,一般是动态库的信息
objdump(尽可能反汇编出源代码)objdump –S <exe>
尽可能反汇编出源代码,尤其当编译的时候指定了-g参数时,效果比较明显。
addr2line(根据地址查找代码行)
当某个进程崩溃时,日志文件(/var/log/messages)中就会给出附