2009-04-20 14 views
4

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

"Microsoft Windowsアプリケーションのプログラミング"で指定された方法でインポートテーブルを書き直してLoadLibrary呼び出しをフックしようとしましたが、WriteProcessMemory()を呼び出すときにエラー998が拒否されました。 (はい、昇格したprivで実行しています)

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

更新:我々は許可拒否された問題を解決し、私たちは混合アセンブリ(アンマネージド+管理)の輸入表を反復処理するとき、今、私たちが見つける唯一のエントリはにmscoree.dllです。誰もネイティブの輸入品を見つける方法を知っていますか? (私たちはC++/CLIで作業しています)。

答えて

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; 
} 
7

代わりにdetours(または無料のN-CodeHook)を使用してください。
Detoursはほとんどの場合、Win32バイナリをインストルメントする事実上の方法です。

+1

...またはあなたが持っている(また、64ビットをサポートしているN-CodeHook(http://newgre.net/ncodehook)のようなオープンソースのlibを使用することができます – newgre

+0

@jn:自己宣伝:)次回は、コードインジェクションに対処する必要がありますが、私は迂回路が私のためにうまく機能していることを認めなければなりません。 APIのミラーリングについて考えましたか?既存の迂回アプリケーションが簡単に移行できるようにする –

+0

私を得ました;-)実際には、私はそれを考えていません。それを私のtodoリストに載せます。 thx – newgre

0

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

2

WriteProcessMemory()を呼び出す前に、VirtualProtect()を呼び出して、指定した問題を解決した後、再度呼び出して保護レベルを復元しました。これにより、IATが常駐するメモリの読み取り専用保護が一時的に削除されます。これは私たちのためにうまく動作し、LoadLibrary()が呼び出されたときの問題を解決します。 LIBに対する管理されていないアセンブリのリンク(ない静的libに)...

ところで

、迂回とN-Code Hookの両方が見えるときのLoadLibrary()が呼び出されない理由を私はちょうど把握することができた場合に今

すてきな製品のようで、私が行かなければならない可能性が最も高いですが、可能ならばサードパーティのアセンブリを追加しないようにしたいと考えています。

+0

これは簡単です。 4つのバリアント(LoadLibraryA、LoadLibraryW、LoadLibraryExA、LoadLibraryExW)をフックしていません。 – Joshua

関連する問題