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