Consider the following code:
In 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();
}
In IDA (inside someFunction
):
mov ecx, dword_XXXX ; ecx = globalPointer
mov eax, [ecx] ; eax = vtable
jmp dword ptr [eax+30h] ; call vtable[0x30]
The meaning of dword_XXXX
is just a pointer value. I tried to check it this way:
printf("Address of pointer = %p, pointer's value = %p\n", &otherPointer, otherPointer);
And I got:
push dword_XXXX ; otherPointer
push offset dword_XXXX ; &otherPointer
push offset format ; "Address of pointer = %p, pointer's value = %p\n"
call printf
Thus dword_XXXX
seems to be a pointer's value and offset dword_XXXX
seems to be an address of the pointer.
However, I noticed another code (which can be expressed the same as the c++ function I provided above):
SomeClass2* globalPointer2;
void someFunction2()
{
globalPointer2->someVirtualFunction2();
}
And IDA surprisingly gave me (inside 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]
I checked the values and found out that IDA somehow "changes" the meaning of dword_XXXX
, in this case it actually was:
mov eax, dword_XXXX ; eax = vtable
mov ecx, offset dword_XXXX ; ecx = globalPointer2
jmp dword ptr [eax+5Ch] ; call vtable[0x5C]
Why the meaning of dword_XXXX
was different in the second case? In the first case it was just pointer
, but in the second case it was *pointer
.
And the meaning of offset dword_XXXX
in the first case was &pointer
and in the second case was pointer
.
I'm sorry if something is unclear, I really tried to simplify that as much as possible.