bug : bs1flt

- 특정 window 10에서 load 되지 않는 현상 수정
 - 디버그 옵션이 정상 적용되지 않는 현상 수정
 - 프로세스 종료 방지 기능이 정상동작 안하는 현상 수정

feat : agent start 로그 시작 추가
bug : RecoverService 시작 위치 변경 → ManagerService 시
 - 복구 파일시 목록 누락된 파일 추가

feat : 설치시 서버 주소 검증 기능 추가
 - 설치정보(si.dat)는 설치 위치에 암호화 하여 저장하고, 복원을 위한 백업 리스스 압축파일에 추가

feat : UsbToUsb  파일 전송 차단시 해당 프로그램에서 반복적으로 차단되는 현상 수정

bug  : 블루투스 파일 전송시 간혈적으로 블루투스 프로세스가 죽는현상
feat : 파일 관리(bluetooth, usb, usbtousb, mtp, cd-rom)
 - 예외 확장자, 예외 경로 기능 추가
This commit is contained in:
mgkim 2026-03-25 21:27:21 +09:00
parent def1b99ef7
commit 826810ca06
466 changed files with 342739 additions and 142380 deletions

View File

@ -11,7 +11,7 @@ unit ApiHookExplorer;
interface interface
uses uses
Winapi.Windows, System.SysUtils, Winapi.ActiveX, Tocsg.Thread, Winapi.ShlObj; Winapi.Windows, System.SysUtils, Winapi.ActiveX, Tocsg.Thread, Winapi.ShlObj, StrUtils;
type type
TFileOpProgressSink = class(TInterfacedObject, IFileOperationProgressSink) TFileOpProgressSink = class(TInterfacedObject, IFileOperationProgressSink)
@ -296,6 +296,59 @@ var
FileUseBlock: TFileUseBlock; FileUseBlock: TFileUseBlock;
resultMsg: string; resultMsg: string;
curAppType: TCurAppType; curAppType: TCurAppType;
function IsExceptionExtenstion(const APath: string; var AtExt : string): Boolean;
var
sExt: string;
ExceptionExt: TArray<string>;
Ext: string;
begin
Result:= False;
if AtExt <> '' then
begin
ExceptionExt := AtExt.Split(['|']);
for Ext in ExceptionExt do
begin
if Trim(Ext) = '' then
Continue;
if SameText(sExt, Ext) then
begin
Result := True;
exit;
end;
end;
end;
end;
function IsExceptionPath(const APath: string; var AtPath : string): Boolean;
var
ExceptionPaths: TArray<string>;
ExPath: string;
begin
Result:= False;
if AtPath <> '' then
begin
ExceptionPaths := AtPath.Split(['|']);
for ExPath in ExceptionPaths do
begin
if Trim(ExPath) = '' then
Continue;
if ContainsText(APath, ExPath) then
begin
Result := True;
exit;
end;
end;
end;
end;
begin begin
Result := S_OK; Result := S_OK;
resultMsg := ''; resultMsg := '';
@ -380,6 +433,12 @@ begin
else else
FileUseBlock := fubMonitor; FileUseBlock := fubMonitor;
if IsExceptionExtenstion(sSrcPath, IntBlockNewFile.extList) then
exit;
if IsExceptionPath(sSrcPath, IntBlockNewFile.excList) then
exit;
DVLOG('ProcMon: mode(%d), blockByFilename(%s), contentsFilter(%s)', DVLOG('ProcMon: mode(%d), blockByFilename(%s), contentsFilter(%s)',
[DWORD(IntBlockNewFile.mode), IntBlockNewFile.blockByFilename_list, IntBlockNewFile.contentsFilter_list]); [DWORD(IntBlockNewFile.mode), IntBlockNewFile.blockByFilename_list, IntBlockNewFile.contentsFilter_list]);

View File

@ -48,6 +48,8 @@ type
PSCSI_PASS_THROUGH_DIRECT = ^SCSI_PASS_THROUGH_DIRECT; PSCSI_PASS_THROUGH_DIRECT = ^SCSI_PASS_THROUGH_DIRECT;
TApiHookContents = class TApiHookContents = class
private
function IsExceptionExtenstion(const APath: string ; var AtExt : string): Boolean;
public public
fileHandleList_: TFileHandleList; fileHandleList_: TFileHandleList;
appType_: TCurAppType; appType_: TCurAppType;
@ -66,7 +68,7 @@ type
function GetDriveBusType(DriveLetter: WideChar): STORAGE_BUS_TYPE; function GetDriveBusType(DriveLetter: WideChar): STORAGE_BUS_TYPE;
function GetOffLineType(dwType: DWORD; dwBusType: DWORD; pwszPath: PWideChar): string; function GetOffLineType(dwType: DWORD; dwBusType: DWORD; pwszPath: PWideChar): string;
function GetFileReadBuffer(const path: string; pbuffer: PByte; buffersize: DWORD): Boolean; stdcall; function GetFileReadBuffer(const path: string; pbuffer: PByte; buffersize: DWORD): Boolean; stdcall;
function IsExceptionPath(const APath: string): Boolean; function IsExceptionPath(const APath: string; var AtPath : string): Boolean;
end; end;
@ -157,7 +159,7 @@ var
implementation implementation
uses uses
BS1Hook, Tocsg.Packet, Tocsg.Files, DefineHelper, ApiHookFile, superobject; BS1Hook, Tocsg.Packet, Tocsg.Safe, Tocsg.Files, DefineHelper, ApiHookFile, superobject;
@ -659,7 +661,45 @@ begin
end; end;
end; end;
function TApiHookContents.IsExceptionPath(const APath: string): Boolean; function TApiHookContents.IsExceptionExtenstion(const APath: string; var AtExt : string): Boolean;
var
sExt: string;
ExceptionExt: TArray<string>;
Ext: string;
begin
Result:= False;
sExt := ExtractFileExt(APath);
if SameText(sExt, '.dll') or SameText(sExt, '.exe') or SameText(sExt, '.ico') then
begin
Result:= True;
Exit;
end;
if AtExt <> '' then
begin
ExceptionExt := AtExt.Split(['|']);
for Ext in ExceptionExt do
begin
if Trim(Ext) = '' then
Continue;
if SameText(sExt, Ext) then
begin
Result := True;
exit;
end;
end;
end;
end;
function TApiHookContents.IsExceptionPath(const APath: string; var AtPath : string): Boolean;
var
ExceptionPaths: TArray<string>;
ExPath: string;
begin begin
Result:= True; Result:= True;
@ -682,12 +722,31 @@ begin
Exit; Exit;
Result:= False; Result:= False;
if AtPath <> '' then
begin
ExceptionPaths := AtPath.Split(['|']);
for ExPath in ExceptionPaths do
begin
if Trim(ExPath) = '' then
Continue;
if ContainsText(APath, ExPath) then
begin
Result := True;
exit;
end;
end;
end;
end; end;
function TApiHookContents.CreateFileProc(hFile: THandle; lpFileName: LPCWSTR; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): Boolean stdcall; function TApiHookContents.CreateFileProc(hFile: THandle; lpFileName: LPCWSTR; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): Boolean stdcall;
var var
sPath: string; sPath: string;
IntBlockNewFile: TIntBlockNewFile;
begin begin
Result:= False; Result:= False;
if (hFile = 0) or (hFile = INVALID_HANDLE_VALUE) then if (hFile = 0) or (hFile = INVALID_HANDLE_VALUE) then
@ -725,20 +784,27 @@ begin
end; end;
sPath:= lpFileName; sPath:= lpFileName;
sPath := Trim(PChar(sPath));
if (Length(sPath) >= 2) and (sPath[1] = '.') and (sPath[2] = '\') then if (Length(sPath) >= 2) and (sPath[1] = '.') and (sPath[2] = '\') then
Exit; Exit;
if StartsText(sPath, 'C:\WINDOWS\') then
Exit;
if EndsText('.dll', sPath) or EndsText('.exe', sPath) then
Exit;
if ContainsText(sPath, '\bs1dc.json') then if ContainsText(sPath, '\bs1dc.json') then
Exit; Exit;
if IsExceptionPath(sPath) then if (appType_ = catFquirt) then
begin
IntBlockNewFile:= gAppHook.Helper.CtrlOpt.IntBtBlockNewFile;
end
else if (appType_ = catLINKENGKM) then
begin
IntBlockNewFile:= gAppHook.Helper.CtrlOpt.IntUsbToUsbBlockNewFile;
end;
if IsExceptionExtenstion(sPath, IntBlockNewFile.extList) then
Exit;
if IsExceptionPath(sPath, IntBlockNewFile.excList) then
Exit; Exit;
if (appType_ = catExplorer) then //or (gbsHook_.processType_ = ptExplore) if (appType_ = catExplorer) then //or (gbsHook_.processType_ = ptExplore)
@ -852,11 +918,11 @@ begin
if dwBytesRead = 0 then Exit; if dwBytesRead = 0 then Exit;
// DVLOG('ReadFileProc: hFile(%p), nNumberOfBytesToRead(%d)', [Pointer(hFile), nNumberOfBytesToRead]); // DVLOG('ReadFileProc: hFile(%p), nNumberOfBytesToRead(%d)', [Pointer(hFile), nNumberOfBytesToRead]);
// var
if fileHandleList_.IsHandle(hFile, handleInfo) then if fileHandleList_.IsHandleOutPath(hFile, sPath) then
begin begin
sPath := handleInfo.path; // sPath := handleInfo.path;
handleInfo.Free; // handleInfo.Free;
fileHandleList_.InsertBufferForHandle(hFile, sPath, lpBuffer, dwBytesRead); fileHandleList_.InsertBufferForHandle(hFile, sPath, lpBuffer, dwBytesRead);
@ -1043,6 +1109,9 @@ begin
begin begin
if appType_ = catLINKENGKM then if appType_ = catLINKENGKM then
begin begin
//2026-03-24 해당 어플리케이션에서 차단시 오류코드로 반환시
//지속적으로 시도하는 것으로 확인되어.. 정상으로 처리하고 원본함수
//호출 하지 않는 방법으로 변경
// SetLastError(ERROR_DEV_NOT_EXIST); // SetLastError(ERROR_DEV_NOT_EXIST);
if (lpOutBuffer <> nil) and (nOutBufferSize >= 3) then if (lpOutBuffer <> nil) and (nOutBufferSize >= 3) then
begin begin
@ -1055,7 +1124,7 @@ begin
end; end;
SetLastError(ERROR_SUCCESS); SetLastError(ERROR_SUCCESS);
Result := True; Result := False;
end end
else else
SetLastError(ERROR_ACCESS_DENIED); SetLastError(ERROR_ACCESS_DENIED);
@ -1090,17 +1159,22 @@ var
FileSizeLow: DWORD; FileSizeLow: DWORD;
pMem: Pointer; pMem: Pointer;
ViewSize: SIZE_T; ViewSize: SIZE_T;
sExt: string;
IntBlockNewFile: TIntBlockNewFile;
begin begin
Result:= False; Result:= False;
if not (flProtect in [PAGE_READONLY, PAGE_READWRITE, PAGE_WRITECOPY]) then if not (flProtect in [PAGE_READONLY, PAGE_READWRITE, PAGE_WRITECOPY]) then
Exit; Exit;
if (appType_ = catFquirt) then
Exit;
sPath:= ''; sPath:= '';
if fileHandleList_.IsHandle(hFile, handleInfo) then if fileHandleList_.IsHandleOutPath(hFile, sPath) then
begin begin
sPath:= handleInfo.path; // sPath:= handleInfo.path;
handleInfo.Free; // handleInfo.Free;
end end
else if GetPathFromHandle(hFile, sPath) then else if GetPathFromHandle(hFile, sPath) then
begin begin
@ -1114,12 +1188,24 @@ begin
if sPath = '' then if sPath = '' then
Exit; Exit;
if EndsText('.dll', sPath) or EndsText('.exe', sPath) then sPath := Trim(PChar(sPath));
if (appType_ = catFquirt) then
begin
IntBlockNewFile:= gAppHook.Helper.CtrlOpt.IntBtBlockNewFile;
end
else if (appType_ = catLINKENGKM) then
begin
IntBlockNewFile:= gAppHook.Helper.CtrlOpt.IntUsbToUsbBlockNewFile;
end;
if IsExceptionExtenstion(sPath, IntBlockNewFile.extList) then
Exit; Exit;
if IsExceptionPath(sPath) then if IsExceptionPath(sPath, IntBlockNewFile.excList) then
Exit; Exit;
CheckSize := (Int64(dwMaximumSizeHigh) shl 32) or dwMaximumSizeLow; CheckSize := (Int64(dwMaximumSizeHigh) shl 32) or dwMaximumSizeLow;
if CheckSize = 0 then if CheckSize = 0 then
begin begin
@ -1374,7 +1460,11 @@ begin
begin begin
Result:= gApiHookContents_.DeviceIoControlProc(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped); Result:= gApiHookContents_.DeviceIoControlProc(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
if not result then if not result then
begin
if gApiHookContents_.appType_ = catLINKENGKM then
result:= True;
Exit; Exit;
end;
end; end;
Result:= ozDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped); Result:= ozDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);

View File

@ -40,6 +40,8 @@ type
end; end;
TFileHandleList = class TFileHandleList = class
private
public public
lFile: TObjectList<TFileHandle>; lFile: TObjectList<TFileHandle>;
lHisFile: TObjectList<TFileHandle>; lHisFile: TObjectList<TFileHandle>;
@ -52,7 +54,7 @@ type
procedure Lock(var ACS: TRTLCriticalSection); procedure Lock(var ACS: TRTLCriticalSection);
procedure UnLock(var ACS: TRTLCriticalSection); procedure UnLock(var ACS: TRTLCriticalSection);
function IsHandleOutPath(h: THandle; out sPath: string): BOOL;
function FindHandle(h: THandle): TFileHandle; function FindHandle(h: THandle): TFileHandle;
function ChangeHandle(h: THandle; const path: string; dwDesiredAccess: DWORD = 0; function ChangeHandle(h: THandle; const path: string; dwDesiredAccess: DWORD = 0;
dwShareMode: DWORD = 0; dwCreationDisposition: DWORD = 0; dwShareMode: DWORD = 0; dwCreationDisposition: DWORD = 0;
@ -486,6 +488,33 @@ begin
end; end;
function TFileHandleList.IsHandleOutPath(h: THandle; out sPath: string): BOOL;
var
fh: TFileHandle;
begin
Result := FALSE;
if not state then Exit;
if lFile.Count = 0 then Exit;
Lock(cs);
try
for fh in lFile do
begin
if fh.h = h then
begin
sPath:= fh.path;
Result := TRUE;
Break;
end;
end;
finally
UnLock(cs);
end;
end;
function TFileHandleList.IsHistoryFileBufferCompare(const path: string; lpBuffer: PByte; size: DWORD; function TFileHandleList.IsHistoryFileBufferCompare(const path: string; lpBuffer: PByte; size: DWORD;
out fileHandle: TFileHandle): BOOL; out fileHandle: TFileHandle): BOOL;

View File

@ -10,7 +10,7 @@ ClassGuid = {b86dff51-a31e-4bac-b3cf-e8cfe75c9fc2} ;This value is determine
;Class = "ActivityMonitor" ;Class = "ActivityMonitor"
;ClassGuid = {AE71EC8D-C1FD-4564-8AA9-D56ADE722321} ;ClassGuid = {AE71EC8D-C1FD-4564-8AA9-D56ADE722321}
Provider = %ManufacturerName% Provider = %ManufacturerName%
DriverVer = 03/20/2026,17.0.19.906 DriverVer = 03/25/2026,17.39.11.270
CatalogFile = bs1flt.cat CatalogFile = bs1flt.cat
PnpLockdown = 1 PnpLockdown = 1

View File

@ -10,7 +10,7 @@ ClassGuid = {b86dff51-a31e-4bac-b3cf-e8cfe75c9fc2} ;This value is determine
;Class = "ActivityMonitor" ;Class = "ActivityMonitor"
;ClassGuid = {AE71EC8D-C1FD-4564-8AA9-D56ADE722321} ;ClassGuid = {AE71EC8D-C1FD-4564-8AA9-D56ADE722321}
Provider = %ManufacturerName% Provider = %ManufacturerName%
DriverVer = 03/20/2026,17.0.19.906 DriverVer = 03/25/2026,17.39.11.270
CatalogFile = bs1flt.cat CatalogFile = bs1flt.cat
PnpLockdown = 1 PnpLockdown = 1

View File

@ -1105,9 +1105,7 @@ Return Value:
UNREFERENCED_PARAMETER(RegistryPath); UNREFERENCED_PARAMETER(RegistryPath);
g_DebugLevel = DEBUG_TRACE_INFO; g_DebugLevel = DEBUG_TRACE_INFO;
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "%s:%s : Entered RegPath(%S)(%d)", DRIVERNAMEA, __FUNCTION__, RegistryPath->Buffer, RegistryPath->Length);
KLogEx(DEBUG_TRACE_INFO, "Entered\n");
KLogEx(DEBUG_TRACE_INFO, "RegPath(%S)(%d)\n", RegistryPath->Buffer, RegistryPath->Length);
RtlZeroMemory(&g_bs1Flt, sizeof(g_bs1Flt)); RtlZeroMemory(&g_bs1Flt, sizeof(g_bs1Flt));
@ -1116,7 +1114,7 @@ Return Value:
g_DebugLevel = 0; g_DebugLevel = 0;
} }
g_DebugLevel = DEBUG_TRACE_ALL; //g_DebugLevel = DEBUG_TRACE_ALL;
// //
// Register with FltMgr to tell it our callback routines // Register with FltMgr to tell it our callback routines
// //
@ -1276,7 +1274,7 @@ $Success:
CleanupPathlist(); CleanupPathlist();
CleanupProcesslist(); CleanupProcesslist();
CleanupProcessProtectList(); CleanupProcessProtectList();
Cleanuplog();
PgReset(); PgReset();
CleanupUsbDiskExceptionList(); CleanupUsbDiskExceptionList();
@ -1297,5 +1295,6 @@ $Success:
g_bs1Flt.Filter = NULL; g_bs1Flt.Filter = NULL;
} }
Cleanuplog();
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View File

