使用bindiff恢复静态连接应用的符号表

还欠好几篇没发,刚好最近在搞某款手机,发现里面一个用c写的deamon进程,基本没有符号,比如open/read/strlen都没有,看起来很蛋疼。于是想办法恢复一下符号表,借助android里的libc.so,很快就可以完成,错误率还ok。

工具:IDA,IDA插件bindiff。

我使用的是IDA6.95,后者在这里下载https://www.zynamics.com/software.html

安装好之后,在IDA的Edit - Plugins - Bindiff4.3处可以使用插件。

先从手机里拉出这个binary和libc.so,刚好这两个都是arm64的。

看一眼function,哇,一滩糊糊。。。

放那里等解析完成,存好example.i64文件,同样libc.so也生成libc.i64文件。

接下来关闭除了libc.i64之外的所有的ida窗口,点击 Edit - plugins - Bindiff,在弹出的框框里选择之前的example.i64文件,确认后等解析完成。

主要关注这个窗口即可,按照可信度和相似度进行排序的,绿色的还算靠谱,反正差不多够我们用就行。

但这里有个很蛋疼的东西,需要人工去手动命名掉那些函数,研究了半天没发现有导出按钮,于是连续选中较为可信的条目,粘贴到文本文件“/tmp/diff.log”里,写个脚本处理一下,也不难,正常操作,每行的文本刚好触发2次正则,第一次是libc里的函数名和地址,第二次是example里的函数名和地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import idc, idaapi
import re

__author__ = "LeadroyaL"

data=[]
fd = open('/tmp/diff.log')
while True:
line = fd.readline()
if line == '':
break
data.append(line)
fd.close()

pattern = re.compile(r"(0000[dA-F]+) ([_A-Za-z0-9]+)")

ms=[]
for d in data:
ms.append(pattern.findall(d))

for m in ms:
if len(m) != 2:
print m, "Error"
ms.remove(m)

succ_count = 0
for m in ms:
unk_addr=int(m[1][0], 16)
sym_name=m[0][1]
if "sub_" in sym_name:
continue
if MakeName(unk_addr, sym_name):
succ_count += 1

print "Rename %d function" % succ_count

期间可能会报同名函数的错误,其他错误暂时没有发现。

例如这一条记录:

1
1.00 0.99 ------- 000000000004A2D0 time       00000000000AAAA sub_AAAA        edges flowgraph MD index                             5     5     5     16     16     16     6     6     6

被正则后:

[('000000000004A2D0', 'time'), ('00000000000AAAA', 'sub_AAAA')],

用python将0xAAAA位置的函数命名为time即可。

成功后如图所示

完美!但是不要高兴太早,这里面有些判断的是错误的,如果感觉逻辑有问题,记得手动去check一下。

开个GitHub repo,欢迎提意见233333 https://github.com/LeadroyaL/StaticSymbolRepair