この方法で main() 関数のアドレスを取得しようとしています:
int main(int argc, char *argv[])
{
void *pMainAddress=(void *)&main;
printf("Address of main() 0x%08X \n", pMainAddress);
リリース構成を使用してプロジェクトをビルドすると、結果は次のようになります:
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オプションを指定してコンパイルするか、デバッグビルドを使用すると、アドレスがリダイレクトされます:
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"
なぜこれが起こるのですか?コードがデバッグ ビルドでコンパイルされている場合
、main() 関数 (上記の例) の実際のアドレスを取得する方法は?0x00412530
編集:
なぜこれが起こるのですか?ここですでに回答されています:関数呼び出しの間接的なレベルがおかしい
以下の関数は、私の 2 番目の質問を解決します。
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;
}