@ -439,7 +439,6 @@ NTSTATUS InstallProcessProtect() {
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
g_bs1Flt.IsProcessProtect = TRUE;
s_operationRegistrations[0].ObjectType = PsProcessType; s_operationRegistrations[0].ObjectType = PsProcessType;
s_operationRegistrations[0].Operations |= OB_OPERATION_HANDLE_CREATE; s_operationRegistrations[0].Operations |= OB_OPERATION_HANDLE_CREATE;
s_operationRegistrations[0].Operations |= OB_OPERATION_HANDLE_DUPLICATE; s_operationRegistrations[0].Operations |= OB_OPERATION_HANDLE_DUPLICATE;
@ -467,6 +466,7 @@ NTSTATUS InstallProcessProtect() {
return status; return status;
} }
g_bs1Flt.IsProcessProtect = TRUE;
s_callbacksInstalled = TRUE; s_callbacksInstalled = TRUE;
KLogEx(DEBUG_TRACE_INFO, "Sucess\n"); KLogEx(DEBUG_TRACE_INFO, "Sucess\n");
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -483,5 +483,7 @@ VOID UnInstallProcessProtect()
g_bs1Flt.IsProcessProtect = FALSE; g_bs1Flt.IsProcessProtect = FALSE;
ObUnRegisterCallbacks(s_registrationHandle); ObUnRegisterCallbacks(s_registrationHandle);
s_registrationHandle = NULL;
s_callbacksInstalled = FALSE;
KLogEx(DEBUG_TRACE_ERROR, "Sucess\n"); KLogEx(DEBUG_TRACE_ERROR, "Sucess\n");
} }

View File

