首页
社区
课程
招聘
[原创]库快速识别和鉴定技术在PRX文件分析中的应用
发表于: 2012-6-26 17:02 3732

[原创]库快速识别和鉴定技术在PRX文件分析中的应用

2012-6-26 17:02
3732

要发3个帖子,才能买邀请码。转下以前写的吧。
a7bK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3u0D9L8$3N6Q4x3X3g2U0M7$3c8F1i4K6u0W2L8X3g2@1i4K6u0r3K9X3g2J5M7Y4W2#2N6s2y4U0L8W2)9J5c8X3q4J5N6r3W2U0L8r3g2Q4x3V1k6V1k6i4c8S2K9h3I4K6i4K6u0r3y4U0M7I4x3U0j5J5y4R3`.`.
库快速识别和鉴定技术在PRX文件分析中的应用

        在着手对二进制文件进行逆向分析时,你最不应该做的事情是浪费时间在分析那些只需要阅读一本手册、一段源代码或搜索一下互联网就可以轻易了解其行为的库函数。静态链接所造成的问题是应用程序代码于库代码之间的区别很模糊。在静态链接的二进制文件中,所有库与应用程序代码混杂在一起,组成了一个庞大的可执行文件。

        库快速识别和鉴定技术,简称FLIRT,是IDA用于识别库代码的一组技术,FLIRT的核心是各种模式匹配算法,这些算法使IDA能够快速确定:一个经过反汇编的函数是否与IDA已知的许多签名中的某一个相匹配。

《IDAPro权威指南》第12章

IDAPro权威指南同时提到不同的库代码、不同的编译器版本以及不同的编译参数导致生成的库是不一样的,所以只有在上面3者完全相同的情况下,我们才能得到一份确定的库文件。这也是IDA中没有提供开源环境下的库签名的原因。

所以如果你知道这个prx是在什么环境上生成的,那只需要找到对应的静态库,通过下面5个步骤,就可以生成签名文件。

1.        pelf.exe libg.a psp.pat

2.        pelf.exe -a libm.a psp.pat

3.        sigmake.exe -n"psp" xxx.patpsp.sig

4.        修改psp.exc,解决冲突的样式

5.        sigmake.exe -xpsp.exc -n"psp"psp.pat psp.sig

然后将psp.sig复制到D:\Program Files\IDA61\sig\mips目录下。在IDA加载完该prx后,通过View-> Open Subviews -> Signatures或者File -> LoadFile -> FLIRT Signature File,来选择你的签名就可以了。

但问题在于有时候你根本无法得知该prx是在什么环境下编译的,这时可以尝试查找参考串,例如可能会看到下面这样的信息:

MW MIPS C Compiler (2.4.1.01)

GCC: (GNU) 4.0.4+allegrex-2.2.3-psp-2.9.0

GCC: (GNU) 3.3.6+allegrex-2.2.2-psp-1.18.0

GCC: (GNU) 3.3.3+allegrex-2.2.2-psp-1.7.1

但可能什么都没有找到,这也非常正常,因为上面列出来的只是其中的一部分环境,或者在生成prx的时候删除了这些串信息。假设通过一些办法最终知道采用了什么环境编译,紧接着的一个问题就是如何来获得对应的静态库文件。如果能获得的话,那是最理想的情况,如果不行的话,我们就要想别的方法。

放在flair工具包里的pat.txt文件描述了样式信息的组织格式。仔细分析后我们发现,一个用来产生样式的elf文件,最基本的条件,就是需要知道代码中哪些字节是会变化的,这个通过可以通过对重定位的分析来完成。另一个比较重要的条件就是需要知道函数名,这个从符号表中获取,要不然我们就只能识别出“这是一个库函数”,没有名字就很难猜测他的真正用途。

所以说,如果可以找到一个有符号表的prx文件,我们就可以产生他的签名,如果再碰到在相同的环境下生成的prx,就可以用该签名对库函数进行识别。

