我试图以这种方式获取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
。
通过执行unconditional jump获取此地址,实际地址为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"
为什么这个hapenes?
如果在Debug构建中编译代码,如何获取main()函数(上例中的0x00412530
)的真实地址?
修改
为什么会这样?已在此处回答:strange level of indirection of a function call
下面的函数解决了我的第二个问题,Here我写了答案。
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;
}
答案 0 :(得分:3)
如果需要获取函数地址,请省略括号。
例如:
int main(){
printf("main is at %p\n", main);
return 0;
}
答案 1 :(得分:0)
这是一个解决方案,当在Visual Studio的项目配置中将Debug Information Format设置为main()
时,如何获取/ZI
函数的实际地址。
这是我的功能:
void *GetMainAddress(void)
{
void* pMainAddress = (void*)&main;
unsigned long calculateJump = 0;
unsigned char* ptrJump;
ptrJump = (unsigned char*)pMainAddress;
if(*(unsigned char*)ptrJump == 0xE9)
{
calculateJump = (*(unsigned long*)(ptrJump + 1));
pMainAddress = (ptrJump + calculateJump + 5);
printf("Unconditional jump is performed\n");
printf("Address of main() : %#x \n", pMainAddress);
}
else
{
printf("Unconditional jump is not performed\n");
printf("Address of main() : %#x \n", pMainAddress);
}
return pMainAddress;
}
要进行测试,请使用Visual Studio创建控制台应用程序,然后从解决方案配置中选择Debug
或Release
。
将GetAddressOfMain()
放入int main()
,然后构建解决方案。
函数也适用于64位项目配置,但您需要使用适当的格式说明符来正确打印地址。