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

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

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

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

最佳答案 类的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,如果我误解了你的例子).查看生成的汇编代码,并确认您的索引是否正确. (在这种事情上,我总是一个人离开,所以这将提供一个检查.)

点赞