1. Инструменты и окружение: ассемблер, линковка, отладка, дизассемблер
Инструменты и окружение: ассемблер, линковка, отладка, дизассемблер
Реверс-инжиниринг на x86-64 почти всегда начинается не с написания кода, а с чтения уже скомпилированных бинарников: просмотр секций, дизассемблирование, отладка, понимание соглашений о вызовах и того, что делает компоновщик.
В этой статье соберём минимально достаточный набор инструментов и разберём, как они связаны между собой: от исходника на ассемблере до исполняемого файла, а затем обратно — к дизассемблеру и отладчику.
Что вы будете уметь после статьи
.asm, .o, ELF, PE, секции, символы, релокацииfile, readelf, objdump, stringsgdb и понимать, что именно вы там видите!Диаграмма показывает путь от исходника до бинарника и обратно к анализу
Платформа и базовые понятия
В курсе мы ориентируемся на x86-64 (AMD64). Это архитектура команд процессора. А вот конкретная среда зависит от ОС и формата исполняемых файлов:
Далее примеры будут в первую очередь для Linux, потому что там проще показать все этапы инструментами командной строки. Но концепции (объектный файл, линковка, отладка, дизассемблирование) одинаковые.
Ассемблер: что это и какой выбрать
Ассемблер — программа, которая переводит текст с мнемониками (mov, call, ret) в машинный код и упаковывает результат в объектный файл.
На x86-64 чаще всего вы встретите два синтаксиса:
mov rax, rbxmov %rbx, %raxДля реверса важно уметь читать оба, но для практики курса удобнее Intel.
NASM
NASM популярен в учебных примерах и небольших проектах.
.oПример команды сборки объекта:
GNU assembler (as)
GNU as обычно идёт в комплекте с GNU binutils и тесно интегрирован с gcc.
Часто as используют через gcc, но можно и напрямую.
Почему реверсеру важен выбор ассемблера
Потому что:
Объектный файл: что внутри .o
Объектный файл — это ещё не программа. Обычно он содержит:
.text, .data, .rodata)В Linux объектный файл часто имеет формат ELF типа relocatable.
Полезные команды:
file быстро говорит, что это за файлreadelf -h показывает заголовок ELFreadelf -S показывает список секцийreadelf -s показывает символыДокументация:
Линковка: как из .o получается исполняемый файл
Линковщик (компоновщик) собирает один или несколько объектных файлов в итоговый бинарник. Он:
printf из libc)В Linux вы можете линковать напрямую через ld, но чаще используют gcc, потому что он автоматически добавляет стандартные библиотеки и корректные флаги.
Линковка через ld
Это сработает только для программ, которые не требуют libc и правильно оформлены (например, используют системные вызовы напрямую).
Документация: ld(1)
Линковка через gcc
Так проще получить рабочую программу, использующую стандартную библиотеку.
Статическая и динамическая линковка
.so библиотеки во время запускаДля реверса важно понимать, что динамически связанные вызовы часто проходят через PLT и GOT (в ELF), и это заметно в дизассемблере.
PIE и ASLR
Современные дистрибутивы часто собирают исполняемые файлы как PIE (position-independent executable). Это помогает ASLR (рандомизации адресов) и влияет на отладку:
Проверить тип ELF можно так:
Полезный термин: entry point — адрес, с которого начинается выполнение.
Отладка: gdb как инструмент реверса
Отладчик позволяет исполнять программу под контролем: ставить брейкпоинты, шагать по инструкциям, смотреть регистры и память.
Установка и запуск
Запуск:
Минимальный набор команд gdb
break main — поставить брейкпоинт на main (если символы доступны)run — запуститьsi — step instruction, шаг по одной инструкцииni — next instruction, “перешагнуть” вызов callinfo registers — посмотреть регистрыx/16gx $rsp — посмотреть 16 8-байтных слов по адресу стекаdisassemble — дизассемблировать текущую функциюПодсказка: gdb умеет показывать дизассемблер в Intel-синтаксисе:
Отладочная информация (DWARF) и флаги
Если вы компилируете или собираете пример сами, полезно добавить отладочную информацию. В мире C/C++ это обычно флаг -g. Для ассемблера зависит от инструмента.
Смысл простой:
Для реверса “чужих” релизных бинарников отладочной информации обычно нет, поэтому важно уметь работать и без неё.
Дизассемблирование: objdump и друзья
Дизассемблер переводит машинный код обратно в текст инструкций. Это не “обратная сборка” исходника: часть информации потеряна (имена переменных, типы, комментарии).
objdump
Показать дизассемблирование:
Показать дизассемблирование с символами (если есть):
Подсказка: чтобы видеть Intel-синтаксис в GNU инструментах, часто используют опцию:
strings
Иногда самое полезное — найти строки, по которым можно понять назначение кода.
hexdump
Чтобы увидеть “сырые” байты:
Статический анализ: Ghidra, IDA, radare2
Командные утилиты хороши для точечной проверки, но для большого реверса обычно используют полноценные платформы.
Ghidra
Ghidra — бесплатная платформа для анализа, включает дизассемблер и декомпилятор.
Что особенно полезно:
IDA
IDA Pro — индустриальный стандарт (коммерческий продукт).
radare2
Консольный фреймворк для анализа и реверса.
Динамический анализ: strace
Иногда проще понять программу не по инструкциям, а по тому, какие системные вызовы она делает.
Пример:
Это особенно полезно для:
Минимальный набор инструментов для курса
Ниже — практичный набор, которого хватит для старта (Linux).
nasm
- gcc (как драйвер линковки)
- ld (чтобы понимать линковку напрямую)
file, readelf, objdump, strings
gdb
Если вы на Windows, концептуально аналогичные роли:
Типичные ошибки новичков и как их избегать
readelf (структура), objdump (инструкции), gdb (поведение)
.o может не иметь точки входа и не запускается
Что дальше по курсу
Следующий шаг — собрать и запустить самый простой пример на x86-64 (например, Hello World), чтобы руками пройти цепочку: ассемблирование, линковка, запуск, дизассемблирование и отладка. После этого мы начнём разбирать базовые инструкции и шаблоны, которые вы постоянно увидите в чужом ассемблере.