91 #pragma message( "hook code disabled for 64-bit builds..." )
93 #pragma message( "hook code enabled for 32-bit builds..." )
101 #define MakePtr(cast,ptr,AddValue) (cast)((DWORD_PTR)(ptr)+(DWORD_PTR)(AddValue))
119 USHORT MaximumLength;
128 typedef NTSYSAPI DWORD (NTAPI *LdrGetProcedureAddress_t)
130 __in HMODULE ModuleHandle,
132 __in_opt WORD Oridinal,
133 __out PVOID *FunctionAddress
135 typedef NTSYSAPI DWORD (NTAPI *LdrGetProcedureAddressForCaller_t)
137 __in HMODULE ModuleHandle,
139 __in_opt WORD Oridinal,
140 __out PVOID *FunctionAddress,
142 __in PVOID *CallbackAddress
148 DWORD NTAPI LocalLdrGetProcedureAddress
150 __in HMODULE ModuleHandle,
152 __in_opt WORD Oridinal,
153 __out PVOID *FunctionAddress
155 DWORD NTAPI LocalLdrGetProcedureAddressForCaller
157 __in HMODULE ModuleHandle,
159 __in_opt WORD Oridinal,
160 __out PVOID *FunctionAddress,
162 __in PVOID *CallbackAddress
190 memset(&pod,0,
sizeof(pod));
197 memset(&pod,0,
sizeof(pod));
242 static int s_iHookCount = 0;
252 static LdrGetProcedureAddress_t OriginalLdrGetProcedureAddress = 0;
253 static LdrGetProcedureAddressForCaller_t OriginalLdrGetProcedureAddressForCaller = 0;
260 static HMODULE s_hmoduleTWAIN32 = 0;
267 static DSMENTRYPROC TWAIN32_DSMEntry = 0;
285 if ( ((_DAT == DAT_NULL)
286 || (_DAT == DAT_CALLBACK && _MSG == MSG_INVOKE_CALLBACK))
291 return (
DSM_Entry(_pOrigin,_pDest,_DG,_DAT,_MSG,_pData));
294 return (TWAIN32_DSMEntry(_pOrigin,_pDest,_DG,_DAT,_MSG,_pData));
315 PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
316 PIMAGE_THUNK_DATA pOrigThunk;
317 PIMAGE_THUNK_DATA pRealThunk;
318 PIMAGE_IMPORT_BY_NAME pByName;
320 MEMORY_BASIC_INFORMATION mbi_thunk;
323 PIMAGE_DOS_HEADER pDOSHeader;
324 PIMAGE_NT_HEADERS pNTHeader;
327 char szTwain32[MAX_PATH];
328 const char *szFunctionName;
331 if (_ehook == HOOK_ATTACH)
348 memset(szTwain32,0,
sizeof(szTwain32));
349 uResult = ::GetWindowsDirectory(szTwain32,
sizeof(szTwain32)-1);
354 SSTRCAT(szTwain32,
sizeof(szTwain32)-1,
"\\TWAIN_32.DLL");
355 s_hmoduleTWAIN32 = ::LoadLibraryEx(szTwain32,NULL,DONT_RESOLVE_DLL_REFERENCES);
356 if (0 == s_hmoduleTWAIN32)
364 OriginalLdrGetProcedureAddress = 0;
365 OriginalLdrGetProcedureAddressForCaller = 0;
366 hmodule = GetModuleHandle(
"ntdll.dll");
369 szFunctionName =
"LdrGetProcedureAddressForCaller";
370 OriginalLdrGetProcedureAddressForCaller = (LdrGetProcedureAddressForCaller_t)GetProcAddress(hmodule,szFunctionName);
371 if (!OriginalLdrGetProcedureAddressForCaller)
373 szFunctionName =
"LdrGetProcedureAddress";
374 OriginalLdrGetProcedureAddress = (LdrGetProcedureAddress_t)GetProcAddress(hmodule,szFunctionName);
382 if (s_hmoduleTWAIN32)
384 ::FreeLibrary(s_hmoduleTWAIN32);
385 s_hmoduleTWAIN32 = 0;
389 if (NULL == pod.pOriginal)
395 if (OriginalLdrGetProcedureAddressForCaller)
397 szFunctionName =
"LdrGetProcedureAddressForCaller";
401 szFunctionName =
"LdrGetProcedureAddress";
412 hmodule = GetModuleHandle(
"kernelbase.dll");
413 if ( NULL == hmodule )
415 hmodule = GetModuleHandle(
"kernel32.dll");
419 pDOSHeader = (PIMAGE_DOS_HEADER)hmodule;
423 || (TRUE == IsBadReadPtr(pDOSHeader,
sizeof(IMAGE_DOS_HEADER)))
424 || (IMAGE_DOS_SIGNATURE != pDOSHeader->e_magic))
430 pNTHeader = MakePtr(PIMAGE_NT_HEADERS,pDOSHeader,pDOSHeader->e_lfanew);
433 if ( (TRUE == IsBadReadPtr(pNTHeader,
sizeof(IMAGE_NT_HEADERS)))
434 || (IMAGE_NT_SIGNATURE != pNTHeader->Signature))
440 if (0 == pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
446 pImportDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR,pDOSHeader,pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
450 while (NULL != pImportDesc->Name)
452 szCurrMod = MakePtr(PSTR,pDOSHeader,pImportDesc->Name);
453 if (0 == _stricmp(szCurrMod,
"ntdll.dll"))
463 if (NULL == pImportDesc->Name)
473 pOrigThunk = MakePtr(PIMAGE_THUNK_DATA,hmodule,pImportDesc->OriginalFirstThunk);
477 pRealThunk = MakePtr(PIMAGE_THUNK_DATA,hmodule,pImportDesc->FirstThunk);
483 while (NULL != pOrigThunk->u1.Function)
487 if (IMAGE_ORDINAL_FLAG != (pOrigThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG))
490 pByName = MakePtr(PIMAGE_IMPORT_BY_NAME,hmodule,pOrigThunk->u1.AddressOfData);
494 && (
'\0' != pByName->Name[0])
495 && (0 == _stricmp(szFunctionName,(
char*)pByName->Name)))
514 VirtualQuery(pRealThunk,&mbi_thunk,
sizeof(MEMORY_BASIC_INFORMATION));
515 if (FALSE == VirtualProtect(mbi_thunk.BaseAddress,mbi_thunk.RegionSize,PAGE_EXECUTE_READWRITE,&mbi_thunk.Protect))
521 if (_ehook == HOOK_ATTACH)
524 pod.pOriginal = (PROC)(INT_PTR)pRealThunk->u1.Function;
525 if (OriginalLdrGetProcedureAddressForCaller)
527 OriginalLdrGetProcedureAddressForCaller = (LdrGetProcedureAddressForCaller_t)pod.pOriginal;
531 OriginalLdrGetProcedureAddress = (LdrGetProcedureAddress_t)pod.pOriginal;
543 if (_ehook == HOOK_ATTACH)
545 pTemp = (DWORD_PTR*)&pRealThunk->u1.Function;
546 if (OriginalLdrGetProcedureAddressForCaller)
548 *pTemp = (DWORD_PTR)LocalLdrGetProcedureAddressForCaller;
552 *pTemp = (DWORD_PTR)LocalLdrGetProcedureAddress;
557 pTemp = (DWORD_PTR*)&pRealThunk->u1.Function;
558 *pTemp = (DWORD_PTR)(pod.pOriginal);
563 boolResult = VirtualProtect(mbi_thunk.BaseAddress,mbi_thunk.RegionSize,mbi_thunk.Protect,&dwOldProtect);
564 if (boolResult == FALSE)
584 for (
int i=0; i<count; i++)
586 if (pod.HookedDSs[i] == DSID)
606 pod.HookedDSs[s_iHookCount] = DSID;
619 for(
int i=0; i<count; i++)
621 if(pod.HookedDSs[i] == DSID)
625 pod.HookedDSs[i] = pod.HookedDSs[i+1];
627 pod.HookedDSs[i] = 0;
635 kLOG((
kLOGERR,
"Trying to removing a hook for a DSID (%d) that was never added.", DSID ));
649 DWORD NTAPI LocalLdrGetProcedureAddress
651 __in HMODULE ModuleHandle,
653 __in_opt WORD Ordinal,
654 __out PVOID *FunctionAddress
668 if (ModuleHandle == s_hmoduleTWAIN32)
671 (OriginalLdrGetProcedureAddress(ModuleHandle,FunctionName,Ordinal,(PVOID*)&TWAIN32_DSMEntry));
673 *FunctionAddress = ::DSM_HookedEntry;
674 return (ERROR_SUCCESS);
678 return (OriginalLdrGetProcedureAddress(ModuleHandle,FunctionName,Ordinal,FunctionAddress));
693 DWORD NTAPI LocalLdrGetProcedureAddressForCaller
695 __in HMODULE ModuleHandle,
697 __in_opt WORD Ordinal,
698 __out PVOID *FunctionAddress,
700 __in PVOID *CallbackAddress
714 if (ModuleHandle == s_hmoduleTWAIN32)
717 (OriginalLdrGetProcedureAddressForCaller(ModuleHandle,FunctionName,Ordinal,(PVOID*)&TWAIN32_DSMEntry,bValue,CallbackAddress));
719 *FunctionAddress = ::DSM_HookedEntry;
720 return (ERROR_SUCCESS);
724 return (OriginalLdrGetProcedureAddressForCaller(ModuleHandle,FunctionName,Ordinal,FunctionAddress,bValue,CallbackAddress));
733 HMODULE InstallTwain32DllHooks
735 const char*
const _lib,
737 const TW_UINT32 _DSID
756 if ( (s_iHookCount > 0)
757 && ((
CTwHook*)NULL != s_ptwhook))
771 if (ptwhook->
Hook(HOOK_ATTACH))
790 hmodule = ::LoadLibrary(_lib);
794 if ( (NULL == hmodule)
798 dwResult = ::GetLastError();
800 if (s_iHookCount <= 0)
806 ::SetLastError(dwResult);
819 BOOL UninstallTwain32DllHooks
821 const HMODULE _hmodule,
823 const TW_UINT32 _DSID
836 if (s_iHookCount <= 0)
846 return(::FreeLibrary(_hmodule));
853 #error error, we need to be either 32-bit or 64-bit...