7

私はメモリアドレスを持っています。それは別のプログラム(そのdllの1つ)の関数のメモリアドレスです。私はすでにDLLインジェクションを介してプログラムにロードされています。私はすでに低音アドレスと、プログラムがロードされるたびに関数の実際の場所を持っています。したがって、これは問題ではありません。

その場所をフックして、変数を取得したいだけです。関数の擬似コードを知っています。したがって、これは問題ではありません。または、そのメモリ位置でブレークポイントを実行してデバッグレジスタを取得することもできます。

この明確な例は見つかりません。関数の「名前」もありません。メモリアドレスだけがあります。メモリアドレスだけを操作する方法はありますか?すべてではないにしても、ほとんどの例では、私が持っていない関数の名前を使用しています。

誰かが私を正しい方向に向けて、私がこの仕事を成し遂げることができれば、私はそれを大いに感謝します。それはまた同じ質問をするかもしれない他の多くの人々を助けるかもしれません。

編集:私はまた、他の誰かのコードでプログラムをオーバーロードするのではなく、ロールアップウィンドウを備えた基本的な車のように、必要最低限​​のものが欲しいだけであることにも言及する必要があります。贅沢なパッケージはありません。

4

2 に答える 2

7

あなたは最も重要な部分を見逃しました、これは32ビットまたは64ビットのコードですか?いずれにせよ、コードプロジェクトには、両方をカバーする優れたランダウンとライブラリがあります。

この「昔ながらの」ことをしたいのなら、それは非常に簡単に行うことができます。

まず、フックする関数の仮想アドレスを見つける必要があります(ASLRのため、同じ場所にあることに依存しないでください)。これは通常、関数のRVA+モジュールベースロードアドレスを使用して行われます。エクスポート、エクスポートされた関数には、を使用できますGetProcAddress

そこから、タイプフックは何を達成したいかによって異なります。あなたの場合、2つの方法があります。

  1. ターゲット関数のプロローグで関数にジャンプ/呼び出しをパッチします
  2. フックしたい関数にすべての呼び出しサイトにパッチを適用し、関数にリダイレクトします

1つ目は単純ですが、一般にインラインアセンブリが必要になるため(/HOTPATCHバイナリをフックしている場合やスタブしたい場合を除く)、2つ目ははるかにクリーンですが、デバッガーで少し作業が必要です。

ジャンプする関数は、フックしている関数と同じパラメーターと呼び出し規約(ABI)を持っている必要があります。この関数では、渡されたパラメーターのキャプチャ、操作、呼び出しのフィルター処理などを行うことができます。

どちらの場合も、Windowsでパッチを適用するためのアセンブリを作成する方法が必要です。これWriteProcessMemoryは、最初の呼び出しポートです(注:これを行うにはRWX権限が必要であるため、を呼び出しますVirtualProtect)。これは、作成する小さなユーティリティ関数です。 32ビットの相対呼び出しまたはジャンプ(として渡されたオペコードに応じてeType

#pragma pack(1)
struct patch_t
{
    BYTE nPatchType;
    DWORD dwAddress;
};
#pragma pack()

BOOL ApplyPatch(BYTE eType, DWORD dwAddress, const void* pTarget)
{
    DWORD dwOldValue, dwTemp;
    patch_t pWrite =
    {
        eType,
        (DWORD)pTarget - (dwAddress + sizeof(DWORD) + sizeof(BYTE))
    };

    VirtualProtect((LPVOID)dwAddress,sizeof(DWORD),PAGE_EXECUTE_READWRITE,&dwOldValue);
    BOOL bSuccess = WriteProcessMemory(GetCurrentProcess(),(LPVOID)dwAddress,&pWrite,sizeof(pWrite),NULL);
    VirtualProtect((LPVOID)dwAddress,sizeof(DWORD),dwOldValue,&dwTemp);
    return bSuccess;
}

この関数は方法2でうまく機能しますが、方法1では、元の関数に戻る前にパッチが上書きしたコードを復元するために、中間アセンブリトランポリンにジャンプする必要があります。これは非常に面倒です。既存のテスト済みライブラリを使用するだけです。

その音から、方法1を使用してパッチを適用すると、パッチを適用した関数を実行する必要がないように見えるため、ターゲット関数のプロローグをジャンプして、必要な処理を実行できます。

(HWブレークポイントを使用する3番目の方法がありますが、これは非常に脆弱であり、4つのHWブレークポイントに制限されているため問題になる可能性があります)。

于 2012-10-23T08:27:41.857 に答える
0

あなたの「サンプル」はここにあります:

http://www.codeproject.com/Articles/4610/Three-Ways-to-Inject-Your-Code-into-Another-Proces#section_1

通常、DLL に「フック」するときは、実際には呼び出される DLL 内の関数の前に関数を配置するため、代わりに関数が呼び出されます。次に、必要なものをキャプチャし、他の関数を呼び出し、その戻り値などをキャプチャしてから、元の呼び出し元に戻ります。

于 2012-10-23T08:35:26.780 に答える