使用FLIRT签名识别库



//转自http://blog.163.com/shanshenye2k@yeah/blog/static/8234054120121015102041843/

第1章    使用FLIRT签名识别库

现在,我们开始讨论IDA的高级功能。同时,我们将探讨在最初的自动分析已经完成[1]之后,该执行什么操作。在本章中,为了识别标准的代码序列,我们将讨论各种技巧,如静态链接二进制文件中的库代码,或者由编译器插入的标准初始化代码和辅助函数。

在着手对二进制文件进行逆向工程时,你最不应该做的事情,是浪费时间逆向工程那些你只需阅读一本手册、一段源代码或搜索一下互联网就可以更轻易地了解其行为的库函数。静态链接二进制文件造成的难题,在于应用程序代码与库代码之间的区别很模糊。在静态链接二进制文件中,所有库与应用程序代码混杂在一起,组成了一个庞大的可执行文件。不过,有许多工具可以帮助我们在IDA中识别和标记库代码,使我们可以把注意力放在应用程序自身的代码上。

1.1 快速库鉴定与识别技术

库快速识别和鉴定技术,简称FLIRT[2],是IDA用于识别库代码序列的一组技术。FLIRT的核心是各种模式匹配算法,这些算法使IDA能够迅速确定:一个经过反汇编的函数是否与IDA已知的许多签名中的某一个相匹配。IDA自带的签名文件保存在<IDADIR>/sig目录中,其中的大多数库是常见的Windows编译器自带的库,当然其中也包括一些非Windows签名。

签名文件利用一种自定义格式将大量签名数据压缩并封装到一个特定于IDA的头文件中。多数情况下,签名文件名并不能清楚说明相关签名是由哪个库生成的。根据签名文件的创建方式,签名文件中可能包含一个描述其内容的库名称注释。查看从某个签名文件中提取出来的ASCII内容的前几行代码,通常可以找到这段注释。通常,下面的Unix风格的命令[3]可以在第二或第三行输出结果中显示上述注释:

# strings sigfile | head -n 3

在IDA中,有两种方法可以查看与签名文件有关的注释。首先,你可以通过View?Open Subviews?Signatures访问应用于某个二进制文件的签名列表。其次,手动签名应用程序中,所有签名文件的列表将会显示出来,通过File?Load File?FLIRT Signature File打开这个列表。

1.2 FLIRT签名的应用

当第一次打开一个二进制文件,IDA尝试对这个文件的入口点应用特殊的签名文件,即启动签名。事实证明,由各种编译器生成的入口点代码各不相同,因此,我们可以通过匹配入口点签名来识别用于生成某个特定二进制文件的编译器。

MAIN VS ._START

如前所述,程序的入口点是即将执行的第一条指令的地址。因此,许多熟练的C程序员错误地认为这就是main函数的地址,但事实并非如此。程序的文件类型,而不是创建程序所使用的语言,决定了向这个程序提交命令行参数的方式。为了使加载器加载命令行参数的方式与程序预期接收参数的方式(例如,通过向main提交参数)保持一致,程序必须在将控制权转交给main之前执行一段初始化代码。IDA将这段初始化代码作为程序的入口点,并将其标记为_start

这段初始化,代码还负责必须在main运行之前完成的初始化任务。在C++程序中,这段代码负责确保在执行main之前调用全局声明对象的构造函数。同样,为了在程序真正终止前调用所有全局对象的析构函数,必须插入在main之后执行的清理代码(c1eanup code)。

如果IDA能够识别用于创建某个二进制文件的编译器,则它会加载对应编译器库的签名文件,并将其应用于该文件的剩余部分。IDA自带的签名大多与专用编译器有关,如微软Visual C++Borland Delphi。这是因为,这些编译器自带的二进制库的数量有限,而与开源编译器(如GNU gcc)关联的库却拥有大量的二进制变体,与这类编译器自带的操作系统一样种类繁多。例如,每个版本的FreeBSD都自带有一个特殊的C标准库。为了获得最佳模式匹配效果,你需要为每一种不同版本的库生成签名文件。想象一下,收集每一个版本的Linux自带的libc.a[4]的每一个变体,其难度会有多大!这简直是一个无法完成的任务。从某种程度上说,这些差异归结为库源代码的变化(因而导致不同的编译代码)。但是,巨大的差异也是因为使用了不同的编译选项,如优化设置,以及在创建库时使用了不同的编译器版本。结果,IDA自带的开源编译器库签名文件非常少。不过,如下所述,Hex-Rays提供了各种工具用于由静态库生成你自己的签名文件。