通过对近百个游戏进行分析,最后发现了ULJM-05151。他的EBOOT是一个具有符号表,在MW MIPS C Compiler (2.4.1.01)环境上生成的prx。

有了前面这些条件,下面就看如何来实现了。

如果直接使用pelf.exe,就会看到下面的信息:

Warning [EBOOT.BIN] (): non-relocatable elfmodule, skipped

这是因为prx采用非标准的重定位的方法。参考前面的《PRX loader for IDA》

866K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3u0D9L8$3N6Q4x3X3g2U0M7$3c8F1i4K6u0W2L8X3g2@1i4K6u0r3K9X3g2J5M7Y4W2#2N6s2y4U0L8W2)9J5c8X3q4J5N6r3W2U0L8r3g2Q4x3V1k6V1k6i4c8S2K9h3I4K6i4K6u0r3y4U0M7I4x3U0j5J5y4R3`.`.

于是要重写一个类似于pelf的工具。

这里有一些可参考的资源:

0c9K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6i4N6G2L8$3c8E0j5h3&6F1i4K6u0W2j5$3!0E0i4K6u0r3k6Y4u0S2N6X3W2S2i4K6u0r3M7Y4m8S2N6q4)9J5k6r3g2F1i4K6u0W2K9s2c8E0L8l9`.`.

52bK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3!0H3k6h3&6J5j5$3g2Q4x3X3g2G2M7X3N6Q4x3V1k6V1L8%4N6F1L8r3!0S2k6s2y4Q4x3V1k6V1k6i4c8S2K9h3I4K6i4K6u0r3x3U0k6Q4x3V1k6A6k6r3u0Q4y4h3j5J5i4K6g2X3M7r3q4@1

因为一个用到了bfd库,一个需要IDA的支持。加上pat.txt文件对一些细节并没有详细的实现说明,于是最终从pelf.exe中来找出这些答案。

从pelf的实现来看,非常有意思:

产生样式信息的最小单位是elf文件中的每个section,也就是说如果一个目标文件里有多个实现函数,当这些函数被放在一个text段时,就产生一行样式信息。这样做是因为在链接的过程中最小的处理单位是单个目标文件,即使只用到其中的一个函数,整个目标文件会出现在最终的程序里。如果这些函数在多个text里,那么就会产生多行样式信息。

用来标记可变化字节的方法是:复制一份和代码段长度相同的数据,先memset成1,如果重定位段标志哪些地址在连接的过程中需要针对实际情况进行修改,就将对应的数据清0。

pelf中指出了只指出哪些架构,其实并不需要像反汇编那样知道具体的机器指令的含义,主要是因为不同的架构对重定位信息的理解不一样。当然也需要考虑到不同的架构使用了不同的字节序。

针对我们从prx产生样式的情况,需要注意的是:

我们无法界定最小的链接单位,所以这里使用了函数作为最小的样式产生单位。

跳过对.sceStub.text段的处理,因为里面的函数名可以通过NID获取,而且这些函数会产生一样的样式,对识别没有帮助。

解析符号表时,发现符号的放置顺序并不是按照地址大小顺序存放的,需要排序。

在处理重定位信息时,无法从REL信息中获得对应交叉引用的符号名称,需要解析指令,计算出交叉引用的地址,找到对应的符号名。

要知道更多的细节就需要阅读代码了。

放在:

42bK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3c8G2N6$3&6D9L8$3q4V1i4K6u0W2j5%4y4V1L8W2)9J5k6h3&6W2N6q4)9J5c8Y4y4G2N6i4u0U0k6g2)9J5c8U0x3#2y4K6f1K6y4K6l9`.

参考资料:

l  6ecK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3S2W2P5q4)9J5k6s2u0S2P5i4y4Q4x3X3g2U0L8$3#2Q4x3V1k6A6k6r3q4H3M7X3!0Q4x3V1k6X3L8r3W2J5N6q4)9J5k6h3S2@1L8b7`.`.

l  pat.txt

l  pelf.exe

l  IDAPro权威指南


[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 6
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回