Ghidra
NSA が開発した逆アセンブラツール。
しかも無料というのだから、これまたすごいの一言です。
IDA Pro はものすごく便利なツールですが、ライセンス料が高いので導入のハードルがかなり高いです。
なので、今回は Ghidra でのコード移植のやり方を紹介します。
::: tip
IDA Pro でできることのほとんどが Ghidra でできます。
:::
JDK
Ghidra の実行には JDK(JAVA)が必要なので、公式サイトからインストールしましょう。
Java Archive Downloads - Java SE 11
インストールが終わったら Path を通してください。
メモリの変更
Ghidra はデフォルトでは 1024MB しかメモリを使ってくれないのですが、これだとメモリが足りずに解析失敗するかもしれないので最低でも 2048MB は確保したほうがいいでしょう。
ghidraRun.bat
:: Ghidra launch
@echo offsetlocal
:: Maximum heap memory size:: Default for Windows 32-bit is 768M and 64-bit is 1024M:: Raising the value too high may cause a silent failure where:: Ghidra fails to launch.:: Uncomment MAXMEM setting if non-default value is needed
set MAXMEM=2048M
call "%~dp0support\launch.bat" bg Ghidra "%MAXMEM%" "" ghidra.GhidraRun %*
こんな感じでコメントを外して好きな値をいれれば OK。
一応 1024MB でも解析できたけど、余裕があるならそれ以上に設定しておこう。
Ghidra の使い方
いくつかのパートに分けて Ghidra の使い方を解説していきたいと思います。
Loader の導入
NSO をそのまま読み込むには Loader が必要なのですが、今現在の最新のGhidra-Switch-LoaderはGhidra 9.1.2にしか対応していないため、旧バージョンを使う必要があります。
インストール出来たら Ghidra を起動して File -> Install Extension を選択してください。
右上の + ボタンを押して、ダウンロードした zip ファイルを直接指定してください。
Ghidra の再起動が要求されると思うので、再起動しましょう。
::: tip
この作業は ELF を分析する場合は不要です。
復号はnx2elfですることができます。
:::
バイナリの分析
まずは実行ファイルである NSO/ELF を分析します。
起動するとプロジェクトを作成するように指示されます。プロジェクト名は適当に決めてしまいましょう。
次に、分析するファイルをドラッグアンドドロップするか、Select File Import からファイルを選択してください。
[ファイル名] has not been analyzed. Would you like to analyze it now?(分析済みではないので分析しますか?)というダイアログが表示されるので Yes を選択します。
Analysis Options はとりあえずデフォルトでチェックが入っているものだけにしました。デフォルトで全く問題なかったので多分これでオッケー。
Analyze をクリックすると分析が始まります。右下の表示で分析中なことがわかりますね。
分析のスピードは使用しているマシンの CPU のスペックに依存します。
i7 6700K で実行したところ約 20 分くらい、MacBook Pro 2019 だと 40 分くらいかかりました。気長に待ちましょう。
コードの移植
移植に関して言えば基本的に命令部は弄る必要がないので、正しいアドレスの位置さえ指定してあげれば良いことになります。
バイト検索
長くなるので時間ができたときに書きます。
文字列検索
文字列検索を利用するコード移植の例としては試し打ち場の置換などが上げられます。では、その方法を解説しましょう。
// ShootingRange Replacements (5.0.0) [AmazingChz]@disabled023FCACA "Fld_Crank00_Vss"
試し打ち場のパラメータ名はFld_ShootingRange_Shr
なのでそれを検索してみましょう。
Search -> Program Text を開きます。
Labels にチェックを入れましょう。
Next と Previous は現在のカーソルからの相対位置で検索し、Search All は全範囲で検索します。
Ghidra で NSO を直接分析した場合にはアドレスが 7100000000 ズレる事がわかっているので、仮に 7102412414 見つかったとしたら、IPSwitch 形式だと 02412414 となるわけです。
// ShootingRange Replacements (5.0.1) [AmazingChz]@disabled02412414 "Fld_Crank00_Vss"
Urchin Underpass = Fld_Crank00_VssSaltspray Rig = Fld_Seaplant00_VssMuseum d'Alfonsino = Fld_Pivot00_VssMahi-Mahi Resort = Fld_Hiagari00_VssHammerhead Bridge = Fld_Kaisou00_VssFlounder Heights = Fld_Jyoheki00_VssAncho-V-Games = Fld_Office01_VssArowna Mall = Fld_UpDown01_VssBlackbelly Skatepark = Fld_SkatePark02_VssCamp Triggerfish = Fld_Athletic01_VssGoby Arena = Fld_Court00_VssHumpback Pump Track = Fld_Wave00_VssInkblot Art Academy = Fld_Upland00_VssKelp Dome = Fld_Maze02_VssMakoMart = Fld_Line00_VssManta Maria = Fld_Pillar00_VssMoray Towers = Fld_Tuzura00_VssMusselforge Fitness = Fld_Unduck00_VssPiranha Pit = Fld_Quarry02_VssPort Mackerel = Fld_Amida01_VssShellendorf Institute = Fld_Tunnel00_VssSnapper Canal = Fld_Kawa01_VssStarfish Mainstage = Fld_Venue02_VssSturgeon Shipyard = Fld_Nagasaki00_VssThe Reef = Fld_Ditch02_VssWahoo World = Fld_Carousel00_VssWalleye Warehouse = Fld_Warehouse01_VssNew Albacore Hotel = Fld_Nakasu00_VssSkipper Pavilion = Fld_Mirror00_VssLost Outpost = Fld_Shakehouse00_CopMarooner's Bay = Fld_Shakeship00_CopSalmonid Smokeyard = Fld_Shakelift00_CopSpawning Grounds = Fld_Shakeup01_CopStaff Roll = Fld_StaffRoll00_StfTutorial = Fld_Tutorial00_TtrOld Starfish Mainstage = Fld_Venue00_VssShifty Station = Fld_Deli_Octa51_Vss
オフセット
逆アセンブラの種類と解析するファイルの種類によって ELF を IDA で解析したときに比べてアドレスがズレるのでその値を覚えて置かなければいけません。
逆アセンブラ | オフセット |
---|---|
GHIDRA (NSO) | +0x7100000000 |
GHIDRA (ELF) | +0x0000100000 |
IDA Pro (NSO) | +0x7100000000 |
IDA Pro (ELF) | 0 |
まとめ
というわけで、今回は Ghidra の使い方やコードの移植のやり方について簡単に解説してみました。
もしわからないことがあれば以下のリンクから Discord サーバに参加して、直接きいていただければ返事します。
記事は以上。