繁体   English   中英

如何使用gcc更改C程序的入口点?

[英]How to change entry point of C program with gcc?

如何更改用 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”部分将使您的程序能够调用外部共享库。 退出调用将使您的入口函数退出程序而不是返回。

然后将程序构建为可执行的共享库:

$ 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
  1. 您首先使用-c编译它以生成可重定位的目标文件:

     $ gcc -c program.c -o program.o
  2. 然后你将entry重新定义为main

     $ objcopy --redefine-sym entry=main program.o
  3. 现在使用 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

    大概是因为在_start main 之前运行的 glibc 设置代码通常调用main

  • 没有为您设置命令行参数,大概是因为它们将由在 main 之前运行的 glibc 代码设置,因此尝试使用它们会打印未定义的值。 我还没有找到适合他们的方法。

在 Ubuntu 20.10 中测试。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM