OSDN Git Service

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