那在什么情况下,你需要手动对数据库应用签名呢?有时IDA能够正确识别创建二进制文件所使用的编译器,但它并没有相关编译器库的签名。在这种情况下,你要么完全不用签名,要么需要获得二进制文件所使用的静态库的副本,并生成你自己的签名。其他情况下,IDA可能根本无法识别一个编译器,因而也无法确定该对数据库应用哪些签名。在分析模糊代码时,你经常会遇到这种情况:为防止编译器识别,混淆代码中的启动例程(startup routine)经过了非常复杂的改编。这时,你必须首先对二进制文件进行大量的去模糊处理,然后才有可能匹配库签名。我们将在第21章讨论处理模糊代码的技巧。

不管什么原因,如果你希望手动对数据库应用签名,你可以通过File?Load  File?FLIRT Signature File打开签名选择对话框,如图12-1所示。

12-1FLIRT签名选择

File栏显示IDA的<IDADIR>/sig目录中每个.sig文件的名称。 请注意.sig文件不能存储在其它的位置。如果生成自己的签名,也需要存储在<IDADIR>/sig目录中。Library name栏显示嵌入到每个文件中的库名称注释。记住,这些注释的描述性取决于签名创建者(可能就是你自己)。

选择一个库模块,IDA将加载对应的.sig文件中包含的签名,并将其与数据库中的每一个函数进行比较. 你一次只能应用一组签名,因此,如果你希望对一个数据库应用几组不同的签名,你需要重复上述过程。如果发现一个函数与签名相匹配,IDA会将这个函数标记为库函数,并根据与其匹配的签名自动对它进行重命名。

警告:只有使用IDA哑名的函数才能被自动重命名。换言之,如果你已经对一个函数进行了重命名,而后这个函数与一个签名相匹配,那么,这时IDA不会再对这个函数进行重命名,因此,在分析过程中,应该尽可能早地应用签名。

如前所述,静态链接二进制文件模糊了应用程序代码与库代码之间的区别。如果你足够幸运,有一个没有去除符号的静态链接二进制文件,那么,你至少拥有有用的函数名(和可信赖的程序员创建的函数名一样有用)来帮助你对代码进行分类。但是,如果二进制文件已经被去除符号,那么,你拥有的只是数百个使用IDA生成名称的函数,并未注明这些函数的用途。在这两种情况下,只要拥有相关签名,IDA仍然能够识别出库函数(去除符号的二进制文件中的函数名称并不能为IDA提供足够的信息,使它准确判定一个函数是否为库函数)。如图12-2所示是一个静态链接二进制文件的“概况导航栏”。

12-2:没有签名的静态链接

在这个函数中,没有函数确定为库函数,因此,需要深入分析代码。在应用一组适当的签名后,概况导航栏如图12-3所示。

如你所见,“概况导航栏”证实了应用一组特殊签名所产生的效果。由于多数函数都找到与之匹配的签名,IDA将大部分的代码标记为库代码,并对它们进行了相应的重命名。在图12-3的例子中,特定于应用程序的代码很可能集中在导航栏窗口的最左边。

12-3:静态链接二进制文件应用的签名

在应用签名时,有两点值得注意:第一,即使是对一个尚未去除符号的二进制文件,签名仍然有用;这时,更多地是使用签名帮助IDA识别库函数,而不是对它们重命名;其次,静态链接二进制文件可能由几个单独的库组成,你需要对其应用几组签名才能完全识别所有的库函数。每应用一个签名,概况导航栏都会发生变化,以反映你发现的库代码。图12-4显示的就是这样一个例子。图中,你看到的是一个使用C标准库和OpenSSL[5]加密库静态链接的二进制文件。

12-4:应用前几个签名的静态二进制文件

具体来说,我们看到,在对二进制文件应用适当的OpenSSL签名后,IDA将一个窄小的代码带(地址范围左侧的浅色代码带)标记为了库代码。通常,要创建静态链接的二进制文件,首先应插入应用程序代码,然后附加所需的库,最终得到可执行文件。根据上图,我们可以得出结论:OpenSSL库的右侧很可能是其他的库代码,而应用程序代码则位于OpenSSL库左侧的一条非常窄小的代码带中。如果我们继续对图12-4中的二进制文件应用签名,最终的概况导航栏将如图12-5所示。

