如果真的想要抓出DLL錯誤的內容可以使用從VC6時就已經添加的功能Delay Load DLL來幫助我們達成目標,至於如何使用,就讓我們繼續看下去。
以下使用執行程式常用到的Windwos DLL(MFC100.dll、MSVCR100.dll、MSVCP100.dll)來做試驗與實際操作的部份做介紹。
後續再介紹自行開發DLL使用Delay Load DLL的差異。
#include <windows.h>
#include <delayimp.h>
#pragma comment(lib, "Delayimp.lib")
//#pragma comment(linker, "/DelayLoad:mfc100.dll") //將DelayLoad直接放在CPP中,經證實這種做法不可行
//#pragma comment(linker, "/Delay:unload")
CWinApp theApp;
FARPROC WINAPI DelayLoadHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
printf("DelayLoadHook:\n");
switch (dliNotify)
{
case dliStartProcessing:
printf("\tdliStartProcessing...\n");
// 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:
printf("\tdliNotePreLoadLibrary...\n");
// 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.
}*/
break;
case dliNotePreGetProcAddress:
printf("\tdliNotePreGetProcAddress...\n");
// 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 :
printf("\tdliFailLoadLib...\n");
// 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.
break;
case dliFailGetProc :
printf("\tdliFailGetProc...\n");
// 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.
printf("Failed to get the function %s.\n", pdli->dlp.szProcName);
break;
case dliNoteEndProcessing :
printf("\tdliNoteEndProcessing...\n");
// 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;
}
printf("\tDLL(HMODULE) = %s(0x%08X)\n", pdli->szDll, pdli->hmodCur);
if (pdli->dlp.fImportByName) {
printf("\tProc = %s\n", pdli->dlp.szProcName);
} else {
printf("\tOrdinal = 0x%08x\n", pdli->dlp.dwOrdinal);
}
return NULL;
}
PfnDliHook __pfnDliNotifyHook2 = DelayLoadHook;
PfnDliHook __pfnDliFailureHook2 = DelayLoadHook;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
//CString csTemp = "123";//可開啟看看執行後的畫面
printf("\n//////////////////////////////////////////////////////////////////////////\n\n");
return nRetCode;
}
設定Linker的參數執行畫面



沒有留言:
張貼留言