1494 lines
34 KiB
C
1494 lines
34 KiB
C
#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 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(ue->ue.vendorid, vid);
|
|
strcpy(ue->ue.productid, pid);
|
|
strcpy(ue->ue.productrevisionlevel, productrevisionlevel);
|
|
strcpy(ue->ue.vendorspecific, vendorspecific);
|
|
|
|
KeAcquireSpinLock(&s_usb_disk_except_lock, &oldIrql);
|
|
InsertTailList(&s_usb_disk_except_list, &ue->list);
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
BOOLEAN IsUsbDiskExceptionList(PCHAR vid, PCHAR pid, PCHAR productrevisionlevel, PCHAR vendorspecific)
|
|
{
|
|
FIND_USBDISK_CONTEXT context = { 0, };
|
|
KIRQL oldIrql;
|
|
BOOLEAN state = FALSE;
|
|
PLIST_ENTRY pLink = NULL;
|
|
|
|
UNREFERENCED_PARAMETER(vid);
|
|
UNREFERENCED_PARAMETER(pid);
|
|
UNREFERENCED_PARAMETER(productrevisionlevel);
|
|
UNREFERENCED_PARAMETER(vendorspecific);
|
|
|
|
KeAcquireSpinLock(&s_usb_disk_except_lock, &oldIrql);
|
|
|
|
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 = TRUE;
|
|
|
|
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;
|
|
}
|
|
|
|
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");
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////
|