BSOne.SFC/Tocsg.Module/Bs1Flt/MTPMon/MTPControl/ApiHookContents.pas

1258 lines
34 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

unit ApiHookContents;
interface
uses
Winapi.Windows, System.SysUtils, System.Classes, Winapi.WinSock2, StrUtils,
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(var FileUseBlock: TFileUseBlock; const sPath: string): Boolean;
function CheckExternalPolicy(Cmd: Integer;
const Data: string): Boolean;
function CheckAppPolicy(var FileUseBlock: TFileUseBlock; sPath: string): Boolean;
procedure SendHeCopyMessage(cmd: DWORD; const sPath: string; bExistsFile: Boolean; deviceName: 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, DefineHelper, GlobalDefine, ApiHookFile, superobject;
function CheckExternalPolicy(Cmd: Integer; const Data: string): Boolean;
begin
var hReceiver := FindWindow(PChar('TDlgeCrmHeMain'), nil);
var hReceiver1 := FindWindow(nil, PCHar('BSOne V2.0'));
DVLOG('CheckExternalPolicy: hReceiver (%d), (%d)', [DWORD(hReceiver), DWORD(hReceiver1)]);
Result := SendCopyData(gAppHook.Helper.CtrlOpt.hRcvWnd, Cmd, Data) = CMD_RESULT_ALLOW;
end;
function CheckAppPolicy(var FileUseBlock: TFileUseBlock; sPath: string): 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 CheckContentPolicy(var FileUseBlock: TFileUseBlock; const sPath: string): Boolean;
var
O: ISuperObject;
begin
Result := True;
// <20><><EFBFBD><EFBFBD> ũ<><C5A9> <20>˻<EFBFBD>
if (FileUseBlock = fubBlock) and (gAppHook.Helper.CtrlOpt.nBlockSizeMB > 0) then
begin
O := SO;
O.S['Path'] := sPath;
O.I['Type'] := Integer(gAppHook.Helper.CurAppType);
O.S['MName'] := gAppHook.ModuleName;
if not CheckExternalPolicy(HPCMD_CHECK_SIZE, O.AsString) then
begin
DVLOG('CheckContentPolicy: HPCMD_CHECK_SIZE not bUseContentFilter(%d)', [DWORD(gAppHook.Helper.CtrlOpt.bUseContentFilter)]);
if not gAppHook.Helper.CtrlOpt.bUseContentFilter then
FileUseBlock := fubMonitor;
end
else
begin
DVLOG('CheckContentPolicy: HPCMD_CHECK_SIZE ok bUseContentFilter(%d)', [DWORD(gAppHook.Helper.CtrlOpt.bUseContentFilter)]);
Result := False;
end;
end;
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>͸<EFBFBD> (DLP <20><>)
if Result and gAppHook.Helper.CtrlOpt.bUseContentFilter then
begin
O := SO;
O.S['Path'] := sPath;
O.I['Type'] := Integer(gAppHook.Helper.CurAppType);
O.S['MName'] := gAppHook.ModuleName;
if not CheckExternalPolicy(HPCMD_CHECK_CONTENT, O.AsString) then
begin
DVLOG('CheckContentPolicy: HPCMD_CHECK_CONTENT not FileUseBlock(%d)', [DWORD(FileUseBlock)]);
if FileUseBlock = fubBlock then
FileUseBlock := fubMonitor;
Result := False;
end
else
begin
DVLOG('CheckContentPolicy: HPCMD_CHECK_CONTENT ok FileUseBlock(%d)', [DWORD(FileUseBlock)]);
Result := True;
end;
end;
end;
procedure SendHeCopyMessage(cmd: DWORD; const sPath: string; bExistsFile: Boolean; deviceName: string);
var
llInfo: LONGLONG;
Send: ISendPacket;
begin
try
case cmd of
NOTI_HOOK_MONITOR_ATTACH,
NOTI_HOOK_BLOCK_ATTACH :
begin
llInfo := Integer(gAppHook.Helper.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;
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 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;
if gAppHook.Helper.CtrlOpt.FileUseBlock = fubNone then
Exit;
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;
begin
data := nil;
size := nInBufferSize;
sbuff := '';
inSize := 0;
block:= False;
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;
FileUseBlock := gAppHook.Helper.CtrlOpt.FileUseBlock;
var bBlockIf: Boolean := true;
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
deviceName:= 'usbTousb'
else if appType_ = catExplorer then
deviceName:= 'cdrom'
else
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';
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);
bBlockIf:= CheckContentPolicy(FileUseBlock, sPath);
if FileUseBlock = fubMonitor then
begin
DVLOG('DeviceIoControlProc: MATCHING!!!!!ALLOW!!!!! hDevice(%p)!! (%s), Matched Path: %s', [Pointer(hDevice), deviceName, PChar(fileHandle.path)]);
SendHeCopyMessage(NOTI_HOOK_MONITOR_ATTACH, sPath, True, deviceName);
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(NOTI_HOOK_BLOCK_ATTACH, sPath, True, deviceName);
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;
begin
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) and (appType_ <> catLINKENGKM) then
begin
Exit;
end;
FileUseBlock := gAppHook.Helper.CtrlOpt.FileUseBlock;
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
bBlockIf:= CheckAppPolicy(FileUseBlock, sPath);
bBlockIf:= CheckContentPolicy(FileUseBlock, sPath);
if FileUseBlock = fubMonitor then
begin
DVLOG('WSASendProc: MATCHING!!!!!ALLOW!!!!! hDevice(%p)!!, Path: (%s)', [Pointer(s), PChar(fileHandle.path)]);
SendHeCopyMessage(NOTI_HOOK_MONITOR_ATTACH, sPath, True, 'BlueTooth');
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(NOTI_HOOK_BLOCK_ATTACH, sPath, True, 'BlueTooth');
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.