#include "precomp.h" #define MAXIMUM_PATH_LENGTH 260 * 4 #define MAXIMUM_PROCESS_LENGTH 512 ///Æú´õ °ü¸® ±¸Á¶Ã¼ typedef struct _PROTECT_PATH { ULONG type; WCHAR protect_path[MAXIMUM_PATH_LENGTH]; ULONG path_size; LIST_ENTRY list; }PROTECT_PATH, * PPROTECT_PATH; ///ÇÁ·Î¼¼½º °ü¸® ±¸Á¶Ã¼ typedef struct _ALLOW_PROCESS { ULONG type; WCHAR process_path[MAXIMUM_PROCESS_LENGTH]; ULONG path_size; LIST_ENTRY list; }ALLOW_PROCESS, * PALLOW_PROCESS; ///Á¾·á °ü¸® ±¸Á¶Ã¼ typedef struct _EXIT_PID_K { ULONG pid; LIST_ENTRY list; }EXIT_PID_K, * PEXIT_PID_K; typedef struct _FIND_PATH_CONTEXT { ULONG type; PWCHAR path; ULONG size; }FIND_PATH_CONTEXT, * PFIND_PATH_CONTEXT; typedef struct _FIND_USB_CONTEXT { ULONG devicetype; ULONG vendor; ULONG product; PWCHAR seiral; }FIND_USB_CONTEXT, * PFIND_USB_CONTEXT; typedef struct _FIND_USBDISK_CONTEXT { PCHAR vendor; PCHAR product; PCHAR productrevisionlevel; PCHAR seiral; }FIND_USBDISK_CONTEXT, * PFIND_USBDISK_CONTEXT; typedef struct _PROTECT_REG { WCHAR regkey[MAXIMUM_PATH_LENGTH]; ULONG size; LIST_ENTRY list; }PROTECT_REG, * PPROTECT_REG; typedef struct _IPADDRESS_MANAGER_LIST { IPADDRESS_MANAGER ipaddress_manager; LIST_ENTRY list; }IP_ADDRESS, * PIP_ADDRESS; typedef struct _HOST_ADDRESS_MANAGER_LIST { HOST_ADDRESS_MANAGER host_address_manager; LIST_ENTRY list; }HOST_ADDRESS, * PHOST_ADDRESS; typedef struct _BS1FLT_USB_DISK_EXCEPT_LIST { BS1FLT_USB_DISK_EXCEPT ue; LIST_ENTRY list; }BS1FLT_USB_DISK_EXCEPT_LIST, * PBS1FLT_USB_DISK_EXCEPT_LIST; typedef struct _BS1FLT_USB_PORT_EXCEPT_LIST { BS1FLT_USB_PORT_EXCEPT upe; LIST_ENTRY list; }BS1FLT_USB_PORT_EXCEPT_LIST, * PBS1FLT_USB_PORT_EXCEPT_LIST; // Çã¿ë ÇÁ·Î¼¼½º Ç® °æ·Î ¸®½ºÆ® static LIST_ENTRY s_allow_processlist; static KSPIN_LOCK s_allow_processlock; // º¸È£ / °¨½Ã °æ·Î ¸®½ºÆ® static LIST_ENTRY s_protect_pathlist; static KSPIN_LOCK s_protect_spinlock; // Çã¿ë ÆÄÀÏ ¸®½ºÆ® static LIST_ENTRY s_allow_filelist; static KSPIN_LOCK s_allow_filelock; //static EXIT_PID s_ExitPid; static ULONG s_exit_pidcnt; static LIST_ENTRY s_exit_pidlist; static KSPIN_LOCK s_exit_pidlock; ///Unload½Ã »èÁ¦ ÆÄÀÏ ¸ñ·Ï static LIST_ENTRY s_deletefile_list; static KSPIN_LOCK s_deletefile_lock; ///Unload½Ã Á¾·á ÇÁ·Î¼¼½º ¸ñ·Ï static LIST_ENTRY s_terminatepid_list; static KSPIN_LOCK s_terminatepid_lock; ///SDist CustomPolicy ¸ñ·Ï static LIST_ENTRY s_sdistcustom_list; static KSPIN_LOCK s_sdistcustom_lock; static BOOLEAN s_IsSdistCustomPolicy = FALSE; // º¸È£ ÇÁ·Î¼¼½º ¸®½ºÆ® static LIST_ENTRY s_protectProcessList; static KSPIN_LOCK s_protectProcessSpinlock; // ·¹Áö½ºÆ®¸® º¸È£ ¸®½ºÆ® // static LIST_ENTRY s_protect_reg_list; static KSPIN_LOCK s_protect_reg_lock; static LIST_ENTRY s_usb_disk_except_list = { 0, }; static KSPIN_LOCK s_usb_disk_except_lock; static ULONG s_usb_disk_except_list_count = 0; static LIST_ENTRY s_usb_port_except_list = { 0, }; static KSPIN_LOCK s_usb_port_except_lock; static LIST_ENTRY s_ipaddresslist = { 0, }; static KSPIN_LOCK s_ipaddresslock; static LIST_ENTRY s_hostaddresslist = { 0, }; static KSPIN_LOCK s_hostaddresslock; #define PROTECT_PATH_POOLTAG 'cspp' #define ALLOW_PROCESS_POOLTAG 'cspo' #define EXIT_PID_POOLTAG 'csep' #define PROTECT_REG_POOLTAG 'csfp' #define USB_EXCEPTION_POOLTAG 'csue' //------------------------------------------------------------------------ VOID Initlist() { InitializeListHead(&s_protect_pathlist); KeInitializeSpinLock(&s_protect_spinlock); InitializeListHead(&s_allow_processlist); KeInitializeSpinLock(&s_allow_processlock); InitializeListHead(&s_allow_filelist); KeInitializeSpinLock(&s_allow_filelock); KeInitializeSpinLock(&s_protect_reg_lock); InitializeListHead(&s_protect_reg_list); InitializeListHead(&s_ipaddresslist); KeInitializeSpinLock(&s_ipaddresslock); InitializeListHead(&s_hostaddresslist); KeInitializeSpinLock(&s_hostaddresslock); InitializeListHead(&s_protectProcessList); KeInitializeSpinLock(&s_protectProcessSpinlock); InitializeListHead(&s_usb_disk_except_list); KeInitializeSpinLock(&s_usb_disk_except_lock); #ifdef USB_PORT_HOOK InitializeListHead(&s_usb_port_except_list); KeInitializeSpinLock(&s_usb_port_except_lock); #endif } static BOOLEAN NTAPI _FindProcessPath(PLIST_ENTRY node, PVOID p, ULONG d) { PALLOW_PROCESS process = (PALLOW_PROCESS)CONTAINING_RECORD(node, ALLOW_PROCESS, list); WCHAR* pwPath = (WCHAR*)p; ULONG size = (ULONG)d; if (process->path_size != size) return TRUE; if (_wcsnicmp(pwPath, process->process_path, process->path_size / sizeof(wchar_t)) == 0) { return FALSE; } return TRUE; } VOID SetProcessPath(ULONG type, PWCHAR process_path, ULONG size) { PALLOW_PROCESS pprocess = NULL; KIRQL oldIrql; PLIST_ENTRY pListEntry = NULL; if (!IsListEmpty(&s_allow_processlist)) { KeAcquireSpinLock(&s_allow_processlock, &oldIrql); pListEntry = (PLIST_ENTRY)WalkList(&s_allow_processlist, _FindProcessPath, (PVOID)process_path, size); if (pListEntry) { pprocess = CONTAINING_RECORD(pListEntry, ALLOW_PROCESS, list); pprocess->type |= type; KeReleaseSpinLock(&s_allow_processlock, oldIrql); return; } KeReleaseSpinLock(&s_allow_processlock, oldIrql); } pprocess = (PALLOW_PROCESS)ExAllocatePoolWithTag(NonPagedPool, sizeof(ALLOW_PROCESS), ALLOW_PROCESS_POOLTAG); if (!pprocess) return; RtlZeroMemory(pprocess, sizeof(ALLOW_PROCESS)); pprocess->type = type; pprocess->path_size = size; wcsncpy(pprocess->process_path, process_path, size); KeAcquireSpinLock(&s_allow_processlock, &oldIrql); InsertTailList(&s_allow_processlist, &pprocess->list); KeReleaseSpinLock(&s_allow_processlock, oldIrql); KLogEx(DEBUG_TRACE_INFO, "path(%S), ulType(%d), size(%d)\n", process_path, type, size); } static BOOLEAN NTAPI _DelAllProcessType(PLIST_ENTRY node, PVOID p, ULONG d) { PALLOW_PROCESS process = (PALLOW_PROCESS)CONTAINING_RECORD(node, ALLOW_PROCESS, list); ULONG type = (ULONG)d; UNREFERENCED_PARAMETER(p); UNREFERENCED_PARAMETER(d); if (process->type == type) { RemoveEntryList(&process->list); ExFreePoolWithTag(process, ALLOW_PROCESS_POOLTAG); } else if (process->type & type) { process->type &= ~type; } return TRUE; } VOID DelProcessPath(ULONG type, PWCHAR process_path, ULONG size) { KIRQL irql; PALLOW_PROCESS l = NULL; PLIST_ENTRY pLink = NULL; //FIND_PATH_CONTEXT context = { 0, }; KeAcquireSpinLock(&s_allow_processlock, &irql); if (process_path == NULL || size == 0) { (PLIST_ENTRY)WalkList(&s_allow_processlist, (WalkCallbackFuncT)_DelAllProcessType, (PVOID)NULL, type); } else { pLink = (PLIST_ENTRY)WalkList(&s_allow_processlist, _FindProcessPath, (PVOID)process_path, size); if (pLink) { l = (PALLOW_PROCESS)CONTAINING_RECORD(pLink, ALLOW_PROCESS, list); if (l->type == type) { RemoveEntryList(&l->list); ExFreePoolWithTag(l, ALLOW_PROCESS_POOLTAG); } else if (l->type & type) { l->type &= ~type; } } } KeReleaseSpinLock(&s_allow_processlock, irql); } VOID CleanupProcesslist() { PLIST_ENTRY pList = NULL; PALLOW_PROCESS pprocess = NULL; KIRQL oldIrql; KeAcquireSpinLock(&s_allow_processlock, &oldIrql); while (!IsListEmpty(&s_allow_processlist)) { pList = RemoveHeadList(&s_allow_processlist); pprocess = CONTAINING_RECORD(pList, ALLOW_PROCESS, list); ExFreePoolWithTag(pprocess, ALLOW_PROCESS_POOLTAG); pprocess = NULL; } KeReleaseSpinLock(&s_allow_processlock, oldIrql); KLogEx(DEBUG_TRACE_INFO, "success\n"); } /// °æ·Î °ü¸® ¸®½ºÆ® ÇÔ¼ö ºÎºÐ static BOOLEAN NTAPI _DelAllType(PLIST_ENTRY node, PVOID p, ULONG d) { PPROTECT_PATH protect_path = (PPROTECT_PATH)CONTAINING_RECORD(node, PROTECT_PATH, list); ULONG type = (ULONG)d; UNREFERENCED_PARAMETER(p); UNREFERENCED_PARAMETER(d); if (protect_path->type & type) { RemoveEntryList(&protect_path->list); ExFreePoolWithTag(protect_path, PROTECT_PATH_POOLTAG); } return TRUE; } static BOOLEAN NTAPI _FindPath(PLIST_ENTRY node, PVOID p, ULONG d) { PPROTECT_PATH pprotect = (PPROTECT_PATH)CONTAINING_RECORD(node, PROTECT_PATH, list); PFIND_PATH_CONTEXT context = (PFIND_PATH_CONTEXT)p; UNREFERENCED_PARAMETER(p); UNREFERENCED_PARAMETER(d); if (!(context->type & pprotect->type)) return TRUE; if (context->size < pprotect->path_size) { return TRUE; } //KLogEx(DEBUG_TRACE_INFO, "_FindPath Path(%S) Type(%d) Size(%d)\n", pprotect->protect_path, pprotect->ulType, pprotect->path_size); if (_wcsnicmp( context->path, pprotect->protect_path, pprotect->path_size / sizeof(wchar_t)) == 0) { return FALSE; } return TRUE; } static BOOLEAN NTAPI _SetFindPath(PLIST_ENTRY node, PVOID p, ULONG d) { PPROTECT_PATH pprotect = (PPROTECT_PATH)CONTAINING_RECORD(node, PROTECT_PATH, list); PWCHAR path = (PWCHAR)p; ULONG size = (ULONG)d; if (size != pprotect->path_size) { return TRUE; } if (_wcsnicmp(path, pprotect->protect_path, pprotect->path_size / sizeof(wchar_t)) == 0) { return FALSE; } return TRUE; } VOID SetProtectPathEx(PLIST_ENTRY pList, PKSPIN_LOCK pSpinLock, ULONG type, PWCHAR path, ULONG size) { PPROTECT_PATH pprotect = NULL; PLIST_ENTRY pLink = NULL; KIRQL oldIrql; if (!IsListEmpty(pList)) { KeAcquireSpinLock(pSpinLock, &oldIrql); pLink = WalkList(pList, _SetFindPath, (PVOID)path, size); if (pLink) { pprotect = CONTAINING_RECORD(pLink, PROTECT_PATH, list); pprotect->type = type; KeReleaseSpinLock(pSpinLock, oldIrql); KLogEx(DEBUG_TRACE_INFO, "Exist Path, ulType = %d, %S(%d)success\n", type, path, size); return; } KeReleaseSpinLock(pSpinLock, oldIrql); } pprotect = (PPROTECT_PATH)ExAllocatePoolWithTag(NonPagedPool, sizeof(PROTECT_PATH), PROTECT_PATH_POOLTAG); if (!pprotect) return; RtlZeroMemory(pprotect, sizeof(PROTECT_PATH)); pprotect->path_size = size; pprotect->type = type; wcsncpy(pprotect->protect_path, path, size); KeAcquireSpinLock(pSpinLock, &oldIrql); InsertTailList(pList, &pprotect->list); KeReleaseSpinLock(pSpinLock, oldIrql); } VOID SetProtectPath(ULONG type, PWCHAR path, ULONG size) { SetProtectPathEx(&s_protect_pathlist, &s_protect_spinlock, type, path, size); } VOID SetProcessProtectList(ULONG type, PWCHAR path, ULONG size) { SetProtectPathEx(&s_protectProcessList, &s_protectProcessSpinlock, type, path, size); } BOOLEAN DelTypePathlistEx(ULONG ulType, PLIST_ENTRY pList, PKSPIN_LOCK pSpinLock) { KIRQL irql; KeAcquireSpinLock(pSpinLock, &irql); (PLIST_ENTRY)WalkList(pList, _DelAllType, (PVOID)NULL, ulType); KeReleaseSpinLock(pSpinLock, irql); return TRUE; } VOID CleanupPathlistEx(PLIST_ENTRY pList, PKSPIN_LOCK pSpinLock) { PLIST_ENTRY l = NULL; PPROTECT_PATH pprotect = NULL; KIRQL oldIrql; KeAcquireSpinLock(pSpinLock, &oldIrql); while (!IsListEmpty(pList)) { l = RemoveHeadList(pList); pprotect = CONTAINING_RECORD(l, PROTECT_PATH, list); ExFreePoolWithTag(pprotect, PROTECT_PATH_POOLTAG); pprotect = NULL; } KeReleaseSpinLock(pSpinLock, oldIrql); KLogEx(DEBUG_TRACE_INFO, "success\n"); } VOID DelTypePathlist(ULONG ulType) { DelTypePathlistEx(ulType, &s_protect_pathlist, &s_protect_spinlock); } BOOLEAN DelPathlistEx(PLIST_ENTRY pList, PKSPIN_LOCK pSpinLock, ULONG ultype, PWCHAR path, ULONG size) { KIRQL irql; PPROTECT_PATH l = NULL; PLIST_ENTRY pLink = NULL; FIND_PATH_CONTEXT context = { 0, }; KeAcquireSpinLock(pSpinLock, &irql); if (path == NULL || size == 0) { // KLogEx("_DelAllType, type = %d success\n", ultype); (PLIST_ENTRY)WalkList(pList, _DelAllType, (PVOID)NULL, ultype); } else { context.path = path; context.size = size; context.type = ultype; pLink = (PLIST_ENTRY)WalkList(pList, _FindPath, (PVOID)&context, 0); if (pLink) { l = (PPROTECT_PATH)CONTAINING_RECORD(pLink, PROTECT_PATH, list); RemoveEntryList(&l->list); ExFreePoolWithTag(l, PROTECT_PATH_POOLTAG); //KLogEx("path = %S, size = %d success\n", path, size); } else { //KLogEx("no exist path = %S, size = %d\n", path, size); } } KeReleaseSpinLock(pSpinLock, irql); return TRUE; } VOID DelPathlist(ULONG type, PWCHAR path, ULONG size) { DelPathlistEx(&s_protect_pathlist, &s_protect_spinlock, type, path, size); } VOID DelProcessProtectList(ULONG type, PWCHAR path, ULONG size) { DelPathlistEx(&s_protectProcessList, &s_protectProcessSpinlock, type, path, size); } VOID CleanupPathlist() { CleanupPathlistEx(&s_protect_pathlist, &s_protect_spinlock); } VOID CleanupProcessProtectList() { CleanupPathlistEx(&s_protectProcessList, &s_protectProcessSpinlock); } ULONG IsProtectPathEx(PLIST_ENTRY pList, PKSPIN_LOCK pSpinLock, ULONG type, PWCHAR path, ULONG size) { PLIST_ENTRY pListEntry = NULL; FIND_PATH_CONTEXT context = { 0, }; PPROTECT_PATH pprotect = NULL; KIRQL oldIrql; ULONG ulRet = PG_PATH_UNDEFINED; UNREFERENCED_PARAMETER(size); if (IsListEmpty(pList)) { return PG_PATH_UNDEFINED; } KeAcquireSpinLock(pSpinLock, &oldIrql); context.path = path; context.size = size; context.type = type; pListEntry = (PLIST_ENTRY)WalkList(pList, _FindPath, (PVOID)&context, 0); if (pListEntry) { pprotect = CONTAINING_RECORD(pListEntry, PROTECT_PATH, list); ulRet = pprotect->type; } KeReleaseSpinLock(pSpinLock, oldIrql); return ulRet; } ULONG IsProtectPath(ULONG type, PWCHAR path, ULONG size) { ULONG state = 0; state = IsProtectPathEx(&s_protect_pathlist, &s_protect_spinlock, type, path, size); return state; } static BOOLEAN NTAPI _FindProcessProcess(PLIST_ENTRY node, PVOID p, ULONG d) { PPROTECT_PATH pprotect = (PPROTECT_PATH)CONTAINING_RECORD(node, PROTECT_PATH, list); PFIND_PATH_CONTEXT context = (PFIND_PATH_CONTEXT)p; UNREFERENCED_PARAMETER(p); UNREFERENCED_PARAMETER(d); /*KLogEx(DEBUG_TRACE_INFO, "Path(%S)(%S) Type(%d)(%d) Size(%d)(%d)\n", \ pprotect->protect_path, context->path, pprotect->ulType, context->type, pprotect->path_size, context->size);*/ if (!(context->type & pprotect->type)) return TRUE; if (context->size < pprotect->path_size) { return TRUE; } if (_wcsnicmp( context->path, pprotect->protect_path, pprotect->path_size / sizeof(wchar_t)) == 0) { return FALSE; } return TRUE; } ULONG IsProtectProcessEx(PLIST_ENTRY pList, PKSPIN_LOCK pSpinLock, ULONG type, PWCHAR path, ULONG size) { PLIST_ENTRY pListEntry = NULL; FIND_PATH_CONTEXT context = { 0, }; PPROTECT_PATH pprotect = NULL; KIRQL oldIrql; ULONG ulRet = PG_PATH_UNDEFINED; UNREFERENCED_PARAMETER(size); if (IsListEmpty(pList)) { return PG_PATH_UNDEFINED; } KeAcquireSpinLock(pSpinLock, &oldIrql); context.path = path; context.size = size; context.type = type; pListEntry = (PLIST_ENTRY)WalkList(pList, _FindProcessProcess, (PVOID)&context, 0); if (pListEntry) { pprotect = CONTAINING_RECORD(pListEntry, PROTECT_PATH, list); ulRet = pprotect->type; } KeReleaseSpinLock(pSpinLock, oldIrql); return ulRet; } ULONG IsProcessProtectList(ULONG type, PWCHAR path, ULONG size) { ULONG state = 0; state = IsProtectProcessEx(&s_protectProcessList, &s_protectProcessSpinlock, type, path, size); return state; } VOID SetFileName(ULONG type, PWCHAR name, ULONG size) { SetProtectPathEx(&s_allow_filelist, &s_allow_filelock, type, name, size); } ULONG IsFileName(ULONG type, PWCHAR path, ULONG size) { return IsProtectPathEx(&s_allow_filelist, &s_allow_filelock, type, path, size); } VOID CleanupFilelist() { CleanupPathlistEx(&s_allow_filelist, &s_allow_filelock); } BOOLEAN IsAllowProcessName(PWCHAR process_path, ULONG size, ULONG* type) { PLIST_ENTRY pListEntry = NULL; PALLOW_PROCESS pprocess = NULL; KIRQL oldIrql; ULONG len = 0; ULONG nlen = 0; wchar_t* name = NULL; wchar_t* rname = NULL; wchar_t* cname = NULL; BOOLEAN state = FALSE; UNREFERENCED_PARAMETER(size); if (IsListEmpty(&s_allow_processlist)) { return FALSE; } KeAcquireSpinLock(&s_allow_processlock, &oldIrql); /// ÇÁ·Î¼¼½º ¸í ºÐ¸® name = wcsrchr(process_path, '\\'); if (name) { ++name; nlen = (ULONG)(wcslen(name) * sizeof(WCHAR)); } else { name = process_path; nlen = size; } for (pListEntry = s_allow_processlist.Flink; pListEntry != &s_allow_processlist; pListEntry = pListEntry->Flink) { pprocess = NULL; pprocess = CONTAINING_RECORD(pListEntry, ALLOW_PROCESS, list); ///µî·ÏµÈ ÇÁ·Î¼¼½º°¡ ÇÁ·Î¼¼½º¸í¸¸ ÀÖ´Â °æ¿ì rname = wcsrchr(pprocess->process_path, '\\'); if (!rname) { cname = name; len = nlen; } else { cname = process_path; len = size; } // KLogEx(DEBUG_TRACE_INFO, "%S, %S, %d, %d\n", name, pprocess->process_manager.path, len, pprocess->process_manager.size/ sizeof(wchar_t)); if (len < pprocess->path_size) continue; if (_wcsnicmp(cname, pprocess->process_path, pprocess->path_size / sizeof(wchar_t)) == 0) { *type = pprocess->type; state = TRUE; KLogEx(DEBUG_TRACE_ERROR, "IsAllowProcessName, cname(%S),name(%S),ulType(%d)\n", cname, name, *type); break; } } KeReleaseSpinLock(&s_allow_processlock, oldIrql); return state; } BOOLEAN IsWritePermmision( __inout PFLT_CALLBACK_DATA Data, __in PCFLT_RELATED_OBJECTS FltObjects ) { ULONG desired_access = 0; ULONG create_option = 0; ULONG disposition = 0; UNREFERENCED_PARAMETER(Data); UNREFERENCED_PARAMETER(FltObjects); switch (Data->Iopb->MajorFunction) { case IRP_MJ_CREATE: { create_option = Data->Iopb->Parameters.Create.Options; desired_access = Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess; disposition = (create_option >> 24) & 0xFF; if (create_option & FILE_DIRECTORY_FILE) { return FALSE; } switch (disposition) { case FILE_CREATE: case FILE_OVERWRITE_IF: case FILE_SUPERSEDE: case FILE_OPEN_IF: case FILE_OVERWRITE: { if (desired_access & (FILE_WRITE_DATA)) { KLogEx(DEBUG_TRACE_ERROR, "block(1) disposition(%x), desired_access(%x)\n", disposition, desired_access); return TRUE; } // »èÁ¦ Â÷´Ü if (desired_access & (DELETE)) { KLogEx(DEBUG_TRACE_ERROR, "block(2) disposition(%x), desired_access(%x)\n", disposition, desired_access); return TRUE; } } break; default: return FALSE; } } break; case IRP_MJ_SET_INFORMATION: { FILE_INFORMATION_CLASS fileinfoclass = Data->Iopb->Parameters.SetFileInformation.FileInformationClass; if (fileinfoclass == FileDispositionInformation || fileinfoclass == FileRenameInformation) { KLogEx(DEBUG_TRACE_ERROR, "block(3) disposition(%x), desired_access(%x) fileinfoclass(%d)\n", disposition, desired_access, fileinfoclass); return TRUE; } } break; } return FALSE; } VOID CleanupRegKeylist() { PLIST_ENTRY pList = NULL; PPROTECT_REG reg = NULL; KIRQL oldIrql; ///»èÁ¦ ÆÄÀÏ ¸ñ·Ï ¸®½ºÆ® Á¦°Å KeAcquireSpinLock(&s_protect_reg_lock, &oldIrql); while (!IsListEmpty(&s_protect_reg_list)) { pList = RemoveHeadList(&s_protect_reg_list); reg = CONTAINING_RECORD(pList, PROTECT_REG, list); ExFreePoolWithTag(reg, PROTECT_REG_POOLTAG); } KeReleaseSpinLock(&s_protect_reg_lock, oldIrql); } VOID SetRegKeylist(PWCHAR regkey) { PPROTECT_REG reg = NULL; KIRQL oldIrql; reg = (PPROTECT_REG)ExAllocatePoolWithTag(NonPagedPool, sizeof(PROTECT_REG), PROTECT_REG_POOLTAG); if (!reg) return; RtlZeroMemory(reg, sizeof(PROTECT_REG)); //reg->reg_key_size = size; wcsncpy(reg->regkey, regkey, wcslen(regkey)); KeAcquireSpinLock(&s_protect_reg_lock, &oldIrql); InsertTailList(&s_protect_reg_list, ®->list); KeReleaseSpinLock(&s_protect_reg_lock, oldIrql); } static BOOLEAN NTAPI _FindRegKey(PLIST_ENTRY node, PVOID p, ULONG d) { PPROTECT_REG reg = (PPROTECT_REG)CONTAINING_RECORD(node, PROTECT_REG, list); WCHAR* reg_key = (WCHAR*)p; //ULONG size = (ULONG)d; UNREFERENCED_PARAMETER(p); UNREFERENCED_PARAMETER(d); /*if (reg->reg_key != size) return TRUE;*/ _wcsupr(reg_key); if (wcsstr(reg_key, reg->regkey) != 0) { return FALSE; } return TRUE; } BOOLEAN IsRegKey(PWCHAR regkey) { PLIST_ENTRY pList = NULL; KIRQL oldIrql; BOOLEAN state = FALSE; if (IsListEmpty(&s_protect_reg_list)) { return FALSE; } KeAcquireSpinLock(&s_protect_reg_lock, &oldIrql); pList = (PLIST_ENTRY)WalkList(&s_protect_reg_list, _FindRegKey, (PVOID)regkey,0); if (pList) { state = TRUE; } KeReleaseSpinLock(&s_protect_reg_lock, oldIrql); return state; } static BOOLEAN NTAPI _DelAllRegKey(PLIST_ENTRY node, PVOID p, ULONG d) { PPROTECT_REG reg = (PPROTECT_REG)CONTAINING_RECORD(node, PROTECT_REG, list); UNREFERENCED_PARAMETER(p); UNREFERENCED_PARAMETER(d); RemoveEntryList(®->list); ExFreePoolWithTag(reg, PROTECT_REG_POOLTAG); return TRUE; } VOID DelRegKeylist(PWCHAR regkey) { KIRQL irql; PPROTECT_REG l = NULL; PLIST_ENTRY pLink = NULL; KeAcquireSpinLock(&s_protect_reg_lock, &irql); if (regkey == NULL) { (PLIST_ENTRY)WalkList(&s_protect_reg_list, _DelAllRegKey, (PVOID)NULL, 0); KeReleaseSpinLock(&s_protect_reg_lock, irql); return; } pLink = (PLIST_ENTRY)WalkList(&s_protect_reg_list, _FindRegKey, (PVOID)regkey, 0); if (pLink) { l = (PPROTECT_REG)CONTAINING_RECORD(pLink, PROTECT_REG, list); RemoveEntryList(&l->list); ExFreePoolWithTag(l, PROTECT_PATH_POOLTAG); } else { } KeReleaseSpinLock(&s_protect_reg_lock, irql); return; } BOOLEAN IsDefalutLocalDiskExceptProcess(char* name) { static char* s_default_process[] = { "svchost.exe", "WerFault.exe", "csrss.exe", "winlogon.exe", "lsass.exe", "services.exe", "lsm.exe", "dwm.exe", "audiodg.exe", "SearchIndexer.exe", //"dllhost.exe", "dwwin.exe", "vmtoolsd.exe", NULL }; //int i = 0; LPCSTR* ep = s_default_process; while (*ep) { if (_strnicmp(name, *ep, strlen(name)) == 0) return TRUE; ++ep; } return FALSE; } BOOLEAN IsDefalutExternalDiskExceptProcess(char* name) { static char* s_default_process[] = { "svchost.exe", "WerFault.exe", "csrss.exe", "winlogon.exe", "lsass.exe", "services.exe", "lsm.exe", "dwm.exe", "audiodg.exe", "SearchIndexer.exe", "dwwin.exe", NULL }; //int i = 0; LPCSTR* ep = s_default_process; while (*ep) { if (_strnicmp(name, *ep, strlen(name)) == 0) return TRUE; ++ep; } return FALSE; } BOOLEAN IsDefalutExceptRegProcess(char* name) { static char* s_default_reg_process[] = { "RegWorkshopX64.exe", "RegWorkshop.exe", "RegScanner.exe", "regedit.exe", NULL }; //int i = 0; LPCSTR* ep = s_default_reg_process; while (*ep) { if (_strnicmp(name, *ep, strlen(name)) == 0) return TRUE; ++ep; } return FALSE; } BOOLEAN GetHostAndIp(PWCHAR pwszPath, PWCHAR pwszRet) { PWCHAR pwszTemp = NULL; WCHAR wszPath[260] = { 0, }; RtlStringCchPrintfW(wszPath, 260, L"%s", pwszPath); _wcslwr(wszPath); pwszTemp = wcsstr(wszPath, L"\\lanmanredirector\\"); if (pwszTemp) { pwszTemp = pwszTemp + 18; ISWcstok(pwszTemp, pwszRet, (ULONG)wcslen(pwszTemp), L'\\', TRUE); return TRUE; } pwszTemp = wcsstr(wszPath, L"\\;lanmanredirector\\"); if (pwszTemp) { pwszTemp = pwszTemp + 19; ISWcstok(pwszTemp, pwszRet, (ULONG)wcslen(pwszTemp), L'\\', TRUE); return TRUE; } pwszTemp = wcsstr(wszPath, L"\\device\\mup\\"); if (pwszTemp) { pwszTemp = pwszTemp + 12; ISWcstok(pwszTemp, pwszRet, (ULONG)wcslen(pwszTemp), L'\\', FALSE); return TRUE; } pwszTemp = wcsstr(wszPath, L"\\\\"); if (pwszTemp) { pwszTemp = pwszTemp + 2; ISWcstok(pwszTemp, pwszRet, (ULONG)wcslen(pwszTemp), L'\\', FALSE); return TRUE; } return FALSE; } static BOOLEAN NTAPI _FindHostAddress(PLIST_ENTRY node, PVOID p, ULONG d) { PHOST_ADDRESS host = (PHOST_ADDRESS)CONTAINING_RECORD(node, HOST_ADDRESS, list); WCHAR* pwHost = (WCHAR*)p; ULONG ulLen = (ULONG)d; if (host->host_address_manager.ulLen > ulLen) return TRUE; if (_wcsnicmp(pwHost, host->host_address_manager.wszHost, host->host_address_manager.ulLen) == 0) { return FALSE; } return TRUE; } static BOOLEAN NTAPI _FindIPAddress(PLIST_ENTRY node, PVOID s, ULONG e) { PIP_ADDRESS ipaddress = (PIP_ADDRESS)CONTAINING_RECORD(node, IP_ADDRESS, list); ULONG ulStartIP = (ULONG)(ULONG_PTR)s; ULONG ulEndIP = e; if (ulEndIP != 0) { if (ipaddress->ipaddress_manager.ulStartIP == ulStartIP && ipaddress->ipaddress_manager.ulEndIP == ulEndIP) { return FALSE; } else { return TRUE; } } else if (ipaddress->ipaddress_manager.ulEndIP != 0) { if (ipaddress->ipaddress_manager.ulStartIP <= ulStartIP && ipaddress->ipaddress_manager.ulEndIP >= ulStartIP) { return FALSE; } else { return TRUE; } } else if (ipaddress->ipaddress_manager.ulStartIP == ulStartIP) { return FALSE; } return TRUE; } BOOLEAN IsAllowHostIp(PWCHAR pwszPath, ULONG ulLen) { PLIST_ENTRY pListEntry = NULL; WCHAR wszBuf[260] = { 0, }; ULONG ulIPAddress = 0; ULONG ulStringSize = 0; BOOLEAN bReturn = FALSE; KIRQL oldIrql; if (ulLen == 0) { return bReturn; } if (!GetHostAndIp(pwszPath, wszBuf)) { return bReturn; } if (wszBuf[0] == L'\0') { return bReturn; } KLogEx(DEBUG_TRACE_INFO, "wszBuf(%S)\n", wszBuf); ulStringSize = (ULONG)wcslen(wszBuf); if (!ISIPAddress(wszBuf, ulStringSize)) { KLogEx(DEBUG_TRACE_INFO, "Host In.\n"); // Host È£Ãâ. KeAcquireSpinLock(&s_hostaddresslock, &oldIrql); pListEntry = (PLIST_ENTRY)WalkList(&s_hostaddresslist, _FindHostAddress, wszBuf, ulStringSize); if (pListEntry) { bReturn = TRUE; } KeReleaseSpinLock(&s_hostaddresslock, oldIrql); } else { KLogEx(DEBUG_TRACE_INFO, "IP In.\n"); // IP È£Ãâ. ISIPAddressToInt(wszBuf, ulStringSize, &ulIPAddress); KeAcquireSpinLock(&s_ipaddresslock, &oldIrql); pListEntry = (PLIST_ENTRY)WalkList(&s_ipaddresslist, _FindIPAddress, (PVOID)ulIPAddress, 0); if (pListEntry) { bReturn = TRUE; } KeReleaseSpinLock(&s_ipaddresslock, oldIrql); } return bReturn; } //////////// USB µå¶óÀÌºê ¿¹¿Ü ¸®½ºÆ® Á¤¸® void SetUsbDiskException(PCHAR vid, PCHAR pid, PCHAR productrevisionlevel, PCHAR vendorspecific) { PBS1FLT_USB_DISK_EXCEPT_LIST ue = NULL; KIRQL oldIrql; ue = (PBS1FLT_USB_DISK_EXCEPT_LIST)ExAllocatePoolWithTag(NonPagedPool, sizeof(BS1FLT_USB_DISK_EXCEPT_LIST), USB_EXCEPTION_POOLTAG); if (!ue) return; RtlZeroMemory(ue, sizeof(BS1FLT_USB_DISK_EXCEPT_LIST)); strcpy_s(ue->ue.vendorid, sizeof(ue->ue.vendorid), vid); strcpy_s(ue->ue.productid, sizeof(ue->ue.productid), pid); strcpy_s(ue->ue.productrevisionlevel, sizeof(ue->ue.productrevisionlevel), productrevisionlevel); strcpy_s(ue->ue.vendorspecific, sizeof(ue->ue.vendorspecific), vendorspecific); KeAcquireSpinLock(&s_usb_disk_except_lock, &oldIrql); InsertTailList(&s_usb_disk_except_list, &ue->list); ++s_usb_disk_except_list_count; KeReleaseSpinLock(&s_usb_disk_except_lock, oldIrql); KLogEx(DEBUG_TRACE_INFO, "success\n"); } VOID CleanupUsbDiskExceptionList() { PLIST_ENTRY pList = NULL; PBS1FLT_USB_DISK_EXCEPT_LIST ue = NULL; KIRQL oldIrql; KeAcquireSpinLock(&s_usb_disk_except_lock, &oldIrql); while (!IsListEmpty(&s_usb_disk_except_list)) { pList = RemoveHeadList(&s_usb_disk_except_list); ue = (PBS1FLT_USB_DISK_EXCEPT_LIST)CONTAINING_RECORD(pList, BS1FLT_USB_DISK_EXCEPT_LIST, list); ExFreePoolWithTag(ue, USB_EXCEPTION_POOLTAG); ue = NULL; } s_usb_disk_except_list_count = 0; KeReleaseSpinLock(&s_usb_disk_except_lock, oldIrql); KLogEx(DEBUG_TRACE_INFO, "success\n"); } static BOOLEAN NTAPI _FindUsbDisk(PLIST_ENTRY node, PVOID p, ULONG d) { PBS1FLT_USB_DISK_EXCEPT_LIST usbContext = (PBS1FLT_USB_DISK_EXCEPT_LIST)CONTAINING_RECORD(node, BS1FLT_USB_DISK_EXCEPT_LIST, list); PFIND_USBDISK_CONTEXT cur = (PFIND_USBDISK_CONTEXT)p; BOOLEAN state = FALSE; UNREFERENCED_PARAMETER(p); UNREFERENCED_PARAMETER(d); if (!cur || !usbContext) return TRUE; //KLogEx(DEBUG_TRACE_INFO, "vendor(%s)(%d)(%s)(%d), product(%s)(%d)(%s)(%d), vendorspecific(%s)(%d)(%s)(%d)\n", // cur->vendor, strlen(cur->vendor), usbContext->ue.vendorid, strlen(usbContext->ue.vendorid), // cur->product, strlen(cur->product), usbContext->ue.productid, strlen(usbContext->ue.productid), // cur->seiral, strlen(cur->seiral), usbContext->ue.vendorspecific, strlen(usbContext->ue.vendorspecific) //); if (cur->vendor && usbContext->ue.vendorid[0] != '\0') { if (_strnicmp((char*)cur->vendor, usbContext->ue.vendorid, strlen(usbContext->ue.vendorid)) != 0) { //KLogEx(DEBUG_TRACE_INFO, "vendor not match\n"); return TRUE; } } if (cur->product && usbContext->ue.productid[0] != '\0') { if (_strnicmp((char*)cur->product, usbContext->ue.productid, strlen(usbContext->ue.productid)) != 0) { //KLogEx(DEBUG_TRACE_INFO, "product not match\n"); return TRUE; } } if (cur->seiral && cur->seiral[0] != '\0') { if (_strnicmp((char*)cur->seiral, usbContext->ue.vendorspecific, strlen(usbContext->ue.vendorspecific)) == 0) { //KLogEx(DEBUG_TRACE_INFO, "seiral not match\n"); state = FALSE; // ¸ðµÎ ÀÏÄ¡ÇÔ } } else { state = FALSE; } //__try //{ // KLogEx(DEBUG_TRACE_INFO, "vendor(%s)(%s), product(%s)(%s), vendorspecific(%s)(%s)\n", // cur->vendor, usbContext->ue.vendorid, // cur->product, usbContext->ue.productid, // cur->seiral, usbContext->ue.vendorspecific // ); // if (strstr((char*)cur->vendor, usbContext->ue.vendorid) != NULL && strstr((char*)cur->product, usbContext->ue.productid) != NULL) // { // if (cur->seiral != NULL && cur->seiral[0] != '\0') // { // if (strstr((char*)cur->seiral, usbContext->ue.vendorspecific) != NULL) // state = TRUE; // else // state = FALSE; // } // else // state = TRUE; // } //} //__except (EXCEPTION_EXECUTE_HANDLER) //{ //} return state; } ULONG IsUsbDiskExceptionList(PCHAR vid, PCHAR pid, PCHAR productrevisionlevel, PCHAR vendorspecific) { FIND_USBDISK_CONTEXT context = { 0, }; KIRQL oldIrql; ULONG state = 0; PLIST_ENTRY pLink = NULL; UNREFERENCED_PARAMETER(vid); UNREFERENCED_PARAMETER(pid); UNREFERENCED_PARAMETER(productrevisionlevel); UNREFERENCED_PARAMETER(vendorspecific); KeAcquireSpinLock(&s_usb_disk_except_lock, &oldIrql); if (s_usb_disk_except_list_count == 0 ) { KeReleaseSpinLock(&s_usb_disk_except_lock, oldIrql); return state; } if (vid) context.vendor = vid; if(pid) context.product = pid; if(productrevisionlevel) context.productrevisionlevel = productrevisionlevel; if(vendorspecific) context.seiral = vendorspecific; pLink = (PLIST_ENTRY)WalkList(&s_usb_disk_except_list, _FindUsbDisk, (PVOID)&context, 0); if (pLink) { state = 1; } else { if (s_usb_disk_except_list_count) state = 2; } KeReleaseSpinLock(&s_usb_disk_except_lock, oldIrql); return state; } BOOLEAN DelUsbDiskExceptionList(PCHAR vid, PCHAR pid, PCHAR productrevisionlevel, PCHAR vendorspecific) { KIRQL irql; PLIST_ENTRY pLink = NULL; PBS1FLT_USB_DISK_EXCEPT_LIST l = NULL; FIND_USBDISK_CONTEXT context = { 0, }; BOOLEAN state = FALSE; if (!vid || !pid) { KLogEx(DEBUG_TRACE_ERROR, "Invalid Parameter: vid or pid is NULL\n"); return FALSE; } KeAcquireSpinLock(&s_usb_disk_except_lock, &irql); context.vendor = vid; context.product = pid; if (productrevisionlevel) context.productrevisionlevel = productrevisionlevel; context.seiral = vendorspecific; pLink = (PLIST_ENTRY)WalkList(&s_usb_disk_except_list, _FindUsbDisk, (PVOID)&context, 0); if (pLink) { l = (PBS1FLT_USB_DISK_EXCEPT_LIST)CONTAINING_RECORD(pLink, BS1FLT_USB_DISK_EXCEPT_LIST, list); RemoveEntryList(&l->list); ExFreePoolWithTag(l, USB_EXCEPTION_POOLTAG); state = TRUE; --s_usb_disk_except_list_count; } KeReleaseSpinLock(&s_usb_disk_except_lock, irql); KLogEx(DEBUG_TRACE_INFO, "success(%d)\n", state); return TRUE; } ////////////////////////////////////////////////////////// //////////// USB Æ÷Æ® ¿¹¿Ü ¸®½ºÆ® Á¤¸® void SetUsbPortException(ULONG devicetype, ULONG vendorid, ULONG productid, ULONG bcddevice, wchar_t * serial) { PBS1FLT_USB_PORT_EXCEPT_LIST p = NULL; KIRQL oldIrql; p = (PBS1FLT_USB_PORT_EXCEPT_LIST)ExAllocatePoolWithTag(NonPagedPool, sizeof(BS1FLT_USB_PORT_EXCEPT_LIST), USB_EXCEPTION_POOLTAG); if (!p) return; RtlZeroMemory(p, sizeof(BS1FLT_USB_PORT_EXCEPT_LIST)); p->upe.productid = productid; p->upe.vendorid = vendorid; p->upe.devicetype = devicetype; p->upe.bcddevice = bcddevice; wcscpy(p->upe.serial, serial); KeAcquireSpinLock(&s_usb_port_except_lock, &oldIrql); InsertTailList(&s_usb_port_except_list, &p->list); KeReleaseSpinLock(&s_usb_port_except_lock, oldIrql); KLogEx(DEBUG_TRACE_INFO, "success\n"); } static BOOLEAN NTAPI _FindUsbPort(PLIST_ENTRY node, PVOID p, ULONG d) { PBS1FLT_USB_PORT_EXCEPT_LIST usbContext = (PBS1FLT_USB_PORT_EXCEPT_LIST)CONTAINING_RECORD(node, BS1FLT_USB_PORT_EXCEPT_LIST, list); PFIND_USB_CONTEXT cur = (PFIND_USB_CONTEXT)p; UNREFERENCED_PARAMETER(p); UNREFERENCED_PARAMETER(d); if (usbContext->upe.devicetype != cur->devicetype) return TRUE; KLogEx(DEBUG_TRACE_INFO, "(%x)(%x), (%x)(%x), (%S)(%S)\n", usbContext->upe.vendorid, cur->vendor, usbContext->upe.productid, cur->product, usbContext->upe.serial, cur->seiral ); if (usbContext->upe.vendorid == cur->vendor && usbContext->upe.productid == cur->product) { if (_wcsnicmp(usbContext->upe.serial, cur->seiral, wcslen(cur->seiral)) == 0) return FALSE; } return TRUE; } BOOLEAN DelUsbPortExceptionList(ULONG devicetype, ULONG vendor, ULONG product, ULONG bcddevice, PWCHAR seiral) { KIRQL irql; PBS1FLT_USB_PORT_EXCEPT_LIST l = NULL; PLIST_ENTRY pLink = NULL; FIND_USB_CONTEXT context = { 0, }; UNREFERENCED_PARAMETER(bcddevice); KeAcquireSpinLock(&s_usb_port_except_lock, &irql); context.devicetype = devicetype; context.vendor = vendor; context.product = product; context.seiral = seiral; pLink = (PLIST_ENTRY)WalkList(&s_usb_port_except_list, _FindUsbPort, (PVOID)&context, 0); if (pLink) { l = (PBS1FLT_USB_PORT_EXCEPT_LIST)CONTAINING_RECORD(pLink, BS1FLT_USB_PORT_EXCEPT_LIST, list); RemoveEntryList(&l->list); ExFreePoolWithTag(l, USB_EXCEPTION_POOLTAG); } KeReleaseSpinLock(&s_usb_port_except_lock, irql); KLogEx(DEBUG_TRACE_INFO, "success\n"); return TRUE; } BOOLEAN IsUsbPortExceptionList(ULONG devicetype, ULONG vendorid, ULONG productid, ULONG bcddevice, PWCHAR serial) { //PLIST_ENTRY current, tail, tmp; //PBS1FLT_USB_PORT_EXCEPT_LIST ue = NULL; KIRQL oldIrql; BOOLEAN state = FALSE; PLIST_ENTRY pLink = NULL; FIND_USB_CONTEXT context = { 0, }; UNREFERENCED_PARAMETER(bcddevice); KeAcquireSpinLock(&s_usb_port_except_lock, &oldIrql); context.devicetype = devicetype; context.vendor = vendorid; context.product = productid; context.seiral = serial; pLink = (PLIST_ENTRY)WalkList(&s_usb_port_except_list, _FindUsbPort, (PVOID)&context, 0); if (pLink) state = TRUE; KeReleaseSpinLock(&s_usb_port_except_lock, oldIrql); return state; } VOID CleanupUsbPortExceptionList() { PLIST_ENTRY pList = NULL; PBS1FLT_USB_PORT_EXCEPT_LIST upe = NULL; KIRQL oldIrql; KeAcquireSpinLock(&s_usb_port_except_lock, &oldIrql); while (!IsListEmpty(&s_usb_port_except_list)) { pList = RemoveHeadList(&s_usb_port_except_list); upe = (PBS1FLT_USB_PORT_EXCEPT_LIST)CONTAINING_RECORD(pList, BS1FLT_USB_PORT_EXCEPT_LIST, list); ExFreePoolWithTag(upe, USB_EXCEPTION_POOLTAG); upe = NULL; } KeReleaseSpinLock(&s_usb_port_except_lock, oldIrql); KLogEx(DEBUG_TRACE_INFO, "success\n"); } //////////////////////////////////////////////////////////////