OSDN Git Service

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