逆向与反汇编工具

分类工具

通常,在初次遇到一个不熟悉的文件时,不要通过文件的扩展名来确定文件的类型。可以通过以下几个工具来判断文件类型

file

  • file命令是一个标准的实用工具,大多数*NIX风格的操作系统和Windows下的Cygwin或MinGw工具都带有该工具。
  • file通过两种方式来判断文件类型
    • 通过检查文件中的某些特定字段来确认文件类型,如#!bin/bash识别为脚本文件,<html>识别为HTML文档
    • 通过判断文件的结构是否符合某种已知的文件格式。多数情况下,它会搜索某些文件类型特有的标签值。
  • file能够识别大量文件格式,包括数种ASCII文本文件、各种可执行文件和数据文件。在某些情况下,file还能够辨别某一指定文件类型中细微的变化,如不同编译器编译的二进制文件
  • file及其类似的工具有其局限性。如果一个文件碰巧包含了某种文件格式的标记,file等工具很可能会错误地识别该文件。在逆向工程过程中,绝不要完全相信任何工具所提供的结果,除非该结果得到其他几款工具和手动分析的确认。

PE Tools

  • PE Tools是一组用于分析Windwos系统中正在运行的进程和可执行文件的工具。PE Tools的主界面如下图所示
  • 在进程列表中,可以将一个进程的内存映像转储到某个文件中,也可使用PE Sniffer来确定可执行文件由何种编译器构建,或者该文件是否经过某种已知的模糊工具的模糊处理。
  • 可以使用内嵌的PE Editor工具查看PE文件头字段,修改文件头的值

PEiD

  • PEiD是另一款Windows工具,主要用于识别构建某一特定的WindowsPE二进制文件所使用的编译器、有无加壳。软件界面如图所示
  • PEiD的许多其他功能与PE Tools相同,包括显示文件头信息摘要、收集进程信息和执行基本反汇编等

摘要工具

在对文件进行初步分类后,需要使用更高级的工具提取详尽信息。

nm

  • nm工具的作用是列举目标文件中的符号。使用nm检查中间目标文件(.o文件)时,默认输出结果是在这个文件中声明的任何函数和全局变量的名称,其中字母表示所列举的符号类型

    以下为常见符号类型说明

    • U:未定义符号,通常为外部符号引用
    • T:在文本部分定义的符号,通常为函数名称
    • t: 在文本部分定义的局部符号,在C程序中,该符号通常等同于一个静态函数
    • D: 已初始化的数据值
    • C: 未初始化的数据值
    • 更多符号类型说明请参阅nm手册
  • 使用nm列举可执行文件中的符号将显示更多信息,因为在链接的过程中,符号被解析为虚拟地址。

ldd

  • 创建可执行文件时,必须解析该文件应用的任何库函数地址。链接器通过两种方法解析对库函数的调用:静态链接和动态链接。一个可执行文件可能为静态链接、动态链接或二者兼有之。
    • 静态链接:链接器会将应用程序的目标文件和所需库文件组合起来,生成一个可执行文件。在运行时不需要确定库代码位置,因此调用函数更快、更容易进行发布。缺点为生成的可执行文件更大,对程序进行升级更加困难。
    • 动态链接:链接器将对所需库的引用(通常为.so.dll文件)插入到最终的可执行文件中。由此生成的可执行文件更小,升级库代码更加简单,但动态链接程序执行时需要更加复杂的加载过程且对库文件有依赖。
  • ldd(list dynamic dependencies)可用来列举任何可执行文件所需的动态库
  • Linux和BSD系统均提供ldd工具。在OS X系统中,使用otool工具并带上-L选项可实现类似的功能。在Windows系统中,可以使用dumpbin来列举文件依赖的库

objdump

  • 与专用的ldd不同,objdump的功能非常多样,它提供了大量的命令行选项以提取目标文件的各种信息。objdump可用来显示以下与目标文件有关的信息
    • 节头部,程序文件每节的摘要信息
    • 专用头部,程序内存分布信息,还有运行时加载器所需的其他信息,包括由ldd等工具生成的库列表
    • 调试信息,提取出程序文件中的任何调试信息
    • 符号信息,以类似nm的方式转储符号表信息
    • 反汇编代码,对文件中标记为代码的部分执行线性扫描反汇编
  • objdumpGNU binutils工具套件的一部分,可以在Linux、FreeBSD和Windows下使用该工具。
  • objdump依靠二进制文件描述符库libbfd来访问目标文件以解析文件格式,readelf工具也可以解析ELF文件,但不依赖libbfd

otool

  • otool可用于解析与OS X Mach-O二进制文件有关的信息,因此,可简单理解为OS X系统下类似于objdump的工具。
  • otool可用于显示与文件的头部和符号表有关的信息,并对文件的代码部分进行反汇编。

dumpbin

  • dumpbinVisual studio工具套件中的一个命令行工具,与otoolobjdump一样,dumpbin可以显示大量关于Windows PE文件的信息
  • dumpbin的其他选项可以从PE文件提取各部分信息,包括符号、导入的函数名、导出的函数名和反汇编代码

C++filt

  • 由于每一个重载的函数使用与原函数相同的名称,因此支持重载函数的语言必须有一种区分函数重载版本的机制。如
void demo(void);
void demo(int x);
void demo(double x);
  • 通常一个目标文件不能含有两个函数名相同的函数,为支持重载,编译器将描述函数参数的类型信息合并到函数的原始名称中,从而为重载函数生成唯一的函数名称。为名称完全相同的函数生成唯一名称的过程叫做名称改编。如果使用nm转储前面的C++代码编译后文件的代码符号,将得到以下输出
0804843c  T _Z4demoPc
08048400  T _Z4demod
08048428  T _Z4demodi
  • 为了由于名称改编的方式没有标准,由编译器决定。因此为了译解上面列出的符号,需要一个理解编译器改编方案的工具。c++filt可执行此工作,它将每个输入名称看成是改编后的名称,并设法确定用于生成该名称的编译器。如果这个名称是一个合法改编的名称,那么,c++filt将输出改编前的原始名称,否则按原样输出名称

  • 改编名称可能包含与其他函数有关的信息,甚至可能包含与类名或函数调用约定有关的信息

深度检测工具

本类型的工具可以从任何格式的文件中提取特定信息

Strings

  • strings工具专门用于提取文件中的字符串内容,通常,使用该工具没有格式的限制。


– 注意:二进制文件中包含某个字符串,并不表示该文件会以某种方式使用这个字符串
– 使用strings处理可执行文件时,默认情况下,strings仅处理文件中可加载的、经初始化的部分。-a参数可强制strings扫描整个文件
strings不会指出字符串在文件中的位置。使用-t参数可令strings显示所发现的每一个字符串的文件偏移量
– 使用-e参数搜索更广泛的字符集

反汇编器

  • 前文所述的摘要工具,如dumpbinotool等无法处理任意格式的二进制数据块。如果遇到一些并不常用的文件格式的二进制文件,需要能够从用户指定偏移量开始反汇编过程的反汇编器
  • 有两个用于x86指令集的流式反汇编器:ndisasmdiStorm。由于流式反汇编非常林辉,因此它的用途非常广泛,如分析网路数据包中可能包含的shellcode,或者分析未知ROM镜像的代码部分

小结

这些工具是二进制文件逆向工程分析的常用工具,这些工具大大促进了流行逆向工具(IDA等)的开发过程