// // DelayImp.h // // define structures and prototypes necessary for delay loading of imports // #if !defined(_delayimp_h) #define _delayimp_h #if _MSC_VER > 1000 #pragma once #endif #ifndef DELAYLOAD_VERSION #ifdef _WIN64 #define DELAYLOAD_VERSION 0x200 #else #define DELAYLOAD_VERSION 0x100 #endif #endif #if defined(__cplusplus) #define ExternC extern "C" #else #define ExternC #endif typedef IMAGE_THUNK_DATA * PImgThunkData; typedef const IMAGE_THUNK_DATA * PCImgThunkData; typedef DWORD RVA; typedef struct ImgDelayDescrV2 { DWORD grAttrs; // attributes RVA rvaDLLName; // RVA to dll name RVA rvaHmod; // RVA of module handle RVA rvaIAT; // RVA of the IAT RVA rvaINT; // RVA of the INT RVA rvaBoundIAT; // RVA of the optional bound IAT RVA rvaUnloadIAT; // RVA of optional copy of original IAT DWORD dwTimeStamp; // 0 if not bound, // O.W. date/time stamp of DLL bound to (Old BIND) } ImgDelayDescrV2, * PImgDelayDescrV2; typedef struct ImgDelayDescrV1 { DWORD grAttrs; // attributes LPCSTR szName; // pointer to dll name HMODULE * phmod; // address of module handle PImgThunkData pIAT; // address of the IAT PCImgThunkData pINT; // address of the INT PCImgThunkData pBoundIAT; // address of the optional bound IAT PCImgThunkData pUnloadIAT; // address of optional copy of original IAT DWORD dwTimeStamp; // 0 if not bound, // O.W. date/time stamp of DLL bound to (Old BIND) } ImgDelayDescrV1, * PImgDelayDescrV1; #if DELAYLOAD_VERSION >= 0x0200 typedef ImgDelayDescrV2 ImgDelayDescr; typedef PImgDelayDescrV2 PImgDelayDescr; #else typedef ImgDelayDescrV1 ImgDelayDescr; typedef PImgDelayDescrV1 PImgDelayDescr; #endif typedef const ImgDelayDescr * PCImgDelayDescr; enum DLAttr { // Delay Load Attributes dlattrRva = 0x1, // RVAs are used instead of pointers }; // // Delay load import hook notifications // enum { dliStartProcessing, // used to bypass or note helper only dliNotePreLoadLibrary, // called just before LoadLibrary, can // override w/ new HMODULE return val dliNotePreGetProcAddress, // called just before GetProcAddress, can // override w/ new FARPROC return value dliFailLoadLib, // failed to load library, fix it by // returning a valid HMODULE dliFailGetProc, // failed to get proc address, fix it by // returning a valid FARPROC dliNoteEndProcessing, // called after all processing is done, no // no bypass possible at this point except // by longjmp()/throw()/RaiseException. }; typedef struct DelayLoadProc { BOOL fImportByName; union { LPCSTR szProcName; DWORD dwOrdinal; }; } DelayLoadProc; typedef struct DelayLoadInfo { DWORD cb; // size of structure PCImgDelayDescr pidd; // raw form of data (everything is there) FARPROC * ppfn; // points to address of function to load LPCSTR szDll; // name of dll DelayLoadProc dlp; // name or ordinal of procedure HMODULE hmodCur; // the hInstance of the library we have loaded FARPROC pfnCur; // the actual function that will be called DWORD dwLastError;// error received (if an error notification) } DelayLoadInfo, * PDelayLoadInfo; typedef FARPROC (WINAPI *PfnDliHook)( unsigned dliNotify, PDelayLoadInfo pdli ); // utility function for calculating the index of the current import // for all the tables (INT, BIAT, UIAT, and IAT). __inline unsigned IndexFromPImgThunkData(PCImgThunkData pitdCur, PCImgThunkData pitdBase) { return (unsigned)(pitdCur - pitdBase); } // C++ template utility function for converting RVAs to pointers // #if defined(_WIN64) && defined(_M_IA64) #pragma section(".base", long, read, write) ExternC __declspec(allocate(".base")) extern IMAGE_DOS_HEADER __ImageBase; #else ExternC extern IMAGE_DOS_HEADER __ImageBase; #endif #if defined(__cplusplus) template X * PFromRva(RVA rva, const X *) { return (X*)(PBYTE(&__ImageBase) + rva); } #else __inline void * WINAPI PFromRva(RVA rva, void *unused) { return (PVOID)(((PBYTE)&__ImageBase) + rva); } #endif // // Unload support // // routine definition; takes a pointer to a name to unload // #if DELAYLOAD_VERSION >= 0x0200 ExternC BOOL WINAPI __FUnloadDelayLoadedDLL2(LPCSTR szDll); #else ExternC BOOL WINAPI __FUnloadDelayLoadedDLL(LPCSTR szDll); #endif // structure definitions for the list of unload records typedef struct UnloadInfo * PUnloadInfo; typedef struct UnloadInfo { PUnloadInfo puiNext; PCImgDelayDescr pidd; } UnloadInfo; // the default delay load helper places the unloadinfo records in the list // headed by the following pointer. ExternC extern PUnloadInfo __puiHead; // // Exception information // #define FACILITY_VISUALCPP ((LONG)0x6d) #define VcppException(sev,err) ((sev) | (FACILITY_VISUALCPP<<16) | err) // utility function for calculating the count of imports given the base // of the IAT. NB: this only works on a valid IAT! __inline unsigned CountOfImports(PCImgThunkData pitdBase) { unsigned cRet = 0; PCImgThunkData pitd = pitdBase; while (pitd->u1.Function) { pitd++; cRet++; } return cRet; } // // Hook pointers // // The "notify hook" gets called for every call to the // delay load helper. This allows a user to hook every call and // skip the delay load helper entirely. // // dliNotify == { // dliStartProcessing | // dliPreLoadLibrary | // dliPreGetProc | // dliNoteEndProcessing} // on this call. // ExternC extern PfnDliHook __pfnDliNotifyHook; ExternC extern PfnDliHook __pfnDliNotifyHook2; // This is the failure hook, dliNotify = {dliFailLoadLib|dliFailGetProc} ExternC extern PfnDliHook __pfnDliFailureHook; ExternC extern PfnDliHook __pfnDliFailureHook2; #if DELAYLOAD_VERSION >= 0x0200 #define __pfnDliFailureHook __pfnDliFailureHook2 #define __pfnDliNotifyHook __pfnDliNotifyHook2 #endif #endif