OSDN Git Service

Enhance routines for extra commands.
[ffftp/ffftp.git] / protectprocess.c
1 // protectprocess.c\r
2 // Copyright (C) 2011 Suguru Kawamoto\r
3 // プロセスの保護\r
4 \r
5 // 次の中から1個のみ有効にする\r
6 // フック先の関数のコードを書き換える\r
7 // 全ての呼び出しをフック可能だが原理的に二重呼び出しに対応できない\r
8 #define USE_CODE_HOOK\r
9 // フック先の関数のインポートアドレステーブルを書き換える\r
10 // 二重呼び出しが可能だが呼び出し方法によってはフックを回避される\r
11 //#define USE_IAT_HOOK\r
12 \r
13 // フック対象の関数名 %s\r
14 // フック対象の型 _%s\r
15 // フック対象のポインタ p_%s\r
16 // フック用の関数名 h_%s\r
17 // フック対象のコードのバックアップ c_%s\r
18 \r
19 #include <tchar.h>\r
20 #include <windows.h>\r
21 #include <ntsecapi.h>\r
22 #include <wincrypt.h>\r
23 #include <wintrust.h>\r
24 #include <softpub.h>\r
25 #include <aclapi.h>\r
26 #include <sfc.h>\r
27 #include <tlhelp32.h>\r
28 #include <imagehlp.h>\r
29 #ifdef USE_IAT_HOOK\r
30 #include <dbghelp.h>\r
31 #endif\r
32 \r
33 #define DO_NOT_REPLACE\r
34 #include "protectprocess.h"\r
35 #include "mbswrapper.h"\r
36 \r
37 #ifdef USE_IAT_HOOK\r
38 #pragma comment(lib, "dbghelp.lib")\r
39 #endif\r
40 \r
41 #ifdef USE_CODE_HOOK\r
42 #if defined(_X86_)\r
43 #define HOOK_JUMP_CODE_LENGTH 5\r
44 #elif defined(_AMD64_)\r
45 #define HOOK_JUMP_CODE_LENGTH 14\r
46 #endif\r
47 #endif\r
48 \r
49 BOOL LockThreadLock();\r
50 BOOL UnlockThreadLock();\r
51 #ifdef USE_CODE_HOOK\r
52 BOOL HookFunctionInCode(void* pOriginal, void* pNew, void* pBackupCode, BOOL bRestore);\r
53 #endif\r
54 #ifdef USE_IAT_HOOK\r
55 BOOL HookFunctionInIAT(void* pOriginal, void* pNew);\r
56 #endif\r
57 HANDLE LockExistingFile(LPCWSTR Filename);\r
58 BOOL FindTrustedModuleSHA1Hash(void* pHash);\r
59 BOOL VerifyFileSignature(LPCWSTR Filename);\r
60 BOOL VerifyFileSignatureInCatalog(LPCWSTR Catalog, LPCWSTR Filename);\r
61 BOOL GetSHA1HashOfModule(LPCWSTR Filename, void* pHash);\r
62 BOOL IsModuleTrusted(LPCWSTR Filename);\r
63 \r
64 // 変数の宣言\r
65 #ifdef USE_CODE_HOOK\r
66 #define HOOK_FUNCTION_VAR(name) _##name p_##name;BYTE c_##name[HOOK_JUMP_CODE_LENGTH * 2];\r
67 #endif\r
68 #ifdef USE_IAT_HOOK\r
69 #define HOOK_FUNCTION_VAR(name) _##name p_##name;\r
70 #endif\r
71 // 関数ポインタを取得\r
72 #define GET_FUNCTION(h, name) p_##name = (_##name)GetProcAddress(h, #name)\r
73 // フック対象のコードを置換してフックを開始\r
74 #define SET_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, &c_##name, FALSE)\r
75 // フック対象を呼び出す前に対象のコードを復元\r
76 #define START_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, &c_##name, TRUE)\r
77 // フック対象を呼び出した後に対象のコードを置換\r
78 #define END_HOOK_FUNCTION(name) HookFunctionInCode(p_##name, h_##name, NULL, FALSE)\r
79 \r
80 HOOK_FUNCTION_VAR(LoadLibraryA)\r
81 HOOK_FUNCTION_VAR(LoadLibraryW)\r
82 HOOK_FUNCTION_VAR(LoadLibraryExA)\r
83 HOOK_FUNCTION_VAR(LoadLibraryExW)\r
84 \r
85 typedef NTSTATUS (NTAPI* _LdrLoadDll)(LPCWSTR, DWORD*, UNICODE_STRING*, HMODULE*);\r
86 typedef NTSTATUS (NTAPI* _LdrGetDllHandle)(LPCWSTR, DWORD*, UNICODE_STRING*, HMODULE*);\r
87 typedef PIMAGE_NT_HEADERS (NTAPI* _RtlImageNtHeader)(PVOID);\r
88 typedef BOOL (WINAPI* _CryptCATAdminCalcHashFromFileHandle)(HANDLE, DWORD*, BYTE*, DWORD);\r
89 \r
90 _LdrLoadDll p_LdrLoadDll;\r
91 _LdrGetDllHandle p_LdrGetDllHandle;\r
92 _RtlImageNtHeader p_RtlImageNtHeader;\r
93 _CryptCATAdminCalcHashFromFileHandle p_CryptCATAdminCalcHashFromFileHandle;\r
94 \r
95 #define MAX_LOCKED_THREAD 16\r
96 #define MAX_TRUSTED_FILENAME_TABLE 16\r
97 #define MAX_TRUSTED_MD5_HASH_TABLE 16\r
98 \r
99 DWORD g_ProcessProtectionLevel;\r
100 DWORD g_LockedThread[MAX_LOCKED_THREAD];\r
101 WCHAR* g_pTrustedFilenameTable[MAX_TRUSTED_FILENAME_TABLE];\r
102 BYTE g_TrustedMD5HashTable[MAX_TRUSTED_MD5_HASH_TABLE][20];\r
103 \r
104 // 以下フック関数\r
105 // フック対象を呼び出す場合は前後でSTART_HOOK_FUNCTIONとEND_HOOK_FUNCTIONを実行する必要がある\r
106 \r
107 HMODULE WINAPI h_LoadLibraryA(LPCSTR lpLibFileName)\r
108 {\r
109         HMODULE r = NULL;\r
110         wchar_t* pw0 = NULL;\r
111         if(pw0 = DuplicateAtoW(lpLibFileName, -1))\r
112                 r = LoadLibraryExW(pw0, NULL, 0);\r
113         FreeDuplicatedString(pw0);\r
114         return r;\r
115 }\r
116 \r
117 HMODULE WINAPI h_LoadLibraryW(LPCWSTR lpLibFileName)\r
118 {\r
119         HMODULE r = NULL;\r
120         r = LoadLibraryExW(lpLibFileName, NULL, 0);\r
121         return r;\r
122 }\r
123 \r
124 HMODULE WINAPI h_LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)\r
125 {\r
126         HMODULE r = NULL;\r
127         wchar_t* pw0 = NULL;\r
128         if(pw0 = DuplicateAtoW(lpLibFileName, -1))\r
129                 r = LoadLibraryExW(pw0, hFile, dwFlags);\r
130         FreeDuplicatedString(pw0);\r
131         return r;\r
132 }\r
133 \r
134 HMODULE WINAPI h_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)\r
135 {\r
136         HMODULE r = NULL;\r
137         BOOL bTrusted;\r
138         wchar_t* pw0;\r
139         HANDLE hLock;\r
140         HMODULE hModule;\r
141         DWORD Length;\r
142         bTrusted = FALSE;\r
143         pw0 = NULL;\r
144         hLock = NULL;\r
145 //      if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE))\r
146         if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE | 0x00000020 | 0x00000040))\r
147                 bTrusted = TRUE;\r
148         if(!bTrusted)\r
149         {\r
150                 if(hModule = System_LoadLibrary(lpLibFileName, NULL, DONT_RESOLVE_DLL_REFERENCES))\r
151                 {\r
152                         Length = MAX_PATH;\r
153                         if(pw0 = AllocateStringW(Length))\r
154                         {\r
155                                 if(GetModuleFileNameW(hModule, pw0, Length) > 0)\r
156                                 {\r
157                                         while(pw0)\r
158                                         {\r
159                                                 if(GetModuleFileNameW(hModule, pw0, Length) + 1 <= Length)\r
160                                                 {\r
161                                                         lpLibFileName = pw0;\r
162                                                         break;\r
163                                                 }\r
164                                                 Length = Length * 2;\r
165                                                 FreeDuplicatedString(pw0);\r
166                                                 pw0 = AllocateStringW(Length);\r
167                                         }\r
168                                 }\r
169                         }\r
170                         hLock = LockExistingFile(lpLibFileName);\r
171                         FreeLibrary(hModule);\r
172                 }\r
173                 if((g_ProcessProtectionLevel & PROCESS_PROTECTION_LOADED) && GetModuleHandleW(lpLibFileName))\r
174                         bTrusted = TRUE;\r
175         }\r
176         if(!bTrusted)\r
177         {\r
178                 if(hLock)\r
179                 {\r
180                         if(IsModuleTrusted(lpLibFileName))\r
181                                 bTrusted = TRUE;\r
182                 }\r
183         }\r
184         if(bTrusted)\r
185                 r = System_LoadLibrary(lpLibFileName, hFile, dwFlags);\r
186         FreeDuplicatedString(pw0);\r
187         if(hLock)\r
188                 CloseHandle(hLock);\r
189         return r;\r
190 }\r
191 \r
192 // 以下ヘルパー関数\r
193 \r
194 BOOL LockThreadLock()\r
195 {\r
196         BOOL bResult;\r
197         DWORD ThreadId;\r
198         DWORD i;\r
199         bResult = FALSE;\r
200         ThreadId = GetCurrentThreadId();\r
201         i = 0;\r
202         while(i < MAX_LOCKED_THREAD)\r
203         {\r
204                 if(g_LockedThread[i] == ThreadId)\r
205                         break;\r
206                 i++;\r
207         }\r
208         if(i >= MAX_LOCKED_THREAD)\r
209         {\r
210                 i = 0;\r
211                 while(i < MAX_LOCKED_THREAD)\r
212                 {\r
213                         if(g_LockedThread[i] == 0)\r
214                         {\r
215                                 g_LockedThread[i] = ThreadId;\r
216                                 bResult = TRUE;\r
217                                 break;\r
218                         }\r
219                         i++;\r
220                 }\r
221         }\r
222         return bResult;\r
223 }\r
224 \r
225 BOOL UnlockThreadLock()\r
226 {\r
227         BOOL bResult;\r
228         DWORD ThreadId;\r
229         DWORD i;\r
230         bResult = FALSE;\r
231         ThreadId = GetCurrentThreadId();\r
232         i = 0;\r
233         while(i < MAX_LOCKED_THREAD)\r
234         {\r
235                 if(g_LockedThread[i] == ThreadId)\r
236                 {\r
237                         g_LockedThread[i] = 0;\r
238                         bResult = TRUE;\r
239                         break;\r
240                 }\r
241                 i++;\r
242         }\r
243         return bResult;\r
244 }\r
245 \r
246 #ifdef USE_CODE_HOOK\r
247 BOOL HookFunctionInCode(void* pOriginal, void* pNew, void* pBackupCode, BOOL bRestore)\r
248 {\r
249         BOOL bResult;\r
250         DWORD Protect;\r
251 #if defined(_X86_)\r
252         BYTE JumpCode[HOOK_JUMP_CODE_LENGTH] = {0xe9, 0x00, 0x00, 0x00, 0x00};\r
253         size_t Relative;\r
254         Relative = (size_t)pNew - (size_t)pOriginal - HOOK_JUMP_CODE_LENGTH;\r
255         memcpy(&JumpCode[1], &Relative, 4);\r
256         bResult = FALSE;\r
257         if(bRestore)\r
258         {\r
259                 if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect))\r
260                 {\r
261                         memcpy(pOriginal, pBackupCode, HOOK_JUMP_CODE_LENGTH);\r
262                         VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect);\r
263                         bResult = TRUE;\r
264                 }\r
265         }\r
266         else\r
267         {\r
268                 if(pBackupCode)\r
269                         memcpy(pBackupCode, pOriginal, HOOK_JUMP_CODE_LENGTH);\r
270                 if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect))\r
271                 {\r
272                         memcpy(pOriginal, &JumpCode, HOOK_JUMP_CODE_LENGTH);\r
273                         VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect);\r
274                         bResult = TRUE;\r
275                 }\r
276         }\r
277 #elif defined(_AMD64_)\r
278         BYTE JumpCode[HOOK_JUMP_CODE_LENGTH] = {0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
279         size_t Absolute;\r
280         Absolute = (size_t)pOriginal;\r
281         memcpy(&JumpCode[6], &Absolute, 8);\r
282         bResult = FALSE;\r
283         if(bRestore)\r
284         {\r
285                 if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect))\r
286                 {\r
287                         memcpy(pOriginal, pBackupCode, HOOK_JUMP_CODE_LENGTH);\r
288                         VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect);\r
289                         bResult = TRUE;\r
290                 }\r
291         }\r
292         else\r
293         {\r
294                 if(pBackupCode)\r
295                         memcpy(pBackupCode, pOriginal, HOOK_JUMP_CODE_LENGTH);\r
296                 if(VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, PAGE_EXECUTE_READWRITE, &Protect))\r
297                 {\r
298                         memcpy(pOriginal, &JumpCode, HOOK_JUMP_CODE_LENGTH);\r
299                         VirtualProtect(pOriginal, HOOK_JUMP_CODE_LENGTH, Protect, &Protect);\r
300                         bResult = TRUE;\r
301                 }\r
302         }\r
303 #endif\r
304         return bResult;\r
305 }\r
306 #endif\r
307 \r
308 #ifdef USE_IAT_HOOK\r
309 BOOL HookFunctionInIAT(void* pOriginal, void* pNew)\r
310 {\r
311         BOOL bResult;\r
312         HANDLE hSnapshot;\r
313         MODULEENTRY32 me;\r
314         BOOL bFound;\r
315         IMAGE_IMPORT_DESCRIPTOR* piid;\r
316         ULONG Size;\r
317         IMAGE_THUNK_DATA* pitd;\r
318         DWORD Protect;\r
319         bResult = FALSE;\r
320         if((hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId())) != INVALID_HANDLE_VALUE)\r
321         {\r
322                 me.dwSize = sizeof(MODULEENTRY32);\r
323                 if(Module32First(hSnapshot, &me))\r
324                 {\r
325                         bFound = FALSE;\r
326                         do\r
327                         {\r
328                                 if(piid = (IMAGE_IMPORT_DESCRIPTOR*)ImageDirectoryEntryToData(me.hModule, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &Size))\r
329                                 {\r
330                                         while(!bFound && piid->Name != 0)\r
331                                         {\r
332                                                 pitd = (IMAGE_THUNK_DATA*)((BYTE*)me.hModule + piid->FirstThunk);\r
333                                                 while(!bFound && pitd->u1.Function != 0)\r
334                                                 {\r
335                                                         if((void*)pitd->u1.Function == pOriginal)\r
336                                                         {\r
337                                                                 bFound = TRUE;\r
338                                                                 if(VirtualProtect(&pitd->u1.Function, sizeof(void*), PAGE_EXECUTE_READWRITE, &Protect))\r
339                                                                 {\r
340                                                                         memcpy(&pitd->u1.Function, &pNew, sizeof(void*));\r
341                                                                         VirtualProtect(&pitd->u1.Function, sizeof(void*), Protect, &Protect);\r
342                                                                         bResult = TRUE;\r
343                                                                 }\r
344                                                         }\r
345                                                         pitd++;\r
346                                                 }\r
347                                                 piid++;\r
348                                         }\r
349                                 }\r
350                         }\r
351                         while(!bFound && Module32Next(hSnapshot, &me));\r
352                 }\r
353                 CloseHandle(hSnapshot);\r
354         }\r
355         return bResult;\r
356 }\r
357 #endif\r
358 \r
359 // ファイルを変更不能に設定\r
360 HANDLE LockExistingFile(LPCWSTR Filename)\r
361 {\r
362         HANDLE hResult;\r
363         hResult = NULL;\r
364         if((hResult = CreateFileW(Filename, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL)) == INVALID_HANDLE_VALUE)\r
365                 hResult = NULL;\r
366         return hResult;\r
367 }\r
368 \r
369 // DLLのハッシュを検索\r
370 BOOL FindTrustedModuleSHA1Hash(void* pHash)\r
371 {\r
372         BOOL bResult;\r
373         int i;\r
374         bResult = FALSE;\r
375         i = 0;\r
376         while(i < MAX_TRUSTED_MD5_HASH_TABLE)\r
377         {\r
378                 if(memcmp(&g_TrustedMD5HashTable[i], pHash, 20) == 0)\r
379                 {\r
380                         bResult = TRUE;\r
381                         break;\r
382                 }\r
383                 i++;\r
384         }\r
385         return bResult;\r
386 }\r
387 \r
388 BOOL VerifyFileSignature_Function(LPCWSTR Filename)\r
389 {\r
390         BOOL bResult;\r
391         HCERTSTORE hStore;\r
392         PCCERT_CONTEXT pcc;\r
393         CERT_CHAIN_PARA ccp;\r
394         CERT_CHAIN_CONTEXT* pccc;\r
395         CERT_CHAIN_POLICY_PARA ccpp;\r
396         CERT_CHAIN_POLICY_STATUS ccps;\r
397         bResult = FALSE;\r
398         if(CryptQueryObject(CERT_QUERY_OBJECT_FILE, Filename, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, NULL, NULL, &hStore, NULL, NULL))\r
399         {\r
400                 pcc = NULL;\r
401                 while(!bResult && (pcc = CertEnumCertificatesInStore(hStore, pcc)))\r
402                 {\r
403                         ZeroMemory(&ccp, sizeof(CERT_CHAIN_PARA));\r
404                         ccp.cbSize = sizeof(CERT_CHAIN_PARA);\r
405                         if(CertGetCertificateChain(NULL, pcc, NULL, NULL, &ccp, 0, NULL, &pccc))\r
406                         {\r
407                                 ZeroMemory(&ccpp, sizeof(CERT_CHAIN_POLICY_PARA));\r
408                                 ccpp.cbSize = sizeof(CERT_CHAIN_POLICY_PARA);\r
409                                 if(g_ProcessProtectionLevel & PROCESS_PROTECTION_EXPIRED)\r
410                                         ccpp.dwFlags |= CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG;\r
411                                 else if(g_ProcessProtectionLevel & PROCESS_PROTECTION_UNAUTHORIZED)\r
412                                         ccpp.dwFlags |= CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG;\r
413                                 ZeroMemory(&ccps, sizeof(CERT_CHAIN_POLICY_STATUS));\r
414                                 ccps.cbSize = sizeof(CERT_CHAIN_POLICY_STATUS);\r
415                                 if(CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_AUTHENTICODE, pccc, &ccpp, &ccps))\r
416                                 {\r
417                                         if(ccps.dwError == ERROR_SUCCESS)\r
418                                         {\r
419                                                 bResult = TRUE;\r
420                                                 break;\r
421                                         }\r
422                                 }\r
423                                 CertFreeCertificateChain(pccc);\r
424                         }\r
425                 }\r
426                 while(pcc = CertEnumCertificatesInStore(hStore, pcc))\r
427                 {\r
428                 }\r
429                 CertCloseStore(hStore, 0);\r
430         }\r
431         return bResult;\r
432 }\r
433 \r
434 // ファイルの署名を確認\r
435 BOOL VerifyFileSignature(LPCWSTR Filename)\r
436 {\r
437         BOOL bResult;\r
438         GUID g = WINTRUST_ACTION_GENERIC_VERIFY_V2;\r
439         WINTRUST_FILE_INFO wfi;\r
440         WINTRUST_DATA wd;\r
441         bResult = FALSE;\r
442         ZeroMemory(&wfi, sizeof(WINTRUST_FILE_INFO));\r
443         wfi.cbStruct = sizeof(WINTRUST_FILE_INFO);\r
444         wfi.pcwszFilePath = Filename;\r
445         ZeroMemory(&wd, sizeof(WINTRUST_DATA));\r
446         wd.cbStruct = sizeof(WINTRUST_DATA);\r
447         wd.dwUIChoice = WTD_UI_NONE;\r
448         wd.dwUnionChoice = WTD_CHOICE_FILE;\r
449         wd.pFile = &wfi;\r
450         if(WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd) == ERROR_SUCCESS)\r
451                 bResult = TRUE;\r
452         else\r
453                 bResult = VerifyFileSignature_Function(Filename);\r
454         return bResult;\r
455 }\r
456 \r
457 // ファイルの署名をカタログファイルで確認\r
458 BOOL VerifyFileSignatureInCatalog(LPCWSTR Catalog, LPCWSTR Filename)\r
459 {\r
460         BOOL bResult;\r
461         GUID g = WINTRUST_ACTION_GENERIC_VERIFY_V2;\r
462         WINTRUST_CATALOG_INFO wci;\r
463         WINTRUST_DATA wd;\r
464         bResult = FALSE;\r
465         if(VerifyFileSignature(Catalog))\r
466         {\r
467                 ZeroMemory(&wci, sizeof(WINTRUST_CATALOG_INFO));\r
468                 wci.cbStruct = sizeof(WINTRUST_CATALOG_INFO);\r
469                 wci.pcwszCatalogFilePath = Catalog;\r
470                 wci.pcwszMemberFilePath = Filename;\r
471                 if((wci.hMemberFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)\r
472                 {\r
473                         p_CryptCATAdminCalcHashFromFileHandle(wci.hMemberFile, &wci.cbCalculatedFileHash, NULL, 0);\r
474                         if(wci.pbCalculatedFileHash = (BYTE*)malloc(wci.cbCalculatedFileHash))\r
475                         {\r
476                                 if(p_CryptCATAdminCalcHashFromFileHandle(wci.hMemberFile, &wci.cbCalculatedFileHash, wci.pbCalculatedFileHash, 0))\r
477                                 {\r
478                                         ZeroMemory(&wd, sizeof(WINTRUST_DATA));\r
479                                         wd.cbStruct = sizeof(WINTRUST_DATA);\r
480                                         wd.dwUIChoice = WTD_UI_NONE;\r
481                                         wd.dwUnionChoice = WTD_CHOICE_CATALOG;\r
482                                         wd.pCatalog = &wci;\r
483                                         if(WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd) == ERROR_SUCCESS)\r
484                                                 bResult = TRUE;\r
485                                 }\r
486                                 free(wci.pbCalculatedFileHash);\r
487                         }\r
488                         CloseHandle(wci.hMemberFile);\r
489                 }\r
490         }\r
491         return bResult;\r
492 }\r
493 \r
494 BOOL WINAPI GetSHA1HashOfModule_Function(DIGEST_HANDLE refdata, PBYTE pData, DWORD dwLength)\r
495 {\r
496         return CryptHashData(*(HCRYPTHASH*)refdata, pData, dwLength, 0);\r
497 }\r
498 \r
499 // モジュールのSHA1ハッシュを取得\r
500 // マニフェストファイルのfile要素のhash属性は実行可能ファイルの場合にImageGetDigestStreamで算出される\r
501 BOOL GetSHA1HashOfModule(LPCWSTR Filename, void* pHash)\r
502 {\r
503         BOOL bResult;\r
504         HCRYPTPROV hProv;\r
505         HCRYPTHASH hHash;\r
506         HANDLE hFile;\r
507         DWORD dw;\r
508         bResult = FALSE;\r
509         if(CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, 0) || CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))\r
510         {\r
511                 if(CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))\r
512                 {\r
513                         if((hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)\r
514                         {\r
515                                 if(ImageGetDigestStream(hFile, CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO, GetSHA1HashOfModule_Function, (DIGEST_HANDLE)&hHash))\r
516                                 {\r
517                                         dw = 20;\r
518                                         if(CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)pHash, &dw, 0))\r
519                                                 bResult = TRUE;\r
520                                 }\r
521                                 CloseHandle(hFile);\r
522                         }\r
523                         CryptDestroyHash(hHash);\r
524                 }\r
525                 CryptReleaseContext(hProv, 0);\r
526         }\r
527         return bResult;\r
528 }\r
529 \r
530 BOOL IsSxsModuleTrusted_Function(LPCWSTR Catalog, LPCWSTR Manifest, LPCWSTR Module)\r
531 {\r
532         BOOL bResult;\r
533         HANDLE hLock0;\r
534         HANDLE hLock1;\r
535         BYTE Hash[20];\r
536         int i;\r
537         static char HexTable[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};\r
538         char HashHex[41];\r
539         HANDLE hFile;\r
540         DWORD Size;\r
541         char* pData;\r
542         DWORD dw;\r
543         bResult = FALSE;\r
544         if(hLock0 = LockExistingFile(Catalog))\r
545         {\r
546                 if(hLock1 = LockExistingFile(Manifest))\r
547                 {\r
548                         if(VerifyFileSignatureInCatalog(Catalog, Manifest))\r
549                         {\r
550                                 if(GetSHA1HashOfModule(Module, &Hash))\r
551                                 {\r
552                                         for(i = 0; i < 20; i++)\r
553                                         {\r
554                                                 HashHex[i * 2] = HexTable[(Hash[i] >> 4) & 0x0f];\r
555                                                 HashHex[i * 2 + 1] = HexTable[Hash[i] & 0x0f];\r
556                                         }\r
557                                         HashHex[i * 2] = '\0';\r
558                                         if((hFile = CreateFileW(Manifest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)\r
559                                         {\r
560                                                 Size = GetFileSize(hFile, NULL);\r
561                                                 if(pData = (char*)VirtualAlloc(NULL, Size + 1, MEM_COMMIT, PAGE_READWRITE))\r
562                                                 {\r
563                                                         VirtualLock(pData, Size + 1);\r
564                                                         if(ReadFile(hFile, pData, Size, &dw, NULL))\r
565                                                         {\r
566                                                                 pData[dw] = '\0';\r
567                                                                 if(strstr(pData, HashHex))\r
568                                                                         bResult = TRUE;\r
569                                                         }\r
570                                                         VirtualUnlock(pData, Size + 1);\r
571                                                         VirtualFree(pData, Size + 1, MEM_DECOMMIT);\r
572                                                 }\r
573                                                 CloseHandle(hFile);\r
574                                         }\r
575                                 }\r
576                         }\r
577                         CloseHandle(hLock1);\r
578                 }\r
579                 CloseHandle(hLock0);\r
580         }\r
581         return bResult;\r
582 }\r
583 \r
584 // サイドバイサイドDLLを確認\r
585 // パスは"%SystemRoot%\WinSxS"以下を想定\r
586 // 以下のファイルが存在するものとする\r
587 // "\xxx\yyy.dll"、"\manifests\xxx.cat"、"\manifests\xxx.manifest"のセット(XPの全てのDLL、Vista以降の一部のDLL)\r
588 // "\xxx\yyy.dll"、"\catalogs\zzz.cat"、"\manifests\xxx.manifest"のセット(Vista以降のほとんどのDLL)\r
589 // 署名されたカタログファイルを用いてマニフェストファイルが改竄されていないことを確認\r
590 // ハッシュ値は   マニフェストファイルのfile要素のhash属性に記述されているものを用いる\r
591 // マニフェストファイル内にSHA1ハッシュ値の16進数表記を直接検索しているが確率的に問題なし\r
592 BOOL IsSxsModuleTrusted(LPCWSTR Filename)\r
593 {\r
594         BOOL bResult;\r
595         wchar_t* pw0;\r
596         wchar_t* pw1;\r
597         wchar_t* pw2;\r
598         wchar_t* pw3;\r
599         wchar_t* pw4;\r
600         wchar_t* pw5;\r
601         wchar_t* p;\r
602         HANDLE hFind;\r
603         WIN32_FIND_DATAW wfd;\r
604         bResult = FALSE;\r
605         if(pw0 = AllocateStringW(wcslen(Filename) + 1))\r
606         {\r
607                 wcscpy(pw0, Filename);\r
608                 if(p = wcsrchr(pw0, L'\\'))\r
609                 {\r
610                         wcscpy(p, L"");\r
611                         if(p = wcsrchr(pw0, L'\\'))\r
612                         {\r
613                                 p++;\r
614                                 if(pw1 = AllocateStringW(wcslen(p) + 1))\r
615                                 {\r
616                                         wcscpy(pw1, p);\r
617                                         wcscpy(p, L"");\r
618                                         if(pw2 = AllocateStringW(wcslen(pw0) + wcslen(L"manifests\\") + wcslen(pw1) + wcslen(L".cat") + 1))\r
619                                         {\r
620                                                 wcscpy(pw2, pw0);\r
621                                                 wcscat(pw2, L"manifests\\");\r
622                                                 wcscat(pw2, pw1);\r
623                                                 if(pw3 = AllocateStringW(wcslen(pw2) + wcslen(L".manifest") + 1))\r
624                                                 {\r
625                                                         wcscpy(pw3, pw2);\r
626                                                         wcscat(pw3, L".manifest");\r
627                                                         wcscat(pw2, L".cat");\r
628                                                         if(IsSxsModuleTrusted_Function(pw2, pw3, Filename))\r
629                                                                 bResult = TRUE;\r
630                                                         FreeDuplicatedString(pw3);\r
631                                                 }\r
632                                                 FreeDuplicatedString(pw2);\r
633                                         }\r
634                                         if(!bResult)\r
635                                         {\r
636                                                 if(pw2 = AllocateStringW(wcslen(pw0) + wcslen(L"catalogs\\") + 1))\r
637                                                 {\r
638                                                         if(pw3 = AllocateStringW(wcslen(pw0) + wcslen(L"manifests\\") + wcslen(pw1) + wcslen(L".manifest") + 1))\r
639                                                         {\r
640                                                                 wcscpy(pw2, pw0);\r
641                                                                 wcscat(pw2, L"catalogs\\");\r
642                                                                 wcscpy(pw3, pw0);\r
643                                                                 wcscat(pw3, L"manifests\\");\r
644                                                                 wcscat(pw3, pw1);\r
645                                                                 wcscat(pw3, L".manifest");\r
646                                                                 if(pw4 = AllocateStringW(wcslen(pw2) + wcslen(L"*.cat") + 1))\r
647                                                                 {\r
648                                                                         wcscpy(pw4, pw2);\r
649                                                                         wcscat(pw4, L"*.cat");\r
650                                                                         if((hFind = FindFirstFileW(pw4, &wfd)) != INVALID_HANDLE_VALUE)\r
651                                                                         {\r
652                                                                                 do\r
653                                                                                 {\r
654                                                                                         if(pw5 = AllocateStringW(wcslen(pw2) + wcslen(wfd.cFileName) + 1))\r
655                                                                                         {\r
656                                                                                                 wcscpy(pw5, pw2);\r
657                                                                                                 wcscat(pw5, wfd.cFileName);\r
658                                                                                                 if(IsSxsModuleTrusted_Function(pw5, pw3, Filename))\r
659                                                                                                         bResult = TRUE;\r
660                                                                                                 FreeDuplicatedString(pw5);\r
661                                                                                         }\r
662                                                                                 }\r
663                                                                                 while(!bResult && FindNextFileW(hFind, &wfd));\r
664                                                                                 FindClose(hFind);\r
665                                                                         }\r
666                                                                         FreeDuplicatedString(pw4);\r
667                                                                 }\r
668                                                                 FreeDuplicatedString(pw3);\r
669                                                         }\r
670                                                         FreeDuplicatedString(pw2);\r
671                                                 }\r
672                                         }\r
673                                         FreeDuplicatedString(pw1);\r
674                                 }\r
675                         }\r
676                 }\r
677                 FreeDuplicatedString(pw0);\r
678         }\r
679         return bResult;\r
680 }\r
681 \r
682 // DLLを確認\r
683 BOOL IsModuleTrusted(LPCWSTR Filename)\r
684 {\r
685         BOOL bResult;\r
686         BYTE Hash[20];\r
687         bResult = FALSE;\r
688         if(LockThreadLock())\r
689         {\r
690                 if(GetSHA1HashOfFile(Filename, &Hash))\r
691                 {\r
692                         if(FindTrustedModuleSHA1Hash(&Hash))\r
693                                 bResult = TRUE;\r
694                 }\r
695                 if(!bResult)\r
696                 {\r
697                         if((g_ProcessProtectionLevel & PROCESS_PROTECTION_BUILTIN) && VerifyFileSignature(Filename))\r
698                                 bResult = TRUE;\r
699                 }\r
700                 if(!bResult)\r
701                 {\r
702                         if((g_ProcessProtectionLevel & PROCESS_PROTECTION_SIDE_BY_SIDE) && IsSxsModuleTrusted(Filename))\r
703                                 bResult = TRUE;\r
704                 }\r
705                 if(!bResult)\r
706                 {\r
707                         if((g_ProcessProtectionLevel & PROCESS_PROTECTION_SYSTEM_FILE) && SfcIsFileProtected(NULL, Filename))\r
708                                 bResult = TRUE;\r
709                 }\r
710                 UnlockThreadLock();\r
711         }\r
712         return bResult;\r
713 }\r
714 \r
715 // kernel32.dllのLoadLibraryExW相当の関数\r
716 // ドキュメントが無いため詳細は不明\r
717 // 一部のウィルス対策ソフト(Avast!等)がLdrLoadDllをフックしているためLdrLoadDllを書き換えるべきではない\r
718 // カーネルモードのコードに対しては効果なし\r
719 // SeDebugPrivilegeが使用可能なユーザーに対しては効果なし\r
720 HMODULE System_LoadLibrary(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)\r
721 {\r
722         HMODULE r = NULL;\r
723         UNICODE_STRING us;\r
724         HANDLE hDataFile;\r
725         HANDLE hMapping;\r
726         DWORD DllFlags;\r
727         us.Length = sizeof(wchar_t) * wcslen(lpLibFileName);\r
728         us.MaximumLength = sizeof(wchar_t) * (wcslen(lpLibFileName) + 1);\r
729         us.Buffer = (PWSTR)lpLibFileName;\r
730 //      if(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE))\r
731         if(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | 0x00000040))\r
732         {\r
733 //              if(p_LdrGetDllHandle(NULL, NULL, &us, &r) == STATUS_SUCCESS)\r
734                 if(p_LdrGetDllHandle(NULL, NULL, &us, &r) == 0)\r
735                 {\r
736 //                      dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE);\r
737                         dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | 0x00000040);\r
738                         dwFlags |= DONT_RESOLVE_DLL_REFERENCES;\r
739                 }\r
740                 else\r
741                 {\r
742 //                      if(dwFlags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)\r
743                         if(dwFlags & 0x00000040)\r
744                                 hDataFile = CreateFileW(lpLibFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);\r
745                         else\r
746                                 hDataFile = CreateFileW(lpLibFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL);\r
747                         if(hDataFile != INVALID_HANDLE_VALUE)\r
748                         {\r
749                                 if(hMapping = CreateFileMappingW(hDataFile, NULL, PAGE_READONLY, 0, 0, NULL))\r
750                                 {\r
751                                         if(r = (HMODULE)MapViewOfFileEx(hMapping, FILE_MAP_READ, 0, 0, 0, NULL))\r
752                                         {\r
753                                                 if(p_RtlImageNtHeader(r))\r
754                                                         r = (HMODULE)((size_t)r | 1);\r
755                                                 else\r
756                                                 {\r
757                                                         UnmapViewOfFile(r);\r
758                                                         r = NULL;\r
759                                                 }\r
760                                         }\r
761                                         CloseHandle(hMapping);\r
762                                 }\r
763                                 CloseHandle(hDataFile);\r
764                         }\r
765                         else\r
766                         {\r
767 //                              dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE);\r
768                                 dwFlags &= ~(LOAD_LIBRARY_AS_DATAFILE | 0x00000040);\r
769                                 dwFlags |= DONT_RESOLVE_DLL_REFERENCES;\r
770                         }\r
771                 }\r
772         }\r
773 //      if(!(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)))\r
774         if(!(dwFlags & (LOAD_LIBRARY_AS_DATAFILE | 0x00000040)))\r
775         {\r
776                 DllFlags = 0;\r
777 //              if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_IMAGE_RESOURCE))\r
778                 if(dwFlags & (DONT_RESOLVE_DLL_REFERENCES | 0x00000020))\r
779                         DllFlags |= 0x00000002;\r
780 //              if(p_LdrLoadDll(NULL, &DllFlags, &us, &r) == STATUS_SUCCESS)\r
781                 if(p_LdrLoadDll(NULL, &DllFlags, &us, &r) == 0)\r
782                 {\r
783                 }\r
784                 else\r
785                         r = NULL;\r
786         }\r
787         return r;\r
788 }\r
789 \r
790 void SetProcessProtectionLevel(DWORD Level)\r
791 {\r
792         g_ProcessProtectionLevel = Level;\r
793 }\r
794 \r
795 // ファイルのSHA1ハッシュを取得\r
796 BOOL GetSHA1HashOfFile(LPCWSTR Filename, void* pHash)\r
797 {\r
798         BOOL bResult;\r
799         HCRYPTPROV hProv;\r
800         HCRYPTHASH hHash;\r
801         HANDLE hFile;\r
802         DWORD Size;\r
803         void* pData;\r
804         DWORD dw;\r
805         bResult = FALSE;\r
806         if(CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, 0) || CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))\r
807         {\r
808                 if(CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))\r
809                 {\r
810                         if((hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)\r
811                         {\r
812                                 Size = GetFileSize(hFile, NULL);\r
813                                 if(pData = VirtualAlloc(NULL, Size, MEM_COMMIT, PAGE_READWRITE))\r
814                                 {\r
815                                         VirtualLock(pData, Size);\r
816                                         if(ReadFile(hFile, pData, Size, &dw, NULL))\r
817                                         {\r
818                                                 if(CryptHashData(hHash, (BYTE*)pData, Size, 0))\r
819                                                 {\r
820                                                         dw = 20;\r
821                                                         if(CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)pHash, &dw, 0))\r
822                                                                 bResult = TRUE;\r
823                                                 }\r
824                                         }\r
825                                         VirtualUnlock(pData, Size);\r
826                                         VirtualFree(pData, Size, MEM_DECOMMIT);\r
827                                 }\r
828                                 CloseHandle(hFile);\r
829                         }\r
830                         CryptDestroyHash(hHash);\r
831                 }\r
832                 CryptReleaseContext(hProv, 0);\r
833         }\r
834         return bResult;\r
835 }\r
836 \r
837 // DLLのハッシュを登録\r
838 BOOL RegisterTrustedModuleSHA1Hash(void* pHash)\r
839 {\r
840         BOOL bResult;\r
841         BYTE NullHash[20] = {0};\r
842         int i;\r
843         bResult = FALSE;\r
844         if(FindTrustedModuleSHA1Hash(pHash))\r
845                 bResult = TRUE;\r
846         else\r
847         {\r
848                 i = 0;\r
849                 while(i < MAX_TRUSTED_MD5_HASH_TABLE)\r
850                 {\r
851                         if(memcmp(&g_TrustedMD5HashTable[i], &NullHash, 20) == 0)\r
852                         {\r
853                                 memcpy(&g_TrustedMD5HashTable[i], pHash, 20);\r
854                                 bResult = TRUE;\r
855                                 break;\r
856                         }\r
857                         i++;\r
858                 }\r
859         }\r
860         return bResult;\r
861 }\r
862 \r
863 // DLLのハッシュの登録を解除\r
864 BOOL UnregisterTrustedModuleSHA1Hash(void* pHash)\r
865 {\r
866         BOOL bResult;\r
867         BYTE NullHash[20] = {0};\r
868         int i;\r
869         bResult = FALSE;\r
870         i = 0;\r
871         while(i < MAX_TRUSTED_MD5_HASH_TABLE)\r
872         {\r
873                 if(memcmp(&g_TrustedMD5HashTable[i], pHash, 20) == 0)\r
874                 {\r
875                         memcpy(&g_TrustedMD5HashTable[i], &NullHash, 20);\r
876                         bResult = TRUE;\r
877                         break;\r
878                 }\r
879                 i++;\r
880         }\r
881         return bResult;\r
882 }\r
883 \r
884 // 信頼できないDLLをアンロード\r
885 BOOL UnloadUntrustedModule()\r
886 {\r
887         BOOL bResult;\r
888         wchar_t* pw0;\r
889         HANDLE hSnapshot;\r
890         MODULEENTRY32 me;\r
891         DWORD Length;\r
892         bResult = FALSE;\r
893         pw0 = NULL;\r
894         if((hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId())) != INVALID_HANDLE_VALUE)\r
895         {\r
896                 bResult = TRUE;\r
897                 me.dwSize = sizeof(MODULEENTRY32);\r
898                 if(Module32First(hSnapshot, &me))\r
899                 {\r
900                         do\r
901                         {\r
902                                 Length = MAX_PATH;\r
903                                 FreeDuplicatedString(pw0);\r
904                                 if(pw0 = AllocateStringW(Length))\r
905                                 {\r
906                                         if(GetModuleFileNameW(me.hModule, pw0, Length) > 0)\r
907                                         {\r
908                                                 while(pw0)\r
909                                                 {\r
910                                                         if(GetModuleFileNameW(me.hModule, pw0, Length) + 1 <= Length)\r
911                                                                 break;\r
912                                                         Length = Length * 2;\r
913                                                         FreeDuplicatedString(pw0);\r
914                                                         pw0 = AllocateStringW(Length);\r
915                                                 }\r
916                                         }\r
917                                 }\r
918                                 if(pw0)\r
919                                 {\r
920                                         if(!IsModuleTrusted(pw0))\r
921                                         {\r
922                                                 if(me.hModule != GetModuleHandleW(NULL))\r
923                                                 {\r
924                                                         while(FreeLibrary(me.hModule))\r
925                                                         {\r
926                                                         }\r
927                                                         if(GetModuleFileNameW(me.hModule, pw0, Length) > 0)\r
928                                                         {\r
929                                                                 bResult = FALSE;\r
930                                                                 break;\r
931                                                         }\r
932                                                 }\r
933                                         }\r
934                                 }\r
935                                 else\r
936                                 {\r
937                                         bResult = FALSE;\r
938                                         break;\r
939                                 }\r
940                         }\r
941                         while(Module32Next(hSnapshot, &me));\r
942                 }\r
943                 CloseHandle(hSnapshot);\r
944         }\r
945         FreeDuplicatedString(pw0);\r
946         return bResult;\r
947 }\r
948 \r
949 // 関数ポインタを使用可能な状態に初期化\r
950 BOOL InitializeLoadLibraryHook()\r
951 {\r
952         BOOL bResult;\r
953         HMODULE hModule;\r
954         bResult = TRUE;\r
955         if(!(hModule = GetModuleHandleW(L"kernel32.dll")))\r
956                 bResult = FALSE;\r
957         if(!(GET_FUNCTION(hModule, LoadLibraryA)))\r
958                 bResult = FALSE;\r
959         if(!(GET_FUNCTION(hModule, LoadLibraryW)))\r
960                 bResult = FALSE;\r
961         if(!(GET_FUNCTION(hModule, LoadLibraryExA)))\r
962                 bResult = FALSE;\r
963         if(!(GET_FUNCTION(hModule, LoadLibraryExW)))\r
964                 bResult = FALSE;\r
965         if(!(hModule = GetModuleHandleW(L"ntdll.dll")))\r
966                 bResult = FALSE;\r
967         if(!(GET_FUNCTION(hModule, LdrLoadDll)))\r
968                 bResult = FALSE;\r
969         if(!(GET_FUNCTION(hModule, LdrGetDllHandle)))\r
970                 bResult = FALSE;\r
971         if(!(GET_FUNCTION(hModule, RtlImageNtHeader)))\r
972                 bResult = FALSE;\r
973         if(!(hModule = LoadLibraryW(L"wintrust.dll")))\r
974                 bResult = FALSE;\r
975         if(!(GET_FUNCTION(hModule, CryptCATAdminCalcHashFromFileHandle)))\r
976                 bResult = FALSE;\r
977         return bResult;\r
978 }\r
979 \r
980 // SetWindowsHookEx対策\r
981 // DLL Injectionされた場合は上のh_LoadLibrary系関数でトラップ可能\r
982 BOOL EnableLoadLibraryHook(BOOL bEnable)\r
983 {\r
984         BOOL bResult;\r
985         bResult = FALSE;\r
986         if(bEnable)\r
987         {\r
988                 bResult = TRUE;\r
989 #ifdef USE_CODE_HOOK\r
990                 if(!SET_HOOK_FUNCTION(LoadLibraryA))\r
991                         bResult = FALSE;\r
992                 if(!SET_HOOK_FUNCTION(LoadLibraryW))\r
993                         bResult = FALSE;\r
994                 if(!SET_HOOK_FUNCTION(LoadLibraryExA))\r
995                         bResult = FALSE;\r
996                 if(!SET_HOOK_FUNCTION(LoadLibraryExW))\r
997                         bResult = FALSE;\r
998 #endif\r
999 #ifdef USE_IAT_HOOK\r
1000                 if(!HookFunctionInIAT(p_LoadLibraryA, h_LoadLibraryA))\r
1001                         bResult = FALSE;\r
1002                 if(!HookFunctionInIAT(p_LoadLibraryW, h_LoadLibraryW))\r
1003                         bResult = FALSE;\r
1004                 if(!HookFunctionInIAT(p_LoadLibraryExA, h_LoadLibraryExA))\r
1005                         bResult = FALSE;\r
1006                 if(!HookFunctionInIAT(p_LoadLibraryExW, h_LoadLibraryExW))\r
1007                         bResult = FALSE;\r
1008 #endif\r
1009         }\r
1010         else\r
1011         {\r
1012                 bResult = TRUE;\r
1013 #ifdef USE_CODE_HOOK\r
1014                 if(!END_HOOK_FUNCTION(LoadLibraryA))\r
1015                         bResult = FALSE;\r
1016                 if(!END_HOOK_FUNCTION(LoadLibraryW))\r
1017                         bResult = FALSE;\r
1018                 if(!END_HOOK_FUNCTION(LoadLibraryExA))\r
1019                         bResult = FALSE;\r
1020                 if(!END_HOOK_FUNCTION(LoadLibraryExW))\r
1021                         bResult = FALSE;\r
1022 #endif\r
1023 #ifdef USE_IAT_HOOK\r
1024                 if(!HookFunctionInIAT(h_LoadLibraryA, p_LoadLibraryA))\r
1025                         bResult = FALSE;\r
1026                 if(!HookFunctionInIAT(h_LoadLibraryW, p_LoadLibraryW))\r
1027                         bResult = FALSE;\r
1028                 if(!HookFunctionInIAT(h_LoadLibraryExA, p_LoadLibraryExA))\r
1029                         bResult = FALSE;\r
1030                 if(!HookFunctionInIAT(h_LoadLibraryExW, p_LoadLibraryExW))\r
1031                         bResult = FALSE;\r
1032 #endif\r
1033         }\r
1034         return bResult;\r
1035 }\r
1036 \r
1037 // ReadProcessMemory、WriteProcessMemory、CreateRemoteThread対策\r
1038 // TerminateProcessのみ許可\r
1039 BOOL RestartProtectedProcess(LPCTSTR Keyword)\r
1040 {\r
1041         BOOL bResult;\r
1042         ACL* pACL;\r
1043         SID_IDENTIFIER_AUTHORITY sia = SECURITY_WORLD_SID_AUTHORITY;\r
1044         PSID pSID;\r
1045         SECURITY_DESCRIPTOR sd;\r
1046         TCHAR* CommandLine;\r
1047         SECURITY_ATTRIBUTES sa;\r
1048         STARTUPINFO si;\r
1049         PROCESS_INFORMATION pi;\r
1050         bResult = FALSE;\r
1051         if(_tcslen(GetCommandLine()) >= _tcslen(Keyword) && _tcscmp(GetCommandLine() + _tcslen(GetCommandLine()) - _tcslen(Keyword), Keyword) == 0)\r
1052                 return FALSE;\r
1053         if(pACL = (ACL*)malloc(sizeof(ACL) + 1024))\r
1054         {\r
1055                 if(InitializeAcl(pACL, sizeof(ACL) + 1024, ACL_REVISION))\r
1056                 {\r
1057                         if(AllocateAndInitializeSid(&sia, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pSID))\r
1058                         {\r
1059                                 if(AddAccessAllowedAce(pACL, ACL_REVISION, PROCESS_TERMINATE, pSID))\r
1060                                 {\r
1061                                         if(InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))\r
1062                                         {\r
1063                                                 if(SetSecurityDescriptorDacl(&sd, TRUE, pACL, FALSE))\r
1064                                                 {\r
1065                                                         if(CommandLine = (TCHAR*)malloc(sizeof(TCHAR) * (_tcslen(GetCommandLine()) + _tcslen(Keyword) + 1)))\r
1066                                                         {\r
1067                                                                 _tcscpy(CommandLine, GetCommandLine());\r
1068                                                                 _tcscat(CommandLine, Keyword);\r
1069                                                                 sa.nLength = sizeof(SECURITY_ATTRIBUTES);\r
1070                                                                 sa.lpSecurityDescriptor = &sd;\r
1071                                                                 sa.bInheritHandle = FALSE;\r
1072                                                                 GetStartupInfo(&si);\r
1073                                                                 if(CreateProcess(NULL, CommandLine, &sa, NULL, FALSE, 0, NULL, NULL, &si, &pi))\r
1074                                                                 {\r
1075                                                                         CloseHandle(pi.hThread);\r
1076                                                                         CloseHandle(pi.hProcess);\r
1077                                                                         bResult = TRUE;\r
1078                                                                 }\r
1079                                                                 free(CommandLine);\r
1080                                                         }\r
1081                                                 }\r
1082                                         }\r
1083                                 }\r
1084                                 FreeSid(pSID);\r
1085                         }\r
1086                 }\r
1087                 free(pACL);\r
1088         }\r
1089         return bResult;\r
1090 }\r
1091 \r