Мы очень быстро привыкаем к полезным мелочам, делающим нашу жизнь удобнее. Настолько привыкаем, что не замечаем их, когда они есть, однако очень болезненно воспринимаем момент, когда они по каким‑то причинам внезапно пропадают. В этом случае приходится заново учиться базовым вещам, горестно вспоминая, как же мы жили без полезных инструментов раньше.
Сегодня мы поговорим об отладочных символах (я думаю, ты уже достаточно глубоко погружен в темы кодинга и реверса, чтобы не нужно было на пальцах объяснять, что это такое, для чего и как используется). Во время отладки программы к ним так привыкаешь, что забываешь убрать их во время финальной компиляции. С другой стороны, хакеры настолько приспособились к тому, что программист забыл убрать отладочную информацию из программы, что воспринимают ее наличие как нечто само собой разумеющееся и временами теряются, если ее не оказывается на месте или с ней что‑то не так.
Давай попробуем разобраться с конкретным случаем, когда отладочная информация в реверсируемом файле вроде как присутствует, но воспользоваться ей напрямую не получается. Для примера мы возьмем некое приложение под macOS формата Mach-O для архитектуры ARM64.

Мы когда‑то начинали разбирать этот формат в статье «Липосакция для fat binary. Ломаем программу для macOS с поддержкой нескольких архитектур», поэтому сегодня будем сочетать полезное с полезным и продолжим разбор, делая упор уже на символьной информации, содержащейся в таких файлах. Загружаем нашу программу в IDA.
На первый взгляд, отладочная информация в файле вроде как присутствует, большинство функций имеют имена. Однако при ближайшем рассмотрении эти «имена» оказываются бессмысленным набором символов без конца и начала и совершенно не вписываются в логику программы.

Можно было бы предположить злонамеренную обфускацию, о которой я говорил в нескольких предыдущих статьях, однако для обфускации имена, наоборот, чересчур осмысленны. Вдобавок по логике проще выкинуть из модуля всю отладочную информацию начисто, чем заморачиваться с ее обфускацией, преследуя непонятную цель.
Соглашусь: последний аргумент несколько слабоват, поскольку за время нашего знакомства нам неоднократно попадались творения с абсолютно нечеловеческой логикой, однако априори я все‑таки стараюсь придерживаться хорошего мнения о людях. Попробуем проанализировать отладочную информацию этого модуля другими средствами. В конце концов, на IDA свет клином не сошелся, функция анализа Debug Symbols Mach-O встроена, например, в тот же Detect It Easy.
Для ее просмотра необходимо нажать слева кнопку «Информация о файле» или кнопку «Mach-O». В открывшемся окне нас интересует расположенная слева вкладка «Команды → LC_SYMTAB → Таблица символов».

Даже на первый взгляд (а мы вернемся к подробному разбору этой таблицы позднее) там содержится полная каша. Однако, пролистав таблицу чуть ниже, мы натыкаемся на более осмысленную информацию, что дает нам надежду на успешное излечение пациента.
Строки в правой колонке напоминают неправильно порезанные декорированные имена символов (если ты еще не слышал о таких, вот ссылка, а мы пока не будем отвлекаться на эту тему). Если мы ткнемся во вкладку «LC_SYMTAB → Таблица строк → Строки», то получим и вовсе полностью валидные декорированные имена функций.
То есть отладочные имена функций в файле все‑таки присутствуют. Попробуем разобраться, что в них не так, почему ни Detect It Easy, ни IDA их правильно не воспринимают, после чего попытаемся руками самостоятельно починить их.
Для этого нам придется снова окунуться в матчасть.
Вспомним статью, в которой мы начинали разбирать формат Mach-O. Правда, там шла речь о «жирном» бинарнике, в котором содержался код, предназначенный для нескольких процессоров, наш же случай проще: у нас бинарник «обезжиренный» и в нем содержится только код для процессора ARM64. В двух словах передам суть полезной информации из той статьи для тех, кому лень читать.
Типичный файл Mach-O состоит из трех областей. Заголовок содержит общую информацию о двоичном файле: порядок байтов (магическое число), тип процессора, количество команд загрузки и так далее. Команды загрузки — это своего рода оглавление, которое описывает положение сегментов, таблицу символов, динамическую таблицу символов и тому подобное. Каждая команда загрузки содержит метаданные, такие как тип команды, ее имя, позиция в двоичном файле и прочие полезные сведения.
Третья область — данные — обычно самая большая часть объектного файла. Она содержит код и данные, такие как таблицы символов, которые, собственно, нас и интересуют. Не будем подробно останавливаться на структурах формата Mach-O, ты можешь самостоятельно изучить их в качестве домашнего задания, прочитав вот эту статью или разбирая код и описание к нему этого парсера с GitHub. Поскольку мы изначально выбрали Detect It Easy в качестве инструмента для анализа, для экономии времени поручим парсинг именно ему. Начнем с заголовка файла.
Как я уже говорил, наш бинарник «постный», поэтому он сразу начинается с mach_header
. Помимо типа процессора, в заголовке мы видим, что за ним следуют 0x2d
команды загрузки общим размером 0x16F0
байт. Каждая команда имеет собственную структуру и собственный размер, поэтому, полагаясь на DIE, сразу находим интересующую нас команду LC_SYMTAB
, содержащую ссылки на отладочные символы (я упоминал ее в начале статьи).
Как следует из спецификации, формат у этой команды следующий:
struct symtab_command { // LC_SYMTAB 0x2 uint32_t cmd; // Размер структуры symtab_command — 0x18 uint32_t cmdsize; // Смещение к таблице символов — 0x4b78e20 uint32_t symoff; // Количество символов в таблице символов — 0x4a537 uint32_t nsyms; // Смещение таблицы строк — 0x5020cc0 uint32_t stroff; // Размер таблицы строк в байтах — 0xa37f50 uint32_t strsize;};
Продолжение доступно только участникам
Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».
Присоединяйся к сообществу «Xakep.ru»!
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее