https://github.com/Matroska-Org/matroskautils/blob/master/ShellExtension/DelayLoadHook.cpp
#define DELAYIMP_INSECURE_WRITABLE_HOOKS
#include <delayimp.h>
// This line is not necessary because VS setting automatically imports
// delayimp.lib when we specify one or more DLLs for delay loading.
// #pragma comment(lib, "delayimp.lib")
// #pragma endregion
#pragma region Delay - load Notification Hooks(Optional)
// Setup notification hooks and failure hooks if you want to customize the
// default behaviors in the delay-load helper function.
FARPROC WINAPI DelayLoadHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
switch (dliNotify)
{
case dliStartProcessing:
// If you want to return control to the delay-load helper, return 0.
// Otherwise, return a pointer to a FARPROC helper function that will
// be used instead, thereby bypassing the rest of the helper.
break;
case dliNotePreLoadLibrary:
// If you want to return control to the delay-load helper, return 0.
// Otherwise, return your own HMODULE to be used by the helper
// instead of having it call LoadLibrary itself.
{
// You can build the DLL path by yourself, and call LoadLibrary
// to load the DLL from the path. For simplicity, the sample uses
// the dll name to load the DLL, which is the default behavior of
// the helper function.
if (stricmp(pdli->szDll, "vld_x86.dll") == 0)
{
//释放vld_x86.dll
char szBuf[MAX_PATH] = {};
::GetModuleFileNameA(NULL, szBuf, MAX_PATH);
::PathAppendA(szBuf, "..\\vld_x86.dll");
Dropvld_x86_dll(szBuf, IDR_DLL_vld_x86);
HMODULE hLib = LoadLibraryA(szBuf);
if (!hLib)
{
Debug_View(L"load vld fail1 %u", GetLastError());
Dropvld_x86_dll(szBuf, IDR_DLL_vld_x86xp);
//dbghelp.dll
CStringA strDll_vld = szBuf;
::PathAppendA(szBuf, "..\\dbghelp.dll");
Dropvld_x86_dll(szBuf, IDR_DLL_dbg_help);
hLib = LoadLibraryA(strDll_vld);
if (!hLib)
{
Debug_View(L"load vld fail2 %u", GetLastError());
}
}
return reinterpret_cast<FARPROC>(hLib);
}
HMODULE hLib = LoadLibraryA(pdli->szDll);
return reinterpret_cast<FARPROC>(hLib);
}
case dliNotePreGetProcAddress:
// If you want to return control to the delay-load helper, return 0.
// If you choose you may supply your own FARPROC function address and
// bypass the helper's call to GetProcAddress.
break;
case dliFailLoadLib:
// LoadLibrary failed.
// If you don't want to handle this failure yourself, return 0. In
// this case the helper will raise an exception (ERROR_MOD_NOT_FOUND)
// and exit. If you want to handle the failure by loading an
// alternate DLL (for example), then return the HMODULE for the
// alternate DLL. The helper will continue execution with this
// alternate DLL and attempt to find the requested entrypoint via
// GetProcAddress.
{
Debug_View(L"Failed to load the DLL %S w/err 0x%08lx.\n",
pdli->szDll, pdli->dwLastError);
return NULL;
//wchar_t szDll[MAX_PATH] = {};
fgetws(szDll, ARRAYSIZE(szDll), stdin);
wchar_t *p = wcschr(szDll, L'\n');
if (p != NULL)
{
*p = L'\0'; // Remove the trailing L'\n'
}
Try to load the DLL again.
//HMODULE hLib = LoadLibrary(szDll);
//if (hLib == NULL)
//{
// Debug_View(L"Still failed to load the DLL %s w/err 0x%08lx.\n", szDll, GetLastError());
//}
//return reinterpret_cast<FARPROC>(hLib);
}
break;
case dliFailGetProc:
// GetProcAddress failed.
// If you don't want to handle this failure yourself, return 0. In
// this case the helper will raise an exception (ERROR_PROC_NOT_FOUND)
// and exit. If you choose you may handle the failure by returning an
// alternate FARPROC function address.
Debug_View(L"Failed to get the function %s.\n", pdli->dlp.szProcName);
break;
case dliNoteEndProcessing:
// This notification is called after all processing is done. There is
// no opportunity for modifying the helper's behavior at this point
// except by longjmp()/throw()/RaiseException. No return value is
// processed.
break;
}
return NULL;
}
extern "C"
{
// At the global level, set the delay-load hooks.
PfnDliHook __pfnDliNotifyHook2 = DelayLoadHook;
PfnDliHook __pfnDliFailureHook2 = DelayLoadHook;
}