Доступ к глобальной статической переменной из файла .so без изменения библиотеки - PullRequest
0 голосов
/ 11 января 2019

У меня есть глобальная статическая переменная, определенная в библиотеке (файл .so), к которой я хочу получить доступ из своего приложения. Приложение загружает библиотеку .so во время выполнения.

Есть ли способ получить доступ к статической переменной без изменения кода библиотеки? Я знаю, что это не так просто, так как я вижу, что сам символ переменной будет удален из таблицы символов после завершения компиляции. Я все еще думаю, что может быть какой-то хакерский способ (путем сканирования таблицы символов и т. Д.) Получить доступ к этой переменной. Любая помощь?

lib.c -> static struct Abc abc --> compiled to a.so
app.c ->loads a.so and need to access abc variable?

обновление: a.so компилируется с использованием gcc -O2 option.

Ответы [ 2 ]

0 голосов
/ 11 января 2019

В общем случае правильно, что статическая глобальная переменная недоступна. Он даже может быть оптимизирован при некоторых обстоятельствах, так что фиксированной области памяти вообще не существует.

Но если он не оптимизирован, то, конечно, всегда есть «хакерские» способы получить к нему доступ. Сканирование таблицы символов, однако, не вариант, так как символ обычно там не указан. Вы должны копать глубже в коде сборки. Этот пример для linux с процессором gcc и x86_64. Предполагается, что источник доступен для идентификации доступа к переменной в коде сборки.

Представьте себе следующий исходный файл общего объекта:

static int bar = 31337;

int foo (void) {
    bar = getpid();
}

bar - ваша статическая переменная. Теперь вы можете узнать смещение bar из функции foo, которая всегда постоянна, несмотря на перемещение всей библиотеки, изучив разобранный источник:

objdump -x shared.so

00000000000006a0 <foo>:
 6a0:   48 83 ec 08             sub    $0x8,%rsp
 6a4:   31 c0                   xor    %eax,%eax
 6a6:   e8 c5 fe ff ff          callq  570 <getpid@plt>
 6ab:   89 05 c7 02 20 00       mov    %eax,0x2002c7(%rip)        # 200978 <_fini+0x2002c0>
 6b1:   48 83 c4 08             add    $0x8,%rsp
 6b5:   c3                      retq  

Здесь вы видите, что функция foo имеет адрес 6a0 (подлежит перемещению позже), а статическая глобальная переменная bar доступна по адресу 200978, что дает общее смещение 200978-6a0 = 2002D8. Так что если вы откроете общую библиотеку

void *h = dlopen("shared.so", RTLD_LAZY);

и поиск символа foo

void *foo = dlsym(h, "foo");

Вы можете рассчитать адрес bar, добавив вычисленное смещение:

int *a = foo + 0x2002D8;
printf("%d\n", *a);

Хакерский путь, как и просили;)

0 голосов
/ 11 января 2019

Это невозможно, поскольку идея глобальной переменной static состоит в том, чтобы сделать ее невидимой ни для чего, кроме текущей единицы компиляции

Если разработчик библиотеки сделал объект статическим, вероятно, это было сделано по какой-то причине, и он не хотел, чтобы этот объект был доступен вне кода библиотеки

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