.so инъекция под Linux: как найти адрес dlopen ()?

Недавно я заинтересовался Linux и пытаюсь создать программу, способную внедрять общий объект (например, .so файл, «динамически загружаемую библиотеку», «DLL» под Windows). Я знаю, что это можно сделать, установив переменная среды, но я хочу сделать это в процессе, который уже запущен.

Я уже знаю, как это сделать под Windows. Есть несколько способов, но, вообще говоря, вы можете просто вызвать LoadLibrary (), создав удаленный поток с помощью CreateRemoteThread (). Конечно, вам нужен адрес LoadLibrary в удаленном процессе, но (по моему опыту) он всегда одинаков для каждого процесса.

Я провел некоторые исследования относительно того, как это можно сделать под Linux. Например интересныйстатья в Phrack 59 показано, как это можно сделать. К статье также прикреплен исходный код, но, поскольку сделаны некоторые предположения о целевом процессе, и он 32-битный, я не смог заставить его работать. Другие вещи, с которыми я столкнулся:статья о проекте кода, но этот только объясняет, как сделать это из GDB. (Я бы опубликовал больше ссылок, но сайт ограничивает меня до 2: - /.)

Для начала я хочу получить адрес функции dlopen () в удаленном процессе. Для этого я решил, что мне нужно получить ELF-заголовок процесса и перебрать таблицы символов. На самом деле, мне удалось сделать это, путем:

1) Получение ELF-заголовка (до 64 бит, хранящихся в 0x400000 по моему опыту.)

2) Расположение таблицы глобальных смещений в заголовке программы, помеченном как ДИНАМИЧНЫЙ.

3) Получение первого файла link_map путем доступа ко второй записи в таблице глобальных смещений.

4) Итерация по динамическим разделам цепочки link_map, таким образом получая адрес таблицы строк, таблицы символов и хэш-таблицы (* Hash_Table + 0x4 содержит количество записей в таблице символов).

5) Цикл по таблице символов

Пример вывода из моей программы:

** looking at lib "" **
   Trying to find symbol main in symbol table... numentries: 49

index 1 name:  val: 0
...
index 49 name: memcpy val: 0
 symbol not found.

** looking at lib "" **
   Trying to find symbol main in symbol table... numentries: 11
index 1 name:  val: 0
...
index 11 name: __vdso_time val: 0xffffffffff700a80
 symbol not found.

** looking at lib "/lib/x86_64-linux-gnu/libc.so.6" **
   Trying to find symbol main in symbol table... numentries: 2190
index 1 name:  val: 0
...
index 2190 name: wcpcpy val: 0xa3570
 symbol not found.

Однако я не могу найти действительный адрес dlopen! (Или даже адрес main, в этом отношении!) В целях тестирования я позволил программе анализировать себя, поэтому я точно знаю, что main существует. Я также попытался readelf -s взглянуть на таблицы символов, и это показывает:

Symbol table '.symtab' contains 151 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
   ...
   149: 0000000000401880   216 FUNC    GLOBAL DEFAULT   13 main

Итак, каким-то образом readelf удалось найти главное, а я не могу. Я также взглянул на библиотеку libelf, но она основывается на чтении из файла приложения, а не на доступе к памяти процесса (т. Е. Ее нельзя использовать во время выполнения процесса). Кто-нибудь знает, как я могу найти dlopen () в удаленном процессе или даже главном, если на то пошло?

Я использую Ubuntu 12.04 64bit.

Ответы на вопрос(3)

Ваш ответ на вопрос