FFFTPのソースコードです。
Revisión | e109535845a9db15313e3d1c3088910ca01c7270 (tree) |
---|---|
Tiempo | 2015-10-12 17:48:28 |
Autor | s_kawamoto <s_kawamoto@user...> |
Commiter | s_kawamoto |
Fix bugs of process protection.
@@ -81,7 +81,7 @@ | ||
81 | 81 | // ソフトウェア自動更新 |
82 | 82 | // リリースバージョンはリリース予定年(10進数4桁)+月(2桁)+日(2桁)+通し番号(0スタート2桁)とする |
83 | 83 | // 2014年7月31日中の30個目のリリースは2014073129 |
84 | -#define RELEASE_VERSION_NUM 2015091201 /* リリースバージョン */ | |
84 | +#define RELEASE_VERSION_NUM 2015101201 /* リリースバージョン */ | |
85 | 85 | |
86 | 86 | |
87 | 87 | // SourceForge.JPによるフォーク |
@@ -4,18 +4,10 @@ | ||
4 | 4 | |
5 | 5 | // 次の中から1個のみ有効にする |
6 | 6 | // フック先の関数のコードを書き換える |
7 | -// 全ての呼び出しをフック可能だが原理的に二重呼び出しに対応できない | |
8 | 7 | #define USE_CODE_HOOK |
9 | 8 | // フック先の関数のインポートアドレステーブルを書き換える |
10 | -// 二重呼び出しが可能だが呼び出し方法によってはフックを回避される | |
11 | 9 | //#define USE_IAT_HOOK |
12 | 10 | |
13 | -// フック対象の関数名 %s | |
14 | -// フック対象の型 _%s | |
15 | -// フック対象のポインタ p_%s | |
16 | -// フック用の関数名 h_%s | |
17 | -// フック対象のコードのバックアップ c_%s | |
18 | - | |
19 | 11 | #include <tchar.h> |
20 | 12 | #include <windows.h> |
21 | 13 | #include <ntsecapi.h> |
@@ -37,7 +29,8 @@ | ||
37 | 29 | |
38 | 30 | #ifdef USE_CODE_HOOK |
39 | 31 | #if defined(_M_IX86) |
40 | -#define HOOK_JUMP_CODE_LENGTH 5 | |
32 | +//#define HOOK_JUMP_CODE_LENGTH 5 | |
33 | +#define HOOK_JUMP_CODE_LENGTH 7 | |
41 | 34 | #elif defined(_M_AMD64) |
42 | 35 | #define HOOK_JUMP_CODE_LENGTH 14 |
43 | 36 | #endif |
@@ -49,42 +42,35 @@ typedef struct | ||
49 | 42 | BYTE BackupCode[HOOK_JUMP_CODE_LENGTH]; |
50 | 43 | } HOOK_JUMP_CODE_PATCH; |
51 | 44 | #endif |
52 | - | |
53 | -BOOL LockThreadLock(); | |
54 | -BOOL UnlockThreadLock(); | |
45 | +typedef struct | |
46 | +{ | |
47 | + DWORD Flags; | |
48 | + LPCTSTR ModuleName; | |
49 | + HMODULE hModule; | |
50 | + LPCSTR ProcName; | |
51 | + FARPROC Proc; | |
52 | + FARPROC Hook; | |
53 | + FARPROC Unhook; | |
55 | 54 | #ifdef USE_CODE_HOOK |
56 | -BOOL HookFunctionInCode(void* pOriginal, void* pNew, HOOK_JUMP_CODE_PATCH* pPatch, BOOL bRestore); | |
57 | -#endif | |
58 | -#ifdef USE_IAT_HOOK | |
59 | -BOOL HookFunctionInIAT(void* pOriginal, void* pNew); | |
55 | + HOOK_JUMP_CODE_PATCH Patch; | |
60 | 56 | #endif |
61 | -HANDLE LockExistingFile(LPCWSTR Filename); | |
62 | -BOOL FindTrustedModuleSHA1Hash(void* pHash); | |
63 | -BOOL VerifyFileSignature(LPCWSTR Filename); | |
64 | -BOOL VerifyFileSignatureInCatalog(LPCWSTR Catalog, LPCWSTR Filename); | |
65 | -BOOL GetSHA1HashOfModule(LPCWSTR Filename, void* pHash); | |
66 | -BOOL IsModuleTrusted(LPCWSTR Filename); | |
57 | +} HOOK_FUNCTION_INFO; | |
67 | 58 | |
68 | -// 変数の宣言 | |
69 | -#ifdef USE_CODE_HOOK | |
70 | -#define HOOK_FUNCTION_VAR(name) _##name p_##name;HOOK_JUMP_CODE_PATCH c_##name; | |
71 | -#endif | |
72 | -#ifdef USE_IAT_HOOK | |
73 | -#define HOOK_FUNCTION_VAR(name) _##name p_##name; | |
74 | -#endif | |
75 | -// 関数ポインタを取得 | |
76 | -#define GET_FUNCTION(h, name) p_##name = (_##name)GetProcAddress(h, #name) | |
77 | -// フック対象のコードを置換してフックを開始 | |
78 | -#define SET_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, &c_##name, FALSE) | |
79 | -// フック対象を呼び出す前に対象のコードを復元 | |
80 | -#define BEGIN_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, &c_##name, TRUE) | |
81 | -// フック対象を呼び出した後に対象のコードを置換 | |
82 | -#define END_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, &c_##name, FALSE) | |
59 | +#define HOOK_INITIALIZED 0x00000001 | |
60 | +#define HOOK_ENABLED 0x00000002 | |
61 | +#define HOOK_USE_GETMODULEHANDLE 0x00000004 | |
62 | +#define HOOK_USE_LOADLIBRARY 0x00000008 | |
63 | +#define HOOK_USE_GETPROCADDRESS 0x00000010 | |
64 | + | |
65 | +typedef HMODULE (WINAPI* _LoadLibraryA)(LPCSTR); | |
66 | +typedef HMODULE (WINAPI* _LoadLibraryW)(LPCWSTR); | |
67 | +typedef HMODULE (WINAPI* _LoadLibraryExA)(LPCSTR, HANDLE, DWORD); | |
68 | +typedef HMODULE (WINAPI* _LoadLibraryExW)(LPCWSTR, HANDLE, DWORD); | |
83 | 69 | |
84 | -HOOK_FUNCTION_VAR(LoadLibraryA) | |
85 | -HOOK_FUNCTION_VAR(LoadLibraryW) | |
86 | -HOOK_FUNCTION_VAR(LoadLibraryExA) | |
87 | -HOOK_FUNCTION_VAR(LoadLibraryExW) | |
70 | +HOOK_FUNCTION_INFO g_LoadLibraryA; | |
71 | +HOOK_FUNCTION_INFO g_LoadLibraryW; | |
72 | +HOOK_FUNCTION_INFO g_LoadLibraryExA; | |
73 | +HOOK_FUNCTION_INFO g_LoadLibraryExW; | |
88 | 74 | |
89 | 75 | typedef NTSTATUS (NTAPI* _LdrLoadDll)(LPCWSTR, DWORD*, UNICODE_STRING*, HMODULE*); |
90 | 76 | typedef NTSTATUS (NTAPI* _LdrGetDllHandle)(LPCWSTR, DWORD*, UNICODE_STRING*, HMODULE*); |
@@ -106,150 +92,8 @@ WCHAR* g_pTrustedFilenameTable[MAX_TRUSTED_FILENAME_TABLE]; | ||
106 | 92 | BYTE g_TrustedSHA1HashTable[MAX_TRUSTED_SHA1_HASH_TABLE][20]; |
107 | 93 | WNDPROC g_PasswordEditControlProc; |
108 | 94 | |
109 | -// 以下フック関数 | |
110 | -// フック対象を呼び出す場合は前後でBEGIN_HOOK_FUNCTIONとEND_HOOK_FUNCTIONを実行する必要がある | |
111 | - | |
112 | -HMODULE WINAPI h_LoadLibraryA(LPCSTR lpLibFileName) | |
113 | -{ | |
114 | - HMODULE r = NULL; | |
115 | - wchar_t* pw0 = NULL; | |
116 | - if(pw0 = DuplicateAtoW(lpLibFileName, -1)) | |
117 | - r = LoadLibraryExW(pw0, NULL, 0); | |
118 | - FreeDuplicatedString(pw0); | |
119 | - return r; | |
120 | -} | |
121 | - | |
122 | -HMODULE WINAPI h_LoadLibraryW(LPCWSTR lpLibFileName) | |
123 | -{ | |
124 | - HMODULE r = NULL; | |
125 | - r = LoadLibraryExW(lpLibFileName, NULL, 0); | |
126 | - return r; | |
127 | -} | |
128 | - | |
129 | -HMODULE WINAPI h_LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) | |
130 | -{ | |
131 | - HMODULE r = NULL; | |
132 | - wchar_t* pw0 = NULL; | |
133 | - if(pw0 = DuplicateAtoW(lpLibFileName, -1)) | |
134 | - r = LoadLibraryExW(pw0, hFile, dwFlags); | |
135 | - FreeDuplicatedString(pw0); | |
136 | - return r; | |
137 | -} | |
138 | - | |
139 | -HMODULE WINAPI h_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) | |
140 | -{ | |
141 | - HMODULE r = NULL; | |
142 | - BOOL bTrusted; | |
143 | - wchar_t* pw0; | |
144 | - HANDLE hLock; | |
145 | - HMODULE hModule; | |
146 | - DWORD Length; | |
147 | - bTrusted = FALSE; | |
148 | - pw0 = NULL; | |
149 | - hLock = NULL; | |
150 | -// if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)) | |
151 | - if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE | 0x00000020 | 0x00000040)) | |
152 | - bTrusted = TRUE; | |
153 | - if(!bTrusted) | |
154 | - { | |
155 | - if(hModule = System_LoadLibrary(lpLibFileName, NULL, DONT_RESOLVE_DLL_REFERENCES)) | |
156 | - { | |
157 | - Length = MAX_PATH; | |
158 | - if(pw0 = AllocateStringW(Length)) | |
159 | - { | |
160 | - if(GetModuleFileNameW(hModule, pw0, Length) > 0) | |
161 | - { | |
162 | - while(pw0) | |
163 | - { | |
164 | - if(GetModuleFileNameW(hModule, pw0, Length) + 1 <= Length) | |
165 | - { | |
166 | - lpLibFileName = pw0; | |
167 | - break; | |
168 | - } | |
169 | - Length = Length * 2; | |
170 | - FreeDuplicatedString(pw0); | |
171 | - pw0 = AllocateStringW(Length); | |
172 | - } | |
173 | - } | |
174 | - } | |
175 | - hLock = LockExistingFile(lpLibFileName); | |
176 | - FreeLibrary(hModule); | |
177 | - } | |
178 | - if((g_ProcessProtectionLevel & PROCESS_PROTECTION_LOADED) && GetModuleHandleW(lpLibFileName)) | |
179 | - bTrusted = TRUE; | |
180 | - } | |
181 | - if(!bTrusted) | |
182 | - { | |
183 | - if(hLock) | |
184 | - { | |
185 | - if(IsModuleTrusted(lpLibFileName)) | |
186 | - bTrusted = TRUE; | |
187 | - } | |
188 | - } | |
189 | - if(bTrusted) | |
190 | - r = System_LoadLibrary(lpLibFileName, hFile, dwFlags); | |
191 | - FreeDuplicatedString(pw0); | |
192 | - if(hLock) | |
193 | - CloseHandle(hLock); | |
194 | - return r; | |
195 | -} | |
196 | - | |
197 | -// 以下ヘルパー関数 | |
198 | - | |
199 | -BOOL LockThreadLock() | |
200 | -{ | |
201 | - BOOL bResult; | |
202 | - DWORD ThreadId; | |
203 | - DWORD i; | |
204 | - bResult = FALSE; | |
205 | - ThreadId = GetCurrentThreadId(); | |
206 | - i = 0; | |
207 | - while(i < MAX_LOCKED_THREAD) | |
208 | - { | |
209 | - if(g_LockedThread[i] == ThreadId) | |
210 | - break; | |
211 | - i++; | |
212 | - } | |
213 | - if(i >= MAX_LOCKED_THREAD) | |
214 | - { | |
215 | - i = 0; | |
216 | - while(i < MAX_LOCKED_THREAD) | |
217 | - { | |
218 | - if(g_LockedThread[i] == 0) | |
219 | - { | |
220 | - g_LockedThread[i] = ThreadId; | |
221 | - bResult = TRUE; | |
222 | - break; | |
223 | - } | |
224 | - i++; | |
225 | - } | |
226 | - } | |
227 | - return bResult; | |
228 | -} | |
229 | - | |
230 | -BOOL UnlockThreadLock() | |
231 | -{ | |
232 | - BOOL bResult; | |
233 | - DWORD ThreadId; | |
234 | - DWORD i; | |
235 | - bResult = FALSE; | |
236 | - ThreadId = GetCurrentThreadId(); | |
237 | - i = 0; | |
238 | - while(i < MAX_LOCKED_THREAD) | |
239 | - { | |
240 | - if(g_LockedThread[i] == ThreadId) | |
241 | - { | |
242 | - g_LockedThread[i] = 0; | |
243 | - bResult = TRUE; | |
244 | - break; | |
245 | - } | |
246 | - i++; | |
247 | - } | |
248 | - return bResult; | |
249 | -} | |
250 | - | |
251 | 95 | #ifdef USE_CODE_HOOK |
252 | -BOOL HookFunctionInCode(void* pOriginal, void* pNew, HOOK_JUMP_CODE_PATCH* pPatch, BOOL bRestore) | |
96 | +BOOL HookFunctionInCode(void* pProc, void* pHook, void** ppUnhook, HOOK_JUMP_CODE_PATCH* pPatch, BOOL bRestore) | |
253 | 97 | { |
254 | 98 | BOOL bResult; |
255 | 99 | bResult = FALSE; |
@@ -266,6 +110,7 @@ BOOL HookFunctionInCode(void* pOriginal, void* pNew, HOOK_JUMP_CODE_PATCH* pPatc | ||
266 | 110 | { |
267 | 111 | memcpy(pPatch->pCode, &pPatch->BackupCode, pPatch->CodeLength); |
268 | 112 | VirtualProtect(pPatch->pCode, pPatch->CodeLength, Protect, &Protect); |
113 | + FlushInstructionCache(GetCurrentProcess(), pPatch->pCode, pPatch->CodeLength); | |
269 | 114 | bResult = TRUE; |
270 | 115 | } |
271 | 116 | } |
@@ -273,19 +118,34 @@ BOOL HookFunctionInCode(void* pOriginal, void* pNew, HOOK_JUMP_CODE_PATCH* pPatc | ||
273 | 118 | { |
274 | 119 | if(!pPatch->pCode) |
275 | 120 | { |
276 | - pCode = (BYTE*)pOriginal; | |
121 | + pCode = (BYTE*)pProc; | |
277 | 122 | while(pCode[0] == 0xeb) |
278 | 123 | { |
279 | 124 | memcpy(&c, pCode + 1, 1); |
280 | 125 | pCode = pCode + 2 + c; |
281 | 126 | } |
282 | - if(pCode[0] == 0xe9) | |
127 | + if(pCode[0] == 0x8b && pCode[1] == 0xff) | |
128 | + { | |
129 | + pCode = pCode - 5; | |
130 | + pPatch->pCode = pCode; | |
131 | + pPatch->CodeLength = 7; | |
132 | + memcpy(&pPatch->BackupCode, pPatch->pCode, pPatch->CodeLength); | |
133 | + pPatch->PatchCode[0] = 0xe9; | |
134 | + l = (long)pHook - ((long)pCode + 5); | |
135 | + memcpy(&pPatch->PatchCode[1], &l, 4); | |
136 | + pPatch->PatchCode[5] = 0xeb; | |
137 | + pPatch->PatchCode[6] = 0xf9; | |
138 | + *ppUnhook = pCode + 7; | |
139 | + } | |
140 | + else if(pCode[0] == 0xe9) | |
283 | 141 | { |
284 | 142 | pPatch->pCode = pCode + 1; |
285 | 143 | pPatch->CodeLength = 4; |
286 | 144 | memcpy(&pPatch->BackupCode, pPatch->pCode, pPatch->CodeLength); |
287 | - l = (long)pNew - ((long)pCode + 5); | |
145 | + l = (long)pHook - ((long)pCode + 5); | |
288 | 146 | memcpy(&pPatch->PatchCode[0], &l, 4); |
147 | + memcpy(&l, pCode + 1, 4); | |
148 | + *ppUnhook = pCode + 5 + l; | |
289 | 149 | } |
290 | 150 | else |
291 | 151 | { |
@@ -293,14 +153,16 @@ BOOL HookFunctionInCode(void* pOriginal, void* pNew, HOOK_JUMP_CODE_PATCH* pPatc | ||
293 | 153 | pPatch->CodeLength = 5; |
294 | 154 | memcpy(&pPatch->BackupCode, pPatch->pCode, pPatch->CodeLength); |
295 | 155 | pPatch->PatchCode[0] = 0xe9; |
296 | - l = (long)pNew - ((long)pCode + 5); | |
156 | + l = (long)pHook - ((long)pCode + 5); | |
297 | 157 | memcpy(&pPatch->PatchCode[1], &l, 4); |
158 | + *ppUnhook = NULL; | |
298 | 159 | } |
299 | 160 | } |
300 | 161 | if(VirtualProtect(pPatch->pCode, pPatch->CodeLength, PAGE_EXECUTE_READWRITE, &Protect)) |
301 | 162 | { |
302 | 163 | memcpy(pPatch->pCode, &pPatch->PatchCode, pPatch->CodeLength); |
303 | 164 | VirtualProtect(pPatch->pCode, pPatch->CodeLength, Protect, &Protect); |
165 | + FlushInstructionCache(GetCurrentProcess(), pPatch->pCode, pPatch->CodeLength); | |
304 | 166 | bResult = TRUE; |
305 | 167 | } |
306 | 168 | } |
@@ -311,6 +173,7 @@ BOOL HookFunctionInCode(void* pOriginal, void* pNew, HOOK_JUMP_CODE_PATCH* pPatc | ||
311 | 173 | BYTE* pCode; |
312 | 174 | CHAR c; |
313 | 175 | LONG l; |
176 | + LONGLONG ll; | |
314 | 177 | bResult = FALSE; |
315 | 178 | if(bRestore) |
316 | 179 | { |
@@ -318,6 +181,7 @@ BOOL HookFunctionInCode(void* pOriginal, void* pNew, HOOK_JUMP_CODE_PATCH* pPatc | ||
318 | 181 | { |
319 | 182 | memcpy(pPatch->pCode, &pPatch->BackupCode, pPatch->CodeLength); |
320 | 183 | VirtualProtect(pPatch->pCode, pPatch->CodeLength, Protect, &Protect); |
184 | + FlushInstructionCache(GetCurrentProcess(), pPatch->pCode, pPatch->CodeLength); | |
321 | 185 | bResult = TRUE; |
322 | 186 | } |
323 | 187 | } |
@@ -325,7 +189,9 @@ BOOL HookFunctionInCode(void* pOriginal, void* pNew, HOOK_JUMP_CODE_PATCH* pPatc | ||
325 | 189 | { |
326 | 190 | if(!pPatch->pCode) |
327 | 191 | { |
328 | - pCode = (BYTE*)pOriginal; | |
192 | + pCode = (BYTE*)pProc; | |
193 | + if(pCode[0] == 0x48) | |
194 | + pCode = pCode + 1; | |
329 | 195 | while(pCode[0] == 0xeb || pCode[0] == 0xe9) |
330 | 196 | { |
331 | 197 | if(pCode[0] == 0xeb) |
@@ -338,6 +204,8 @@ BOOL HookFunctionInCode(void* pOriginal, void* pNew, HOOK_JUMP_CODE_PATCH* pPatc | ||
338 | 204 | memcpy(&l, pCode + 1, 4); |
339 | 205 | pCode = pCode + 5 + l; |
340 | 206 | } |
207 | + if(pCode[0] == 0x48) | |
208 | + pCode++; | |
341 | 209 | } |
342 | 210 | if(pCode[0] == 0xff && pCode[1] == 0x25) |
343 | 211 | { |
@@ -345,7 +213,9 @@ BOOL HookFunctionInCode(void* pOriginal, void* pNew, HOOK_JUMP_CODE_PATCH* pPatc | ||
345 | 213 | pPatch->pCode = pCode + 6 + l; |
346 | 214 | pPatch->CodeLength = 8; |
347 | 215 | memcpy(&pPatch->BackupCode, pPatch->pCode, pPatch->CodeLength); |
348 | - memcpy(&pPatch->PatchCode[0], &pNew, 8); | |
216 | + memcpy(&pPatch->PatchCode[0], &pHook, 8); | |
217 | + memcpy(&ll, pCode + 6 + l, 8); | |
218 | + *ppUnhook = (void*)ll; | |
349 | 219 | } |
350 | 220 | else |
351 | 221 | { |
@@ -356,13 +226,15 @@ BOOL HookFunctionInCode(void* pOriginal, void* pNew, HOOK_JUMP_CODE_PATCH* pPatc | ||
356 | 226 | pPatch->PatchCode[1] = 0x25; |
357 | 227 | l = 0; |
358 | 228 | memcpy(&pPatch->PatchCode[2], &l, 4); |
359 | - memcpy(&pPatch->PatchCode[6], &pNew, 8); | |
229 | + memcpy(&pPatch->PatchCode[6], &pHook, 8); | |
230 | + *ppUnhook = NULL; | |
360 | 231 | } |
361 | 232 | } |
362 | 233 | if(VirtualProtect(pPatch->pCode, pPatch->CodeLength, PAGE_EXECUTE_READWRITE, &Protect)) |
363 | 234 | { |
364 | 235 | memcpy(pPatch->pCode, &pPatch->PatchCode, pPatch->CodeLength); |
365 | 236 | VirtualProtect(pPatch->pCode, pPatch->CodeLength, Protect, &Protect); |
237 | + FlushInstructionCache(GetCurrentProcess(), pPatch->pCode, pPatch->CodeLength); | |
366 | 238 | bResult = TRUE; |
367 | 239 | } |
368 | 240 | } |
@@ -373,7 +245,7 @@ BOOL HookFunctionInCode(void* pOriginal, void* pNew, HOOK_JUMP_CODE_PATCH* pPatc | ||
373 | 245 | #endif |
374 | 246 | |
375 | 247 | #ifdef USE_IAT_HOOK |
376 | -BOOL HookFunctionInIAT(void* pOriginal, void* pNew) | |
248 | +BOOL HookFunctionInIAT(void* pProc, void* pHook, void** ppUnhook) | |
377 | 249 | { |
378 | 250 | BOOL bResult; |
379 | 251 | HANDLE hSnapshot; |
@@ -399,13 +271,14 @@ BOOL HookFunctionInIAT(void* pOriginal, void* pNew) | ||
399 | 271 | pitd = (IMAGE_THUNK_DATA*)((BYTE*)me.hModule + piid->FirstThunk); |
400 | 272 | while(!bFound && pitd->u1.Function != 0) |
401 | 273 | { |
402 | - if((void*)pitd->u1.Function == pOriginal) | |
274 | + if((void*)pitd->u1.Function == pProc) | |
403 | 275 | { |
404 | 276 | bFound = TRUE; |
405 | 277 | if(VirtualProtect(&pitd->u1.Function, sizeof(void*), PAGE_EXECUTE_READWRITE, &Protect)) |
406 | 278 | { |
407 | - memcpy(&pitd->u1.Function, &pNew, sizeof(void*)); | |
279 | + memcpy(&pitd->u1.Function, &pHook, sizeof(void*)); | |
408 | 280 | VirtualProtect(&pitd->u1.Function, sizeof(void*), Protect, &Protect); |
281 | + *ppUnhook = pProc; | |
409 | 282 | bResult = TRUE; |
410 | 283 | } |
411 | 284 | } |
@@ -423,6 +296,139 @@ BOOL HookFunctionInIAT(void* pOriginal, void* pNew) | ||
423 | 296 | } |
424 | 297 | #endif |
425 | 298 | |
299 | +BOOL InitializeHookFunction(HOOK_FUNCTION_INFO* pInfo) | |
300 | +{ | |
301 | + BOOL bResult; | |
302 | + bResult = FALSE; | |
303 | + if(!(pInfo->Flags & HOOK_INITIALIZED)) | |
304 | + { | |
305 | + if(pInfo->Flags & HOOK_USE_GETMODULEHANDLE) | |
306 | + pInfo->hModule = GetModuleHandle(pInfo->ModuleName); | |
307 | + if(pInfo->Flags & HOOK_USE_LOADLIBRARY) | |
308 | + pInfo->hModule = LoadLibrary(pInfo->ModuleName); | |
309 | + if(pInfo->Flags & HOOK_USE_GETPROCADDRESS) | |
310 | + pInfo->Proc = GetProcAddress(pInfo->hModule, pInfo->ProcName); | |
311 | + if(pInfo->Proc) | |
312 | + { | |
313 | + pInfo->Flags |= HOOK_INITIALIZED; | |
314 | + bResult = TRUE; | |
315 | + } | |
316 | + } | |
317 | + return bResult; | |
318 | +} | |
319 | + | |
320 | +void UninitializeHookFunction(HOOK_FUNCTION_INFO* pInfo) | |
321 | +{ | |
322 | + if(pInfo->Flags & HOOK_INITIALIZED) | |
323 | + { | |
324 | + if(pInfo->Flags & HOOK_USE_LOADLIBRARY) | |
325 | + FreeLibrary(pInfo->hModule); | |
326 | + pInfo->Flags &= ~HOOK_INITIALIZED; | |
327 | + } | |
328 | +} | |
329 | + | |
330 | +BOOL EnableHookFunction(HOOK_FUNCTION_INFO* pInfo, BOOL bEnable) | |
331 | +{ | |
332 | + BOOL bResult; | |
333 | + bResult = FALSE; | |
334 | + if(pInfo->Flags & HOOK_INITIALIZED) | |
335 | + { | |
336 | + if(bEnable) | |
337 | + { | |
338 | + if(!(pInfo->Flags & HOOK_ENABLED)) | |
339 | + { | |
340 | +#ifdef USE_CODE_HOOK | |
341 | + if(HookFunctionInCode(pInfo->Proc, pInfo->Hook, (void**)&pInfo->Unhook, &pInfo->Patch, FALSE)) | |
342 | + { | |
343 | + pInfo->Flags |= HOOK_ENABLED; | |
344 | + bResult = TRUE; | |
345 | + } | |
346 | +#endif | |
347 | +#ifdef USE_IAT_HOOK | |
348 | + if(HookFunctionInIAT(pInfo->Proc, pInfo->Hook, (void**)&pInfo->Unhook)) | |
349 | + { | |
350 | + pInfo->Flags |= HOOK_ENABLED; | |
351 | + bResult = TRUE; | |
352 | + } | |
353 | +#endif | |
354 | + } | |
355 | + } | |
356 | + else | |
357 | + { | |
358 | + if(pInfo->Flags & HOOK_ENABLED) | |
359 | + { | |
360 | +#ifdef USE_CODE_HOOK | |
361 | + if(HookFunctionInCode(pInfo->Proc, pInfo->Hook, (void**)&pInfo->Unhook, &pInfo->Patch, TRUE)) | |
362 | + { | |
363 | + pInfo->Flags &= ~HOOK_ENABLED; | |
364 | + bResult = TRUE; | |
365 | + } | |
366 | +#endif | |
367 | +#ifdef USE_IAT_HOOK | |
368 | + if(HookFunctionInIAT(pInfo->Hook, pInfo->Proc, (void**)&pInfo->Unhook)) | |
369 | + { | |
370 | + pInfo->Flags &= ~HOOK_ENABLED; | |
371 | + bResult = TRUE; | |
372 | + } | |
373 | +#endif | |
374 | + } | |
375 | + } | |
376 | + } | |
377 | + return bResult; | |
378 | +} | |
379 | + | |
380 | +BOOL LockThreadLock() | |
381 | +{ | |
382 | + BOOL bResult; | |
383 | + DWORD ThreadId; | |
384 | + DWORD i; | |
385 | + bResult = FALSE; | |
386 | + ThreadId = GetCurrentThreadId(); | |
387 | + i = 0; | |
388 | + while(i < MAX_LOCKED_THREAD) | |
389 | + { | |
390 | + if(g_LockedThread[i] == ThreadId) | |
391 | + break; | |
392 | + i++; | |
393 | + } | |
394 | + if(i >= MAX_LOCKED_THREAD) | |
395 | + { | |
396 | + i = 0; | |
397 | + while(i < MAX_LOCKED_THREAD) | |
398 | + { | |
399 | + if(g_LockedThread[i] == 0) | |
400 | + { | |
401 | + g_LockedThread[i] = ThreadId; | |
402 | + bResult = TRUE; | |
403 | + break; | |
404 | + } | |
405 | + i++; | |
406 | + } | |
407 | + } | |
408 | + return bResult; | |
409 | +} | |
410 | + | |
411 | +BOOL UnlockThreadLock() | |
412 | +{ | |
413 | + BOOL bResult; | |
414 | + DWORD ThreadId; | |
415 | + DWORD i; | |
416 | + bResult = FALSE; | |
417 | + ThreadId = GetCurrentThreadId(); | |
418 | + i = 0; | |
419 | + while(i < MAX_LOCKED_THREAD) | |
420 | + { | |
421 | + if(g_LockedThread[i] == ThreadId) | |
422 | + { | |
423 | + g_LockedThread[i] = 0; | |
424 | + bResult = TRUE; | |
425 | + break; | |
426 | + } | |
427 | + i++; | |
428 | + } | |
429 | + return bResult; | |
430 | +} | |
431 | + | |
426 | 432 | // ファイルを変更不能に設定 |
427 | 433 | HANDLE LockExistingFile(LPCWSTR Filename) |
428 | 434 | { |
@@ -779,6 +785,93 @@ BOOL IsModuleTrusted(LPCWSTR Filename) | ||
779 | 785 | return bResult; |
780 | 786 | } |
781 | 787 | |
788 | +// 以下フック関数 | |
789 | + | |
790 | +HMODULE WINAPI h_LoadLibraryA(LPCSTR lpLibFileName) | |
791 | +{ | |
792 | + HMODULE r = NULL; | |
793 | + wchar_t* pw0 = NULL; | |
794 | + if(pw0 = DuplicateAtoW(lpLibFileName, -1)) | |
795 | + r = LoadLibraryExW(pw0, NULL, 0); | |
796 | + FreeDuplicatedString(pw0); | |
797 | + return r; | |
798 | +} | |
799 | + | |
800 | +HMODULE WINAPI h_LoadLibraryW(LPCWSTR lpLibFileName) | |
801 | +{ | |
802 | + HMODULE r = NULL; | |
803 | + r = LoadLibraryExW(lpLibFileName, NULL, 0); | |
804 | + return r; | |
805 | +} | |
806 | + | |
807 | +HMODULE WINAPI h_LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) | |
808 | +{ | |
809 | + HMODULE r = NULL; | |
810 | + wchar_t* pw0 = NULL; | |
811 | + if(pw0 = DuplicateAtoW(lpLibFileName, -1)) | |
812 | + r = LoadLibraryExW(pw0, hFile, dwFlags); | |
813 | + FreeDuplicatedString(pw0); | |
814 | + return r; | |
815 | +} | |
816 | + | |
817 | +HMODULE WINAPI h_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) | |
818 | +{ | |
819 | + HMODULE r = NULL; | |
820 | + BOOL bTrusted; | |
821 | + wchar_t* pw0; | |
822 | + HANDLE hLock; | |
823 | + HMODULE hModule; | |
824 | + DWORD Length; | |
825 | + bTrusted = FALSE; | |
826 | + pw0 = NULL; | |
827 | + hLock = NULL; | |
828 | +// if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)) | |
829 | + if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE | 0x00000020 | 0x00000040)) | |
830 | + bTrusted = TRUE; | |
831 | + if(!bTrusted) | |
832 | + { | |
833 | + if(hModule = System_LoadLibrary(lpLibFileName, NULL, DONT_RESOLVE_DLL_REFERENCES)) | |
834 | + { | |
835 | + Length = MAX_PATH; | |
836 | + if(pw0 = AllocateStringW(Length)) | |
837 | + { | |
838 | + if(GetModuleFileNameW(hModule, pw0, Length) > 0) | |
839 | + { | |
840 | + while(pw0) | |
841 | + { | |
842 | + if(GetModuleFileNameW(hModule, pw0, Length) + 1 <= Length) | |
843 | + { | |
844 | + lpLibFileName = pw0; | |
845 | + break; | |
846 | + } | |
847 | + Length = Length * 2; | |
848 | + FreeDuplicatedString(pw0); | |
849 | + pw0 = AllocateStringW(Length); | |
850 | + } | |
851 | + } | |
852 | + } | |
853 | + hLock = LockExistingFile(lpLibFileName); | |
854 | + FreeLibrary(hModule); | |
855 | + } | |
856 | + if((g_ProcessProtectionLevel & PROCESS_PROTECTION_LOADED) && GetModuleHandleW(lpLibFileName)) | |
857 | + bTrusted = TRUE; | |
858 | + } | |
859 | + if(!bTrusted) | |
860 | + { | |
861 | + if(hLock) | |
862 | + { | |
863 | + if(IsModuleTrusted(lpLibFileName)) | |
864 | + bTrusted = TRUE; | |
865 | + } | |
866 | + } | |
867 | + if(bTrusted) | |
868 | + r = System_LoadLibrary(lpLibFileName, hFile, dwFlags); | |
869 | + FreeDuplicatedString(pw0); | |
870 | + if(hLock) | |
871 | + CloseHandle(hLock); | |
872 | + return r; | |
873 | +} | |
874 | + | |
782 | 875 | // kernel32.dllのLoadLibraryExW相当の関数 |
783 | 876 | // ドキュメントが無いため詳細は不明 |
784 | 877 | // 一部のウィルス対策ソフト(Avast!等)がLdrLoadDllをフックしているためLdrLoadDllを書き換えるべきではない |
@@ -859,7 +952,7 @@ void SetProcessProtectionLevel(DWORD Level) | ||
859 | 952 | g_ProcessProtectionLevel = Level; |
860 | 953 | } |
861 | 954 | |
862 | -// メモリのSHA1ハッシュを取得 | |
955 | +// メモリのSHA1ハッシュを取得 | |
863 | 956 | BOOL GetSHA1HashOfMemory(const void* pData, DWORD Size, void* pHash) |
864 | 957 | { |
865 | 958 | BOOL bResult; |
@@ -1030,27 +1123,45 @@ BOOL InitializeLoadLibraryHook() | ||
1030 | 1123 | BOOL bResult; |
1031 | 1124 | HMODULE hModule; |
1032 | 1125 | bResult = TRUE; |
1033 | - if(!(hModule = GetModuleHandleW(L"kernel32.dll"))) | |
1034 | - bResult = FALSE; | |
1035 | - if(!(GET_FUNCTION(hModule, LoadLibraryA))) | |
1126 | + memset(&g_LoadLibraryA, 0, sizeof(HOOK_FUNCTION_INFO)); | |
1127 | + g_LoadLibraryA.Flags = HOOK_USE_GETMODULEHANDLE | HOOK_USE_GETPROCADDRESS; | |
1128 | + g_LoadLibraryA.ModuleName = _T("kernel32.dll"); | |
1129 | + g_LoadLibraryA.ProcName = "LoadLibraryA"; | |
1130 | + g_LoadLibraryA.Hook = (FARPROC)h_LoadLibraryA; | |
1131 | + if(!InitializeHookFunction(&g_LoadLibraryA)) | |
1036 | 1132 | bResult = FALSE; |
1037 | - if(!(GET_FUNCTION(hModule, LoadLibraryW))) | |
1133 | + memset(&g_LoadLibraryW, 0, sizeof(HOOK_FUNCTION_INFO)); | |
1134 | + g_LoadLibraryW.Flags = HOOK_USE_GETMODULEHANDLE | HOOK_USE_GETPROCADDRESS; | |
1135 | + g_LoadLibraryW.ModuleName = _T("kernel32.dll"); | |
1136 | + g_LoadLibraryW.ProcName = "LoadLibraryW"; | |
1137 | + g_LoadLibraryW.Hook = (FARPROC)h_LoadLibraryW; | |
1138 | + if(!InitializeHookFunction(&g_LoadLibraryW)) | |
1038 | 1139 | bResult = FALSE; |
1039 | - if(!(GET_FUNCTION(hModule, LoadLibraryExA))) | |
1140 | + memset(&g_LoadLibraryExA, 0, sizeof(HOOK_FUNCTION_INFO)); | |
1141 | + g_LoadLibraryExA.Flags = HOOK_USE_GETMODULEHANDLE | HOOK_USE_GETPROCADDRESS; | |
1142 | + g_LoadLibraryExA.ModuleName = _T("kernel32.dll"); | |
1143 | + g_LoadLibraryExA.ProcName = "LoadLibraryExA"; | |
1144 | + g_LoadLibraryExA.Hook = (FARPROC)h_LoadLibraryExA; | |
1145 | + if(!InitializeHookFunction(&g_LoadLibraryExA)) | |
1040 | 1146 | bResult = FALSE; |
1041 | - if(!(GET_FUNCTION(hModule, LoadLibraryExW))) | |
1147 | + memset(&g_LoadLibraryExW, 0, sizeof(HOOK_FUNCTION_INFO)); | |
1148 | + g_LoadLibraryExW.Flags = HOOK_USE_GETMODULEHANDLE | HOOK_USE_GETPROCADDRESS; | |
1149 | + g_LoadLibraryExW.ModuleName = _T("kernel32.dll"); | |
1150 | + g_LoadLibraryExW.ProcName = "LoadLibraryExW"; | |
1151 | + g_LoadLibraryExW.Hook = (FARPROC)h_LoadLibraryExW; | |
1152 | + if(!InitializeHookFunction(&g_LoadLibraryExW)) | |
1042 | 1153 | bResult = FALSE; |
1043 | 1154 | if(!(hModule = GetModuleHandleW(L"ntdll.dll"))) |
1044 | 1155 | bResult = FALSE; |
1045 | - if(!(GET_FUNCTION(hModule, LdrLoadDll))) | |
1156 | + if(!(p_LdrLoadDll = (_LdrLoadDll)GetProcAddress(hModule, "LdrLoadDll"))) | |
1046 | 1157 | bResult = FALSE; |
1047 | - if(!(GET_FUNCTION(hModule, LdrGetDllHandle))) | |
1158 | + if(!(p_LdrGetDllHandle = (_LdrGetDllHandle)GetProcAddress(hModule, "LdrGetDllHandle"))) | |
1048 | 1159 | bResult = FALSE; |
1049 | - if(!(GET_FUNCTION(hModule, RtlImageNtHeader))) | |
1160 | + if(!(p_RtlImageNtHeader = (_RtlImageNtHeader)GetProcAddress(hModule, "RtlImageNtHeader"))) | |
1050 | 1161 | bResult = FALSE; |
1051 | 1162 | if(!(hModule = LoadLibraryW(L"wintrust.dll"))) |
1052 | 1163 | bResult = FALSE; |
1053 | - if(!(GET_FUNCTION(hModule, CryptCATAdminCalcHashFromFileHandle))) | |
1164 | + if(!(p_CryptCATAdminCalcHashFromFileHandle = (_CryptCATAdminCalcHashFromFileHandle)GetProcAddress(hModule, "CryptCATAdminCalcHashFromFileHandle"))) | |
1054 | 1165 | bResult = FALSE; |
1055 | 1166 | // バグ対策 |
1056 | 1167 | ImageGetDigestStream(NULL, 0, NULL, NULL); |
@@ -1062,55 +1173,15 @@ BOOL InitializeLoadLibraryHook() | ||
1062 | 1173 | BOOL EnableLoadLibraryHook(BOOL bEnable) |
1063 | 1174 | { |
1064 | 1175 | BOOL bResult; |
1065 | - bResult = FALSE; | |
1066 | - if(bEnable) | |
1067 | - { | |
1068 | - bResult = TRUE; | |
1069 | -#ifdef USE_CODE_HOOK | |
1070 | - if(!SET_HOOK_FUNCTION(LoadLibraryA)) | |
1071 | - bResult = FALSE; | |
1072 | - if(!SET_HOOK_FUNCTION(LoadLibraryW)) | |
1073 | - bResult = FALSE; | |
1074 | - if(!SET_HOOK_FUNCTION(LoadLibraryExA)) | |
1075 | - bResult = FALSE; | |
1076 | - if(!SET_HOOK_FUNCTION(LoadLibraryExW)) | |
1077 | - bResult = FALSE; | |
1078 | -#endif | |
1079 | -#ifdef USE_IAT_HOOK | |
1080 | - if(!HookFunctionInIAT(p_LoadLibraryA, h_LoadLibraryA)) | |
1081 | - bResult = FALSE; | |
1082 | - if(!HookFunctionInIAT(p_LoadLibraryW, h_LoadLibraryW)) | |
1083 | - bResult = FALSE; | |
1084 | - if(!HookFunctionInIAT(p_LoadLibraryExA, h_LoadLibraryExA)) | |
1085 | - bResult = FALSE; | |
1086 | - if(!HookFunctionInIAT(p_LoadLibraryExW, h_LoadLibraryExW)) | |
1087 | - bResult = FALSE; | |
1088 | -#endif | |
1089 | - } | |
1090 | - else | |
1091 | - { | |
1092 | - bResult = TRUE; | |
1093 | -#ifdef USE_CODE_HOOK | |
1094 | - if(!BEGIN_HOOK_FUNCTION(LoadLibraryA)) | |
1095 | - bResult = FALSE; | |
1096 | - if(!BEGIN_HOOK_FUNCTION(LoadLibraryW)) | |
1097 | - bResult = FALSE; | |
1098 | - if(!BEGIN_HOOK_FUNCTION(LoadLibraryExA)) | |
1099 | - bResult = FALSE; | |
1100 | - if(!BEGIN_HOOK_FUNCTION(LoadLibraryExW)) | |
1101 | - bResult = FALSE; | |
1102 | -#endif | |
1103 | -#ifdef USE_IAT_HOOK | |
1104 | - if(!HookFunctionInIAT(h_LoadLibraryA, p_LoadLibraryA)) | |
1105 | - bResult = FALSE; | |
1106 | - if(!HookFunctionInIAT(h_LoadLibraryW, p_LoadLibraryW)) | |
1107 | - bResult = FALSE; | |
1108 | - if(!HookFunctionInIAT(h_LoadLibraryExA, p_LoadLibraryExA)) | |
1109 | - bResult = FALSE; | |
1110 | - if(!HookFunctionInIAT(h_LoadLibraryExW, p_LoadLibraryExW)) | |
1111 | - bResult = FALSE; | |
1112 | -#endif | |
1113 | - } | |
1176 | + bResult = TRUE; | |
1177 | + if(!EnableHookFunction(&g_LoadLibraryA, bEnable)) | |
1178 | + bResult = FALSE; | |
1179 | + if(!EnableHookFunction(&g_LoadLibraryW, bEnable)) | |
1180 | + bResult = FALSE; | |
1181 | + if(!EnableHookFunction(&g_LoadLibraryExA, bEnable)) | |
1182 | + bResult = FALSE; | |
1183 | + if(!EnableHookFunction(&g_LoadLibraryExW, bEnable)) | |
1184 | + bResult = FALSE; | |
1114 | 1185 | return bResult; |
1115 | 1186 | } |
1116 | 1187 |
@@ -7,43 +7,6 @@ | ||
7 | 7 | |
8 | 8 | #define ENABLE_PROCESS_PROTECTION |
9 | 9 | |
10 | -// 次の中から1個のみ有効にする | |
11 | -// フック先の関数のコードを書き換える | |
12 | -// 全ての呼び出しをフック可能だが原理的に二重呼び出しに対応できない | |
13 | -#define USE_CODE_HOOK | |
14 | -// フック先の関数のインポートアドレステーブルを書き換える | |
15 | -// 二重呼び出しが可能だが呼び出し方法によってはフックを回避される | |
16 | -//#define USE_IAT_HOOK | |
17 | - | |
18 | -typedef HMODULE (WINAPI* _LoadLibraryA)(LPCSTR); | |
19 | -typedef HMODULE (WINAPI* _LoadLibraryW)(LPCWSTR); | |
20 | -typedef HMODULE (WINAPI* _LoadLibraryExA)(LPCSTR, HANDLE, DWORD); | |
21 | -typedef HMODULE (WINAPI* _LoadLibraryExW)(LPCWSTR, HANDLE, DWORD); | |
22 | - | |
23 | -#ifndef DO_NOT_REPLACE | |
24 | - | |
25 | -#ifdef USE_IAT_HOOK | |
26 | - | |
27 | -// 変数の宣言 | |
28 | -#define EXTERN_HOOK_FUNCTION_VAR(name) extern _##name p_##name; | |
29 | - | |
30 | -#undef LoadLibraryA | |
31 | -#define LoadLibraryA p_LoadLibraryA | |
32 | -EXTERN_HOOK_FUNCTION_VAR(LoadLibraryA) | |
33 | -#undef LoadLibraryW | |
34 | -#define LoadLibraryW p_LoadLibraryW | |
35 | -EXTERN_HOOK_FUNCTION_VAR(LoadLibraryW) | |
36 | -#undef LoadLibraryExA | |
37 | -#define LoadLibraryExA p_LoadLibraryExA | |
38 | -EXTERN_HOOK_FUNCTION_VAR(LoadLibraryExA) | |
39 | -#undef LoadLibraryExW | |
40 | -#define LoadLibraryExW p_LoadLibraryExW | |
41 | -EXTERN_HOOK_FUNCTION_VAR(LoadLibraryExW) | |
42 | - | |
43 | -#endif | |
44 | - | |
45 | -#endif | |
46 | - | |
47 | 10 | // ロード済みのモジュールは検査をパス |
48 | 11 | #define PROCESS_PROTECTION_LOADED 0x00000001 |
49 | 12 | // モジュールに埋め込まれたAuthenticode署名を検査 |