@ -28,8 +28,8 @@ typedef struct _LOG_LIST
static LIST_ENTRY s_log_list; static LIST_ENTRY s_log_list;
static KSPIN_LOCK s_log_list_lock; static KSPIN_LOCK s_log_list_lock;
static ULONG s_log_cnt; static ULONG s_log_cnt;
static NPAGED_LOOKASIDE_LIST s_log_PoolList; //static NPAGED_LOOKASIDE_LIST s_log_PoolList;
static LOOKASIDE_LIST_EX s_log_PoolList;
#define LOG_POOL_TAG 'kdrp' #define LOG_POOL_TAG 'kdrp'
@ -67,13 +67,23 @@ VOID Initlog()
s_log_cnt = 0; s_log_cnt = 0;
InitializeListHead(&s_log_list); InitializeListHead(&s_log_list);
KeInitializeSpinLock(&s_log_list_lock); KeInitializeSpinLock(&s_log_list_lock);
ExInitializeNPagedLookasideList(&s_log_PoolList //ExInitializeNPagedLookasideList(&s_log_PoolList
, NULL // , NULL
, NULL // , NULL
, 0 // , 0
, sizeof(LOG_LIST) // , sizeof(LOG_LIST)
, LOG_POOL_TAG // , LOG_POOL_TAG
, 0); // , 0);
ExInitializeLookasideListEx(
&s_log_PoolList,
NULL,
NULL,
NonPagedPoolNx, // 기존 NonPagedPool 대신 NX 풀 사용
0,
sizeof(LOG_LIST), // 실제 할당할 구조체 크기
LOG_POOL_TAG,
0
);
} }
@ -479,13 +489,15 @@ NTSTATUS SetLog(
code, a0, a1, desc.ProcessName, desc.path); code, a0, a1, desc.ProcessName, desc.path);
} }
log = (PLOG_LIST)ExAllocateFromNPagedLookasideList(&s_log_PoolList); //log = (PLOG_LIST)ExAllocateFromNPagedLookasideList(&s_log_PoolList);
log = (PLOG_LIST)ExAllocateFromLookasideListEx(&s_log_PoolList);
if (!log) if (!log)
{ {
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
RtlZeroMemory(log, s_log_PoolList.L.Size); //RtlZeroMemory(log, s_log_PoolList.L.Size);
RtlZeroMemory(log, sizeof(LOG_LIST));
memcpy(&log->a, &desc, sizeof(REPORT_DESC)); memcpy(&log->a, &desc, sizeof(REPORT_DESC));
KeAcquireSpinLock(&s_log_list_lock, &oldIrql); KeAcquireSpinLock(&s_log_list_lock, &oldIrql);
@ -523,13 +535,15 @@ NTSTATUS SetConnectLog(
if (!(g_bs1Flt.LogType & LOG_CONNECT)) if (!(g_bs1Flt.LogType & LOG_CONNECT))
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
log = (PLOG_LIST)ExAllocateFromNPagedLookasideList(&s_log_PoolList); //log = (PLOG_LIST)ExAllocateFromNPagedLookasideList(&s_log_PoolList);
log = (PLOG_LIST)ExAllocateFromLookasideListEx(&s_log_PoolList);
if (!log) if (!log)
{ {
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
RtlZeroMemory(log, s_log_PoolList.L.Size); //RtlZeroMemory(log, s_log_PoolList.L.Size);
RtlZeroMemory(log, sizeof(LOG_LIST));
KeQuerySystemTime(&current_time); KeQuerySystemTime(&current_time);
log->a.time = (LONGLONG)current_time.QuadPart; log->a.time = (LONGLONG)current_time.QuadPart;
@ -608,13 +622,15 @@ NTSTATUS SetProcessLog(
if (!(g_bs1Flt.LogType & code)) if (!(g_bs1Flt.LogType & code))
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
log = (PLOG_LIST)ExAllocateFromNPagedLookasideList(&s_log_PoolList); //log = (PLOG_LIST)ExAllocateFromNPagedLookasideList(&s_log_PoolList);
log = (PLOG_LIST)ExAllocateFromLookasideListEx(&s_log_PoolList);
if (!log) if (!log)
{ {
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
RtlZeroMemory(log, s_log_PoolList.L.Size); //RtlZeroMemory(log, s_log_PoolList.L.Size);
RtlZeroMemory(log, sizeof(LOG_LIST));
KeQuerySystemTime(&current_time); KeQuerySystemTime(&current_time);
log->a.time = (LONGLONG)current_time.QuadPart; log->a.time = (LONGLONG)current_time.QuadPart;
@ -739,7 +755,8 @@ NTSTATUS SetENLog(PFLT_CALLBACK_DATA data, ULONG code, ULONG devicetype, ULONG u
KeAcquireSpinLock(&s_log_list_lock, &oldIrql); KeAcquireSpinLock(&s_log_list_lock, &oldIrql);
log = (PLOG_LIST)ExAllocateFromNPagedLookasideList(&s_log_PoolList); //log = (PLOG_LIST)ExAllocateFromNPagedLookasideList(&s_log_PoolList);
log = (PLOG_LIST)ExAllocateFromLookasideListEx(&s_log_PoolList);
if (!log) if (!log)
{ {
KeReleaseSpinLock(&s_log_list_lock, oldIrql); KeReleaseSpinLock(&s_log_list_lock, oldIrql);
@ -760,22 +777,61 @@ NTSTATUS SetENLog(PFLT_CALLBACK_DATA data, ULONG code, ULONG devicetype, ULONG u
//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);
// //ExDeleteLookasideListEx(&s_log_PoolList);
// s_log_cnt = 0;
//
// KeReleaseSpinLock(&s_log_list_lock, oldIrql);
//
// KLogEx(DEBUG_TRACE_INFO, "success\n");
//}
VOID Cleanuplog() VOID Cleanuplog()
{ {
//PLIST_ENTRY pList = NULL; PLIST_ENTRY pList = NULL;
//PLOG_LIST plog = NULL; PLOG_LIST plog = NULL;
KIRQL oldIrql; KIRQL oldIrql;
LIST_ENTRY tempList;
// 1. 임시 리스트 초기화
InitializeListHead(&tempList);
// 2. 락을 걸고 기존 리스트의 항목들을 임시 리스트로 빠르게 옮깁니다.
KeAcquireSpinLock(&s_log_list_lock, &oldIrql); KeAcquireSpinLock(&s_log_list_lock, &oldIrql);
InitializeListHead(&s_log_list); if (!IsListEmpty(&s_log_list))
ExDeleteNPagedLookasideList(&s_log_PoolList); {
s_log_cnt = 0; tempList.Flink = s_log_list.Flink;
tempList.Blink = s_log_list.Blink;
s_log_list.Flink->Blink = &tempList;
s_log_list.Blink->Flink = &tempList;
InitializeListHead(&s_log_list); // 원본 리스트 비우기
}
s_log_cnt = 0;
// ★ 여기서 반드시 락을 먼저 풀어야 합니다! (IRQL 강하)
KeReleaseSpinLock(&s_log_list_lock, oldIrql); KeReleaseSpinLock(&s_log_list_lock, oldIrql);
KLogEx(DEBUG_TRACE_INFO, "success\n"); // 3. 락이 풀린 안전한 상태(PASSIVE_LEVEL)에서 남은 메모리들을 모두 해제합니다.
} while (!IsListEmpty(&tempList))
{
pList = RemoveHeadList(&tempList);
plog = CONTAINING_RECORD(pList, LOG_LIST, list);
ExFreeToLookasideListEx(&s_log_PoolList, plog);
}
// 4. 리스트 메모리를 모두 비운 후, 마지막으로 Lookaside 풀을 삭제합니다.
ExDeleteLookasideListEx(&s_log_PoolList);
KLogEx(DEBUG_TRACE_INFO, "Cleanuplog success\n");
}
NTSTATUS GetLog(PVOID buf, ULONG size, ULONG* req) NTSTATUS GetLog(PVOID buf, ULONG size, ULONG* req)
{ {
@ -854,7 +910,8 @@ NTSTATUS GetLog(PVOID buf, ULONG size, ULONG* req)
RtlCopyMemory(r, &plog->a, sizeof(REPORT_DESC)); RtlCopyMemory(r, &plog->a, sizeof(REPORT_DESC));
RemoveEntryList(&plog->list); RemoveEntryList(&plog->list);
ExFreeToNPagedLookasideList(&s_log_PoolList, plog); //ExFreeToNPagedLookasideList(&s_log_PoolList, plog);
ExFreeToLookasideListEx(&s_log_PoolList, plog);
--s_log_cnt; --s_log_cnt;
--ulReminCnt; --ulReminCnt;

View File

@ -1,7 +1,8 @@
#include "precomp.h" #include "precomp.h"
// ---------------------------------------------------------------------------
// [헬퍼 함수] URB 전송 및 메모리 해제 로직 (기존 코드 유지)
// ---------------------------------------------------------------------------
NTSTATUS UDF_CallUSBDI(IN PDEVICE_OBJECT pDevObj, IN PVOID UrbEtc) NTSTATUS UDF_CallUSBDI(IN PDEVICE_OBJECT pDevObj, IN PVOID UrbEtc)
{ {
IO_STATUS_BLOCK IoStatus; IO_STATUS_BLOCK IoStatus;
@ -10,36 +11,22 @@ NTSTATUS UDF_CallUSBDI(IN PDEVICE_OBJECT pDevObj, IN PVOID UrbEtc)
PIRP Irp = NULL; PIRP Irp = NULL;
PIO_STACK_LOCATION NextIrpStack = NULL; PIO_STACK_LOCATION NextIrpStack = NULL;
//g_Temp = pDevObj;
//g_Temp2 = UrbEtc;
// Initialise IRP completion event
KeInitializeEvent(&event, NotificationEvent, FALSE); KeInitializeEvent(&event, NotificationEvent, FALSE);
// Build Internal IOCTL IRP
Irp = IoBuildDeviceIoControlRequest( Irp = IoBuildDeviceIoControlRequest(
IOCTL_INTERNAL_USB_SUBMIT_URB, pDevObj, IOCTL_INTERNAL_USB_SUBMIT_URB, pDevObj,
NULL, 0, // Input buffer NULL, 0, NULL, 0, TRUE, &event, &IoStatus);
NULL, 0, // Output buffer
TRUE, &event, &IoStatus);
// Get IRP stack location for next driver down (already set up)
NextIrpStack = IoGetNextIrpStackLocation(Irp); NextIrpStack = IoGetNextIrpStackLocation(Irp);
// Store pointer to the URB etc
NextIrpStack->Parameters.Others.Argument1 = UrbEtc; NextIrpStack->Parameters.Others.Argument1 = UrbEtc;
NextIrpStack->Parameters.Others.Argument2 = (PVOID)0; NextIrpStack->Parameters.Others.Argument2 = (PVOID)0;
// Call the driver and wait for completion if necessary
status = IoCallDriver(pDevObj, Irp); status = IoCallDriver(pDevObj, Irp);
if (status == STATUS_PENDING) if (status == STATUS_PENDING)
{ {
KLogEx(DEBUG_TRACE_ERROR, "waiting for URB completion\n");
status = KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL); status = KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
status = IoStatus.Status; status = IoStatus.Status;
} }
// return IRP completion status
KLogEx(DEBUG_TRACE_ERROR, "returned %x\n", status);
return status; return status;
} }
@ -52,310 +39,109 @@ PURB AllocUrb(USHORT Size)
VOID FreeUsbDeviceInfo(IN PUSB_PARSED_INFO pInfo) VOID FreeUsbDeviceInfo(IN PUSB_PARSED_INFO pInfo)
{ {
if (!pInfo) return; if (!pInfo)
return;
// 문자열 메모리 해제 if (pInfo->ManufacturerStr)
if (pInfo->ManufacturerStr) ExFreePool(pInfo->ManufacturerStr); ExFreePool(pInfo->ManufacturerStr);
if (pInfo->ProductStr) ExFreePool(pInfo->ProductStr);
if (pInfo->SerialNumberStr) ExFreePool(pInfo->SerialNumberStr);
// Configuration Descriptor 해제 if (pInfo->ProductStr)
if (pInfo->ConfigDesc) ExFreePool(pInfo->ConfigDesc); ExFreePool(pInfo->ProductStr);
if (pInfo->SerialNumberStr)
ExFreePool(pInfo->SerialNumberStr);
if (pInfo->ConfigDesc)
ExFreePool(pInfo->ConfigDesc);
// 구조체 자체 해제
ExFreePool(pInfo); ExFreePool(pInfo);
} }
// --------------------------------------------------------------------------- NTSTATUS GetUsbDeviceDescriptor(IN PDEVICE_OBJECT DeviceObject, OUT PUSB_DEVICE_DESCRIPTOR* ppDescriptor)
// 1. Device Descriptor 가져오기
// ---------------------------------------------------------------------------
NTSTATUS GetUsbDeviceDescriptor(
IN PDEVICE_OBJECT DeviceObject,
OUT PUSB_DEVICE_DESCRIPTOR* ppDescriptor
)
{ {
PURB urb = NULL; PURB urb = AllocUrb(sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
PUSB_DEVICE_DESCRIPTOR descriptor = NULL;
NTSTATUS status;
urb = AllocUrb(sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
if (!urb) return STATUS_INSUFFICIENT_RESOURCES; if (!urb) return STATUS_INSUFFICIENT_RESOURCES;
descriptor = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_DEVICE_DESCRIPTOR), 'DST'); PUSB_DEVICE_DESCRIPTOR descriptor = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_DEVICE_DESCRIPTOR), 'DST');
if (!descriptor) { if (!descriptor) { ExFreePool(urb); return STATUS_INSUFFICIENT_RESOURCES; }
ExFreePool(urb);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(descriptor, sizeof(USB_DEVICE_DESCRIPTOR)); RtlZeroMemory(descriptor, sizeof(USB_DEVICE_DESCRIPTOR));
UsbBuildGetDescriptorRequest(urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, descriptor, NULL, sizeof(USB_DEVICE_DESCRIPTOR), NULL);
UsbBuildGetDescriptorRequest( NTSTATUS status = UDF_CallUSBDI(DeviceObject, urb);
urb, if (!NT_SUCCESS(status)) { ExFreePool(descriptor); *ppDescriptor = NULL; }
sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), else { *ppDescriptor = descriptor; }
USB_DEVICE_DESCRIPTOR_TYPE,
0, 0,
descriptor, NULL,
sizeof(USB_DEVICE_DESCRIPTOR), NULL
);
status = UDF_CallUSBDI(DeviceObject, urb);
if (!NT_SUCCESS(status)) {
ExFreePool(descriptor);
*ppDescriptor = NULL;
}
else {
*ppDescriptor = descriptor;
}
ExFreePool(urb); ExFreePool(urb);
return status; return status;
} }
// --------------------------------------------------------------------------- NTSTATUS GetUsbStringDescriptor(IN PDEVICE_OBJECT DeviceObject, IN UCHAR Index, IN USHORT LangId, OUT PWCHAR* ppStringData)
// 2. String Descriptor 가져오기 (특정 Index, Language ID)
// ---------------------------------------------------------------------------
NTSTATUS GetUsbStringDescriptor(
IN PDEVICE_OBJECT DeviceObject,
IN UCHAR Index,
IN USHORT LangId,
OUT PWCHAR* ppStringData
)
{ {
PURB urb = NULL;
PUSB_STRING_DESCRIPTOR pStrDesc = NULL;
NTSTATUS status;
ULONG size = 256; // 넉넉하게 잡음
if (Index == 0) return STATUS_INVALID_PARAMETER; if (Index == 0) return STATUS_INVALID_PARAMETER;
urb = AllocUrb(sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST)); PURB urb = AllocUrb(sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
if (!urb) return STATUS_INSUFFICIENT_RESOURCES; if (!urb) return STATUS_INSUFFICIENT_RESOURCES;
pStrDesc = ExAllocatePoolWithTag(NonPagedPool, size, 'STR'); ULONG size = 256;
if (!pStrDesc) { PUSB_STRING_DESCRIPTOR pStrDesc = ExAllocatePoolWithTag(NonPagedPool, size, 'STR');
ExFreePool(urb); if (!pStrDesc) { ExFreePool(urb); return STATUS_INSUFFICIENT_RESOURCES; }
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(pStrDesc, size); RtlZeroMemory(pStrDesc, size);
UsbBuildGetDescriptorRequest( UsbBuildGetDescriptorRequest(urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
urb, USB_STRING_DESCRIPTOR_TYPE, Index, LangId, pStrDesc, NULL, size, NULL);
sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_STRING_DESCRIPTOR_TYPE,
Index,
LangId,
pStrDesc, NULL,
size, NULL
);
status = UDF_CallUSBDI(DeviceObject, urb);
NTSTATUS status = UDF_CallUSBDI(DeviceObject, urb);
if (NT_SUCCESS(status) && pStrDesc->bLength > 2) { if (NT_SUCCESS(status) && pStrDesc->bLength > 2) {
// bString은 WCHAR 배열입니다. NULL Termination을 위해 별도 버퍼에 복사
ULONG strLenBytes = pStrDesc->bLength - 2; ULONG strLenBytes = pStrDesc->bLength - 2;
PWCHAR outBuf = ExAllocatePoolWithTag(NonPagedPool, strLenBytes + sizeof(WCHAR), 'STR2'); PWCHAR outBuf = ExAllocatePoolWithTag(NonPagedPool, strLenBytes + sizeof(WCHAR), 'STR2');
if (outBuf) { if (outBuf) {
RtlZeroMemory(outBuf, strLenBytes + sizeof(WCHAR)); RtlZeroMemory(outBuf, strLenBytes + sizeof(WCHAR));
RtlCopyMemory(outBuf, pStrDesc->bString, strLenBytes); RtlCopyMemory(outBuf, pStrDesc->bString, strLenBytes);
*ppStringData = outBuf; *ppStringData = outBuf;
} }
else { else { status = STATUS_INSUFFICIENT_RESOURCES; }
status = STATUS_INSUFFICIENT_RESOURCES;
}
} }
else { else {
*ppStringData = NULL; *ppStringData = NULL;
status = STATUS_UNSUCCESSFUL; status = STATUS_UNSUCCESSFUL;
} }
ExFreePool(pStrDesc); ExFreePool(pStrDesc);
ExFreePool(urb); ExFreePool(urb);
return status; return status;
} }
// --------------------------------------------------------------------------- NTSTATUS GetUsbFullConfigDescriptor(IN PDEVICE_OBJECT DeviceObject, OUT PUSB_CONFIGURATION_DESCRIPTOR* ppConfigDesc)
// 3. Configuration Descriptor 전체 가져오기 (Interface, Endpoint 포함)
// ---------------------------------------------------------------------------
NTSTATUS GetUsbFullConfigDescriptor(
IN PDEVICE_OBJECT DeviceObject,
OUT PUSB_CONFIGURATION_DESCRIPTOR* ppConfigDesc
)
{ {
PURB urb = NULL; PURB urb = AllocUrb(sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
PUSB_CONFIGURATION_DESCRIPTOR pHeader = NULL;
PUSB_CONFIGURATION_DESCRIPTOR pFullDesc = NULL;
NTSTATUS status;
ULONG fullSize = 0;
// 1단계: 헤더(9바이트)만 먼저 읽어서 전체 크기(wTotalLength) 파악
urb = AllocUrb(sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
if (!urb) return STATUS_INSUFFICIENT_RESOURCES; if (!urb) return STATUS_INSUFFICIENT_RESOURCES;
pHeader = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_CONFIGURATION_DESCRIPTOR), 'CFG'); PUSB_CONFIGURATION_DESCRIPTOR pHeader = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_CONFIGURATION_DESCRIPTOR), 'CFG');
if (!pHeader) { if (!pHeader) { ExFreePool(urb); return STATUS_INSUFFICIENT_RESOURCES; }
ExFreePool(urb);
return STATUS_INSUFFICIENT_RESOURCES;
}
UsbBuildGetDescriptorRequest( UsbBuildGetDescriptorRequest(urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, 0, pHeader, NULL, sizeof(USB_CONFIGURATION_DESCRIPTOR), NULL);
USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, 0,
pHeader, NULL, sizeof(USB_CONFIGURATION_DESCRIPTOR), NULL
);
status = UDF_CallUSBDI(DeviceObject, urb); NTSTATUS status = UDF_CallUSBDI(DeviceObject, urb);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) { ExFreePool(pHeader); ExFreePool(urb); return status; }
ExFreePool(pHeader);
ExFreePool(urb);
return status;
}
fullSize = pHeader->wTotalLength; ULONG fullSize = pHeader->wTotalLength;
ExFreePool(pHeader); // 헤더는 이제 필요 없음 (크기 알았으므로) ExFreePool(pHeader);
// 2단계: 전체 크기만큼 할당 후 다시 요청 PUSB_CONFIGURATION_DESCRIPTOR pFullDesc = ExAllocatePoolWithTag(NonPagedPool, fullSize, 'CFG');
pFullDesc = ExAllocatePoolWithTag(NonPagedPool, fullSize, 'CFG'); if (!pFullDesc) { ExFreePool(urb); return STATUS_INSUFFICIENT_RESOURCES; }
if (!pFullDesc) {
ExFreePool(urb);
return STATUS_INSUFFICIENT_RESOURCES;
}
// URB 재사용을 위해 ZeroMemory (버퍼 포인터 등이 바뀌므로)
RtlZeroMemory(urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST)); RtlZeroMemory(urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
UsbBuildGetDescriptorRequest(urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
UsbBuildGetDescriptorRequest( USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, 0, pFullDesc, NULL, fullSize, NULL);
urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, 0,
pFullDesc, NULL, fullSize, NULL
);
status = UDF_CallUSBDI(DeviceObject, urb); status = UDF_CallUSBDI(DeviceObject, urb);
if (NT_SUCCESS(status)) { if (NT_SUCCESS(status)) { *ppConfigDesc = pFullDesc; }
*ppConfigDesc = pFullDesc; else { ExFreePool(pFullDesc); *ppConfigDesc = NULL; }
}
else {
ExFreePool(pFullDesc);
*ppConfigDesc = NULL;
}
ExFreePool(urb); ExFreePool(urb);
return status; return status;
} }
// ---------------------------------------------------------------------------
// Main Logic: 모든 정보를 수집하고 출력(Logging)하는 함수
// ---------------------------------------------------------------------------
VOID GetAllUsbDeviceInfo(PDEVICE_OBJECT DeviceObject)
{
NTSTATUS status;
PUSB_DEVICE_DESCRIPTOR pDevDesc = NULL;
PUSB_CONFIGURATION_DESCRIPTOR pConfigDesc = NULL;
USHORT LangId = 0x0409; // Default English
KLogEx(DEBUG_TRACE_INFO, "===== START USB INFO COLLECTION =====\n");
// 1. Device Descriptor 수집
status = GetUsbDeviceDescriptor(DeviceObject, &pDevDesc);
if (NT_SUCCESS(status) && pDevDesc)
{
KLogEx(DEBUG_TRACE_INFO, "[Device Descriptor]\n");
KLogEx(DEBUG_TRACE_INFO, " bLength: 0x%X\n", pDevDesc->bLength);
KLogEx(DEBUG_TRACE_INFO, " bDescriptorType: 0x%X\n", pDevDesc->bDescriptorType);
KLogEx(DEBUG_TRACE_INFO, " bcdUSB: 0x%X\n", pDevDesc->bcdUSB);
KLogEx(DEBUG_TRACE_INFO, " idVendor: 0x%04X\n", pDevDesc->idVendor);
KLogEx(DEBUG_TRACE_INFO, " idProduct: 0x%04X\n", pDevDesc->idProduct);
KLogEx(DEBUG_TRACE_INFO, " bcdDevice: 0x%X\n", pDevDesc->bcdDevice);
KLogEx(DEBUG_TRACE_INFO, " bNumConfigurations: 0x%X\n", pDevDesc->bNumConfigurations);
// String Descriptor 수집 (Manufacturer, Product, Serial)
// 실제로는 String Index 0을 먼저 호출하여 지원 언어를 확인해야 하지만,
// 여기서는 편의상 0x0409(English)를 시도합니다.
if (pDevDesc->iManufacturer)
{
PWCHAR pStr = NULL;
if (NT_SUCCESS(GetUsbStringDescriptor(DeviceObject, pDevDesc->iManufacturer, LangId, &pStr)) && pStr) {
KLogEx(DEBUG_TRACE_INFO, " Manufacturer: %ws\n", pStr);
ExFreePool(pStr);
}
}
if (pDevDesc->iProduct)
{
PWCHAR pStr = NULL;
if (NT_SUCCESS(GetUsbStringDescriptor(DeviceObject, pDevDesc->iProduct, LangId, &pStr)) && pStr) {
KLogEx(DEBUG_TRACE_INFO, " Product: %ws\n", pStr);
ExFreePool(pStr);
}
}
if (pDevDesc->iSerialNumber)
{
PWCHAR pStr = NULL;
if (NT_SUCCESS(GetUsbStringDescriptor(DeviceObject, pDevDesc->iSerialNumber, LangId, &pStr)) && pStr) {
KLogEx(DEBUG_TRACE_INFO, " SerialNumber: %ws\n", pStr);
ExFreePool(pStr);
}
}
}
// 2. Configuration Descriptor (Full) 수집 및 파싱
status = GetUsbFullConfigDescriptor(DeviceObject, &pConfigDesc);
if (NT_SUCCESS(status) && pConfigDesc)
{
PUCHAR pCurr = (PUCHAR)pConfigDesc;
PUCHAR pEnd = pCurr + pConfigDesc->wTotalLength;
KLogEx(DEBUG_TRACE_INFO, "[Configuration Descriptor]\n");
KLogEx(DEBUG_TRACE_INFO, " wTotalLength: 0x%X\n", pConfigDesc->wTotalLength);
KLogEx(DEBUG_TRACE_INFO, " bNumInterfaces: 0x%X\n", pConfigDesc->bNumInterfaces);
KLogEx(DEBUG_TRACE_INFO, " bConfigurationValue: 0x%X\n", pConfigDesc->bConfigurationValue);
KLogEx(DEBUG_TRACE_INFO, " MaxPower: 0x%X", pConfigDesc->MaxPower);
// Loop를 돌면서 Interface 및 Endpoint 파싱
// 첫 번째 Descriptor는 Configuration이므로 건너뜀
pCurr += pConfigDesc->bLength;
while (pCurr < pEnd)
{
PUSB_COMMON_DESCRIPTOR pCommon = (PUSB_COMMON_DESCRIPTOR)pCurr;
if (pCommon->bLength == 0) break; // 에러 방지
if (pCommon->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
{
PUSB_INTERFACE_DESCRIPTOR pIntf = (PUSB_INTERFACE_DESCRIPTOR)pCommon;
KLogEx(DEBUG_TRACE_INFO, "[Interface Descriptor]\n");
KLogEx(DEBUG_TRACE_INFO, " bInterfaceNumber: 0x%X\n", pIntf->bInterfaceNumber);
KLogEx(DEBUG_TRACE_INFO, " bAlternateSetting: 0x%X\n", pIntf->bAlternateSetting);
KLogEx(DEBUG_TRACE_INFO, " bNumEndpoints: 0x%X\n", pIntf->bNumEndpoints);
KLogEx(DEBUG_TRACE_INFO, " bInterfaceClass: 0x%X\n", pIntf->bInterfaceClass);
KLogEx(DEBUG_TRACE_INFO, " bInterfaceSubClass: 0x%X\n", pIntf->bInterfaceSubClass);
KLogEx(DEBUG_TRACE_INFO, " bInterfaceProtocol: 0x%X\n", pIntf->bInterfaceProtocol);
}
else if (pCommon->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE)
{
PUSB_ENDPOINT_DESCRIPTOR pEp = (PUSB_ENDPOINT_DESCRIPTOR)pCommon;
KLogEx(DEBUG_TRACE_INFO, "[Endpoint Descriptor]\n");
KLogEx(DEBUG_TRACE_INFO, " bEndpointAddress: 0x%X\n", pEp->bEndpointAddress);
KLogEx(DEBUG_TRACE_INFO, " bmAttributes: 0x%X\n", pEp->bmAttributes);
KLogEx(DEBUG_TRACE_INFO, " wMaxPacketSize: 0x%X\n", pEp->wMaxPacketSize);
KLogEx(DEBUG_TRACE_INFO, " bInterval: 0x%X\n", pEp->bInterval);
}
pCurr += pCommon->bLength;
}
}
// 메모리 정리
if (pDevDesc) ExFreePool(pDevDesc);
if (pConfigDesc) ExFreePool(pConfigDesc);
KLogEx(DEBUG_TRACE_INFO, "===== END USB INFO COLLECTION =====\n");
}
NTSTATUS CollectUsbDeviceInfo( NTSTATUS CollectUsbDeviceInfo(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
OUT PUSB_PARSED_INFO* ppInfo OUT PUSB_PARSED_INFO* ppInfo
@ -369,87 +155,175 @@ NTSTATUS CollectUsbDeviceInfo(
*ppInfo = NULL; *ppInfo = NULL;
if (KeGetCurrentIrql() > APC_LEVEL) if (KeGetCurrentIrql() > APC_LEVEL)
{
KLogEx(DEBUG_TRACE_ERROR, "not APC_LEVEL\n");
return STATUS_INVALID_DEVICE_STATE; return STATUS_INVALID_DEVICE_STATE;
}
// 1. 구조체 할당
pInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_PARSED_INFO), 'INFO'); pInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_PARSED_INFO), 'INFO');
if (!pInfo) return STATUS_INSUFFICIENT_RESOURCES; if (!pInfo) return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory(pInfo, sizeof(USB_PARSED_INFO)); RtlZeroMemory(pInfo, sizeof(USB_PARSED_INFO));
// 2. Device Descriptor 수집
status = GetUsbDeviceDescriptor(DeviceObject, &pDevDesc); status = GetUsbDeviceDescriptor(DeviceObject, &pDevDesc);
if (!NT_SUCCESS(status) || !pDevDesc) { if (!NT_SUCCESS(status) || !pDevDesc)
{
FreeUsbDeviceInfo(pInfo); FreeUsbDeviceInfo(pInfo);
return status; return status;
} }
// 구조체에 복사 후 임시 버퍼 해제
RtlCopyMemory(&pInfo->DeviceDesc, pDevDesc, sizeof(USB_DEVICE_DESCRIPTOR)); RtlCopyMemory(&pInfo->DeviceDesc, pDevDesc, sizeof(USB_DEVICE_DESCRIPTOR));
ExFreePool(pDevDesc); ExFreePool(pDevDesc);
// 3. String Descriptor 수집 (Manufacturer, Product, Serial) // String Descriptor 수집
if (pInfo->DeviceDesc.iManufacturer) { if (pInfo->DeviceDesc.iManufacturer)
GetUsbStringDescriptor(DeviceObject, pInfo->DeviceDesc.iManufacturer, LangId, &pInfo->ManufacturerStr); GetUsbStringDescriptor(DeviceObject, pInfo->DeviceDesc.iManufacturer, LangId, &pInfo->ManufacturerStr);
} if (pInfo->DeviceDesc.iProduct)
if (pInfo->DeviceDesc.iProduct) {
GetUsbStringDescriptor(DeviceObject, pInfo->DeviceDesc.iProduct, LangId, &pInfo->ProductStr); GetUsbStringDescriptor(DeviceObject, pInfo->DeviceDesc.iProduct, LangId, &pInfo->ProductStr);
} if (pInfo->DeviceDesc.iSerialNumber)
if (pInfo->DeviceDesc.iSerialNumber) {
GetUsbStringDescriptor(DeviceObject, pInfo->DeviceDesc.iSerialNumber, LangId, &pInfo->SerialNumberStr); GetUsbStringDescriptor(DeviceObject, pInfo->DeviceDesc.iSerialNumber, LangId, &pInfo->SerialNumberStr);
}
// 4. Configuration Descriptor (Full) 수집
// ConfigDesc는 내부적으로 할당된 메모리를 그대로 포인터로 연결 // Configuration Descriptor (Full) 수집 및 원-패스 파싱
status = GetUsbFullConfigDescriptor(DeviceObject, &pInfo->ConfigDesc); status = GetUsbFullConfigDescriptor(DeviceObject, &pInfo->ConfigDesc);
if (NT_SUCCESS(status) && pInfo->ConfigDesc) if (NT_SUCCESS(status) && pInfo->ConfigDesc)
{ {
pInfo->ConfigDescSize = pInfo->ConfigDesc->wTotalLength; pInfo->ConfigDescSize = pInfo->ConfigDesc->wTotalLength;
PUCHAR pCurr = (PUCHAR)pInfo->ConfigDesc; PUCHAR pCurr = (PUCHAR)pInfo->ConfigDesc;
PUCHAR pEnd = pCurr + pInfo->ConfigDescSize; PUCHAR pEnd = pCurr + pInfo->ConfigDescSize;
LONG currentInterfaceIndex = -1; // 현재 파싱 중인 인터페이스 번호 LONG currentInterfaceIndex = -1;
if (pCurr + sizeof(USB_CONFIGURATION_DESCRIPTOR) < pEnd) if (pCurr + sizeof(USB_CONFIGURATION_DESCRIPTOR) < pEnd)
pCurr += ((PUSB_COMMON_DESCRIPTOR)pCurr)->bLength; pCurr += ((PUSB_COMMON_DESCRIPTOR)pCurr)->bLength;
KLogEx(DEBUG_TRACE_INFO, "[Configuration Descriptor] bNumInterfaces: 0x%X", pInfo->ConfigDesc->bNumInterfaces);
while (pCurr < pEnd) while (pCurr < pEnd)
{ {
PUSB_COMMON_DESCRIPTOR pCommon = (PUSB_COMMON_DESCRIPTOR)pCurr; PUSB_COMMON_DESCRIPTOR pCommon = (PUSB_COMMON_DESCRIPTOR)pCurr;
// 유효성 체크
if (pCommon->bLength == 0 || pCurr + pCommon->bLength > pEnd) if (pCommon->bLength == 0 || pCurr + pCommon->bLength > pEnd)
break; break;
// Interface Descriptor 확인 // =================================================================
if (pCommon->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) { // Interface Descriptor 파싱
// =================================================================
if (pCommon->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
{
PUSB_INTERFACE_DESCRIPTOR pIntf = (PUSB_INTERFACE_DESCRIPTOR)pCommon; PUSB_INTERFACE_DESCRIPTOR pIntf = (PUSB_INTERFACE_DESCRIPTOR)pCommon;
UCHAR cls = pIntf->bInterfaceClass;
UCHAR subCls = pIntf->bInterfaceSubClass;
UCHAR proto = pIntf->bInterfaceProtocol;
KLogEx(DEBUG_TRACE_INFO, "[Interface Descriptor] bInterfaceNumber: 0x%X, bAlternateSetting: 0x%X, bNumEndpoints: 0x%X, bInterfaceClass: 0x%X, bInterfaceSubClass: 0x%X, bInterfaceProtocol: 0x%X",
pIntf->bInterfaceNumber,
pIntf->bAlternateSetting,
pIntf->bNumEndpoints,
pIntf->bInterfaceClass,
pIntf->bInterfaceSubClass,
pIntf->bInterfaceProtocol
);
currentInterfaceIndex = pIntf->bInterfaceNumber; currentInterfaceIndex = pIntf->bInterfaceNumber;
pInfo->FoundClassCount++;
if (pInfo->FoundClassCount > 1)
pInfo->IsCompositeDevice = TRUE;
switch (cls)
{
case 0x01: pInfo->IsAudio = TRUE; break;
case 0x02: pInfo->IsCDC = TRUE; break;
case 0x06:
case 0x0E: pInfo->IsImageOrVideo = TRUE; break;
case 0x07: pInfo->IsPrinter = TRUE; break;
case 0x08: pInfo->IsMassStorage = TRUE; break;
case 0x09: pInfo->IsHub = TRUE; break;
case 0x03: // HID (키보드, 마우스, 기타)
if (subCls == 0x01)
{
if (proto == 0x01) pInfo->IsBootKeyboard = TRUE;
else if (proto == 0x02) pInfo->IsBootMouse = TRUE;
else pInfo->IsAbnormalHID = TRUE;
}
else if (subCls == 0x00)
{
pInfo->IsCustomHID = TRUE;
}
else
{
pInfo->IsAbnormalHID = TRUE;
}
if (!pInfo->IsBootKeyboard && !pInfo->IsBootMouse)
{
pInfo->OtherHidSubClass = subCls;
pInfo->OtherHidProtocol = proto;
}
break;
}
} }
// [B] HID Descriptor 발견 (0x21) // =================================================================
// Endpoint Descriptor 파싱 (BadUSB 위협 분석용)
// =================================================================
else if (pCommon->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE)
{
PUSB_ENDPOINT_DESCRIPTOR pEp = (PUSB_ENDPOINT_DESCRIPTOR)pCommon;
UCHAR epType = pEp->bmAttributes & 0x03; // USB_ENDPOINT_TYPE_MASK
KLogEx(DEBUG_TRACE_INFO, "[Endpoint Descriptor] bEndpointAddress: 0x%X, bmAttributes: 0x%X, wMaxPacketSize: 0x%X, bInterval: 0x%X\n",
pEp->bEndpointAddress,
pEp->bmAttributes,
pEp->wMaxPacketSize,
pEp->bInterval
);
pInfo->TotalEndpoints++;
if (epType == USB_ENDPOINT_TYPE_INTERRUPT)
{
pInfo->InterruptEndpoints++;
}
else if (epType == USB_ENDPOINT_TYPE_BULK)
{
pInfo->BulkEndpoints++;
}
}
// =================================================================
// [C] HID Descriptor 별도 보관 (필요 시 Report 분석용)
// =================================================================
else if (pCommon->bDescriptorType == USB_DESCRIPTOR_TYPE_HID) else if (pCommon->bDescriptorType == USB_DESCRIPTOR_TYPE_HID)
{ {
PUSB_HID_DESCRIPTOR pHid = (PUSB_HID_DESCRIPTOR)pCommon; PUSB_HID_DESCRIPTOR pHid = (PUSB_HID_DESCRIPTOR)pCommon;
// 저장 공간이 있고, 유효한 인터페이스 내부에 있는 경우
if (pInfo->HidInterfaceCount < MAX_HID_INTERFACES && currentInterfaceIndex >= 0) if (pInfo->HidInterfaceCount < MAX_HID_INTERFACES && currentInterfaceIndex >= 0)
{ {
ULONG idx = pInfo->HidInterfaceCount; ULONG idx = pInfo->HidInterfaceCount;
pInfo->HidEntries[idx].InterfaceNumber = (UCHAR)currentInterfaceIndex; pInfo->HidEntries[idx].InterfaceNumber = (UCHAR)currentInterfaceIndex;
pInfo->HidEntries[idx].HidDesc = pHid; pInfo->HidEntries[idx].HidDesc = pHid;
pInfo->HidInterfaceCount++; pInfo->HidInterfaceCount++;
KLogEx(DEBUG_TRACE_INFO, " Found HID Desc at Interface %d (Count: %d)\n",
currentInterfaceIndex, pInfo->HidInterfaceCount);
} }
} }
pCurr += pCommon->bLength; pCurr += pCommon->bLength;
} }
// =================================================================
// [결론] 최종 BadUSB 휴리스틱 판별 (루프 종료 후)
// =================================================================
// 1. Bulk와 Interrupt가 혼용되었는지 (아이폰, 프린터 등 복합장치 특성)
if (pInfo->InterruptEndpoints > 0 && pInfo->BulkEndpoints > 0)
{
pInfo->HasMixedEndpoints = TRUE;
}
BOOLEAN hasHID = pInfo->IsBootKeyboard || pInfo->IsBootMouse;
BOOLEAN hasBothHID = pInfo->IsBootKeyboard && pInfo->IsBootMouse;
// 2. 최종 판별 로직 (안전한 신형 로직 적용)
// 조건: 자기가 키보드나 마우스라고 주장하는데, 아래 중 하나라도 해당하면 BadUSB로 차단!
// - 키보드와 마우스가 동시에 존재 (해커들이 자주 씀)
// - 인터럽트 엔드포인트가 3개 이상으로 비정상적으로 많음
// - 엔드포인트가 전혀 없음 (가짜 장치)
// - 키보드라면서 대용량 전송용 BULK 엔드포인트가 섞여 있음
if (hasBothHID || (hasHID && (pInfo->InterruptEndpoints >= 3 || pInfo->TotalEndpoints == 0 || pInfo->HasMixedEndpoints)))
{
pInfo->IsBadUSB = TRUE;
KLogEx(DEBUG_TRACE_ERROR, "[!!!] MALICIOUS BAD-USB DETECTED! (IntEps: %d, BulkEps: %d)\n",
pInfo->InterruptEndpoints, pInfo->BulkEndpoints);
}
} }
else else
{ {
@ -457,7 +331,53 @@ NTSTATUS CollectUsbDeviceInfo(
pInfo->ConfigDescSize = 0; pInfo->ConfigDescSize = 0;
} }
// 성공 시 포인터 반환
*ppInfo = pInfo; *ppInfo = pInfo;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
VOID PrintUsbParsedInfo(IN PUSB_PARSED_INFO pInfo)
{
if (!pInfo)
{
KLogEx(DEBUG_TRACE_ERROR, "[-] PrintUsbParsedInfo: pInfo is NULL\n");
return;
}
// HID 정보 출력
if (pInfo->IsBootKeyboard) KLogEx(DEBUG_TRACE_INFO, " - IsBootKeyboard : TRUE\n");
if (pInfo->IsBootMouse) KLogEx(DEBUG_TRACE_INFO, " - IsBootMouse : TRUE\n");
if (pInfo->IsCustomHID) KLogEx(DEBUG_TRACE_INFO, " - IsCustomHID : TRUE\n");
if (pInfo->IsAbnormalHID) KLogEx(DEBUG_TRACE_INFO, " - IsAbnormalHID : TRUE\n");
// 기타 HID일 경우에만 서브클래스와 프로토콜 값을 출력
if (pInfo->IsCustomHID || pInfo->IsAbnormalHID) {
KLogEx(DEBUG_TRACE_INFO, " > OtherHidSubClass : 0x%02X\n", pInfo->OtherHidSubClass);
KLogEx(DEBUG_TRACE_INFO, " > OtherHidProtocol : 0x%02X\n", pInfo->OtherHidProtocol);
}
// 디바이스 클래스 정보 출력
if (pInfo->IsMassStorage) KLogEx(DEBUG_TRACE_INFO, " - IsMassStorage : TRUE\n");
if (pInfo->IsAudio) KLogEx(DEBUG_TRACE_INFO, " - IsAudio : TRUE\n");
if (pInfo->IsPrinter) KLogEx(DEBUG_TRACE_INFO, " - IsPrinter : TRUE\n");
if (pInfo->IsImageOrVideo) KLogEx(DEBUG_TRACE_INFO, " - IsImageOrVideo : TRUE\n");
if (pInfo->IsHub) KLogEx(DEBUG_TRACE_INFO, " - IsHub : TRUE\n");
if (pInfo->IsCDC) KLogEx(DEBUG_TRACE_INFO, " - IsCDC : TRUE\n");
if (pInfo->IsCompositeDevice) KLogEx(DEBUG_TRACE_INFO, " - IsCompositeDevice : TRUE\n");
KLogEx(DEBUG_TRACE_INFO, " - FoundClassCount : %lu\n", pInfo->FoundClassCount);
// 3. BadUSB 및 엔드포인트 정보 출력
KLogEx(DEBUG_TRACE_INFO, "\n[BadUSB & Endpoint Information]\n");
KLogEx(DEBUG_TRACE_INFO, " - TotalEndpoints : %lu\n", pInfo->TotalEndpoints);
KLogEx(DEBUG_TRACE_INFO, " - InterruptEndpoints : %lu\n", pInfo->InterruptEndpoints);
KLogEx(DEBUG_TRACE_INFO, " - BulkEndpoints : %lu\n", pInfo->BulkEndpoints);
if (pInfo->HasMixedEndpoints)
KLogEx(DEBUG_TRACE_INFO, " - HasMixedEndpoints : TRUE\n");
// BadUSB 탐지 여부는 눈에 잘 띄게 출력
if (pInfo->IsBadUSB) {
KLogEx(DEBUG_TRACE_INFO, " - IsBadUSB : *** TRUE (MALICIOUS DEVICE DETECTED!) ***\n");
}
}

View File

@ -28,20 +28,50 @@ typedef struct _HID_INTERFACE_ENTRY {
PUSB_HID_DESCRIPTOR HidDesc; // HID Descriptor 포인터 (ConfigDesc 내부 위치) PUSB_HID_DESCRIPTOR HidDesc; // HID Descriptor 포인터 (ConfigDesc 내부 위치)
} HID_INTERFACE_ENTRY, * PHID_INTERFACE_ENTRY; } HID_INTERFACE_ENTRY, * PHID_INTERFACE_ENTRY;
// USB 정보를 담을 구조체 정의
typedef struct _USB_PARSED_INFO { typedef struct _USB_PARSED_INFO {
// 1. Device Descriptor (VendorID, ProductID 등)
USB_DEVICE_DESCRIPTOR DeviceDesc; USB_DEVICE_DESCRIPTOR DeviceDesc;
// 2. String Descriptors (사람이 읽을 수 있는 문자열) PWCHAR ManufacturerStr;
PWCHAR ManufacturerStr; // 제조사 (NULL일 수 있음) PWCHAR ProductStr;
PWCHAR ProductStr; // 제품명 (NULL일 수 있음) PWCHAR SerialNumberStr;
PWCHAR SerialNumberStr; // 시리얼 번호 (NULL일 수 있음)
// 3. Configuration Descriptor (Interface, Endpoint 포함된 전체 Blob)
PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc; PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc;
ULONG ConfigDescSize; ULONG ConfigDescSize;
// -----------------------------------------
// 1. [CC 인증 요구사항] HID 상세 분류 플래그
// -----------------------------------------
BOOLEAN IsBootKeyboard; // 완벽한 표준 키보드 (SubClass 1, Protocol 1)
BOOLEAN IsBootMouse; // 완벽한 표준 마우스 (SubClass 1, Protocol 2)
BOOLEAN IsCustomHID; // 기타 커스텀 HID (SubClass 0, Protocol 0 - 바코드, 터치 등)
BOOLEAN IsAbnormalHID; // 스펙에 맞지 않는 비정상 HID
UCHAR OtherHidSubClass;
UCHAR OtherHidProtocol;
// -----------------------------------------
// 2. [매체 제어 요구사항] 주요 디바이스 클래스
// -----------------------------------------
BOOLEAN IsMassStorage; // 0x08: USB 메모리, 외장하드
BOOLEAN IsAudio; // 0x01: USB 스피커, 헤드셋
BOOLEAN IsPrinter; // 0x07: USB 프린터
BOOLEAN IsImageOrVideo; // 0x06 (Image), 0x0E (Video): 웹캠, 스마트폰 MTP 일부
BOOLEAN IsHub; // 0x09: USB 허브
BOOLEAN IsCDC; // 0x02: 통신 장치 (스마트폰 테더링, 가상 시리얼)
BOOLEAN IsCompositeDevice; // 복합 장치 여부
ULONG FoundClassCount; // 발견된 고유 인터페이스 개수
// -----------------------------------------
// 3. [안티 해킹] BadUSB 탐지용 카운터 및 플래그
// -----------------------------------------
ULONG TotalEndpoints; // 전체 엔드포인트 개수
ULONG InterruptEndpoints; // 인터럽트 엔드포인트 개수
ULONG BulkEndpoints; // 대용량 전송 엔드포인트 개수
BOOLEAN HasMixedEndpoints; // Bulk와 Interrupt가 섞여 있는지 여부 (구형 CheckBADUSB 아이디어)
BOOLEAN IsBadUSB; // 최종 BadUSB 확정 플래그 (TRUE면 차단)
// HID 부가 정보 보관용
ULONG HidInterfaceCount; ULONG HidInterfaceCount;
HID_INTERFACE_ENTRY HidEntries[MAX_HID_INTERFACES]; HID_INTERFACE_ENTRY HidEntries[MAX_HID_INTERFACES];
@ -50,4 +80,4 @@ typedef struct _USB_PARSED_INFO {
// 함수 원형 선언 // 함수 원형 선언
NTSTATUS CollectUsbDeviceInfo(IN PDEVICE_OBJECT DeviceObject, OUT PUSB_PARSED_INFO* ppInfo); NTSTATUS CollectUsbDeviceInfo(IN PDEVICE_OBJECT DeviceObject, OUT PUSB_PARSED_INFO* ppInfo);
VOID FreeUsbDeviceInfo(IN PUSB_PARSED_INFO pInfo); VOID FreeUsbDeviceInfo(IN PUSB_PARSED_INFO pInfo);
VOID PrintUsbParsedInfo(IN PUSB_PARSED_INFO pInfo);

View File

@ -261,105 +261,107 @@ NTSTATUS USBPnpControl(PDRIVER_DISPATCH dispath, PDEVICE_OBJECT DeviceObject, PI
goto $USBCleanup; goto $USBCleanup;
} }
if (pUsbInfo->ProductStr) //if (pUsbInfo->ProductStr)
{ //{
KLogEx(DEBUG_TRACE_INFO, " Product: %S\n", pUsbInfo->ProductStr); // KLogEx(DEBUG_TRACE_INFO, " Product: %S\n", pUsbInfo->ProductStr);
} //}
if (pUsbInfo->SerialNumberStr) if (pUsbInfo->SerialNumberStr)
{ {
KLogEx(DEBUG_TRACE_INFO, " Serial: %S\n", pUsbInfo->SerialNumberStr); KLogEx(DEBUG_TRACE_INFO, " Serial: %S\n", pUsbInfo->SerialNumberStr);
} }
if (pUsbInfo->ConfigDesc && pUsbInfo->ConfigDescSize > 0) PrintUsbParsedInfo(pUsbInfo);
{
PUSB_CONFIGURATION_DESCRIPTOR pConfigDesc = pUsbInfo->ConfigDesc;
PUCHAR pCurr = (PUCHAR)pConfigDesc;
PUCHAR pEnd = pCurr + pConfigDesc->wTotalLength;
KLogEx(DEBUG_TRACE_INFO, "[Configuration Descriptor]"); //if (pUsbInfo->ConfigDesc && pUsbInfo->ConfigDescSize > 0)
KLogEx(DEBUG_TRACE_INFO, " wTotalLength: 0x%X, bNumInterfaces: 0x%X, bConfigurationValue: 0x%X, MaxPower: 0x%X\n", //{
pConfigDesc->wTotalLength, // PUSB_CONFIGURATION_DESCRIPTOR pConfigDesc = pUsbInfo->ConfigDesc;
pConfigDesc->bNumInterfaces, // PUCHAR pCurr = (PUCHAR)pConfigDesc;
pConfigDesc->bConfigurationValue, // PUCHAR pEnd = pCurr + pConfigDesc->wTotalLength;
pConfigDesc->MaxPower
);
// Loop를 돌면서 Interface 및 Endpoint 파싱 // KLogEx(DEBUG_TRACE_INFO, "[Configuration Descriptor]");
// 첫 번째 Descriptor는 Configuration이므로 건너뜀 // KLogEx(DEBUG_TRACE_INFO, " wTotalLength: 0x%X, bNumInterfaces: 0x%X, bConfigurationValue: 0x%X, MaxPower: 0x%X\n",
pCurr += pConfigDesc->bLength; // pConfigDesc->wTotalLength,
// pConfigDesc->bNumInterfaces,
// pConfigDesc->bConfigurationValue,
// pConfigDesc->MaxPower
// );
//
// // Loop를 돌면서 Interface 및 Endpoint 파싱
// // 첫 번째 Descriptor는 Configuration이므로 건너뜀
// pCurr += pConfigDesc->bLength;
while (pCurr < pEnd) // while (pCurr < pEnd)
{ // {
PUSB_COMMON_DESCRIPTOR pCommon = (PUSB_COMMON_DESCRIPTOR)pCurr; // PUSB_COMMON_DESCRIPTOR pCommon = (PUSB_COMMON_DESCRIPTOR)pCurr;
if (pCommon->bLength == 0) // if (pCommon->bLength == 0)
break; // 에러 방지 // break; // 에러 방지
if (pCommon->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) // if (pCommon->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
{ // {
PUSB_INTERFACE_DESCRIPTOR pIntf = (PUSB_INTERFACE_DESCRIPTOR)pCommon; // PUSB_INTERFACE_DESCRIPTOR pIntf = (PUSB_INTERFACE_DESCRIPTOR)pCommon;
KLogEx(DEBUG_TRACE_INFO, "[Interface Descriptor]"); // KLogEx(DEBUG_TRACE_INFO, "[Interface Descriptor]");
KLogEx(DEBUG_TRACE_INFO, " bInterfaceNumber: 0x%X, bAlternateSetting: 0x%X, bNumEndpoints: 0x%X, bInterfaceClass: 0x%X, bInterfaceSubClass: 0x%X, bInterfaceProtocol: 0x%X", // KLogEx(DEBUG_TRACE_INFO, " bInterfaceNumber: 0x%X, bAlternateSetting: 0x%X, bNumEndpoints: 0x%X, bInterfaceClass: 0x%X, bInterfaceSubClass: 0x%X, bInterfaceProtocol: 0x%X",
pIntf->bInterfaceNumber, // pIntf->bInterfaceNumber,
pIntf->bAlternateSetting, // pIntf->bAlternateSetting,
pIntf->bNumEndpoints, // pIntf->bNumEndpoints,
pIntf->bInterfaceClass, // pIntf->bInterfaceClass,
pIntf->bInterfaceSubClass, // pIntf->bInterfaceSubClass,
pIntf->bInterfaceProtocol // pIntf->bInterfaceProtocol
); // );
} // }
else if (pCommon->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE) // else if (pCommon->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE)
{ // {
PUSB_ENDPOINT_DESCRIPTOR pEp = (PUSB_ENDPOINT_DESCRIPTOR)pCommon; // PUSB_ENDPOINT_DESCRIPTOR pEp = (PUSB_ENDPOINT_DESCRIPTOR)pCommon;
KLogEx(DEBUG_TRACE_INFO, "[Endpoint Descriptor]\n"); // KLogEx(DEBUG_TRACE_INFO, "[Endpoint Descriptor]\n");
KLogEx(DEBUG_TRACE_INFO, " bEndpointAddress: 0x%X, bmAttributes: 0x%X, wMaxPacketSize: 0x%X, bInterval: 0x%X\n", // KLogEx(DEBUG_TRACE_INFO, " bEndpointAddress: 0x%X, bmAttributes: 0x%X, wMaxPacketSize: 0x%X, bInterval: 0x%X\n",
pEp->bEndpointAddress, // pEp->bEndpointAddress,
pEp->bmAttributes, // pEp->bmAttributes,
pEp->wMaxPacketSize, // pEp->wMaxPacketSize,
pEp->bInterval // pEp->bInterval
); // );
} // }
pCurr += pCommon->bLength; // pCurr += pCommon->bLength;
} // }
} //}
if (pUsbInfo->HidInterfaceCount > 0) //if (pUsbInfo->HidInterfaceCount > 0)
{ //{
ULONG i; // ULONG i;
KLogEx(DEBUG_TRACE_INFO, " Total HID Interfaces Found: %d\n", pUsbInfo->HidInterfaceCount); // KLogEx(DEBUG_TRACE_INFO, " Total HID Interfaces Found: %d\n", pUsbInfo->HidInterfaceCount);
for (i = 0; i < pUsbInfo->HidInterfaceCount; i++) // for (i = 0; i < pUsbInfo->HidInterfaceCount; i++)
{ // {
HID_INTERFACE_ENTRY* pEntry = &pUsbInfo->HidEntries[i]; // HID_INTERFACE_ENTRY* pEntry = &pUsbInfo->HidEntries[i];
PUSB_HID_DESCRIPTOR pHid = pEntry->HidDesc; // PUSB_HID_DESCRIPTOR pHid = pEntry->HidDesc;
KLogEx(DEBUG_TRACE_INFO, " [HID Interface #%d]\n", pEntry->InterfaceNumber); // KLogEx(DEBUG_TRACE_INFO, " [HID Interface #%d]\n", pEntry->InterfaceNumber);
if (pHid) // if (pHid)
{ // {
KLogEx(DEBUG_TRACE_INFO, " bcdHID: 0x%04X\n", pHid->bcdHID); // KLogEx(DEBUG_TRACE_INFO, " bcdHID: 0x%04X\n", pHid->bcdHID);
KLogEx(DEBUG_TRACE_INFO, " Report Descs: %d\n", pHid->bNumDescriptors); // KLogEx(DEBUG_TRACE_INFO, " Report Descs: %d\n", pHid->bNumDescriptors);
if (pHid->bNumDescriptors > 0) // if (pHid->bNumDescriptors > 0)
{ // {
KLogEx(DEBUG_TRACE_INFO, " Desc Length: %d\n", pHid->DescriptorList[0].wDescriptorLength); // KLogEx(DEBUG_TRACE_INFO, " Desc Length: %d\n", pHid->DescriptorList[0].wDescriptorLength);
} // }
} // }
} // }
// 예시: 1번 인터페이스가 HID라면 차단? // // 예시: 1번 인터페이스가 HID라면 차단?
/* // /*
for (i = 0; i < pUsbInfo->HidInterfaceCount; i++) { // for (i = 0; i < pUsbInfo->HidInterfaceCount; i++) {
if (pUsbInfo->HidEntries[i].InterfaceNumber == 1) { // if (pUsbInfo->HidEntries[i].InterfaceNumber == 1) {
bBlock = TRUE; // bBlock = TRUE;
} // }
} // }
*/ // */
} //}
else //else
{ //{
KLogEx(DEBUG_TRACE_INFO, " No HID Interfaces found.\n"); // KLogEx(DEBUG_TRACE_INFO, " No HID Interfaces found.\n");
} //}
} }
if (state == DISABLE && pUsbInfo) if (state == DISABLE && pUsbInfo)

View File

@ -723,6 +723,103 @@ UGetIoOpenDriverRegistryKey(
return pIoOpenDriverRegistryKey; return pIoOpenDriverRegistryKey;
} }
//NTSTATUS
//UOpenServiceParametersKey(
// _In_ PUNICODE_STRING RegistryPath,
// _Out_ PHANDLE ServiceParametersKey
//)
//{
// NTSTATUS Status;
// HANDLE ServiceKey = NULL;
// HANDLE ParametersKey = NULL;
// OBJECT_ATTRIBUTES Attributes;
// UNICODE_STRING SubKeyName;
//
// // 1. 서비스 루트 키 열기 (\Registry\...\bs1flt)
// InitializeObjectAttributes(&Attributes,
// RegistryPath,
// OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
// NULL,
// NULL);
//
// Status = ZwOpenKey(&ServiceKey, KEY_READ, &Attributes);
// if (!NT_SUCCESS(Status)) {
// return Status;
// }
//
// // 2. "Parameters" 서브 키 열기
// RtlInitUnicodeString(&SubKeyName, L"Parameters");
// InitializeObjectAttributes(&Attributes,
// &SubKeyName,
// OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
// ServiceKey,
// NULL);
//
// Status = ZwOpenKey(&ParametersKey, KEY_READ, &Attributes);
//
// // 3. 서비스 루트 키는 이제 필요 없으므로 닫음
// ZwClose(ServiceKey);
//
// if (NT_SUCCESS(Status)) {
// *ServiceParametersKey = ParametersKey;
// }
//
// return Status;
//}
/////NTSTATUS USetConfiguration(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath);
//NTSTATUS
//USetConfiguration(
// _In_ PUNICODE_STRING RegistryPath // DriverObject는 필요 없음
//)
//{
// NTSTATUS status;
// HANDLE settingsKey = NULL;
// UNICODE_STRING valueName;
//
// // 버퍼 크기를 넉넉하게 잡음 (데이터가 ULONG이 아닐 수도 있으므로)
// UCHAR buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
// PKEY_VALUE_PARTIAL_INFORMATION value = (PKEY_VALUE_PARTIAL_INFORMATION)buffer;
// ULONG resultLength;
//
// // 1. Parameters 키 열기
// status = UOpenServiceParametersKey(RegistryPath, &settingsKey);
// if (!NT_SUCCESS(status)) {
// return STATUS_SUCCESS;
// }
//
// // 2. DebugLevel 값 읽기
// RtlInitUnicodeString(&valueName, L"DebugLevel");
// status = ZwQueryValueKey(settingsKey,
// &valueName,
// KeyValuePartialInformation,
// value,
// sizeof(buffer),
// &resultLength);
//
// if (NT_SUCCESS(status) && value->Type == REG_DWORD) {
// // 전역 변수 설정 (extern 선언 필요)
// g_DebugLevel = *(PULONG)value->Data;
// }
//
// // 3. ProcessCreate 값 읽기
// RtlInitUnicodeString(&valueName, L"ProcessCreate");
// status = ZwQueryValueKey(settingsKey,
// &valueName,
// KeyValuePartialInformation,
// value,
// sizeof(buffer),
// &resultLength);
//
// if (NT_SUCCESS(status) && value->Type == REG_DWORD) {
// g_bs1Flt.IsProcessCreate = *(PULONG)value->Data;
// }
//
// // 4. 핸들 닫기 (필수)
// ZwClose(settingsKey);
//
// return STATUS_SUCCESS;
//}
NTSTATUS NTSTATUS
UOpenServiceParametersKey( UOpenServiceParametersKey(
_In_ PUNICODE_STRING RegistryPath, _In_ PUNICODE_STRING RegistryPath,
@ -735,7 +832,7 @@ UOpenServiceParametersKey(
OBJECT_ATTRIBUTES Attributes; OBJECT_ATTRIBUTES Attributes;
UNICODE_STRING SubKeyName; UNICODE_STRING SubKeyName;
// 1. 서비스 루트 키 열기 (\Registry\...\bs1flt) // 1. 서비스 루트 키 열기
InitializeObjectAttributes(&Attributes, InitializeObjectAttributes(&Attributes,
RegistryPath, RegistryPath,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
@ -744,6 +841,7 @@ UOpenServiceParametersKey(
Status = ZwOpenKey(&ServiceKey, KEY_READ, &Attributes); Status = ZwOpenKey(&ServiceKey, KEY_READ, &Attributes);
if (!NT_SUCCESS(Status)) { if (!NT_SUCCESS(Status)) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[MGKIM] Failed to open Service Root Key (0x%X)\n", Status);
return Status; return Status;
} }
@ -757,37 +855,40 @@ UOpenServiceParametersKey(
Status = ZwOpenKey(&ParametersKey, KEY_READ, &Attributes); Status = ZwOpenKey(&ParametersKey, KEY_READ, &Attributes);
// 3. 서비스 루트 키는 이제 필요 없으므로 닫음 // 3. 서비스 루트 키 닫기
ZwClose(ServiceKey); ZwClose(ServiceKey);
if (NT_SUCCESS(Status)) { if (NT_SUCCESS(Status)) {
*ServiceParametersKey = ParametersKey; *ServiceParametersKey = ParametersKey;
} }
else {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[MGKIM] Failed to open 'Parameters' SubKey (0x%X)\n", Status);
}
return Status; return Status;
} }
///NTSTATUS USetConfiguration(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath);
NTSTATUS NTSTATUS
USetConfiguration( USetConfiguration(
_In_ PUNICODE_STRING RegistryPath // DriverObject는 필요 없음 _In_ PUNICODE_STRING RegistryPath
) )
{ {
NTSTATUS status; NTSTATUS status;
HANDLE settingsKey = NULL; HANDLE settingsKey = NULL;
UNICODE_STRING valueName; UNICODE_STRING valueName;
// 버퍼 크기를 넉넉하게 잡음 (데이터가 ULONG이 아닐 수도 있으므로) ULONG buffer[32] = { 0 };
UCHAR buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
PKEY_VALUE_PARTIAL_INFORMATION value = (PKEY_VALUE_PARTIAL_INFORMATION)buffer; PKEY_VALUE_PARTIAL_INFORMATION value = (PKEY_VALUE_PARTIAL_INFORMATION)buffer;
ULONG resultLength; ULONG resultLength;
// 1. Parameters 키 열기 // Parameters 키 열기
status = UOpenServiceParametersKey(RegistryPath, &settingsKey); status = UOpenServiceParametersKey(RegistryPath, &settingsKey);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status))
return STATUS_SUCCESS; {
return status;
} }
// 2. DebugLevel 값 읽기 // DebugLevel 값 읽기
RtlInitUnicodeString(&valueName, L"DebugLevel"); RtlInitUnicodeString(&valueName, L"DebugLevel");
status = ZwQueryValueKey(settingsKey, status = ZwQueryValueKey(settingsKey,
&valueName, &valueName,
@ -796,12 +897,17 @@ USetConfiguration(
sizeof(buffer), sizeof(buffer),
&resultLength); &resultLength);
if (NT_SUCCESS(status) && value->Type == REG_DWORD) { if (NT_SUCCESS(status) && value->Type == REG_DWORD)
// 전역 변수 설정 (extern 선언 필요) {
g_DebugLevel = *(PULONG)value->Data; g_DebugLevel = *((PULONG)value->Data);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "%s:%s: DebugLevel loaded: %d\n", DRIVERNAMEA, __FUNCTION__, g_DebugLevel);
}
else
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "%s:%s: ZwQueryValueKey failed for DebugLevel (0x%X)\n", DRIVERNAMEA, __FUNCTION__, status);
} }
// 3. ProcessCreate 값 읽기 // ProcessCreate 값 읽기
RtlInitUnicodeString(&valueName, L"ProcessCreate"); RtlInitUnicodeString(&valueName, L"ProcessCreate");
status = ZwQueryValueKey(settingsKey, status = ZwQueryValueKey(settingsKey,
&valueName, &valueName,
@ -810,11 +916,17 @@ USetConfiguration(
sizeof(buffer), sizeof(buffer),
&resultLength); &resultLength);
if (NT_SUCCESS(status) && value->Type == REG_DWORD) { if (NT_SUCCESS(status) && value->Type == REG_DWORD)
g_bs1Flt.IsProcessCreate = *(PULONG)value->Data; {
g_bs1Flt.IsProcessCreate = *((PULONG)value->Data);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "%s:%s: ProcessCreate loaded: %d\n", DRIVERNAMEA, __FUNCTION__, g_bs1Flt.IsProcessCreate);
}
else
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "%s:%s: ZwQueryValueKey failed for ProcessCreate (0x%X)\n", DRIVERNAMEA, __FUNCTION__, status);
} }
// 4. 핸들 닫기 (필수) // 핸들 닫기
ZwClose(settingsKey); ZwClose(settingsKey);
return STATUS_SUCCESS; return STATUS_SUCCESS;

View File

@ -6,7 +6,8 @@
#pragma warning(disable : 4995) #pragma warning(disable : 4995)
#undef NTDDI_VERSION
#define NTDDI_VERSION 0x0A00000A
#include <fltKernel.h> #include <fltKernel.h>
#include <dontuse.h> #include <dontuse.h>
#include <suppress.h> #include <suppress.h>
@ -95,7 +96,7 @@ do { \
{ \ { \
DbgPrintEx( \ DbgPrintEx( \
DPFLTR_IHVDRIVER_ID, \ DPFLTR_IHVDRIVER_ID, \
DPFLTR_ERROR_LEVEL, \ DPFLTR_INFO_LEVEL, \
"%s:%s: " Format, \ "%s:%s: " Format, \
DRIVERNAMEA, \ DRIVERNAMEA, \
__FUNCTION__, \ __FUNCTION__, \

View File

@ -93,9 +93,9 @@ int CLocalConf::GetConfig(const char* filename, DWORD pid)
debug_type = GetJsonUint32("bs1flt", debug); debug_type = GetJsonUint32("bs1flt", debug);
bs1fltkernel = GetJsonUint32("bs1fltkernel", debug); bs1fltkernel = GetJsonUint32("bs1fltkernel", debug);
/*char debugporint[100] = { 0, }; char debugporint[100] = { 0, };
sprintf_s(debugporint, sizeof(debugporint), "debug_type(%d), bs1fltkernel(%d)", debug_type, bs1fltkernel); sprintf_s(debugporint, sizeof(debugporint), "[BS1] debug_type(%d), bs1fltkernel(%d)", debug_type, bs1fltkernel);
OutputDebugStringA(debugporint);*/ OutputDebugStringA(debugporint);
stream.close(); stream.close();
} }
else else

View File

@ -637,16 +637,16 @@ void CtoolDlg::OnBnClickedButtonSetPolicy()
if ((DWORD)policy[i].device_type == BDC_USB && policy[i].state == DISABLE) if ((DWORD)policy[i].device_type == BDC_USB && policy[i].state == DISABLE)
{ {
bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_UNSPECIFIED, DISABLE); //bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_UNSPECIFIED, DISABLE);
bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_CDC, DISABLE); //bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_CDC, DISABLE);
bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_HID, ENABLE); //bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_HID, ENABLE);
bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_AUDIO, DISABLE); //bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_AUDIO, DISABLE);
bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_PHYSICAL, DISABLE); //bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_PHYSICAL, DISABLE);
bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_IMAGE, DISABLE); //bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_IMAGE, DISABLE);
bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_PRINTER, DISABLE); //bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_PRINTER, DISABLE);
bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_MSC, DISABLE); //bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_MSC, DISABLE);
bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_CDC_DATA, DISABLE); //bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_CDC_DATA, DISABLE);
bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_SMART_CARD, DISABLE); //bs1flt_.Bs1fltSetUsbPolicy((DWORD)BDC_USB_CLASS_SMART_CARD, DISABLE);
debug.Format(L"SetPolicy : ReStartUsb"); debug.Format(L"SetPolicy : ReStartUsb");
CloseHandle(CreateThread(NULL, 0, ReStartUsb, NULL, 0, NULL)); CloseHandle(CreateThread(NULL, 0, ReStartUsb, NULL, 0, NULL));

View File

@ -5,7 +5,7 @@
<FrameworkType>VCL</FrameworkType> <FrameworkType>VCL</FrameworkType>
<Base>True</Base> <Base>True</Base>
<Config Condition="'$(Config)'==''">Release</Config> <Config Condition="'$(Config)'==''">Release</Config>
<Platform Condition="'$(Platform)'==''">Win64</Platform> <Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>3</TargetedPlatforms> <TargetedPlatforms>3</TargetedPlatforms>
<AppType>Library</AppType> <AppType>Library</AppType>
<MainSource>eCrmHeHelper.dpr</MainSource> <MainSource>eCrmHeHelper.dpr</MainSource>
@ -135,10 +135,12 @@
<DCC_RemoteDebug>false</DCC_RemoteDebug> <DCC_RemoteDebug>false</DCC_RemoteDebug>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale> <VerInfo_Locale>1033</VerInfo_Locale>
<DCC_MapFile>3</DCC_MapFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''"> <PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale> <VerInfo_Locale>1033</VerInfo_Locale>
<DCC_MapFile>3</DCC_MapFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''"> <PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols> <DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
@ -156,6 +158,8 @@ $(PostBuildEvent)]]></PostBuildEvent>
<DCC_MapFile>3</DCC_MapFile> <DCC_MapFile>3</DCC_MapFile>
<DCC_DebugInformation>2</DCC_DebugInformation> <DCC_DebugInformation>2</DCC_DebugInformation>
<DCC_LocalDebugSymbols>true</DCC_LocalDebugSymbols> <DCC_LocalDebugSymbols>true</DCC_LocalDebugSymbols>
<VerInfo_Build>1</VerInfo_Build>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.1;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.1;Comments=</VerInfo_Keys>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win64)'!=''"> <PropertyGroup Condition="'$(Cfg_2_Win64)'!=''">
<PostBuildEvent><![CDATA[copy "$(OUTPUTPATH)" "$(OUTPUTDIR)\conf\$(OUTPUTFILENAME)" <PostBuildEvent><![CDATA[copy "$(OUTPUTPATH)" "$(OUTPUTDIR)\conf\$(OUTPUTFILENAME)"

View File

@ -1,20 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<BorlandProject> <BorlandProject>
<Transactions> <Transactions>
<Transaction>1899-12-30 00:00:00.000.581,=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\ObexParserUnit.pas</Transaction>
<Transaction>1899-12-30 00:00:00.000.934,C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\ObexParserUnit.pas=</Transaction> <Transaction>1899-12-30 00:00:00.000.934,C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\ObexParserUnit.pas=</Transaction>
<Transaction>1899-12-30 00:00:00.000.033,=C:\mgkim\8.bsone\BSOne.SFC\eCrmHE\DLL_eCrmHeHelper\WindowFinderThread.pas</Transaction>
<Transaction>1899-12-30 00:00:00.000.361,=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\ObexParserUnit.pas</Transaction> <Transaction>1899-12-30 00:00:00.000.361,=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\ObexParserUnit.pas</Transaction>
<Transaction>1899-12-30 00:00:00.000.033,=C:\mgkim\8.bsone\BSOne.SFC\eCrmHE\DLL_eCrmHeHelper\WindowFinderThread.pas</Transaction>
<Transaction>1899-12-30 00:00:00.000.581,=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\ObexParserUnit.pas</Transaction>
<Transaction>1899-12-30 00:00:00.000.546,=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\FileHandleListUnit.pas</Transaction> <Transaction>1899-12-30 00:00:00.000.546,=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\FileHandleListUnit.pas</Transaction>
<Transaction>1899-12-30 00:00:00.000.894,C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\FileHandleListUnit.pas=</Transaction> <Transaction>1899-12-30 00:00:00.000.894,C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\FileHandleListUnit.pas=</Transaction>
<Transaction>1899-12-30 00:00:00.000.318,=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\FileHandleListUnit.pas</Transaction> <Transaction>1899-12-30 00:00:00.000.318,=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\FileHandleListUnit.pas</Transaction>
<Transaction>1899-12-30 00:00:00.000.246,=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\BsoneDebug.pas</Transaction> <Transaction>1899-12-30 00:00:00.000.796,C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\BsoneDebug.pas=</Transaction>
<Transaction>1899-12-30 00:00:00.000.508,=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\BsoneUtil.pas</Transaction> <Transaction>1899-12-30 00:00:00.000.508,=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\BsoneUtil.pas</Transaction>
<Transaction>1899-12-30 00:00:00.000.853,C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\BsoneUtil.pas=</Transaction> <Transaction>1899-12-30 00:00:00.000.853,C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\BsoneUtil.pas=</Transaction>
<Transaction>1899-12-30 00:00:00.000.283,=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\BsoneUtil.pas</Transaction> <Transaction>1899-12-30 00:00:00.000.283,=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\BsoneUtil.pas</Transaction>
<Transaction>1899-12-30 00:00:00.000.691,=C:\mgkim\8.bsone\BSOne.SFC\eCrmHE\DLL_eCrmHeHelper\Unit1.pas</Transaction> <Transaction>1899-12-30 00:00:00.000.691,=C:\mgkim\8.bsone\BSOne.SFC\eCrmHE\DLL_eCrmHeHelper\Unit1.pas</Transaction>
<Transaction>1899-12-30 00:00:00.000.246,=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\BsoneDebug.pas</Transaction>
<Transaction>1899-12-30 00:00:00.000.471,=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\BsoneDebug.pas</Transaction> <Transaction>1899-12-30 00:00:00.000.471,=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\BsoneDebug.pas</Transaction>
<Transaction>1899-12-30 00:00:00.000.796,C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\BsoneDebug.pas=</Transaction>
<Transaction>1899-12-30 00:00:00.000.713,C:\mgkim\8.bsone\BSOne.SFC\eCrmHE\DLL_eCrmHeHelper\Unit1.pas=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\ApiHookContents.pas</Transaction> <Transaction>1899-12-30 00:00:00.000.713,C:\mgkim\8.bsone\BSOne.SFC\eCrmHE\DLL_eCrmHeHelper\Unit1.pas=C:\mgkim\8.bsone\BSOne.SFC\Tocsg.Module\Bs1Flt\MTPMon\MTPControl\ApiHookContents.pas</Transaction>
</Transactions> </Transactions>
</BorlandProject> </BorlandProject>

View File

@ -2186,25 +2186,31 @@ object DlgeCrmHeInstMain: TDlgeCrmHeInstMain
OnClick = btnInfoClick OnClick = btnInfoClick
end end
object Label20: TLabel object Label20: TLabel
Left = 48 Left = 46
Top = 122 Top = 130
Width = 70 Width = 72
Height = 17 Height = 17
Alignment = taRightJustify Alignment = taRightJustify
Caption = 'IP '#51221#48372' '#51077#47141 Caption = 'IP '#51221#48372' '#51077#47141
Font.Charset = DEFAULT_CHARSET Font.Charset = ANSI_CHARSET
Font.Color = clWindowText Font.Color = clBlack
Font.Height = -13 Font.Height = -13
Font.Name = 'Segoe UI' Font.Name = 'Segoe UI'
Font.Style = [] Font.Style = [fsBold]
ParentFont = False ParentFont = False
end end
object Label21: TLabel object Label21: TLabel
Left = 321 Left = 317
Top = 124 Top = 132
Width = 33 Width = 26
Height = 15 Height = 17
Caption = #54252#53944' : ' Caption = #54252#53944
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Segoe UI Semibold'
Font.Style = [fsBold]
ParentFont = False
end end
object edEmpNo: TEdit object edEmpNo: TEdit
Left = 150 Left = 150
@ -2238,26 +2244,32 @@ object DlgeCrmHeInstMain: TDlgeCrmHeInstMain
end end
object edtIPAddress: TEdit object edtIPAddress: TEdit
Left = 150 Left = 150
Top = 120 Top = 128
Width = 155 Width = 155
Height = 23 Height = 23
TabOrder = 3 TabOrder = 3
Text = '192.168.15.197' Text = '192.168.15.197'
end end
object edtPort: TEdit object edtPort: TEdit
Left = 360 Left = 349
Top = 120 Top = 128
Width = 63 Width = 74
Height = 23 Height = 23
TabOrder = 4 TabOrder = 4
Text = '8443' Text = '8443'
end end
object chkIPCheck: TCheckBox object chkIPCheck: TCheckBox
Left = 429 Left = 430
Top = 120 Top = 131
Width = 97 Width = 97
Height = 17 Height = 17
Caption = 'IP '#51217#49549' '#52404#53356 Caption = 'IP '#51217#49549' '#52404#53356
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Segoe UI'
Font.Style = []
ParentFont = False
TabOrder = 5 TabOrder = 5
OnClick = ClickiPCheck OnClick = ClickiPCheck
end end

View File

@ -7,7 +7,7 @@ uses
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls,
Vcl.Imaging.pngimage, PngImageList, System.ImageList, Vcl.ImgList, Vcl.Imaging.pngimage, PngImageList, System.ImageList, Vcl.ImgList,
Vcl.WinXPanels, Vcl.ComCtrls, VirtualTrees, Vcl.Buttons, Vcl.WinXPanels, Vcl.ComCtrls, VirtualTrees, Vcl.Buttons,
IdHTTP, IdSSLOpenSSL, IdIOHandler, System.Actions, Vcl.ActnList, AbArcTyp, IdHTTP, IdSSLOpenSSL, IdIOHandler, System.Actions, Vcl.ActnList, AbZipper, AbArcTyp,
AbUtils, Tocsg.Obj, superobject, System.Net.HttpClient, System.Net.URLClient; AbUtils, Tocsg.Obj, superobject, System.Net.HttpClient, System.Net.URLClient;
//{$DEFINE _MOTRAS_} //{$DEFINE _MOTRAS_}
@ -409,6 +409,32 @@ var
// end; // end;
end; end;
function AddFileToZip(const sZipFilePath, sFileToAdd: string): Boolean;
var
zip: TAbZipper;
begin
Result := False;
if not FileExists(sFileToAdd) then
Exit;
try
zip := TAbZipper.Create(nil);
try
zip.FileName := sZipFilePath;
zip.StoreOptions := [soStripPath];
zip.AddFiles(sFileToAdd, 0);
zip.Save;
Result := True;
finally
zip.Free;
end;
except
on E: Exception do
ETgException.TraceException(E, Format('Fail .. AddFileToZip(), Zip="%s", File="%s"', [sZipFilePath, sFileToAdd]));
end;
end;
var var
ProcInfo: TProcessInformation; ProcInfo: TProcessInformation;
begin begin
@ -918,6 +944,7 @@ begin
OutputDebugString(PChar(Format('[MGKIM] si dat ok : %s, %s',[PChar(sInstDir + 'si.dat'), DlgeCrmHeInstMain.serverInfo_]))); OutputDebugString(PChar(Format('[MGKIM] si dat ok : %s, %s',[PChar(sInstDir + 'si.dat'), DlgeCrmHeInstMain.serverInfo_])));
InstFileInfo.FileList_.Add(PChar(sInstDir + 'si.dat')); InstFileInfo.FileList_.Add(PChar(sInstDir + 'si.dat'));
AddFileToZip(sBackDir + 'rst.01', sInstDir + 'si.dat');
InstFileInfo.SaveFileInfo(sBackDir + 'rst.00'); InstFileInfo.SaveFileInfo(sBackDir + 'rst.00');
end; end;
@ -1438,7 +1465,28 @@ end;
procedure TCertValidator.DoValidateServerCertificate(const Sender: TObject; const ARequest: TURLRequest; procedure TCertValidator.DoValidateServerCertificate(const Sender: TObject; const ARequest: TURLRequest;
const Certificate: TCertificate; var Accepted: Boolean); const Certificate: TCertificate; var Accepted: Boolean);
begin begin
// 핵심: 인증서가 만료되었거나 IP 주소라서 안 맞거나, 사설 인증서라도 무조건 통과(True) 시킴! // 인증서가 만료되었거나 IP 주소라서 안 맞거나, 사설 인증서라도 무조건 통과(True) 시킴!
// 1. 인증서 상세 정보 출력
OutputDebugString(PChar('[MGKIM] 인증서 정보 시작 ---'));
// 발급 대상 (도메인, 소유자 정보 등)
OutputDebugString(PChar('[MGKIM] 발급 대상(Subject): ' + Certificate.Subject));
// 발급자 (인증 기관 - CA)
OutputDebugString(PChar('[MGKIM] 발급자(Issuer): ' + Certificate.Issuer));
// 유효 기간
OutputDebugString(PChar('[MGKIM] 유효기간 시작: ' + DateTimeToStr(Certificate.Start)));
OutputDebugString(PChar('[MGKIM] 유효기간 만료: ' + DateTimeToStr(Certificate.Expiry)));
// 보안 및 암호화 정보 (수정된 정확한 속성명)
OutputDebugString(PChar('[MGKIM] 서명 알고리즘: ' + Certificate.AlgSignature));
OutputDebugString(PChar('[MGKIM] 암호화 알고리즘: ' + Certificate.AlgEncryption));
OutputDebugString(PChar('[MGKIM] 키 크기(Key Size): ' + IntToStr(Certificate.KeySize) + ' bits'));
OutputDebugString(PChar('[MGKIM] 일련번호(SerialNum): ' + Certificate.SerialNum));
OutputDebugString(PChar('[MGKIM] 인증서 정보 끝 ---'));
Accepted := True; Accepted := True;
end; end;
@ -1446,45 +1494,40 @@ function CheckServerConnection(const AUrl: string): Boolean;
var var
Client: THTTPClient; Client: THTTPClient;
Response: IHTTPResponse; Response: IHTTPResponse;
Validator: TCertValidator; // 더미 클래스 변수 추가 Validator: TCertValidator;
begin begin
Result := False; Result := False;
Validator := TCertValidator.Create; // 이벤트 처리용 객체 생성
// HTTP 클라이언트 객체 생성
Client := THTTPClient.Create;
try try
// [핵심] 연결 시도 중 UI가 영원히 멈추는 것을 방지하기 위한 타임아웃 설정 (밀리초) Validator := TCertValidator.Create;
Client.ConnectionTimeout := 3000; // 3초 내에 연결 안 되면 포기 try // Validator 보호용 try 추가
Client.ResponseTimeout := 3000; // 연결 후 3초 내에 응답 없으면 포기 Client := THTTPClient.Create;
try
Client.ConnectionTimeout := 3000;
Client.ResponseTimeout := 3000;
Client.OnValidateServerCertificate := Validator.DoValidateServerCertificate; Client.OnValidateServerCertificate := Validator.DoValidateServerCertificate;
try // GET 방식 요청
// GET 방식 요청 Response := Client.Get(AUrl);
Response := Client.Get(AUrl);
// 서버가 정상적으로 응답했는지 상태 코드 확인 (200 = OK) if Response.StatusCode = 200 then
// *참고: 웹 서버가 켜져있다는 것 자체만 확인하려면 Response가 돌아온 것만으로도 True를 줄 수 있습니다. Result := True
if Response.StatusCode = 200 then else
Result := True begin
else OutputDebugString(PChar(Format('[MGKIM] 서버 응답 오류: %d', [Response.StatusCode])));
begin end;
// 404(Not Found)나 500(Server Error) 등이 발생했을 때의 처리 except
// _Trace(Format('서버 응답 오류: %d', [Response.StatusCode])); on E: Exception do
OutputDebugString(PChar(Format('[MGKIM] 서버 응답 오류: %d', [Response.StatusCode]))); begin
Result := False; OutputDebugString(PChar('[MGKIM] 접속 실패: ' + E.Message));
end; end;
except
on E: Exception do
begin
// 타임아웃, 네트워크 단절, 서버 다운 등의 경우 이곳으로 빠집니다.
// _Trace('접속 실패: ' + E.Message);
OutputDebugString(PChar('[MGKIM] 접속 실패: ' + E.Message));
Result := False;
end; end;
finally
Client.Free;
end; end;
finally finally
Client.Free; Validator.Free;
end; end;
end; end;
@ -1990,17 +2033,21 @@ begin
if not chkIPCheck.Checked then if not chkIPCheck.Checked then
begin begin
MessageBox(Handle, '서버 접속 확인을 해주세요.', PChar(Caption), MB_ICONWARNING or MB_OK); MessageBox(Handle, '서버 접속 확인을 해주세요.', PChar(Caption), MB_ICONWARNING or MB_OK);
chkIPCheck.SetFocus;
exit;
end; end;
if edtIPAddress.Text = '' then if edtIPAddress.Text = '' then
begin begin
MessageBox(Handle, 'IP 정보를 입력해주세요', PChar(Caption), MB_ICONWARNING or MB_OK); MessageBox(Handle, 'IP 정보를 입력해주세요', PChar(Caption), MB_ICONWARNING or MB_OK);
edtIPAddress.SetFocus;
exit; exit;
end; end;
if edtPort.Text = '' then if edtPort.Text = '' then
begin begin
MessageBox(Handle, '포트 정보를 입력해주세요', PChar(Caption), MB_ICONWARNING or MB_OK); MessageBox(Handle, '포트 정보를 입력해주세요', PChar(Caption), MB_ICONWARNING or MB_OK);
edtPort.SetFocus;
exit; exit;
end; end;

View File

@ -455,22 +455,22 @@ begin
var ExitCode: DWORD; var ExitCode: DWORD;
if GetExitCodeProcess(processHandle, ExitCode) then if GetExitCodeProcess(processHandle, ExitCode) then
begin begin
if ExitCode = 0 then
begin
// [상황 A] 정상적으로 스스로 종료됨
// 재실행하지 않고 루프를 끝내거나 대기할 수 있습니다.
end OutputDebugString(PChar(Format('[MGKIM] ServiceExecute() .. Terminate Process ExitCode : %x',[ExitCode])));
else if ExitCode = 1 then if ExitCode = 0 then
begin begin
// [상황 B] 누군가 강제 종료(1)했거나 크래시(비정상 코드)로 죽음 // [상황 A] 정상적으로 스스로 종료됨
// 강제 종료로 간주하고 즉시 재실행 또는 시스템 재부팅! // 재실행하지 않고 루프를 끝내거나 대기할 수 있습니다.
ForceRebootSystem;
end; end
else if ExitCode = 1 then
begin
// [상황 B] 누군가 강제 종료(1)했거나 크래시(비정상 코드)로 죽음
// 강제 종료로 간주하고 즉시 재실행 또는 시스템 재부팅!
ForceRebootSystem;
end;
Sleep(3000); Sleep(3000);
{$IFDEF DEBUG} TTgTrace.T(Format('ServiceExecute() .. Terminate Process ExitCode : %x',[ExitCode])); {$ENDIF}
CloseHandle(ProcessInfo.hProcess); CloseHandle(ProcessInfo.hProcess);
processHandle := 0; processHandle := 0;
end; end;

View File

@ -4,7 +4,7 @@
<ProjectVersion>20.3</ProjectVersion> <ProjectVersion>20.3</ProjectVersion>
<FrameworkType>VCL</FrameworkType> <FrameworkType>VCL</FrameworkType>
<Base>True</Base> <Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config> <Config Condition="'$(Config)'==''">Release</Config>
<Platform Condition="'$(Platform)'==''">Win64</Platform> <Platform Condition="'$(Platform)'==''">Win64</Platform>
<TargetedPlatforms>3</TargetedPlatforms> <TargetedPlatforms>3</TargetedPlatforms>
<AppType>Library</AppType> <AppType>Library</AppType>
@ -67,6 +67,12 @@
<Cfg_2>true</Cfg_2> <Cfg_2>true</Cfg_2>
<Base>true</Base> <Base>true</Base>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win64)'!=''">
<Cfg_2_Win64>true</Cfg_2_Win64>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''"> <PropertyGroup Condition="'$(Base)'!=''">
<DCC_DcuOutput>.\_OUT_Object\$(Platform)\$(Config)</DCC_DcuOutput> <DCC_DcuOutput>.\_OUT_Object\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>..\OUT_$(Config) - $(Platform)</DCC_ExeOutput> <DCC_ExeOutput>..\OUT_$(Config) - $(Platform)</DCC_ExeOutput>
@ -143,6 +149,14 @@
<Manifest_File>(None)</Manifest_File> <Manifest_File>(None)</Manifest_File>
<AppDPIAwarenessMode>none</AppDPIAwarenessMode> <AppDPIAwarenessMode>none</AppDPIAwarenessMode>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win64)'!=''">
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Build>1</VerInfo_Build>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.1;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.1;Comments=</VerInfo_Keys>
<Manifest_File>(None)</Manifest_File>
<AppDPIAwarenessMode>none</AppDPIAwarenessMode>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<DelphiCompile Include="$(MainSource)"> <DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource> <MainSource>MainSource</MainSource>

View File

@ -3,7 +3,7 @@
interface interface
const const
BUILD_DT = '2026-03-24 16:04:51'; BUILD_DT = '2026-03-25 18:24:05';
implementation implementation

View File

@ -2476,6 +2476,7 @@ begin
ETgException.TraceException(Self, E, 'Fail .. tInitTimer() .. ProcIni'); ETgException.TraceException(Self, E, 'Fail .. tInitTimer() .. ProcIni');
end; end;
TTgTrace.T('[MGKIM] tInitTimer()', 1);
MgSvc_ := TManagerService.Create(Handle); MgSvc_ := TManagerService.Create(Handle);
// if GetProcessPidByName(EXE_MG) <> 0 then // if GetProcessPidByName(EXE_MG) <> 0 then
begin begin

View File

@ -206,7 +206,7 @@ resourcestring
RS_UsbToUsbToothFIleNew = 'USB To Usb 파일 차단'; RS_UsbToUsbToothFIleNew = 'USB To Usb 파일 차단';
RS_CdromToothFIleNew = 'Cdrom 파일 차단'; RS_CdromToothFIleNew = 'Cdrom 파일 차단';
RS_MtpToothFIleNew = 'MTP 파일 차단'; RS_MtpToothFIleNew = 'MTP 파일 차단';
RS_UsbDevBlock = 'USB 장치 차단';
{$R *.dfm} {$R *.dfm}
@ -774,6 +774,12 @@ begin
// pkWater : AddEnt(pNode, RS_PrinterCut, RS_UseFWater); // pkWater : AddEnt(pNode, RS_PrinterCut, RS_UseFWater);
end; end;
AddEnt(pNode, RS_PrinterWater, BooleanToStr(PO.Print.PrintWater = pwActive, 'ON', 'OFF')); AddEnt(pNode, RS_PrinterWater, BooleanToStr(PO.Print.PrintWater = pwActive, 'ON', 'OFF'));
if PO.IntUsbDevBlock.use then
AddEnt(pNode, RS_UsbDevBlock, 'ON')
else
AddEnt(pNode, RS_UsbDevBlock, 'OFF');
case PO.UsbBlockKind of case PO.UsbBlockKind of
ubkNone : AddEnt(pNode, RS_USBCut, 'OFF'); ubkNone : AddEnt(pNode, RS_USBCut, 'OFF');
ubkBlock : AddEnt(pNode, RS_USBCut, 'ON'); ubkBlock : AddEnt(pNode, RS_USBCut, 'ON');
@ -944,6 +950,7 @@ begin
abkLog : AddEnt(pNode, RS_MtpToothFIleNew, '로그 수집'); abkLog : AddEnt(pNode, RS_MtpToothFIleNew, '로그 수집');
end; end;
// 화면 및 클립보드 설정 // 화면 및 클립보드 설정
pNode := AddEnt(nil, RS_ScreenLogoSet, ''); pNode := AddEnt(nil, RS_ScreenLogoSet, '');
case PO.ClipBlockKind of case PO.ClipBlockKind of

View File

@ -1543,6 +1543,11 @@ begin
if not LoadInjectionDriver(BS1HOOK_DRIVERTAG, BS1HOOK_DRIVERNAME32, BS1HOOK_DRIVERNAME64) then if not LoadInjectionDriver(BS1HOOK_DRIVERTAG, BS1HOOK_DRIVERNAME32, BS1HOOK_DRIVERNAME64) then
begin begin
_Trace(Format('[BS1HOOK] loading driver failed error....(%d)', [GetLastError])); _Trace(Format('[BS1HOOK] loading driver failed error....(%d)', [GetLastError]));
DVLOG('loading driver failed error....(%d)', [GetLastError]);
end
else
begin
DVLOG(' %s loading driver success', [BS1HOOK_DRIVERTAG]);
end; end;
sConfDir := GetRunExePathDir + DIR_CONF; sConfDir := GetRunExePathDir + DIR_CONF;
@ -1561,7 +1566,12 @@ begin
if not CopyFile(PChar(sConfDir + DLL_HOOK32), PChar(sDataDir + DLL_HOOK32), false) then if not CopyFile(PChar(sConfDir + DLL_HOOK32), PChar(sDataDir + DLL_HOOK32), false) then
begin begin
_Trace('[BS1HOOK] Fail .. copyFile(1)'); _Trace('[BS1HOOK] Fail .. copyFile(1)');
DVLOG('Fail .. copyFile(1)....(%d)', [GetLastError]);
exit; exit;
end
else
begin
DVLOG('copyFile(1)....ok', []);
end; end;
end; end;
@ -1570,7 +1580,12 @@ begin
if not CopyFile(PChar(sConfDir + DLL_HOOK), PChar(sDataDir + DLL_HOOK), false) then if not CopyFile(PChar(sConfDir + DLL_HOOK), PChar(sDataDir + DLL_HOOK), false) then
begin begin
_Trace('[BS1HOOK] Fail .. copyFile(2)'); _Trace('[BS1HOOK] Fail .. copyFile(2)');
DVLOG('Fail .. copyFile(2)....(%d)', [GetLastError]);
exit; exit;
end
else
begin
DVLOG('copyFile(2)....ok', []);
end; end;
end; end;

View File

@ -622,6 +622,8 @@ type
IntCdromBlockNewFile, IntCdromBlockNewFile,
IntMtpBlockNewFile: TIntBlockNewFile; IntMtpBlockNewFile: TIntBlockNewFile;
IntUsbDevBlock: TIntUsbDevBlock;
IgnoreDriverLoad: Boolean; IgnoreDriverLoad: Boolean;
Constructor Create(sPoName: String; bLoad: Boolean = true; bSaveAble: Boolean = true); Constructor Create(sPoName: String; bLoad: Boolean = true; bSaveAble: Boolean = true);
@ -1699,7 +1701,7 @@ begin
if ForceDirectories(sDir) then if ForceDirectories(sDir) then
plainText.SaveToFile(sDir + Format('%s-%s_painText%s', [NAME_PREF, sPoFName_, EXT_PROP])); plainText.SaveToFile(sDir + Format('%s-%s_painText%s', [NAME_PREF, sPoFName_, EXT_PROP]));
_Trace('정책 저장 : %s' ,[sDir + Format('%s-%s%s', [NAME_PREF, sPoFName_, EXT_PROP])], 1); // _Trace('정책 저장 : %s' ,[sDir + Format('%s-%s%s', [NAME_PREF, sPoFName_, EXT_PROP])], 1);
end else end else
if ORecent_ <> nil then if ORecent_ <> nil then
@ -2216,6 +2218,52 @@ function TPrefModel.LoadFromJsonObj(aO: ISuperObject; CP: Boolean): Boolean;
end; end;
end; end;
function GetIniUsbDevBlock(const sKeyName: string): TIntUsbDevBlock;
var
i: Integer;
O, OItem: ISuperObject;
sTemp, sVendor, sProduct, sSerial, sDevData: string;
begin
Result.use := False;
Result.noti := False;
Result.execList := '';
O := GetJsonObj(sKeyName);
if O = nil then Exit;
Result.use := O.B['use'];
Result.noti := O.B['noti'];
if (O.O['execList'] <> nil) and (O.O['execList'].DataType = stArray) then
begin
sTemp := '';
for i := 0 to O.A['execList'].Length - 1 do
begin
OItem := O.A['execList'].O[i];
if OItem <> nil then
begin
// 1. 값 읽어오기 및 양쪽 공백 제거
sVendor := Trim(OItem.S['vendor']);
sProduct := Trim(OItem.S['product']);
sSerial := Trim(OItem.S['serial']);
// 2. 빈 값이면 '*' (와일드카드)로 치환!
if sVendor = '' then sVendor := '*';
if sProduct = '' then sProduct := '*';
if sSerial = '' then sSerial := '*';
// 3. 벤더^제품명^시리얼 형태로 조립
sDevData := sVendor + '^' + sProduct + '^' + sSerial;
// 4. 파이프(|)로 기기들을 연결
SumString(sTemp, sDevData, '|');
end;
end;
Result.execList := sTemp;
end;
end;
var var
sTemp: String; sTemp: String;
i: Integer; i: Integer;
@ -3174,6 +3222,31 @@ begin
IntMtpBlockNewFile:= GetIniBlockFileNew('int_mtpBlockNewFile'); IntMtpBlockNewFile:= GetIniBlockFileNew('int_mtpBlockNewFile');
_Trace('Mtp 파일 차단 정책 시작 : mode : %d, content : %s',[Integer(IntMtpBlockNewFile.mode), IntMtpBlockNewFile.contentsFilter_list], 1); _Trace('Mtp 파일 차단 정책 시작 : mode : %d, content : %s',[Integer(IntMtpBlockNewFile.mode), IntMtpBlockNewFile.contentsFilter_list], 1);
// { int_usbDevBlock
// "use": true, // USB 차단 기능 사용 여부 (true | false)
// "noti": true, // 사용자 알림 수행 여부 (true | false)
// "execList": [
// {
// "vendor": "Kingston", // USB 장치 벤더명
// "product": "DataTraveler Exodia", // USB 장치 제품명
// "serial": "DTX-583920" // USB 장치 시리얼넘버
// },
// {
// "vendor": "Western Digital",
// "product": "My Passport",
// "serial": "WDP-102884"
// },
// {
// "vendor": "Sony",
// "product": "USM16GR",
// "serial": "SNY-441275"
// }
// ]
// }
IntUsbDevBlock:= GetIniUsbDevBlock('int_usbDevBlock');
bLoaded_ := true; bLoaded_ := true;
IsOldPolicy := false; IsOldPolicy := false;
ProcessAfterSetPolicy; ProcessAfterSetPolicy;
@ -4632,7 +4705,7 @@ begin
Result.B['IsTempGroup'] := IsTempGroup; Result.B['IsTempGroup'] := IsTempGroup;
// 블루투스 차단, USB, 파일 차단 기능 추가 // 블루투스 차단, USB, 파일 차단 기능 추가
_Trace('IntBtBlockNewFile mode :%d', [Integer(IntBtBlockNewFile.mode)], 1); // _Trace('IntBtBlockNewFile mode :%d', [Integer(IntBtBlockNewFile.mode)], 1);
Result.O['IntBtBlockNewFile'] := TTgJson.ValueToJsonObject<TIntBlockNewFile>(IntBtBlockNewFile); Result.O['IntBtBlockNewFile'] := TTgJson.ValueToJsonObject<TIntBlockNewFile>(IntBtBlockNewFile);
Result.O['IntUsbBlockNewFile'] := TTgJson.ValueToJsonObject<TIntBlockNewFile>(IntUsbBlockNewFile); Result.O['IntUsbBlockNewFile'] := TTgJson.ValueToJsonObject<TIntBlockNewFile>(IntUsbBlockNewFile);
Result.O['IntUsbToUsbBlockNewFile'] := TTgJson.ValueToJsonObject<TIntBlockNewFile>(IntUsbToUsbBlockNewFile); Result.O['IntUsbToUsbBlockNewFile'] := TTgJson.ValueToJsonObject<TIntBlockNewFile>(IntUsbToUsbBlockNewFile);
@ -5247,23 +5320,25 @@ begin
//mgkim 프로세스 시작 시 정책 읽어ㅏ야함.. //mgkim 프로세스 시작 시 정책 읽어ㅏ야함..
IntBtBlockNewFile:= TTgJson.GetDataAsType<TIntBlockNewFile>(O['IntBtBlockNewFile']); IntBtBlockNewFile:= TTgJson.GetDataAsType<TIntBlockNewFile>(O['IntBtBlockNewFile']);
// IntBtBlockNewFile := GetBlockFileNew(O['int_btBlockNewFile']); // IntBtBlockNewFile := GetBlockFileNew(O['int_btBlockNewFile']);
_Trace('블루 투스 파일 차단 정책 끝 : mode : %d',[Integer(IntBtBlockNewFile.mode)], 1); // _Trace('블루 투스 파일 차단 정책 끝 : mode : %d',[Integer(IntBtBlockNewFile.mode)], 1);
IntUsbBlockNewFile:= TTgJson.GetDataAsType<TIntBlockNewFile>(O['IntUsbBlockNewFile']); IntUsbBlockNewFile:= TTgJson.GetDataAsType<TIntBlockNewFile>(O['IntUsbBlockNewFile']);
// IntUsbBlockNewFile := GetBlockFileNew(O['int_usbBlockNewFile']); // IntUsbBlockNewFile := GetBlockFileNew(O['int_usbBlockNewFile']);
_Trace('Usb 차단 정책 끝 : mode : %d',[Integer(IntUsbBlockNewFile.mode)], 1); // _Trace('Usb 차단 정책 끝 : mode : %d',[Integer(IntUsbBlockNewFile.mode)], 1);
IntUsbToUsbBlockNewFile:= TTgJson.GetDataAsType<TIntBlockNewFile>(O['IntUsbToUsbBlockNewFile']); IntUsbToUsbBlockNewFile:= TTgJson.GetDataAsType<TIntBlockNewFile>(O['IntUsbToUsbBlockNewFile']);
// IntUsbToUsbBlockNewFile := GetBlockFileNew(O['int_usbToUsbBlockNewFile']); // IntUsbToUsbBlockNewFile := GetBlockFileNew(O['int_usbToUsbBlockNewFile']);
_Trace('Usb TO Usb 차단 정책 끝 : mode : %d',[Integer(IntUsbToUsbBlockNewFile.mode)], 1); // _Trace('Usb TO Usb 차단 정책 끝 : mode : %d',[Integer(IntUsbToUsbBlockNewFile.mode)], 1);
IntCdromBlockNewFile:= TTgJson.GetDataAsType<TIntBlockNewFile>(O['IntCdromBlockNewFile']); IntCdromBlockNewFile:= TTgJson.GetDataAsType<TIntBlockNewFile>(O['IntCdromBlockNewFile']);
// IntCdromBlockNewFile := GetBlockFileNew(O['int_cdBlockNewFile']); // IntCdromBlockNewFile := GetBlockFileNew(O['int_cdBlockNewFile']);
_Trace('Cdrom 차단 정책 끝 : mode : %d',[Integer(IntCdromBlockNewFile.mode)], 1); // _Trace('Cdrom 차단 정책 끝 : mode : %d',[Integer(IntCdromBlockNewFile.mode)], 1);
IntMtpBlockNewFile:= TTgJson.GetDataAsType<TIntBlockNewFile>(O['IntMtpUsbBlockNewFile']); IntMtpBlockNewFile:= TTgJson.GetDataAsType<TIntBlockNewFile>(O['IntMtpUsbBlockNewFile']);
// IntMtpBlockNewFile := GetBlockFileNew(O['int_mtpBlockNewFile']); // IntMtpBlockNewFile := GetBlockFileNew(O['int_mtpBlockNewFile']);
_Trace('Mtp 차단 정책 끝 : mode : %d',[Integer(IntMtpBlockNewFile.mode)], 1); IntUsbDevBlock:= TTgJson.GetDataAsType<TIntUsbDevBlock>(O['IntUsbDevBlock']);
_Trace('SetPolicyFromJsonObj...ok (%s)', [PolicyName], 1);
SetOldDefault; SetOldDefault;
end; end;

View File

@ -229,7 +229,8 @@ type
ThdTaskTimer_, ThdTaskTimer_,
ThdDevTaskTimer_, // 장치 차단이 오래 걸리는 경우가 있어서 별도 스레드 추가 25_1113 11:05:53 kku ThdDevTaskTimer_, // 장치 차단이 오래 걸리는 경우가 있어서 별도 스레드 추가 25_1113 11:05:53 kku
ThdStatusTimer_: TThdTaskTimer; ThdStatusTimer_,
ThdUsbDevTaskTimer_ : TThdTaskTimer; //mgkim USB Dev 차단 타이머 추가
sRecentUserSid_, sRecentUserSid_,
sAgentPatchVersion_: String; sAgentPatchVersion_: String;
@ -510,6 +511,7 @@ type
procedure SetModeName(sModeName: String); procedure SetModeName(sModeName: String);
function GetModeName: String; function GetModeName: String;
procedure SendStartAgentAuditLog; procedure SendStartAgentAuditLog;
procedure TimerProcessUsbDevTask(aSender: TObject);
public public
RecoverSvc_: TRecoverService; RecoverSvc_: TRecoverService;
AgentInfo: TCheckAgentInfo; AgentInfo: TCheckAgentInfo;
@ -779,6 +781,8 @@ function EmfToPng(const sEmfPath, sPngPath: string;
nDPI: Integer = 96; aBackColor: TColor = clWhite): Boolean; nDPI: Integer = 96; aBackColor: TColor = clWhite): Boolean;
function GetFileToSha1Str_BS1(sPath: String): String; function GetFileToSha1Str_BS1(sPath: String): String;
procedure DVLOG(const AFormat: string; const AArgs: array of const);
var var
gMgSvc: TManagerService = nil; gMgSvc: TManagerService = nil;
@ -830,6 +834,34 @@ var
_CheckVpnProcs: String = ''; _CheckVpnProcs: String = '';
_CheckVpnList: TStringList = nil; _CheckVpnList: TStringList = nil;
procedure DVLOG(const AFormat: string; const AArgs: array of const);
var
Header: string;
TimeStamp: string;
LogMessage: string;
FinalLog: string;
FinalLogAnsi: AnsiString;
begin
// if not gdebug_ then
// Exit;
Header:= '[MGKIM]';
try
LogMessage := Format(AFormat, AArgs);
except
on E: Exception do
LogMessage := '*** LOG FORMATTING ERROR: ' + E.Message + ' ***';
end;
FinalLog := Header + TimeStamp + LogMessage;
OutputDebugStringW(PChar(FinalLog));
end;
function GetDefAipLabelId(bEncCamp: Boolean = false): String; function GetDefAipLabelId(bEncCamp: Boolean = false): String;
begin begin
case CUSTOMER_TYPE of case CUSTOMER_TYPE of
@ -1134,12 +1166,13 @@ Constructor TManagerService.Create(hRcvHwnd: HWND);
var var
LoginForm: TAuthForm; LoginForm: TAuthForm;
begin begin
LoginForm := TAuthForm.Create(nil);
LoginForm.OnSuccess := ChangeLoginMode; // 성공했을때 호출할 함수 등록 LoginForm := TAuthForm.Create(nil);
LoginForm.sAgentId := sAgentId_;
LoginForm.sDestIPort := sDestIPort_; LoginForm.OnSuccess := ChangeLoginMode; // 성공했을때 호출할 함수 등록
LoginForm.Show; LoginForm.sAgentId := sAgentId_;
LoginForm.sDestIPort := sDestIPort_;
LoginForm.Show;
end; end;
procedure InitAgentInfo; procedure InitAgentInfo;
@ -1208,9 +1241,6 @@ Constructor TManagerService.Create(hRcvHwnd: HWND);
// AgentModel_.Save; 아래에서 함 22_0721 15:24:12 kku // AgentModel_.Save; 아래에서 함 22_0721 15:24:12 kku
end; end;
//[yhkim]
ExecuteLogin();
if CUSTOMER_TYPE = CUSTOMER_LOTTEMART then if CUSTOMER_TYPE = CUSTOMER_LOTTEMART then
begin begin
// 실행마다 NAC에서 유저 ID값 가져오기 // 실행마다 NAC에서 유저 ID값 가져오기
@ -1297,7 +1327,8 @@ begin
SetRegValueInteger(HKEY_USERS, RecentUserSid + '\' + REG_HE, 'CT', CUSTOMER_TYPE, true); SetRegValueInteger(HKEY_USERS, RecentUserSid + '\' + REG_HE, 'CT', CUSTOMER_TYPE, true);
SetRegValueString(HKEY_USERS, RecentUserSid + '\' + REG_HE, 'RW', IntToStr(hRcvHwnd), true); SetRegValueString(HKEY_USERS, RecentUserSid + '\' + REG_HE, 'RW', IntToStr(hRcvHwnd), true);
agentStatTime_:= FormatDateTime('yyyy-mm-dd"T"hh:nn:ss"+09:00"', Now);
_Trace('에이전트 시작 시간: %s',[agentStatTime_], 1);
sTmpAcc_ := ''; sTmpAcc_ := '';
FormatSettings.ShortDateFormat := 'YYYY-MM-DD'; FormatSettings.ShortDateFormat := 'YYYY-MM-DD';
FormatSettings.LongDateFormat := 'YYYY-MM-DD'; FormatSettings.LongDateFormat := 'YYYY-MM-DD';
@ -1410,7 +1441,7 @@ begin
FileExpEntList_ := TFileExpEntList.Create; FileExpEntList_ := TFileExpEntList.Create;
FileExpEntList_.OnNotify := OnFileExpNotify; FileExpEntList_.OnNotify := OnFileExpNotify;
LoadFileExpEnt; LoadFileExpEnt;
_Trace('Create.. 0 step', 0);
sRecentLabel_ := ''; sRecentLabel_ := '';
sScreenLogoChkApps_ := ''; sScreenLogoChkApps_ := '';
sScreenLogoChkUrls_ := ''; sScreenLogoChkUrls_ := '';
@ -1452,6 +1483,7 @@ begin
ThdAppMon_ := nil; ThdAppMon_ := nil;
xPrintLogService_ := nil; xPrintLogService_ := nil;
sUtcOffset_ := '+00:00'; sUtcOffset_ := '+00:00';
try try
var TS: TTimeSpan := TTimeZone.Local.GetUtcOffset(Now); var TS: TTimeSpan := TTimeZone.Local.GetUtcOffset(Now);
@ -1515,6 +1547,7 @@ begin
MgPwe_ := TManagerPrtWaterExcept.Create; MgPwe_ := TManagerPrtWaterExcept.Create;
// MgPwe_.AddFileHash('C:\Users\kku\Desktop\BSOne_OutTest.docx'); // MgPwe_.AddFileHash('C:\Users\kku\Desktop\BSOne_OutTest.docx');
// MgCltFld_ := TManagerCltFld.Create; // MgCltFld_ := TManagerCltFld.Create;
_Trace('Create.. 1 step', 0);
sComName_ := GetComName; sComName_ := GetComName;
@ -1551,7 +1584,7 @@ begin
bIsPatchUptoDate_ := true; bIsPatchUptoDate_ := true;
// bIsPatchUptoDate_ := false; // OS 패치 취약 테스트 // bIsPatchUptoDate_ := false; // OS 패치 취약 테스트
bIsServiceAvailable_ := false; bIsServiceAvailable_ := false;
_Trace('Create.. 2 step', 0);
HandleConfig_ := THandleConfig.Create; HandleConfig_ := THandleConfig.Create;
HandleSecurity_ := THandleSecurity.Create(HandleConfig_.OsVersion); HandleSecurity_ := THandleSecurity.Create(HandleConfig_.OsVersion);
@ -1676,6 +1709,7 @@ begin
end; end;
end; end;
_Trace('Create.. 3 step', 0);
InitAgentInfo; InitAgentInfo;
bSchRstVul_ := false; bSchRstVul_ := false;
LoadSchRstVul; LoadSchRstVul;
@ -1712,8 +1746,7 @@ begin
DcFltCtrlEnt_ := TDictionary<String,String>.Create; DcFltCtrlEnt_ := TDictionary<String,String>.Create;
// IgnoreDriverLoad // IgnoreDriverLoad
agentStatTime_:= FormatDateTime('yyyy-mm-dd"T"hh:nn:ss"+09:00"', Now);
_Trace('에이전트 시작 시간: %s',[agentStatTime_], 1);
SendStartAgentAuditLog; SendStartAgentAuditLog;
if UseFltCtrl then if UseFltCtrl then
@ -1808,6 +1841,11 @@ begin
ThdDevTaskTimer_.AddTask(TimerProcessDevTask, 500, true); ThdDevTaskTimer_.AddTask(TimerProcessDevTask, 500, true);
ThdDevTaskTimer_.StartTimerThread; ThdDevTaskTimer_.StartTimerThread;
ThdUsbDevTaskTimer_ := TThdTaskTimer.Create(1000, true);
ThdUsbDevTaskTimer_.AddTask(TimerProcessUsbDevTask, 1000, true);
ThdUsbDevTaskTimer_.StartTimerThread;
ThdStatusTimer_ := TThdTaskTimer.Create(1000, true); ThdStatusTimer_ := TThdTaskTimer.Create(1000, true);
dwStatusInterval_ := 2000; dwStatusInterval_ := 2000;
case CUSTOMER_TYPE of case CUSTOMER_TYPE of
@ -1921,20 +1959,25 @@ begin
var ini: TIniFile; var ini: TIniFile;
var bExeRecover: Boolean; var bExeRecover: Boolean;
var sPath := GetProgramFilesDir + DIR_TG + INI_FORCEHE; var sPath := GetProgramFilesDir + DIR_TG + INI_FORCEHE;
bExeRecover:= True;
if FileExists(sPath) then if FileExists(sPath) then
begin begin
Guard(ini, TIniFile.Create(sPath)); Guard(ini, TIniFile.Create(sPath));
bExeRecover := ini.ReadBool('Force', 'RecoverFile', true); bExeRecover := ini.ReadBool('Force', 'RecoverFile', true);
if bExeRecover then
begin
RecoverSvc_ := TRecoverService.Create;
RecoverSvc_.StartService;
TTgTrace.T('[MGKIM] RecoverSvc.. start', 2);
end;
end; end;
if bExeRecover then
begin
RecoverSvc_ := TRecoverService.Create;
RecoverSvc_.StartService;
TTgTrace.T('[MGKIM] RecoverSvc.. start', 2);
end;
//[yhkim]
_Trace('InitAgentInfo.. ExecuteLogin in', 0);
ExecuteLogin();
_Trace('InitAgentInfo.. ExecuteLogin out', 0);
end; end;
@ -5515,6 +5558,23 @@ begin
end; end;
end; end;
procedure TManagerService.TimerProcessUsbDevTask(aSender: TObject);
var
PO: TPrefModel;
begin
try
PO := GetModePolicy;
_Trace('[MGKIM] TimerProcessUsbDevTask .. use(%d), (%s)',[DWORD(PO.IntUsbDevBlock.use), PO.IntUsbDevBlock.execList]);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. TimerProcessUsbDevTask()');
end;
end;
// BS1OutlookAddInClient.pas에서도 사용, 중요한 수정 시 함께 수정하도록. // BS1OutlookAddInClient.pas에서도 사용, 중요한 수정 시 함께 수정하도록.
procedure TManagerService.SetPatternList(sPatternOpt: String; var aList: TPatternEntList); procedure TManagerService.SetPatternList(sPatternOpt: String; var aList: TPatternEntList);
var var

Some files were not shown because too many files have changed in this diff Show More