3

ゲームのランチャーを開発しています。テキストを出力する関数のゲームの呼び出しをインターセプトしたい。

この関数を含むコードが動的にリンクされているか静的にリンクされているかはわかりません。そのため、関数名もわかりません。

私は、Microsoft Detours、Ninject などを通じて、このゲームのいくつかの windows-api 呼び出しを傍受しました。

しかし、これもインポートテーブルにはありません。

この関数呼び出しをキャッチするにはどうすればよいですか? どのプロファイラーを使用する必要がありますか? アイダ?これはどのように行うことができますか?


編集:

最後に関数アドレスが見つかりました。ありがとう、スキノ!

Detours でフックしようとして、dll を注入しました。注入された DllMain:

typedef int (WINAPI *PrintTextType)(char *, int, float , int);

static PrintTextType PrintText_Origin = NULL;

int WINAPI PrintText_Hooked(char * a, int b, float c, int d)
{
    return PrintText_Origin(a, b, c , d);
}

HMODULE game_dll_base;
/* game_dll_base initialization goes here */

BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    if(fdwReason==DLL_PROCESS_ATTACH)
    {
        DisableThreadLibraryCalls(hinstDLL);
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        PrintText_Origin = (PrintTextType)((DWORD)game_dll_base + 0x6049B0);
        DetourAttach((PVOID *)&PrintText_Origin , PrintText_Hooked);
        DetourTransactionCommit();
    }
}

予想通り引っ掛かります。パラメータaには、表示されるべきテキストがあります。ただし、元の関数を呼び出すとreturn PrintText_Origin (a, b, c , d);アプリケーションがクラッシュします( http://i46.tinypic.com/ohabm.pnghttp://i46.tinypic.com/dfeh4.png )

元の関数の分解:

http://pastebin.com/1Ydg7NED

迂回後:

http://pastebin.com/eM3L8EJh

EDIT2:

迂回後:

http://pastebin.com/GuJXtyad

PrintText_Hooked逆アセンブリhttp://pastebin.com/FPRMK5qt w3_loader.dllは注入された dll です

私は ASM が苦手です。何が問題なのか教えてください。

4

2 に答える 2

1

テキストを出力する関数のゲームの呼び出しをインターセプトしたい。

調査段階ではデバッガを使用できます。IDA、または Visual Studio (たとえば HxD と組み合わせて) のいずれかで行う必要があります。以下の手順を使用して、関数を特定するのは比較的簡単です。

  1. 印刷をトレースしたいテキストの特定の断片を識別します (例: Hello World!)
  2. 上記で特定したフラグメントをゲームが正常に出力するの任意の時点で、ゲームの実行を中断します。
  3. ゲームのメモリ内でそのテキスト†</sup>のフラグメントを検索します( Unicode または ANSI を探します)。IDA では、無料のHxD ( > )と同様に、その IIRC を実行できます。ExtrasOpen RAM...
  4. フラグメントのアドレスが特定されたら、ブレーク オン アクセス/読み取りデータ ブレークポイントを設定して、ゲームがそのフラグメントを読み取ろうとする瞬間(表示中または表示の直前) にデバッガーが制御できるようにします。
  5. 実行を再開し、データブレークポイントがトリガーされるのを待ちます
  6. スタック トレースを調べて、フックに適した候補を探します
  7. 追加の潜在的なフック ポイントを調べたい場合は、フラグメントがメモリから読み取られた瞬間から出力されるまでステップスルーします。

†提供されたテキストは、最後の瞬間まで圧縮されていません (または、何らかの理由で暗号化されていません)

調査フェーズが完了し、フックを挿入する場所を特定したら、 launcher を作成するときに 2 つのオプションがあります

  1. 上記の演習に基づいて、最終的にエクスポート/インポートを特定できた場合は、任意の API フック手法を使用してください。
  2. EDIT Microsoft Detours を使用して、迂回しようとしている関数の呼び出し規約(cdecl、fastcall、stdcall)を最初に正しく識別し、その呼び出し規約を元のプロトタイプと実装の両方に使用します。ダミー。を参照してください。
  3. そうでない場合は、する必要があります
    • Debugging APIを使用してプログラムでゲームをロードする
    • 調査フェーズに基づいてフック アドレスを計算します (モジュール ベースからのハードコードされたオフセットとして、またはフック サイト周辺の命令バイトを探すことによって‡</sup>) 。
    • ブレークポイントを設定する
    • プロセスを再開する
    • ブレークポイントがトリガーされるのを待ち、必要なことは何でも実行します
    • 実行を再開し、次のトリガーを待つなど、すべてランチャーによって Debugging API を介してプログラムで行われます

‡ゲームの最終的なパッチ リリースで引き続き作業できるようにするため

于 2012-11-24T15:32:53.067 に答える
1

この段階では、フックしようとしているライブラリ関数の概念がないように聞こえますが、それは (明らかに少なくとも) インポート テーブルにインポートされた外部関数ではないと述べています。テキストを生成する責任は、直接逆アセンブルするか動的にロードするアプリケーションの .text 内にある可能性が高く、テキスト生成 (特にゲーム内) はアプリケーションの一部である可能性があります。

私の経験では、このような追跡が困難なコードを見つける最も簡単な方法は、テキストが表示されている間、またはその前後にアプリケーションを停止し、IDA の優れたコールグラフ機能を使用して、それを書き出す原因を特定することです (ウォッチとブレークポイントを自由に使用してください!)

インポート テーブルに表示されないエクスポートされた関数によってこの機能が提供される可能性があると考える理由がある場合は、 CreateRemoteThreadまたはその他の一般的に使用される動的読み込みメカニズムの呼び出しを注意深く調べてください。

強くお勧めしませんが、完全を期すために、システム サービス ディスパッチ テーブルで NtSetInformationThread をフックすることもできます。ここに、さまざまな Windows バージョンの表の適切なダンプがあります。テーブルのインデックスを自分で取得したい場合は、ntdll.dll から NtSetInformationThread エクスポートを逆アセンブルするだけです。

于 2012-11-24T07:01:39.483 に答える