{*******************************************************} { } { ApiHookFile } { } { Copyright (C) 2023 kku } { } {*******************************************************} unit ApiHookFile; interface //{$DEFINE USE_BOXAPP} // eCrmHeHelperf.dll, eCrmHeHelper32f.dll 빌드 시 꺼야함 25_0819 15:59:08 kku // 이제 안쓰는걸루 25_1215 kku {$DEFINE _MTP_RO_} uses Winapi.Windows, System.SysUtils, System.Classes, Winapi.WinSock2; const IMAGE_EXTS = 'PNG|JPG|JPEG|GIF|PCX|BMP'; type THandleStreamEx = class(THandleStream) protected llSize_: LONGLONG; function GetSize: Int64; override; public constructor Create(aHandle: THandle; llSize: LONGLONG); end; TFun_CreateFileA = function(lpFileName: PAnsiChar; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): THandle; stdcall; TFun_CreateFileW = function(lpFileName: PWideChar; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): THandle; stdcall; TFun_CloseHandle = function(hFile: THandle): BOOL; stdcall; TFun_MapViewOfFile = function(hFileMappingObject: THandle; dwDesiredAccess: DWORD; dwFileOffsetHigh, dwFileOffsetLow: DWORD; dwNumberOfBytesToMap: SIZE_T): Pointer; stdcall; TFun_ReadFile = function(hFile: THandle; lpBuffer: Pointer; nNumberOfBytesToRead: DWORD; lpNumberOfBytesRead: PDWORD; lpOverlapped: POverlapped): BOOL; stdcall; TFun_ReadFileEx = function(hFile: THandle; lpBuffer: Pointer; nNumberOfBytesToRead: DWORD; lpOverlapped: POverlapped; lpCompletionRoutine: TPROverlappedCompletionRoutine): BOOL; stdcall; TFun_WriteFile = function(hFile: THandle; const Buffer; nNumberOfBytesToWrite: DWORD; var lpNumberOfBytesWritten: DWORD; lpOverlapped: POverlapped): BOOL; stdcall; TFun_WriteFileEx = function(hFile: THandle; lpBuffer: Pointer; nNumberOfBytesToWrite: DWORD; const lpOverlapped: TOverlapped; lpCompletionRoutine: FARPROC): BOOL; stdcall; function CreateFileAHook(lpFileName: PAnsiChar; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): THandle; stdcall; function CreateFileWHook(lpFileName: PWideChar; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): THandle; stdcall; function CloseHandleHook(hFile: THandle): BOOL; stdcall; {$IFDEF DEBUG} // 사용하지 않아서 비활성화 함 24_0122 14:14:41 kku //function MapViewOfFileHook(hFileMappingObject: THandle; dwDesiredAccess: DWORD; // dwFileOffsetHigh, dwFileOffsetLow: DWORD; dwNumberOfBytesToMap: SIZE_T): Pointer; stdcall; //function ReadFileHook(hFile: THandle; var Buffer; nNumberOfBytesToRead: DWORD; // var lpNumberOfBytesRead: DWORD; lpOverlapped: POverlapped): BOOL; stdcall; //function ReadFileExHook(hFile: THandle; lpBuffer: Pointer; nNumberOfBytesToRead: DWORD; // lpOverlapped: POverlapped; lpCompletionRoutine: TPROverlappedCompletionRoutine): BOOL; stdcall; //function WriteFileHook(hFile: THandle; const Buffer; nNumberOfBytesToWrite: DWORD; // var lpNumberOfBytesWritten: DWORD; lpOverlapped: POverlapped): BOOL; stdcall; //function WriteFileExHook(hFile: THandle; lpBuffer: Pointer; nNumberOfBytesToWrite: DWORD; // const lpOverlapped: TOverlapped; lpCompletionRoutine: FARPROC): BOOL; stdcall; {$ENDIF} var ozCreateFileA: TFun_CreateFileA = nil; ozCreateFileW: TFun_CreateFileW = nil; ozCloseHandle: TFun_CloseHandle = nil; ozMapViewOfFile: TFun_MapViewOfFile = nil; ozReadFile: TFun_ReadFile = nil; ozReadFileEx: TFun_ReadFileEx = nil; ozWriteFile: TFun_WriteFile = nil; ozWriteFileEx: TFun_WriteFileEx = nil; implementation uses {$IFDEF USE_BOXAPP} BoxedAppSDK_Static, {$ENDIF} {$IFDEF _BS1HP_} BS1Hook, GlobalDefine, DefineHelper, {$ELSE} AppHook, {$ENDIF} Tocsg.WndUtil, Tocsg.Path, Tocsg.DRM.Encrypt, Tocsg.Files, Tocsg.Safe, Tocsg.Encrypt, AppCtrlDefine, Tocsg.Exception, Winapi.Messages, Tocsg.Win32, superobject, Tocsg.Process, Tocsg.Strings, Tocsg.Registry, Tocsg.Convert, Tocsg.Trace, Tocsg.Hash, Condition, ApiHookContents; var _nTest: Integer = 0; _sEncFileHash: string = ''; { THandleStreamEx } constructor THandleStreamEx.Create(aHandle: THandle; llSize: LONGLONG); begin inherited Create(aHandle); llSize_ := llSize; end; function THandleStreamEx.GetSize: Int64; begin Result := llSize_; end; procedure LogToReg(sVName, sLog: string); inline; begin // SetRegValueString(HKEY_CURRENT_USER, 'SOFTWARE\eCrmHomeEdition', sVName, sLog, true); end; procedure LogToReg2(sVName, sLog: string); inline; begin // SetRegValueString(HKEY_CURRENT_USER, 'SOFTWARE\eCrmHomeEdition', sVName, sLog, true); end; function DecText(sText: string): string; inline; begin Result := ''; if Length(sText) < 2 then exit; if sText[1] = ':' then begin Delete(sText, 1, 1); Result := DecBinStrToStr(ekAes256cbc, PASS_STRENC, sText); end else Result := sText; end; function IsReliableWindow(hWnd: HWND): Boolean; var Res: LRESULT; begin Result := IsWindow(hWnd) or (SendMessageTimeout(hWnd, WM_NULL, 0, 0, SMTO_ABORTIFHUNG or SMTO_BLOCK, 100, @Res) <> 0); end; function IsActiveFileDialog(sPath: string): Boolean; stdcall; var h, hNext: HWND; dwAPid: DWORD; sWClass, sCap: string; i: Integer; Label LB_DoFind; begin Result := false; if gAppHook = nil then exit; // var bLog := Pos('fgfgf', sPath) <> 0; try // if bLog then LogToReg('IsActiveFileDialog1', sPath + ' - ' + gAppHook.Helper.OpenDlgWordList.CommaText); if (gAppHook.Helper.hOpenDlgWnd_ = 0) and (gAppHook.Helper.OpenDlgWordList.Count > 0) then begin LB_DoFind : h := FindWindowEx(0, 0, '#32770', nil); while h <> 0 do begin sWClass := ''; hNext := GetWindow(h, GW_HWNDNEXT); dwAPid := GetProcessPIDFromWndHandle(h); if dwAPid = gAppHook.Helper.PID then begin sWClass := GetWndClassName(h); // if bLog then LogToReg('IsActiveFileDialog11', sPath + ' - ' + sWClass); end; if sWClass = '#32770' then begin sCap := UpperCase(GetWindowCaption(h)); // if bLog then LogToReg(Format('IsActiveFileDialog3, A_PID=%d, A_PName=%s, A_Cap=%s', [dwAPid, GetProcessNameByPid(dwAPid), sCap]), sPath); if sCap <> '' then begin for i := 0 to gAppHook.Helper.OpenDlgWordList.Count - 1 do begin if Pos(gAppHook.Helper.OpenDlgWordList[i], sCap) > 0 then begin // if bLog then LogToReg(Format('IsActiveFileDialog4, A_PID=%d, A_PName=%s, A_Cap=%s', [dwAPid, GetProcessNameByPid(dwAPid), sCap]), sPath); gAppHook.Helper.hOpenDlgWnd_ := h; Result := true; exit; end; end; end else // if bLog then LogToReg(Format('IsActiveFileDialog5, A_PID=%d, A_PName=%s, A_Cap=%s', [dwAPid, GetProcessNameByPid(dwAPid), sCap]), sPath); end; h := hNext; end; gAppHook.Helper.hOpenDlgWnd_ := 0; end else if IsWindow(gAppHook.Helper.hOpenDlgWnd_) then begin // if bLog then LogToReg('IsActiveFileDialog2', sPath); // 다열로그창에서 마우스 오른쪽 팝업 시 먹통되서 이렇게 보완 처리함 22_1129 15:33:40 kku Result := true; end else begin // if bLog then LogToReg('IsActiveFileDialog3', sPath + ' - ' + IntToStr(gAppHook.Helper.hOpenDlgWnd_)); // 왜인지 모르겠지만... // 특정 PC에서 윈도우가 살아있는데 // IsWindow(gAppHook.Helper.hOpenDlgWnd_) 이게 false가 떠서 여기로 넘어오는 경우가 발생한다. // 그래서 다시 찾도록 보완 25_0121 11:09:36 kku goto LB_DoFind; // gAppHook.Helper.hOpenDlgWnd_ := 0; end; except // .. end; end; function CheckBlockFile(dwDesiredAccess, dwShareMode, dwCreationDisposition, dwFlagsAndAttributes: DWORD; sPath: string): Boolean; inline; var i: Integer; sExt, sFName, sChkPath: string; dwFlags: DWORD; hFile: THandle; hTagWnd: HWND; FileUseBlock: TFileUseBlock; bIsNetPath, bExistsFile: Boolean; begin Result := false; try var bDoLog: Boolean := False; //Pos('[bs1]', sPath.ToLower) > 0; //Pos('.html', sPath.ToLower) > 0; // sExt := GetFileExt(sPath).ToUpper; // if (ExtractFilePath(sPath) <> '') and (sExt = 'WEBP') then // begin // bDoLog := true; if bDoLog then LogToReg('Step000', sPath); // end; bIsNetPath := false; case dwDesiredAccess of // 0, $80, GENERIC_WRITE : exit; 0, $80: exit; end; if bDoLog then LogToReg('Step001', Format('dwFlagsAndAttribute=%d', [dwFlagsAndAttributes])); // {$IFNDEF _BS1HP_} // if CompareText('C:\taskToCSG\Tocsg.Module\AppCtrl\OUT_Debug - Win64\AppCtrl_d.log', sPath) = 0 then // exit; //// gAppHook.Log(Format('CheckBlockFile(), Path=%s, Attr=%d', [sPath, dwFlagsAndAttributes])); // // if GetFileExt(sPath).ToUpper = 'TXT' then // begin // gAppHook.Log(Format('Path=%s, dwDesiredAccess=%d, dwShareMode=%d, dwFlagsAndAttributes=%d', [sPath, dwDesiredAccess, dwShareMode, dwFlagsAndAttributes])); // Result := true; // exit; // end; // {$ENDIF} // 브라우저에서 파일 첨부 시 dwFlagsAndAttributes 값에 FILE_FLAG_OPEN_NO_RECALL가 들어옴 case dwFlagsAndAttributes of 0, // : exit; // 0 이면 파일 열기로 인식 25_0227 17:02:13 kku 33554432: begin if (dwFlagsAndAttributes = 0) and (gAppHook.Helper.CurAppType <> catwinscp) and // winscp.exe에서 업로드 시 dwFlagsAndAttributes = 0 이렇게 처리됨, 걸러줌 25_1105 13:19:19 kku (CompareText(gAppHook.ModuleName, 'firefox.exe') <> 0) and // 파이어폭스는 첨부 시 dwFlagsAndAttributes = 0 이렇게 되서 걸러준다... 25_0424 13:17:36 kku gAppHook.Helper.CtrlOpt.bOpenDetect then begin // 브라우저 다운로드는 무시하지 않게 처리 25_0327 17:48:49 kku if (gAppHook.Helper.CurAppType = catWebb) and (GetFileExt(sPath).ToUpper = 'TMP') then begin // 1ec3031e-946c-4de3-b3d4-b5abc2b3edba.tmp 이런 형식 // 차단 처리 및 로깅 될수 있게 함 end else exit; end; // 모든 파일을 GetFileAttributes() 처리하면 엣지등 프로그램이 뻗음 // 그래서 디렉토리로 추정되는 특정 플러그만 검사 25_0211 10:04:33 kku dwFlags := GetFileAttributes(PChar(sPath)); if (dwFlags and FILE_ATTRIBUTE_DIRECTORY) <> 0 then exit; end; end; sPath := StringReplace(sPath, '"', '', [rfReplaceAll]); // 파일 이름만 달랑 오는 경우가 있다... 무시 25_0421 15:54:36 kku // webex에서 파일 여러거 첨부할때 발생함 if ExtractFilePath(sPath) = '' then exit; sFName := ExtractFileName(sPath); if sFName = '' then exit; sExt := GetFileExt(sFName).ToUpper; // 실행 체크? // if (sExt = 'EXE') and ((dwDesiredAccess and GENERIC_READ) = 0) then // exit; case gAppHook.Helper.CurAppType of catBizbox: begin // 더존 메신저 내에서 파일 열기 감지, 무시 25_1112 10:29:54 kku if dwShareMode = 7 then exit; if (dwDesiredAccess = $40000000) and (dwShareMode = 3) and (dwFlagsAndAttributes = $100000) then exit; end; catwinscp: begin if (dwDesiredAccess <> $80000000) or (dwShareMode <> 3) or (dwFlagsAndAttributes <> 0) then exit; end; catFilezilla: begin //윈스테크넷 filezilla 미첨부 exe 파일을 탐지하는 현상 수정 251128 mgkim if (dwDesiredAccess <> $80000000) or (dwShareMode <> 3) or (dwFlagsAndAttributes <> $8000000) then exit; end; catOlk, catMswebv: begin // 다운로드 차단이 아니라면 olk.exe > msedgewebview2.exe에서 처리하는 임시파일은 무시 25_1217 16:30:29 kku if not gAppHook.Helper.CtrlOpt.bWriteBlock and (sExt = 'CRSWAP') then exit; end; end; if gAppHook.Helper.CurAppType = catWebb then begin case gAppHook.Helper.CtrlOpt.dwCustomerType of CUSTOMER_WINSTN, CUSTOMER_SKEC : begin case gAppHook.Helper.CurAppDetailType of catChrome, catMsedge, catWhale : begin if gAppHook.Helper.CtrlOpt.bReadBlock then //20251201 mgkim 브라우저에서 다운로드 후 이미지 열시 이미지내에 권한 없음 메시지 처리 begin if (dwDesiredAccess = $80000000) and // GENERIC_READ (dwShareMode = 7) and // SHARE_READ | SHARE_WRITE | SHARE_DELETE (dwFlagsAndAttributes = $40040000) then // OVERLAPPED | RECALL_ON_OPEN begin exit; end; end; end; end; end; end; end; if bDoLog then LogToReg('Step002', sPath); // if (dwDesiredAccess and GENERIC_READ) = 0 then // exit; // 아래 코드를 추가하면 픽픽에서 캡쳐 이미지 저장할때 감지를 하지 못한다.. 23_1206 14:24:05 kku // 아래처럼 하면 일부 프로그램(크롬,엣지등)은 실행조차 안된다... 22_1109 08:47:30 kku // dwFlags := GetFileAttributes(PChar(sPath)); // if (dwFlags and FILE_ATTRIBUTE_DIRECTORY) <> 0 then // exit; if (gAppHook._hMTP <> 0) then begin if Length(sPath) = 3 then begin {$IFDEF _BS1HP_} gAppHook.ProcessNoti(NOTI_HOOK_BLOCK_MTP_WRITE, gAppHook._sMtpDev, 3, false);//gAppHook._sMtpRecentFile); {$ELSE} gAppHook.Log(Format('cut : %s', [sPath])); {$ENDIF} Result := true; exit; end; // else // gAppHook._hMTP := 0; // sExt := GetFileExt(sFName).ToUpper; // if (sExt = 'DOCX') or (sExt = 'PDF') or (sExt = 'TXT') then // begin // {$IFNDEF _BS1HP_} // gAppHook.Log(Format('MTP Use? (%d) : %s', [GetForegroundWindow, sPath])); // {$ENDIF} // end; end; if bDoLog then LogToReg('Step003', sPath); if (gAppHook.Helper.CurAppType = catExplorer) and (gAppHook._hMTP = 0) then begin // if Pos('_quick', sPath) = 0 then // begin // if gAppHook._hMTP <> 0 then // LogToReg('Step98', sPath) // else // LogToReg('Step99', sPath); // end; exit; end; if bDoLog then LogToReg('Step004', sPath); // if sPath.StartsWith('\\') then // begin // if (sPath[3] <> '.') and (sPath[3] <> '?') then // begin // if GetFileExt(sPath).ToUpper = 'HWP' then // begin // LogToReg('Step-00', sPath); // Result := true; // end; // end; // exit; // end else // if sPath[1] = 'Q' then // LogToReg('Step-01', sPath); if (sPath.Length > 5) and sPath.StartsWith('\\?\') and (sPath[6] = ':') then Delete(sPath, 1, 4); // if bDoLog then LogToReg('Step111', BooleanToStr(gAppHook.Helper.CtrlOpt.bIgrNetPathAB, 'Y', 'N')); // 경로가 c:/abcd/efg.txt 이렇게 오는 경우가 있다... (WebEx) // 아래 처럼 바꿔줘야 예외 경로가 먹힘 25_0313 13:48:17 kku sPath := StringReplace(sPath, '/', '\', [rfReplaceAll]); // 드라이브 없이 : 로 시작하는거 거름 if (sPath.Length > 0) and (sPath[1] = ':') then exit; sChkPath := UpperCase(sPath); if gAppHook.Helper.CurAppType = catExplorer then begin // todo : 탐색기에서 공유폴더, 네트워크 드라이브 파일 처리 로깅 기능 필요 25_0408 08:56:56 kku end else begin if bDoLog then LogToReg('Step222', sPath); if (sPath.Length > 2) and sPath.StartsWith('\\') and (sPath[3] <> '.') and (sPath[3] <> '?') then bIsNetPath := true; if sChkPath.StartsWith('\\?\UNC\') then begin // 네트워크 드라이브는 차단 처리 25_0305 13:53:05 kku // \\?\UNC\bsteam\BSShare\김구진\BSOne_OutTest_E_Blue.docx // \\?\UNC\192.168.15.3\BSShare\김구진\BSOne_OutTest_E.docx bIsNetPath := true; end; if not bIsNetPath then bIsNetPath := gAppHook.Helper.IsNetPath(sPath); end; // if bIsNetPath then // begin // if bDoLog then LogToReg('Step333', sPath); // // if not gAppHook.Helper.CtrlOpt.bIgrNetPathAB then // begin // if bDoLog then LogToReg('Step444', sPath); // Result := true; // {$IFDEF _BS1HP_} // gAppHook.ProcessNoti(NOTI_HOOK_BLOCK_ATTACH, sPath, 2); // {$ENDIF} // exit; // end; // end; if bDoLog then LogToReg('Step005', sPath); // 확장자 없는거 거르면... 디렉토리 접근은 거를수 있는데... // 문제는 확장자 없는 파일을 차단할 수 없다.. 그래도 일단 이렇게 진행함 22_1028 09:20:48 kku // if sExt = '' then // exit; // var bDoLog: Boolean := (sExt <> 'LOG') and (sExt <> 'TBRES') and (sExt <> 'TMP') and // (sExt <> 'API') and (sExt <> 'TEMP') and (sExt <> 'JS') and (sExt <> 'TTC') and // (sExt <> 'TTF'); if CompareText(gAppHook.sLogPath_, sPath) = 0 then exit; // gAppHook.Log(Format('CheckBlockFile(), Path=%s', [sPath])); // 디렉토리 거르는게 힘들다.. (1) 그래서 "1. abc" 라는 디렉토리를 거르기 위해서 추가 22_1109 08:55:52 kku // if sExt[1] = ' ' then // exit; // 디렉토리 거르는게 힘들다.. (2) // if StrToIntDef(sExt, -1) > -1 then // exit; if (gAppHook.Helper.CurAppType <> catExplorer) and // MTP 읽기만 사용시 탐색기로 인지되면 확장자 체크안함 24_0806 14:30:04 kku (gAppHook.Helper.CurAppType <> catwinscp) and ///DLL 예외 되어서 추가 (gAppHook.Helper.CurAppType <> catFilezilla) and (gAppHook.Helper.IgrAttBlkExts.IndexOf(sExt) <> -1) then exit; if CompareText(sFName, 'desktop.ini') = 0 then exit; if gAppHook.Helper.CurAppType = catOutlook then begin if Pos('\CONTENT.OUTLOOK\', sChkPath) = 0 then begin for i := 0 to gAppHook.Helper.IgrAttBlkPaths.Count - 1 do if Pos(gAppHook.Helper.IgrAttBlkPaths[i], sChkPath) > 0 then exit; end; end else begin for i := 0 to gAppHook.Helper.IgrAttBlkPaths.Count - 1 do if Pos(gAppHook.Helper.IgrAttBlkPaths[i], sChkPath) > 0 then exit; // if not FileExists('C:\ProgramData\HE\test.txt') then // gAppHook.Helper.IgrAttBlkPaths.SaveToFile('C:\ProgramData\HE\test.txt', TEncoding.UTF8); end; if bDoLog then LogToReg('Step006', sChkPath); if IsActiveFileDialog(sPath) then exit; if bDoLog then LogToReg('Step007', sPath); // 태그 확인 // hTagWnd := gAppHook.Helper.CtrlOpt.hTagWnd; // if hTagWnd <> 0 then // begin // if SendMessage(hTagWnd, 99, sPath) = 200 then // exit; // end; {$IFDEF _BS1HP_} if (gAppHook.Helper.CurAppType = catWebb) and (sExt = 'TMP') then bExistsFile := false // 브라우저의 다운로드 및 임시 파일은 없는걸로 인식 25_0327 17:55:32 kku else begin var O: ISuperObject := SO; O.S['P'] := sPath; O.S['M'] := gAppHook.ModuleName; O.I['D'] := dwDesiredAccess; O.I['S'] := dwShareMode; O.I['F'] := dwFlagsAndAttributes; O.I['T'] := Integer(gAppHook.Helper.CurAppType); // 존재하는 파일인지(첨부), 없는 파일인지(다운로드), // 파일명, 시그니처 체크 등 처리 // 파일명, 시그니처를 체크해서 대상이 아니면 100 반환 25_0429 16:37:10 kku case SendCopyData(gAppHook.Helper.CtrlOpt.hRcvWnd, HPCMD_EXISTS_FILE, O.AsJSon) of 100: exit; // 무시 300: bExistsFile := true; end; end; {$ENDIF} if bDoLog then LogToReg('Step4', '4'); // DRM 확인 if bExistsFile and gAppHook.Helper.CtrlOpt.bDrmAttachAble then begin hFile := ozCreateFileW(PChar(sPath), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); if (hFile <> 0) and (hFile <> INVALID_HANDLE_VALUE) then begin try var llSize: LONGLONG := 0; if GetFileSizeEx(hFile, llSize) then begin var hs: THandleStreamEx; Guard(hs, THandleStreamEx.Create(hFile, llSize)); if TTgEncrypt.CheckSign(hs, SIG_DRM) then exit; end; finally CloseHandle(hFile); end; end; end; if bDoLog then LogToReg('Step5', '5'); case gAppHook.Helper.CurAppType of catOutlook: begin if (sExt = 'PST') or (sExt = 'PDB') or (sExt = 'TLB') or (sExt = 'CONFIG') or // { (sExt = 'LNK') or } (sExt = 'ICO') or (sExt = 'TMP') then exit; // if (Pos('\INETCACHE\CONTENT.WORD\', sChkPath) > 0) and // (sFName[1] <> '~') then // 메일 메시지면 ~가 앞에 붙음 // begin // Result := true; // exit; // end; if (Pos('\INETCACHE\CONTENT.WORD\', sChkPath) > 0) and (sFName[1] = '~') then // 메일 메시지면 ~가 앞에 붙음 exit; // 아웃룩 업데이트 되었는지... 잡는 경로가 추가됨 23_1205 13:43:59 kku --- if Pos('\MICROSOFT\IDENTITYCACHE\', sChkPath) > 0 then exit; // if Pos('\INETCACHE\IE\', sChkPath) > 0 then // exit; if Pos('\WINDOWSAPPS\', sChkPath) > 0 then exit; // if Pos('\INETCACHE\CONTENT.OUTLOOK\', sChkPath) > 0 then // exit; if Pos('PREP_', ExtractFileName(sChkPath)) = 1 then exit; // ----------------------------------------------------------------------- // 캐시 폴더이고 이미지면 무시 23_0720 16:23:04 kku if (Pos('\MICROSOFT\WINDOWS\INETCACHE\', sChkPath) > 0) and (Pos(sExt, IMAGE_EXTS) > 0) then exit; if CompareText('HEARTBEATCACHE.XML', sFName) = 0 then exit; if sExt = 'DAT' then begin if Pos('ExchangePerf', sFName) = 1 then exit; // 8A9FF65F.dat 이런 형식의 첨부파일 캐시 넘기기 23_0511 14:11:17 kku if StrToInt64Def('$' + CutFileExt(sFName), 0) > 0 then exit; end; end; catWebb: begin if bDoLog then LogToReg('Step6', '6'); if gAppHook.Helper.IgrAttBlkWebFiles.IndexOf(sFName) <> -1 then exit; end; else begin if (CompareText(gAppHook.ModuleName, 'slack.exe') = 0) and (CompareText(sFName, 'package.json') = 0) then exit; end; end; if bDoLog then LogToReg('Step7', '7'); // {$IFDEF DEBUG} // var dwAttr: DWORD := GetFileAttributes(PChar(sPath)); // gAppHook.Log(Format('CheckBlockFile() .. Path=%s .. Attr=%d, Acc=%d, Mode=%d, 1=%d, 2=%d', [sPath, dwAttr, dwDesiredAccess, dwMode, dw1, dw2])); //// if dwAttr > 8000 then // 8449, 8480, 8224... //// gAppHook.Log(Format('CheckBlockFile() .. Path=%s .. Download, Attr=%d', [sPath, dwAttr])) //// else //// gAppHook.Log(Format('CheckBlockFile() .. Path=%s .. Upload, Attr=%d', [sPath, dwAttr])); // exit; // {$ENDIF} {$IFDEF _BS1HP_} FileUseBlock := gAppHook.Helper.CtrlOpt.FileUseBlock; var bBlockIf: Boolean := true; // if bIsNetPath and gAppHook.Helper.CtrlOpt.bIgrNetPathAB then // begin // FileUseBlock := fubMonitor; // bBlockIf := false; // end; if bDoLog then LogToReg('Step8', '8'); if gAppHook.Helper.CurAppType <> catOutlook then begin end; case gAppHook.Helper.CurAppType of catWebb: begin // 아래 왜 해놓은지 기억이 안니지만... // 이거 활성화 하면 다운로드 차단 후 다시 다운로드 시도하면 차단하지 못하는 문제 발생됨 24_1031 10:42:44 kku // if (sExt = 'TMP') and (CountStr(sFName, '-') = 4) then // exit; // if dwShareMode = 5 then // begin // // FILE_SHARE_READ 0x00000001, FILE_SHARE_WRITE 0x00000002, FILE_SHARE_DELETE 0x00000004 // // 브라우저에서 다운로드 받은 파일은 5로 확인됨 (FILE_SHARE_READ, FILE_SHARE_DELETE) // // 그 외 일반 업로드 시 3 (FILE_SHARE_READ, FILE_SHARE_WRITE) // // 특이점으로 gmail은 7 (FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_DELETE) // exit; // end; // var pt: TPoint; // GetCursorPos(pt); // var h: HWND := WindowFromPoint(pt); // var r: TRect; // ZeroMemory(@r, SizeOf(r)); // GetWindowRect(h, r); // LogToReg('MouseWnd', Format('H=%d, W=%d, H=%d', [h, r.Width, r.Height])); if bBlockIf and gAppHook.Helper.CtrlOpt.bCheckUrl then begin var O: ISuperObject := SO; O.S['ext'] := sExt; O.I['pid'] := gAppHook.PID; O.I['hwnd'] := gAppHook.Helper.CtrlOpt.hMainWnd; // if not gAppHook.Helper.CtrlOpt.bFileApproval and (sExt = 'PDF') then // begin // // 브라우저에서 PDF 파일 읽기면 허용하도록 추가 24_0814 10:29:17 kku // if SendCopyData(gAppHook.Helper.CtrlOpt.hRcvWnd, HPCMD_CHECK_URL, O.AsJSon) = 300 then // exit; // end; if SendCopyData(gAppHook.Helper.CtrlOpt.hRcvWnd, HPCMD_CHECK_URL, O.AsJSon) = 300 then begin if FileUseBlock = fubBlock then begin FileUseBlock := fubMonitor; // 차단 대상이 아닐경우 로그 남기도록 기능 추가 24_0812 13:34:36 kku bBlockIf := false; // 조건 더이상 따지지마라 end else exit; end; end; if bBlockIf and gAppHook.Helper.CtrlOpt.bFileApproval then begin if SendCopyData(gAppHook.Helper.CtrlOpt.hRcvWnd, HPCMD_APPROVAL_FILE, sPath) = 300 then begin if FileUseBlock = fubBlock then begin FileUseBlock := fubMonitor; // 차단 대상이 아닐경우 로그 남기도록 기능 추가 24_0812 13:34:36 kku bBlockIf := false; // 조건 더이상 따지지마라 end else exit; end; end; if bDoLog then LogToReg('Step9', '9'); end; catHwp, catMsOffice, catExplorer, catAdobeReader: ; else begin if bBlockIf and gAppHook.Helper.CtrlOpt.bFileApproval then begin if SendCopyData(gAppHook.Helper.CtrlOpt.hRcvWnd, HPCMD_APPROVAL_FILE, sPath) = 300 then begin if FileUseBlock = fubBlock then begin FileUseBlock := fubMonitor; // 차단 대상이 아닐경우 로그 남기도록 기능 추가 24_0812 13:34:36 kku bBlockIf := false; // 조건 더이상 따지지마라 end else exit; end; end; end; end; if bBlockIf and (FileUseBlock = fubBlock) and (gAppHook.Helper.CtrlOpt.nBlockSizeMB > 0) then begin var O: ISuperObject := SO; O.S['Path'] := sPath; O.I['Type'] := Integer(gAppHook.Helper.CurAppType); O.S['MName'] := gAppHook.ModuleName; if SendCopyData(gAppHook.Helper.CtrlOpt.hRcvWnd, HPCMD_CHECK_SIZE, O.AsString) <> 300 then begin if not gAppHook.Helper.CtrlOpt.bUseContentFilter then FileUseBlock := fubMonitor end else bBlockIf := false; end; if bBlockIf and gAppHook.Helper.CtrlOpt.bUseContentFilter then begin if bIsNetPath then begin if not gAppHook.Helper.CtrlOpt.bIgrNetPathAB then begin Result := true; {$IFDEF _BS1HP_} gAppHook.ProcessNoti(NOTI_HOOK_BLOCK_ATTACH, sPath, 2); {$ENDIF} exit; end else if FileUseBlock = fubBlock then FileUseBlock := fubMonitor // 차단 대상이 아닐경우 로그 남기도록 기능 추가 24_0812 13:34:36 kku end else if bExistsFile then begin var O: ISuperObject := SO; O.S['Path'] := sPath; O.I['Type'] := Integer(gAppHook.Helper.CurAppType); O.S['MName'] := gAppHook.ModuleName; if SendCopyData(gAppHook.Helper.CtrlOpt.hRcvWnd, HPCMD_CHECK_CONTENT, O.AsString) <> 300 then begin if FileUseBlock = fubBlock then FileUseBlock := fubMonitor; // 차단 대상이 아닐경우 로그 남기도록 기능 추가 24_0812 13:34:36 kku end; end; end; if bDoLog then LogToReg('Step10', '10'); var bDoPop: Boolean := false; // LogToReg('WebUp', Format('FName=%s, SM=%d', [sFName, dwShareMode])); if (gAppHook.Helper.CurAppType = catWebb) and not gAppHook.Helper.CtrlOpt.bWriteBlock then // 다운로드 차단이 아닐때만 체크 24_1031 10:37:07 kku begin if gAppHook.ThdWebABLog = nil then begin gAppHook.ThdWebABLog := TThdWebABLog.Create; gAppHook.ThdWebABLog.StartThread; end; // 다운로드 파일을 브라우저로 열기해서 다른 프로그램으로 열리는 경우 무시 24_0828 09:53:52 kku var h: HWND := GetForegroundWindow; var sPName: string := GetProcessNameFromWndHandle(h); // LogToReg('Focuce', Format('H=%d, M=%s, P=%s', [h, gAppHook.ModuleName, sPName])); if ((dwShareMode = 5) or (CompareText(gAppHook.ModuleName, sPName) <> 0)) and // if (CompareText(gAppHook.ModuleName, sPName) <> 0) and (gAppHook.ThdWebABLog <> nil) then begin // 브라우저에서 다운로드 파일을 "열기" 하면 로그가 두번 발생하는데 // 첫번째 로그는 dwShareMode=3, 두번째 로그는 dwShareMode=7 확인된다. // 열기는 제외하기 위해 7로 뜨면 기존꺼 삭제함 24_0328 08:22:36 kku // dwShareMode = 7 에서 5로 바꿈... 이거 브라우저 업데이트 될때마다 바뀌는건지 확인 필요... var n: Integer := gAppHook.ThdWebABLog.IndexOf(sPath); if n > -1 then begin gAppHook.ThdWebABLog.Del(n); exit; end; end; end; // 로그, 차단 분리해서 처리 하도록 보완 24_0325 14:54:32 kku case FileUseBlock of fubMonitor: begin if bDoLog then LogToReg('Step11', '11'); // var bExistsFile: Boolean := GetFileAttributes(PChar(sPath)) <> INVALID_FILE_ATTRIBUTES; // 읽기 체크 if gAppHook.Helper.CtrlOpt.bReadBlock then begin if bDoLog then LogToReg('Step11-1', '11'); if bExistsFile then begin case gAppHook.Helper.CurAppType of catWebb: begin if sExt = 'CRDOWNLOAD' then exit; // if dwShareMode = 7 then // begin // gAppHook.AddWebABLog(sPath); // exit; // end; end; catOutlook: begin // exit; // 사용하지 않음 24_0326 14:56:28 kku // 티맵에서 사용... 24_0520 13:38:00 kku // 다운로드는 한번, 업로드는 경로 읽기가 여러번 발생한다 이걸 이용 24_0325 17:42:02 kku // if gAppHook.Helper.sRecentWrBkPath_ = sPath then // begin // // 업로드 감지 // gAppHook.Helper.sRecentWrBkPath_ := ''; // end else // if Pos('\CONTENT.OUTLOOK\', sChkPath) > 0 then // begin // // 여기서 한번 끝나면 다운로드, 두번 이상 발생되면 업로드 // gAppHook.Helper.sRecentWrBkPath_ := sPath; // exit; // end; var dwAttr: DWORD := GetFileAttributes(PChar(sPath)); if dwAttr > 8000 then // 8449, 8480, 8224... Download begin exit; end; // 미리보기의 경우 dwAttr=128 일 수 있다. 한번더 체크 24_0326 13:59:02 kku // if Pos(' (00', sFName) > 0 then // exit; end; end; if gAppHook.Helper.CurAppType <> catOutlook then begin if gAppHook.Helper.sRecentWrBkPath_ = sPath then begin gAppHook.Helper.sRecentWrBkPath_ := ''; exit; end; end; bDoPop := ((dwDesiredAccess and GENERIC_ALL) <> 0) or ((dwDesiredAccess and GENERIC_READ) <> 0); end else if bIsNetPath then begin bDoPop := true; if bDoLog then LogToReg('Step11-2', '11'); end; end; if bDoLog then LogToReg('Step12', BooleanToStr(bDoPop, 'Y', 'N')); // 쓰기 체크 if not bDoPop and not bExistsFile then begin // 아웃룩 해당 없음 gAppHook.Helper.sRecentWrBkPath_ := sPath; // if gAppHook.Helper.CurAppType = catWebb then // begin // if sExt = 'TMP' then // exit; // // if Pos('DOWNLOAD', sPath.ToUpper) > 0 then // exit; // end; if gAppHook.Helper.CtrlOpt.bWriteBlock then bDoPop := bDoPop or ((dwDesiredAccess and GENERIC_ALL) <> 0) or ((dwDesiredAccess and GENERIC_WRITE) <> 0); end; if bDoPop then begin if bDoLog then LogToReg('Step13', '13'); if (gAppHook.Helper.CurAppType = catWebb) and (gAppHook.ThdWebABLog <> nil) then begin if bDoLog then LogToReg('Step14', '14'); gAppHook.ThdWebABLog.Add(sPath, BooleanToInt(bExistsFile or bIsNetPath, 1, 0), false); // if gAppHook.Helper.CurAppType = catWebb then // gAppHook.AddWebABLog(sPath) end else gAppHook.ProcessNoti(NOTI_HOOK_MONITOR_ATTACH, sPath, BooleanToInt(bExistsFile or bIsNetPath, 1, 0), true); end; exit; end; fubBlock: begin // if gAppHook.Helper.CurAppType = catWebb then // begin //// if GetFileAttributes(PChar(sPath)) <> INVALID_FILE_ATTRIBUTES then // begin // if gAppHook.ThdWebABLog = nil then // begin // gAppHook.ThdWebABLog := TThdWebABLog.Create; // gAppHook.ThdWebABLog.StartThread; // end; // // LogToReg('Step-01', sPath); // LogToReg('Step-02', IntToStr(dwShareMode)); // if (dwShareMode = 7) and (gAppHook.ThdWebABLog <> nil) then // begin // // 브라우저에서 다운로드 파일을 "열기" 하면 로그가 두번 발생하는데 // // 첫번째 로그는 dwShareMode=3, 두번째 로그는 dwShareMode=7 확인된다. // // 열기는 제외하기 위해 7로 뜨면 기존꺼 삭제함 24_0328 08:22:36 kku // gAppHook.ThdWebABLog.Del(sPath); // LogToReg('Step-03', sPath); // exit; // end; // end; // end; if bDoLog then LogToReg('Step14', '14'); // 읽기 체크 if gAppHook.Helper.CtrlOpt.bReadBlock then bDoPop := ((dwDesiredAccess and GENERIC_ALL) <> 0) or ((dwDesiredAccess and GENERIC_READ) <> 0); // 쓰기 체크 if gAppHook.Helper.CtrlOpt.bWriteBlock then bDoPop := bDoPop or not bExistsFile or ((dwDesiredAccess and GENERIC_ALL) <> 0) or ((dwDesiredAccess and GENERIC_WRITE) <> 0); if bDoPop then begin if (gAppHook.Helper.CurAppType = catWebb) and (gAppHook.ThdWebABLog <> nil) then begin gAppHook.ThdWebABLog.Add(sPath, BooleanToInt(bExistsFile or bIsNetPath, 1, 0), true); end else gAppHook.ProcessNoti(NOTI_HOOK_BLOCK_ATTACH, sPath, BooleanToInt(bExistsFile or bIsNetPath, 1, 0), true); end else exit; // 대상 아니면 차단 안되게 넘김 24_0122 15:57:56 kku end; end; {$ENDIF} Result := true; except // ... end; end; procedure ReqEncFile(sPath: String; nDelaySec: Integer); var hRcvWnd: HWND; O: ISuperObject; begin hRcvWnd := gAppHook.Helper.CtrlOpt.hRcvWnd; if hRcvWnd = 0 then hRcvWnd := StrToIntDef(GetRegValueAsString(HKEY_CURRENT_USER, 'Software\eCrmHomeEdition', 'RW'), 0); if hRcvWnd > 0 then begin O := SO; O.S['S'] := sPath; O.I['D'] := nDelaySec; SendCopyData(hRcvWnd, HPCMD_REQ_ENCRYPT, O.AsJSon); end; end; function ProcessEncFile(sPath: string; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): THandle; inline; var ms: TMemoryStream; dec: TTgDrmDec; dwTemp: DWORD; sExt, sFName, sVirtualPath: string; hFile: THandle; // llSize: LONGLONG; bChgRO, bValid, bModifyAble, bDecSuccess: Boolean; // h: HWND; pDrmFI: PDrmFileInfo; dwFlags: DWORD; dwFileAttr: DWORD; HeadInfo: TDrmHeadInfo; backupPath: string; begin Result := 0; ms := nil; dec := nil; backupPath := sPath; bValid := false; if (sPath.Length > 5) and sPath.StartsWith('\\?\') and (sPath[6] = ':') then Delete(sPath, 1, 4); if gAppHook = nil then exit; var bLog := false; // gAppHook.Helper.IsWord and (Pos('암호화 모듈 사용료.pdf', sPath) > 0); // if SameText('Microsoft.Mashup.Container.Loader.exe', gAppHook.ModuleName) and SameText('엑셀테스트 - 복사본.xlsx', ExtractFileName(sPath)) then // begin // sPath := 'C:\Users\kku\Desktop\엑셀테스트 - 복사본.xlsx'; // bLog := true; // end; if bLog then LogToReg('ProcessEncFile-01', sPath + ' - ' + IntToStr(dwDesiredAccess)); // gAppHook.Log('ProcessEncFile() .. '); ZeroMemory(@HeadInfo, SizeOf(HeadInfo)); try sFName := ExtractFileName(sPath); if sFName = '' then exit; sExt := GetFileExt(sFName).ToUpper; if sExt = '' then exit; if gAppHook.Helper.DrmExtList.IndexOf(sExt) = -1 then exit; try // 파일 열기 창에서 DRM 체크 안하도록 보완 22_1014 09:56:05 kku case dwDesiredAccess of 0, $80, GENERIC_WRITE: begin // if SameText('excel.exe', gAppHook.ModuleName) and (dwDesiredAccess = $80) then // begin // // end else exit; end; end; if IsActiveFileDialog(sPath) then exit; if bLog then LogToReg('ProcessEncFile-02', sPath); if CompareText(gAppHook.ModuleName, 'hwpviewer.exe') = 0 then begin var sExtTmp := ExtractFileExt(sPath); if (CompareText(sExtTmp, '.hwp') <> 0) and (CompareText(sExtTmp, '.hwpx') <> 0) then begin Exit; end; end else begin dwFlags := dwFlagsAndAttributes;//GetFileAttributes(PChar(sPath)); if (dwFlags and FILE_ATTRIBUTE_DIRECTORY) <> 0 then exit; end; if bLog then LogToReg('ProcessEncFile-03', sPath); bValid := true; if (not gAppHook.LogProcessing and not gAppHook.InternalOpen) then begin {$IFDEF USE_BOXAPP} // DEF_BOXEDAPPSDK_OPTION__ALL_CHANGES_ARE_VIRTUAL 옵션을 사용해서 // 기타 가상 파일이 있을 수 있으므로 이걸로 판별하면 안된다. 22_1128 15:17:31 kku // if gAppHook.LoadedBoxApp and BoxedAppSDK_IsVirtualFile(PChar(sPath)) then // begin // sVirtualPath := sPath; // end else if gAppHook.LoadedBoxApp and gAppHook.Helper.IsDrmUseBoxedApp and gAppHook.Helper.DcDecPath.ContainsKey(sPath) then begin sVirtualPath := gAppHook.Helper.DcDecPath[sPath]; end else {$ENDIF} begin sVirtualPath := ''; bDecSuccess := false; if bLog then LogToReg('ProcessEncFile-04', sPath); // if not ForceDirectories(gAppHook.Helper.CtrlOpt.sTaskDir) then // exit; // if (gAppHook.Helper.CurAppType = catMsOffice) and sFName.StartsWith('~$') then // if (gAppHook.Helper.CurAppType = catMsOffice) and (sFName.StartsWith('~')) then case gAppHook.Helper.CurAppType of catMsOffice: begin if (sFName.StartsWith('~$') or sFName.StartsWith('~W')) then begin exit; end; if (sExt = 'DOC') and ( (Pos('\AC\TEMP\', UpperCase(sPath)) > 0) or (Pos('\CONTENT.WORD\', UpperCase(sPath)) > 0) ) then exit; end; end; if bLog then LogToReg('ProcessEncFile-05', sPath); // _TgDrmHook.Log(Format('Check Ext Success .. FName=%s', [sFName])); bModifyAble := true; try gAppHook.InternalOpen := true; // LogToReg('ProcessEncFile-_bInternalOpen-true', DateTimeToStr(Now) + '-' + IntToStr(GetTickCount)); try ms := TMemoryStream.Create; if bLog then LogToReg('ProcessEncFile-06', sPath); case gAppHook.Helper.CurAppType of catHwp, catMsOffice: begin if (gAppHook.Helper.RecentDrmFI_.sOrgPath <> '') and (CompareText(gAppHook.Helper.RecentDrmFI_.sOrgPath, sPath) = 0) and not TTgEncrypt.CheckSign(sPath, SIG_DRM) then begin gAppHook.Helper.RecentDrmFI_.sOrgPath := ''; var sTemp: string := gAppHook.Helper.CtrlOpt.sTaskDir + ExtractFileName(sPath) + '.etmp'; if CopyFile(PChar(sPath), PChar(sTemp), false) then begin DeleteFile(sPath); var enc: TTgDrmEnc; Guard(enc, TTgDrmEnc.Create(sPath)); with gAppHook.Helper.RecentDrmFI_.HeadInfo do begin if enc.SetHaed(PASS_DRM_HEAD, SIG_DRM, sEmpNo, sHostName, sPartName, sPgName, dwCustomerCode) then if enc.EncryptFromFile(DecText(gAppHook.Helper.CtrlOpt.sDrmPass), sTemp) then DeleteFile(PChar(sTemp)); end; end; end; end; end; if TTgEncrypt.CheckSign(sPath, SIG_DRM) then begin if bLog then LogToReg('ProcessEncFile-07', sPath); // _TgDrmHook.Log(Format('FileSize=%d', [fs.Size])); dec := TTgDrmDec.Create(sPath); try if not dec.CheckSig(SIG_DRM) then begin // _TgDrmHook.Log(Format('Fail .. CheckSign(), FName=%s', [sFName])); exit; end else begin gAppHook.Log(Format('Success .. CheckSign(), FName=%s', [sFName])); end; // HWP에서는 딜레이를 줘야 파일을 인식함... 25_0226 11:16:59 kku if gAppHook.Helper.CurAppType = catHwp then Sleep(100); if not dec.ExtrHead(PASS_DRM_HEAD) then begin gAppHook.Log('Fail .. ExtrHead()'); exit; end; if dec.Head.dwCustomerCode <> gAppHook.Helper.CtrlOpt.dwCustomerType then begin {$IFDEF _BS1HP_} // gAppHook.ProcessNoti(NOTI_HOOK_BLOCK_DRM_CT, sPath + Format('-%d=%d', [DrmHead.dwCustomerCode, gAppHook.Helper.CtrlOpt.dwCustomerType])); gAppHook.ProcessNoti(NOTI_HOOK_BLOCK_DRM_CT, sPath, 0); {$ENDIF} exit; end; if bLog then LogToReg('ProcessEncFile-08', sPath); // LogToReg('DRM-05', Format('Path=%s', [sPath])); {$IFDEF _BS1HP_} // LogToReg('DRM-01', Format('EmpNo=%s, DrmEmpNo=%s', [dec.EmpNo, gAppHook.Helper.CtrlOpt.sEmpNo])); // LogToReg('DRM-02', Format('PartName=%s, DeptName=%s', [dec.PartName, gAppHook.Helper.CtrlOpt.sDeptName])); case gAppHook.Helper.CtrlOpt.DrmAccessKind of dakEmpNo: begin // LogToReg('DRM-EmpNo-1', Format('EmpNo=%s, DrmEmpNo=%s', [dec.EmpNo, gAppHook.Helper.CtrlOpt.sEmpNo])); if CompareText(dec.EmpNo, gAppHook.Helper.CtrlOpt.sEmpNo) <> 0 then begin gAppHook.ProcessNoti(NOTI_HOOK_BLOCK_DRM, sPath, 0); exit; end; end; dakDept: begin // LogToReg('DRM-Dept-1', Format('EmpNo=%s, DrmEmpNo=%s', [dec.EmpNo, gAppHook.Helper.CtrlOpt.sEmpNo])); // LogToReg('DRM-Dept-2', Format('PartName=%s, DeptName=%s', [dec.PartName, gAppHook.Helper.CtrlOpt.sDeptName])); if (CompareText(dec.EmpNo, gAppHook.Helper.CtrlOpt.sEmpNo) <> 0) and (CompareText(dec.PartName, gAppHook.Helper.CtrlOpt.sDeptName) <> 0) then begin gAppHook.ProcessNoti(NOTI_HOOK_BLOCK_DRM, sPath, 0); exit; end; end; end; {$ENDIF} if not dec.DecryptToStream(DecText(gAppHook.Helper.CtrlOpt.sDrmPass), ms) then begin gAppHook.Log('Fail .. DecryptToStream()'); exit; end; if bLog then LogToReg('ProcessEncFile-09', sPath); if (sExt = 'TXT') or (sExt = 'PDF') or (sExt = 'HWP') then begin ms.Position := 0; _sEncFileHash := GetStreamToSha1Str(ms); // ms.SaveToFile(sPath + '.bak'); // LogToReg('FHash1', Format('Hash1 = %s (%d)', [_sEncFileHash, ms.Size])); ms.Position := 0; end else _sEncFileHash := ''; if bLog then LogToReg('ProcessEncFile-09-01', sPath); gAppHook.Helper.dwRecentOpenCustomType_ := dec.Head.dwCustomerCode; gAppHook.Helper.sRecentOpenPath_ := sPath; gAppHook.Helper.sRecentOpenEmpNo_ := dec.EmpNo; gAppHook.Helper.sRecentOpenDeptName_ := dec.PartName; HeadInfo.sEmpNo := dec.EmpNo; HeadInfo.sHostName := dec.HostName; HeadInfo.sPartName := dec.PartName; HeadInfo.sPgName := dec.PolicyGroup; HeadInfo.dwCustomerCode := dec.Head.dwCustomerCode; {$IFDEF _BS1HP_} case gAppHook.Helper.CtrlOpt.DrmModifyKind of dakNone: bModifyAble := false; dakEmpNo: bModifyAble := CompareText(dec.EmpNo, gAppHook.Helper.CtrlOpt.sEmpNo) = 0; dakDept: bModifyAble := (CompareText(dec.EmpNo, gAppHook.Helper.CtrlOpt.sEmpNo) = 0) or (CompareText(dec.PartName, gAppHook.Helper.CtrlOpt.sDeptName) = 0); end; {$ELSE} bModifyAble := true; {$ENDIF} // LogToReg('DRM-MOD', Format('%s', [BooleanToStr(bModifyAble, 'YES', 'NO')])); finally FreeAndNil(dec); if bLog then LogToReg('ProcessEncFile-09-02', sPath); // if (sExt = 'DOC') and bModifyAble then if ((sExt = 'DOC') and bModifyAble) or (gAppHook.Helper.IsWord and (sExt = 'PDF')) then begin // DOC는 이렇게 원본파일을 복호화 해놓고 처리 25_1030 14:18:42 kku ms.SaveToFile(sPath); ms.Position := 0; end; end; if bLog then LogToReg('ProcessEncFile-09-03', sPath); {$IFDEF USE_BOXAPP} if gAppHook.LoadedBoxApp and not bModifyAble then BoxedAppSDK_EnableOption(DEF_BOXEDAPPSDK_OPTION__ALL_CHANGES_ARE_VIRTUAL, TRUE); {$ELSE} // if not bModifyAble then // begin // var nAttr: Integer := FileGetAttr(sPath); // if (nAttr and faReadOnly) = 0 then // FileSetAttr(sPath, nAttr or faReadOnly); // end; {$ENDIF} if bLog then LogToReg('ProcessEncFile-09-04', sPath); bDecSuccess := true; if bLog then LogToReg('ProcessEncFile-10', sPath); end; finally if bDecSuccess then begin var sWorkDir: string := gAppHook.Helper.CtrlOpt.sTaskDir; if sWorkDir = '' then begin sWorkDir := 'C:\ProgramData\HE\Desk\'; if not ForceDirectories(sWorkDir) then sWorkDir := ''; end; {$IFDEF USE_BOXAPP} if gAppHook.LoadedBoxApp and gAppHook.Helper.IsDrmUseBoxedApp then begin BoxedAppSDK_EnableOption(DEF_BOXEDAPPSDK_OPTION__ALL_CHANGES_ARE_VIRTUAL, TRUE); sVirtualPath := sWorkDir + 'V@' + sFName; // sVirtualPath := '@TgDRM\' + ExtractFilePath(sPath) + sFName; // sVirtualPath := ExtractFilePath(sPath) + Format('#%d_%s', [GetTickCount, sFName]); // 가상 파일 생성 hFile := BoxedAppSDK_CreateVirtualFile(PChar(sVirtualPath), GENERIC_WRITE, FILE_SHARE_READ, nil, CREATE_NEW, FILE_ATTRIBUTE_HIDDEN, 0); // GENERIC_WRITE, dwShareMode, lpSecurityAttributes, CREATE_NEW, dwFlagsAndAttributes {FILE_ATTRIBUTE_HIDDEN}, hTemplateFile); end else {$ENDIF} begin // if (sExt = 'DOC') and bModifyAble then if ((sExt = 'DOC') and bModifyAble) or (gAppHook.Helper.IsWord and (sExt = 'PDF')) then begin Result := ozCreateFileW(PChar(sPath), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); end else begin sVirtualPath := sWorkDir + Format('#%d_%s', [GetTickCount, sFName]); // LogToReg('DRM-VTPATH', Format('Path=%s', [sVirtualPath])); // LogToReg('DRM-KEY', Format('Path=%s', [gAppHook.Helper.CtrlOpt.sDrmPass])); var dwAttr: DWORD := FILE_ATTRIBUTE_HIDDEN or FILE_FLAG_DELETE_ON_CLOSE; if gAppHook.Helper.ChkDelOnClose then begin // if (sExt = 'XLSX') or (sExt = 'XLS') then begin dwAttr := FILE_ATTRIBUTE_HIDDEN; sVirtualPath := sWorkDir + Format('$d-#%d_%s', [GetTickCount, sFName]); end; end; // 가상 파일 생성 hFile := ozCreateFileW(PChar(sVirtualPath), GENERIC_WRITE or GENERIC_READ, dwShareMode, nil, CREATE_ALWAYS { CREATE_NEW } , dwAttr, 0); end; end; if (hFile <> 0) and (hFile <> INVALID_HANDLE_VALUE) then begin WriteFile(hFile, ms.Memory^, ms.Size, dwTemp, nil); // if bLog then ms.SaveToFile(sVirtualPath + '.txt'); {$IFDEF USE_BOXAPP} if gAppHook.LoadedBoxApp and gAppHook.Helper.IsDrmUseBoxedApp then gAppHook.Helper.DcDecPath.Add(sPath, sVirtualPath); {$ENDIF} if bLog then LogToReg('ProcessEncFile-11', sPath); if FileSeek(hFile, 0, 0) = 0 then begin if bLog then LogToReg('ProcessEncFile-12', sPath); Result := hFile end else begin CloseHandle(hFile); if bLog then LogToReg('ProcessEncFile-13', sPath); end; end; end; gAppHook.InternalOpen := false; // LogToReg('ProcessEncFile-_bInternalOpen-false', DateTimeToStr(Now) + '-' + IntToStr(GetTickCount)); if ms <> nil then FreeAndNil(ms); end; {$IFDEF _BS1HP_} // if (sExt = 'DOC') and (Result <> 0) and bModifyAble then if (Result <> 0) and ( ((sExt = 'DOC') and bModifyAble) or (gAppHook.Helper.IsWord and (sExt = 'PDF')) ) then begin if sExt = 'PDF' then ReqEncFile(sPath, 13) else ReqEncFile(sPath, 2); // LogToReg('DRM-0000', 'HPCMD_REQ_ENCRYPT->' + IntToStr(hRcvWnd)); end; {$ENDIF} except // .. sVirtualPath := ''; end; end; if (Result = 0) and (sVirtualPath <> '') then begin {$IFDEF USE_BOXAPP} if gAppHook.LoadedBoxApp and gAppHook.Helper.IsDrmUseBoxedApp then begin Result := ozCreateFileW(PChar(sVirtualPath), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); end {$ELSE} else begin var dwAttr: DWORD := dwFlagsAndAttributes or FILE_FLAG_DELETE_ON_CLOSE; if gAppHook.Helper.ChkDelOnClose then begin if (sExt = 'XLSX') or (sExt = 'XLS') then begin dwAttr := dwFlagsAndAttributes; sVirtualPath := sWorkDir + Format('$d-#%d_%s', [GetTickCount, sFName]); end; end; Result := ozCreateFileW(PChar(sVirtualPath), dwDesiredAccess, 0, lpSecurityAttributes, dwCreationDisposition, dwAttr, hTemplateFile); end {$ENDIF} ; end; if (Result <> 0) and (Result <> INVALID_HANDLE_VALUE) then begin {$IFDEF _BS1HP_} if bModifyAble then begin gAppHook.ProcessNoti(NOTI_HOOK_OPEN_DRM, sPath, 0) end else begin gAppHook.ProcessNoti(NOTI_HOOK_OPEN_DRM_NO_MODIFY, sPath, 0); // gAppHook.Helper.AddIgrWriteFile(Result); end; {$ENDIF} if gAppHook.Helper.DcDrmFI.ContainsKey(Result) then begin gAppHook.Log('Fail .. ProcessEncFile() .. Already Handle??'); {$IFDEF DEBUG} ASSERT(false); {$ELSE} exit; {$ENDIF} ; end; bChgRO := false; // {$IFNDEF USE_BOXAPP} // if gAppHook.LoadedBoxApp and not bModifyAble then // begin // var nAttr: Integer := FileGetAttr(sPath); // if (nAttr and faReadOnly) = 0 then // begin // FileSetAttr(sPath, nAttr or faReadOnly); // bChgRO := true; // end; // end; // {$ENDIF} New(pDrmFI); ZeroMemory(pDrmFI, SizeOf(TDrmFileInfo)); pDrmFI.hFile := Result; pDrmFI.sOrgPath := sPath; pDrmFI.sDecPath := sVirtualPath; pDrmFI.bModifyAble := bModifyAble; pDrmFI.bChgRO := bChgRO; if HeadInfo.dwCustomerCode <> 0 then begin pDrmFI.HeadInfo := HeadInfo; // LogToReg('DRM-FI-01', Format('EmpNo=%s', [pDrmFI.HeadInfo.sEmpNo])); // LogToReg('DRM-FI-02', Format('PartName=%s', [pDrmFI.HeadInfo.sPartName])); end; pDrmFI.bModified := true; gAppHook.Helper.DcDrmFI.Add(Result, pDrmFI); end; end; except // .. if bLog then LogToReg('ProcessEncFile-exp???', sPath); end; finally if bLog then LogToReg('ProcessEncFile-end', sPath); if Result = 0 then begin if bLog then LogToReg('ProcessEncFile-end0', sPath); if (sFName <> '') and sFName.StartsWith('$d-') then dwFlagsAndAttributes := dwFlagsAndAttributes or FILE_FLAG_DELETE_ON_CLOSE; Result := ozCreateFileW(PChar(backupPath), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); end; if bValid then begin {$IFDEF _BS1HP_} case gAppHook.Helper.CtrlOpt.dwCustomerType of CUSTOMER_DEMO, CUSTOMER_DEV: begin case dwDesiredAccess of 0, $80, GENERIC_WRITE: ; else begin if ((dwFlags and FILE_ATTRIBUTE_DIRECTORY) = 0) and ((dwDesiredAccess and GENERIC_READ <> 0) or (dwDesiredAccess and FILE_READ_DATA <> 0)) then begin if (gAppHook.DocExtList.IndexOf(GetFileExt(sPath)) <> -1) and not sFName.StartsWith('~$') then begin if SameText('FOXITPDFREADER.EXE', gAppHook.ModuleName) and (GetFileExt(sPath).ToUpper = 'TXT') then begin // foxit에서 실행될때 frpkey.txt 파일 읽음... end else gAppHook.ProcessNoti(NOTI_HOOK_OPEN_DOC, sPath, 0, true); end; end; end; end; end; end; {$ENDIF} end; end; end; function ProcessFileHook(sPath: string; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): THandle; inline; var bMtpWB, bIgrRead, bIgrWrite: Boolean; bMtpOpen: Boolean; dwFlags: DWORD; sChkPath: string; begin Result := 0; // INVALID_HANDLE_VALUE; // 하나의 프로시저에서 끝내야 안전성이 높아서 보안 처리 22_1228 14:39:16 kku var bLog := false; // gAppHook.Helper.IsWord and (Pos('암호화 모듈 사용료.pdf', sPath) > 0); if bLog then LogToReg('ProcessFileHook-01', sPath + ' - IOpen : ' + BooleanToStr(gAppHook.InternalOpen, 'Yes', 'No')); bIgrRead := false; bIgrWrite := false; bMtpOpen := false; try if (gAppHook <> nil) and (((gAppHook.Helper.CurAppType = catAdobeReader) and (GetFileExt(sPath).ToUpper <> 'PDF')) or gAppHook.InternalOpen) then begin Result := ozCreateFileW(PChar(sPath), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); exit; end; if bLog then LogToReg('ProcessFileHook-02', sPath); sChkPath := sPath.ToUpper; bMtpWB := gAppHook.Helper.CtrlOpt.bMtpWB and (Pos('\\.\PIPE\', sChkPath) = 0); // cloudium 가상 드라이브 예외 처리 25_0925 12:07:53 kku if bMtpWB then begin if (gAppHook._dwMtpTick > 0) and ((GetTickCount - gAppHook._dwMtpTick) < 1500) then begin gAppHook._dwMtpTick := GetTickCount // MTP로 인지하고 1.5초안지나면 계속 MTP로 이동하는 파일로 인지 24_0604 16:23:13 kku end else begin gAppHook._hMTP := 0; gAppHook._sMtpDev := ''; gAppHook._dwMtpTick := 0; end; end; // USB 저장소 = \\?\STORAGE#Volume#{8f8d27bb-4dd9-11ee-bd39-806e6f6e6963}#0000000001000000#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b} // 고정 드라이브 = \\?\Volume{30c55c29-4415-494d-9e10-028b93f0127b} // MTP 이미지 전송 = \\?\usb#vid_04e8&pid_6865#r3ct80nyn8y#{6ac27878-a6fa-4155-ba85-f98f491d4f33} // MTP 파일 전송 = \\?\usb#vid_04e8&pid_6860&ms_comp_mtp&samsung_android#7&636b8ec&50&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33} if bMtpWB and (gAppHook._dwMtpTick = 0) and (Pos('\\?\USB', sChkPath) = 1) then // and (Pos('mtp', sChkPath) > 0) then // MTP 이미지 전송도 읽기만 가능하기 위해 수정 24_0625 13:54:04 kku begin var bBlock := true; if gAppHook.Helper.MtpRoExpList.Count > 0 then begin var i: Integer; for i := 0 to gAppHook.Helper.MtpRoExpList.Count - 1 do begin if Pos(gAppHook.Helper.MtpRoExpList[i], sChkPath) > 0 then begin bBlock := false; break; end; end; end; if bBlock then begin // 보완 필요... 24_0305 16:23:02 kku bMtpOpen := true; gAppHook._sMtpDev := sPath; gAppHook._dwMtpTick := GetTickCount; LogToReg2('Step-MTP0', sPath); end; end; if bLog then LogToReg('ProcessFileHook-03', sPath); // var bLog: Boolean := false; //(Pos('C:\PROGRAMDATA\', sChkPath) = 0) and (Pos('C:\USERS\', sChkPath) = 0); // if bLog then // LogToReg('Step-MTP001', sPath); if (Pos('\\.\PIPE\', sChkPath) = 0) and ((gAppHook.Helper.CtrlOpt.FileUseBlock <> fubNone) or bMtpWB) then begin // MTP 읽기만 사용 시 123.456 처럼 .이 있는 폴더가 차단됨.. // 폴더는 무시하도록 기능 보완 24_0620 19:17:20 kku if gAppHook.Helper.CurAppType = catExplorer then dwFlags := GetFileAttributes(PChar(sPath)) else dwFlags := 0; if ((dwFlags and FILE_ATTRIBUTE_DIRECTORY) = 0) and CheckBlockFile(dwDesiredAccess, dwShareMode, dwCreationDisposition, dwFlagsAndAttributes, sPath) then begin if CompareText(gAppHook.ModuleName, 'firefox.exe') = 0 then begin // 파이어폭스는 아래처럼 처리하면 차단이 안된다... 25_0424 10:48:54 kku exit; end; // LogToReg('Step-MTP1', sPath); // {$IFDEF DEBUG} // bIgrRead := true; // bIgrWrite := true; // MTP 쓰기 차단, 차단정책이 있으면 explorer.exe만 bMtpWB에 true가 들어감 24_0304 16:43:12 kku // if bMtpWB then // exit; // 읽기 차단 if ((gAppHook.Helper.CtrlOpt.FileUseBlock = fubBlock) and gAppHook.Helper.CtrlOpt.bReadBlock) or (bMtpWB and (gAppHook._sMtpDev <> '')) then begin if (dwDesiredAccess and GENERIC_ALL) <> 0 then dwDesiredAccess := (dwDesiredAccess - GENERIC_ALL) + GENERIC_WRITE + GENERIC_EXECUTE else if (dwDesiredAccess and GENERIC_READ) <> 0 then dwDesiredAccess := dwDesiredAccess - GENERIC_READ; end; // 쓰기 차단 if ((gAppHook.Helper.CtrlOpt.FileUseBlock = fubBlock) and gAppHook.Helper.CtrlOpt.bWriteBlock) or (bMtpWB and (gAppHook._sMtpDev <> '')) then begin if (dwDesiredAccess and GENERIC_ALL) <> 0 then dwDesiredAccess := (dwDesiredAccess - GENERIC_ALL) + GENERIC_READ + GENERIC_EXECUTE else if (dwDesiredAccess and GENERIC_WRITE) <> 0 then dwDesiredAccess := dwDesiredAccess - GENERIC_WRITE; end; // {$ELSE} // exit; // {$ENDIF} end; end; if bLog then LogToReg('ProcessFileHook-04', sPath); if (gAppHook.Helper.CurAppType <> catExplorer) and gAppHook.Helper.IsDrmSupport and (gAppHook.Helper.CtrlOpt.DrmAccessKind <> dakNone) then // {$IFDEF _BS1HP_} and MutexExists(MUTEX_SHELL_DRMOPEN) {$ENDIF} then begin if bLog then LogToReg('ProcessFileHook-05', sPath); // 인터넷 다운로드 파일의 경우 ADS 삭제 24_1121 09:15:36 kku case gAppHook.Helper.CurAppType of catMsOffice: begin if FileExists(sPath + ':Zone.Identifier:$DATA') then DeleteFile(sPath + ':Zone.Identifier:$DATA'); end; end; Result := ProcessEncFile(sPath, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); end; except // .. end; if Result = 0 then begin Result := ozCreateFileW(PChar(sPath), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); end; if (Result <> 0) and (Result <> INVALID_HANDLE_VALUE) then begin // todo : 사용하지 않을거 같음 24_0122 14:18:29 kku if bIgrRead then gAppHook.Helper.AddIgrReadFile(Result); if bIgrWrite then gAppHook.Helper.AddIgrWriteFile(Result); if bMtpOpen then begin gAppHook._hMTP := Result; gAppHook.Log('MTP Open ..'); LogToReg2('Step-MTP2', sPath); // gAppHook.Log(Format('MTP Open .. Title = %s', [GetWindowCaption(GetForegroundWindow)])); end; end; // 아래를 켜야 프린트 하는 파일 이름을 알아올 수 있다. (DLL이 붙기전에 열린 파일은 안됨) // 하지만 크롬, 엣지에서 크러쉬 되는 문제가 있어서 일단 닫아둔다. 22_1025 13:46:56 kku // if gAppHook.Helper.CtrlOpt.bPrintWater then // begin // if (Result <> 0) and (Result <> INVALID_HANDLE_VALUE) then // begin // if CompareText(PChar(gAppHook.sLogPath_), PChar(sPath)) = 0 then // exit; // // if Pos(GetFileExt(sPath).ToUpper, PRINT_PATH_EXT) = 0 then // exit; // // gAppHook.AddCreateFile(Result, sPath); //// if (gAppHook.OFList_ <> nil) and (gAppHook.OFList_.IndexOf(sPath) = -1) then //// gAppHook.OFList_.Add(sPath); // end; // end; end; function CreateFileAHook(lpFileName: PAnsiChar; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): THandle; stdcall; begin Result := ProcessFileHook(StrPas(lpFileName), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); end; function CreateFileWHook(lpFileName: PWideChar; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): THandle; stdcall; begin Result := ProcessFileHook(StrPas(lpFileName), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); if gApiHookContents_ <> nil then gApiHookContents_.CreateFileProc(Result, lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); end; function CloseHandleHook(hFile: THandle): BOOL; stdcall; var pInfo: PDrmFileInfo; enc: TTgDrmEnc; hs: THandleStreamEx; ms: TMemoryStream; llSize: LONGLONG; bDoEnc: Boolean; sExt: string; // ms: TMemoryStream; begin Result := FALSE; try if (gAppHook = nil) or (gAppHook.Helper = nil) then exit; if gApiHookContents_ <> nil then gApiHookContents_.CloseHandleProc(hFile); if gAppHook.InternalOpen then begin Result := ozCloseHandle(hFile); exit; end; gAppHook.Helper.DelOgrReadFile(hFile); gAppHook.Helper.DelOgrWriteFile(hFile); gAppHook.DelCloseFile(hFile); if gAppHook.Helper.DcDrmFI.ContainsKey(hFile) then begin pInfo := gAppHook.Helper.DcDrmFI[hFile]; sExt := GetFileExt(pInfo.sOrgPath).ToUpper; // if GetFileExt(pInfo.sOrgPath).ToUpper = 'DOC' then // begin // Result := ozCloseHandle(hFile); // exit; // end; gAppHook.InternalOpen := true; // gAppHook.Log(Format('CloseHandleHook() .. ProcessEncHandle, OrgPath=%s', [pInfo.sOrgPath])); // gAppHook.Log(Format('CloseHandleHook() .. ProcessEncHandle, DecPath=%s', [pInfo.sDecPath])); try // LogToReg('Enc01', Format('CloseHandleHook() .. Path=%s', [pInfo.sOrgPath])); // LogToReg('DRM-ENC-00', ExtractFileName(pInfo.sOrgPath)); if gAppHook.Helper.IsForceEncSave or pInfo.bModified then begin // LogToReg('DRM-ENC-00aaa', ExtractFileName(pInfo.sOrgPath)); // if (sExt = 'DOC') then // begin // gAppHook.Helper.RecentDrmFI_.sOrgPath := pInfo.sOrgPath; // gAppHook.Helper.RecentDrmFI_.HeadInfo := pInfo.HeadInfo; // // LogToReg('DRM-ENC-01', ExtractFileName(pInfo.sOrgPath)); // // Result := ozCloseHandle(hFile); // hFile := 0; // // if not TTgEncrypt.CheckSign(pInfo.sOrgPath, SIG_DRM) then // 이중으로 암호화 되지 않도록 한번더 체크 24_1122 11:09:17 kku // begin // LogToReg('DRM-ENC-02', ExtractFileName(pInfo.sOrgPath)); // // Guard(ms, TMemoryStream.Create); // ms.LoadFromFile(pInfo.sOrgPath); // // var sBkPath: String := 'C:\ProgramData\HE\EncTask\'; // if ForceDirectories(sBkPath) then // begin // sBkPath := sBkPath + '$bk_' + ExtractFileName(pInfo.sOrgPath); // if CopyFile(PChar(pInfo.sOrgPath), PChar(sBkPath), false) then // SaveStrToFile(sBkPath + '.i', pInfo.sOrgPath, TEncoding.UTF8); // end; // // LogToReg('DRM-ENC-03', ExtractFileName(pInfo.sOrgPath)); // // enc := TTgDrmEnc.Create(pInfo.sOrgPath); // try // with pInfo.HeadInfo do // begin // if enc.SetHaed(PASS_DRM_HEAD, SIG_DRM, sEmpNo, sHostName, // sPartName, sPgName, dwCustomerCode) then // begin // LogToReg('DRM-ENC-04', ExtractFileName(pInfo.sOrgPath)); // if enc.EncryptFromStream(DecText(gAppHook.Helper.CtrlOpt.sDrmPass), ms) then // begin // if FileExists(sBkPath) then // begin // LogToReg('DRM-ENC-05', ExtractFileName(pInfo.sOrgPath)); //// FreeAndNil(enc); //// ms.SaveToFile(pInfo.sOrgPath); // // DeleteFile(PChar(sBkPath)); // DeleteFile(PChar(sBkPath + '.i')); // end; // end else begin // if FileExists(sBkPath) and // CopyFile(PChar(sBkPath), PChar(pInfo.sOrgPath), false) then // begin // DeleteFile(PChar(sBkPath)); // DeleteFile(PChar(sBkPath + '.i')); // end; // end; // end else begin // // end; // end; // LogToReg('DRM-ENC-06', ExtractFileName(pInfo.sOrgPath)); // finally // if enc <> nil then // FreeAndNil(enc); // end; // end; // end else if ((gAppHook.Helper.CurAppType = catMsOffice) or ((gAppHook.Helper.CurAppType = catHwp) and (sExt = 'HWPX'))) then begin {$IFDEF _BS1HP_} // if sExt = 'DOC' then // DOC는 위에서 HPCMD_REQ_ENCRYPT 로 처리 함 25_1030 14:49:49 kku if (sExt = 'DOC') or (gAppHook.Helper.IsWord and (sExt = 'PDF')) then begin if sExt = 'PDF' then ReqEncFile(pInfo.sOrgPath, 13) else ReqEncFile(pInfo.sOrgPath, 2); end else {$ENDIF} begin gAppHook.Helper.RecentDrmFI_.sOrgPath := pInfo.sOrgPath; gAppHook.Helper.RecentDrmFI_.HeadInfo := pInfo.HeadInfo; end; // gAppHook.Helper.RecentDrmFI_.sDecPath := pInfo.sDecPath; // gAppHook.Helper.RecentDrmFI_.bModifyAble := pInfo.bModifyAble; // gAppHook.Helper.RecentDrmFI_.Head := pInfo.Head; // CopyMemory(@gAppHook.Helper.RecentDrmFI_.Head, @pInfo.Head, SizeOf(pInfo.Head)); end else begin if not GetFileSizeEx(hFile, llSize) then begin // gAppHook.Log('CloseHandleHook() .. Fail .. GetFileSizeEx()'); exit; end; // LogToReg('Enc02', Format('CloseHandleHook() .. Path=%s', [pInfo.sOrgPath])); Guard(hs, THandleStreamEx.Create(hFile, llSize)); hs.Position := 0; // hs로 GetStreamToSha1Str() 처리가 제대로 안되서 아래처럼 추가 처리.. 25_0911 17:47:15 kku Guard(ms, TMemoryStream.Create); ms.CopyFrom(hs); if not TTgEncrypt.CheckSign(hs, SIG_DRM) then // 이중으로 암호화 되지 않도록 한번더 체크 24_1122 11:09:17 kku begin bDoEnc := true; if _sEncFileHash <> '' then begin ms.Position := 0; var sTemp: string := GetStreamToSha1Str(ms); // TXT 파일은 수정권한이 있을때 항상 파일을 읽고 바로 쓰기 때문에 수정일자가 변경 되고 파일 변경 감시에 감지된다. // 수정된게 있는지 체크, 지금은 TXT 파일만 대상 25_0911 17:09:28 kku if _sEncFileHash = sTemp then bDoEnc := false; // LogToReg('FHash2', Format('Hash1 = %s, Hash2 = %s (%d)', [_sEncFileHash, sTemp, ms.Size])); _sEncFileHash := ''; end; if bDoEnc then begin // LogToReg('Enc03', Format('CloseHandleHook() .. Path=%s', [pInfo.sOrgPath])); hs.Position := 0; ms.Position := 0; var sBkPath: string := 'C:\ProgramData\HE\EncTask\'; if ForceDirectories(sBkPath) then begin sBkPath := sBkPath + '$bk_' + ExtractFileName(pInfo.sOrgPath); if CopyFile(PChar(pInfo.sOrgPath), PChar(sBkPath), false) then SaveStrToFile(sBkPath + '.i', pInfo.sOrgPath, TEncoding.UTF8); end; Guard(enc, TTgDrmEnc.Create(pInfo.sOrgPath)); with pInfo.HeadInfo do begin if enc.SetHaed(PASS_DRM_HEAD, SIG_DRM, sEmpNo, sHostName, sPartName, sPgName, dwCustomerCode) then begin // LogToReg('Enc04', Format('CloseHandleHook() .. Path=%s', [pInfo.sOrgPath])); // if enc.EncryptFromStream(DecText(gAppHook.Helper.CtrlOpt.sDrmPass), hs) then if enc.EncryptFromStream(DecText(gAppHook.Helper.CtrlOpt.sDrmPass), ms) then begin if FileExists(sBkPath) then begin DeleteFile(PChar(sBkPath)); DeleteFile(PChar(sBkPath + '.i')); end; // LogToReg('Enc05', Format('CloseHandleHook() .. Path=%s', [pInfo.sOrgPath])); // gAppHook.Log('CloseHandleHook() .. Success .. EncryptFromStream()') end else begin if FileExists(sBkPath) and CopyFile(PChar(sBkPath), PChar(pInfo.sOrgPath), false) then begin DeleteFile(PChar(sBkPath)); DeleteFile(PChar(sBkPath + '.i')); end; // gAppHook.Log('CloseHandleHook() .. Fail .. EncryptFromStream()'); // LogToReg('Enc06', Format('CloseHandleHook() .. Path=%s', [pInfo.sOrgPath])); end; end else begin // LogToReg('Enc07', Format('CloseHandleHook() .. Path=%s', [pInfo.sOrgPath])); // gAppHook.Log('CloseHandleHook() .. Fail .. SetHaed()'); end; end; end; end; end; end else begin // gAppHook.Log(Format('CloseHandleHook() .. Not Modify.. DecPath=%s', [pInfo.sDecPath])); end; finally if hFile <> 0 then Result := ozCloseHandle(hFile); DeleteFile(pInfo.sDecPath); gAppHook.Helper.DcDrmFI.Remove(hFile); gAppHook.InternalOpen := false; end; end else Result := ozCloseHandle(hFile); except on E: Exception do ETgException.TraceException(E, 'Fail .. CloseHandleHook()'); end; end; //function MapViewOfFileHook(hFileMappingObject: THandle; dwDesiredAccess: DWORD; // dwFileOffsetHigh, dwFileOffsetLow: DWORD; dwNumberOfBytesToMap: SIZE_T): Pointer; stdcall; //begin // if (gAppHook <> nil) and (gAppHook.Helper <> nil) and (gAppHook.Helper.IsIgrReadFile(hFileMappingObject)) and not gAppHook._bInternalOpen then // begin // Result := nil; // end else // Result := ozMapViewOfFile(hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap); //end; //function ReadFileHook(hFile: THandle; var Buffer; nNumberOfBytesToRead: DWORD; // var lpNumberOfBytesRead: DWORD; lpOverlapped: POverlapped): BOOL; stdcall; //begin //// Result := false; // if (gAppHook <> nil) and (gAppHook.Helper <> nil) and (gAppHook.Helper.IsIgrReadFile(hFile)) and not gAppHook._bInternalOpen then // begin // lpNumberOfBytesRead := 0; // Result := false; // end else // Result := ozReadFile(hFile, Buffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); //end; // //function ReadFileExHook(hFile: THandle; lpBuffer: Pointer; nNumberOfBytesToRead: DWORD; // lpOverlapped: POverlapped; lpCompletionRoutine: TPROverlappedCompletionRoutine): BOOL; stdcall; //begin //// Result := false; // if (gAppHook <> nil) and (gAppHook.Helper <> nil) and (gAppHook.Helper.IsIgrReadFile(hFile)) and not gAppHook._bInternalOpen then // begin // Result := false; // end else // Result := ozReadFileEx(hFile, lpBuffer, nNumberOfBytesToRead, lpOverlapped, lpCompletionRoutine); //end; // //function WriteFileHook(hFile: THandle; const Buffer; nNumberOfBytesToWrite: DWORD; // var lpNumberOfBytesWritten: DWORD; lpOverlapped: POverlapped): BOOL; stdcall; //begin // if (gAppHook <> nil) and (gAppHook.Helper <> nil) and (gAppHook.Helper.IsIgrWriteFile(hFile)) and not gAppHook._bInternalOpen then // begin // lpNumberOfBytesWritten := 0; // Result := false; // end else // Result := ozWriteFile(hFile, Buffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped); // // (* // if Result and gAppHook.Helper.DcDrmFI.ContainsKey(hFile) then // begin //// gAppHook.Log('WriteFileHook()'); // gAppHook.Helper.DcDrmFI[hFile].bModified := true; // end; // *) //end; // //function WriteFileExHook(hFile: THandle; lpBuffer: Pointer; nNumberOfBytesToWrite: DWORD; // const lpOverlapped: TOverlapped; lpCompletionRoutine: FARPROC): BOOL; stdcall; //begin // if (gAppHook <> nil) and (gAppHook.Helper <> nil) and (gAppHook.Helper.IsIgrWriteFile(hFile)) and not gAppHook._bInternalOpen then // begin // Result := false; // end else // Result := ozWriteFileEx(hFile, lpBuffer, nNumberOfBytesToWrite, lpOverlapped, lpCompletionRoutine); // // (* // if Result and gAppHook.Helper.DcDrmFI.ContainsKey(hFile) then // begin //// _TgDrmHook.Log('WriteFileExHook()'); // gAppHook.Helper.DcDrmFI[hFile].bModified := true; // end; // *) //end; end.