考虑以下代码:
在 C++ 中:
SomeClass* globalPointer; // we don't know what it points to, but it's not null a pointer, it's initialized
void someFunction()
{
globalPointer->someVirtualFunction();
}
在 IDA(内部someFunction
)中:
mov ecx, dword_XXXX ; ecx = globalPointer
mov eax, [ecx] ; eax = vtable
jmp dword ptr [eax+30h] ; call vtable[0x30]
的含义dword_XXXX
只是一个指针值。我试图以这种方式检查它:
printf("Address of pointer = %p, pointer's value = %p\n", &otherPointer, otherPointer);
我得到了:
push dword_XXXX ; otherPointer
push offset dword_XXXX ; &otherPointer
push offset format ; "Address of pointer = %p, pointer's value = %p\n"
call printf
因此dword_XXXX
似乎是一个指针的值,offset dword_XXXX
似乎是一个指针的地址。
但是,我注意到另一个代码(可以与我上面提供的 c++ 函数表示相同):
SomeClass2* globalPointer2;
void someFunction2()
{
globalPointer2->someVirtualFunction2();
}
IDA 出人意料地给了我(里面someFunction2
):
mov eax, dword_XXXX ; eax = globalPointer2
mov ecx, offset dword_XXXX ; ecx = &globalPointer2
jmp dword ptr [eax+5Ch] ; call [globalPointer2+0x5C] with &globalPointer2 as this?? It should be call vtable[0x5C]
我检查了这些值,发现 IDA 以某种方式“改变”了 的含义dword_XXXX
,在这种情况下,它实际上是:
mov eax, dword_XXXX ; eax = vtable
mov ecx, offset dword_XXXX ; ecx = globalPointer2
jmp dword ptr [eax+5Ch] ; call vtable[0x5C]
为什么dword_XXXX
在第二种情况下的含义不同?在第一种情况下它只是pointer
,但在第二种情况下它是*pointer
。
offset dword_XXXX
在第一种情况下的含义是&pointer
,在第二种情况下是pointer
。
如果有不清楚的地方,我很抱歉,我真的试图尽可能地简化它。