1417 lines
39 KiB
Plaintext
1417 lines
39 KiB
Plaintext
unit ApiHookContents;
|
||
|
||
interface
|
||
|
||
|
||
uses
|
||
Winapi.Windows, System.SysUtils, System.Classes, Winapi.WinSock2, StrUtils, GlobalDefine,
|
||
AppCtrlDefine, BsoneUtil, BsoneDebug, FileHandleListUnit, ObexParserUnit;
|
||
|
||
const
|
||
CMD_RESULT_ALLOW = 300;
|
||
IMAGE_EXTS = 'PNG|JPG|JPEG|GIF|PCX|BMP';
|
||
|
||
METHOD_BUFFERED = 0;
|
||
FILE_READ_ACCESS = 1;
|
||
FILE_WRITE_ACCESS = 2;
|
||
|
||
//#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||
IOCTL_SCSI_BASE = $00000004;
|
||
SCSI_IOCTL_DATA_OUT = 0;
|
||
SCSI_IOCTL_DATA_IN = 1;
|
||
SCSI_IOCTL_DATA_UNSPECIFIED = 2;
|
||
IOCTL_SCSI_PASS_THROUGH_DIRECT = ( IOCTL_SCSI_BASE shl 16) or ((FILE_READ_ACCESS or FILE_WRITE_ACCESS) shl 14) or ($0405 shl 2) or METHOD_BUFFERED;
|
||
|
||
//#define IOCTL_WPD_MESSAGE_READWRITE_ACCESS CTL_CODE(FILE_DEVICE_WPD, WPD_CONTROL_FUNCTION_GENERIC_MESSAGE, METHOD_BUFFERED, (FILE_READ_ACCESS | FILE_WRITE_ACCESS))
|
||
FILE_DEVICE_WPD = $00000040;
|
||
WPD_CONTROL_FUNCTION_GENERIC_MESSAGE = $00000042;
|
||
IOCTL_WPD_MESSAGE_READWRITE_ACCESS = ( FILE_DEVICE_WPD shl 16) or ((FILE_READ_ACCESS or FILE_WRITE_ACCESS) shl 14) or (WPD_CONTROL_FUNCTION_GENERIC_MESSAGE shl 2) or METHOD_BUFFERED; // ($0036C004)
|
||
|
||
type
|
||
|
||
SCSI_PASS_THROUGH_DIRECT = packed record
|
||
Length: Word; // USHORT
|
||
ScsiStatus: Byte; // UCHAR
|
||
PathId: Byte; // UCHAR
|
||
TargetId: Byte; // UCHAR
|
||
Lun: Byte; // UCHAR
|
||
CdbLength: Byte; // UCHAR
|
||
SenseInfoLength: Byte; // UCHAR
|
||
DataIn: Byte; // UCHAR
|
||
Padding0: array[0..2] of Byte;
|
||
DataTransferLength: DWORD; // ULONG
|
||
TimeOutValue: DWORD; // ULONG
|
||
DataBuffer: Pointer; // PVOID
|
||
SenseInfoOffset: DWORD; // ULONG
|
||
Cdb: array[0..15] of Byte; // UCHAR Cdb[16]
|
||
end;
|
||
PSCSI_PASS_THROUGH_DIRECT = ^SCSI_PASS_THROUGH_DIRECT;
|
||
|
||
TApiHookContents = class
|
||
public
|
||
fileHandleList_: TFileHandleList;
|
||
appType_: TCurAppType;
|
||
|
||
constructor Create(AppType: TCurAppType);
|
||
destructor Destroy; override;
|
||
|
||
function CreateFileProc(hFile: THandle; lpFileName: LPCWSTR; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): Boolean; stdcall;
|
||
function CloseHandleProc(hFile: THandle): BOOL; stdcall;
|
||
function ReadFileProc(hFile: THandle; lpBuffer: Pointer; nNumberOfBytesToRead: DWORD; lpNumberOfBytesRead: PDWORD; lpOverlapped: POverlapped): BOOL; stdcall;
|
||
function DeviceIoControlProc(hDevice: THandle; dwIoControlCode: DWORD; lpInBuffer: Pointer; nInBufferSize: DWORD; lpOutBuffer: Pointer; nOutBufferSize: DWORD; lpBytesReturned: PDWORD; lpOverlapped: POverlapped): BOOL; stdcall;
|
||
function CreateFileMappingProc(hReturnFile: THandle;hFile: THandle; lpFileMappingAttributes: PSecurityAttributes; flProtect: DWORD; dwMaximumSizeHigh: DWORD; dwMaximumSizeLow: DWORD; lpName: PWideChar): Boolean; stdcall;
|
||
function WSASendProc(s: TSocket; lpBuffers: PWSABuf; dwBufferCount: DWORD; lpNumberOfBytesSent: PDWORD; dwFlags: DWORD; lpOverlapped: POverlapped;lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall;
|
||
|
||
function GetPathFromHandle(hFile: THandle; out sPath: string): BOOL; stdcall;
|
||
function GetDriveBusType(DriveLetter: WideChar): STORAGE_BUS_TYPE;
|
||
function GetOffLineType(dwType: DWORD; dwBusType: DWORD; pwszPath: PWideChar): string;
|
||
function GetFileReadBuffer(const path: string; pbuffer: PByte; buffersize: DWORD): Boolean; stdcall;
|
||
function IsExceptionPath(const APath: string): Boolean;
|
||
end;
|
||
|
||
|
||
|
||
TFun_DeviceIoControl = function(
|
||
hDevice: THandle;
|
||
dwIoControlCode: DWORD;
|
||
lpInBuffer: Pointer;
|
||
nInBufferSize: DWORD;
|
||
lpOutBuffer: Pointer;
|
||
nOutBufferSize: DWORD;
|
||
lpBytesReturned: PDWORD;
|
||
lpOverlapped: POverlapped
|
||
): BOOL; stdcall;
|
||
|
||
TFun_WSASend = function(
|
||
s: TSocket;
|
||
lpBuffers: PWSABuf;
|
||
dwBufferCount: DWORD;
|
||
lpNumberOfBytesSent: PDWORD;
|
||
dwFlags: DWORD;
|
||
lpOverlapped: POverlapped;
|
||
lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE
|
||
): Integer; stdcall;
|
||
|
||
TFun_CreateFileMappingW = function(
|
||
hFile: THandle;
|
||
lpFileMappingAttributes: PSecurityAttributes;
|
||
flProtect: DWORD;
|
||
dwMaximumSizeHigh: DWORD;
|
||
dwMaximumSizeLow: DWORD;
|
||
lpName: PWideChar
|
||
): THandle; stdcall;
|
||
|
||
|
||
function DeviceIoControlHook(
|
||
hDevice: THandle;
|
||
dwIoControlCode: DWORD;
|
||
lpInBuffer: Pointer;
|
||
nInBufferSize: DWORD;
|
||
lpOutBuffer: Pointer;
|
||
nOutBufferSize: DWORD;
|
||
lpBytesReturned: PDWORD;
|
||
lpOverlapped: POverlapped
|
||
): BOOL; stdcall;
|
||
|
||
function CreateFileMappingWHook(
|
||
hFile: THandle;
|
||
lpFileMappingAttributes: PSecurityAttributes;
|
||
flProtect: DWORD;
|
||
dwMaximumSizeHigh: DWORD;
|
||
dwMaximumSizeLow: DWORD;
|
||
lpName: PWideChar
|
||
): THandle; stdcall;
|
||
|
||
function WSASendHook(
|
||
s: TSocket;
|
||
lpBuffers: PWSABuf;
|
||
dwBufferCount: DWORD;
|
||
lpNumberOfBytesSent: PDWORD;
|
||
dwFlags: DWORD;
|
||
lpOverlapped: POverlapped;
|
||
lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE
|
||
): Integer; stdcall;
|
||
|
||
|
||
function ReadFileHook(
|
||
hFile: THandle;
|
||
lpBuffer: Pointer;
|
||
nNumberOfBytesToRead: DWORD;
|
||
lpNumberOfBytesRead: PDWORD;
|
||
lpOverlapped: POverlapped
|
||
): BOOL; stdcall;
|
||
|
||
function CheckContentPolicy(curAppType: TCurAppType; FileUseBlock: TFileUseBlock; const sPath: string; var IntBlockNewFile: TIntBlockNewFile; var resultMsg: string): Boolean;
|
||
function CheckExternalPolicy(Cmd: Integer;
|
||
const Data: string): Boolean;
|
||
function CheckAppPolicy(var FileUseBlock: TFileUseBlock; sPath: string; var IntBlockNewFile: TIntBlockNewFile): Boolean;
|
||
procedure SendHeCopyMessage(curAppType: TCurAppType; cmd: DWORD; const sPath: string; bExistsFile: Boolean; deviceName: string; resultMsg: string);
|
||
|
||
var
|
||
ozDeviceIoControl: TFun_DeviceIoControl = nil;
|
||
ozCreateFileMappingW: TFun_CreateFileMappingW = nil;
|
||
ozWSASend: TFun_WSASend = nil;
|
||
|
||
gApiHookContents_: TApiHookContents = nil;
|
||
ghooked_: boolean = False;
|
||
implementation
|
||
|
||
uses
|
||
BS1Hook, Tocsg.Packet, Tocsg.Files, DefineHelper, ApiHookFile, superobject;
|
||
|
||
|
||
|
||
function CheckExternalPolicy(Cmd: Integer; const Data: string): Boolean;
|
||
var
|
||
SendCopyDataResult: int64;
|
||
begin
|
||
var hReceiver := FindWindow(PChar('TDlgeCrmHeMain'), nil);
|
||
|
||
SendCopyDataResult:= SendCopyData(gAppHook.Helper.CtrlOpt.hRcvWnd, Cmd, Data);
|
||
DVLOG('CheckExternalPolicy: hReceiver (%d), Result(%d)', [DWORD(hReceiver),DWORD(SendCopyDataResult)]);
|
||
Result := SendCopyDataResult = CMD_RESULT_ALLOW;
|
||
end;
|
||
|
||
|
||
function CheckAppPolicy(var FileUseBlock: TFileUseBlock; sPath: string; var IntBlockNewFile: TIntBlockNewFile): Boolean;
|
||
begin
|
||
Result := True;
|
||
// 2. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> üũ
|
||
if gAppHook.Helper.CtrlOpt.bFileApproval then
|
||
begin
|
||
if CheckExternalPolicy(HPCMD_APPROVAL_FILE, sPath) then
|
||
begin
|
||
DVLOG('CheckAppPolicy: HPCMD_APPROVAL_FILE not FileUseBlock(%d)', [DWORD(FileUseBlock)]);
|
||
if FileUseBlock = fubBlock then
|
||
FileUseBlock := fubMonitor;
|
||
Result := False;
|
||
end
|
||
else
|
||
begin
|
||
DVLOG('CheckAppPolicy: HPCMD_APPROVAL_FILE ok FileUseBlock(%d)', [DWORD(FileUseBlock)]);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function CheckFileNamePolicy(const FilePath: string; var IntBlockNewFile: TIntBlockNewFile): Boolean;
|
||
var
|
||
OnlyFileName: string;
|
||
SearchTarget, FormattedList: string;
|
||
begin
|
||
Result := False;
|
||
|
||
DVLOG('ProcMon:CheckFileNamePolicy.. blockByFilename_use(%d)', [DWORD(IntBlockNewFile.blockByFilename_use)]);
|
||
if not IntBlockNewFile.blockByFilename_use then
|
||
Exit;
|
||
|
||
OnlyFileName := ExtractFileName(FilePath);
|
||
|
||
OnlyFileName := LowerCase(OnlyFileName);
|
||
FormattedList := LowerCase(IntBlockNewFile.blockByFilename_list);
|
||
|
||
SearchTarget := '|' + OnlyFileName + '|';
|
||
FormattedList := '|' + FormattedList + '|';
|
||
|
||
DVLOG('ProcMon:CheckFileNamePolicy.. SearchTarget(%s), FormattedList(%s)', [SearchTarget, FormattedList]);
|
||
Result := Pos(SearchTarget, FormattedList) > 0;
|
||
end;
|
||
|
||
function CheckSizePolicy(FilePath: string; var IntBlockNewFile: TIntBlockNewFile): Boolean;
|
||
begin
|
||
Result:= False;
|
||
|
||
DVLOG('ProcMon:CheckSizePolicy.. blockBySizeLimit_use(%d)', [DWORD(IntBlockNewFile.blockBySizeLimit_use)]);
|
||
if IntBlockNewFile.blockBySizeLimit_use then
|
||
begin
|
||
var ullLimitSize: ULONGLONG := IntBlockNewFile.blockBySizeLimit_minMb * 1048576;
|
||
if GetFileSize_path(FilePath) >= ullLimitSize then
|
||
Result:= True;
|
||
end
|
||
else
|
||
exit;
|
||
end;
|
||
|
||
function CheckSigPolicy(FilePath: string; var IntBlockNewFile: TIntBlockNewFile): Boolean;
|
||
var
|
||
sExt: string;
|
||
sFounds: string;
|
||
ExtList: TStringList;
|
||
begin
|
||
Result := False;
|
||
|
||
DVLOG('ProcMon:CheckSigPolicy.. blockBySig_use(%d)', [DWORD(IntBlockNewFile.blockBySig_use)]);
|
||
if not IntBlockNewFile.blockBySig_use then
|
||
Exit;
|
||
|
||
sFounds := IntBlockNewFile.blockBySig_list;
|
||
if sFounds = '' then
|
||
Exit;
|
||
|
||
sExt := UpperCase(ExtractFileExt(FilePath));
|
||
if (Length(sExt) > 0) and (sExt[1] = '.') then
|
||
Delete(sExt, 1, 1);
|
||
|
||
ExtList:= TStringList.Create;
|
||
try
|
||
ExtList.StrictDelimiter := True;
|
||
ExtList.Delimiter := '|';
|
||
ExtList.DelimitedText := UpperCase(sFounds);
|
||
|
||
if ExtList.IndexOf(sExt) > -1 then
|
||
begin
|
||
Result := True;
|
||
end;
|
||
finally
|
||
ExtList.Free;
|
||
end;
|
||
end;
|
||
|
||
|
||
function CheckContentPolicy(curAppType: TCurAppType; FileUseBlock: TFileUseBlock; const sPath: string; var IntBlockNewFile: TIntBlockNewFile; var resultMsg: string): Boolean;
|
||
var
|
||
O: ISuperObject;
|
||
bBasicBlocked: Boolean;
|
||
bInitialMonitor: Boolean;
|
||
begin
|
||
Result := False;
|
||
bBasicBlocked := False;
|
||
bInitialMonitor := (FileUseBlock = fubMonitor);
|
||
|
||
if not bInitialMonitor then
|
||
begin
|
||
if CheckSizePolicy(sPath, IntBlockNewFile) then
|
||
begin
|
||
bBasicBlocked := True;
|
||
resultMsg := 'Blocked by file size policy.';
|
||
end
|
||
else if CheckFileNamePolicy(sPath, IntBlockNewFile) then
|
||
begin
|
||
bBasicBlocked := True;
|
||
resultMsg := 'Blocked by file name policy.';
|
||
end
|
||
else if CheckSigPolicy(sPath, IntBlockNewFile) then
|
||
begin
|
||
bBasicBlocked := True;
|
||
resultMsg := 'Blocked by file extension policy.';
|
||
end;
|
||
end;
|
||
|
||
if bBasicBlocked then
|
||
begin
|
||
O := SO;
|
||
O.S['Path'] := sPath;
|
||
O.I['Type'] := Integer(curAppType);
|
||
O.S['MName'] := gAppHook.ModuleName;
|
||
O.S['resultMsg'] := resultMsg;
|
||
|
||
DVLOG('CheckContentPolicy: HPCMD_BLOCK resultMsg(%s)', [resultMsg]);
|
||
if CheckExternalPolicy(HPCMD_BLOCK, O.AsString) then
|
||
begin
|
||
DVLOG('CheckContentPolicy: HPCMD_BLOCK ok FileUseBlock(%d)', [DWORD(FileUseBlock)]);
|
||
end;
|
||
Result := True;
|
||
exit;
|
||
end;
|
||
|
||
|
||
if IntBlockNewFile.contentsFilter_use then
|
||
begin
|
||
O := SO;
|
||
O.S['Path'] := sPath;
|
||
O.I['Type'] := Integer(curAppType);
|
||
O.S['MName'] := gAppHook.ModuleName;
|
||
|
||
resultMsg := 'Contents Policy.';
|
||
if CheckExternalPolicy(HPCMD_CHECK_CONTENT, O.AsString) then
|
||
begin
|
||
Result := True;
|
||
if bInitialMonitor then
|
||
FileUseBlock := fubMonitor
|
||
else
|
||
FileUseBlock := fubBlock;
|
||
|
||
DVLOG('CheckContentPolicy: HPCMD_CHECK_CONTENT ok FileUseBlock(%d)', [DWORD(FileUseBlock)]);
|
||
end
|
||
else
|
||
begin
|
||
Result := False;
|
||
FileUseBlock := fubMonitor;
|
||
DVLOG('CheckContentPolicy: HPCMD_CHECK_CONTENT not FileUseBlock(%d)', [DWORD(FileUseBlock)]);
|
||
end;
|
||
end
|
||
else
|
||
begin
|
||
if not bInitialMonitor and not bBasicBlocked then
|
||
FileUseBlock := fubMonitor;
|
||
end;
|
||
end;
|
||
|
||
|
||
procedure SendHeCopyMessage(curAppType: TCurAppType; cmd: DWORD; const sPath: string; bExistsFile: Boolean; deviceName: string; resultMsg: string);
|
||
var
|
||
llInfo: LONGLONG;
|
||
Send: ISendPacket;
|
||
begin
|
||
try
|
||
case cmd of
|
||
NOTI_HOOK_MONITOR_ATTACH,
|
||
NOTI_HOOK_BLOCK_ATTACH :
|
||
begin
|
||
llInfo := Integer(curAppType);
|
||
end;
|
||
else llInfo := 0;
|
||
end;
|
||
|
||
Send := TTgPacket.Create(ACC_NOTI_MSG);
|
||
Send.I['Noti'] := cmd;
|
||
Send.S['FDeviceName'] := deviceName;
|
||
Send.S['MdName'] := gAppHook.ModuleName;
|
||
Send.I['PID'] := gAppHook.PID;
|
||
Send.S['FPath'] := sPath;
|
||
Send.I['FType'] := 1;
|
||
Send.I['Info'] := llInfo;
|
||
Send.S['ResultMsg'] := resultMsg;
|
||
|
||
|
||
if (gAppHook.Helper.CtrlOpt.hRcvWnd <> 0) then
|
||
begin
|
||
SendCopyData(gAppHook.Helper.CtrlOpt.hRcvWnd, HPCMD_HOOK_NOTI, Send.ToJsonString);
|
||
end;
|
||
except
|
||
// ...
|
||
end;
|
||
end;
|
||
|
||
|
||
constructor TApiHookContents.Create(AppType: TCurAppType);
|
||
begin
|
||
inherited Create;
|
||
appType_:= appType;
|
||
gApiHookContents_ := Self;
|
||
fileHandleList_:= TFileHandleList.Create;
|
||
//ghooked_:= True;
|
||
end;
|
||
|
||
destructor TApiHookContents.Destroy;
|
||
begin
|
||
|
||
FreeAndNil(fileHandleList_);
|
||
ghooked_:= False;
|
||
inherited Destroy;
|
||
end;
|
||
|
||
function TApiHookContents.GetPathFromHandle(hFile: THandle; out sPath: string): BOOL; stdcall;
|
||
var
|
||
dwRet, dwRequiredSize: DWORD;
|
||
Buffer: array[0..1024] of WideChar;
|
||
begin
|
||
sPath := '';
|
||
Result := FALSE;
|
||
|
||
dwRequiredSize := 1024;
|
||
SetLength(sPath, dwRequiredSize);
|
||
dwRet := GetFinalPathNameByHandleW(hFile, PWideChar(sPath), dwRequiredSize, VOLUME_NAME_DOS);
|
||
|
||
if (dwRet > 0) and (dwRet < MAX_PATH) then
|
||
begin
|
||
Result := TRUE;
|
||
end
|
||
else if dwRet > MAX_PATH then
|
||
begin
|
||
|
||
dwRequiredSize := dwRet;
|
||
DVLOG('GetPathFromHandle, Buffer is too small. Required size: %d', [dwRequiredSize]);
|
||
|
||
SetLength(sPath, dwRequiredSize);
|
||
dwRet := GetFinalPathNameByHandleW(hFile, PWideChar(sPath), dwRequiredSize, VOLUME_NAME_DOS);
|
||
|
||
if (dwRet > 0) and (dwRet < dwRequiredSize) then
|
||
begin
|
||
Result := TRUE;
|
||
end
|
||
else
|
||
begin
|
||
//<2F><> <20><>° <20>õ<EFBFBD><C3B5><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
DVLOG('GetPathFromHandle, GetFinalPathNameByHandleW failed on second attempt: hFile(%x), GE(%x)', [hFile, GetLastError()]);
|
||
sPath := '';
|
||
Result := FALSE;
|
||
end;
|
||
end
|
||
else
|
||
begin
|
||
DVLOG('GetPathFromHandle, GetFinalPathNameByHandleW failed with error: hFile(%x), GE(%x)', [hFile, GetLastError()]);
|
||
Result := FALSE;
|
||
end;
|
||
|
||
if Result then
|
||
begin
|
||
if StartsText('\\?\UNC\', sPath) then
|
||
begin
|
||
// '\\?\UNC\Server\Share' -> '\\Server\Share'
|
||
Delete(sPath, 1, 7); // '\\?\UNC' (7<><37><EFBFBD><EFBFBD>) <20><><EFBFBD><EFBFBD>
|
||
Insert('\', sPath, 1); // <20><> <20>տ<EFBFBD> '\' <20>߰<EFBFBD> (<28><><EFBFBD><EFBFBD>: \\Server...)
|
||
end
|
||
else if StartsText('\\?\', sPath) then
|
||
begin
|
||
Delete(sPath, 1, 4); // '\\?\' (4<><34><EFBFBD><EFBFBD>) <20><><EFBFBD><EFBFBD>
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TApiHookContents.GetDriveBusType(DriveLetter: WideChar): STORAGE_BUS_TYPE;
|
||
var
|
||
hDevice: THandle;
|
||
Query: STORAGE_PROPERTY_QUERY;
|
||
Sdh: STORAGE_DESCRIPTOR_HEADER;
|
||
Psdd: PSTORAGE_DEVICE_DESCRIPTOR;
|
||
cbBytesReturned: DWORD;
|
||
VolumePath: string;
|
||
WindowsDir: array[0..MAX_PATH] of Char;
|
||
ReturnType: STORAGE_BUS_TYPE;
|
||
bDriverMatch: Boolean;
|
||
begin
|
||
// <20>ʱ<EFBFBD>ȭ
|
||
ReturnType := BusTypeUnknown;
|
||
cbBytesReturned := 0;
|
||
Psdd := nil;
|
||
bDriverMatch := False;
|
||
|
||
// 1. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>丮 <20><><EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD> Ȯ<><C8AE> <20><><EFBFBD><EFBFBD>
|
||
FillChar(WindowsDir, SizeOf(WindowsDir), 0);
|
||
GetWindowsDirectory(WindowsDir, Length(WindowsDir));
|
||
|
||
// 2. <20><>ġ <20>ڵ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>: \\.\C:
|
||
VolumePath := Format('\\.\%s:', [DriveLetter]);
|
||
|
||
hDevice := ozCreateFileW(PChar(VolumePath),
|
||
0, // Query Access
|
||
FILE_SHARE_READ or FILE_SHARE_WRITE,
|
||
nil,
|
||
OPEN_EXISTING,
|
||
0,
|
||
0);
|
||
|
||
if hDevice = INVALID_HANDLE_VALUE then
|
||
begin
|
||
Result := ReturnType;
|
||
Exit;
|
||
end;
|
||
|
||
try
|
||
FillChar(Query, SizeOf(Query), 0);
|
||
Query.PropertyId := StorageDeviceProperty;
|
||
Query.QueryType := PropertyStandardQuery;
|
||
|
||
if not ozDeviceIoControl(hDevice,
|
||
IOCTL_STORAGE_QUERY_PROPERTY,
|
||
@Query, SizeOf(Query),
|
||
@Sdh, SizeOf(Sdh),
|
||
PDWORD(cbBytesReturned),
|
||
nil) then
|
||
begin
|
||
Exit;
|
||
end;
|
||
|
||
GetMem(Psdd, Sdh.Size);
|
||
try
|
||
FillChar(Psdd^, Sdh.Size, 0);
|
||
|
||
if not ozDeviceIoControl(hDevice,
|
||
IOCTL_STORAGE_QUERY_PROPERTY,
|
||
@Query, SizeOf(Query),
|
||
Psdd, Sdh.Size,
|
||
PDWORD(cbBytesReturned),
|
||
nil) then
|
||
begin
|
||
Exit;
|
||
end;
|
||
|
||
ReturnType := Psdd^.BusType;
|
||
|
||
finally
|
||
if Assigned(Psdd) then
|
||
FreeMem(Psdd);
|
||
end;
|
||
|
||
finally
|
||
if hDevice <> INVALID_HANDLE_VALUE then
|
||
ozCloseHandle(hDevice);
|
||
end;
|
||
|
||
Result := ReturnType;
|
||
end;
|
||
|
||
function TApiHookContents.GetOffLineType(dwType: DWORD; dwBusType: DWORD; pwszPath: PWideChar): string;
|
||
var
|
||
OffType: string;
|
||
VolumePath: string;
|
||
hDevice: THandle;
|
||
DeviceType: DWORD;
|
||
ulCharacteristics: ULONG;
|
||
MupPath: string;
|
||
begin
|
||
OffType := '';
|
||
|
||
case dwType of
|
||
DRIVE_REMOVABLE:
|
||
begin
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (<28><>: C -> \\.\C:)
|
||
if pwszPath <> nil then
|
||
VolumePath := Format('\\.\%s:', [pwszPath[0]])
|
||
else
|
||
Exit('');
|
||
|
||
OffType := 'removalbe';
|
||
|
||
// <20><>ġ <20>ڵ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
hDevice := ozCreateFileW(PChar(VolumePath),
|
||
0,
|
||
FILE_SHARE_READ or FILE_SHARE_WRITE,
|
||
nil,
|
||
OPEN_EXISTING,
|
||
0,
|
||
0);
|
||
|
||
if hDevice = INVALID_HANDLE_VALUE then
|
||
Exit('');
|
||
|
||
try
|
||
if UtilGetDriveTypeAndCharacteristics(hDevice, DeviceType, ulCharacteristics) then
|
||
begin
|
||
// FILE_FLOPPY_DISKETTE(0x4) <20>̰<EFBFBD> FILE_DEVICE_DISK(0x7) <20><><EFBFBD><EFBFBD> Ȯ<><C8AE>
|
||
if ((ulCharacteristics and $4) <> 0) and (DeviceType = $7) then
|
||
begin
|
||
OffType := 'floppy';
|
||
end;
|
||
end;
|
||
finally
|
||
ozCloseHandle(hDevice);
|
||
end;
|
||
|
||
Result := OffType;
|
||
Exit;
|
||
end;
|
||
|
||
DRIVE_REMOTE:
|
||
OffType := 'networkdriveout';
|
||
|
||
DRIVE_CDROM:
|
||
OffType := 'cdrom';
|
||
|
||
DRIVE_FIXED:
|
||
begin
|
||
dwBusType:= DWORD(GetDriveBusType(pwszPath[0]));
|
||
// FIXED <20≯鼭 USB Bus Type<70≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>
|
||
if dwBusType = DWORD(BusTypeUsb) then
|
||
OffType := 'externalhdd';
|
||
end;
|
||
|
||
DRIVE_NO_ROOT_DIR:
|
||
begin
|
||
// <20><>Ʈ<EFBFBD><C6AE>ũ <20><><EFBFBD><EFBFBD>(\Device\Mup\) Ȯ<><C8AE>
|
||
MupPath := '\Device\Mup\';
|
||
if StrLIComp(pwszPath, PChar(MupPath), Length(MupPath)) = 0 then
|
||
begin
|
||
OffType := 'networkdriveout';
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
Result := OffType;
|
||
end;
|
||
|
||
function TApiHookContents.GetFileReadBuffer(const path: string; pbuffer: PByte; buffersize: DWORD): Boolean; stdcall;
|
||
var
|
||
size: DWORD;
|
||
fp: THandle;
|
||
Retsize: DWORD;
|
||
bReadSuccess: Boolean;
|
||
begin
|
||
Result := FALSE;
|
||
fp := INVALID_HANDLE_VALUE;
|
||
Retsize := 0;
|
||
|
||
fp := ozCreateFileW(PChar(path), GENERIC_READ, FILE_SHARE_READ, nil,
|
||
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||
|
||
if fp = INVALID_HANDLE_VALUE then
|
||
Exit;
|
||
|
||
try
|
||
|
||
size := GetFileSize(fp, nil);
|
||
if (size = 0) or (size = INVALID_FILE_SIZE) then
|
||
Exit;
|
||
|
||
if size < MIN_BUFFERSIZE then
|
||
Exit;
|
||
|
||
if @ozReadFile = nil then
|
||
bReadSuccess := ReadFile(fp, pbuffer^, buffersize, Retsize, nil)
|
||
else
|
||
bReadSuccess := ozReadFile(fp, pbuffer, buffersize, @Retsize, nil);
|
||
|
||
Result := TRUE;
|
||
|
||
finally
|
||
ozCloseHandle(fp);
|
||
end;
|
||
end;
|
||
|
||
function TApiHookContents.IsExceptionPath(const APath: string): Boolean;
|
||
begin
|
||
|
||
Result:= True;
|
||
if ContainsText(APath, 'AppData\Roaming\Microsoft\Windows\Recent') or
|
||
ContainsText(APath, '\desktop.ini') or
|
||
ContainsText(APath, 'ProgramData\Microsoft\Windows\AppRepository\Packages') or
|
||
ContainsText(APath, 'AppData\Roaming\Microsoft\Internet Explorer\Quick Launch') or
|
||
ContainsText(APath, 'AppData\Roaming\Microsoft\Windows\SendTo') or
|
||
ContainsText(APath, 'AppData\Roaming\Microsoft\Windows\Themes\') or
|
||
ContainsText(APath, 'AppData\Roaming\Mozilla\Firefox\Profiles') or
|
||
ContainsText(APath, 'program files\windowsapps\microsoft') or
|
||
ContainsText(APath, 'AppData\Local\') or
|
||
ContainsText(APath, '\Program Files\Tocsg\') or
|
||
ContainsText(APath, '\ProgramData\Tocsg\bs1') or
|
||
ContainsText(APath, '\\.\MountPointManager') or
|
||
ContainsText(APath, '\\.\Global\vmhgfs') or
|
||
ContainsText(APath, 'C:\Windows\') or
|
||
ContainsText(APath, '\\.\Pipe\') or
|
||
ContainsText(APath, 'wpd_data_') then
|
||
Exit;
|
||
|
||
Result:= False;
|
||
end;
|
||
|
||
|
||
function TApiHookContents.CreateFileProc(hFile: THandle; lpFileName: LPCWSTR; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): Boolean stdcall;
|
||
var
|
||
sPath: string;
|
||
begin
|
||
Result:= False;
|
||
if (hFile = 0) or (hFile = INVALID_HANDLE_VALUE) then
|
||
Exit;
|
||
|
||
if (gAppHook.Helper.CtrlOpt.IntMtpBlockNewFile.mode = abkNone) or
|
||
(gAppHook.Helper.CtrlOpt.IntBtBlockNewFile.mode = abkNone) or
|
||
(gAppHook.Helper.CtrlOpt.IntUsbToUsbBlockNewFile.mode = abkNone) then
|
||
Exit;
|
||
|
||
if dwCreationDisposition = CREATE_NEW then
|
||
Exit;
|
||
if dwCreationDisposition = TRUNCATE_EXISTING then
|
||
Exit;
|
||
|
||
if (dwFlagsAndAttributes and FILE_FLAG_BACKUP_SEMANTICS) <> 0 then
|
||
Exit;
|
||
|
||
if (dwFlagsAndAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0 then
|
||
Exit;
|
||
|
||
if (dwFlagsAndAttributes and FILE_FLAG_DELETE_ON_CLOSE) <> 0 then
|
||
Exit;
|
||
|
||
//FILE_ATTRIBUTE_NO_SCRUB_DATA 0x00020000 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ũ<EFBFBD><C5A9><EFBFBD><EFBFBD>
|
||
if (dwFlagsAndAttributes and (FILE_FLAG_OVERLAPPED or $20000)) =
|
||
(FILE_FLAG_OVERLAPPED or $20000) then
|
||
//MTP <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ΰ<EFBFBD> <20>ش<EFBFBD> Ÿ<><C5B8><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
||
Exit;
|
||
|
||
if (appType_ = catFquirt) then //or (gbsHook_.processType_ = ptExplore)
|
||
begin
|
||
if dwFlagsAndAttributes = 0 then
|
||
Exit;
|
||
end;
|
||
|
||
sPath:= lpFileName;
|
||
|
||
if (Length(sPath) >= 2) and (sPath[1] = '.') and (sPath[2] = '\') then
|
||
Exit;
|
||
|
||
if StartsText(sPath, 'C:\WINDOWS\') then
|
||
Exit;
|
||
|
||
if EndsText('.dll', sPath) or EndsText('.exe', sPath) then
|
||
Exit;
|
||
|
||
if ContainsText(sPath, '\bs1dc.json') then
|
||
Exit;
|
||
|
||
if IsExceptionPath(sPath) then
|
||
Exit;
|
||
|
||
if (appType_ = catExplorer) then //or (gbsHook_.processType_ = ptExplore)
|
||
begin
|
||
//explorer mtp <20><><EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD> <20>Ʒ<EFBFBD><C6B7><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
//(C:\1234.pdf), c(3), s(5), d(80000000), f(80)
|
||
if (dwCreationDisposition <> OPEN_EXISTING) and
|
||
(dwShareMode <> GENERIC_READ) and
|
||
(dwDesiredAccess <> FILE_FLAG_WRITE_THROUGH) and
|
||
(dwFlagsAndAttributes <> FILE_ATTRIBUTE_NORMAL) then
|
||
begin
|
||
Exit;
|
||
end;
|
||
end;
|
||
|
||
DVLOG('_CreateFileW: hFile(%p), (%s), c(%x), s(%x), d(%x), f(%x)', [Pointer(hFile), PChar(sPath), dwCreationDisposition, dwShareMode, dwDesiredAccess, dwFlagsAndAttributes]);
|
||
fileHandleList_.InsertHandle(hFile, sPath, dwDesiredAccess, dwShareMode, dwCreationDisposition, dwFlagsAndAttributes);
|
||
|
||
end;
|
||
|
||
function TApiHookContents.CloseHandleProc(hFile: THandle): BOOL; stdcall;
|
||
begin
|
||
Result:= False;
|
||
fileHandleList_.DelHandle(hFile);
|
||
end;
|
||
|
||
function TApiHookContents.ReadFileProc(
|
||
hFile: THandle;
|
||
lpBuffer: Pointer;
|
||
nNumberOfBytesToRead: DWORD;
|
||
lpNumberOfBytesRead: PDWORD;
|
||
lpOverlapped: POverlapped
|
||
): BOOL; stdcall;
|
||
const
|
||
INVALID_SET_FILE_POINTER = DWORD(-1);
|
||
|
||
var
|
||
sPath: string;
|
||
dwError: DWORD;
|
||
dwBytesRead: DWORD;
|
||
handleInfo: TFileHandle;
|
||
CurrentPos: DWORD;
|
||
IsStartOfFile: Boolean;
|
||
|
||
begin
|
||
Result:= False;
|
||
if (lpBuffer = nil) or (not ghooked_) then
|
||
begin
|
||
Result := ozReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
|
||
Exit;
|
||
end;
|
||
|
||
if appType_ = catExplorer then
|
||
begin
|
||
Result := ozReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
|
||
Exit;
|
||
end;
|
||
|
||
IsStartOfFile := False;
|
||
|
||
if lpOverlapped <> nil then
|
||
begin
|
||
if (lpOverlapped.Offset = 0) and (lpOverlapped.OffsetHigh = 0) then
|
||
IsStartOfFile := True;
|
||
end
|
||
else
|
||
begin
|
||
|
||
CurrentPos := SetFilePointer(hFile, 0, nil, FILE_CURRENT);
|
||
if (CurrentPos <> INVALID_SET_FILE_POINTER) and (CurrentPos = 0) then
|
||
IsStartOfFile := True;
|
||
end;
|
||
|
||
if not IsStartOfFile then
|
||
begin
|
||
Result := ozReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
|
||
Exit;
|
||
end;
|
||
|
||
Result := ozReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
|
||
|
||
dwError := GetLastError;
|
||
dwBytesRead := 0;
|
||
|
||
if Result then
|
||
begin
|
||
// <20><><EFBFBD><EFBFBD> ȣ<><C8A3> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> ũ<><C5A9> ȹ<><C8B9>
|
||
if lpNumberOfBytesRead <> nil then
|
||
dwBytesRead := lpNumberOfBytesRead^
|
||
else
|
||
dwBytesRead := 0;
|
||
end
|
||
else
|
||
begin
|
||
if dwError = ERROR_IO_PENDING then
|
||
begin
|
||
if (lpOverlapped <> nil) and GetOverlappedResult(hFile, lpOverlapped^, dwBytesRead, FALSE) then
|
||
begin
|
||
end
|
||
else
|
||
begin
|
||
Exit;
|
||
end;
|
||
end
|
||
else
|
||
begin
|
||
Exit;
|
||
end;
|
||
end;
|
||
|
||
if dwBytesRead = 0 then Exit;
|
||
|
||
// DVLOG('ReadFileProc: hFile(%p), nNumberOfBytesToRead(%d)', [Pointer(hFile), nNumberOfBytesToRead]);
|
||
|
||
if fileHandleList_.IsHandle(hFile, handleInfo) then
|
||
begin
|
||
sPath := handleInfo.path;
|
||
handleInfo.Free;
|
||
|
||
fileHandleList_.InsertBufferForHandle(hFile, sPath, lpBuffer, dwBytesRead);
|
||
|
||
DVLOG('ReadFileProc: hFile(%p), sPath(%s), nNumberOfBytesToRead(%d), lpNumberOfBytesRead(%p)',
|
||
[Pointer(hFile), PChar(sPath), nNumberOfBytesToRead, Pointer(lpNumberOfBytesRead)]);
|
||
|
||
end;
|
||
end;
|
||
|
||
function TApiHookContents.DeviceIoControlProc(
|
||
hDevice: THandle;
|
||
dwIoControlCode: DWORD;
|
||
lpInBuffer: Pointer;
|
||
nInBufferSize: DWORD;
|
||
lpOutBuffer: Pointer;
|
||
nOutBufferSize: DWORD;
|
||
lpBytesReturned: PDWORD;
|
||
lpOverlapped: POverlapped
|
||
): BOOL; stdcall;
|
||
var
|
||
data: PByte;
|
||
size: DWORD;
|
||
sbuff: string;
|
||
inSize: DWORD;
|
||
i: Integer;
|
||
fileHandle: TFilehandle;
|
||
sPath: string;
|
||
// var IniFile: TIniFile;
|
||
// var bBlock: Boolean;
|
||
// var bDump: Boolean;
|
||
scsi: PSCSI_PASS_THROUGH_DIRECT;
|
||
// policy: TProcessPolicy;
|
||
// devicePolicy: TDeviceControlPolicy;
|
||
deviceName: string;
|
||
block: Boolean;
|
||
FileUseBlock: TFileUseBlock;
|
||
resultMsg: string;
|
||
curAppType: TCurAppType;
|
||
begin
|
||
data := nil;
|
||
size := nInBufferSize;
|
||
sbuff := '';
|
||
inSize := 0;
|
||
block:= False;
|
||
resultMsg := '';
|
||
Result:= True;
|
||
|
||
|
||
if not ghooked_ then
|
||
begin
|
||
Exit;
|
||
end;
|
||
|
||
if (hDevice = INVALID_HANDLE_VALUE) or (lpInBuffer = nil) or ( nInBufferSize < 32 ) then
|
||
begin
|
||
Exit;
|
||
end;
|
||
|
||
if (dwIoControlCode <> IOCTL_SCSI_PASS_THROUGH_DIRECT) and
|
||
(dwIoControlCode <> IOCTL_WPD_MESSAGE_READWRITE_ACCESS) then
|
||
begin
|
||
Exit;
|
||
end;
|
||
|
||
|
||
var bBlockIf: Boolean := true;
|
||
var IntBlockNewFile: TIntBlockNewFile;
|
||
// DVLOG('DeviceIoControlProc: FileUseBlock(%d)',[DWORD(FileUseBlock)]);
|
||
// if FileUseBlock = fubNone then
|
||
// Exit;
|
||
|
||
// DVLOG('DeviceIoControlProc: hDevice(%p) size(%d) dwIoControlCode(%x)', [Pointer(hDevice), size, dwIoControlCode]);
|
||
|
||
case dwIoControlCode of
|
||
IOCTL_SCSI_PASS_THROUGH_DIRECT:
|
||
begin
|
||
|
||
if appType_ = catLINKENGKM then
|
||
begin
|
||
deviceName:= 'usbTousb';
|
||
curAppType:= catLINKENGKM;
|
||
IntBlockNewFile:= gAppHook.Helper.CtrlOpt.IntUsbToUsbBlockNewFile;
|
||
end
|
||
else if appType_ = catExplorer then
|
||
begin
|
||
deviceName:= 'cdrom';
|
||
curAppType:= catCdrom;
|
||
IntBlockNewFile:= gAppHook.Helper.CtrlOpt.IntCdromBlockNewFile;
|
||
end
|
||
else
|
||
Exit;
|
||
|
||
if IntBlockNewFile.mode = abkNone then
|
||
exit
|
||
else if IntBlockNewFile.mode = abkBlock then
|
||
FileUseBlock := fubBlock
|
||
else
|
||
FileUseBlock := fubMonitor;
|
||
|
||
//DVLOG('DeviceIoControlProc: FileUseBlock(%d)',[DWORD(FileUseBlock)]);
|
||
if FileUseBlock = fubNone then
|
||
Exit;
|
||
|
||
try
|
||
scsi := nil;
|
||
scsi := PSCSI_PASS_THROUGH_DIRECT(lpInBuffer);
|
||
if (scsi.DataIn = SCSI_IOCTL_DATA_OUT) and (scsi.DataBuffer <> nil) then
|
||
begin
|
||
data := PByte(scsi.DataBuffer);
|
||
size := scsi.DataTransferLength;
|
||
|
||
DVLOG('DeviceIoControlProc: scsi.PathId(%d), scsi.ScsiStatus(%d), scsi.TargetId(%d), size(%d)', [DWORD(scsi.PathId), DWORD(scsi.ScsiStatus), DWORD(scsi.TargetId) , DWORD(size)]);
|
||
|
||
end
|
||
else
|
||
begin
|
||
Exit;
|
||
end;
|
||
except
|
||
on E: Exception do
|
||
DVLOG('DeviceIoControlProc: Error accessing DataBuffer: %s', [PChar(E.Message)]);
|
||
end;
|
||
|
||
end;
|
||
IOCTL_WPD_MESSAGE_READWRITE_ACCESS:
|
||
begin
|
||
if appType_ <> catExplorer then
|
||
Exit;
|
||
|
||
deviceName:= 'mtp';
|
||
curAppType:= catMtp;
|
||
IntBlockNewFile:= gAppHook.Helper.CtrlOpt.IntMtpBlockNewFile;
|
||
if IntBlockNewFile.mode = abkNone then
|
||
exit
|
||
else if IntBlockNewFile.mode = abkBlock then
|
||
FileUseBlock := fubBlock
|
||
else
|
||
FileUseBlock := fubMonitor;
|
||
|
||
data := PByte(lpInBuffer);
|
||
size := nInBufferSize;
|
||
end;
|
||
else
|
||
begin
|
||
Exit;
|
||
end;
|
||
end;
|
||
|
||
try
|
||
|
||
//sbuff := UtilGetBufferHex(data, size, 50);
|
||
//DVLOG('_DeviceIoControl: hDevice(%p) size(%d) data(%s)', [Pointer(hDevice), size, PChar(sbuff)]);
|
||
|
||
//if devicePolicy.dump_ = 1 then
|
||
// UtilSaveBufferToFile('c:\MTPMon\dump', data, size);
|
||
|
||
if fileHandleList_.IsBufferCompare('', data, size, fileHandle) then
|
||
begin
|
||
sPath:= fileHandle.path;
|
||
|
||
DVLOG('DeviceIoControlProc: IsBufferCompare ok', []);
|
||
|
||
if FileUseBlock = fubBlock then
|
||
bBlockIf:= CheckAppPolicy(FileUseBlock, sPath, IntBlockNewFile);
|
||
|
||
bBlockIf:= CheckContentPolicy(curAppType, FileUseBlock, sPath, IntBlockNewFile, resultMsg);
|
||
|
||
if not bBlockIf then
|
||
begin
|
||
DVLOG('DeviceIoControlProc: MATCHING!!!!!ALLOW!!!!! hDevice(%p)!! (%s), Matched Path: %s', [Pointer(hDevice), deviceName, PChar(fileHandle.path)]);
|
||
SendHeCopyMessage(curAppType, NOTI_HOOK_MONITOR_ATTACH, sPath, True, deviceName, resultMsg);
|
||
DVLOG('DeviceIoControlProc: MATCHING!!!!!ALLOW!!!!! OK....', []);
|
||
end
|
||
else
|
||
begin
|
||
DVLOG('DeviceIoControlProc: MATCHING!!!!!BLOCK!!!!! hDevice(%p)!! (%s), Matched Path: %s', [Pointer(hDevice), deviceName, PChar(fileHandle.path)]);
|
||
SendHeCopyMessage(curAppType, NOTI_HOOK_BLOCK_ATTACH, sPath, True, deviceName, resultMsg);
|
||
DVLOG('DeviceIoControlProc: MATCHING!!!!!BLOCK!!!!! OK....', []);
|
||
end;
|
||
|
||
fileHandle.Free;
|
||
|
||
if bBlockIf then
|
||
begin
|
||
SetLastError(ERROR_ACCESS_DENIED);
|
||
Result:= False;
|
||
Exit;
|
||
end;
|
||
end;
|
||
|
||
except
|
||
on E: Exception do
|
||
DVLOG('DeviceIoControlProc: Exception: %s', [PChar(E.Message)]);
|
||
end;
|
||
|
||
end;
|
||
|
||
function TApiHookContents.CreateFileMappingProc(
|
||
hReturnFile: THandle;
|
||
hFile: THandle;
|
||
lpFileMappingAttributes: PSecurityAttributes;
|
||
flProtect: DWORD;
|
||
dwMaximumSizeHigh: DWORD;
|
||
dwMaximumSizeLow: DWORD;
|
||
lpName: PWideChar
|
||
): Boolean; stdcall;
|
||
var
|
||
handleInfo: TFileHandle;
|
||
sPath: string;
|
||
buf: array[0..MIN_BUFFERSIZE - 1] of Byte;
|
||
CheckSize: Int64;
|
||
FileSizeHigh: DWORD;
|
||
FileSizeLow: DWORD;
|
||
pMem: Pointer;
|
||
ViewSize: SIZE_T;
|
||
begin
|
||
Result:= False;
|
||
|
||
if not (flProtect in [PAGE_READONLY, PAGE_READWRITE, PAGE_WRITECOPY]) then
|
||
Exit;
|
||
|
||
sPath:= '';
|
||
if fileHandleList_.IsHandle(hFile, handleInfo) then
|
||
begin
|
||
sPath:= handleInfo.path;
|
||
handleInfo.Free;
|
||
end
|
||
else if GetPathFromHandle(hFile, sPath) then
|
||
begin
|
||
|
||
end
|
||
else
|
||
begin
|
||
DVLOG('CreateFileMappingProc: not find handle', []);
|
||
end;
|
||
|
||
if sPath = '' then
|
||
Exit;
|
||
|
||
if EndsText('.dll', sPath) or EndsText('.exe', sPath) then
|
||
Exit;
|
||
|
||
if IsExceptionPath(sPath) then
|
||
Exit;
|
||
|
||
CheckSize := (Int64(dwMaximumSizeHigh) shl 32) or dwMaximumSizeLow;
|
||
if CheckSize = 0 then
|
||
begin
|
||
FileSizeLow := GetFileSize(hFile, @FileSizeHigh);
|
||
if FileSizeLow = INVALID_FILE_SIZE
|
||
then Exit;
|
||
CheckSize := (Int64(FileSizeHigh) shl 32) or FileSizeLow;
|
||
end;
|
||
|
||
if CheckSize < MIN_BUFFERSIZE then
|
||
ViewSize := CheckSize
|
||
else
|
||
ViewSize := MIN_BUFFERSIZE;
|
||
|
||
if ViewSize = 0 then Exit;
|
||
|
||
DVLOG('CreateFileMappingProc: hFile(%p), sPath(%s), CheckSize(%d), dwMaximumSizeLow(%d), flProtect(%x)', [Pointer(hFile), PChar(sPath), CheckSize, dwMaximumSizeLow, flProtect]);
|
||
|
||
try
|
||
pMem := MapViewOfFile(hReturnFile, FILE_MAP_READ, 0, 0, ViewSize);
|
||
|
||
if pMem <> nil then
|
||
begin
|
||
try
|
||
|
||
Move(pMem^, buf[0], ViewSize);
|
||
|
||
fileHandleList_.InsertBufferForHandle(hFile, sPath, @buf, ViewSize);
|
||
|
||
DVLOG('CreateFileMappingProc: Data Cached via Mapping: %s', [PChar(sPath)]);
|
||
finally
|
||
UnmapViewOfFile(pMem);
|
||
end;
|
||
end
|
||
else
|
||
begin
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>α<EFBFBD> (<28><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>)
|
||
DVLOG('CreateFileMappingProc: MapViewOfFile Failed code: %d', [GetLastError]);
|
||
end;
|
||
except
|
||
on E: Exception do
|
||
DVLOG('CreateFileMappingProc: Exception: %s', [PChar(E.Message)]);
|
||
end;
|
||
end;
|
||
|
||
|
||
function TApiHookContents.WSASendProc(
|
||
s: TSocket;
|
||
lpBuffers: PWSABuf;
|
||
dwBufferCount: DWORD;
|
||
lpNumberOfBytesSent: PDWORD;
|
||
dwFlags: DWORD;
|
||
lpOverlapped: POverlapped;
|
||
lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE
|
||
): Integer; stdcall;
|
||
var
|
||
data: PByte;
|
||
size: DWORD;
|
||
sbuff: string;
|
||
inSize: DWORD;
|
||
i: Integer;
|
||
fileHandle: TFilehandle;
|
||
sPath: string;
|
||
|
||
sin: sockaddr_in;
|
||
sinlen: Integer;
|
||
ip: array[0..99] of AnsiChar;
|
||
sIp: string;
|
||
// policy: TProcessPolicy;
|
||
// devicePolicy: TDeviceControlPolicy;
|
||
ObexPacket: TObexPacket;
|
||
opCode: Byte;
|
||
sName: string;
|
||
FileUseBlock: TFileUseBlock;
|
||
deviceName: string;
|
||
IntBlockNewFile: TIntBlockNewFile;
|
||
resultMsg: string;
|
||
curAppType: TCurAppType;
|
||
begin
|
||
|
||
deviceName:= 'BlueTooth';
|
||
FillChar(sin, SizeOf(sin), 0);
|
||
FillChar(ip, SizeOf(ip), 0);
|
||
Result:= 0;
|
||
|
||
if ( not ghooked_ ) or ( lpBuffers = nil )then
|
||
begin
|
||
Exit;
|
||
end;
|
||
|
||
if (appType_ = catFquirt) then
|
||
begin
|
||
IntBlockNewFile:= gAppHook.Helper.CtrlOpt.IntBtBlockNewFile;
|
||
deviceName:= 'BlueTooth';
|
||
curAppType:= catFquirt;
|
||
end
|
||
else if (appType_ = catLINKENGKM) then
|
||
begin
|
||
IntBlockNewFile:= gAppHook.Helper.CtrlOpt.IntUsbToUsbBlockNewFile;
|
||
deviceName:= 'UsbToUsb';
|
||
curAppType:= catLINKENGKM;
|
||
end
|
||
else
|
||
Exit;
|
||
|
||
|
||
if IntBlockNewFile.mode = abkNone then
|
||
exit
|
||
else if IntBlockNewFile.mode = abkBlock then
|
||
FileUseBlock := fubBlock
|
||
else
|
||
FileUseBlock := fubMonitor;
|
||
|
||
var bBlockIf: Boolean := true;
|
||
|
||
DVLOG('WSASendProc: FileUseBlock(%d)',[DWORD(FileUseBlock)]);
|
||
if FileUseBlock = fubNone then
|
||
Exit;
|
||
|
||
ObexPacket := TObexPacket.Create;
|
||
try
|
||
|
||
data:= PByte(lpBuffers.buf);
|
||
size:= lpBuffers.len;
|
||
|
||
if (data = nil) or (Size < MIN_BUFFERSIZE) then
|
||
begin
|
||
Exit;
|
||
end;
|
||
|
||
// sIp:= '';
|
||
opCode:= data[0];
|
||
|
||
// if (opCode <> $82) or (size < 32) then
|
||
// begin
|
||
// DVLOG('_WSASend, : sBuff(%s) size(%d)', [opCode, size]);
|
||
// Result:= WSASendNext(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine);
|
||
// Exit;
|
||
// end;
|
||
|
||
// sinlen := SizeOf(sockaddr_in);
|
||
//
|
||
// getpeername(s, sockaddr(sin), sinlen);
|
||
// sIp:= inet_ntoa(sin.sin_addr);
|
||
|
||
// for i := 0 to size - 1 do
|
||
// sBuff := sBuff + IntToHex(data[i], 2);
|
||
// DVLOG('_WSASend, : sBuff(%s) size(%d)', [sBuff, size]);
|
||
|
||
ObexPacket.Parse(data, size);
|
||
DVLOG('WSASendProc: ObexPacket.Parse End',[]);
|
||
if ObexPacket.Name <> '' then
|
||
begin
|
||
// <20>Ľ̵<C4BD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ӽ<EFBFBD><D3BC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
|
||
// Name <20><><EFBFBD><EFBFBD> (0x01)
|
||
|
||
DVLOG('WSASendProc: --- OBEX <20><>Ŷ <20>м<EFBFBD> ---',[]);
|
||
DVLOG('WSASendProc: Opcode: $%02x, Packet Length: %d, File Name: %s', [ObexPacket.Opcode, ObexPacket.PacketLength, PChar(ObexPacket.Name)]);
|
||
sName:= ObexPacket.Name;
|
||
|
||
// Length <20><><EFBFBD><EFBFBD> (0xC3)
|
||
DVLOG('WSASendProc: Total File Size: %d bytes', [ObexPacket.TotalLength]);
|
||
// Body <20><><EFBFBD><EFBFBD> (0x49)
|
||
if Length(ObexPacket.Body) > 0 then
|
||
begin
|
||
DVLOG('WSASendProc: Body Length: %d bytes', [Length(ObexPacket.Body)]);
|
||
// DVLOG(HexDump(ObexPacket.Body)); // <20>ٵ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (<28>ʿ<EFBFBD><CABF><EFBFBD>)
|
||
end;
|
||
end;
|
||
|
||
ObexPacket.Free;
|
||
|
||
if fileHandleList_.IsBufferCompare(sName, data, size, fileHandle) then
|
||
begin
|
||
sPath:= fileHandle.path;
|
||
|
||
DVLOG('WSASendProc: IsBufferCompare ok, nBlockSizeMB(%d), bUseContentFilter(%d), bFileApproval(%d)',
|
||
[ gAppHook.Helper.CtrlOpt.nBlockSizeMB,
|
||
DWORD(gAppHook.Helper.CtrlOpt.bUseContentFilter),
|
||
DWORD(gAppHook.Helper.CtrlOpt.bFileApproval)
|
||
]);
|
||
|
||
if FileUseBlock = fubBlock then
|
||
begin
|
||
bBlockIf:= CheckAppPolicy(FileUseBlock, sPath, IntBlockNewFile);
|
||
end;
|
||
|
||
bBlockIf:= CheckContentPolicy(curAppType, FileUseBlock, sPath, IntBlockNewFile, resultMsg);
|
||
|
||
if not bBlockIf then
|
||
begin
|
||
DVLOG('WSASendProc: MATCHING!!!!!ALLOW!!!!! hDevice(%p)!!, Path: (%s)', [Pointer(s), PChar(fileHandle.path)]);
|
||
SendHeCopyMessage(curAppType, NOTI_HOOK_MONITOR_ATTACH, sPath, True, deviceName, resultMsg);
|
||
DVLOG('WSASendProc: MATCHING!!!!!ALLOW!!!!! OK....(%d)', [DWORD(bBlockIf)]);
|
||
end
|
||
else
|
||
begin
|
||
DVLOG('WSASendProc: MATCHING!!!!!BLOCK!!!!! hDevice(%p)!!, Path: (%s)', [Pointer(s), PChar(fileHandle.path)]);
|
||
SendHeCopyMessage(curAppType, NOTI_HOOK_BLOCK_ATTACH, sPath, True, deviceName, resultMsg);
|
||
DVLOG('WSASendProc: MATCHING!!!!!BLOCK!!!!! OK....(%d)', [DWORD(bBlockIf)]);
|
||
end;
|
||
|
||
fileHandle.Free;
|
||
|
||
if bBlockIf then
|
||
begin
|
||
Result:= SOCKET_ERROR;
|
||
Exit;
|
||
end;
|
||
end
|
||
else
|
||
begin
|
||
DVLOG('WSASendProc: IsBufferCompare not match', []);
|
||
end;
|
||
except
|
||
on E: Exception do
|
||
DVLOG('WSASendProc: Exception: %s', [PChar(E.Message)]);
|
||
end;
|
||
Result:= 0;
|
||
end;
|
||
|
||
|
||
function ReadFileHook(
|
||
hFile: THandle;
|
||
lpBuffer: Pointer;
|
||
nNumberOfBytesToRead: DWORD;
|
||
lpNumberOfBytesRead: PDWORD;
|
||
lpOverlapped: POverlapped
|
||
): BOOL; stdcall;
|
||
begin
|
||
if gApiHookContents_ = nil then
|
||
begin
|
||
Result:= ozReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
|
||
Exit;
|
||
end;
|
||
Result:= gApiHookContents_.ReadFileProc(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
|
||
end;
|
||
|
||
|
||
function DeviceIoControlHook(
|
||
hDevice: THandle;
|
||
dwIoControlCode: DWORD;
|
||
lpInBuffer: Pointer;
|
||
nInBufferSize: DWORD;
|
||
lpOutBuffer: Pointer;
|
||
nOutBufferSize: DWORD;
|
||
lpBytesReturned: PDWORD;
|
||
lpOverlapped: POverlapped
|
||
): BOOL; stdcall;
|
||
begin
|
||
if gApiHookContents_ <> nil then
|
||
begin
|
||
Result:= gApiHookContents_.DeviceIoControlProc(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
|
||
if not result then
|
||
Exit;
|
||
end;
|
||
|
||
Result:= ozDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
|
||
end;
|
||
|
||
function CreateFileMappingWHook(
|
||
hFile: THandle;
|
||
lpFileMappingAttributes: PSecurityAttributes;
|
||
flProtect: DWORD;
|
||
dwMaximumSizeHigh: DWORD;
|
||
dwMaximumSizeLow: DWORD;
|
||
lpName: PWideChar
|
||
): THandle; stdcall;
|
||
begin
|
||
|
||
Result:= ozCreateFileMappingW(hFile, lpFileMappingAttributes, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, lpName);
|
||
|
||
if (not ghooked_) or (Result = 0) or (Result = INVALID_HANDLE_VALUE) then
|
||
Exit;
|
||
|
||
if hFile = INVALID_HANDLE_VALUE then
|
||
Exit;
|
||
|
||
if gApiHookContents_ <> nil then
|
||
gApiHookContents_.CreateFileMappingProc(Result, hFile, lpFileMappingAttributes, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, lpName);
|
||
end;
|
||
|
||
function WSASendHook(
|
||
s: TSocket;
|
||
lpBuffers: PWSABuf;
|
||
dwBufferCount: DWORD;
|
||
lpNumberOfBytesSent: PDWORD;
|
||
dwFlags: DWORD;
|
||
lpOverlapped: POverlapped;
|
||
lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE
|
||
): Integer; stdcall;
|
||
begin
|
||
|
||
if gApiHookContents_ <> nil then
|
||
begin
|
||
Result:= gApiHookContents_.WSASendProc(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine);
|
||
if Result = SOCKET_ERROR then
|
||
begin
|
||
WSASetLastError(WSAECONNABORTED);
|
||
Exit;
|
||
DVLOG('WSASendHook: Block!!!!!!!!!!!!',[]);
|
||
end;
|
||
end;
|
||
|
||
Result:= ozWSASend(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine);
|
||
|
||
end;
|
||
|
||
end.
|
||
|
||
|
||
|