От исходника к машинному коду: компиляция

Понимаем, что именно мы реверсим: как исходник становится байтами.

Компиляция — превращение исходного кода в машинный код, понятный процессору.

Этапы превращения C в исполняемый файл

  1. Препроцессор — раскрывает #include и макросы.
  2. Компилятор — переводит C в ассемблер.
  3. Ассемблер — превращает ассемблер в объектный файл (машинный код + таблицы).
  4. Компоновщик (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Дизассемблер