所以我正在尝试编写一个逆向工具,解析符号表以找到主函数的地址
现在我正在检查主函数名称的所有二进制文件仍然是符号表中的主
我的问题是这能改变吗?因为现在我查找 main 函数的检查是该字符串等于 main
如果它可以改变,可能的值是什么?如果它可以有太多可能的值,那么我如何在二进制文件中找到它?
所以我正在尝试编写一个逆向工具,解析符号表以找到主函数的地址
现在我正在检查主函数名称的所有二进制文件仍然是符号表中的主
我的问题是这能改变吗?因为现在我查找 main 函数的检查是该字符串等于 main
如果它可以改变,可能的值是什么?如果它可以有太多可能的值,那么我如何在二进制文件中找到它?
既然你ELF
在标签中提到了。WinMain
, DllMain
, 等不应该是你的问题。它们是 Windows 的命名约定。
该main
函数是为 C/C++ 程序执行的第一个函数。但是,这并不意味着这是真正执行的第一个函数/代码。您通常会在调用此函数之前找到一些初始化代码。
我的问题是这能改变吗?因为现在我查找 main 函数的检查是该字符串等于 main
是的。实际上,您会找到这个静态符号,因为您的可执行文件没有被剥离。如果您在可执行文件上运行 strip(1),您将丢失此信息。
如果它可以改变,可能的值是什么?如果它可以有太多可能的值,那么我如何在二进制文件中找到它?
它可以是任何东西。
例如:没有静态符号,如果你的可执行文件不是用-static
switch编译的,你仍然可以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 不能直接运行,而是被上述两种应用程序使用。