FridaとEasyHook

投稿日: 2025-07-06

とあるオンラインゲームで自分のキャラクターの座標を取得する必要があったのでその時に使った方法をまとめます。 ここには具体的なコードなどは書かず、大まかな流れを書きます。


使用したツール

Frida

https://frida.re/

Frida用のスクリプトを書いて注入することでアプリの動作を変更したり、付属のツールで動作している関数やその関数の引数・戻り値を見ることができます。
WindowsだけでなくiOSやAndroidでも使えます。
今回は調査のために使いました。

EasyHook

https://easyhook.github.io/

WindowsAPIの動作を書き換えるためのライブラリです。 C++とC#から利用できますが、今回はC#で利用しました。


Fridaを使ってキャラクター座標を引数や戻り値にとる関数を探す

関数を探す方法は2つあると思います。
もしWindowsプログラミングに詳しいのであれば、APIのリストを見ながらこの関数は間違いなく使っているだろうという予想から探す方法。
もう一つはキーワードから探す方法で、欲しいデータが文字列であれば関数名にはStringが含まれているだろう、などと予想しながら探す方法です。

自分は最終的にDebugという単語からWindowsAPIのOutputDebugStringAという関数にたどり着きました。
これはWindowsアプリケーションを開発するときにデバッガに文字列を渡すための関数です。
ここでキャラクターの座標が含まれる文字列がデバッガに渡されているのに気づきました。
おそらくゲーム開発者が開発時に使用していたのを消し忘れたか、意図的に残したままにしたのだと思います。

Fridaを使ってOutputDebugStringAに渡された文字列を表示している様子

https://www.youtube.com/watch?v=q8kJkovifzs


EasyHookを使って値を取得し、他のアプリに渡す

まずはEasyHookを使ってフック用のOutputDebugStringAを実装します。
実装した関数はDLLとして保存し、EasyHookのAPIを使って自分のアプリからゲームに対して読み込ませます。
ゲームが元々使っていたOutputDebugStringAを自作のOutputDebugStringAに置き換えるイメージです。
ただし今回やりたいことは関数に渡された文字列を取得したいだけなので、元の実装を邪魔しないように文字列取得部分だけを追加します。
元の関数に渡された引数をそのまま渡し、戻り値もそのまま返すことで、元の実装に影響を与えません。
DLLから自分のアプリにデータを渡すために、今回はMemoryMappedFileを使いました。

擬似コード


function myOutputDebugStringA(argument) {
  // アプリに文字列を渡す
  sharedMemoryAccessor.write(argument);
  // オリジナルの実装を呼び出す
  return OutputDebugStringA(argument);
}

https://www.youtube.com/watch?v=Tsnz0WHfQZs

EasyHookの使い方は公式のチュートリアルが参考になると思います

https://easyhook.github.io/tutorials