我正在尝试以这种方式获取 main() 函数的地址:
int main(int argc, char *argv[])
{
void *pMainAddress=(void *)&main;
printf("Address of main() 0x%08X \n", pMainAddress);
当我使用Release配置构建项目时,结果是:
main() 地址:0x00401000
这是在调试器下:
00401000 /$ 68 00104000 PUSH GetMain.00401000 ; Entry address
00401005 |. 68 50A14000 PUSH GetMain.0040A150 ; ASCII "0x%p \n"
0040100A |. E8 8B000000 CALL GetMain.0040109A
但是当使用/Zi选项编译或使用Debug构建时,地址被重定向:
地址 main() : 0x0041178A
。这个地址是通过无条件跳转获得的,实际地址是0x00412530
这是在调试器下:
00412530 /> \55 PUSH EBP
...
00412539 |. C745 FC 8A174100 MOV [LOCAL.1],GetMain.0041178A ; Entry address
00412540 |. 8B45 FC MOV EAX,[LOCAL.1]
00412543 |. 50 PUSH EAX
00412544 |. 68 5CEC4200 PUSH GetMain.0042EC5C ; ASCII "0x%p \n"
为什么会这样?如果代码是在 Debug build 中编译的,
如何获取 main() 函数的真实地址(在上面的例子中)?0x00412530
编辑:
为什么会这样?已经在这里回答了:奇怪的函数调用间接级别
下面的函数解决了我的第二个问题,这里我写了 answer 。
void *GetMainAddress(void)
{
void *pMainAddress=(void*)&main;/* address in main() function */
unsigned long calculateJump=0;
unsigned char *ptrJump;
printf("Address of main() : 0x%08X\n", pMainAddress);
ptrJump=(unsigned char*)pMainAddress;/* get pointer to main address */
if(*(unsigned char*)ptrJump == 0xE9)/* address point to jmp opcode ? */
{
calculateJump = ( *(unsigned long *)(ptrJump+1) ); /* get address after 0xe9 */
pMainAddress = ptrJump + calculateJump + 5; /* calculate real address */
printf("Unconditional jump is performed\n");
printf("Actual sddress of main() is: 0x%08X \n", pMainAddress);
}
else
{
printf("Unconditional jump is not performed\n");
}
return pMainAddress;
}