От исходника к машинному коду: компиляция
Понимаем, что именно мы реверсим: как исходник становится байтами.
Компиляция — превращение исходного кода в машинный код, понятный процессору.
Этапы превращения C в исполняемый файл
- Препроцессор — раскрывает
#includeи макросы. - Компилятор — переводит C в ассемблер.
- Ассемблер — превращает ассемблер в объектный файл (машинный код + таблицы).
- Компоновщик (linker) — собирает объектные файлы и библиотеки в один исполняемый файл.
main.c --препроцессор--> main.i --компилятор--> main.s --ассемблер--> main.o --линкер--> a.out
Что теряется по дороге
Это ключевая идея реверса. Машинный код не содержит:
- имён переменных и функций (если убраны отладочные символы);
- комментариев;
- исходной структуры кода (циклы и условия превращаются в переходы);
- типов (компилятор знает, реверсер — восстанавливает).
Поэтому реверс — это не просто «обратная компиляция»: часть информации потеряна навсегда, и её приходится восстанавливать по смыслу.
Простой пример
Функция на C:
int add(int a, int b) {
return a + b;
}
Превращается в примерно такой ассемблер (x86-64, упрощённо):
add:
mov eax, edi ; первый аргумент a в eax
add eax, esi ; прибавить второй аргумент b
ret ; вернуть результат (он в eax)
Имена a и b исчезли — остались регистры edi, esi (так передаются аргументы).
Как работает под капотом: оптимизации
Компилятор с включённой оптимизацией (-O2) может радикально изменить код: убрать ненужные переменные, развернуть циклы, заменить умножение сдвигами, встроить (inline) функции. Поэтому оптимизированный бинарь читать сложнее — структура не похожа на исходник.
Частые ошибки
- Ждать, что в бинаре будут имена переменных. Обычно их нет.
- Думать, что один к одному восстановишь исходник. Восстанавливается логика, а не текст.
Итог
- Путь: исходник → препроцессор → компилятор → ассемблер → линкер → исполняемый файл.
- По дороге теряются имена, комментарии, структура и типы.
- Оптимизации компилятора усложняют реверс.
Проверьте себя
1. Что из перечисленного НЕ сохраняется в обычном машинном коде без отладочных символов?
AИнструкции процессора
BИмена локальных переменных и комментарии
CАдреса функций
DКонстанты-числа
2. Какой инструмент собирает несколько объектных файлов и библиотек в один исполняемый файл?
AПрепроцессор
BКомпилятор
CКомпоновщик (linker)
DДизассемблер