Reputation: 3625
First of all - I apologize if this question shows ignorance or I'm not aware of something. I'm trying to do something that involves reading the instructions under a function's address and I've already managed to get function's generated code size by examining the .pdb file generated by the compiler.
But there is something that confuses me, look at the following example:
int function(int a, int b)
{
return a + b;
}
int main(int argc, char* argv[])
{
// (...)
void* address = &function;
function(10, 20);
// (...)
}
For a particular run under a debugger I've got 0x00c011f4 stored in void* address and VS's dissassembly window was showing accordingly:
int main(int argc, char* argv[])
{
00C04B00 push ebp
00C04B01 mov ebp,esp
00C04B03 sub esp,178h
00C04B09 push ebx
00C04B0A push esi
00C04B0B push edi
00C04B0C lea edi,[ebp-178h]
00C04B12 mov ecx,5Eh
00C04B17 mov eax,0CCCCCCCCh
00C04B1C rep stos dword ptr es:[edi]
void* address = &function;
00C04B1E mov dword ptr [address],offset function (0C011F4h)
function(10, 20);
00C04B25 push 14h
00C04B27 push 0Ah
00C04B29 call function (0C011F4h)
00C04B2E add esp,8
According to the instruction under 00C04B1E, the address that corresponds to the beginning of function
is under 0C011F4 - which is exactly what gets stored in void* address.
Now stepping through with the debugger and following the jump to function(int, int) gives me the following disassembly:
int function(int a, int b)
{
00C019C0 push ebp
00C019C1 mov ebp,esp
00C019C3 sub esp,0C0h
00C019C9 push ebx
00C019CA push esi
00C019CB push edi
00C019CC lea edi,[ebp-0C0h]
00C019D2 mov ecx,30h
00C019D7 mov eax,0CCCCCCCCh
00C019DC rep stos dword ptr es:[edi]
return a + b;
00C019DE mov eax,dword ptr [a]
00C019E1 add eax,dword ptr [b]
}
00C019E4 pop edi
00C019E5 pop esi
00C019E6 pop ebx
00C019E7 mov esp,ebp
00C019E9 pop ebp
00C019EA ret
Here the begging of function(int, int) is under 0x00C019C0. Why is that? that's 1996 bytes apart. I've tried to find any correlation but I think that I'm missing something fundamental here. Could someone please tell me why these two addresses are different?
Also when I copy the area pointed by void* address (0C011F4) I don't get the machine code that corresponds to the asm instructions that are under function(int, int).
Thanks in advance!
Env: Windows x64, VC10
Upvotes: 2
Views: 521
Reputation: 26171
This is cause you have compiled the binary in Debug mode, causing MSVC to put an intermediary jump between the call and the actual function (for use by Edit & Continue). So the address that you are getting (and the assembly) is the address of the jump that points to your function.
You can remove this by either using release mode or disabling Edit & Continue. Alternatively you can take the long route and just disassemble the jump (it should be a 32-bit relative jump), and adjust the address using the relative displacement the jump would you.
Upvotes: 4