12-5:应用几组签名后的静态二进制文件

在这个例子中,我们应用了libclibcryptolibkrb5libresolv及其他库的签名。有时我们根据二进制文件中的字符串来选择签名。其他情况下,我们选择与二进制文件中已经确定的其他库关系密切的签名。最终,导航窗口会在导航带的右半部分显示一个深色的代码带,在导航带的最左边缘显示一个更小的深色代码带。要确定二进制文件中剩下的非库代码的性质,你需要进行更加深入的分析。在这个例子中,我们知道,右侧较宽的深色代码带是一种尚未识别的库,而左侧的深色代码带则为应用程序代码。

1.3 创建FLIRT签名文件

如前所述,IDA不可能自带现有的每一个静态库的签名文件。为了向IDA用户提供创建他们自己的签名所需的工具和信息,Hex-Rays开发了FLAIRFast Library Acquisition for Identification and Recognition—快速获取库的识别和鉴定)工具集,可从IDA发行的光盘上获得,授权用户也可从Hex-Rays网站[6]上下载。与IDA的另外几个附加件一样,FLAIR工具通过一个Zip文件发布。IDA 5.2版的FLAIR工具位于flair52.zip文件中。Hex-Rays不一定会为每一版本的IDA发布新的FLAIR工具,由此,只需使用不高于你的IDA版本的最新FLAlR工具即可。

安装FLAIR实用工具的过程非常简单,只需解压相关的Zip文件即可。尽管如此,我们仍建议创建一个专用的flair目录,因为Zip文件并不包含顶级目录。FLAIR文件解压后,你会看到FLAIR工具文挡资料的几个文本文件。其中特别有用的文件如下所示:

readme.txt

这是一个签名创建过程的总体概述。

plb.txt

说明静态库解析器plb.exe的用法。库解析器在X创建模式文件中详细讨论。

pat.txt

详细说明模式文件的格式;它是签名创建过程的第一步。在X创建模式文件中介绍模式文件。

sigmake.txt

说明使用sigmake.exe从模式文件生成sig文件的方法。请参阅Y创建签名文件了解详情。

其他目录包括bin目录,其中包括FLAIR工具的所有可执行文件和startup目录,后者包含与各种编译器及相关的输出文件类型(PEELF等)有关的常见启动顺序的模式文件。6.1版本之前,FLAIR所有工具只适用于Windows,但其生成的签名文件可以用在所有的IDA版本中(Windows、Linux和OS X)。

1.3.1    创建签名概述

创建签名文件的基本过程似乎并不复杂,可归结为四个看似简单的步骤:

1.    获得一个你希望为其创建签名文件的静态库副本。

2.    利用其中一个FLAIR解析器为该库创建一个模式文件。

3.    运行sigmake.exe来处理生成的模式文件,并生成签名文件。

4.    IDA中,将新签名文件复制到<IDADIR>/sig目录,安装此文件。

很遗憾,实际只有最后一个步骤较为简单。在下面几节中,我们将详细讨论前三个步骤。

1.3.2    识别和获取静态库

生成签名的第一个步骤,是确定一个你希望为其生成签名的静态库。由于各种原因,完成这个任务可能需要克服一些挑战。第一个挑战是确定你到底需要哪一个库。如果你足够幸运,你所分析的二进制文件并没有去除符号,那么,你的反汇编代码清单将显示真实的函数名称。这时,你只需要使用互联网搜索,就可以获得一些线索。

与未去除符号的二进制文件相比,已去除符号的二进制文件并不能为我们提供太大的帮助。缺乏函数名称的帮助时,使用strings进行搜索也可以得到足够特殊的字符串,以帮助你识别库,如下面的例子所示,从中你一眼就可以发现相关的库:

OpenSSL 1.0.0b-fips 16 Nov 2010

通常,版权声明和错误字符串已经足够特殊,当然,你同样可以使用互联网来缩小搜索范围。如果你选择从命令行中运行strings,一定要记得使用-a选项,迫使strings扫描整个二进制文件。否则,你可能会遗漏一些有用的字符串数据。

