想逆向一个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!"