Гибридный анализ crackme на Linux x86-64 (определение структур на стеке)

Тема в разделе "WASM.RESEARCH", создана пользователем sutulin, 14 авг 2026 в 10:36.

Метки:
  1. sutulin

    sutulin New Member

    Публикаций:
    0
    Регистрация:
    Сегодня
    Сообщения:
    1
    Здравствуйте, коллеги.

    Разбираю crackme на Linux x86-64 с использованием гибридного анализа (Ghidra + GDB). Бинарник скомпилирован с оптимизациями (-O1). В процессе столкнулся с интересной проблемой, которую хотел бы обсудить с сообществом.

    В декомпилированном коде Ghidra я вижу локальные переменные, которые по логике должны быть полями одной структуры (предположительно std::string). Однако из-за оптимизации пролога компилятор отказался от использования RBP как базы кадра стека (Frame Pointer Omission) и все переменные доступны через смещения от RSP.

    Вот как Ghidra интерпретирует эти переменные (упрощенно, из кода main):

    Код (Text):
    1. undefined1 *local_78; // Указатель
    2. long local_70; // Переменная, используемая в проверке длины
    3. undefined1 local_68[16]; // Буфер
    При этом Ghidra ошибочно определяет размер структуры std::string как 40 байт, хотя в libstdc++ она занимает 32. В итоге, реальные смещения, которые я вычислил для GDB, не совпадают с теми, что предлагает Ghidra.

    Мой основной вопрос: как вы, при анализе оптимизированных C++ бинарников, точно определяете границы структур на стеке, когда Ghidra вводит в заблуждение размерами переменных? Используете ли вы какие-то специфические техники или скрипты для Ghidra, чтобы вручную задавать правильные структуры?

    Для наглядности я подготовил подробную статью, где шаг за шагом описал весь процесс и свои рассуждения. Буду признателен, если кто-то из опытных коллег взглянет и укажет на возможные слабые места в моем подходе. Это первая статья из трёх. Прежде чем выкладывать следующие две, решил обсудить с вами, не заблуждаюсь ли:

    https://habr.com/ru/articles/1068160/

    Надеюсь на конструктивные комментарии.
     
  2. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    2.231
    История о том, как написать диссертацию о 8 байтах выравнивания. Как я понял std::string это объект, string в гидре встроенный тип строки с нулетерминатором. То есть вообще мимо. Возможно кое-кто этот тип на переменную применил вручную. Можно было бы задаться вопросом с какой стати вообще гидра должна из коробки знать тип std::string. А потом сделать скрипт, который зарегистрирует нужные типы и будет подтягивать их к прототипам процедур/методов.
    изображение_2026-08-14_143025662.png