Как изменить точку входа программы C с помощью gcc?

17

Как изменить точку входа программы на языке C, скомпилированной с помощью gcc?
Как и в следующем коде

#include<stdio.h>
int entry()  //entry is the entry point instead of main
 {
   return 0;
 }
    
задан asitm9 21.09.2011 в 05:26
источник
  • просто любопытно - почему? –  iandotkelly 21.09.2011 в 05:28
  • Возможный дубликат: существует ли опция компилятора / компоновщика GCC для изменения имени основного? –  Ciro Santilli 新疆改造中心 六四事件 法轮功 13.07.2015 в 15:59
  • @iandotkelly Не OP, но мне нужно было использовать библиотеку контрольных точек, которая требовала от меня изменить main () на что-то еще;) –  Nubcake 18.05.2017 в 18:52

3 ответа

23

Это установка компоновщика:

-Wl,-eentry

вещь -Wl,... передает аргументы компоновщику, а компоновщик принимает аргумент -e для установки функции записи

    
ответ дан Foo Bah 21.09.2011 в 05:31
  • Это то, что я получил, когда скомпилировал программу приветствия мира C с этой опцией: $ gcc -Wl, -emymain t27.c /usr/lib/gcc/i686-redhat-linux/4.8.2/../ ../../crt1.o: В функции '_start': (.text + 0x18): неопределенная ссылка на 'main' –  Lee Duhem 08.03.2014 в 10:11
  • @LeeDuhem, это связано с тем, что вы связываете свою программу со стандартной библиотекой времени выполнения c. Точкой входа в программу, связанную с библиотекой времени c, является _start. Начать имеет ссылку на main () вашей программы (она ожидает, что ваша программа будет иметь функцию main () вместо вашей настраиваемой функции). Попытайтесь не ссылаться на crt и укажите точку входа как your_main и посмотрите, что произойдет. –  PaulD 01.10.2014 в 15:03
  • @LeeDuhem, -nostdlibs этот флаг. –  PaulD 01.10.2014 в 15:08
  • -nostartfiles - это фактический флаг, который вы хотите, это опускает файлы crt * .o, содержащие _start, но все же позволяет вам использовать libc (если вы также не используете -nostdlib или -nodefaultlibs, и в этом случае вы все же можете вручную указать они используют -lc -lgcc и т. д.) –  technosaurus 17.07.2015 в 08:38
5

Вы можете изменить исходный код следующим образом:

#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
    
ответ дан Sam Liao 10.08.2014 в 06:18
  • Что такое вызывающая конвенция функции входа? Таким образом инициализируется C-runtime? –  harper 20.10.2014 в 08:38
  • не могли бы вы объяснить, что это значит: «Создайте программу как общую библиотеку, которая является исполняемой». Как это может быть? –  Nawaz 18.09.2015 в 10:56
  • @harper: это не соглашение о совместимости с C. Точка входа ELF ABI имеет свой главный аргумент в указателе стека, указывая на «массив», состоящий из указателей argc, argv, нулевых указателей, env, null, aux vector table. Некоторые арки имеют дополнительные аргументы в конкретных регистрах. –  R.. 06.06.2017 в 12:32
3

Если вы находитесь в системе, которая предоставляет 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
    
ответ дан Rudy Matela 14.12.2015 в 23:26