
Три месяца назад SOC прислал подозрительный ELF-файл, снятый с скомпрометированного сервера. Через 40 минут в окне Decompile я нашёл захардкоженный C2-адрес — ни одной строки ассемблера для этого читать не пришлось. Ghidra превратила машинный код в C-подобный псевдокод, и задача свелась к банальному чтению программы. Этот Ghidra туториал — маршрут, который я бы прошёл в первый день, будь у меня тогда нормальное руководство на русском.
Ghidra — бесплатный инструмент для обратной разработки ПО с открытым исходным кодом, выпущенный NSA в 2019 году. До её появления рынок дизассемблеров держала IDA Pro с плагином Hex-Rays — связка мощная, но с ценником, который закрывал вход новичкам и небольшим командам. Появление Ghidra этот барьер снесло. Подробнее — в нашем материале про бинарный анализ уязвимостей.
Главное отличие от простых дизассемблеров — встроенный декомпилятор. Дизассемблер переводит машинный код в ассемблерные инструкции (MOV, PUSH, CALL) — читать их без подготовки тяжело. Декомпилятор идёт дальше: восстанавливает из байт-кода подобие исходного текста на C. Вместо десятков строк ассемблера вы видите if, for, вызовы функций с аргументами. Это не тот код, что писал автор программы, и местами декомпилятор врёт — но для первого анализа исполняемых файлов хватает за глаза.
Ghidra поддерживает десятки архитектур: x86, x86_64, ARM, MIPS, PowerPC. Для типовых задач на обычном ПК — анализ вредоносного ПО, решение CTF-задач — хватает x86_64.
Русскоязычные руководства часто предлагают собирать Ghidra из master-ветки — с установкой Visual Studio, Gradle и компиляцией из исходников. Статья Securelist подробно описывает этот процесс для Windows, Linux и macOS. Если нужны последние исправления из dev-ветки — сборка оправдана. Для первого знакомства — избыточна, и именно на этом шаге многие бросают.
Быстрый путь:
ghidraRun (Linux/macOS) или ghidraRun.bat (Windows).При первом запуске Ghidra предложит создать проект. Проект — контейнер для результатов: база данных бинарника, ваши комментарии, переименованные функции, типы данных. Один проект может хранить несколько файлов. Без проекта работать нельзя — все изменения пропадут при закрытии. (Я наступил на эти грабли в первую неделю — с тех пор создаю проект даже для одноразового анализа.)
После создания проекта откройте CodeBrowser через иконку с зелёным драконом — это основная рабочая среда для reverse engineering.
В CodeBrowser через File → Import File выберите бинарник. Ghidra определит формат (ELF, PE, Mach-O) и архитектуру автоматически. На этом этапе менять настройки обычно не нужно — подтверждайте импорт.
Сразу после импорта Ghidra предложит запустить автоанализ (Auto Analysis). Пропускать его нельзя. Автоанализ запускает набор алгоритмов, которые:
Для бинарника до нескольких мегабайт автоанализ занимает секунды. Для крупных — минуты. После завершения вы получаете полностью размеченный файл, готовый к препарированию.
CodeBrowser выглядит перегруженным при первом открытии — четыре-пять панелей с незнакомой информацией. Не пугайтесь. Для анализа бинарников в Ghidra реально нужны четыре окна.
Program Trees (слева вверху) — структура бинарника: секции .text (исполняемый код), .data (данные), .rodata (строки и константы). Считайте это оглавлением файла. Секция .text — то, где живут функции.
Symbol Tree (слева) — список всех имён: функции, импортируемые библиотечные вызовы, глобальные переменные. Если бинарник не stripped (не лишён отладочной информации), здесь будут оригинальные имена: main, check_license, send_report. Если stripped — Ghidra сгенерирует имена вида FUN_00401000, где число — адрес начала функции. Второй вариант встречается чаще.
Listing (центр) — окно дизассемблирования. Показывает ассемблерный код. Новичкам оно кажется пугающим, но читать его целиком не нужно. Listing полезен для навигации: кликаете по адресу или имени — Ghidra переносит в нужное место.
Decompile (справа) — главное окно для тех, кто не знает ассемблер на зубок. Ghidra decompiler превращает машинный код в C-подобный псевдокод. Кликаете на функцию в Symbol Tree или Listing — Decompile показывает её восстановленный текст. Здесь происходит 80% работы аналитика.
Окна связаны: клик по строке в Decompile подсвечивает соответствующие инструкции в Listing, и наоборот. Это позволяет сопоставить строку псевдокода с реальными инструкциями процессора — полезно, когда декомпилятор ошибается. А он ошибается регулярно.
Допустим, вы открыли функцию и видите в окне Decompile:
void FUN_00401150(void) {
char local_28[32];
puts("Enter password:");
fgets(local_28, 32, stdin);
if (strcmp(local_28, "s3cr3t_k3y\n") == 0) {
puts("Access granted!");
} else {
puts("Wrong password.");
}
}
Даже без опыта в reverse engineering для начинающих видно: функция запрашивает пароль, сравнивает его с s3cr3t_k3y через strcmp и выводит результат. Вы только что «решили» простой CrackMe — типичную задачу категории reverse на CTF-соревнованиях. Ассемблер не понадобился.
Несколько нюансов чтения псевдокода, которые стоит знать с первого дня:
Автоматические имена переменных. Ghidra генерирует имена вроде local_28, param_1, uVar2. Они ничего не значат — технические метки. Правый клик по переменной → Rename Variable позволяет дать осмысленное имя. Я переименовываю ключевые переменные при каждом анализе — через час бинарник превращается в читаемую программу.
Типы данных. Декомпилятор пытается угадать типы, но часто промахивается. undefined4 означает «четыре байта неизвестного типа» — с высокой вероятностью это int или uint32_t. Через Retype Variable (правый клик) можно исправить тип, после чего декомпилятор пересчитает зависимые выражения.
Обращения к полям структур. Конструкции вида *(int *)(param_1 + 0x10) — обращение к полю структуры по смещению. Ghidra не знает оригинальную структуру, поэтому показывает сырое смещение. Если удаётся понять, какая структура используется, можно создать свой тип в Data Type Manager и применить его — псевдокод станет значительно читаемее.
Ошибки декомпилятора. Ghidra decompiler иногда генерирует конструкции, которых не было в исходном коде: лишние приведения типов, «мёртвые» переменные, неправильные границы циклов. Если псевдокод выглядит нелогично — переключайтесь на Listing и сверяйте с ассемблерными инструкциями. Именно для этого окна синхронизированы. Не доверяйте декомпилятору слепо — он инструмент, а не оракул.
Статический анализ бинарных файлов — это не последовательное чтение кода сверху вниз. Это прыжки между функциями по цепочке вызовов: от подозрительной строки к функции, которая её использует, от функции к тому, кто её вызывает.
Правый клик по имени функции или переменной → References → Show References to. Ghidra покажет все места в бинарнике, где эта функция вызывается или переменная используется.
Типичный сценарий: вы нашли подозрительную строку через Window → Defined Strings (например, IP-адрес или URL). Кликнули на перекрёстную ссылку — попали в функцию, которая эту строку использует. Открыли Decompile — видите контекст: строка передаётся в connect() или send(). Вывод: бинарник лезет на этот адрес. Дальше — дело техники.
По умолчанию горячие клавиши в Ghidra отличаются от привычных IDA-шных. В статье Securelist описана конфигурация, совместимая с IDA-привычками: X — перекрёстные ссылки, Esc — назад, C — код, D — данные. Советую настроить так, если планируете работать с Ghidra регулярно — пальцы скажут спасибо.
Window → Function Call Graph показывает визуальную карту: какие функции вызывает текущая и кто вызывает её. Для анализа вредоносного ПО это критически важно — вы видите «скелет» программы и определяете, какие ветки отвечают за сеть, файловую систему или шифрование.
Вот алгоритм, который я применяю для каждого нового файла. Он не требует глубокого знания ассемблера — достаточно читать псевдокод и пользоваться навигацией.
Шаг 1: разведка до Ghidra. Перед импортом запускаю file suspicious_binary для определения формата и архитектуры. Затем strings suspicious_binary | grep -iE "http|\.com|password|key" — утилита strings извлекает читаемые строки из бинарника. Часто C2-адреса или ключи обнаруживаются ещё до запуска декомпилятора. Десять секунд в терминале могут сэкономить полчаса в Ghidra.
Шаг 2: импорт и автоанализ. Открываю файл в Ghidra, соглашаюсь на автоанализ. После завершения проверяю Symbol Tree: есть осмысленные имена функций (main, init, send_data) или только FUN_*. Первый вариант — бинарник не stripped, задача проще. Второй — придётся разбираться по поведению.
Шаг 3: строки. Window → Defined Strings. Ghidra показывает все строки, найденные автоанализом: сообщения об ошибках, URL, пути к файлам, команды оболочки, ключи реестра. Каждая подозрительная строка — точка входа для глубокого анализа через перекрёстные ссылки.
Шаг 4: точка входа. В Symbol Tree ищу функцию main (или entry, если main отсутствует). Открываю в Decompile и читаю: что программа делает первым делом? Инициализирует сеть? Проверяет окружение? Расшифровывает конфигурацию?
Шаг 5: движение по вызовам. Из main перехожу по вызовам функций, кликая по именам в псевдокоде. Каждую функцию, назначение которой стало понятно, переименовываю: FUN_00401150 → check_password, FUN_00401300 → connect_to_c2, FUN_004015A0 → decrypt_config. Через час бинарник превращается из набора безликих адресов в программу с понятной логикой.
Шаг 6: документирование. Ghidra сохраняет все переименования и комментарии в проекте. Добавляю заметки к ключевым находкам через Set Comment (правый клик). При повторном открытии — всё на месте.
Этот workflow масштабируется: простой CrackMe — 20 минут, бинарник среднего размера с обфускацией — несколько часов. Подход один и тот же: строки → перекрёстные ссылки → чтение псевдокода → переименование → повтор.
Категория reverse на CTF-соревнованиях — лучший тренажёр для освоения Ghidra. Типичная задача: дают скомпилированный бинарник, нужно найти флаг — строку формата flag{...}.
Задачи начального уровня решаются за минуты по описанному workflow: импорт → строки → чтение псевдокода. Строка с флагом может лежать в открытом виде (как в примере с strcmp) или быть зашифрована простым XOR.
Более сложные задачи добавляют обфускацию: строки зашифрованы нетривиальным алгоритмом, бинарник проверяет наличие отладчика, логика разбросана по десятку функций. Но даже здесь декомпилятор выдаёт читаемый псевдокод — вопрос в терпении при разборе.
Согласно материалам курса Introduction to Reverse Engineering with Ghidra (wrongbaud, программа Hackaday-U), оптимальный формат обучения — четыре сессии с CrackMe-задачами возрастающей сложности. Каждая задача — бинарник с паролем или ключом, который нужно извлечь. Курс рассчитан на студентов с минимальными предусловиями: базовое знакомство с C и любым скриптовым языком. После четвёртой задачи студенты уверенно ориентируются в интерфейсе и читают декомпилированный код без посторонней помощи. Четыре CrackMe — и Ghidra перестаёт казаться инопланетной.
Этот вопрос задают в каждом втором треде на Reddit по реверс-инжинирингу. Вот сравнение по критериям, которые реально влияют на работу:
| Критерий | Ghidra | IDA Pro + Hex-Rays |
|---|---|---|
| Цена | Бесплатно, open source | Коммерческая лицензия |
| Встроенный декомпилятор | Да, все архитектуры | Hex-Rays — отдельный модуль |
| Качество декомпиляции x86_64 | Хорошее | Отличное |
| Скриптинг | Java, Python (Jython) | IDAPython |
| Совместная работа | Ghidra Server (нативно) | Через сторонние решения |
| Удобство интерфейса из коробки | Требует настройки | Интуитивнее |
| Поддержка архитектур | Широкая, включая редкие | Широкая |
| Скорость автоанализа | Средняя | Быстрее на больших файлах |
Для начинающих выбор очевиден: Ghidra бесплатна и включает декомпилятор из коробки. IDA Free (бесплатная версия) имеет существенные ограничения по декомпиляции. Полная IDA Pro с Hex-Rays — инструмент для профессионалов с соответствующим бюджетом.
На практике я использую Ghidra как основной инструмент для статического анализа бинарных файлов, IDA Free — для быстрой перепроверки отдельных участков, x64dbg — когда нужен динамический анализ. Автор статьи на Securelist описывает аналогичный переход: после настройки горячих клавиш и интерфейса он перестал возвращаться к привычным инструментам.
Нюанс, о котором не пишут: качество декомпиляции Hex-Rays для x86_64 действительно выше. Псевдокод чище, типы определяются точнее. Но разница критична при анализе сложных оптимизированных бинарников — для типовых задач (malware-анализ, CTF reverse с Ghidra) декомпилятора Ghidra хватает. Я перешёл на Ghidra как основной инструмент два года назад и не жалею.
Чтение ассемблера вместо псевдокода. Новички открывают Listing и пугаются стены из MOV и PUSH. Начинайте с окна Decompile. Ассемблер понадобится позже, когда декомпилятор выдаст мусор.
Отказ от переименования. FUN_00401000 ничего не говорит. Потратьте 5 секунд на переименование каждой понятой функции — через час у вас будет читаемая карта бинарника. Этот навык экономит часы при повторном возврате к файлу.
Слепое доверие декомпилятору. Ghidra decompiler путает типы, неправильно определяет границы функций, генерирует конструкции, которых в оригинале не существовало. Псевдокод выглядит нелогично — сверяйтесь с ассемблером в Listing. Не ленитесь.
Пропуск автоанализа. Нажали «Нет» на предложение Auto Analysis — бинарник останется неразмеченным: функции не определены, строки не найдены, перекрёстные ссылки отсутствуют. Запускайте автоанализ при каждом импорте. Без исключений.
Анализ без внешней разведки. Открывать бинарник в Ghidra, не прогнав через file и strings — тратить 30 минут на поиск того, что командная строка показала бы за 10 секунд. Утилита strings часто выдаёт C2-адреса, пароли или пути к конфигурации ещё до запуска декомпилятора.
Работа без проекта. Ghidra привязывает все ваши переименования, комментарии и изменения типов к проекту. Закрыли файл вне проекта — потеряли результаты. Привычка создавать проект даже для одноразового анализа окупается.
За два года я разобрал в Ghidra больше сотни подозрительных файлов — от банальных дропперов до многослойно запакованных бэкдоров. В каждом втором случае ключевую информацию удавалось извлечь, не написав ни строчки ассемблера и не запуская отладчик. Декомпилятор закрывает основную часть задач, остальное — опыт чтения псевдокода и знание типичных паттернов вредоносного ПО.
Проблема подавляющего большинства руководств по reverse engineering для начинающих — они начинают с регистров, стека и опкодов. Человек открывает материал, видит EAX, ESP, DWORD PTR — и закрывает вкладку. Правильный путь обратный: начать с декомпилятора, научиться читать псевдокод, и только потом, когда декомпилятор выдаёт мусор, заглядывать в ассемблер за ответом. Изучение ассемблера через Ghidra происходит естественно: вы видите строку в Decompile, не понимаете её, переключаетесь на Listing — и запоминаете конкретную инструкцию в контексте реальной задачи, а не из абстрактного учебника. Через полгода такой работы ассемблер перестаёт пугать. Если хочется не ограничиваться реверсом и разложить основы ИБ по полочкам — IB Basics на codeby.school покрывает базу за пару месяцев, без требования «знать ассемблер на входе».
🚀 Хочешь закрепить на практике? Реши задачи по теме на HackerLab — категория «pentest-machines».
0 комментариев
Пожалуйста, войдите, чтобы оставить комментарий.
Загрузка комментариев...