如何更改用 gcc 编译的 C 程序的入口点?
就像在下面的代码中一样
#include<stdio.h>
int entry() //entry is the entry point instead of main
{
return 0;
}
如何更改用 gcc 编译的 C 程序的入口点?
就像在下面的代码中一样
#include<stdio.h>
int entry() //entry is the entry point instead of main
{
return 0;
}
这是一个链接器设置:
-Wl,-eentry
-Wl,...
事物将参数传递给链接器,链接器接受一个参数-e
来设置入口函数
您可以将源代码修改为:
#include<stdio.h>
const char my_interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2";
int entry() //entry is the entry point instead of main
{
exit(0);
}
“.interp”部分将使您的程序能够调用外部共享库。exit 调用将使您的入口函数退出程序而不是返回。
然后将程序构建为可执行的共享库:
$ gcc -shared -fPIC -e entry test_main.c -o test_main.so
$ ./test_main
如果您使用的是提供GNU Binutils的系统(如 Linux),则可以使用该objcopy
命令将任意函数设为新入口点。
假设一个名为的文件program.c
包含该entry
函数:
$ cat > program.c
#include <stdio.h>
int entry()
{
return 0;
}
^D
您首先使用它来编译它-c
以生成可重定位的目标文件:
$ gcc -c program.c -o program.o
然后你重新定义entry
为main
:
$ objcopy --redefine-sym entry=main program.o
现在使用 gcc 编译新的目标文件:
$ gcc program.o -o program
注意:如果您的程序已经有一个名为 的函数main
,则在第 2 步之前,您可以执行单独的objcopy
调用:
objcopy --redefine-sym oldmain=main program.o
最小的可运行示例和其他答案的注释
主程序
#include <stdio.h>
#include <stdlib.h>
int mymain(void) {
puts("hello");
exit(0);
}
编译并运行:
gcc -nostartfiles -Wl,--entry=mymain -o main.out main.c
# or -Wl,-emymain
./main.out 1 2 3
笔记:
没有-nostartfiles
,链接将失败,并显示:
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
大概是因为在 main in之前运行的 glibc 设置代码_start
通常会调用main
.
没有为您设置命令行参数,大概是因为它们将由在 main 之前运行的 glibc 代码设置,因此尝试使用它们会打印未定义的值。我还没有找到适合他们的方法。
在 Ubuntu 20.10 中测试。