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镜像

符号(symbol)节(section) 静态链接 动态链接 函数重载

可执行文件