函数签名

radare2有自己的签名格式,可以在创建时即时地进行加载/应用。这些命令存在于z命令空间下:

[0x00000000]> z?
Usage: z[*j-aof/cs] [args]   # Manage zignatures
| z            show zignatures
| z.           find matching zignatures in current offset
| zb[?][n=5]   search for best match
| z*           show zignatures in radare format
| zq           show zignatures in quiet mode
| zj           show zignatures in json format
| zk           show zignatures in sdb format
| z-zignature  delete zignature
| z-*          delete all zignatures
| za[?]        add zignature
| zg           generate zignatures (alias for zaF)
| zo[?]        manage zignature files
| zf[?]        manage FLIRT signatures
| z/[?]        search zignatures
| zc[?]        compare current zignspace zignatures with another one
| zs[?]        manage zignspaces
| zi           show zignatures matching information

需要使用zo命令从SDB文件中加载签名然后创建签名,如果SDB文件经过压缩,则需要使用zoz命令。

创建签名前首先要创建函数,之后可以通过函数创建它:

可以看到,它从entry0函数中创建了一个名为entry的签名。此外你可以以JSON格式显示结果,JSON格式的结果在能够用于脚本之中:

使用z-entry可以移除签名。

如果想保存所有的签名,可以用zos myentry将签名存入SDB文件中。

之后可以加载该文件并应用之,首先重新打开一个文件:

这些消息代表成功得从myentry文件里加载签名,而且可以通过搜索找到对应函数:

注意z.命令仅仅对照当前的地址搜索签名,如果想要在全文件中进行签名搜索则需要一些不同的操作。 底下展示的是一个重要时刻,当我们试图搜索签名时 -- r2却找不到任何东西:

这是由于搜索地址配置的原因,我们需要先调整搜索的范围:

我们将搜索模式设置为io.section(默认的是file)用于在当前节区进行搜索(假设我们目前所处的位置是.text节区)。 现在来看看radare2为我们找到了什么信息:

现在我们看到了entry0的注释,其是在ELF解析阶段时添加的,同时还有一个sign.bytes.entry_0,它正是签名匹配的结果。

签名配置在zign.配置变量空间中:

寻找最佳匹配 zb

常常你知道二进制文件中存在一个签名,但是z/z.都无法找到。这通常是因为签名和函数之间的差异非常小导致的,有可能是编译器交换了两条指令,或者你搜索的签名对于该版本的函数并不适用。 在此情景下,zb命令能够帮你指向相似的匹配位置。

zb(zign best)命令会展示5个与函数最相近的签名,每个签名都会有一个打分,分值从1.0到0.0不等。

在上面那个例子里,zb正确地将sym.fclose签名与当前函数相关联,而z/z.命令则无法发现,这是因为其Byte和Graph的分值都小于1.0。 第一相近结果和第二相近结果之间30%的偏差度也意味着第一个结果是个正确的匹配。

zbr(zign best reverse)接受一个签名作为参数,然后找到最相近的匹配函数。在此之前记得先用aa发现函数。

最后更新于

这有帮助吗?