798 lines
18 KiB
C
798 lines
18 KiB
C
#include "precomp.h"
|
|
|
|
|
|
static PROCESS_MANAGER s_exceopionprocess[] =
|
|
{
|
|
{PG_PID_ALLOW, L"vmtoolsd.exe",12},
|
|
{PG_PID_ALLOW, L"lsass.exe", 9},
|
|
};
|
|
|
|
static PROCESS_MANAGER s_Filesystem_exceopionprocess[] =
|
|
{
|
|
{PG_PID_ALLOW, L"SearchIndexer.exe",17},
|
|
{PG_PID_ALLOW, L"svchost.exe", 11},
|
|
{PG_PID_ALLOW, L"WUDFHost.exe", 12},
|
|
{PG_PID_ALLOW, L"system", 6}
|
|
};
|
|
|
|
|
|
typedef struct _LOG_LIST
|
|
{
|
|
REPORT_DESC a;
|
|
LIST_ENTRY list;
|
|
|
|
}LOG_LIST, * PLOG_LIST;
|
|
|
|
|
|
|
|
static LIST_ENTRY s_log_list;
|
|
static KSPIN_LOCK s_log_list_lock;
|
|
static ULONG s_log_cnt;
|
|
static NPAGED_LOOKASIDE_LIST s_log_PoolList;
|
|
|
|
|
|
#define LOG_POOL_TAG 'kdrp'
|
|
|
|
#define REPORT_KERNEL_EVENT_NAME L"\\BaseNamedObjects\\" LOG_SHARE_EVENT
|
|
|
|
PKEVENT rptEvent = NULL;
|
|
HANDLE rptEventHandle;
|
|
|
|
|
|
void RptNotifyEvent()
|
|
{
|
|
//HANDLE rptEventHandle;
|
|
//PKEVENT rptEvent;
|
|
UNICODE_STRING name;
|
|
|
|
if (InterlockedCompareExchange((volatile LONG*) & s_log_cnt, 0, 0) == 0)
|
|
return;
|
|
|
|
RtlInitUnicodeString(&name, REPORT_KERNEL_EVENT_NAME);
|
|
rptEvent = IoCreateNotificationEvent(&name, &rptEventHandle);
|
|
//iLog("!!!RptNotifyEvent %08p %08p\n", rptEvent, rptEventHandle);
|
|
|
|
if (rptEvent)
|
|
{
|
|
KeSetEvent(rptEvent, FALSE, FALSE);
|
|
ZwClose(rptEventHandle);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
VOID Initlog()
|
|
{
|
|
s_log_cnt = 0;
|
|
InitializeListHead(&s_log_list);
|
|
KeInitializeSpinLock(&s_log_list_lock);
|
|
ExInitializeNPagedLookasideList(&s_log_PoolList
|
|
, NULL
|
|
, NULL
|
|
, 0
|
|
, sizeof(LOG_LIST)
|
|
, LOG_POOL_TAG
|
|
, 0);
|
|
|
|
}
|
|
|
|
|
|
BOOLEAN IsNetWorkExceptionPath(LPWSTR path)
|
|
{
|
|
static LPCWSTR s_expath[] =
|
|
{
|
|
L"\\PIPE\\srvsvc",
|
|
L"\\;Csc\\.\\.\\",
|
|
L"\\pipe\\",
|
|
L"\\desktop.ini",
|
|
/// 네트워크 드라이브 사용 etc. \Device\Mup\;LanmanRedirector\;Z:00000000001cdd14\KMG-PC\share\allowpl - 복사본 (2).ini
|
|
/// L"\\;LanmanRedirector\\",
|
|
/// L"\\;lanmanredirector\\",
|
|
L"*\\mailslot\\",
|
|
L";RdpDr\\;",
|
|
L"\\pipe\\spoolss",
|
|
/// sqlite 같은 경우 씀
|
|
L"\\Device\\Mup\\localhost\\",
|
|
NULL
|
|
};
|
|
|
|
/// 20160627 kmg
|
|
/// hwp 의 경우 루트 경로 없이 \\Device\\Mup\\\\로만 접근 시도
|
|
/// s_expathlen를 기준으로 경로 길이 까지 볼 경우 추가
|
|
//static LPCWSTR s_expathlen[] =
|
|
//{
|
|
// L"\\Device\\Mup\\\\",
|
|
// NULL
|
|
//};
|
|
|
|
LPCWSTR* ep = s_expath;
|
|
while (*ep)
|
|
{
|
|
if (wcsstr(path, *ep) != NULL)
|
|
return TRUE;
|
|
|
|
++ep;
|
|
}
|
|
|
|
|
|
|
|
//ep = s_expathlen;
|
|
//while (*ep)
|
|
//{
|
|
// if (_wcsnicmp(*ep, path, wcslen(path)) == 0)
|
|
// return TRUE;
|
|
|
|
// ++ep;
|
|
//}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOLEAN IsFileSystemExceptionPath(LPWSTR path)
|
|
{
|
|
static LPCWSTR s_expath[] =
|
|
{
|
|
L"\\desktop.ini",
|
|
NULL
|
|
};
|
|
|
|
LPCWSTR* ep = s_expath;
|
|
while (*ep)
|
|
{
|
|
if (wcsstr(path, *ep) != NULL)
|
|
return TRUE;
|
|
|
|
++ep;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOLEAN CreateOptionDebug(PFLT_CALLBACK_DATA data, PREPORT_DESC log)
|
|
{
|
|
ULONG disposition;
|
|
ULONG desired_access = 0;
|
|
ULONG create_option = 0;
|
|
USHORT create_fileattribute = 0;
|
|
//USHORT share_access = 0;
|
|
//ULONG devicetype = 0;
|
|
|
|
if (data == NULL)
|
|
return FALSE;
|
|
|
|
if (data->Iopb->MajorFunction != IRP_MJ_CREATE)
|
|
return FALSE;
|
|
|
|
desired_access = data->Iopb->Parameters.Create.SecurityContext->DesiredAccess;
|
|
create_option = data->Iopb->Parameters.Create.Options;
|
|
disposition = (create_option >> 24) & 0xFF;
|
|
create_fileattribute = data->Iopb->Parameters.Create.FileAttributes;
|
|
|
|
KLogEx(DEBUG_TRACE_ERROR, "desired_access(%x) create_option(%x) disposition(%x) create_fileattribute(%x) \n", desired_access, create_option, disposition, create_fileattribute);
|
|
//KLogEx(DEBUG_TRACE_ERROR, "FileName.Length(%x) Data->Iopb->OperationFlags(%x) TargetFileObject->Flags(%x)\n", fltobject->FileObject->FileName.Length, data->Iopb->OperationFlags, data->Iopb->TargetFileObject->Flags);
|
|
KLogEx(DEBUG_TRACE_ERROR, "Path(%S) ProcessName(%S\n", log->path, log->ProcessName);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
///차단 메시지 & 로그 예외
|
|
BOOLEAN IsException(PFLT_CALLBACK_DATA data, PREPORT_DESC log)
|
|
{
|
|
/// 불필요한 로그 필터링
|
|
ULONG desired_access = 0;
|
|
ULONG create_option = 0;
|
|
ULONG fileattributes = 0;
|
|
ULONG disposition = 0;
|
|
|
|
if (log->a0 == BDC_NETWORKDRIVEOUT || log->a0 == BDC_NETWORKSHAREOUT)
|
|
{
|
|
if (IsExceptionProcess(s_Filesystem_exceopionprocess, ARRAYSIZE(s_Filesystem_exceopionprocess), log->ProcessName) == PG_PID_ALLOW)
|
|
return TRUE;
|
|
|
|
/// 예외 경로 필터
|
|
if (IsNetWorkExceptionPath(log->path))
|
|
return TRUE;
|
|
|
|
/*if (data && data->Iopb->MajorFunction == IRP_MJ_CREATE)
|
|
{
|
|
create_option = data->Iopb->Parameters.Create.Options;
|
|
disposition = (create_option >> 24) & 0xFF;
|
|
desired_access = data->Iopb->Parameters.Create.SecurityContext->DesiredAccess;
|
|
|
|
KLogEx(DEBUG_TRACE_ERROR, "Network log->a1(%d) disposition(%x) desired_access(%x)\n", log->a1, disposition, desired_access);
|
|
|
|
if (log->a1 == DISABLE)
|
|
{
|
|
if (disposition == FILE_OPEN)
|
|
{
|
|
if (!(desired_access & (FILE_READ_DATA)))
|
|
return TRUE;
|
|
}
|
|
}
|
|
else if (log->a1 == READONLY)
|
|
{
|
|
///20160622 kmg
|
|
///FILE_OPEN 의 경우 클릭 시 explorer, office 문서 열떄 들어오므로 차단및 로그 예외.
|
|
if (disposition == FILE_OPEN)
|
|
{
|
|
if (!(desired_access & (FILE_READ_DATA)))
|
|
return TRUE;
|
|
}
|
|
}
|
|
}*/
|
|
}
|
|
else if (log->a0 == BDC_USB_DISK || log->a0 == BDC_EXTERNALHDD)
|
|
{
|
|
if (IsFileSystemExceptionPath(log->path))
|
|
return TRUE;
|
|
|
|
if (IsExceptionProcess(s_Filesystem_exceopionprocess, ARRAYSIZE(s_Filesystem_exceopionprocess), log->ProcessName) == PG_PID_ALLOW)
|
|
return TRUE;
|
|
|
|
if (data && data->Iopb->MajorFunction == IRP_MJ_CREATE)
|
|
{
|
|
desired_access = data->Iopb->Parameters.Create.SecurityContext->DesiredAccess;
|
|
create_option = data->Iopb->Parameters.Create.Options;
|
|
fileattributes = data->Iopb->Parameters.Create.FileAttributes;
|
|
disposition = (create_option >> 24) & 0xFF;
|
|
|
|
KLogEx(DEBUG_TRACE_ERROR, "desired_access(%x) create_option(%x) fileattributes(%x)\n", desired_access, create_option, fileattributes);
|
|
|
|
if (log->a1 == READONLY)
|
|
{
|
|
///20160622 kmg
|
|
///FILE_OPEN 의 경우 클릭 시 explorer, office 문서 열떄 들어오므로 차단및 로그 예외
|
|
if (disposition == FILE_OPEN)
|
|
{
|
|
if (desired_access & (FILE_WRITE_DATA))
|
|
return TRUE;
|
|
}
|
|
}
|
|
else if (!(create_option & 0x1004020))
|
|
return TRUE;
|
|
}
|
|
}
|
|
else if (log->a0 == BDC_CDROM)
|
|
{
|
|
if (data && data->Iopb->MajorFunction == IRP_MJ_CREATE)
|
|
{
|
|
if (wcsrchr(log->path, '\\') == NULL)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
// if((create_option & FILE_NON_DIRECTORY_FILE))
|
|
// return TRUE;
|
|
}
|
|
}
|
|
|
|
///모든 정책에서 예외 프로세스 목록
|
|
if (IsExceptionProcess(s_exceopionprocess, ARRAYSIZE(s_exceopionprocess), log->ProcessName) == PG_PID_ALLOW)
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
///시간 주기로 중복 로그 예외
|
|
BOOLEAN IsOvlappedLog(PFLT_CALLBACK_DATA data, PREPORT_DESC log)
|
|
{
|
|
//static LARGE_INTEGER s_distime = { 0, };
|
|
static LARGE_INTEGER s_LastTick = { 0 };
|
|
static REPORT_DESC s_overlap_log[BDC_MAX_DEVICE_TYPE] = { 0, };
|
|
LARGE_INTEGER CurrentTick;
|
|
ULONG TimeIncrement;
|
|
|
|
ULONG idx = log->a0;
|
|
|
|
UNREFERENCED_PARAMETER(data);
|
|
|
|
if (idx >= BDC_MAX_DEVICE_TYPE)
|
|
return FALSE;
|
|
|
|
///최초 시간 구함
|
|
KeQueryTickCount(&CurrentTick);
|
|
|
|
// 2. 시간 주기 체크 (2초 경과 여부)
|
|
// Tick 단위로 계산하는 것이 훨씬 가볍고 빠름
|
|
TimeIncrement = KeQueryTimeIncrement(); // 1 Tick당 시간(100ns 단위) 반환
|
|
|
|
// 최초 실행이거나 2초(2 * 10,000,000 * 100ns) 지났는지 확인
|
|
// 간단하게 Tick Count 차이로 계산
|
|
if (s_LastTick.QuadPart == 0 ||
|
|
(CurrentTick.QuadPart - s_LastTick.QuadPart) * TimeIncrement > 20000000)
|
|
{
|
|
// 2초 경과 -> 캐시 초기화
|
|
RtlZeroMemory(s_overlap_log, sizeof(s_overlap_log));
|
|
s_LastTick.QuadPart = CurrentTick.QuadPart;
|
|
}
|
|
|
|
//if (s_distime.LowPart == 0)
|
|
//{
|
|
// KeQuerySystemTime((PLARGE_INTEGER)&s_distime);
|
|
//}
|
|
//else
|
|
//{
|
|
// LONGLONG delay;
|
|
// KeQuerySystemTime((PLARGE_INTEGER)&c);
|
|
// if (c.QuadPart >= s_distime.QuadPart)
|
|
// {
|
|
// delay = c.QuadPart - s_distime.QuadPart;
|
|
// }
|
|
// else
|
|
// {
|
|
// delay = s_distime.QuadPart;
|
|
// delay += (0xFFFFFFFFFFFFFFFF - c.QuadPart);
|
|
// }
|
|
|
|
// /// 2초이상이면 중복로그 버퍼 초기화. 중복로그 예외로 인해 새로운 로그가 안올라오는 현상 방지
|
|
// if (delay > (LONGLONG)(2 * 10000 * 1000))
|
|
// {
|
|
// KLogEx(DEBUG_TRACE_INFO, "delay(%llx), time(%llx) -> (%llx)\n", delay, c.QuadPart, s_distime.QuadPart);
|
|
// memset(&s_overlapp_log, 0, sizeof(s_overlapp_log));
|
|
// memset(&s_distime, 0, sizeof(LARGE_INTEGER));
|
|
// }
|
|
//}
|
|
|
|
|
|
/// 중복 로그 필터링
|
|
if (s_overlap_log[log->a0].path[0] != 0)
|
|
{
|
|
KLogEx(DEBUG_TRACE_INFO, "ov (%S), (%S)\n", s_overlap_log[log->a0].path, log->path);
|
|
if (_wcsicmp(s_overlap_log[log->a0].path, log->path) == 0 && _wcsicmp(s_overlap_log[log->a0].ProcessName, log->ProcessName) == 0)
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
else if (log->a0 == BDC_CDROM)
|
|
{
|
|
if (_wcsicmp(s_overlap_log[log->a0].ProcessName, log->ProcessName) == 0 && s_overlap_log[log->a0].a1 == log->a1)
|
|
return TRUE;
|
|
}
|
|
|
|
memcpy(&s_overlap_log[log->a0], log, sizeof(REPORT_DESC));
|
|
return FALSE;
|
|
}
|
|
|
|
NTSTATUS SetLog(
|
|
_In_ PFLT_CALLBACK_DATA Data,
|
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
|
_In_ ULONG code,
|
|
_In_ ULONG a0,
|
|
_In_ ULONG a1,
|
|
_In_ ULONG a2,
|
|
_In_ PWCHAR processName,
|
|
_In_ PWCHAR path
|
|
)
|
|
{
|
|
PLOG_LIST log = NULL;
|
|
LARGE_INTEGER current_time;
|
|
//ULONG path_size = 0;
|
|
//ULONG process_size = 0;
|
|
PWCHAR name = NULL;
|
|
REPORT_DESC desc = { 0, };
|
|
KIRQL oldIrql;
|
|
|
|
UNREFERENCED_PARAMETER(Data);
|
|
UNREFERENCED_PARAMETER(a2);
|
|
UNREFERENCED_PARAMETER(FltObjects);
|
|
UNREFERENCED_PARAMETER(processName);
|
|
UNREFERENCED_PARAMETER(path);
|
|
|
|
if (path == NULL || processName == NULL)
|
|
{
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (!(g_bs1Flt.LogType & code))
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
KeQuerySystemTime(¤t_time);
|
|
desc.time = (LONGLONG)current_time.QuadPart;
|
|
desc.pid = HandleToULong(PsGetCurrentProcessId());
|
|
desc.code = code;
|
|
desc.a0 = a0;
|
|
desc.a1 = a1;
|
|
|
|
if (code == LOG_POLICY)
|
|
{
|
|
|
|
desc.a2 = IsPolicyLog(a0);
|
|
|
|
///경로 저장
|
|
if (!NT_SUCCESS(RtlStringCbCopyW(desc.path, sizeof(desc.path), path)))
|
|
{
|
|
// 경로가 너무 길 경우 잘라서라도 넣고 싶다면 RtlStringCbCopyN 등을 고려,
|
|
// 현재는 에러가 나더라도 desc.path는 비어있지 않고 안전하게 null 종료됨.
|
|
}
|
|
|
|
///프로세스 명만 사용
|
|
name = wcsrchr(processName, '\\');
|
|
if (!name)
|
|
name = processName;
|
|
else
|
|
++name;
|
|
|
|
if (!NT_SUCCESS(RtlStringCbCopyW(desc.ProcessName, sizeof(desc.ProcessName), name)))
|
|
{
|
|
// 복사 실패 처리 (필요시)
|
|
}
|
|
|
|
KLogEx(DEBUG_TRACE_INFO, "LOG_POLICY code(%d), a0(%d), a1(%d), name(%S), path(%S)\n",
|
|
code, a0, a1, desc.ProcessName, desc.path);
|
|
|
|
///차단 메시지 및 로그 예외
|
|
if (IsException(Data, &desc))
|
|
{
|
|
KLogEx(DEBUG_TRACE_INFO, "IsException !!!\n");
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
// /// 사용자에게 차단 메시지를 보내기 위함
|
|
// UserNotifyMessage(desc.a0, desc.ProcessName, NULL);
|
|
//
|
|
// if(!IsPolicyLog(a0))
|
|
// return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
/// 중복 로그만 예외 하기 위해 사용
|
|
if (IsOvlappedLog(Data, &desc))
|
|
{
|
|
KLogEx(DEBUG_TRACE_INFO, "IsOvlappedLog !!!\n");
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
}
|
|
else if (code == LOG_PROCESS_PROTECT)
|
|
{
|
|
///경로 저장
|
|
if (!NT_SUCCESS(RtlStringCbCopyW(desc.path, sizeof(desc.path), processName)))
|
|
{
|
|
}
|
|
|
|
if (!NT_SUCCESS(RtlStringCbCopyW(desc.renamepath, sizeof(desc.renamepath), path)))
|
|
{
|
|
}
|
|
}
|
|
else
|
|
{
|
|
///경로 저장
|
|
if (!NT_SUCCESS(RtlStringCbCopyW(desc.path, sizeof(desc.path), path)))
|
|
{
|
|
// 경로가 너무 길 경우 잘라서라도 넣고 싶다면 RtlStringCbCopyN 등을 고려,
|
|
// 현재는 에러가 나더라도 desc.path는 비어있지 않고 안전하게 null 종료됨.
|
|
}
|
|
|
|
///프로세스 명만 사용
|
|
name = wcsrchr(processName, '\\');
|
|
if (!name)
|
|
name = processName;
|
|
else
|
|
++name;
|
|
|
|
if (!NT_SUCCESS(RtlStringCbCopyW(desc.ProcessName, sizeof(desc.ProcessName), name)))
|
|
{
|
|
// 복사 실패 처리 (필요시)
|
|
}
|
|
|
|
KLogEx(DEBUG_TRACE_INFO, "code(%d), a0(%d), a1(%d), name(%S), path(%S)\n",
|
|
code, a0, a1, desc.ProcessName, desc.path);
|
|
}
|
|
|
|
log = (PLOG_LIST)ExAllocateFromNPagedLookasideList(&s_log_PoolList);
|
|
if (!log)
|
|
{
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
RtlZeroMemory(log, s_log_PoolList.L.Size);
|
|
memcpy(&log->a, &desc, sizeof(REPORT_DESC));
|
|
|
|
KeAcquireSpinLock(&s_log_list_lock, &oldIrql);
|
|
{
|
|
InsertTailList(&s_log_list, &log->list);
|
|
++s_log_cnt;
|
|
}
|
|
KeReleaseSpinLock(&s_log_list_lock, oldIrql);
|
|
|
|
RptNotifyEvent();
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS SetConnectLog(
|
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
|
_In_ ULONG a0,
|
|
_In_ ULONG a1,
|
|
_In_ ULONG a2,
|
|
_In_ PWCHAR volum,
|
|
_In_ PWCHAR processName,
|
|
_In_ PWCHAR path
|
|
)
|
|
{
|
|
PLOG_LIST log = NULL;
|
|
LARGE_INTEGER current_time;
|
|
//REPORT_DESC desc = { 0, };
|
|
KIRQL oldIrql;
|
|
|
|
UNREFERENCED_PARAMETER(a2);
|
|
UNREFERENCED_PARAMETER(FltObjects);
|
|
UNREFERENCED_PARAMETER(processName);
|
|
UNREFERENCED_PARAMETER(path);
|
|
|
|
KLogEx(DEBUG_TRACE_INFO, ", SET_LOG_TYPE(%d)\n", g_bs1Flt.LogType);
|
|
if (!(g_bs1Flt.LogType & LOG_CONNECT))
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
log = (PLOG_LIST)ExAllocateFromNPagedLookasideList(&s_log_PoolList);
|
|
if (!log)
|
|
{
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
RtlZeroMemory(log, s_log_PoolList.L.Size);
|
|
|
|
KeQuerySystemTime(¤t_time);
|
|
log->a.time = (LONGLONG)current_time.QuadPart;
|
|
log->a.pid = HandleToULong(PsGetCurrentProcessId());
|
|
log->a.code = LOG_CONNECT;
|
|
log->a.a0 = a0;
|
|
log->a.a1 = a1;
|
|
|
|
if (processName)
|
|
{
|
|
RtlStringCbCopyW(log->a.ProcessName, sizeof(log->a.ProcessName), processName);
|
|
}
|
|
else
|
|
{
|
|
RtlStringCbCopyW(log->a.ProcessName, sizeof(log->a.ProcessName), L"Unknown");
|
|
}
|
|
|
|
if (path)
|
|
{
|
|
RtlStringCbCopyW(log->a.path, sizeof(log->a.path), path);
|
|
}
|
|
else
|
|
{
|
|
RtlStringCbCopyW(log->a.path, sizeof(log->a.path), L"Unknown Path");
|
|
}
|
|
|
|
if (volum)
|
|
{
|
|
RtlStringCbCopyW(log->a.renamepath, sizeof(log->a.renamepath), volum);
|
|
}
|
|
else
|
|
{
|
|
RtlStringCbCopyW(log->a.renamepath, sizeof(log->a.renamepath), volum);
|
|
}
|
|
|
|
|
|
|
|
KLogEx(DEBUG_TRACE_INFO, "code(%d), a0(%d), a1(%d), name(%S), path(%S)\n",
|
|
log->a.code, log->a.a0, log->a.a1, log->a.ProcessName, log->a.path);
|
|
|
|
//memcpy(&log->a, &desc, sizeof(REPORT_DESC));
|
|
|
|
KeAcquireSpinLock(&s_log_list_lock, &oldIrql);
|
|
{
|
|
InsertTailList(&s_log_list, &log->list);
|
|
++s_log_cnt;
|
|
}
|
|
KeReleaseSpinLock(&s_log_list_lock, oldIrql);
|
|
|
|
RptNotifyEvent();
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
NTSTATUS SetENLog(PFLT_CALLBACK_DATA data, ULONG code, ULONG devicetype, ULONG uAction, ULONG filesize, PWCHAR process_name, PWCHAR path, PWCHAR prenampath)
|
|
{
|
|
PLOG_LIST log = NULL;
|
|
LARGE_INTEGER current_time;
|
|
ULONG path_size = 0;
|
|
ULONG process_size = 0;
|
|
PWCHAR name = NULL;
|
|
REPORT_DESC desc = { 0, };
|
|
KIRQL oldIrql;
|
|
|
|
if (path == NULL)
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
if (process_name == NULL)
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
if(!(g_bs1Flt.LogType & code))
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
KeQuerySystemTime(¤t_time);
|
|
desc.time = (LONGLONG)current_time.QuadPart;
|
|
desc.pid = (ULONG)(ULONG_PTR)PsGetCurrentProcessId();
|
|
desc.code = code;
|
|
desc.a0 = devicetype;
|
|
desc.a1 = uAction;
|
|
desc.a2 = filesize;
|
|
|
|
///경로 저장
|
|
path_size = (ULONG)wcslen(path) * (ULONG)sizeof(WCHAR);
|
|
if (path_size >= sizeof(desc.path))
|
|
path_size = sizeof(desc.path);
|
|
|
|
wcsncpy(desc.path, path, path_size);
|
|
|
|
if (wcslen(prenampath) > 0)
|
|
{
|
|
path_size = (ULONG)wcslen(prenampath) * (ULONG)sizeof(WCHAR);
|
|
if (path_size >= sizeof(desc.renamepath))
|
|
path_size = sizeof(desc.renamepath);
|
|
|
|
wcsncpy(desc.renamepath, prenampath, path_size);
|
|
}
|
|
|
|
///프로세스 명만 사용
|
|
name = wcsrchr(process_name, '\\');
|
|
if (!name)
|
|
name = process_name;
|
|
else
|
|
++name;
|
|
|
|
process_size = (ULONG)wcslen(name) * (ULONG)sizeof(WCHAR);
|
|
if (process_size >= sizeof(desc.ProcessName))
|
|
process_size = sizeof(desc.ProcessName);
|
|
|
|
wcsncpy(desc.ProcessName, name, process_size);
|
|
|
|
KLogEx(DEBUG_TRACE_ERROR, "code(%d), devicetype(%d), uAction(%d),filesize(%d) name(%S), path(%S)\n", code, devicetype, uAction, filesize, process_name, path);
|
|
|
|
///차단 메시지 및 로그 예외
|
|
if (IsException(data, &desc))
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
if (!IsPolicyLog(devicetype))
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
/// 중복 로그만 예외 하기 위해 사용
|
|
if (IsOvlappedLog(data, &desc))
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
KeAcquireSpinLock(&s_log_list_lock, &oldIrql);
|
|
|
|
log = (PLOG_LIST)ExAllocateFromNPagedLookasideList(&s_log_PoolList);
|
|
if (!log)
|
|
{
|
|
KeReleaseSpinLock(&s_log_list_lock, oldIrql);
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
RtlZeroMemory(log, sizeof(LOG_LIST));
|
|
memcpy(&log->a, &desc, sizeof(REPORT_DESC));
|
|
|
|
++s_log_cnt;
|
|
|
|
InsertTailList(&s_log_list, &log->list);
|
|
KeReleaseSpinLock(&s_log_list_lock, oldIrql);
|
|
RptNotifyEvent();
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
VOID Cleanuplog()
|
|
{
|
|
//PLIST_ENTRY pList = NULL;
|
|
//PLOG_LIST plog = NULL;
|
|
KIRQL oldIrql;
|
|
|
|
KeAcquireSpinLock(&s_log_list_lock, &oldIrql);
|
|
InitializeListHead(&s_log_list);
|
|
ExDeleteNPagedLookasideList(&s_log_PoolList);
|
|
s_log_cnt = 0;
|
|
|
|
KeReleaseSpinLock(&s_log_list_lock, oldIrql);
|
|
|
|
KLogEx(DEBUG_TRACE_INFO, "success\n");
|
|
}
|
|
|
|
|
|
NTSTATUS GetLog(PVOID buf, ULONG size, ULONG* req)
|
|
{
|
|
KIRQL irql;
|
|
ULONG require_size = 0;
|
|
PLIST_ENTRY current, tmp = NULL; //tail,
|
|
PLOG_LIST plog = NULL;
|
|
PLOG_NOTIFICATION l = (PLOG_NOTIFICATION)buf;
|
|
PREPORT_DESC r = (PREPORT_DESC)&l->desc;
|
|
ULONG ulReminCnt = 0;
|
|
|
|
KeAcquireSpinLock(&s_log_list_lock, &irql);
|
|
|
|
if (!s_log_cnt && IsListEmpty(&s_log_list))
|
|
{
|
|
if (req)
|
|
*req = 0;
|
|
KeReleaseSpinLock(&s_log_list_lock, irql);
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
if (!MmIsAddressValid(buf))
|
|
{
|
|
if (req)
|
|
*req = require_size;
|
|
KeReleaseSpinLock(&s_log_list_lock, irql);
|
|
return STATUS_BUFFER_OVERFLOW;
|
|
}
|
|
|
|
require_size = sizeof(ULONG) + sizeof(REPORT_DESC) * s_log_cnt;
|
|
|
|
if (buf == NULL || size == 0)
|
|
{
|
|
if (req)
|
|
*req = require_size;
|
|
|
|
KLogEx(DEBUG_TRACE_INFO, "size mistach require_size(%d), size(%d)\n", require_size, size);
|
|
KeReleaseSpinLock(&s_log_list_lock, irql);
|
|
return STATUS_BUFFER_OVERFLOW;
|
|
}
|
|
else if (size < require_size)
|
|
{
|
|
if (s_log_cnt > 1000)
|
|
{
|
|
ulReminCnt = (size - sizeof(ULONG)) / sizeof(REPORT_DESC);
|
|
l->count = ulReminCnt;
|
|
}
|
|
else
|
|
{
|
|
if (req)
|
|
*req = require_size;
|
|
|
|
KLogEx(DEBUG_TRACE_INFO, "remain size mistach require_size(%d), size(%d)\n", require_size, size);
|
|
KeReleaseSpinLock(&s_log_list_lock, irql);
|
|
RptNotifyEvent();
|
|
return STATUS_BUFFER_OVERFLOW;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ulReminCnt = s_log_cnt;
|
|
l->count = s_log_cnt;
|
|
}
|
|
|
|
KLogEx(DEBUG_TRACE_INFO, "s_log_cnt(%d), ulReminCnt(%d)\n", s_log_cnt, ulReminCnt);
|
|
current = s_log_list.Flink;
|
|
while (&s_log_list != current)
|
|
{
|
|
if (!ulReminCnt)
|
|
break;
|
|
|
|
tmp = current;
|
|
current = current->Flink;
|
|
|
|
plog = CONTAINING_RECORD(tmp, LOG_LIST, list);
|
|
RtlCopyMemory(r, &plog->a, sizeof(REPORT_DESC));
|
|
RemoveEntryList(&plog->list);
|
|
|
|
ExFreeToNPagedLookasideList(&s_log_PoolList, plog);
|
|
--s_log_cnt;
|
|
--ulReminCnt;
|
|
|
|
r = (PREPORT_DESC)GetPtr(r, sizeof(REPORT_DESC));
|
|
plog = NULL;
|
|
}
|
|
|
|
|
|
KeReleaseSpinLock(&s_log_list_lock, irql);
|
|
|
|
if (!IsListEmpty(&s_log_list))
|
|
{
|
|
RptNotifyEvent();
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|