Pコード分析を備えたGOバイナリで文字列定義を回復するためのスクリプト。 X86、X86-64、ARM、およびARM64でテストしました。
これらは、スクリプトマネージャーのGolangカテゴリにあります。
GoDynamicStrings.javaGoFuncCallStrings.javaGoStaticStrings.javaGoKnownStrings.javadata/known_strings.jsonからロードされます。GoStringFiller.javago.string.*最初の分析後、文字列データの昇順の長さの順序に基づいています。動的文字列分析スクリプトの特別なバリエーションもいくつかあります。
GoDynamicStringsSingle.javaGoDynamicStrings.javaと同じ分析を実行しますが、単一の分解プロセスを使用します。バイナリを分析すると、並列処方プロセスがシステムメモリを排出する場合にこれを使用します。GoDynamicStringsHigh.javaこれは、スクリプトマネージャーのPCODEカテゴリにあります。
PrintHighPCode.javaこれらのスクリプトを使用してGOバイナリで文字列定義を回復するための一般的なフローは次のとおりです。
.rodata 、 .rdata 、または__rodataのすべての文字列を選択します。次に、コードリストを右クリックして、「クリアコードバイト」を選択します。GoKnownStrings.javaを実行して、いくつかの標準文字列を検出します。GoStaticStrings.javaを実行します。GoFuncCallStrings.javaを実行します(GolangバイナリバージョンがGhidraの組み込みGolang機能によってサポートされている場合) 。GoDynamicStrings.javaを実行します。GoStringFiller.javaを実行します。go.string.*最初の1バイト文字列で作成します。go.string.*の残りのギャップを確認し、明らかな開始点とエンドポイントを持つ文字列を定義します。GoStringFiller.javaを最大限に活用するには、未定義の文字列データの文字列の長さがどこに変化しているかを特定し、その境界に最も近い文字列を定義します。次に、 GoStringFiller.javaを再実行して、残りの未定義の文字列の長さを正しく決定できるスポットを自動的に埋めます。ギドラで:
Ghidradevプラグインを使用したEclipseの場合:
Eclipseでビルド:
Gradleで直接構築する:
$ cd Ghostrings
$ gradle -PGHIDRA_INSTALL_DIR= < ghidra_install_dir > リバースエンジニアリングGOプログラムの有名な問題は、GO文字列にヌルターミネーターが不足しているため、コンパイルされたバイナリからの文字列定義を回復することが困難になることです。 GOプログラムの一定の文字列値の多くは、コンパイルされたビルドの1つの巨大なブロブに一緒に保存されます。ターミネーター文字が文字列データに組み込まれて、1つの文字列が終了し、別の文字列が始まる場所をマークします。 「Hello World!」を印刷するだけのシンプルなプログラムでさえもGOランタイムシステムおよびその他の標準ライブラリに関連する1,500以上の文字列があります。これにより、Ghidraが提供するような典型的なASCII String Discoveryの実装により、数万文字の誤った肯定的な文字列定義が作成されます。
NULLの終了文字列の代わりに、GOはポインターと長さの値で構成される文字列構造を使用します。これらの文字列構造の多くは、実行時にプログラムのスタックに作成されるため、個々の文字列の開始場所と長さの値を回復するには、コンパイルされたマシンコードを分析する必要があります。 x86-64命令の特定のパターンをチェックすることでこの分析を実行する既存のスクリプトがいくつかありますが、最終的にはスタックに同じ効果をもたらす命令の未処理のバリエーションで作成された構造を見逃し、特定のISAにも制限されています。
GhoStringsは、Ghidraの逆コンパイラ分析によって生成された簡略化されたアーキテクチャに依存しないPコード操作と協力することにより、これらの両方の問題を回避します。
著作権2022 NCCグループ。 GPLV3ライセンスの下でリリースされます(ライセンスを参照)。
主なプロジェクト著者:James Chambers [email protected]