对开源库来说,你很可能会找到它们的源代码。不过,虽然源代码可以帮助你理解二进制文件的行为,但你不能使用它来为你生成签名。不过,你可以使用源代码创建你自己的静态库,然后使用这个库来生成签名。然而,创建过程中出现的变化很有可能会在生成的库与你分析的库之间造成相当大的差异,因此,你生成的签名也不十分准确。

当然,最好的办法还是确定你所分析的二进制文件的真实来源,即具体的操作系统、操作系统版本和发行版本(如果适用)。根据这些信息,创建签名的最佳方法是从一个配置完全相同的系统中复制相关的库。自然,这会导致下一个问题:对任意一个二进制文件来说,如何确定它到底是在什么系统上创建的?应对这个问题的第一个步骤:是使用file实用工具获得一些与该二进制文件有关的基本信息。在第2章中,我们看到了file工具的一些样本输出。有时候,这些输出足以帮助你确定可能的操作系统。下面的例子就是file文件的一个非常特殊的输出:

$ file sample_file_1

sample_file_1: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), statically linked, for FreeBSD 8.0 (800107), stripped

从这个例子中,我们可以迅速确定该文件使用的是FreeBSD8.0系统,并追踪到libc.a库。下面的例子更加复杂一些:

$ file  sample_file_2

sample_file_2: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux),

statically linked, for GNU/Linux 2.6.32, stripped

我们似乎将文件的来源缩小到了Linux系统,但由于Linux系统存在大量不同的版本,这对我们并没有太大的帮助。运行strings后,我们发现以下信息:

GCC: (GNU) 4.5.1 20100924 (Red Hat 4.5.1-4)

这时,搜索范围进一步缩小到Red Hat发行版(或派生版)自带的gcc 4.5.1版本。在使用gcc编译的二进制文件中,这种GCC标记并不少见。好在去除符号的过程中,它们并没有被删除,仍然可以被strings搜索到。

请记住,file实用工具并不是用于识别文件的决定性因素。下面的输出证实了一种简单的情况,在这种情况下,file似乎知道所分析文件的类型,但它的输出并无特殊之处。

$ file sample_file_3

sample_file_3: ELF  32-bit  LSB  executable,  Intel  80386, version  1 (SYSV), dynamically  linked  (uses  shared libs), stripped

这个例子取自Solaris 10 x86系统。这里,我们仍然可以使用strings实用工具来确定该系统。

1.3.3    创建模式文件

现在,你可能希望为一个或几个库创建签名。下一步是为每个库创建一个模式文件。模式文件是利用合适的FLAlR解析器实用工具创建的。和可执行文件一样,库文件也是基于各种文件格式规范而创建的。FLAIR为解析器提供几种通用的库文件格式。如FLAIRreadme.txt所述,你可以在FLAIRbin目录中找到以下解析器:

plb.exe/plb——OMF库的解析器(Borland编译器常用)

pcf.exe/pcf——COFF库的解析器(微软编译器常用)

pelf.exe/pelf—— ELF库的解析器(许多Unix系统常用)

ppsx.exe/ppsx—— 索尼PlayStation PSX的库解析器

ptmobj.exe/ptmobj——TriMedia库的解析器

pomf166.exe/pomf166——Kiel OMF 166对象文件的解析器

要为某个库创建一个模式文件,需要指定与库格式对应的解析器、希望解析的库名称、以及生成模式文件的名称。对于FreeBSD8.0系统中的libc.a库,你可以使用以下代码创建模式文件:

$ ./pelf libc.a  libc_FreeBSD80.pat

libc.a:  skipped 1,  total  1089

这里,解析器指出解析的文件(libc.a)、忽略的函数[7]的数量(1)及生成的签名模式的数量(1086)。每个解析器接受的命令行选项都略有不同,这些差异全部记录在该解析器的使用声明中。若执行解析器时不使用参数,这个解析器所接受的所有命令行选项将显示出来。plb.txt文件提供了有关plb解析器所接受选项的详细信息。这个文件中包含大量基本信息,因为它还描述了其他解析器接受的许多选项。多数情况下,仅仅指出被解析的库及将要生成的模式文件的名称就够了。

模式文件是一个文本文件,其中包含提取出、表示被解析库中函数的模式(每行显示一种模式)。前面创建模式文件中的几行模式如下所示:

