0

関数がアプリに呼び出されないようにするために、LoadLibraryAを迂回しました。これは、「dllインジェクション」をブロックすることを目的としています。これらを見たことがない場合は、有名なCDetourライブラリを参照してください。

ライブラリのロード関数をフックし、正常に戻ることもできます。また、不明なdllがメモリにロードされるのをブロックします。任意のヒント?

bool ( __stdcall* LoadLibraryA ) ( LPCSTR );

bool LoadLibraryADetoured( LPCSTR szMsg )
{
    if( strcmp( szMsg, "MyAllowedDll.dll" ) )
        return TRUE;

    return FALSE;
}

INT APIENTRY DllMain( HMODULE hModule, DWORD dwReason, LPVOID Reserved )
{
    switch( dwReason )
    {
        case DLL_PROCESS_ATTACH:
            {
                DWORD dwRetAddress = (DWORD)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "LoadLibraryA" );
                ZChatInput = ( bool ( __stdcall* ) ( ) )LoadLibraryA( ( PBYTE )dwRetAddress, ( PBYTE )LoadLibraryADetoured );
                DisableThreadLibraryCalls( hModule );
                break;
            }
        case DLL_THREAD_ATTACH:
        case DLL_PROCESS_DETACH:
            DetourRemove( ( PBYTE )dwRetAddress, ( PBYTE )LoadLibraryADetoured );
        case DLL_THREAD_DETACH:
            break;
    }
    return TRUE;
}
4

2 に答える 2

2

MSDNによると、で安全に実行できることには厳しい制限がありますDllMain()LoadLibrary()確かにそこは安全ではありません。

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583%28v=vs.85%29.aspxから:

Kernel32.dllは、エントリポイント関数が呼び出されたときにプロセスアドレス空間に読み込まれることが保証されているため、Kernel32.dllで関数を呼び出しても、初期化コードが実行される前にDLLが使用されることはありません。したがって、エントリポイント関数は、他のDLLをロードしないKernel32.dllの関数を呼び出すことができます。たとえば、DllMainは、クリティカルセクションやミューテックスなどの同期オブジェクトを作成し、TLSを使用できます。残念ながら、Kernel32.dllには安全な関数の包括的なリストはありません。

(大胆な強調は私のものです)

于 2012-06-22T21:56:46.660 に答える
0

迂回は、迂回される関数と同じ呼び出し規約を使用する必要があります。 LoadLibraryA()を使用します__stdcallが、迂回路はコンパイラのデフォルトを使用します。これは通常、__cdecl代わりに使用されます。

于 2012-06-22T22:32:03.207 に答える