c++逆向之找出被调用的虚函数名字

想逆向一个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()+8o
.data.rel.ro:004EF040                                         ; st3d::TestClass::TestClass(void)+10o ...
.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!"




你可能感兴趣的:(c++逆向之找出被调用的虚函数名字)