Как изменить точку входа программы на C, скомпилированной с помощью gcc?
Как в следующем коде
#include<stdio.h>
int entry() //entry is the entry point instead of main
{
return 0;
}
Как изменить точку входа программы на C, скомпилированной с помощью gcc?
Как в следующем коде
#include<stdio.h>
int entry() //entry is the entry point instead of main
{
return 0;
}
Это настройка компоновщика:
-Wl,-eentry
вещь -Wl,...
передает аргументы компоновщику, а компоновщик принимает аргумент -e
для установки функции входа
$ gcc -Wl,-emymain t27.c /usr/lib/gcc/i686-redhat-linux/4.8.2/../../../crt1.o: In function '_start': (.text+0x18): undefined reference to 'main'
- person Lee Duhem; 08.03.2014
-nostartfiles
- это фактический флаг, который вам нужен, он пропускает файлы crt * .o, содержащие _start, но все же позволяет вам использовать libc (если вы также не используете -nostdlib или -nodefaultlibs, в этом случае вы все равно можете указать их вручную, используя -lc -lgcc и т.д...)
- person technosaurus; 17.07.2015
-Wl,--entry="MyCutomEntryFunction"
или -Wl,-e="MyCutomEntryFunction"
- person Romain VIOLLETTE; 22.10.2018
Вы можете изменить исходный код следующим образом:
#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
entry
? Инициализирована ли C-runtime таким образом?
- person harper; 20.10.2014
Если вы работаете в системе, которая предоставляет 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
Минимальный рабочий пример и примечания к другим ответам
main.c
#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
предположительно, потому что код установки glibc, который запускается перед main в _start
, обычно вызывает main
.
Аргументы командной строки не настроены для вас, предположительно, потому что они будут настроены кодом glibc, который запускается перед основным, поэтому попытка их использования выводит неопределенные значения. Я не нашел метод, который работает для них.
Протестировано в Ubuntu 20.10.
-eentry=
должно было быть --entry=
; Я отредактировал ответ соответственно.
- person Demi-Lune; 05.01.2021
--wrap=xxx
? Он заменяет все ссылкиxxx
на__wrap_xxx
и все определенияxxx
на__real_xxx
. Я успешно использовал его для тестированияmain()
. - person the busybee   schedule 29.10.2019