Работа в дизассемблере: граф, переименование, аннотации

Превращаем сырой дизассемблер в понятную карту программы.

Граф потока управления (CFG) — схема, показывающая блоки кода и переходы между ними (ветвления, циклы).

Граф потока управления

Ghidra и IDA умеют показывать функцию не сплошным списком, а графом: прямоугольники-блоки (участки без переходов) и стрелки между ними. Видно ветвление if, тело цикла, слияние веток. Это резко упрощает понимание логики по сравнению с линейным листингом.

[проверка] --да--> [блок A] --
     |                        \
     --нет--> [блок B] -------> [конец]

Переименование

По умолчанию функции называются FUN_00401000, переменные — local_4. Как только вы поняли смысл, переименуйте: check_password, input_len. Это главный приём реверса — превращать абстрактные имена в осмысленные, постепенно «расшифровывая» программу.

Аннотации (комментарии)

Добавляйте комментарии прямо в листинг: «здесь сравнивается длина», «цикл XOR по байтам». В большой программе без заметок легко запутаться. Хороший анализ — это документированный анализ.

Кросс-ссылки (xrefs)

Очень мощный приём: «кто вызывает эту функцию?» и «откуда ссылаются на эту строку?». По кросс-ссылке от строки «Wrong password» вы мгновенно прыгаете к коду проверки. Это часто самый быстрый путь к нужному месту.

Как работает под капотом

Дизассемблер строит CFG, анализируя переходы: каждый условный/безусловный jump и call создаёт рёбра графа. Кросс-ссылки — это индекс «адрес → кто на него ссылается», который инструмент строит при загрузке файла. Переименования и комментарии хранятся в проекте инструмента, не в самом бинаре.

Частые ошибки

  • Не переименовывать — через час забудете, что значит FUN_00402130.
  • Игнорировать кросс-ссылки и искать нужное место вручную.
  • Не оставлять комментариев в сложных местах.

Итог

  • Граф потока управления делает логику наглядной.
  • Переименование и аннотации — основной рабочий приём реверсера.
  • Кросс-ссылки (xrefs) от строк и функций — быстрый путь к нужному коду.
Проверьте себя
1. Зачем реверсер переименовывает функции вроде FUN_00401000?
AЧтобы изменить поведение программы
BЧтобы постепенно делать анализ понятным, давая осмысленные имена
CЧтобы ускорить дизассемблер
DЭто обязательное требование закона
2. Как кросс-ссылка (xref) от строки помогает в анализе?
AУдаляет строку
BПозволяет мгновенно перейти к коду, который использует эту строку
CШифрует строку
DЗапускает программу с этой строкой