C & C++ 程序符号表中的主函数名称是否总是“main”?如果没有,如何找到名称?

逆向工程 x86 C 小精灵 二进制 x86-64
2021-07-02 16:56:21

所以我正在尝试编写一个逆向工具,解析符号表以找到主函数的地址

现在我正在检查主函数名称的所有二进制文件仍然是符号表中的主

我的问题是这能改变吗?因为现在我查找 main 函数的检查是该字符串等于 main

如果它可以改变,可能的值是什么?如果它可以有太多可能的值,那么我如何在二进制文件中找到它?

3个回答

既然你ELF在标签中提到了。WinMain, DllMain, 等不应该是你的问题。它们是 Windows 的命名约定。

main函数是为 C/C++ 程序执行第一个函数但是,这并不意味着这是真正执行的第一个函数/代码。您通常会在调用此函数之前找到一些初始化代码。

我的问题是这能改变吗?因为现在我查找 main 函数的检查是该字符串等于 main

是的。实际上,您会找到这个静态符号,因为您的可执行文件没有被剥离。如果您在可执行文件上运行 strip(1),您将丢失此信息。

如果它可以改变,可能的值是什么?如果它可以有太多可能的值,那么我如何在二进制文件中找到它?

它可以是任何东西。

例如:没有静态符号,如果你的可执行文件不是用-staticswitch编译的,你仍然可以main通过查找 的第一个参数来检索函数的地址__libc_start_main该函数通常是从共享对象中导入的libc.so,因此您可以找到它的动态符号

只是一个快速说明,以防您不知道这一点:

$ cat tiny.c
#include <unistd.h>
void _start() {
  _exit(42);
}

在 x86-64 上,这是我得到的(你需要一个静态 libc:libc.a):

$ gcc -static -ffreestanding -nostartfiles  -s -o tiny tiny.c
$ ./tiny || echo $?
42

请注意:

$ file tiny
tiny: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=5557e6655b77976b7c248711af6f508d931fc3af, stripped

但只有:

$ objdump -x tiny

tiny:     file format elf64-x86-64
tiny
architecture: i386:x86-64, flags 0x00000102:
EXEC_P, D_PAGED
start address 0x0000000000400180

Program Header:
    LOAD off    0x0000000000000000 vaddr 0x0000000000400000 paddr 0x0000000000400000 align 2**21
         filesz 0x0000000000000240 memsz 0x0000000000000240 flags r-x
    LOAD off    0x0000000000001000 vaddr 0x0000000000601000 paddr 0x0000000000601000 align 2**21
         filesz 0x0000000000000018 memsz 0x0000000000000018 flags rw-
    NOTE off    0x0000000000000158 vaddr 0x0000000000400158 paddr 0x0000000000400158 align 2**2
         filesz 0x0000000000000024 memsz 0x0000000000000024 flags r--
     TLS off    0x0000000000001000 vaddr 0x0000000000601000 paddr 0x0000000000601000 align 2**2
         filesz 0x0000000000000000 memsz 0x0000000000000004 flags r--
   STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
         filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .note.gnu.build-id 00000024  0000000000400158  0000000000400158  00000158  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .text         0000006a  0000000000400180  0000000000400180  00000180  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .eh_frame     00000050  00000000004001f0  00000000004001f0  000001f0  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .tbss         00000004  0000000000601000  0000000000601000  00001000  2**2
                  ALLOC, THREAD_LOCAL
  4 .got.plt      00000018  0000000000601000  0000000000601000  00001000  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  5 .comment      0000002c  0000000000000000  0000000000000000  00001018  2**0
                  CONTENTS, READONLY
SYMBOL TABLE:
no symbols

main() 表示你的程序是一个控制台应用程序。

WinMain() 表示该程序是一个 GUI 应用程序——也就是说,它显示窗口和对话框而不是显示控制台。

DllMain() 表示程序是一个DLL。DLL 不能直接运行,而是被上述两种应用程序使用。