在不调试正在运行的程序的情况下确定对象的内存布局?

时间:2012-08-12 00:27:33

标签: c++ reverse-engineering ida

我正在为一个程序进行逆向工程。我正在使用IDA Pro和Hex-Rays Decompiler。我遇到了大量的代码,我知道有一个对象,并且对象上有一个方法调用,但它以一种我无法弄清楚的方式显示出来。例如:

 if ( (*(*interfacePtr + 24))(interfacePtr, &v23) >= 0 )

我在这里知道interfacePtr指向ICLRRuntimeHost对象。 (C ++,.NET CLR运行时)但是......我不知道*(* interfacePtr + 24)是什么。我可以告诉它这是一种方法,但我如何弄清楚什么是+24?

2 个答案:

答案 0 :(得分:2)

类的vtable只是函数指针的列表。它包含每个虚函数的一个指针,顺序为:非常非常顶级的基类,下一个基类,它的子类,。 。 。大多数派生类。

示例:

struct A {
    virtual ~A() {}
    virtual void foo() = 0;
}
struct B : public A {
    virtual void foo() { // do something }
    virtual void bar() { // do something else }
}

B的vtable将按以下顺序包含:

  • 〜A
  • FOO

(A的那些必须先到,所以相同的vtable可以被具有类型A的指针的代码部分用于该对象;该代码不知道底层对象是否真的是B 。)

如果您正在查看32位源,指针是4个字节,那么24 = 4 * 6,您正在查看第7个虚函数(索引从0开始)。如果你是64位,指针是8个字节,所以24 = 8 * 3,你正在寻找第4个。实际上,我没有使用IDA“转换为C ++”功能,所以24可能实际上是表中的第24个条目。

简单的确认方法:编写自己的程序。声明ICLRRuntimeHost类型的变量。调用你怀疑的函数(基于查看头文件并计数到7或4,取决于位数,或24,如果我误解了你的例子)。查看生成的汇编代码,并确认您的索引是否正确。 (在这种事情上我总是一个人,所以这将提供一个检查。)

答案 1 :(得分:0)

查看ICLRRuntimeHostVtbl

ICLRRuntimeHostVtblmscoree.h的定义

粗略地翻译成hexrays会理解的东西,它们看起来像这样:

struct ICLRRuntimeHost {
    ICLRRuntimeHostVtbl *vtbl;
};
struct ICLRRuntimeHostVtbl {
    _DWORD (*QueryInterface)(ICLRRuntimeHost*, _DWORD*, void**);
    _DWORD (*AddRef)(ICLRRuntimeHost*);
    _DWORD (*Release)(ICLRRuntimeHost*);
    _DWORD (*Start)(ICLRRuntimeHost*);
    _DWORD (*Stop)(ICLRRuntimeHost*);
    _DWORD (*SetHostControl)(ICLRRuntimeHost*, void*);
    _DWORD (*GetCLRControl)(ICLRRuntimeHost*, void**);
};

您的变量interfacePtr应该具有类型:ICLRRuntimeHost,那么您的代码应该像这样反编译:

interfacePtr->GetCLRControl(&v23);