57568B7C240C8B742410FC8B4C2414C1E902F3A775108B4C241483E103F3A675  1E A55D 003E :0000 _memcmp

0FBC442404740340C39031C0C3......................................  00 0000 000D :0000 _ffs

57538B7C240C8B4C2410FC31C083F90F7E1B89FAF7DA83E20389CB29D389D1F3  12 9E31 0032 :0000 _bzero

FLAIRpat.txt文件说明各个模式的格式。简单地说,模式的第一个部分列举了它所代表的函数的初始字节序列,最长为32个字节。一些字节因为重定位的入口而有所不同,这些字节将得到补偿,每个字节以两点显示。如果一个函数小于32个字节(例如前面代码中的_ffs函数),用点将模式填充到64[8]个字符。除32个初始字节外,模式中记录的其他信息专用于提高签名匹配过程的准确性。每个模式行中的其他信息包括由函数的某个部分计算得出的CRC16[9]值、函数的字节长度、以及函数引用的符号名称列表。一般来说,引用许多其他符号的函数越长,它生成的模式行就越复杂。在前面生成的libc_FreeBSD80.pat文件中,一些模式行的长度超过了20000个字符。

几名第三方程序员开发出了一些实用工具,可用于从现有的IDA数据库生成模式。其中一个实用工具为IDB_2_PAT[10],这个IDA插件由J.C.Roberts编写,它能够为现有数据库中的一个或多个函数生成模式。如果你想在其他数据库中遇到与现有数据库中函数的代码类似的代码,但却无法访问用于创建被分析的二进制文件的原始库文件,就可以用到这些实用工具。

1.3.4    创建签名文件

为某个库创建模式文件后,创建签名过程的下一个步骤,是生成一个适合IDA使用的.sig文件。IDA签名文件的格式与模式文件的格式截然不同。签名文件采用一种专用二进制格式,最大限度地减少呈现模式文件中的全部信息所需的空间数量,并且努力根据具体的数据库内容实现高效的签名匹配。Hex-Rays的网站[11]宏观介绍了签名文件的结构。

FLAIRsigmake实用工具用于从模式文件创建签名文件。由于模式与签名的生成划分成两个不同阶段,因此,签名生成过程完全独立于模式生成过程,这使我们可以使用第三方的模式生成工具。使用sigmake解析一个.pat文件并创建一个.sig文件,是生成签名的最简单方法,如下所示:

$ ./sigmake libssl.pat  libssl.sig

如果一切正常,将得到一个.sig文件,并将它安装到<IDADIR>/sig中。但是,很少能够顺序完成这个过程。

注:sigmake的文档文件sigmake.txt建议在给签名文件取名时,应遵循MS-DOS 8.3名称长度约定。这并不是一个强制性的要求。如果使用的文件名较长,则选择签名对话框仅显示文件名的前8个字符。

通常,因为在生成签名的过程中,你必须处理冲突,因此,这个过程是一个不断反复的过程。只要有两个函数的模式相同,就会发生冲突。如果不能解决冲突,在应用签名的过程中,我们就无法确定函数到底与哪一个签名相匹配。因此,sigmake必须能够将每一个生成的签名解析成一个函数名称。否则,如果一个或几个函数的模式完全相同,sigmake生成的不是.sig文件,而是一个排斥文件(.exc)。使用sigmake和一个(组)新的.pat文件,得到以下结果:

$ ./sigmake libc_FreeBSD80.pat libc_FreeBSD80.sig

libc_FreeBSD80.sig: modules/leaves: 1088/1024, COLLISIONS: 10

See the documentation to learn how to resolve collisions.

这里引用的文档资料为sigmake.txt,它描述了sigmake的用法及冲突解决过程。实际上,每次sigmake开始执行时,它都会搜索一个对应的排斥文件,以从中了解如何解决在处理指定的模式文件时遇到的任何冲突。如果没有这个排斥文件,在发生冲突时,sigmake会生成这样一个排斥文件,而不是签名文件。在上面的例子中,我们发现了一个名为libc_FreeBSD80.exc的新建文件。在创建之初,排斥文件是一个文本文件,它详细说明了sigmake在处理模式文件时遇到的冲突。你必须编辑排斥文件,以指导sigmake应如何解决任何相互冲突的模式。下面我们将讨论编辑排斥文件的一般过程。

