Гидра великолепна, и я люблю сценарии как можно большую часть моего режима. Но сценарии Ghidra Python основаны на Jython, которого в наши дни не в большом состоянии. Установка новых пакетов - это хлопот, если они могут даже работать в среде Jython, и это будет только хуже, поскольку Python 2 медленно отключается.
Таким образом, мост Ghidra-это попытка обойти эту проблему-вместо того, чтобы застрять в Jython, настройте прокси RPC для объектов Python, чтобы мы могли вызвать Ghidra/Jython-Land, чтобы получить данные, которые нам нужны, а затем вернуть их к более современному Python со всеми пакетами, которые вам необходимы для вашей работы.
Цель состоит в том, чтобы быть настолько прозрачной, насколько это возможно, поэтому, как только вы настроите, вам не нужно знать, является ли объект локальным или от удаленной Ghidra - мост должен плавно обрабатывать/настройку/призыв к нему.
Если вам это нравится, вы также можете быть заинтересованы в эквивалентах других инструментов обратного инженера:
Если вам это действительно нравится, не стесняйтесь купить мне кофе: https://ko-fi.com/justfoxing
pip install ghidra_bridge
python -m ghidra_bridge.install_server ~/ghidra_scripts
Для лучшей интерактивной оболочки, такой как ipython или, если вам нужны библиотеки Python 3 в вашей интерактивной среде, вы можете запустить мост в контексте интерактивного сеанса GUI.
В противном случае:
Вы можете запустить Ghidra Bridge в качестве сценария после анализа для анализа без головы, а затем запустить дальнейший анализ от клиента. Используйте ghidra_bridge_server.py (не _background.py) для этого, чтобы он не выйдет, пока вы не закроете мост вниз.
$ghidraRoot/support/analyzeHeadless <path to directory to store project> <name for project> -import <path to file to import> -scriptPath <install directory for the server scripts> -postscript ghidra_bridge_server.py
См. AnalyzeHeadlessReadMe.html в поддержке/ каталоге Ghidra для получения дополнительной информации о том, как запустить команду без анализов, если это необходимо.
Вы можете запустить мост в среде без какой -либо загрузки программы, например, если вы хотите получить доступ к некоторым API, таким как DataTypeManager, который не требует анализируемой программы
$ghidraRoot/support/pythonRun <install directory for the server scripts>/ghidra_bridge_server.py
От клиентской среды Python:
import ghidra_bridge
with ghidra_bridge . GhidraBridge ( namespace = globals ()):
print ( getState (). getCurrentAddress (). getOffset ())
ghidra . program . model . data . DataUtilities . isUndefinedData ( currentProgram , currentAddress )или
import ghidra_bridge
b = ghidra_bridge . GhidraBridge ( namespace = globals ()) # creates the bridge and loads the flat API into the global namespace
print ( getState (). getCurrentAddress (). getOffset ())
# ghidra module implicitly loaded at the same time as the flat API
ghidra . program . model . data . DataUtilities . isUndefinedData ( currentProgram , currentAddress )ПРЕДУПРЕЖДЕНИЕ: Если вы работаете в режиме без Background, избегайте нажатия кнопки «Отмена» во всплывающем окне сценария, так как это оставит серверный розетка в плохом состоянии, и вам придется полностью закрыть Ghidra, чтобы исправить его.
Чтобы выключить сервер чисто, если вы сделали шаг 3 в инструкциях по установке выше, нажмите «Инструменты»-> ghidra bridge-> weplowd. В противном случае запустите сценарий ghidra_bridge_server_shutdown.py из папки моста.
В качестве альтернативы вы можете вызвать remote_shutdown от любого подключенного клиента.
import ghidra_bridge
b = ghidra_bridge . GhidraBridge ( namespace = globals ())
b . remote_shutdown ()Имейте в виду, что при запуске сервер Ghidra Bridge эффективно обеспечивает выполнение кода в качестве услуги. Если злоумышленник может поговорить с мостом Порт -Гидры, он может тривиально получить выполнение с привилегиями, с которыми управляется ghidra.
Также имейте в виду, что протокол, используемый для отправки и получения сообщений моста Ghidra, не зашифрован и не вывершен-атака человека в среднем уровне позволит полностью управлять командами и ответами, снова обеспечивая тривиальное выполнение кода на сервере (и с небольшим количеством работы на клиенте).
По умолчанию сервер Ghidra Bridge только слушает Localhost, чтобы немного уменьшить поверхность атаки. Слушайте только внешние сетевые адреса, если вы уверены, что находитесь в сети, где это безопасно. Кроме того, злоумышленники по -прежнему могут отправлять сообщения в Localhost (например, через злонамеренный JavaScript в браузере или путем использования другого процесса и атаки моста Ghidra, чтобы поднять привилегии). Вы можете смягчить этот риск, запустив мост Ghidra с сервера Ghidra с уменьшенными разрешениями (пользователь, не являющийся админом, или внутри контейнера), запустив его только при необходимости или запуская в не сетевых системах.
Мост Ghidra предназначен для прозрачного, чтобы обеспечить легкое перенос не мостиковых сценариев без слишком большого количества изменений. Однако, если вы рады внести изменения, и вы сталкиваетесь с замедлением, вызванными большим количеством удаленных запросов (например, что -то вроде for function in currentProgram.getFunctionManager().getFunctions(): doSomething() может быть довольно медленным с большим количеством функций, так как каждая функция приведет к сообщению в мосту), что вы можете использовать, что вы сможете использовать все, что можно будет использовать, чтобы вы могли быть навещанием, что будет навсегда, что можно будет использовать на сервере. Требуется только одно сообщение об обратном пути.
Следующий пример демонстрирует получение списка всех имен всех функций в двоичном режиме:
import ghidra_bridge
b = ghidra_bridge . GhidraBridge ( namespace = globals ())
name_list = b . remote_eval ( "[ f.getName() for f in currentProgram.getFunctionManager().getFunctions(True)]" )Если ваша оценка займет некоторое время, вам может потребоваться использовать аргумент timeout_override, чтобы увеличить, как долго мост будет ждать, прежде чем решать, что вещи пойдут не так.
Если вам необходимо предоставить аргумент для удаленной оценки, вы можете предоставить произвольные аргументы ключевых слов для функции remote_eval, которая будет передана в контекст оценки как локальные переменные. Следующий аргумент проходит в функции:
import ghidra_bridge
b = ghidra_bridge . GhidraBridge ( namespace = globals ())
func = currentProgram . getFunctionManager (). getFunctions ( True ). next ()
mnemonics = b . remote_eval ( "[ i.getMnemonicString() for i in currentProgram.getListing().getInstructions(f.getBody(), True)]" , f = func )В качестве упрощения, также обратите внимание, что контекст оценки имеет те же глобалы, загруженные в __main__ сценария, который запустил сервер - в случае сервера моста Ghidra, они включают в себя плоский API и значения, такие как текущая программа.
Если в вашем сценарии есть особенно медленный вызов, он может нанести удар по тайм -ауту ответа, который мост использует, чтобы убедиться, что соединение не сломалось. Если это произойдет, вы увидите что -то вроде Exception: Didn't receive response <UUID> before timeout .
Есть два варианта увеличения тайм -аута. При создании моста вы можете установить значение тайм -аута за несколько секунд с аргументом repply_timeout (например, b = ghidra_bridge.GhidraBridge(namespace=globals(), response_timeout=20) ), что будет применяться ко всем командам, проходящим через мост. В качестве альтернативы, если вы просто хотите изменить тайм -аут для одной команды, вы можете использовать remote_eval, как упомянуто выше, с аргументом timeout_override (например, b.remote_eval("[ f.getName() for f in currentProgram.getFunctionManager().getFunctions(True)]", timeout_override=20) ). Если вы используете значение -1 для любого из этих аргументов, тайм -аут отклика будет отключен, и мост навсегда будет ждать, пока ваш ответ вернется - обратите внимание, что это может привести к тому, что ваш сценарий висит, если мост столкнется с проблемами.
Если вы хотите импортировать модули с Ghidra (например, Ghidra, Java, стыковки имен), у вас есть два варианта.
remote_module = b.remote_import("java.math.BigInteger") ). Это имеет то преимущество, что у вас есть точный контроль над получением удаленного модуля (и можете получить удаленные модули с тем же именем, что и локальные модули), и когда он выпущен, но это требует немного больше работы.b = ghidra_bridge.GhidraBridge(namespace=globals(), hook_import=True) ). Это добавит крючок в импортный механизм, так что, если ничто другое не может заполнить импорт, мост попытается справиться с ним. Это позволяет просто использовать стандартный import ghidra.framework.model.ToolListener после подключения моста. Это имеет то преимущество, что он может быть немного проще в использовании (вам все равно нужно убедиться, что импорт произошел после подключения моста), но он не позволяет вам импортировать удаленные модули с тем же названием, что и локальные модули (локальный импорт имеет приоритет), и он ставит удаленные модули в Sys.Modules, что и надлежащий импорт, поэтому они и мост останутся до тех пор, пока не будут нагружаться в процесс. Кроме того, несколько мостов с помощью Hook_import = true попытаются разрешить импорт в том порядке, в котором они были подключены, что может быть не тем поведением, которое вы хотите.Обычно сценарии Ghidra получают экземпляр состояния Гидры и текущих* переменных* (CurrentProgram, CurrentAddress и т. Д.) При первом запуске, и он не обновляется, пока сценарий работает. Однако, если вы запускаете интерпретатор Ghidra Python, он обновляет его состояние с каждой командой, так что CurrentDress всегда соответствует графическому интерфейсу.
Чтобы отразить это, Ghidrabridge автоматически попытается определить, используете ли вы клиент в интерактивной среде (например, интерпретатор Python, ipython) или просто из сценария. Если это интерактивная среда, она зарегистрирует слушателя событий с Ghidra и выполнит несколько сомнительных закулисных махинаций, чтобы убедиться, что государство обновляется с помощью графического интерфейса, чтобы вести себя как интерпретатор Ghidra Python. Он также заменит help() на тот, который протягивает руку, чтобы использовать помощь Гидры по всему мосту, если вы дадите ему мостовой объект.
Вам не нужно заботиться об этом, но если по какой-то причине автоматическое обнаружение не дает вам необходимого вам результата, вы можете указать аргумент логического интерактивного_моде при создании клиента Ghidrabridge, чтобы заставить его включить или выключить по мере необходимости.
Фактический код RPC моста реализован в JFX-Bridge. Проверьте это там и подайте конкретные проблемы, не связанные с негидрой, связанные с мостом.