簡體   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