想逆向一个c++ so文件,请人先反汇编出伪代码,拿到c文件就是自己慢慢分析了。可以确定的是这个so文件中用到了一个开源库代码,包含有大量虚函数。伪代码中调用虚函数的地方都是对象地址加偏移地址,想要知道到底是调用哪个虚函数,只能根据这个偏移地址去ida反汇编的vtable中查询,然后就可以知道它是调用哪个函数。
只是我感觉这个过程太没有效率了,本身ida搜索就慢,找到vtable头就要费一段时间,然后根据偏移量进行计算,再定位到对应的地址,慢死了。祭起google也没发现什么好办法。
想了一个笨办法来加速这个过程,就是把常用的类的vtable提取出来保存到txt文件中,把偏移量都计算出来,以后每次查询时根据类名和偏移量就可以得到虚函数名了,这个在Sublime Text中搜索很快的。
vtable数据会是这个样子的:
.data.rel.ro:004EF040 ; `vtable for'st3d::TestClass
.data.rel.ro:004EF040 _ZTVN7st3d17TestClassE DCB 0
.data.rel.ro:004EF040 ; DATA XREF: st3d::TestClass::~TestClass()+8 o
.data.rel.ro:004EF040 ; st3d::TestClass::TestClass(void)+10 o ...
.data.rel.ro:004EF041 DCB 0
.data.rel.ro:004EF042 DCB 0
.data.rel.ro:004EF043 DCB 0
.data.rel.ro:004EF044 DCD _ZTIN7st3d17TestClassE ; `typeinfo for'st3d::TestClass
.data.rel.ro:004EF048 DCD _ZN7st3d9CCInfo12getInfoEPNS_6FlagE+1
.data.rel.ro:004EF04C DCD _ZN7st3d17TestClassD2Ev+1
其中typeinfo for的下一行地址就是首地址了,以这个首地址为基准,分别计算其后各行的偏移地址。这个时候python就派上用场了,我也是边学边写,七拼八凑终得下面的代码:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
encoding = 'UTF-8'
import re
import sys
import urllib
f = open("virtualFunc.txt", 'r')
t = open("result.txt", 'w+');
hexRegrex = re.compile('ro:([A-Z0-9]{8})')
typeInfoRegrex = re.compile('typeinfo for')
line = f.readline();
count = 0;
addrBase = 0;
isStart = 0;
while line:
count = count + 1;
addr = hexRegrex.search(line);
strAddr = addr.group(1);
if 0 == isStart:
resultTypeInfo = typeInfoRegrex.search(line);
if resultTypeInfo:
isStart = 1;
t.writelines(line);
line = f.readline();
continue;
if 0 == addrBase:
addrBase = int(strAddr, 16);
if count == 8:
addrBase = int(strAddr, 16);
addrDec = int(strAddr, 16);
diff = addrDec - addrBase;
sign = "";
if diff>=0:
sign = " + ";
b = hexRegrex.sub(strAddr + sign + str(diff),line)
t.writelines(b);
line = f.readline();
f.close();
t.close();
print "finished!"