idapro权威指南第二版阅读笔记-第二章 逆向和反汇编工具
2.1 分类工具
拿到文件后第一步,确定文件类型。注意文件扩展名可能是不正确的,所以要使用工具
2.1.1 file
在*nix风格的操作系统,和cygwin /mingw 工具都提供
通过识别幻数(magic number)判断文件类型。如Windows PE的magicnumber 为 MZ(MZ文件头),对应4D5A(ascii);;;;java .class file 为0xCAFEBABE
还能判断文件的链接类型(动静态)、是否去除符号(stripped)等等、
去除符号:编译过程,会在二进制目标文件留下符号(符号用于,在生成二进制文件/可执行文件时,解析文件间引用关系和提供调试器相关信息)。链接结束后很多符号就没用了,链接器选项可以去除符号。也可以通过strip工具去除现有的二进制文件中的符号。去除符号可能不改变大小,但文件功能保持不变。
file当然也可能出错。如构建一个文件,只要加上MZ字符头,就会使得识别出错
2.1.2 pe tools
分析windows中的进程、可执行程序
2.1.3 PEiD
类似
2.2 摘要工具
识别文件类型后,解析其输入文件/信息等(如符号、链接库等等)
2.2.1 nm
将源文件编译成目标文件时, 编译器必须嵌人一些全局(外部)符号的位置信息, 以便链接器在组合目标文件以创建可执行文件时, 能够解析对这些符号的引用。
除非被告知要去除最终的可执行文件中的符号, 否则 , 链接器通你会将目标文件中的符号带入最终的可执行文件中。
根据 nm手册的描述, 这一实用工具的作用是 "列举目标文件中的符号”。
使用nm检查中间目标文件(扩展名为.o的文件, 而非可执行文件)时, 默认输出结果是在 这个文件中声明的任何函数和全局变量的名称。
U, 未定义符号, 通常为外部符号引用。
T, 在文本部分定义的符号, 通常为函数名称.
t, 在文本部分定义的局部符号。在C程序中, 这个符号通常等同于一个静态函数。
D, 已初始化的数据侦。
C, 未初始化的数据值。
也可以对可执行文件分析,在此不列举
2.2.2 ldd
创建可执行文件时,需要解析该文件引用的库函数的地址。链接器通过两种方法解析对库函数的调用:静态链接和动态链接。链接器的命令行参数决定使用哪种方法,或二者兼有。
静态链接:链接器将应用程序的目标文件和库文件组合,生成可执行文件。运行时就无需寻找库代码的位置,因为已经包含在可执行文件了。静态链接优点在于函数调用快,无需考虑用户系统中可用的库函数;;;;缺点在于可执行文件更大,库函数升级后需要对文件重新链接。
相对而言,静态链接的二进制文件分析起来更困难。
动态链接:不复制库,只将所需库(.so,.dll)的引用插入到可执行文件。运行时定位所需库文件并加载到内存,而非加载包含所有库代码的静态链接文件。优点在于只需升级库函数的代码即可,无需重新链接。缺点在于速度较慢,且发布商/用户需要准备需要的全部库文件
linux中提供ldd工具,列举可执行文件所需动态库。
windows中,visual studio提供dumpin工具,dumpin /dependents 文件名
2.2.3 objdump readelf
显示与目标文件相关的信息:节头部,专用头部(可以实现类似ldd的功能),调试信息,符号信息(类似 nm),反汇编代码清单(使用线性扫描分析文件中被标记为代码的部分,并保存到文件中)
objdump依赖libbfd,可分析ELF/PE
readelf类似objdump。但不依赖libbfd
2.2.4 otool
解析OS X Mach-O二进制文件。类似OS X系统下的objdump工具
2.2.5 dumpbin
Visual Studio中提供的分析Windows PE文件信息的工具。类似objdump
2.2.6 c++filt
函数重载时使用和原函数名相同的名称,而目标文件中不能有相同名称的函数。所以编译器整合参数相关的信息和原始名称,为重载函数生成唯一名称。这一过程称为名称改编(name mangling)
C++标准没有为名称改变指定标准。所以名称改编和编译器设计者有关。
c++filt将输入的名称看做改变后的名称(mangled name),输出原始名称(如果能识别),否则输出原始输入
2.3 深度检测工具
2.3.1 strings
可以在可执行文件中搜索字符串
默认搜索至少含四位ascii字符的字符串。(ascii字符为7位)
需要注意,出现的字符串不一定被使用
strings仅扫描可加载的、经过初始化的部分。使用-a 参数扫描整个文件
-t,给出字符串的偏移量
-e 搜索其他字符集,如unicode
2.3.2 反汇编器
dumpbin objdump otool 只能生成反汇编代码清单(使用线性扫描分析文件中被标记为代码的部分,并保存到文件中),即死代码清单形式,并且和格式有关。而无法处理任意的二进制数据块(任意格式、任意位置开始)
两个用于x86指令集的流式反汇编器(stream disassembler):ndisasm diStorm
流式反汇编器灵活。可用于反汇编网络数据包中包含shellcode的部分。也可分析不包含布局参考的ROM镜像
PS
符号(symbol)节(section) 静态链接 动态链接 函数重载
编译
链接
目标文件
可执行文件