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。因此,入口点函数可以调用 Kernel32.dll中不加载其他 DLL的函数。例如,DllMain 可以创建临界区和互斥锁等同步对象,并使用 TLS。不幸的是,Kernel32.dll 中没有安全函数的完整列表。

(粗体强调是我的)

于 2012-06-22T21:56:46.660 回答
0

您的 detour 需要使用与被 detoured 的函数相同的调用约定。 LoadLibraryA()使用__stdcall,但您的绕道使用编译器默认值,通常是__cdecl

于 2012-06-22T22:32:03.207 回答