1535 lines
44 KiB
Plaintext
1535 lines
44 KiB
Plaintext
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.
|
||
|