Этот экспериментальный плагин Ghidra позволяет вам легко работать с собственной эмуляцией pcode. Никакие скрипты больше не нужны, просто используйте его прямо из Ghidra. Это может быть особенно полезно для работы с различными экзотическими процессорами, которые не поддерживаются распространенными эмуляторами.
Если процессор/виртуальная машина поддерживается Ghidra для обратного проектирования, его можно эмулировать! Например, ниже показана эмуляция инструкций eBPF:
По сути, плагин представляет собой расширенную оболочку классов внутри пакета ghidra.app.emulator
. Вот что было реализовано:
Хотя эмуляция PCode в идеале подразумевает унификацию, большинству процессоров нужен собственный подход. Не стесняйтесь сообщать о любых проблемах, с которыми вы столкнулись. Очень хотелось бы протестировать все процессоры, но вряд ли это возможно.
Содержит все окна плагина: представление стека, регистры, представление точек останова и главное окно.
Содержит горячие клавиши для установки начала и окончания эмуляции, точек останова и применения измененных байтов к состоянию эмулятора.
Меняйте регистры как хотите. Установка регистра связи (зеленая стрелка) поможет эмулятору понять, в каком регистре находится обратный адрес. Плагин знает, как он работает, через стек, регистр lr, регистры AARCH64 и MIPS. Если у вас экзотический, выберите регистр ссылок и нажмите кнопку.
Когда вы открываете свою программу в СodeBrowser, GhidraEmu автоматически отображает пространство стека. Указатель стека будет установлен в середине диапазона стека. Это позволяет вам устанавливать значения вверху или внизу кадров стека. Прокрутите его, если у вас возникли зависания при обновлении или сбросе настроек. Если в процессе эмуляции программе потребуется больше места для стека, плагин выделит его автоматически.
Если какие-либо байты изменятся во время эмуляции, вы увидите их в классическом ByteViewer. Не волнуйтесь, после нажатия кнопки «Сброс» они вернутся к исходным значениям.
Если вы внесли изменения, сообщите эмулятору об измененных байтах (стек обновляется автоматически — в этом нет необходимости). После изменения выберите их (они будут зелеными) и нажмите эту опцию (или используйте горячую клавишу «М»).
Здесь плагин печатает выходную информацию. Например, сообщения об ошибках эмуляции выглядят следующим образом:
Функция «Перейти» позволяет перейти на одну инструкцию вперед, если по какой-то причине вы не хотите эмулировать текущую. Поскольку процесс эмуляции будет прерван при обнаружении попытки чтения неинициализированной памяти, данная возможность позволяет обойти ее. Посмотрите пример. Вот одна из первых инструкций во многих программах x86_64 — канареечное сохранение стека:
MOV RAX, qword ptr FS:[0x28]
Мы просто попробуем немного схитрить и перепрыгнуть через это, увеличив значение ПК. Для этого остановитесь на инструкции, которую вы не хотите эмулировать, и нажмите горячую клавишу J
В противном случае дальнейшее движение приведет к ошибке чтения неинициализированной памяти.
Если вы остановились на инструкции, ведущей к подпрограмме (внутренний вызов), и хотите эмулировать все до следующей инструкции (классический «шаг через»), нажмите горячую клавишу F6
, и это обязательно произойдет:
Несколько важных моментов, которые следует учитывать :
Используйте gradle для создания расширения: GHIDRA_INSTALL_DIR=${GHIDRA_HOME} gradle
и используйте Ghidra для его установки: File → Install Extensions...
В CodeBrowser перейдите в File → Configure → Miscellaneous
и установите флажок для плагина GhidraEmu.
Обнаружили какие-либо ошибки при использовании плагина или у вас есть идеи по улучшению? Не стесняйтесь открывать новый вопрос, а я разберусь.
Ограничения EmulatorHelper не позволяют использовать пространство программы в другом. Таким образом, ваша внешняя общая библиотека, например, никогда не узнает о пространстве памяти программы, и наоборот. Поэтому вы не можете эмулировать его как один процесс с одним пространством памяти. Дайте мне знать, если я что-то здесь упустил.