Свяжите двоичный файл ELF с программой c - PullRequest
0 голосов
/ 04 апреля 2020

Учитывая только доступ к автономной программе ELF, я хочу иметь возможность вызывать функцию в программе из моей собственной программы. Допустим, приведенный ниже код: main.c

#include <stdio.h>

extern int mystery(int a,int b);

int main() {
        int a = 0;
        int b = 1;
        printf("mystery(a,b) = %d\n",mystery(a,b));
        return 0;
}

Функция mystery существует в некотором файле эльфа not_my_program. Я пытаюсь сделать что-то вроде

gcc main.c not_my_program

Однако это дает мне неопределенную ошибку ссылки на mystery. Я искал методы на форумах и обнаружил, что преобразование этого файла elf в общий объектный файл невозможно. Я также изучил компиляцию main.c в перемещаемый объектный файл с

gcc -c main.c

, а затем с помощью ld связал эльфа с main.o, но я не мог понять, как это сделать. Эльф 32-битный, но я опустил флаг -m32. Если флаг отличается для ld, пожалуйста, дайте мне знать. Любая помощь будет принята с благодарностью.

edit: вывод readelf -h not_my_program

ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x10e0
  Start of program headers:          52 (bytes into file)
  Start of section headers:          15116 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         11
  Size of section headers:           40 (bytes)
  Number of section headers:         30
  Section header string table index: 29

Ответы [ 2 ]

1 голос
/ 05 апреля 2020

Этот хакерский способ работал с очень простым делом.

[ aquila ~ ] $ cat 1.c
int func (int a) { return a * (a-1) ; }
int main(int argc) { return func (argc) ; }
[ aquila ~ ] $ cc 1.c
[ aquila ~ ] $ ./a.out ; echo $?
0
[ aquila ~ ] $ readelf -s a.out | grep func
    43: 0000000000400487    19 FUNC    GLOBAL DEFAULT   11 func
[ aquila ~ ] $ cat 2.c
#include <stdlib.h>
static __attribute__((constructor)) void main() {
  int (*func)() = (int (*)())0x0000000000400487;
  exit(func(3));
}
[ aquila ~ ] $ cc -fPIC -shared 2.c -o a.so
[ aquila ~ ] $ LD_PRELOAD=./a.so ./a.out ; echo $?
6

Вызывающая сторона в 2. c превращена в конструктор с выходом, так что основная программа main() не вызывается, в попытке ограничить выполнение кода, отличного от вызывающего и самого func(). Возвращаемое значение 6 вместо 0 показывает, что вызов работал и что основная программа main() не была вызвана.

0 голосов
/ 05 апреля 2020

Учитывая только доступ к автономной программе ELF, я хочу иметь возможность вызывать функцию в программе из моей собственной программы

Похоже, у вас проблема XY .

Хотя то, что вы желаете, технически возможно, сложность сделать это примерно в 1000 раз больше того, что вы пробовали до сих пор. Если вы не готовы потратить месяц или два на то, чтобы это сработало, вам следует поискать другие решения.

Фактически вам придется написать собственный загрузчик ELF, чтобы загрузить not_my_program в память и инициализировать его, но затем вызовите mystery вместо main.

Обратите также внимание, что mystery может зависеть от глобальных данных, и что данные могут быть инициализированы в main, поэтому не гарантирует что mystery будет работать вообще при вызове до main.

PS Достаточно ли будет вызвать mystery из отладчика? Это может быть достигнуто менее чем за 30 секунд.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...