BSOne.SFC/Tocsg.Module/Bs1Flt/bs1flt/bs1flt_lst.c

1511 lines
35 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 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, &reg->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(&reg->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");
}
//////////////////////////////////////////////////////////////