unit ApiHookContents; interface uses Winapi.Windows, System.SysUtils, System.Classes, Winapi.WinSock2, StrUtils, AppCtrlDefine, BsoneUtil, BsoneDebug, FileHandleListUnit, ObexParserUnit; const IMAGE_EXTS = 'PNG|JPG|JPEG|GIF|PCX|BMP'; METHOD_BUFFERED = 0; FILE_READ_ACCESS = 1; FILE_WRITE_ACCESS = 2; //#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) IOCTL_SCSI_BASE = $00000004; SCSI_IOCTL_DATA_OUT = 0; SCSI_IOCTL_DATA_IN = 1; SCSI_IOCTL_DATA_UNSPECIFIED = 2; IOCTL_SCSI_PASS_THROUGH_DIRECT = ( IOCTL_SCSI_BASE shl 16) or ((FILE_READ_ACCESS or FILE_WRITE_ACCESS) shl 14) or ($0405 shl 2) or METHOD_BUFFERED; //#define IOCTL_WPD_MESSAGE_READWRITE_ACCESS CTL_CODE(FILE_DEVICE_WPD, WPD_CONTROL_FUNCTION_GENERIC_MESSAGE, METHOD_BUFFERED, (FILE_READ_ACCESS | FILE_WRITE_ACCESS)) FILE_DEVICE_WPD = $00000040; WPD_CONTROL_FUNCTION_GENERIC_MESSAGE = $00000042; IOCTL_WPD_MESSAGE_READWRITE_ACCESS = ( FILE_DEVICE_WPD shl 16) or ((FILE_READ_ACCESS or FILE_WRITE_ACCESS) shl 14) or (WPD_CONTROL_FUNCTION_GENERIC_MESSAGE shl 2) or METHOD_BUFFERED; // ($0036C004) type SCSI_PASS_THROUGH_DIRECT = packed record Length: Word; // USHORT ScsiStatus: Byte; // UCHAR PathId: Byte; // UCHAR TargetId: Byte; // UCHAR Lun: Byte; // UCHAR CdbLength: Byte; // UCHAR SenseInfoLength: Byte; // UCHAR DataIn: Byte; // UCHAR Padding0: array[0..2] of Byte; DataTransferLength: DWORD; // ULONG TimeOutValue: DWORD; // ULONG DataBuffer: Pointer; // PVOID SenseInfoOffset: DWORD; // ULONG Cdb: array[0..15] of Byte; // UCHAR Cdb[16] end; PSCSI_PASS_THROUGH_DIRECT = ^SCSI_PASS_THROUGH_DIRECT; TApiHookContents = class public fileHandleList_: TFileHandleList; appType_: TCurAppType; constructor Create(AppType: TCurAppType); destructor Destroy; override; function CreateFileProc(hFile: THandle; lpFileName: LPCWSTR; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): THandle; stdcall; function CloseHandleProc(hFile: THandle): BOOL; stdcall; function ReadFileProc(hFile: THandle; lpBuffer: Pointer; nNumberOfBytesToRead: DWORD; lpNumberOfBytesRead: PDWORD; lpOverlapped: POverlapped): BOOL; stdcall; function DeviceIoControlProc(hDevice: THandle; dwIoControlCode: DWORD; lpInBuffer: Pointer; nInBufferSize: DWORD; lpOutBuffer: Pointer; nOutBufferSize: DWORD; lpBytesReturned: PDWORD; lpOverlapped: POverlapped): BOOL; stdcall; function CreateFileMappingProc(hReturnFile: THandle;hFile: THandle; lpFileMappingAttributes: PSecurityAttributes; flProtect: DWORD; dwMaximumSizeHigh: DWORD; dwMaximumSizeLow: DWORD; lpName: PWideChar): THandle; stdcall; function WSASendProc(s: TSocket; lpBuffers: PWSABuf; dwBufferCount: DWORD; lpNumberOfBytesSent: PDWORD; dwFlags: DWORD; lpOverlapped: POverlapped;lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; function GetPathFromHandle(hFile: THandle; out sPath: string): BOOL; stdcall; function GetDriveBusType(DriveLetter: WideChar): STORAGE_BUS_TYPE; function GetOffLineType(dwType: DWORD; dwBusType: DWORD; pwszPath: PWideChar): string; function GetFileReadBuffer(const path: string; pbuffer: PByte; buffersize: DWORD): Boolean; stdcall; function IsExceptionPath(const APath: string): Boolean; end; TFun_DeviceIoControl = function( hDevice: THandle; dwIoControlCode: DWORD; lpInBuffer: Pointer; nInBufferSize: DWORD; lpOutBuffer: Pointer; nOutBufferSize: DWORD; lpBytesReturned: PDWORD; lpOverlapped: POverlapped ): BOOL; stdcall; TFun_WSASend = function( s: TSocket; lpBuffers: PWSABuf; dwBufferCount: DWORD; lpNumberOfBytesSent: PDWORD; dwFlags: DWORD; lpOverlapped: POverlapped; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE ): Integer; stdcall; TFun_CreateFileMappingW = function( hFile: THandle; lpFileMappingAttributes: PSecurityAttributes; flProtect: DWORD; dwMaximumSizeHigh: DWORD; dwMaximumSizeLow: DWORD; lpName: PWideChar ): THandle; stdcall; function DeviceIoControlHook( hDevice: THandle; dwIoControlCode: DWORD; lpInBuffer: Pointer; nInBufferSize: DWORD; lpOutBuffer: Pointer; nOutBufferSize: DWORD; lpBytesReturned: PDWORD; lpOverlapped: POverlapped ): BOOL; stdcall; function CreateFileMappingWHook( hFile: THandle; lpFileMappingAttributes: PSecurityAttributes; flProtect: DWORD; dwMaximumSizeHigh: DWORD; dwMaximumSizeLow: DWORD; lpName: PWideChar ): THandle; stdcall; function WSASendHook( s: TSocket; lpBuffers: PWSABuf; dwBufferCount: DWORD; lpNumberOfBytesSent: PDWORD; dwFlags: DWORD; lpOverlapped: POverlapped; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE ): Integer; stdcall; function ReadFileHook( hFile: THandle; lpBuffer: Pointer; nNumberOfBytesToRead: DWORD; lpNumberOfBytesRead: PDWORD; lpOverlapped: POverlapped ): BOOL; stdcall; var ozDeviceIoControl: TFun_DeviceIoControl = nil; ozCreateFileMappingW: TFun_CreateFileMappingW = nil; ozWSASend: TFun_WSASend = nil; gApiHookContents_: TApiHookContents = nil; ghooked_: boolean = False; implementation uses ApiHookFile; constructor TApiHookContents.Create(AppType: TCurAppType); begin inherited Create; appType_:= appType; gApiHookContents_ := Self; fileHandleList_:= TFileHandleList.Create; ghooked_:= True; end; destructor TApiHookContents.Destroy; begin FreeAndNil(fileHandleList_); ghooked_:= False; inherited Destroy; end; function TApiHookContents.GetPathFromHandle(hFile: THandle; out sPath: string): BOOL; stdcall; var dwRet, dwRequiredSize: DWORD; Buffer: array[0..1024] of WideChar; begin sPath := ''; Result := FALSE; dwRequiredSize := 1024; SetLength(sPath, dwRequiredSize); dwRet := GetFinalPathNameByHandleW(hFile, PWideChar(sPath), dwRequiredSize, VOLUME_NAME_DOS); if (dwRet > 0) and (dwRet < MAX_PATH) then begin Result := TRUE; end else if dwRet > MAX_PATH then begin dwRequiredSize := dwRet; 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 //µÎ ¹øÂ° ½Ãµµµµ ½ÇÆÐ 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±ÛÀÚ) »èÁ¦ Insert('\', sPath, 1); // ¸Ç ¾Õ¿¡ '\' Ãß°¡ (°á°ú: \\Server...) end else if StartsText('\\?\', sPath) then begin Delete(sPath, 1, 4); // '\\?\' (4±ÛÀÚ) »èÁ¦ end; end; end; function TApiHookContents.GetDriveBusType(DriveLetter: WideChar): STORAGE_BUS_TYPE; var hDevice: THandle; Query: STORAGE_PROPERTY_QUERY; Sdh: STORAGE_DESCRIPTOR_HEADER; Psdd: PSTORAGE_DEVICE_DESCRIPTOR; cbBytesReturned: DWORD; VolumePath: string; WindowsDir: array[0..MAX_PATH] of Char; ReturnType: STORAGE_BUS_TYPE; bDriverMatch: Boolean; begin // ÃʱâÈ­ ReturnType := BusTypeUnknown; cbBytesReturned := 0; Psdd := nil; bDriverMatch := False; // 1. À©µµ¿ì µð·ºÅ丮 µå¶óÀ̺ê È®ÀÎ ·ÎÁ÷ FillChar(WindowsDir, SizeOf(WindowsDir), 0); GetWindowsDirectory(WindowsDir, Length(WindowsDir)); // 2. ÀåÄ¡ ÇÚµé ¿­±â // °æ·Î »ý¼º: \\.\C: VolumePath := Format('\\.\%s:', [DriveLetter]); hDevice := ozCreateFileW(PChar(VolumePath), 0, // Query Access FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); if hDevice = INVALID_HANDLE_VALUE then begin Result := ReturnType; Exit; end; try FillChar(Query, SizeOf(Query), 0); Query.PropertyId := StorageDeviceProperty; Query.QueryType := PropertyStandardQuery; if not ozDeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, @Query, SizeOf(Query), @Sdh, SizeOf(Sdh), PDWORD(cbBytesReturned), nil) then begin Exit; end; GetMem(Psdd, Sdh.Size); try FillChar(Psdd^, Sdh.Size, 0); if not ozDeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, @Query, SizeOf(Query), Psdd, Sdh.Size, PDWORD(cbBytesReturned), nil) then begin Exit; end; ReturnType := Psdd^.BusType; finally if Assigned(Psdd) then FreeMem(Psdd); end; finally if hDevice <> INVALID_HANDLE_VALUE then ozCloseHandle(hDevice); end; Result := ReturnType; end; function TApiHookContents.GetOffLineType(dwType: DWORD; dwBusType: DWORD; pwszPath: PWideChar): string; var OffType: string; VolumePath: string; hDevice: THandle; DeviceType: DWORD; ulCharacteristics: ULONG; MupPath: string; begin OffType := ''; case dwType of DRIVE_REMOVABLE: begin // µå¶óÀÌºê °æ·Î »ý¼º (¿¹: C -> \\.\C:) if pwszPath <> nil then VolumePath := Format('\\.\%s:', [pwszPath[0]]) else Exit(''); OffType := 'removalbe'; // ÀåÄ¡ ÇÚµé ¿­±â hDevice := ozCreateFileW(PChar(VolumePath), 0, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); if hDevice = INVALID_HANDLE_VALUE then Exit(''); try if UtilGetDriveTypeAndCharacteristics(hDevice, DeviceType, ulCharacteristics) then begin // FILE_FLOPPY_DISKETTE(0x4) À̰í FILE_DEVICE_DISK(0x7) ÀÎÁö È®ÀÎ if ((ulCharacteristics and $4) <> 0) and (DeviceType = $7) then begin OffType := 'floppy'; end; end; finally ozCloseHandle(hDevice); end; Result := OffType; Exit; end; DRIVE_REMOTE: OffType := 'networkdriveout'; DRIVE_CDROM: OffType := 'cdrom'; DRIVE_FIXED: begin dwBusType:= DWORD(GetDriveBusType(pwszPath[0])); // FIXED À̸鼭 USB Bus TypeÀÌ¸é ¿ÜÀåÇϵå if dwBusType = DWORD(BusTypeUsb) then OffType := 'externalhdd'; end; DRIVE_NO_ROOT_DIR: begin // ³×Æ®¿öÅ© °æ·Î(\Device\Mup\) È®ÀÎ MupPath := '\Device\Mup\'; if StrLIComp(pwszPath, PChar(MupPath), Length(MupPath)) = 0 then begin OffType := 'networkdriveout'; end; end; end; Result := OffType; end; function TApiHookContents.GetFileReadBuffer(const path: string; pbuffer: PByte; buffersize: DWORD): Boolean; stdcall; var size: DWORD; fp: THandle; Retsize: DWORD; bReadSuccess: Boolean; begin Result := FALSE; fp := INVALID_HANDLE_VALUE; Retsize := 0; fp := ozCreateFileW(PChar(path), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if fp = INVALID_HANDLE_VALUE then Exit; try size := GetFileSize(fp, nil); if (size = 0) or (size = INVALID_FILE_SIZE) then Exit; if size < MIN_BUFFERSIZE then Exit; if @ozReadFile = nil then bReadSuccess := ReadFile(fp, pbuffer^, buffersize, Retsize, nil) else bReadSuccess := ozReadFile(fp, pbuffer, buffersize, @Retsize, nil); Result := TRUE; finally ozCloseHandle(fp); end; end; function TApiHookContents.IsExceptionPath(const APath: string): Boolean; begin Result:= True; if ContainsText(APath, 'AppData\Roaming\Microsoft\Windows\Recent') or ContainsText(APath, '\desktop.ini') or ContainsText(APath, 'ProgramData\Microsoft\Windows\AppRepository\Packages') or ContainsText(APath, 'AppData\Roaming\Microsoft\Internet Explorer\Quick Launch') or ContainsText(APath, 'AppData\Roaming\Microsoft\Windows\SendTo') or ContainsText(APath, 'AppData\Roaming\Microsoft\Windows\Themes\') or ContainsText(APath, 'AppData\Roaming\Mozilla\Firefox\Profiles') or ContainsText(APath, 'program files\windowsapps\microsoft') or ContainsText(APath, 'AppData\Local\') or ContainsText(APath, 'wpd_data_') then Exit; Result:= False; end; function TApiHookContents.CreateFileProc(hFile: THandle; lpFileName: LPCWSTR; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): THandle; stdcall; var sPath: string; begin if (Result = 0) or (Result = INVALID_HANDLE_VALUE) then begin Exit; end; if dwCreationDisposition = CREATE_NEW then Exit; if dwCreationDisposition = TRUNCATE_EXISTING then Exit; if (dwFlagsAndAttributes and FILE_FLAG_BACKUP_SEMANTICS) <> 0 then Exit; if (dwFlagsAndAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0 then Exit; if (dwFlagsAndAttributes and FILE_FLAG_DELETE_ON_CLOSE) <> 0 then Exit; //FILE_ATTRIBUTE_NO_SCRUB_DATA 0x00020000 µ¥ÀÌÅÍ ½ºÅ©·¯ºù if (dwFlagsAndAttributes and (FILE_FLAG_OVERLAPPED or $20000)) = (FILE_FLAG_OVERLAPPED or $20000) then //MTP ¿ÀÇ °æ·Î°¡ ÇØ´ç ŸÀÔÀÏ ‹š µé¾î¿È... Exit; if (appType_ = catFquirt) then //or (gbsHook_.processType_ = ptExplore) begin if dwFlagsAndAttributes = 0 then Exit; end; sPath:= lpFileName; if (Length(sPath) >= 2) and (sPath[1] = '.') and (sPath[2] = '\') then Exit; if StartsText('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 IsExceptionPath(sPath) then Exit; LOG('_CreateFileW: (%p), (%s), c(%x), s(%x), d(%x), f(%x)', [Pointer(Result), PChar(sPath), dwCreationDisposition, dwShareMode, dwDesiredAccess, dwFlagsAndAttributes]); fileHandleList_.InsertHandle(Result, sPath, dwDesiredAccess, dwShareMode, dwCreationDisposition, dwFlagsAndAttributes); end; function TApiHookContents.CloseHandleProc(hFile: THandle): BOOL; stdcall; begin Result:= False; fileHandleList_.DelHandle(hFile); end; function TApiHookContents.ReadFileProc( hFile: THandle; lpBuffer: Pointer; nNumberOfBytesToRead: DWORD; lpNumberOfBytesRead: PDWORD; lpOverlapped: POverlapped ): BOOL; stdcall; const INVALID_SET_FILE_POINTER = DWORD(-1); var sPath: string; dwError: DWORD; dwBytesRead: DWORD; handleInfo: TFileHandle; CurrentPos: DWORD; IsStartOfFile: Boolean; begin if (lpBuffer = nil) or (not ghooked_) then begin Result := ozReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); Exit; end; // 2. Ž»ö±â ¿¹¿Ü ó¸® (ÇÊ¿ä ½Ã À¯Áö) if appType_ = catExplorer then begin Result := ozReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); Exit; end; IsStartOfFile := False; if lpOverlapped <> nil then begin if (lpOverlapped.Offset = 0) and (lpOverlapped.OffsetHigh = 0) then IsStartOfFile := True; end else begin CurrentPos := SetFilePointer(hFile, 0, nil, FILE_CURRENT); if (CurrentPos <> INVALID_SET_FILE_POINTER) and (CurrentPos = 0) then IsStartOfFile := True; end; if not IsStartOfFile then begin Result := ozReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); Exit; end; Result := ozReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); dwError := GetLastError; dwBytesRead := 0; if Result then begin // µ¿±â È£Ãâ ¼º°ø ½Ã ÀÐÀº Å©±â ȹµæ if lpNumberOfBytesRead <> nil then dwBytesRead := lpNumberOfBytesRead^ else dwBytesRead := 0; end else begin if dwError = ERROR_IO_PENDING then begin if (lpOverlapped <> nil) and GetOverlappedResult(hFile, lpOverlapped^, dwBytesRead, FALSE) then begin end else begin Exit; end; end else begin Exit; end; end; if dwBytesRead = 0 then Exit; if fileHandleList_.IsHandle(hFile, handleInfo) then begin sPath := handleInfo.path; handleInfo.Free; 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 TApiHookContents.DeviceIoControlProc( hDevice: THandle; dwIoControlCode: DWORD; lpInBuffer: Pointer; nInBufferSize: DWORD; lpOutBuffer: Pointer; nOutBufferSize: DWORD; lpBytesReturned: PDWORD; lpOverlapped: POverlapped ): BOOL; stdcall; var data: PByte; size: DWORD; sbuff: string; inSize: DWORD; i: Integer; fileHandle: TFilehandle; sPath: string; // var IniFile: TIniFile; // var bBlock: Boolean; // var bDump: Boolean; scsi: PSCSI_PASS_THROUGH_DIRECT; // policy: TProcessPolicy; // devicePolicy: TDeviceControlPolicy; deviceName: string; block: Boolean; begin data := nil; size := nInBufferSize; sbuff := ''; inSize := 0; block:= False; Result:= True; if not ghooked_ then begin Exit; end; if (hDevice = INVALID_HANDLE_VALUE) or (lpInBuffer = nil) or ( nInBufferSize < 32 ) then begin Exit; end; if (dwIoControlCode <> IOCTL_SCSI_PASS_THROUGH_DIRECT) and (dwIoControlCode <> IOCTL_WPD_MESSAGE_READWRITE_ACCESS) then begin Exit; end; // 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 // Exit; // end; // // try // scsi := nil; // scsi := PSCSI_PASS_THROUGH_DIRECT(lpInBuffer); // if (scsi.DataIn = SCSI_IOCTL_DATA_OUT) and (scsi.DataBuffer <> nil) then // begin // data := PByte(scsi.DataBuffer); // size := scsi.DataTransferLength; // // 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 // 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 // Exit; // end; // // data := PByte(lpInBuffer); // size := nInBufferSize; // end; // else // begin // 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 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; end; function TApiHookContents.CreateFileMappingProc( hReturnFile: THandle; 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; bufSize: DWORD; CheckSize: Int64; FileSizeHigh: DWORD; FileSizeLow: DWORD; pMem: Pointer; begin sPath:= ''; if fileHandleList_.IsHandle(hFile, handleInfo) then begin sPath:= handleInfo.path; handleInfo.Free; end else if GetPathFromHandle(hFile, sPath) then begin end else begin LOG('_CreateFileMappingW, not find handle', []); end; if sPath = '' then Exit; if IsExceptionPath(sPath) then Exit; CheckSize := (Int64(dwMaximumSizeHigh) shl 32) or dwMaximumSizeLow; if CheckSize = 0 then begin FileSizeLow := GetFileSize(hFile, @FileSizeHigh); if FileSizeLow = INVALID_FILE_SIZE then Exit; CheckSize := (Int64(FileSizeHigh) shl 32) or FileSizeLow; end; LOG('_CreateFileMappingW, hFile(%p), sPath(%s), dwMaximumSizeLow(%d), flProtect(%x)', [Pointer(hFile), PChar(sPath), dwMaximumSizeLow, flProtect]); try // FILE_MAP_READ ±ÇÇÑÀ¸·Î ¾ÕºÎºÐ(MIN_BUFFERSIZE)¸¸ ¸ÅÇÎ pMem := MapViewOfFile(Result, FILE_MAP_READ, 0, 0, MIN_BUFFERSIZE); if pMem <> nil then begin try // ¸Þ¸ð¸® ³»¿ëÀ» ¹öÆÛ·Î º¹»ç Move(pMem^, buf[0], MIN_BUFFERSIZE); // ¸®½ºÆ®¿¡ µî·Ï // (ÁÖÀÇ: InsertBufferForHandle ³»ºÎ¿¡¼­ bufÀÇ º¹»çº»À» ¸¸µé¾î¾ß ¾ÈÀüÇÔ) fileHandleList_.InsertBufferForHandle(hFile, sPath, @buf, MIN_BUFFERSIZE); LOG('_CreateFileMappingW Data Cached via Mapping: %s', [PChar(sPath)]); finally UnmapViewOfFile(pMem); end; end else begin // ¸ÅÇÎ ½ÇÆÐ ·Î±× (±ÇÇÑ ¹®Á¦ µî) LOG('_CreateFileMappingW: MapViewOfFile Failed code: %d', [GetLastError]); end; except on E: Exception do LOG('_CreateFileMappingW Exception: %s', [PChar(E.Message)]); end; end; function TApiHookContents.WSASendProc( s: TSocket; lpBuffers: PWSABuf; dwBufferCount: DWORD; lpNumberOfBytesSent: PDWORD; dwFlags: DWORD; lpOverlapped: POverlapped; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE ): Integer; stdcall; var data: PByte; size: DWORD; sbuff: string; inSize: DWORD; i: Integer; fileHandle: TFilehandle; sPath: string; sin: sockaddr_in; sinlen: Integer; ip: array[0..99] of AnsiChar; sIp: string; // policy: TProcessPolicy; // devicePolicy: TDeviceControlPolicy; ObexPacket: TObexPacket; opCode: Byte; sName: string; block: Boolean; begin block:= False; FillChar(sin, SizeOf(sin), 0); FillChar(ip, SizeOf(ip), 0); Result:= 0; if ( not ghooked_ ) or ( lpBuffers = nil )then begin Exit; end; if (appType_ <> catFquirt) and (appType_ <> catLINKENGKM) then begin Exit; end; // gbsHook_.policy_.GetPolicy; // if gbsHook_.policy_.CurrentProcessPolicy = nil then // begin // Exit; // end; // // policy:= gbsHook_.policy_.CurrentProcessPolicy; // // if not gbsHook_.policy_.GetDeviceControlPolicy('bluetooth', devicePolicy) then // begin // Exit; // end; // // ObexPacket := TObexPacket.Create; // try // // data:= PByte(lpBuffers.buf); // size:= lpBuffers.len; // // if (data = nil) or (Size < MIN_BUFFERSIZE) then // begin // Exit; // end; // // sIp:= ''; // opCode:= data[0]; // //// if (opCode <> $82) or (size < 32) then //// begin //// 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. ÆÄ½ÌµÈ µ¥ÀÌÅ͸¦ ¼Ó¼ºÀ¸·Î ½±°Ô Á¢±ÙÇÕ´Ï´Ù. // Log('_WSASend, --- OBEX ÆÐŶ ºÐ¼® ---',[]); // Log('_WSASend, Opcode: $%02x, Packet Length: %d', [ObexPacket.Opcode, ObexPacket.PacketLength]); // // // Name Çì´õ (0x01) // Log('_WSASend, File Name: %s', [PChar(ObexPacket.Name)]); // sName:= ObexPacket.Name; // // Length Çì´õ (0xC3) // Log('_WSASend, Total File Size: %d bytes', [ObexPacket.TotalLength]); // // Body Çì´õ (0x49) // if Length(ObexPacket.Body) > 0 then // begin // Log('_WSASend, Body Length: %d bytes', [Length(ObexPacket.Body)]); // // Log(HexDump(ObexPacket.Body)); // ¹Ùµð ³»¿ë ´ýÇÁ (ÇÊ¿ä½Ã) // end; // // // ObexPacket.Free; // // if 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; end; function ReadFileHook( hFile: THandle; lpBuffer: Pointer; nNumberOfBytesToRead: DWORD; lpNumberOfBytesRead: PDWORD; lpOverlapped: POverlapped ): BOOL; stdcall; begin if gApiHookContents_ = nil then begin ozReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); Exit; end; Result:= gApiHookContents_.ReadFileProc(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); end; function DeviceIoControlHook( hDevice: THandle; dwIoControlCode: DWORD; lpInBuffer: Pointer; nInBufferSize: DWORD; lpOutBuffer: Pointer; nOutBufferSize: DWORD; lpBytesReturned: PDWORD; lpOverlapped: POverlapped ): BOOL; stdcall; begin if gApiHookContents_ <> nil then begin Result:= gApiHookContents_.DeviceIoControlProc(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped); if not result then Exit; end; Result:= ozDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped); end; function CreateFileMappingWHook( hFile: THandle; lpFileMappingAttributes: PSecurityAttributes; flProtect: DWORD; dwMaximumSizeHigh: DWORD; dwMaximumSizeLow: DWORD; lpName: PWideChar ): THandle; stdcall; begin Result:= ozCreateFileMappingW(hFile, lpFileMappingAttributes, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, lpName); if (not ghooked_) or (Result = 0) then Exit; if hFile = INVALID_HANDLE_VALUE then Exit; if gApiHookContents_ <> nil then gApiHookContents_.CreateFileMappingProc(Result, hFile, lpFileMappingAttributes, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, lpName); end; function WSASendHook( s: TSocket; lpBuffers: PWSABuf; dwBufferCount: DWORD; lpNumberOfBytesSent: PDWORD; dwFlags: DWORD; lpOverlapped: POverlapped; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE ): Integer; stdcall; begin if gApiHookContents_ <> nil then begin Result:= gApiHookContents_.WSASendProc(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine); if Result = SOCKET_ERROR then Exit; end; Result:= ozWSASend(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine); end; end.