sigmake生成的所有排斥文件均以下面几行开头:

;--------- (delete these  lines  to  allow  sigmake to  read this file)

; add '+'  at  the  start  of  a line to  select  a module

; add '-'  if you are not  sure about the  selection

; do nothing  if you want to  exclude all  modules

这些行的目的是告诉你如何解决冲突,成功生成签名。你需要做的头件大事,是删除四行以分号开始的行,否则,sigmake将无法在随后的执行过程中解析排斥文件。下一步是告诉sigmake你希望如何解决冲突。从libc FreeBSD80.exc中提取出的几行如下所示:

_index     00 0000 538B4424088A4C240C908A1838D974074084DB75F531C05BC3..............

_strchr    00 0000 538B4424088A4C240C908A1838D974074084DB75F531C05BC3..............

_rindex    00 0000 538B5424088A4C240C31C0908A1A38D9750289D04284DB75F35BC3..........

_strrchr  00 0000 538B5424088A4C240C31C0908A1A38D9750289D04284DB75F35BC3..........

_flsl     01 EF04 5531D289E58B450885C0741183F801B201740AD1E883C20183F80175F65D89D0

_fls  01 EF04 5531D289E58B450885C0741183F801B201740AD1E883C20183F80175F65D89D0

这些行详细说明了三个冲突:index函数很难与strchr函数区分开,rindex的签名与strrchr相间,flslfls相互冲突。如果你熟悉其中一些函数,对于上面的结果,你就不会觉得奇怪,因为相互冲突的函数基本上完全相同(例如,indexstrchr执行相同的操作)。

为了让你“掌握自己的命运”,在每组相互冲突的函数中,sigmake让你仅指定一个函数作为相关签名的匹配函数。任何时候,如果在数据库中发现一个对应的签名,并且你想应用一个函数的名称,那么,你可以在该函数名称前附加一个加号(+);如果你只想在数据库中添加某个函数的注释,则在该函数名称前附加一个减号(-);如果在数据库中发现对应的签名时,你不想应用任何名称,那么,你不需要添加任何符号。下面的代码为上面提到的三个冲突提供了一种可行的解决方案:

+_index  00 0000 538B4424088A4C240C908A1838D974074084DB75F531C05BC3..............

_strchr  00 0000 538B4424088A4C240C908A1838D974074084DB75F531C05BC3..............

_rindex  00 0000 538B5424088A4C240C31C0908A1A38D9750289D04284DB75F35BC3..........

_strrchr 00 0000 538B5424088A4C240C31C0908A1A38D9750289D04284DB75F35BC3..........

_flsl    01 EF04 5531D289E58B450885C0741183F801B201740AD1E883C20183F80175F65D89D0

-_fls    01 EF04 5531D289E58B450885C0741183F801B201740AD1E883C20183F80175F65D89D0

在这个代码段中,我们决定,在数据库中发现第一个签名时,使用函数名index;发现第二个签名时,不做任何处理;发现第三个签名时,在数据库中添加一段有关fls的注释。在解决冲突时,请记住以下要点。

1. 为最大限度地减少冲突,请删除排斥文件开头的四个注释行。

2. 最多只能给冲突函数组中的一函数附加+/-

3. 如果一个冲突函数组仅包含一个函数,不要在该函数前附加+/-,让它保持原状即可。

4. sigmake连续运行失败会将包括注释行的数据附加到现有的任何排斥文件后。再次运行sigmake之前,必须删除这些附加数据,并更正原始数据(如果这些数据正确,sigmake将不会再次运行失败)。

更改排斥文件后,你必须保存这个文件,并使用你最初使用的命令行参数重新运行sigmake。这一次,sigmake应该能够定位和遵照你的排斥文件,并成功生成一个.sig文件。如果IDA没有显示错误消息,则表示sigmake操作成功并生成.sig文件,如下所示:

$ ./sigmake libc_FreeBSD80.pat libc_FreeBSD80.sig

成功生成签名文件后,你需要将它复制到<IDADIR>/sig目录中,以便IDA使用这个文件。随后,你可以通过File>Load Fi1e>FLlRT Signature File访问这个新签名。

