1 #include "HookImportFunction.h"
2 #include <tlhelp32.h>
3
4
5 // These code come from: http://dev.csdn.net/article/2/2786.shtm
6 // I fixed a bug in it and improved it to hook all the modules of a program.
7
8 #define MakePtr(cast, ptr, AddValue) (cast)((size_t)(ptr)+(size_t)(AddValue))
9
GetNamedImportDescriptor(HMODULE hModule,LPCSTR szImportModule)10 static PIMAGE_IMPORT_DESCRIPTOR GetNamedImportDescriptor(HMODULE hModule, LPCSTR szImportModule)
11 {
12 PIMAGE_DOS_HEADER pDOSHeader;
13 PIMAGE_NT_HEADERS pNTHeader;
14 PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
15
16 if ((szImportModule == NULL) || (hModule == NULL))
17 return NULL;
18 pDOSHeader = (PIMAGE_DOS_HEADER) hModule;
19 if (IsBadReadPtr(pDOSHeader, sizeof(IMAGE_DOS_HEADER)) || (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)) {
20 return NULL;
21 }
22 pNTHeader = MakePtr(PIMAGE_NT_HEADERS, pDOSHeader, pDOSHeader->e_lfanew);
23 if (IsBadReadPtr(pNTHeader, sizeof(IMAGE_NT_HEADERS)) || (pNTHeader->Signature != IMAGE_NT_SIGNATURE))
24 return NULL;
25 if (pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0)
26 return NULL;
27 pImportDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, pDOSHeader, pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
28 while (pImportDesc->Name) {
29 PSTR szCurrMod = MakePtr(PSTR, pDOSHeader, pImportDesc->Name);
30 // if (_stricmp(szCurrMod, szImportModule) == 0)
31 if (lstrcmpi(szCurrMod, szImportModule) == 0)
32 break;
33 pImportDesc++;
34 }
35 if (pImportDesc->Name == (DWORD)0)
36 return NULL;
37 return pImportDesc;
38 }
39
IsNT()40 static BOOL IsNT()
41 {
42 OSVERSIONINFO stOSVI;
43 BOOL bRet;
44
45 memset(&stOSVI, 0, sizeof(OSVERSIONINFO));
46 stOSVI.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
47 bRet = GetVersionEx(&stOSVI);
48 if (FALSE == bRet) return FALSE;
49 return (VER_PLATFORM_WIN32_NT == stOSVI.dwPlatformId);
50 }
51
HookImportFunction(HMODULE hModule,LPCSTR szImportModule,LPCSTR szFunc,PROC paHookFuncs,PROC * paOrigFuncs)52 static BOOL HookImportFunction(HMODULE hModule, LPCSTR szImportModule, LPCSTR szFunc, PROC paHookFuncs, PROC* paOrigFuncs)
53 {
54 PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
55 PIMAGE_THUNK_DATA pOrigThunk;
56 PIMAGE_THUNK_DATA pRealThunk;
57
58 if (!IsNT() && ((size_t)hModule >= 0x80000000))
59 return FALSE;
60 pImportDesc = GetNamedImportDescriptor(hModule, szImportModule);
61 if (pImportDesc == NULL)
62 return FALSE;
63 pOrigThunk = MakePtr(PIMAGE_THUNK_DATA, hModule, pImportDesc->OriginalFirstThunk);
64 pRealThunk = MakePtr(PIMAGE_THUNK_DATA, hModule, pImportDesc->FirstThunk);
65 while (pOrigThunk->u1.Function) {
66 if (IMAGE_ORDINAL_FLAG != (pOrigThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG)) {
67 PIMAGE_IMPORT_BY_NAME pByName = MakePtr(PIMAGE_IMPORT_BY_NAME, hModule, pOrigThunk->u1.AddressOfData);
68 BOOL bDoHook;
69 // When hook EditPlus, read pByName->Name[0] will case this dll terminate, so call IsBadReadPtr() here.
70 if (IsBadReadPtr(pByName, sizeof(IMAGE_IMPORT_BY_NAME))) {
71 pOrigThunk++;
72 pRealThunk++;
73 continue;
74 }
75 if ('\0' == pByName->Name[0]) {
76 pOrigThunk++;
77 pRealThunk++;
78 continue;
79 }
80 bDoHook = FALSE;
81 // if ((szFunc[0] == pByName->Name[0]) && (_strcmpi(szFunc, (char*)pByName->Name) == 0)) {
82 if ((szFunc[0] == pByName->Name[0]) && (lstrcmpi(szFunc, (char*)pByName->Name) == 0)) {
83 if (paHookFuncs)
84 bDoHook = TRUE;
85 }
86 if (bDoHook) {
87 MEMORY_BASIC_INFORMATION mbi_thunk;
88 DWORD dwOldProtect;
89 if( VirtualQuery(pRealThunk, &mbi_thunk, sizeof(MEMORY_BASIC_INFORMATION)) != sizeof(MEMORY_BASIC_INFORMATION))
90 return FALSE;
91 if( !VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, PAGE_READWRITE, &mbi_thunk.Protect) )
92 return FALSE;
93 if (paOrigFuncs)
94 *paOrigFuncs = (PROC)InterlockedExchangePointer((PVOID)&(pRealThunk->u1.Function), paHookFuncs);
95 else
96 InterlockedExchangePointer((PVOID)&(pRealThunk->u1.Function), paHookFuncs);
97
98 VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, mbi_thunk.Protect, &dwOldProtect);
99 return TRUE;
100 }
101 }
102 pOrigThunk++;
103 pRealThunk++;
104 }
105 return FALSE;
106 }
107
HookAPI(LPCSTR szImportModule,LPCSTR szFunc,PROC paHookFuncs,PROC * paOrigFuncs)108 BOOL HookAPI(LPCSTR szImportModule, LPCSTR szFunc, PROC paHookFuncs, PROC* paOrigFuncs)
109 {
110 HANDLE hSnapshot;
111 MODULEENTRY32 me;
112 BOOL bOk;
113 DWORD err;
114
115 ZeroMemory(&me,sizeof(me));
116 me.dwSize=sizeof(me);
117
118 if ((szImportModule == NULL) || (szFunc == NULL)) {
119 return FALSE;
120 }
121
122 do {
123 hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
124 if(hSnapshot != INVALID_HANDLE_VALUE) break;
125 err = GetLastError();
126 if(err == ERROR_BAD_LENGTH) Sleep(100);
127 } while(err == ERROR_BAD_LENGTH);
128
129 if(hSnapshot == INVALID_HANDLE_VALUE) return FALSE;
130
131 bOk = Module32First(hSnapshot, &me);
132 while (bOk) {
133 HookImportFunction(me.hModule, szImportModule, szFunc, paHookFuncs, paOrigFuncs);
134 bOk = Module32Next(hSnapshot, &me);
135 }
136 CloseHandle(hSnapshot);
137 return TRUE;
138 }
139