
Native Pcode emulator
Этот экспериментальный плагин для Ghidra позволяет легко работать с эмуляцией нативного pcode. Больше не нужны скрипты — просто используйте его напрямую из Ghidra. Он может быть особенно полезен для работы с самыми разными экзотическими процессорами, которые не поддерживаются обычными эмуляторами.
Если процессор/ВМ поддерживается Ghidra для реверс-инжиниринга, его можно эмулировать! Например, ниже продемонстрирована эмуляция инструкций eBPF:

По сути, плагин представляет собой расширенную обёртку над классами из пакета ghidra.app.emulator. Вот что реализовано:
Хотя эмуляция PCode в идеале подразумевает унификацию, большинству процессоров нужен свой подход. Не стесняйтесь сообщать о любых возникающих проблемах. Я бы очень хотел протестировать все процессоры, но это вряд ли возможно.

Содержит все окна плагина: представление стека, регистры, представление точек останова и главное окно.

Содержит горячие клавиши для установки начала и конца эмуляции, точек останова и применения изменённых байтов к состоянию эмулятора.
Изменяйте регистры как хотите. Установка регистра связи (зелёная стрелка) поможет эмулятору понять, какой регистр содержит адрес возврата. Плагин знает, как это работает через стек, регистр lr, а также регистры AARCH64 и MIPS. Если у вас экзотический регистр, выберите регистр связи и нажмите кнопку.
Когда вы открываете программу в CodeBrowser, GhidraEmu автоматически сопоставит пространство стека. Указатель стека будет установлен в середине диапазона стека. Это позволяет устанавливать значения в верхней или нижней части стековых кадров. Прокрутите его, если столкнётесь с зависаниями при обновлении или сбросе. В процессе эмуляции, если программе потребуется больше места для стека, плагин выделит его автоматически.
Если во время эмуляции изменятся какие-либо байты, вы увидите их в классическом ByteViewer. Не волнуйтесь, после нажатия кнопки "Reset" они будут сброшены к исходным значениям.
Если вы внесли изменения, сообщите эмулятору об изменённых байтах (стек обновляется автоматически — этого делать не нужно). После изменения выберите их (они будут зелёными) и нажмите этот пункт меню (или воспользуйтесь горячей клавишей "M").

Здесь плагин выводит информацию. Например, сообщения об ошибках эмуляции, как здесь:

Функция «Jump Over» позволяет перепрыгнуть на одну инструкцию вперёд, если вы по какой-то причине не хотите эмулировать текущую. Поскольку процесс эмуляции будет прерван при обнаружении попытки чтения неинициализированной памяти, эта функция позволяет обойти это. Посмотрите на пример. Вот одна из первых инструкций во многих программах x86_64 — сохранение канарейки стека:
MOV RAX, qword ptr FS:[0x28]
Мы просто попробуем немного схитрить и перепрыгнуть через неё, увеличив значение PC. Для этого остановитесь на инструкции, которую не хотите эмулировать, и нажмите горячую клавишу J. В противном случае дальнейший шаг приведёт к ошибке чтения неинициализированной памяти.

Если вы остановитесь на инструкции, которая ведёт к подпрограмме (внутреннему вызову), и захотите эмулировать всё вплоть до следующей инструкции (классический «step over»), нажмите горячую клавишу F6, и это обязательно произойдёт:

Несколько важных моментов, которые следует учесть:
Используйте gradle для сборки расширения: GHIDRA_INSTALL_DIR=${GHIDRA_HOME} gradle, а затем установите его через Ghidra: File → Install Extensions...
В CodeBrowser перейдите в File → Configure → Miscellaneous и установите флажок для плагина GhidraEmu.
Обнаружили какие-либо баги при использовании плагина или есть идеи по улучшению? Не стесняйтесь открыть новый issue, и я разберусь.
Ограничения EmulatorHelper не позволяют использовать программное пространство в другом. Так что ваша внешняя общая библиотека, например, никогда не узнает о пространстве памяти программы, и наоборот. Поэтому вы не можете эмулировать это как один процесс с единым пространством памяти. Дайте мне знать, если я что-то упускаю.