Как выполнить команду отладчика из приложения

Во время выполнения я пытаюсь восстановить адрес функции, которая не экспортируется, но доступна через таблицу символов общей библиотеки и, следовательно, видна отладчику.

Я работаю над расширенной процедурой отладки, которая должна фиксировать определенные события и управлять временем выполнения. Одно из действий требует знания адреса частной функции (просто адреса), который используется как ключ в другом месте.

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

Предпочтительное решение должно иметь возможность восстановления адреса во время выполнения.

Я надеялся связаться с прикрепленным отладчиком из приложения, но изо всех сил пытался найти для этого API.

Какие у меня варианты?

2 ответа

В lldb вы можете быстро найти адрес, установив символическую точку останова, если она известна отладчику каким-либо образом:

b symbolname

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

  • Жестко закодируйте смещение из экспортированной библиотеки и вызовите exportedSymbol+offset (это будет работать для конкретной двоичной версии библиотеки, но, скорее всего, сломается для чего-либо еще)
  • Попытайтесь найти двоичную подпись вашей неэкспортированной функции в загруженной библиотеке. (немного менее подвержен взлому, но двоичная подпись всегда может измениться)

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

Обновление:
поскольку lldb каким-то образом знает символ, я подозреваю, что он определен в Mach-OLC_SYMTABзагрузить команду вашей библиотеки. Чтобы убедиться, что вы можете проверить двоичный файл библиотеки с помощью таких инструментов, как MachOView или MachOExplorer. Или Appleotool или Джонатана Левина jtool/jtool2 в консоли.

Вот пример записи первого символа, полученной из LC_SYMTAB в MachOView. Это бинарный файл /usr/lib/dyld В примере здесь0x1000это виртуальный адрес. Ваша библиотека, скорее всего, будет 64-битной, поэтому ожидайте0x10000000и выше. Фактическая база рандомизируется ASLR, но вы можете проверить текущее значение с помощью

sample yourProcess

yourProcess является исполняемым файлом, использующим библиотеку, которая вам нужна. Вывод должен содержать:

Binary Images:
       0x10566a000 -        0x105dc0fff  com.apple.finder (10.14.5 - 1143.5.1) <3B0424E1-647C-3279-8F90-4D374AA4AC0D> /System/Library/CoreServices/Finder.app/Contents/MacOS/Finder
       0x1080cb000 -        0x1081356ef  dyld (655.1.1) <D3E77331-ACE5-349D-A7CC-433D626D4A5B> /usr/lib/dyld
...

Это загруженные адреса 0x100000000, сдвинутые ASLR. Могут быть еще нюансы, как именно эти адреса выбираются для дилибов, но идею вы поняли.

Tbh Мне никогда не нужно было найти такой адрес программно, но это определенно выполнимо (как /usr/bin/sample умеет это делать).

Отсюда, чтобы достичь чего-то практически:

  1. Разберите заголовок Mach-o вашего двоичного файла библиотеки (проверьте это и это для начала)
  2. найти LC_SYMTAB команда загрузки
  3. Найдите запись на основе текста символа и найдите виртуальный адрес (материал красного поля)
  4. Рассчитайте ASLR и примените сдвиг

Есть некоторый API C Apple для разбора Mach-O. Также в дикой природе существует некоторый код Python (популярный среди специалистов по обратному проектированию).

Надеюсь, это поможет.

Во время выполнения я пытаюсь восстановить адрес функции, которая не экспортируется, но доступна через таблицу символов общей библиотеки и, следовательно, видна отладчику.

Отладчик - это не волшебный единорог. Если таблица символов доступна отладчику, она также доступна для вашего приложения.

Мне нужно восстановить его адрес по имени с помощью отладчика...

Это совершенно неправильный подход.

Вместо использования отладчика прочтите таблицу символов для библиотеки в вашем приложении и используйте полученную информацию для вызова целевой функции.

Читать таблицу символов ELF довольно просто. Пример. Если вы не используете платформу ELF, получить эквивалентную информацию не должно быть намного сложнее.

Другие вопросы по тегам