
Скрипты Ghidra для восстановления определений строк в Go-бинарниках
Скрипты для восстановления определений строк в Go-бинарниках с помощью P-Code анализа. Протестировано на x86, x86-64, ARM и ARM64.
Их можно найти в категории Golang в Script Manager.
GoDynamicStrings.java
GoFuncCallStrings.java
GoStaticStrings.java
GoKnownStrings.java
data/known_strings.json.GoStringFiller.java
go.string.* после первичного анализа, основываясь на возрастающем порядке длины строковых данных.Также есть несколько особых вариаций скрипта динамического анализа строк:
GoDynamicStringsSingle.java
GoDynamicStrings.java, но использует один процесс декомпилятора. Используйте этот вариант, если анализ бинарника приводит к исчерпанию системной памяти параллельными процессами декомпилятора.GoDynamicStringsHigh.java
Его можно найти в категории PCode в Script Manager.
PrintHighPCode.java
Ниже описан общий порядок использования этих скриптов для восстановления определений строк в Go-бинарнике:
.rodata, .rdata или __rodata. Затем щёлкните правой кнопкой мыши в листинге кода и выберите "Clear Code Bytes".GoKnownStrings.java для обнаружения некоторых стандартных строк.GoStaticStrings.java.GoFuncCallStrings.java (если версия Golang-бинарника поддерживается встроенными функциями Golang в Ghidra).GoDynamicStrings.java.GoStringFiller.java.
go.string.* на первой однобайтовой строке.В Ghidra:
Для Eclipse с плагином GhidraDev:
Сборка в Eclipse:
Сборка напрямую с помощью Gradle:
$ cd Ghostrings
$ gradle -PGHIDRA_INSTALL_DIR=<ghidra_install_dir>
Хорошо известная проблема при реверс-инжиниринге Go-программ заключается в том, что отсутствие нулевых терминаторов в Go-строках затрудняет восстановление определений строк из скомпилированных бинарников. Многие константные строковые значения Go-программы хранятся вместе в одном огромном блоке в скомпилированной сборке, без каких-либо символов-терминаторов в строковых данных, которые отмечали бы, где заканчивается одна строка и начинается другая. Даже простая программа, которая просто выводит "Hello world!", содержит более 1500 строк, связанных с системой выполнения Go и другими стандартными библиотеками. Это может привести к тому, что типичные реализации обнаружения ASCII строк, например, та, что встроена в Ghidra, будут создавать ложноположительные определения строк длиной в десятки тысяч символов.
Вместо строк с нулевым терминатором Go использует строковую структуру, состоящую из указателя и значения длины. Многие из этих строковых структур создаются в стеке программы во время выполнения, поэтому восстановление отдельных начальных позиций строк и значений длины требует анализа скомпилированного машинного кода. Существует несколько существующих скриптов, которые выполняют этот анализ, проверяя определённые шаблоны инструкций x86-64, но они пропускают структуры, создаваемые с помощью необработанных вариаций инструкций, которые в конечном итоге оказывают то же воздействие на стек, а также они ограничены конкретной ISA.
Ghostrings избегает обеих этих проблем, работая с упрощёнными, архитектурно независимыми операциями P-Code, создаваемыми анализом декомпилятора Ghidra.
Copyright 2022 NCC Group. Выпущено под лицензией GPLv3 (см. LICENSE).
Основной автор проекта: James Chambers [email protected]
go.string.* и определите все строки с очевидными начальной и конечной точками.
GoStringFiller.java, определите места, где длины строк меняются в неопределённых строковых данных, и определите строки, ближайшие к этой границе. Затем запустите GoStringFiller.java повторно, чтобы автоматически заполнить места, где он может корректно определить длину оставшихся неопределённых строк.