OSDN Git Service

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