めいくりぷとのブログ

技術的なことやゲームのことやら・・・

マニュアルマッピングされたシステムモジュールをアンロードして、正規のモジュールにすり替える。

    EXTERN_C
    NTSTATUS
    NTAPI LdrLoadDll(
        _In_  PWCHAR          PathToFile OPTIONAL,
        _In_  ULONG           Flags OPTIONAL,
        _In_  PUNICODE_STRING ModuleFileName,
        _Out_ PHANDLE         ModuleHandle
        );
 
    VOID Detour_LdrLoadDll()
    {
        static decltype(&LdrLoadDll) _LdrLoadDll = LdrLoadDll;
 
        decltype(&LdrLoadDll) LdrLoadDll_Hook = [](
            _In_  PWCHAR          PathToFile OPTIONAL,
            _In_  ULONG           Flags OPTIONAL,
            _In_  PUNICODE_STRING ModuleFileName,
            _Out_ PHANDLE         ModuleHandle) -> NTSTATUS
        {
            IMAGE_EXPORT_DIRECTORY *pExportDirectory;
            NTSTATUS ntStatus;
            HMODULE  hModule;
            HMODULE  hModuleOriginal;
 
            ntStatus = _LdrLoadDll(PathToFile, Flags, ModuleFileName, ModuleHandle);
            if (NT_SUCCESS(ntStatus))
            {
                hModule = reinterpret_cast<HMODULE>(*ModuleHandle);
                if (hModule != NULL)
                {
                    pExportDirectory = ImageExportDirectory(reinterpret_cast<PVOID>(hModule));
                    if (pExportDirectory != NULL)
                    {
                        hModuleOriginal = GetModuleHandleA(reinterpret_cast<LPCSTR>(PBYTE(hModule) + pExportDirectory->Name));
                        if (hModuleOriginal != NULL &&
                            hModuleOriginal != hModule)
                        {
                            // _tprintf(L"%p, %s\n", hModule, ModuleFileName->Buffer);
                            FreeLibrary(hModule);
                            *ModuleHandle = hModuleOriginal;
                        }
                    }                  
                }
            }
 
            return ntStatus;
        };
 
        DetourFunction(TRUE, reinterpret_cast<LPVOID*>(&_LdrLoadDll), LdrLoadDll_Hook);
    }