4

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

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

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

4

2 回答 2

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 的那些必须先出现,以便具有指向该对象的 A 类型指针的部分代码可以使用相同的 vtable;该代码不知道底层对象实际上是 B。)

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

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

于 2012-08-12T04:53:42.217 回答
0

看看 和ICLRRuntimeHostVtblICLRRuntimeHostVtbl定义mscoree.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);
于 2012-09-12T08:14:35.113 回答