4

見つからないアセンブリをダウンロードするために、LoadLibraryへの呼び出しをフックしたいと思います。管理されたアセンブリを処理するResolveAssemblyのハンドラーがありますが、管理されていないアセンブリも処理する必要があります。

「MicrosoftWindows用のアプリケーションのプログラミング」で指定された手法でインポートテーブルを書き直してLoadLibrary呼び出しをフックしようとしましたが、WriteProcessMemory()を呼び出すと、アクセス許可拒否エラー(998)が発生します。(はい、私たちは高い特権で実行しています)

CLRがロードされている間にインポートテーブルを書き直すことに成功した人はいますか?誰かが私を正しい方向に向けることができますか?

更新:アクセス許可が拒否される問題を解決しましたが、混合アセンブリ(管理対象+非管理対象)のインポートテーブルを反復処理すると、mscoree.dllのみが見つかります。ネイティブインポートを見つける方法を知っている人はいますか?(私たちはC ++ / CLIで作業しています)。

4

4 に答える 4

10

マネージコードから正常にフックしました。ただし、アンマネージDLLをリモートプロセスに挿入し、DllMainのインポートテーブルを書き換えてもらいました。この方法を検討することをお勧めします。

これが私のフッキング機能です:

//structure of a function to hook
struct HookedFunction {
public:
    LPTSTR moduleName;
    LPTSTR functionName;
    LPVOID newfunc;
    LPVOID* oldfunc;
};

BOOL Hook(HMODULE Module, struct HookedFunction Function) {
    //parse dos header
    IMAGE_DOS_HEADER* dos_header = (IMAGE_DOS_HEADER*)Module;
    if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) return 0; //not a dos program

    //parse nt header
    IMAGE_NT_HEADERS* nt_header = (IMAGE_NT_HEADERS*)(dos_header->e_lfanew + (SIZE_T)Module);
    if (nt_header->Signature != IMAGE_NT_SIGNATURE) return 0; //not a windows program

    //optional header (pretty much not optional)
    IMAGE_OPTIONAL_HEADER optional_header = nt_header->OptionalHeader;
    if (optional_header.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) return 0; //no optional header

    IMAGE_IMPORT_DESCRIPTOR* idt_address = (IMAGE_IMPORT_DESCRIPTOR*)(optional_header.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + (SIZE_T)Module);
    if (!optional_header.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size) return 0; //no import table

    //enumerate the import dlls
    BOOL hooked = false;
    for(IMAGE_IMPORT_DESCRIPTOR* i = idt_address; i->Name != NULL; i++)
        //check the import filename
        if (!_stricmp(Function.moduleName, (char*)(i->Name + (SIZE_T)Module)))
            //enumerate imported functions for this dll
            for (int j = 0; *(j + (LPVOID*)(i->FirstThunk + (SIZE_T)Module)) != NULL; j++)
                //check if the function matches the function we are looking for
                if (!_stricmp(Function.functionName, (char*)(*(j + (SIZE_T*)(i->OriginalFirstThunk + (SIZE_T)Module)) + (SIZE_T)Module + 2) )) {
                    //replace the function
                    LPVOID* memloc = j + (LPVOID*)(i->FirstThunk + (SIZE_T)Module);
                    if (*memloc != Function.newfunc) { //not already hooked
                        DWORD oldrights;
                        DWORD newrights = PAGE_READWRITE;
                        VirtualProtect(memloc, sizeof(LPVOID), newrights, &oldrights);
                        if (Function.oldfunc && !*Function.oldfunc)
                            *Function.oldfunc = *memloc;
                        *memloc = Function.newfunc;
                        VirtualProtect(memloc, sizeof(LPVOID), oldrights, &newrights);
                    }
                    hooked = true;
                }

    return hooked;
}
于 2009-04-21T02:31:21.000 に答える
7

動作するはずですが、代わりに迂回路(または無料のN-CodeHook)を使用してみてください。
迂回は、Win32バイナリをインストルメント化するほとんど事実上の方法です。

于 2009-04-20T20:02:53.400 に答える
2

WriteProcessMemory()を呼び出す前にVirtualProtect()を呼び出すことで指定された問題を解決し、その後、保護レベルを復元するために再度呼び出します。これにより、IATが存在するメモリの読み取り専用保護が一時的に削除されます。これは私たちにとってうまく機能し、LoadLibrary()が呼び出されたときの問題を解決します。

ここで、アンマネージアセンブリがlib(静的libではない)に対してリンクしているときにLoadLibrary()が呼び出されない理由を理解できれば...

ちなみに、DetourとN-Code Hookはどちらも素晴らしい製品のように見え、おそらく私が行くべき方法ですが、可能であればサードパーティのアセンブリを追加することは避けたいと思います。

于 2009-04-21T02:14:09.293 に答える
0

最善の方法は、LoadLibrary / LoadLibraryExをフックし、必要に応じてダウンロードを実行し、ダウンロードしたファイルをチェーンに渡すことです。ただし、そのダウンロード中にGUIがブロックされるのではないかと心配しています。

于 2009-04-20T22:18:45.350 に答える