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

1535 lines
44 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 BsoneMtpHook;
interface
uses
Windows, Winapi.ShellAPI, System.Classes, Generics.Collections,
Generics.Defaults, System.IOUtils, System.SysUtils, System.SyncObjs, System.StrUtils, IniFiles, Winapi.WinSock2, System.Math,
winapi.WinInet, SuperObject,
madCodeHook, madStrings, madTypes,
DefineHelper,
GlobalDefine,
BsoneDebug,
FileHandleListUnit,
Bs1ContentsFlowPolicyUnit,
ObexParserUnit,
ApiHookExplorer,
BsoneUtil;
const
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;
type
TBsoneMtpHook = class
public
installpath_: string;
currentPath_: string;
processName_: string;
processType_: TProcessType;
fileHandleList_: TFileHandleList;
policy_: TPolicyManager;
constructor Create(h: HMODULE);
destructor Destroy; override;
function HookInit(h: HMODULE): integer; stdcall;
function HookCleanup(): Integer; stdcall;
function GetPathFromHandle(hFile: THandle; out sPath: string): BOOL; stdcall;
end;
TCreateFileW = function(
lpFileName: LPCWSTR;
dwDesiredAccess, dwShareMode: DWORD;
lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD;
hTemplateFile: THandle
): THandle; stdcall;
TCreateFileA = function(
lpFileName: PAnsiChar;
dwDesiredAccess, dwShareMode: DWORD;
lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD;
hTemplateFile: THandle
): THandle; stdcall;
TCloseHandle = function(hObject: THandle): BOOL; stdcall;
TDeviceIoControl = function(
hDevice: THandle;
dwIoControlCode: DWORD;
lpInBuffer: Pointer;
nInBufferSize: DWORD;
lpOutBuffer: Pointer;
nOutBufferSize: DWORD;
lpBytesReturned: PDWORD;
lpOverlapped: POverlapped
): BOOL; stdcall;
TReadFile = function(
hFile: THandle;
lpBuffer: Pointer;
nNumberOfBytesToRead: DWORD;
lpNumberOfBytesRead: PDWORD;
lpOverlapped: POverlapped
): BOOL; stdcall;
TSend = function(s: TSocket; buf: PAnsiChar; len: Integer; flags: Integer): Integer; stdcall;
TWriteFile = function(
hFile: THandle;
const Buffer;
nNumberOfBytesToWrite: DWORD;
lpNumberOfBytesWritten: PDWORD;
lpOverlapped: POverlapped
): BOOL; stdcall;
TWSASend = function(
s: TSocket;
lpBuffers: PWSABuf;
dwBufferCount: DWORD;
lpNumberOfBytesSent: PDWORD;
dwFlags: DWORD;
lpOverlapped: POverlapped;
lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE
): Integer; stdcall;
TCreateFileMappingW = function(
hFile: THandle;
lpFileMappingAttributes: PSecurityAttributes;
flProtect: DWORD;
dwMaximumSizeHigh: DWORD;
dwMaximumSizeLow: DWORD;
lpName: PWideChar
): THandle; stdcall;
function _CreateFileW(lpFileName: LPCWSTR; dwDesiredAccess, dwShareMode: DWORD;
lpSecurityAttributes: PSecurityAttributes;
dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): THandle; stdcall;
function _CloseHandle(hObject: THandle): BOOL; stdcall;
function _DeviceIoControl(
hDevice: THandle;
dwIoControlCode: DWORD;
lpInBuffer: Pointer;
nInBufferSize: DWORD;
lpOutBuffer: Pointer;
nOutBufferSize: DWORD;
lpBytesReturned: PDWORD;
lpOverlapped: POverlapped
): BOOL; stdcall;
function _ReadFile(
hFile: THandle;
lpBuffer: Pointer;
nNumberOfBytesToRead: DWORD;
lpNumberOfBytesRead: PDWORD;
lpOverlapped: POverlapped
): BOOL; stdcall;
function _CreateFileMappingW(
hFile: THandle;
lpFileMappingAttributes: PSecurityAttributes;
flProtect: DWORD;
dwMaximumSizeHigh: DWORD;
dwMaximumSizeLow: DWORD;
lpName: PWideChar
): THandle; stdcall;
function _WSASend(
s: TSocket;
lpBuffers: PWSABuf;
dwBufferCount: DWORD;
lpNumberOfBytesSent: PDWORD;
dwFlags: DWORD;
lpOverlapped: POverlapped;
lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE
): Integer; stdcall;
function _send(s: TSocket; const buf: PAnsiChar; len: Integer; flags: Integer): Integer; stdcall;
function _WriteFile(
hFile: THandle;
const Buffer: Pointer;
nNumberOfBytesToWrite: DWORD;
lpNumberOfBytesWritten: PDWORD;
lpOverlapped: POverlapped
): BOOL; stdcall;
function SendUI(block: Boolean; deviceName: string; sPath: string ; dPath: string): BOOL; stdcall;
var
gbsHook_: TBsoneMtpHook = nil;
ghooked_: boolean = False;
implementation
var
CreateFileWNext: TCreateFileW = nil;
CreateFileANext: TCreateFileA = nil;
CloseHandleNext: TCloseHandle = nil;
DeviceIoControlNext: TDeviceIoControl = nil;
CreateFileMappingWNext: TCreateFileMappingW = nil;
WSASendNext: TWSASend = nil;
ReadFileNext: TReadFile = nil;
sendNext: TSend = nil;
WriteFileNext: TWriteFile = nil;
gProcessMap: TDictionary<string, TProcessType>;
function SendUI(block: Boolean; deviceName: string; sPath: string ; dPath: string): BOOL; stdcall;
var
hReceiver: HWND;
begin
hReceiver := FindWindow(PChar(BS1DC_CLASS_NAME), nil);
var state: LRESULT;
if hReceiver <> 0 then
begin
var O: ISuperObject := SO;
O.S['T'] := deviceName;
O.S['S'] := sPath;
O.S['D'] := dPath;
O.I['E'] := 1;
O.B['B'] := block;
O.B['N'] := true; // <20><>Ʈ<EFBFBD><C6AE>ũ <20><><EFBFBD><EFBFBD>?
state:= SendCopyData(hReceiver, HPCMD_FILE_OPERATION_NOTI, O.AsJSon);
LOG('ProcMon: SendCopyData : %d', [DWORD(state)]);
end
else
begin
LOG('ProcMon: hReceiver not find window.......', []);
end;
end;
constructor TBsoneMtpHook.Create(h: HMODULE);
var
buffer: array[0..MAX_PATH - 1] of WideChar;
processPolicy: TProcessPolicy;
begin
inherited Create;
GetModuleFileName(0, buffer, MAX_PATH);
processName_:= TPath.GetFileName(buffer);
var process := TPath.GetFileNameWithoutExtension(processName_).ToUpper;
gProcessMap := TDictionary<string, TProcessType>.Create;
gProcessMap.Add('FSQUIRT', ptFquirt);
gProcessMap.Add('EXPLORER', ptExplore);
gProcessMap.Add('CMD', ptCmd);
gProcessMap.Add('LINKENGKM', ptLINKENGKM); // LinkEngKM
if not gProcessMap.TryGetValue(process, processType_) then
begin
processType_:= ptNone;
Exit;
end;
// if not (SameText(processName_, 'explorer.exe') //Common(MTP)
// or SameText(processName_, 'fsquirt.exe') or SameText(processName_, 'cmd.exe')) then //BlueToot
policy_:= TPolicyManager.Create('C:\DeviceLock\bs1dc.json', processName_);
policy_.GetPolicy;
if policy_.CurrentProcessPolicy = nil then
Exit;
processPolicy:= policy_.CurrentProcessPolicy;
for var s in processPolicy.DeviceTypes do
LOG('TBsoneMtpHook.Create, : %s (%s)', [processName_, s]);
gbsHook_ := Self;
fileHandleList_:= TFileHandleList.Create;
HookInit(h);
if processType_ = ptExplore then
begin
LOG('TBsoneMtpHook.Create, : (%s), InstallFileOperationHooks', [processName_]);
InstallFileOperationHooks;
end;
ghooked_:= True;
end;
destructor TBsoneMtpHook.Destroy;
begin
ghooked_:= False;
UninstallFileOperationHooks;
HookCleanup;
FreeAndNil(fileHandleList_);
FreeAndNil(gProcessMap);
FreeAndNil(Policy_);
gbsHook_ := nil;
inherited Destroy;
end;
function TBsoneMtpHook.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;
LOG('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>
LOG('GetPathFromHandle, GetFinalPathNameByHandleW failed on second attempt: hFile(%x), GE(%x)', [hFile, GetLastError()]);
sPath := '';
Result := FALSE;
end;
end
else
begin
LOG('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 TBsoneMtpHook.HookInit(h: HMODULE): integer; stdcall;
begin
CollectHooks;
HookAPI('kernelbase.dll', 'CreateFileW', @_CreateFileW, @CreateFileWNext);
HookAPI('kernelbase.dll', 'CloseHandle', @_CloseHandle, @CloseHandleNext);
HookAPI('kernel32.dll', 'WriteFile', @_WriteFile, @WriteFileNext);
HookAPI('kernelbase.dll', 'DeviceIoControl', @_DeviceIoControl, @DeviceIoControlNext);
HookAPI('kernelbase.dll', 'CreateFileMappingW', @_CreateFileMappingW, @CreateFileMappingWNext);
HookAPI('kernelbase.dll', 'ReadFile', @_ReadFile, @ReadFileNext);
HookAPI('Ws2_32.dll', 'WSASend', @_WSASend, @WSASendNext);
FlushHooks;
LOG('HookInit, processName(%s)--', [PChar(processName_)]);
end;
function TBsoneMtpHook.HookCleanup(): Integer; stdcall;
begin
LOG('HookCleanup, --', []);
end;
function 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));
// // <20>Էµ<D4B7> <20><><EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ġ <20><><EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE> (<28><><EFBFBD>ҹ<EFBFBD><D2B9><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD> UpCase <20>ʿ<EFBFBD>)
// if UpCase(WindowsDir[0]) = UpCase(DriveLetter) then
// begin
// if g_driverletter = DriveLetter then
// begin
// bDriverMatch := True;
// end
// else
// begin
// bDriverMatch := False;
// // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>α<EFBFBD> <20><><EFBFBD><EFBFBD>
// DebugLog(Format('GetDriveBusType: Driver MisMatch PreDrive(%s) CurrentDrive(%s)!! Get Try BusType',
// [g_driverletter, DriveLetter]));
// end;
//
// // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD> ij<><C4B3>
// g_driverletter := DriveLetter;
// end;
// // ij<>̵<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><>ġ<EFBFBD>ϸ<EFBFBD> Unknown <20><><EFBFBD><EFBFBD> (C++ <20><><EFBFBD><EFBFBD> <20>״<EFBFBD><D7B4><EFBFBD> <20>ݿ<EFBFBD>)
// if bDriverMatch then
// begin
// Result := BusTypeUnknown;
// Exit;
// end;
// 2. <20><>ġ <20>ڵ<EFBFBD> <20><><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>: \\.\C:
VolumePath := Format('\\.\%s:', [DriveLetter]);
hDevice := CreateFileWNext(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 DeviceIoControlNext(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 DeviceIoControlNext(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
CloseHandleNext(hDevice);
end;
Result := ReturnType;
end;
function 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 := CreateFileWNext(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
CloseHandleNext(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 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 := CreateFileWNext(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 @ReadFileNext = nil then
bReadSuccess := ReadFile(fp, pbuffer^, buffersize, Retsize, nil)
else
bReadSuccess := ReadFileNext(fp, pbuffer, buffersize, @Retsize, nil);
Result := TRUE;
finally
CloseHandleNext(fp);
end;
end;
function _CreateFileW(lpFileName: LPCWSTR; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): THandle; stdcall;
var
sPath: string;
begin
sPath := lpFileName;
Result := CreateFileWNext(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
if not ghooked_ then
Exit;
if (Result = 0) or (Result = INVALID_HANDLE_VALUE) then
begin
// LOG('_CreateFileW: INVALID_HANDLE_VALUE (%s)', [PChar(sPath)]);
Exit;
end;
if dwCreationDisposition = CREATE_NEW then
Exit;
if dwCreationDisposition = TRUNCATE_EXISTING then
Exit;
// if (dwDesiredAccess and GENERIC_READ) = 0 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 (gbsHook_.processType_ = ptFquirt) then //or (gbsHook_.processType_ = ptExplore)
begin
if dwFlagsAndAttributes = 0 then
Exit;
end;
if (Length(sPath) >= 2) and (sPath[1] = '.') and (sPath[2] = '\') then
Exit;
if StartsText('C:\WINDOWS\', sPath) then
Exit;
if SameText(ExtractFileExt(sPath), '.dll') then
Exit;
if ContainsText(sPath, '\bs1dc.json') then
Exit;
if ContainsText(sPath, '\\.\MountPointManager') then
Exit;
if gbsHook_.policy_.IsExceptionPath(sPath) then
Exit;
// if ContainsText(sPath, 'AppData\Roaming\Microsoft\Windows\Recent') or
// ContainsText(sPath, '\desktop.ini') or
// ContainsText(sPath, 'ProgramData\Microsoft\Windows\AppRepository\Packages') or
// ContainsText(sPath, 'AppData\Local\Microsoft\Windows\Caches') or
// ContainsText(sPath, 'AppData\Roaming\Microsoft\Internet Explorer\Quick Launch') or
// ContainsText(sPath, 'AppData\Roaming\Microsoft\Windows\SendTo') or
// ContainsText(sPath, 'AppData\Local\Microsoft\Windows\INetCache') or
// ContainsText(sPath, 'AppData\Local\Microsoft\Windows\Explorer') or
// ContainsText(sPath, 'AppData\Roaming\Microsoft\Windows\Themes\') or
// ContainsText(sPath, 'AppData\Local\Packages\') or
// ContainsText(sPath, 'wpd_data_') then
// Exit;
// var isTarget := ContainsText(sPath, 'mgkim.vmw11\Desktop\mtptest\');
// if isTarget then
// begin
LOG('_CreateFileW: (%p), (%s), dwCreationDisposition(%x), dwShareMode(%x), dwDesiredAccess(%x), dwFlagsAndAttributes(%x)', [Pointer(Result), PChar(sPath), dwCreationDisposition, dwShareMode, dwDesiredAccess, dwFlagsAndAttributes]);
gbsHook_.fileHandleList_.InsertHandle(Result, sPath, dwDesiredAccess, dwShareMode, dwCreationDisposition, dwFlagsAndAttributes);
// end;
end;
function _CreateFileMappingW(
hFile: THandle;
lpFileMappingAttributes: PSecurityAttributes;
flProtect: DWORD;
dwMaximumSizeHigh: DWORD;
dwMaximumSizeLow: DWORD;
lpName: PWideChar
): THandle; stdcall;
var
handleInfo: TFileHandle;
sPath: string;
buf: array[0..MIN_BUFFERSIZE - 1] of Byte;
policy: TProcessPolicy;
bufSize: DWORD;
CheckSize: Int64;
FileSizeHigh: DWORD;
FileSizeLow: DWORD;
pMem: Pointer;
begin
Result:= CreateFileMappingWNext(hFile, lpFileMappingAttributes, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, lpName);
if (not ghooked_) or (Result = 0) then
Exit;
if hFile = INVALID_HANDLE_VALUE then
Exit;
sPath:= '';
if gbsHook_.fileHandleList_.IsHandle(hFile, handleInfo) then
begin
sPath:= handleInfo.path;
handleInfo.Free;
end
else if gbsHook_.GetPathFromHandle(hFile, sPath) then
begin
end
else
begin
LOG('_CreateFileMappingW, not find handle', []);
end;
if sPath = '' then
Exit;
if ContainsText(sPath, '\bs1dc.json') then
Exit;
if gbsHook_.policy_.IsExceptionPath(sPath) then
Exit;
// if ContainsText(sPath, 'AppData\Roaming\Microsoft\Windows\Recent') or
// ContainsText(sPath, '\desktop.ini') or
// ContainsText(sPath, 'ProgramData\Microsoft\Windows\AppRepository\Packages') or
// ContainsText(sPath, 'AppData\Local\Microsoft\Windows\Caches') or
// ContainsText(sPath, 'AppData\Roaming\Microsoft\Internet Explorer\Quick Launch') or
// ContainsText(sPath, 'AppData\Roaming\Microsoft\Windows\SendTo') or
// ContainsText(sPath, 'AppData\Local\Microsoft\Windows\INetCache') or
// ContainsText(sPath, 'wpd_data_') 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; // <20><><EFBFBD><EFBFBD> <20><> Ż<><C5BB>
CheckSize := (Int64(FileSizeHigh) shl 32) or FileSizeLow;
end;
//if CheckSize < MIN_BUFFERSIZE then Exit;
LOG('_CreateFileMappingW, hFile(%p), sPath(%s), dwMaximumSizeLow(%d), flProtect(%x)', [Pointer(hFile), PChar(sPath), dwMaximumSizeLow, flProtect]);
// bufSize:= Sizeof(buf);
// if GetFileReadBuffer(sPath, @buf, bufSize) then
// begin
// gbsHook_.fileHandleList_.InsertBufferForHandle(hFile, sPath, @buf, Sizeof(buf));
// end
// else
// LOG('_CreateFileMappingW, GetFileReadBuffer Fail!!', []);
try
// FILE_MAP_READ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>պκ<D5BA>(MIN_BUFFERSIZE)<29><> <20><><EFBFBD><EFBFBD>
pMem := MapViewOfFile(Result, FILE_MAP_READ, 0, 0, MIN_BUFFERSIZE);
if pMem <> nil then
begin
try
// <20>޸<EFBFBD><DEB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>۷<EFBFBD> <20><><EFBFBD><EFBFBD>
Move(pMem^, buf[0], MIN_BUFFERSIZE);
// <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD>
// (<28><><EFBFBD><EFBFBD>: InsertBufferForHandle <20><><EFBFBD>ο<EFBFBD><CEBF><EFBFBD> buf<75><66> <20><><EFBFBD><EFBFBD><E7BABB> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
gbsHook_.fileHandleList_.InsertBufferForHandle(hFile, sPath, @buf, MIN_BUFFERSIZE);
LOG('_CreateFileMappingW 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><>)
LOG('_CreateFileMappingW: MapViewOfFile Failed code: %d', [GetLastError]);
end;
except
on E: Exception do
LOG('_CreateFileMappingW Exception: %s', [PChar(E.Message)]);
end;
end;
function _ReadFile(
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
// 1. <20><20><>ȿ<EFBFBD><C8BF> <20>˻<EFBFBD>
if (lpBuffer = nil) or (not ghooked_) then
begin
Result := ReadFileNext(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
Exit;
end;
// 2. Ž<><C5BD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3> (<28>ʿ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD>)
if gbsHook_.processType_ = ptExplore then
begin
Result := ReadFileNext(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
Exit;
end;
// ---------------------------------------------------------------------------
// [<5B><>û<EFBFBD>Ͻ<EFBFBD> <20>κ<EFBFBD>] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(Offset 0)<29><><EFBFBD><EFBFBD> Ȯ<><C8AE>
// ---------------------------------------------------------------------------
IsStartOfFile := False;
if lpOverlapped <> nil then
begin
// [Case A] <20>񵿱<EFBFBD>(Overlapped) I/O: <20><><EFBFBD><EFBFBD>ü<EFBFBD><C3BC> Offset <20>ʵ带 Ȯ<><C8AE><EFBFBD>ؾ<EFBFBD> <20><>
// Offset<65><74> OffsetHigh<67><68> <20><> <20><> 0<>̾<EFBFBD><CCBE><EFBFBD> <20><>¥ 0<><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (lpOverlapped.Offset = 0) and (lpOverlapped.OffsetHigh = 0) then
IsStartOfFile := True;
end
else
begin
// [Case B] <20><><EFBFBD><EFBFBD>(Synchronous) I/O: SetFilePointer<65><72> <20><><EFBFBD><EFBFBD> <20><>ġ Ȯ<><C8AE>
// 0, nil, FILE_CURRENT -> <20><>ġ <20>̵<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20><>ȯ
CurrentPos := SetFilePointer(hFile, 0, nil, FILE_CURRENT);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ƴϰ<C6B4>, <20><>ġ<EFBFBD><C4A1> 0<≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (CurrentPos <> INVALID_SET_FILE_POINTER) and (CurrentPos = 0) then
IsStartOfFile := True;
end;
// [<5B>ٽ<EFBFBD>] <20><><EFBFBD><EFBFBD> <20>κ<EFBFBD><CEBA><EFBFBD> <20>ƴϸ<C6B4> -> <20>׳<EFBFBD> <20>а<EFBFBD> <20><><EFBFBD><EFBFBD> (<28>˻<EFBFBD> <20>н<EFBFBD>)
if not IsStartOfFile then
begin
Result := ReadFileNext(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
Exit;
end;
// ---------------------------------------------------------------------------
// [<5B><><EFBFBD><EFBFBD><E2BCAD><EFBFBD>ʹ<EFBFBD> Offset 0<><30> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>]
// ---------------------------------------------------------------------------
// 3. <20><><EFBFBD><EFBFBD> API ȣ<><C8A3>
Result := ReadFileNext(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
dwError := GetLastError;
// 4. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ũ<><C5A9> Ȯ<><C8AE> (<28>񵿱<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ذ<EFBFBD> <20><><EFBFBD><EFBFBD>)
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
// <20><><EFBFBD><EFBFBD> <20>Ǵ<EFBFBD> Pending <20><><EFBFBD><EFBFBD>
if dwError = ERROR_IO_PENDING then
begin
// <20>񵿱<EFBFBD><F1B5BFB1><EFBFBD><EFBFBD><EFBFBD> <20>̹<EFBFBD> <20>Ϸ<EFBFBD><CFB7>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD> '<27><><EFBFBD><EFBFBD>' Ȯ<><C8AE> (<28><><EFBFBD><EFBFBD> <20>ð<EFBFBD> <20><><EFBFBD><EFBFBD>)
if (lpOverlapped <> nil) and GetOverlappedResult(hFile, lpOverlapped^, dwBytesRead, FALSE) then
begin
// <20>Ϸ<EFBFBD><CFB7><EFBFBD> -> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ĸó <20><><EFBFBD><EFBFBD>
end
else
begin
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>(Pending) -> <20><>ŷ<EFBFBD><C5B7><EFBFBD><EFBFBD> <20><><EFBFBD>ٸ<EFBFBD><D9B8><EFBFBD> <20><> <20>ɸ<EFBFBD><C9B8>Ƿ<EFBFBD> <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD>
Exit;
end;
end
else
begin
// <20><>¥ <20><><EFBFBD><EFBFBD> -> <20><><EFBFBD><EFBFBD>
Exit;
end;
end;
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>н<EFBFBD>
if dwBytesRead = 0 then Exit;
// 5. <20>ڵ<EFBFBD> ij<><C4B3> Ȯ<><C8AE> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ĸó
// (<28>̹<EFBFBD> Offset 0<><30><EFBFBD><EFBFBD> Ȯ<>εǾ<CEB5><C7BE><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20>Ƚ<EFBFBD><C8BD>ϰ<EFBFBD> ĸó)
if gbsHook_.fileHandleList_.IsHandle(hFile, handleInfo) then
begin
sPath := handleInfo.path;
handleInfo.Free;
// LOG('_ReadFile [Offset 0]: %s, Bytes: %d', [PChar(sPath), dwBytesRead]);
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ũ<><C5A9>(dwBytesRead)<29><>ŭ <20><><EFBFBD><EFBFBD> ĸó
gbsHook_.fileHandleList_.InsertBufferForHandle(hFile, sPath, lpBuffer, dwBytesRead);
LOG('_ReadFile, hFile(%p), sPath(%s), nNumberOfBytesToRead(%d), lpNumberOfBytesRead(%p)',
[Pointer(hFile), PChar(sPath), nNumberOfBytesToRead, Pointer(lpNumberOfBytesRead)]);
end;
end;
//function _ReadFile(hFile: THandle; lpBuffer: Pointer; nNumberOfBytesToRead: DWORD; lpNumberOfBytesRead: PDWORD; lpOverlapped: POverlapped): BOOL; stdcall;
//var
// sPath: string;
// dwError: DWORD;
// state: DWORD;
// dwValue: DWORD;
// handleInfo: TFileHandle;
//
// lFilePointer: DWORD;
// firstOffset: DWORD;
// totalsize: DWORD;
// IsStartOfFile: Boolean;
//begin
//
// if (lpBuffer = nil) and (not ghooked_) then
// begin
// Result := ReadFileNext(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
// Exit;
// end;
//
// if gbsHook_.processType_ = ptExplore then
// begin
// Result := ReadFileNext(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
// Exit;
// end;
//
// totalsize:= GetFileSize( hFile, 0 );
// if (nNumberOfBytesToRead < MIN_BUFFERSIZE) and (totalsize > MIN_BUFFERSIZE ) then
// begin
//
// Result := ReadFileNext(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
// Exit;
// end;
//
// IsStartOfFile := False;
//
// lFilePointer:= 0;
// lFilePointer:= SetFilePointer(hFile, 0, nil, FILE_CURRENT);
//
// Result := ReadFileNext(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
// dwError:= GetLastError;
//
//// if lFilePointer <> 0 then
//// Exit;
//
// if Result = False then
// begin
//
//// gbsHook_.GetPathFromHandle(hFile, sPath);.
//// LOG('_ReadFilePost, hFile(%p), dwError(%x), lpOverlapped(%p)', [Pointer(hFile), dwError, Pointer(lpOverlapped)]);
//
// if dwError = ERROR_IO_PENDING then
// begin
// if lpOverlapped <> nil then
// begin
// if (lpOverlapped.hEvent = THandle(nil)) then
// Exit;
//
// state := WaitForSingleObject(lpOverlapped.hEvent, 1000);
// Result := GetOverlappedResult(hFile, lpOverlapped^, dwValue, FALSE);
// LOG('_ReadFilePost, hFile(%p), dwValue(%d), lpOverlapped(%p)', [Pointer(hFile), dwValue, Pointer(lpOverlapped)]);
// if (lpNumberOfBytesRead <> nil) then
// begin
// lpNumberOfBytesRead^ := dwValue;
// end;
//
// if dwValue = 0 then
// Exit;
//
// end;
// end
// else if dwError <> ERROR_SUCCESS then
// begin
// Exit;
// end;
// end;
//
// if gbsHook_.fileHandleList_.IsHandle(hFile, handleInfo) then
// begin
// sPath:= handleInfo.path;
// handleInfo.Free;
//// LOG('_ReadFile, IsHandle (%p)', [Pointer(hFile)]);
// end
//// else if gbsHook_.GetPathFromHandle(hFile, sPath) then
//// begin
//// LOG('_ReadFile, GetPathFromHandle', []);
//// if gbsHook_.policy_.IsExceptionPath(sPath) then
//// Exit;
//// end
// else
// begin
//// LOG('_ReadFile, not find handle (%p), GE(%x)', [Pointer(hFile), GetLastError]);
// Exit;
// end;
//
// LOG('_ReadFile, hFile(%p), sPath(%s), nNumberOfBytesToRead(%d), lpNumberOfBytesRead(%p), lFilePointer(%d), totalsize(%d)',
// [Pointer(hFile), PChar(sPath), nNumberOfBytesToRead, Pointer(lpNumberOfBytesRead), lFilePointer, totalsize]);
//
// gbsHook_.fileHandleList_.InsertBufferForHandle(hFile, sPath, lpBuffer, nNumberOfBytesToRead);
//
//end;
function _WriteFile(
hFile: THandle;
const Buffer: Pointer;
nNumberOfBytesToWrite: DWORD;
lpNumberOfBytesWritten: PDWORD;
lpOverlapped: POverlapped
): BOOL; stdcall;
Label Cleanup;
var
sPath: string;
handleInfo: TFileHandle;
dwOffset: DWORD;
dwDriveType: DWORD;
deviceName: string;
devicePolicy: TDeviceControlPolicy;
sbuff: string;
fileHandle: TFilehandle;
bustype: DWORD;
block: Boolean;
begin
sPath:= '';
dwOffset:= 0;
block:= False;
//bustype:= DWORD(BusTypeUnknown);
if (not ghooked_) or ( Buffer = nil ) then
goto Cleanup;
if (hFile = INVALID_HANDLE_VALUE) or (hFile = 0) then
goto Cleanup;
if (gbsHook_.processType_ <> ptExplore) and (gbsHook_.processType_ <> ptCmd) then
goto Cleanup;
if nNumberOfBytesToWrite < MIN_BUFFERSIZE then
goto Cleanup;
LOG('_WriteFile, hFile (%p), nNumberOfBytesToWrite (%d), (%p)', [Pointer(hFile), nNumberOfBytesToWrite, Pointer(lpOverlapped)]);
/// Write <20>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ù<><C3B9>° <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>۸<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>. <20>ӵ<EFBFBD> <20><><EFBFBD><EFBFBD>
if lpOverlapped = nil then
begin
dwOffset:= SetFilePointer( hFile, 0, nil, FILE_CURRENT );
if (dwOffset <> DWORD(-1)) and ( dwOffset <> 0 ) then
goto Cleanup;
end
else
begin
if lpOverlapped.Offset <> 0 then
goto Cleanup;
end;
if gbsHook_.GetPathFromHandle(hFile, sPath) then
begin
dwDriveType:= UtilGetDriveTypeEx(sPath);
LOG('_WriteFile, GetPathFromHandle(%s), dwDriveType(%d)', [sPath, dwDriveType]);
end
else if gbsHook_.fileHandleList_.IsHandle(hFile, handleInfo) then
begin
sPath:= handleInfo.path;
dwDriveType:= handleInfo.drivetype;
handleInfo.Free;
LOG('_WriteFile, IsHandle (%p)(%s)(%d)', [Pointer(hFile), sPath, dwDriveType]);
end
else
begin
LOG('_WriteFile, not find handle (%p), GE(%x)', [Pointer(hFile), GetLastError]);
goto Cleanup;
end;
// if (dwDriveType = DRIVE_UNKNOWN) or (dwDriveType = DRIVE_FIXED) then
// begin
// Result:= WriteFileNext(hFile, Buffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
// Exit;
// end;
if ContainsText(sPath, '\CD Burning') or
ContainsText(sPath, '\AppData\Local\Microsoft\Windows\Burn\Burn\') or
ContainsText(sPath, '\AppData\Local\Microsoft\Windows\Burn\Burn1\') then
begin
dwDriveType:= DRIVE_CDROM;
deviceName:= 'cdrom';
end;
if gbsHook_.policy_.IsExceptionPath(sPath) then
goto Cleanup;
deviceName:= GetOffLineType(dwDriveType, bustype, PChar(sPath));
//
if not gbsHook_.policy_.GetDeviceControlPolicy(deviceName, devicePolicy) then
goto Cleanup;
LOG('_WriteFile, hFile(%p), deviceName(%s), sPath(%s), nNumberOfBytesToWrite(%d)',
[Pointer(hFile), deviceName, PChar(sPath), nNumberOfBytesToWrite]);
try
sbuff := UtilGetBufferHex(Buffer, nNumberOfBytesToWrite, 20);
LOG('_WriteFile: data(%s)', [PChar(sbuff)]);
if gbsHook_.fileHandleList_.IsBufferCompare('', Buffer, nNumberOfBytesToWrite, fileHandle) then
begin
sPath:= fileHandle.path;
if devicePolicy.policy_ = 1 then
begin
if UtilIsFileSizeOverBlockSize(sPath, devicePolicy.fileSize_) then
begin
block:= True;
end;
end;
SendUI(block, deviceName, sPath, sPath);
if block then
LOG('_WriteFile: MATCHING!!!!!!!!!!BLOCK!!!!!!!!!!!!! (%s), Matched Path: %s', [deviceName, PChar(fileHandle.path)])
else
LOG('_WriteFile: MATCHING!!!!!!!!!!ALLOW!!!!!!!!!!!!! (%s), Matched Path: %s', [deviceName, PChar(fileHandle.path)]);
fileHandle.Free;
if block then
begin
SetLastError(ERROR_ACCESS_DENIED);
Result := False;
Exit;
end;
end;
except
on E: Exception do
LOG('_WriteFile: Exception: %s', [PChar(E.Message)]);
end;
Cleanup:
Result:= WriteFileNext(hFile, Buffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
end;
function _CloseHandle(hObject: THandle): BOOL; stdcall;
begin
if not ghooked_ then
begin
Result := CloseHandleNext(hObject);
Exit;
end;
gbsHook_.fileHandleList_.DelHandle(hObject);
Result := CloseHandleNext(hObject);
end;
function _DeviceIoControl(
hDevice: THandle;
dwIoControlCode: DWORD;
lpInBuffer: Pointer;
nInBufferSize: DWORD;
lpOutBuffer: Pointer;
nOutBufferSize: DWORD;
lpBytesReturned: PDWORD;
lpOverlapped: POverlapped
): BOOL; stdcall;
//const
// IniPath = 'c:\MTPMon\policy.ini';
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;
begin
data := nil;
size := nInBufferSize;
sbuff := '';
inSize := 0;
block:= False;
if not ghooked_ then
begin
Result := DeviceIoControlNext(hDevice, dwIoControlCode, lpInBuffer,
nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
Exit;
end;
if (hDevice = INVALID_HANDLE_VALUE) or (lpInBuffer = nil) or ( nInBufferSize < 32 ) then
begin
Result := DeviceIoControlNext(hDevice, dwIoControlCode, lpInBuffer,
nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
Exit;
end;
if (dwIoControlCode <> IOCTL_SCSI_PASS_THROUGH_DIRECT) and
(dwIoControlCode <> IOCTL_WPD_MESSAGE_READWRITE_ACCESS) then
begin
Result := DeviceIoControlNext(hDevice, dwIoControlCode, lpInBuffer,
nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
Exit;
end;
// LOG('_DeviceIoControl: hDevice(%p) size(%d) dwIoControlCode(%x)', [Pointer(hDevice), size, dwIoControlCode]);
gbsHook_.policy_.GetPolicy;
policy:= gbsHook_.policy_.CurrentProcessPolicy;
case dwIoControlCode of
IOCTL_SCSI_PASS_THROUGH_DIRECT:
begin
if gbsHook_.processType_ = ptLINKENGKM then
deviceName:= 'usbTousb'
else
deviceName:= 'cdrom';
if not gbsHook_.policy_.GetDeviceControlPolicy(deviceName, devicePolicy) then
begin
Result := DeviceIoControlNext(hDevice, dwIoControlCode, lpInBuffer,
nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
Exit;
end;
try
scsi := nil;
scsi := PSCSI_PASS_THROUGH_DIRECT(lpInBuffer);
// LOG('_DeviceIoControl, : scsi.DataIn(%d)', [DWORD(scsi.DataIn)]);
if (scsi.DataIn = SCSI_IOCTL_DATA_OUT) and (scsi.DataBuffer <> nil) then
begin
data := PByte(scsi.DataBuffer);
size := scsi.DataTransferLength;
// if (gbsHook_.processType_ = ptLINKENGKM) and (size = 112) then
// begin
// Result := DeviceIoControlNext(hDevice, dwIoControlCode, lpInBuffer,
// nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
// Exit;
// end;
LOG('_DeviceIoControl, 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
Result := DeviceIoControlNext(hDevice, dwIoControlCode, lpInBuffer,
nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
Exit;
end;
except
on E: Exception do
LOG('_DeviceIoControl, Error accessing DataBuffer: %s', [PChar(E.Message)]);
end;
end;
IOCTL_WPD_MESSAGE_READWRITE_ACCESS:
begin
deviceName:= 'mtp';
if not gbsHook_.policy_.GetDeviceControlPolicy(deviceName, devicePolicy) then
begin
Result := DeviceIoControlNext(hDevice, dwIoControlCode, lpInBuffer,
nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
Exit;
end;
data := PByte(lpInBuffer);
size := nInBufferSize;
end;
else
begin
Result := DeviceIoControlNext(hDevice, dwIoControlCode, lpInBuffer,
nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
Exit;
end;
end;
try
sbuff := UtilGetBufferHex(data, size, 50);
LOG('_DeviceIoControl: hDevice(%p) size(%d) data(%s)', [Pointer(hDevice), size, PChar(sbuff)]);
if devicePolicy.dump_ = 1 then
UtilSaveBufferToFile('c:\MTPMon\dump', data, size);
if gbsHook_.fileHandleList_.IsBufferCompare('', data, size, fileHandle) then
begin
sPath:= fileHandle.path;
if devicePolicy.policy_ = 1 then
begin
if UtilIsFileSizeOverBlockSize(sPath, devicePolicy.fileSize_) then
begin
block:= True;
end;
end;
SendUI(block, deviceName, sPath, sPath);
if block then
LOG('_DeviceIoControl: MATCHING!!!!!!!!!!BLOCK!!!!!!!!!!!!! hDevice(%p)!! (%s), Matched Path: %s', [Pointer(hDevice), deviceName, PChar(fileHandle.path)])
else
LOG('_DeviceIoControl: MATCHING!!!!!!!!!!ALLOW!!!!!!!!!!!!! hDevice(%p)!! (%s), Matched Path: %s', [Pointer(hDevice), deviceName, PChar(fileHandle.path)]);
fileHandle.Free;
if block then
begin
SetLastError(ERROR_ACCESS_DENIED);
Result := False;
Exit;
end;
end;
except
on E: Exception do
LOG('_DeviceIoControl: Exception: %s', [PChar(E.Message)]);
end;
Result := DeviceIoControlNext(hDevice, dwIoControlCode, lpInBuffer,
nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
end;
function _WSASend(
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;
block: Boolean;
begin
block:= False;
FillChar(sin, SizeOf(sin), 0);
FillChar(ip, SizeOf(ip), 0);
if ( not ghooked_ ) or ( lpBuffers = nil )then
begin
Result:= WSASendNext(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine);
Exit;
end;
if (gbsHook_.processType_ <> ptFquirt) and (gbsHook_.processType_ <> ptLINKENGKM) then
begin
Result:= WSASendNext(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine);
Exit;
end;
gbsHook_.policy_.GetPolicy;
if gbsHook_.policy_.CurrentProcessPolicy = nil then
begin
Result:= WSASendNext(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine);
Exit;
end;
policy:= gbsHook_.policy_.CurrentProcessPolicy;
if not gbsHook_.policy_.GetDeviceControlPolicy('bluetooth', devicePolicy) then
begin
Result:= WSASendNext(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine);
Exit;
end;
ObexPacket := TObexPacket.Create;
try
data:= PByte(lpBuffers.buf);
size:= lpBuffers.len;
if (data = nil) or (Size < MIN_BUFFERSIZE) then
begin
Result:= WSASendNext(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine);
Exit;
end;
sIp:= '';
opCode:= data[0];
// if (opCode <> $82) or (size < 32) then
// begin
// LOG('_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);
LOG('_WSASend, : sBuff(%s) size(%d)', [sBuff, size]);
ObexPacket.Parse(data, size);
// 2. <20>Ľ̵<C4BD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20>Ӽ<EFBFBD><D3BC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
Log('_WSASend, --- OBEX <20><>Ŷ <20>м<EFBFBD> ---',[]);
Log('_WSASend, Opcode: $%02x, Packet Length: %d', [ObexPacket.Opcode, ObexPacket.PacketLength]);
// Name <20><><EFBFBD><EFBFBD> (0x01)
Log('_WSASend, File Name: %s', [PChar(ObexPacket.Name)]);
sName:= ObexPacket.Name;
// Length <20><><EFBFBD><EFBFBD> (0xC3)
Log('_WSASend, Total File Size: %d bytes', [ObexPacket.TotalLength]);
// Body <20><><EFBFBD><EFBFBD> (0x49)
if Length(ObexPacket.Body) > 0 then
begin
Log('_WSASend, Body Length: %d bytes', [Length(ObexPacket.Body)]);
// Log(HexDump(ObexPacket.Body)); // <20>ٵ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (<28>ʿ<EFBFBD><CABF><EFBFBD>)
end;
ObexPacket.Free;
if gbsHook_.fileHandleList_.IsBufferCompare(sName, data, size, fileHandle) then
begin
sPath:= fileHandle.path;
if devicePolicy.policy_ = 1 then
begin
if UtilIsFileSizeOverBlockSize(sPath, devicePolicy.fileSize_) then
begin
block:= True;
end;
end;
SendUI(block, 'bluetooth', sPath, sPath);
if block then
LOG('_WSASend: MATCHING!!!!!BLOCK!!!!! hDevice(%p)!! (bluetooth) %d, %d, Matched Ip : (%s), Path: (%s)', [Pointer(s), devicePolicy.policy_, devicePolicy.fileSize_, PChar(sIp), PChar(fileHandle.path)])
else
LOG('_WSASend: MATCHING!!!!!ALLOW!!!!! hDevice(%p)!! (bluetooth) %d, %d, Matched Ip : (%s), Path: %s', [Pointer(s), devicePolicy.policy_, devicePolicy.fileSize_, PChar(sIp), PChar(fileHandle.path)]);
fileHandle.Free;
if block then
begin
WSASetLastError(WSAECONNABORTED);
Result := SOCKET_ERROR;
Exit;
end;
end;
except
on E: Exception do
LOG('_WSASend: Exception: %s', [PChar(E.Message)]);
end;
Result:= WSASendNext(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine);
end;
function _send(s: TSocket; const buf: PAnsiChar; len: Integer; flags: Integer): Integer; stdcall;
var
sBuff: string;
size: DWORD;
data: PByte;
begin
if (not ghooked_) or (gbsHook_.processType_ <> ptLINKENGKM) then
begin
Result := sendNext(s, buf, len, flags);
Exit;
end;
if (len > 0) and (buf <> nil) then
begin
size:= Min(len, 100);
data:= PByte(buf);
for var i := 0 to size - 1 do
sBuff := sBuff + IntToHex(data[i], 2);
LOG('_send: sBuff(%s)', [PChar(sBuff)]);
end;
Result := sendNext(s, buf, len, flags);
end;
end.