シンボルがないELFバイナリのmain関数を特定する

まず、以下のコードをgccコンパイルして、main関数のシンボルを確かめる。

#include <stdio.h>

int main() {
    printf("test\n");
}
$ objdump -d a.out|grep main
0000000000400420 <__libc_start_main@plt>:
  400464: e8 b7 ff ff ff    callq  400420 <__libc_start_main@plt>
000000000040052d <main>:

stripコマンドでmain関数のシンボルを削ると、main関数がないように見える。

$ strip --strip-unneeded a.out
$ objdump -d a.out|grep main
0000000000400420 <__libc_start_main@plt>:
  400464: e8 b7 ff ff ff    callq  400420 <__libc_start_main@plt>

しかし、__libc_start_mainの第1引数がmain関数のアドレスとなっているので、main関数は簡単に特定できる。

$ objdump -d a.out|grep main -B5
...
  40044d: 50                    push  %rax
  40044e: 54                    push  %rsp
  40044f: 49 c7 c0 b0 05 40 00  mov  $0x4005b0,%r8
  400456: 48 c7 c1 40 05 40 00  mov  $0x400540,%rcx
  40045d: 48 c7 c7 2d 05 40 00  mov  $0x40052d,%rdi 
  // 0x40052dがmain関数のアドレス
  400464: e8 b7 ff ff ff        callq  400420 <__libc_start_main@plt>