需要注意的是,我们有意隐藏了所有可应用于模式生成工具和sigmake的选项。有关可选项的完整列表,请参阅plb.txt和sigmake.txt文件。这里我们仅介绍sigmake的-n选项,它用于在一个生成的签名文件中植入一个描述性的名称。这个名称将在选择签名的过程中显示(见图12-1),并可在对签名排序时提供极大的帮助。下面的命令行将名称字符串“FreeBSD8.0 C standard library”植入到生成的签名文件中:

$ ./sigmake -n"FreeBSD 8.0 C standard library" libc_FreeBSD80.pat libc_FreeBSD80.sig

另外,你还可以使用排斥文件中的指令指定库名称。但是,并不是所有生成签名的过程都会需要排斥文件,因此,使用命令行的方法更加有用。有关详细信息,请参考sigrnake.txt

1.3.5    启动签名

IDA还能够识别一种特殊的签名,即启动签名(startup signature)。在初次将一个二进制文件加载到数据库中,确定用于创建该二进制文件的编译器时,IDA将应用启动签名。如果IDA能够确定用于构建一个二进制文件的编译器,那在初步分析这个二进制文件的过程中,IDA会自动加载与已确定的编译器有关的其他签名文件。

由于在初次加载文件时,编译器类型并不知道,IDA根据所加载的二进制类型来分类和选择启动签名。例如,如果加载的是WindowsPE二进制文件,那么,IDA会加载与PE二进制文件有关的启动签名,以确定用于构建该PE二进制文件的编译器。

要生成启动签名,sigmake将处理描述各种编译器生成启动例程[12]的模式,并把得到的签名组合到一个特定于类型的签名文件中。FLAIR工具的startup目录中包含IDA使用的启动模式,以及用于从这些模式创建对应的启动签名的脚本—startup.bat。请参阅startup.bat了解使用sigmake创建某一特定文件格式的启动签名的示例。

PE文件而言,你会在startup目录中发现几个pe_*.pat文件,这些文件描述的是一些常用的Windows编译器所使用的启动模式,如描述Visua1 Studio模式的pe_vc.pat文件和描述Cygwin/gcc模式的pe_gcc.pat文件。如果你希望添加PE文件的其他启动模式,必须将它们添加到一个现有的PE模式文件中,或创建一个名称以pe_开头的新模式文件,以方便生成启动签名的脚本找到你的模式,并将它们合并到新生成的PE签名中。

最后,你还需要注意启动模式的格式,它与为库函数生成模式的格式稍有不同。其不同在于:启动模式行能够将启动模式与其他签名关联起来,在对启动模式进行匹配时,IDA还会应用这些签名。除startup目录中保存的示例启动模式外,FLALR中的任何文本文件都没有记录启动模式的格式。

1.4 小结

库代码自动识别是一个重要功能,它明显减少了分析静态链接二进制文件所需的时间。利用它的FLRITFLAIR功能,用户可从现有的静态库创建自己的库签名,它不仅使自动代码识别成为可能,而且使它具有了可扩展性。对任何可能遇到静态链接二进制文件的用户而言,了解如何生成签名是一项基本的技能。



[1]在自动处理新加载的二进制文件之后,IDA在输出窗口中生成“The initial autoanalysis has been finished.”这条消息。

[2]请参阅http://www.hex-rays.com/idapro/flirt.htm。

[3]在第2章讨论了strings命令,而head命令用于只查看其输入源代码的前几行(这里为3行)。

[4] libc.aUnix风格的系统上的静态链接二进制文件所使用的C标准库。

[5] 请参见http://www.openssl.org/。

[6]目前的版本是flair61.zip,下载地址:http://www.hex-rays.com/idapro/ida/flair61.zip。Hex-Rays所提供的下载,需要输入用户名和密码。

[7] plbpcf可能会根据提供给解析器的命令行选项及被解析库的结构,忽略一些函数。

[8] 每个字节需要两个字符。要显示32个字节的内容,需要64个十六进制字符。

[9] 这是一个16位循环冗余校验值。生成模式时使用的CRC16实现包含在FLAIR工具光盘的crcl6.cpp文件中。

[10] 参见http://www.openrce.org/downloads/details/26/IDB_2_PAT

[11] 参见http://www.hex-rays.com/idapro/flirt.htm

[12]通常,启动例程被视为程序的入口点。在C/C++程序中,启动例程用于在将控制权转交给main函数之前对程序的环境进行初始化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值