如果真的想要抓出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的參數
執行畫面
沒有留言:
張貼留言