获取Debug Build下的main()函数的地址

时间:2013-07-10 23:24:29

标签: c visual-studio debugging

我试图以这种方式获取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;
}  

2 个答案:

答案 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创建控制台应用程序,然后从解决方案配置中选择DebugRelease
GetAddressOfMain()放入int main(),然后构建解决方案。

函数也适用于64位项目配置,但您需要使用适当的格式说明符来正确打印地址。