{*******************************************************} { } { BS1Hook } { } { Copyright (C) 2022 kku } { } {*******************************************************} unit BS1Hook; interface uses System.SysUtils, System.Classes, Tocsg.DllEntry, Tocsg.CommonData, Winapi.Windows, Winapi.Messages, Winapi.ShellAPI, Tocsg.Trace, Tocsg.Json, System.Generics.Collections, Tocsg.DRM.Encrypt, Vcl.Graphics, AppCtrlDefine, AppHookClient, GlobalDefine, System.SyncObjs, Tocsg.Thread, WindowFinderThread, ApiHookContents; const PIPE_NAME = 'BS1@230316'; // PIPE_NAME = 'BS1@260107'; type PWebLogEnt = ^TWebLogEnt; TWebLogEnt = record dwTick: DWORD; sPath: String; nFType: Integer; bPrevent: Boolean; end; TThdWebABLog = class(TTgThread) protected sModuleName_: String; EntList_: TList; procedure OnEntNotify(Sender: TObject; const Item: PWebLogEnt; Action: TCollectionNotification); procedure Execute; override; public Constructor Create; Destructor Destroy; override; procedure Add(sPath: String; nFType: Integer; bPrevent: Boolean); procedure Del(nIdx: Integer); function IndexOf(sPath: String): Integer; procedure FindDel(sPath: String); end; TBS1Hook = class(TTgDllEntry) private CS_: TCriticalSection; dtCreate_: TDateTime; ProcList_: TList; Helper_: TAppCtrlHelper; Client_: TAppHookClient; Trace_: TTgTrace; // madCodeHook 관련 bIgnoreHook_, bUse_madCodeHook_: Boolean; ThdWndFinder_: TWindowFinderThread; bInitDrm_: Boolean; bInitPrt_: Boolean; DrmFList_: TStringList; DocExtList_: TStringList; CapBlockWndList_: TList; RFileList_: TStringList; bLoadedBoxApp_: Boolean; // 프린트 마스킹 // PrtMaskList_: TStringList; _bLogProcessing, _bInternalOpen: Boolean; procedure InitDrmProcess; procedure InitContentsFlowHook; procedure InitPrtProcess(aCtrlOpt: TAppCtrlOpt); procedure AddInterceptAPI(var aProcDest: Pointer; aProcSrc, aProcHook: Pointer; sProcName, sDllName: AnsiString; bCHFH: Boolean = false); procedure OnBeforeLog(Sender: TObject); procedure OnAfterLog(Sender: TObject); procedure Lock; procedure Unlock; procedure OnWebLogTimer(aSender: TObject); procedure OnWebLogEntNotify(Sender: TObject; const Item: PWebLogEnt; Action: TCollectionNotification); function GetLogProcessing: Boolean; function GetInternalOpen: Boolean; procedure SetInternalOpen(bVal: Boolean); public // 전역 옵션 sLogPath_: String; _hMTP: THandle; _sMtpDev: String; _dwMtpTick: DWORD; // MTP 인지하고 연속 차단을 위한 타임아웃 24_0604 16:19:01 kku // 브라우저 파일 차단 - 로그 ThdWebABLog: TThdWebABLog; // TimerWebABLog: TTimer; // WebLogEntList_: TList; Constructor Create; Destructor Destroy; override; procedure ProcessGoodbye; procedure OnAppDisconnected(aSener: TObject); procedure AddWebABLog(sPath: String); procedure DelWebABLog(sPath: String); procedure AddCapBlockWnd(h: HWND); procedure DelCapBlockWnd(h: HWND); procedure ClearCapBlockWnd; procedure Log(sLog: String); overload; procedure Log(const sFormat: string; const Args: array of const); overload; procedure ProcessAppCtrlOpt(aOpt: TAppCtrlOpt); procedure ProcessNoti(nNotiCode: Integer; sPath: String; nFType: Integer; bDirect: Boolean = false); procedure DoInterceptRemove; procedure AddCreateFile(hFile: THandle; sPath: String); procedure DelCloseFile(hFile: THandle); function GetRFilePath(sFName: String): String; property Helper: TAppCtrlHelper read Helper_; //property PrtMaskList: TStringList read PrtMaskList_; property DocExtList: TStringList read DocExtList_; property LoadedBoxApp: Boolean read bLoadedBoxApp_; property LogProcessing: Boolean read GetLogProcessing; property InternalOpen: Boolean read GetInternalOpen write SetInternalOpen; end; var gAppHook: TBS1Hook = nil; _HInstance: HMODULE = 0; implementation //{$DEFINE USE_BOXAPP} uses {$IFDEF USE_BOXAPP} BoxedAppSDK_Static, {$ENDIF} Condition, DDetours, Tocsg.Safe, Tocsg.Path, Tocsg.Strings, Tocsg.Exception, DefineHelper, ApiHookFile, ApiHookPrint, ApiHookDraw, Tocsg.Packet, Tocsg.Encrypt, Tocsg.Process, Tocsg.Registry, ApiHookExplorer, Tocsg.Win32, madCodeHook, superobject, Tocsg.Convert, BsoneDebug; { TThdWebABLog } Constructor TThdWebABLog.Create; begin Inherited Create; sModuleName_ := gAppHook.ModuleName; // FreeOnTerminate := true; EntList_ := TList.Create; EntList_.OnNotify := OnEntNotify; end; Destructor TThdWebABLog.Destroy; begin FreeAndNil(EntList_); Inherited; end; procedure TThdWebABLog.OnEntNotify(Sender: TObject; const Item: PWebLogEnt; Action: TCollectionNotification); begin try if Action = cnRemoved then Dispose(Item); except end; end; procedure TThdWebABLog.Add(sPath: String; nFType: Integer; bPrevent: Boolean); var pEnt: PWebLogEnt; begin try New(pEnt); pEnt.dwTick := GetTickCount; pEnt.sPath := sPath; pEnt.bPrevent := bPrevent; pEnt.nFType := nFType; Lock; try EntList_.Add(pEnt); finally Unlock; end; except // .. end; end; procedure TThdWebABLog.Del(nIdx: Integer); begin try Lock; try if (nIdx >= 0) and (EntList_.Count > nIdx) then EntList_.Delete(nIdx); finally Unlock; end; except // .. end; end; function TThdWebABLog.IndexOf(sPath: String): Integer; var i: Integer; begin Result := -1; try Lock; try for i := 0 to EntList_.Count - 1 do begin if EntList_[i].sPath = sPath then begin Result := i; exit; end; end; finally Unlock; end; except // .. end; end; procedure TThdWebABLog.FindDel(sPath: String); var i: Integer; begin try Lock; try for i := 0 to EntList_.Count - 1 do begin if EntList_[i].sPath = sPath then begin EntList_.Delete(i); exit; end; end; finally Unlock; end; except // .. end; end; procedure TThdWebABLog.Execute; var pEnt: PWebLogEnt; h: HWND; sPName: String; begin while not Terminated and not GetWorkStop do begin try Lock; try if EntList_.Count > 0 then pEnt := EntList_[0] else pEnt := nil; finally Unlock; end; if pEnt <> nil then begin if (GetTickCount - pEnt.dwTick) > 1000 then begin h := GetForegroundWindow; sPName := GetProcessNameFromWndHandle(h); if CompareText(sModuleName_, sPName) = 0 then begin if pEnt.bPrevent then gAppHook.ProcessNoti(NOTI_HOOK_BLOCK_ATTACH, pEnt.sPath, pEnt.nFType, true) else gAppHook.ProcessNoti(NOTI_HOOK_MONITOR_ATTACH, pEnt.sPath, pEnt.nFType, true); end; EntList_.Delete(0); end; end; Sleep(100); except // .. end; end; end; function IsExceptionProcess(sAppPath: string): Boolean; var FIgnoreList: TStringList; begin FIgnoreList := TStringList.Create; with FIgnoreList do begin CaseSensitive := False; // 대소문자 무시 Sorted := True; // 이진 검색을 위해 정렬 (필수) Duplicates := dupIgnore; Add('dwm.exe'); // Desktop Window Manager (후킹 시 화면 깜빡임/블랙스크린 위험) Add('svchost.exe'); // Service Host (수많은 시스템 서비스, 후킹 시 시스템 불안정) Add('sihost.exe'); // Shell Infrastructure Host Add('taskhostw.exe'); // Task Host Add('smss.exe'); Add('csrss.exe'); Add('lsass.exe'); Add('winlogon.exe'); Add('services.exe'); Add('conhost.exe'); // Console Window Host Add('ctfmon.exe'); // 텍스트 입력기 (키보드 입력 충돌 방지) Add('smartscreen.exe'); // Windows Defender SmartScreen Add('SecurityHealthSystray.exe'); Add('UserOOBEBroker.exe'); // [2] 윈도우 UI 및 쉘 구성요소 (파일 편집 기능 없음) Add('ShellHost.exe'); Add('StartMenuExperienceHost.exe'); // 시작 메뉴 Add('SearchHost.exe'); // 윈도우 검색 Add('TextInputHost.exe'); // 입력기 UI Add('WidgetService.exe'); // 윈도우 위젯 서비스 Add('Widgets.exe'); // 윈도우 위젯 Add('ApplicationFrameHost.exe'); // UWP 앱 프레임 Add('SystemSettings.exe'); // 윈도우 설정 Add('StoreDesktopExtension.exe'); // MS 스토어 관련 // [Explorer 참고] 탐색기는 아이콘 오버레이 등을 위해 후킹이 필요할 수도 있지만, // 단순 파일 암호화 엔진이라면 제외하는 것이 성능상 좋습니다. // 필요하다면 아래 주석을 해제하세요. // Add('Explorer.EXE'); Add('CrossDeviceResume.exe'); // Edge 관련 서비스 // [4] 백그라운드 동기화 및 네트워크 도구 (충돌 잦음) Add('OneDrive.exe'); Add('OneDrive.Sync.Service.exe'); Add('FileCoAuth.exe'); // OneDrive 관련 Add('ms-teams.exe'); // MS Teams (Electron 기반이라 무거움) Add('openvpn.exe'); // VPN 터널링 Add('openvpn-gui.exe'); // VPN UI Add('mstsc.exe'); // 원격 데스크톱 연결 // [5] 기타 유틸리티 및 업데이트 트레이 Add('HncUpdateTray.exe'); // 한컴 업데이트 트레이 Add('vmtoolsd.exe'); Add('backgroundTaskHost.exe'); Add('ShellExperienceHost.exe'); Add('LockApp.exe'); Add('DbgX.Shell.exe'); Add('ai.exe'); Add('MoNotificationUx.exe'); Add('SDXHelper.exe'); end; Result := FIgnoreList.IndexOf(sAppPath) >= 0; FIgnoreList.Free; end; { TBS1Hook } function LoadJsonEncTestFile(var aO: ISuperObject; sPath: String; sPass: String; aEncoding: TEncoding = nil; nRetry: Integer = 0): Boolean; var ss: TStringStream; bRetry: Boolean; Label DoRetry; begin Result := false; DoRetry : if FileExists(sPath) then begin bRetry := false; if aEncoding = nil then aEncoding := TEncoding.UTF8; try ss := TStringStream.Create('', aEncoding); try ss.LoadFromFile(sPath); aO := SO(DecBinStrToStr(ekAes256cbc, sPass, ss.DataString)); DVLOG('LoadJsonEncTestFile ok',[]); Result := true; finally ss.Free; end; except if nRetry > 0 then begin Dec(nRetry); bRetry := true; Sleep(500); end; end; if bRetry then goto DoRetry; end else begin DVLOG('LoadJsonEncTestFile Not Exit File (%s)',[sPath]); end; end; Constructor TBS1Hook.Create; procedure GetStartTime; var ftCreate, ftExit, ftKernel, ftUser: TFileTime; nDosTime: Integer; begin dtCreate_ := 0; GetProcessTimes(GetCurrentProcess, ftCreate, ftExit, ftKernel, ftUser); if FileTimeToLocalFileTime(ftCreate, ftCreate) then if FileTimeToDosDateTime(ftCreate, LongRec(nDosTime).Hi, LongRec(nDosTime).Lo) then dtCreate_ := FileDateToDateTime(nDosTime); end; var IgrList: TStringList; //DrmInitInfo: TTgFileMapping; CtrlOpt: TAppCtrlOpt; O: ISuperObject; begin Inherited Create; bIgnoreHook_ := IsExceptionProcess(ModuleName); // bIgnoreHook_ := true; if bIgnoreHook_ then exit; ASSERT(gAppHook = nil); gAppHook := Self; CS_ := TCriticalSection.Create; sLogPath_ := ''; _bLogProcessing := false; _bInternalOpen := false; _hMTP := 0; _sMtpDev := ''; _dwMtpTick := 0; bInitDrm_ := false; bInitPrt_ := false; bLoadedBoxApp_ := false; GetStartTime; DVLOG('TBS1Hook.Create: start 0',[]); O := nil; Trace_ := nil; ThdWebABLog := nil; ThdWndFinder_ := nil; // PrtMaskList_ := nil; // PrtMaskList_ := TStringList.Create; RFileList_ := TStringList.Create; RFileList_.CaseSensitive := false; //{$IFDEF DEBUG} // 이거 켜면 DLL 해제 시 떨어지지 않는다 23_0315 11:09:49 kku // sLogPath_ := 'C:\taskToCSG\Tocsg.Module\AppCtrl\OUT_Debug - Win64\AppCtrl.log'; //// if FileExists(sLogPath_) then //// DeleteFile(PChar(sLogPath_)); // Trace_ := TTgTrace.Create(ExtractFilePath(sLogPath_), ExtractFileName(sLogPath_)); // Trace_.OnBeforeLog := OnBeforeLog; // Trace_.OnAfterLog := OnAfterLog; // Trace_.LoadHead := ModuleName + ' > '; //{$ENDIF} CapBlockWndList_ := TList.Create; DrmFList_ := TStringList.Create; DrmFList_.CaseSensitive := false; DocExtList_ := TStringList.Create; DocExtList_.CaseSensitive := false; SplitString('TXT|DOC|PDF|XLS|PPT|HWP|HWPX|DOCX|DOTX|XLSX|XLTX|PPTX|POTX', '|', DocExtList_); ProcList_ := TList.Create; Helper_ := TAppCtrlHelper.Create(ModulePath); if Helper_.CurAppType = catWebb then begin // ThdWebABLog := TThdWebABLog.Create; // ThdWebABLog.StartThread; // Sleep(2000); // FreeAndNil(ThdWebABLog); end; //bUse_madCodeHook_:= True; // PPT에서 출력물 수집 시 일부가 폰트가 깨지는 현상이 확인됨... // 기존 DDetours로 API 훅하면 괜찮아서 일단 이걸로 쓰는걸로... 25_0202 15:44:33 kku // bUse_madCodeHook_ := false; //MutexExists(MUTEX_MH); // madCodeHook으로 Injection 되는 건지 판단 25_0107 15:58:09 kku // madCodeHook으로 해야 아래한글에서 정상출력하는게 있음 25_0202 18:57:17 kku // 위치 "BSShare\07. Test Data\문서\아래한글\프린터 워터마크 출력 테스트\한글_개체_문서 - 엑셀 개체 복사.hwp" // bUse_madCodeHook_ := (Helper_.CurAppType = catHwp) and MutexExists(MUTEX_MH); // 탐색기에서 문서 여러개 선택 후 "인쇄" 하면 bUse_madCodeHook_가 false 일 경우 Hook이 늦게 붙어서 5개중 1개는 실패하는 문제가 있다. // 파워포인트는 폰트 깨지는 문제가 있어서 파워포인트 아닌것만 madHook 사용한다 25_0205 18:46:10 kku bUse_madCodeHook_ := not Helper_.IsPPT and MutexExists(MUTEX_MH); ZeroMemory(@CtrlOpt, SizeOf(CtrlOpt)); if Helper_.IsDrmSupport and LoadJsonObjFromEncFile(O, ExtractFilePath(gAppHook.Helper.DllPath) + 'hpli.dat', '9live@u', nil, 6) then begin CtrlOpt.hRcvWnd := O.I['RcvWnd']; CtrlOpt.dwCustomerType := O.I['CT']; CtrlOpt.DrmAccessKind := TDrmAccessKind(O.I['DAK']); CtrlOpt.DrmModifyKind := TDrmAccessKind(O.I['DMK']); CtrlOpt.sTaskDir := O.S['TskDir']; CtrlOpt.sDrmPass := O.S['AS']; CtrlOpt.sEmpNo := O.S['EmpNo']; CtrlOpt.sDeptName := O.S['Dept']; if CtrlOpt.sDrmPass <> '' then CtrlOpt.sDrmPass := DecText(CtrlOpt.sDrmPass); Helper_.CtrlOpt := CtrlOpt; end; DVLOG('TBS1Hook.Create: start 1, IsPrtSupport(%d)',[DWORD(Helper_.IsPrtSupport)]); if Helper_.IsPrtSupport and ( (O <> nil) or LoadJsonObjFromEncFile(O, ExtractFilePath(gAppHook.Helper.DllPath) + 'hpli.dat', '9live@u', nil, 6) ) then begin // 탐색기에서 바로 "인쇄" 사용하는 고객사에만 일단 이렇게 적용한다 25_0205 13:42:03 kku var dwCustomerType: DWORD := O.I['CT']; case dwCustomerType of CUSTOMER_DEV, CUSTOMER_SHCI, CUSTOMER_SERVE1 : begin CtrlOpt := Helper_.CtrlOpt; CtrlOpt.hRcvWnd := O.I['RcvWnd']; CtrlOpt.dwCustomerType := dwCustomerType; CtrlOpt.bPrintSecu := O.B['PrtSecu']; CtrlOpt.bPrintWater := O.B['bPrtWater']; CtrlOpt.bPrtCollect := O.B['PrtCol']; CtrlOpt.sPrtEmfOutDir := O.S['EmfDir']; CtrlOpt.sUName := O.S['UName']; CtrlOpt.sIpAddr := O.S['IP']; CtrlOpt.sEmpNo := O.S['EmpNo']; CtrlOpt.sDeptName := O.S['Dept']; CtrlOpt.fWmTran := StrToFloatDef(GetRegValueAsString(HKEY_CURRENT_USER, REG_HE, 'WmTran'), 0.0); // LogToReg(Format('PrtInfo-%d-RcvWnd', [Helper_.PID]), IntToStr(CtrlOpt.hRcvWnd)); // LogToReg(Format('PrtInfo-%d-CT', [Helper_.PID]), IntToStr(CtrlOpt.dwCustomerType)); // // LogToReg(Format('PrtInfo-%d-bPrintSecu', [Helper_.PID]), BooleanToStr(CtrlOpt.bPrintSecu, 'true', 'false')); // LogToReg(Format('PrtInfo-%d-bPrintWater', [Helper_.PID]), BooleanToStr(CtrlOpt.bPrintWater, 'true', 'false')); // LogToReg(Format('PrtInfo-%d-bPrtCollect', [Helper_.PID]), BooleanToStr(CtrlOpt.bPrtCollect, 'true', 'false')); // // LogToReg(Format('PrtInfo-%d-sPrtEmfOutDir', [Helper_.PID]), CtrlOpt.sPrtEmfOutDir); // LogToReg(Format('PrtInfo-%d-sUName', [Helper_.PID]), CtrlOpt.sUName); // LogToReg(Format('PrtInfo-%d-sIpAddr', [Helper_.PID]), CtrlOpt.sIpAddr); // LogToReg(Format('PrtInfo-%d-sEmpNo', [Helper_.PID]), CtrlOpt.sEmpNo); // LogToReg(Format('PrtInfo-%d-sDeptName', [Helper_.PID]), CtrlOpt.sDeptName); Helper_.CtrlOpt := CtrlOpt; end; end; end; if CtrlOpt.dwCustomerType = CUSTOMER_KOCES then begin Helper_.NoDrmUse; // SetErrorMode(SEM_NOGPFAULTERRORBOX); // 시스템 에러 씹기 23_0330 11:21:25 kku end; DVLOG('TBS1Hook.Create: start 2, CurAppType(%d)',[DWORD(Helper_.CurAppType)]); Client_ := TAppHookClient.Create; if Helper_.CurAppType = catkvHelper then begin ZeroMemory(@CtrlOpt, SizeOf(CtrlOpt)); CtrlOpt.bPrintSecu := true; CtrlOpt.bPrintWater := true; CtrlOpt.dwCustomerType := GetRegValueAsInteger(HKEY_CURRENT_USER, REG_HE, 'CT'); CtrlOpt.sUName := GetRegValueAsString(HKEY_CURRENT_USER, REG_HE, 'UName'); CtrlOpt.sEmpNo := GetRegValueAsString(HKEY_CURRENT_USER, REG_HE, 'EmpNo'); CtrlOpt.sDeptName := GetRegValueAsString(HKEY_CURRENT_USER, REG_HE, 'DeptName'); CtrlOpt.fWmTran := StrToFloatDef(GetRegValueAsString(HKEY_CURRENT_USER, REG_HE, 'WmTran'), 0.0); Helper_.CtrlOpt := CtrlOpt; // LogToReg('kvcttsch.exe_Load', 'MName = ' + ModuleName); // LogToReg('kvcttsch.exe_Load', 'dwCustomerType = ' + IntToStr(Helper_.CtrlOpt.dwCustomerType)); if bUse_madCodeHook_ then CollectHooks; AddInterceptAPI(@ozCreateDC, @CreateDC, @CreateDCHook, 'CreateDC', 'gdi32.dll'); AddInterceptAPI(@ozCreateDCA, @CreateDCA, @CreateDCAHook, 'CreateDCA', 'gdi32.dll'); AddInterceptAPI(@ozCreateDCW, @CreateDCW, @CreateDCWHook, 'CreateDCW', 'gdi32.dll'); AddInterceptAPI(@ozStartDocA, @StartDocA, @StartDocAHook, 'StartDocA', 'gdi32.dll'); AddInterceptAPI(@ozStartDocW, @StartDocW, @StartDocWHook, 'StartDocW', 'gdi32.dll'); AddInterceptAPI(@ozStartPage, @StartPage, @StartPageHook, 'StartPage', 'gdi32.dll'); AddInterceptAPI(@ozEndPage, @EndPage, @EndPageHook, 'EndPage', 'gdi32.dll'); AddInterceptAPI(@ozEndDoc, @EndDoc, @EndDocHook, 'EndDoc', 'gdi32.dll'); if bUse_madCodeHook_ then FlushHooks; end else begin Client_.OnDisconnected := OnAppDisconnected; Client_.TryReconnect := true; Client_.ModulePath := ModulePath; if not Client_.ActiveNp(PIPE_NAME, false) then begin Log('Fail .. ActiveNp()'); exit; end; if not Client_.ConnectNp then begin Log('Fail .. Connection'); exit; end; end; if Helper_.IsDrmSupport and (Helper_.CtrlOpt.DrmAccessKind <> dakNone) then InitDrmProcess; DVLOG('TBS1Hook.Create: start 3, IsDrmSupport(%d)',[DWORD(Helper_.IsDrmSupport)]); if Helper_.IsPrtSupport and (Helper_.CtrlOpt.bPrintSecu or Helper_.CtrlOpt.bPrintWater) then begin Sleep(1000); // LogToReg('IsPrtSupport-00', 'Hook'); InitPrtProcess(Helper_.CtrlOpt); // ProcessNoti(NOTI_HOOK_PRINT_API_START_INIT, '', 0, true); end; gApiHookContents_:= TApiHookContents.Create(Helper_.CurAppType); if (Helper_.CurAppType = catFquirt) or (Helper_.CurAppType = catLINKENGKM) or (Helper_.CurAppType = catExplorer)then begin var sConfDir := 'C:\Program Files\Tocsg\eCrmHome'; sConfDir := sConfDir + '\conf\'; DVLOG('InitContentsFlowHook: CurAppType(%d), (%s)',[DWORD(Helper_.CurAppType), sConfDir]); if ( (O <> nil) or LoadJsonEncTestFile(O, sConfDir + 'hpli.dat', '9live@u', nil, 6) ) then begin DVLOG('InitContentsFlowHook: ++',[]); CtrlOpt := Helper_.CtrlOpt; CtrlOpt.hRcvWnd := O.I['RcvWnd']; // CtrlOpt.FileUseBlock := TFileUseBlock(O.I['FileUseBlock']); CtrlOpt.bCheckUrl := O.B['bCheckUrl']; // CtrlOpt.bUseContentFilter := O.B['bUseContentFilter']; // CtrlOpt.bReadBlock := O.B['bReadBlock']; // CtrlOpt.bWriteBlock := O.B['bWriteBlock']; // CtrlOpt.bFileApproval := O.B['bFileApproval']; // CtrlOpt.bIgrNetPathAB := O.B['bIgrNetPathAB']; // CtrlOpt.bOpenDetect := O.B['bOpenDetect']; if O['ShFileCrMon'] <> nil then CtrlOpt.ShFileCrMon := TTgJson.GetDataAsType(O.O['ShFileCrMon']) else CtrlOpt.ShFileCrMon.nKind := 0; // CtrlOpt.nBlockSizeMB := O.I['nBlockSizeMB']; var OEtcApps, OCurApp: ISuperObject; var sPureAppName: string; begin OEtcApps := O.O['EtcABApps']; if OEtcApps <> nil then begin sPureAppName := ChangeFileExt(ExtractFileName(ModuleName), ''); OCurApp := OEtcApps.O[UpperCase(sPureAppName)]; if OCurApp <> nil then begin CtrlOpt.FileUseBlock := TFileUseBlock(OCurApp.I['FileUseBlock']); CtrlOpt.bUseContentFilter := OCurApp.B['bUseContentFilter']; CtrlOpt.bReadBlock := OCurApp.B['bReadBlock']; CtrlOpt.bWriteBlock := OCurApp.B['bWriteBlock']; CtrlOpt.nBlockSizeMB := OCurApp.I['nBlockSizeMB']; DVLOG('InitContentsFlowHook: Applied App-Specific Policy for: %s', [sPureAppName]); end; end; end; Helper_.CtrlOpt := CtrlOpt; DVLOG('InitContentsFlowHook: hRcvWnd(%d), FileUseBlock(%d), bUseContentFilter(%d)', [DWORD(CtrlOpt.hRcvWnd), DWORD(CtrlOpt.FileUseBlock), DWORD(CtrlOpt.bUseContentFilter)]); end; InitContentsFlowHook; ghooked_:= True; end; Log('Create() ..'); end; procedure TBS1Hook.ProcessGoodbye; begin DoInterceptRemove; if Helper_ <> nil then FreeAndNil(Helper_); // UninjectLibraryW('eCrmHeHelper.dll', GetCurrentProcess); end; Destructor TBS1Hook.Destroy; var sMN: String; begin if bIgnoreHook_ then begin // Inherited; exit; end; sMN := ModuleName; gAppHook := nil; DoInterceptRemove; FreeAndNil(gApiHookContents_); if ThdWebABLog <> nil then begin ThdWebABLog.Terminate; ThdWebABLog.WaitFor; FreeAndNil(ThdWebABLog); end; ClearCapBlockWnd; if Trace_ <> nil then FreeAndNil(Trace_); if ThdWndFinder_ <> nil then begin ThdWndFinder_.Terminate; ThdWndFinder_.WaitFor; FreeAndNil(ThdWndFinder_); end; FreeAndNil(Client_); if Helper_ <> nil then FreeAndNil(Helper_); FreeAndNil(ProcList_); FreeAndNil(DocExtList_); FreeAndNil(DrmFList_); FreeAndNil(CapBlockWndList_); FreeAndNil(RFileList_); FreeAndNil(CS_); Inherited; end; procedure TBS1Hook.OnAppDisconnected(aSener: TObject); var CtrlOpt: TAppCtrlOpt; begin ZeroMemory(@CtrlOpt, SizeOf(CtrlOpt)); Helper_.CtrlOpt := CtrlOpt; end; procedure TBS1Hook.OnWebLogEntNotify(Sender: TObject; const Item: PWebLogEnt; Action: TCollectionNotification); begin if Action = cnRemoved then Dispose(Item); end; function TBS1Hook.GetLogProcessing: Boolean; begin Lock; try Result := _bLogProcessing; finally Unlock; end; end; function TBS1Hook.GetInternalOpen: Boolean; begin Lock; try Result := _bInternalOpen; finally Unlock; end; end; procedure TBS1Hook.SetInternalOpen(bVal: Boolean); begin Lock; try _bInternalOpen := bVal; finally Unlock; end; end; procedure TBS1Hook.AddWebABLog(sPath: String); var pEnt: PWebLogEnt; begin // if TimerWebABLog = nil then // begin // WebLogEntList_ := TList.Create; // WebLogEntList_.OnNotify := OnWebLogEntNotify; // // TimerWebABLog := TTimer.Create(nil); // TimerWebABLog.OnTimer := OnWebLogTimer; // TimerWebABLog.Interval := 200; // TimerWebABLog.Enabled := true; // end; // // New(pEnt); // pEnt.dwTick := GetTickCount; // pEnt.sPath := sPath; // WebLogEntList_.Add(pEnt); end; procedure TBS1Hook.DelWebABLog(sPath: String); var i: Integer; begin // if WebLogEntList_ <> nil then // begin // for i := 0 to WebLogEntList_.Count - 1 do // begin // if WebLogEntList_[i].sPath = sPath then // begin // WebLogEntList_.Delete(i); // exit; // end; // end; // end; end; procedure TBS1Hook.OnWebLogTimer(aSender: TObject); var pEnt: PWebLogEnt; begin // if WebLogEntList_ = nil then // exit; // // try // if WebLogEntList_.Count > 0 then // pEnt := WebLogEntList_[0] // else // pEnt := nil; // // if pEnt <> nil then // begin // if (GetTickCount - pEnt.dwTick) > 1000 then // begin // gAppHook.ProcessNoti(NOTI_HOOK_MONITOR_ATTACH, pEnt.sPath); // WebLogEntList_.Delete(0); // end; // end; // except // // .. // end; end; procedure TBS1Hook.OnBeforeLog(Sender: TObject); begin Lock; try _bLogProcessing := true; finally Unlock; end; end; procedure TBS1Hook.OnAfterLog(Sender: TObject); begin Lock; try _bLogProcessing := false; finally Unlock; end; end; procedure TBS1Hook.Lock; begin CS_.Acquire; end; procedure TBS1Hook.Unlock; begin CS_.Release; end; procedure TBS1Hook.AddCapBlockWnd(h: HWND); begin try if h = 0 then exit; if CapBlockWndList_.IndexOf(h) = -1 then CapBlockWndList_.Add(h); SetWindowDisplayAffinity(h, 1); except // .. end; end; procedure TBS1Hook.DelCapBlockWnd(h: HWND); begin try if h = 0 then exit; if CapBlockWndList_.IndexOf(h) <> -1 then SetWindowDisplayAffinity(h, 0); except // .. end; end; procedure TBS1Hook.ClearCapBlockWnd; var i: Integer; begin try if CapBlockWndList_.Count = 0 then exit; for i := 0 to CapBlockWndList_.Count - 1 do SetWindowDisplayAffinity(CapBlockWndList_[i], 0); CapBlockWndList_.Clear; except // .. end; end; procedure TBS1Hook.InitDrmProcess; {$IFDEF USE_BOXAPP} var bLoadBx: Boolean; Label LB_LoadBx; {$ENDIF} begin if not bInitDrm_ then begin Log('InitDrmProcess() ..'); {$IFDEF USE_BOXAPP} var bUseBoxApp: Boolean := (Helper_.CurAppType <> catAdobeReader) and (Helper_.CtrlOpt.DrmModifyKind <> dakAll); // MS개체 가져오기를 위해 MS-Office에 의해 실행된 거라면 무시한다 25_0109 09:37:13 kku if bUseBoxApp then begin var sPPName: String := GetProcessNameByPid(GetProcessPPidByPid(GetCurrentProcessId)); if SameText('svchost.exe', sPPName) or SameText('WINWORD.EXE', sPPName) or SameText('POWERPNT.EXE', sPPName) or SameText('NeoiCube.exe', sPPName) or // 더존 아이큐브 ERP SameText('excel.EXE', sPPName) then // SameText('Microsoft.Mashup.Container.Loader.exe', ModuleName) then begin bUseBoxApp := false; end; end; // if bUseBoxedApp_ then if bUseBoxApp then begin try bLoadBx := false; LB_LoadBx : try // Init BoxedApp SDK BoxedAppSDK_SetContext('21f2f010-06e4-465f-af8f-cde6a3752c39'); BoxedAppSDK_Init; // Allow injection BoxedApp engine into child processes // BoxedAppSDK_EnableOption(DEF_BOXEDAPPSDK_OPTION__EMBED_BOXEDAPP_IN_CHILD_PROCESSES, TRUE); // BoxedAppSDK_EnableOption(DEF_BOXEDAPPSDK_OPTION__HIDE_VIRTUAL_FILES_FROM_FILE_DIALOG, TRUE); // BoxedAppSDK_EnableOption(DEF_BOXEDAPPSDK_OPTION__ALL_CHANGES_ARE_VIRTUAL, TRUE); bLoadBx := true; except Log('Fail .. BoxedAppSDK'); end; if not bLoadBx then begin Sleep(10); goto LB_LoadBx; end; except Log('Fail .. UseBoxedAppSDK'); end; end; bLoadedBoxApp_ := bLoadBx; {$ENDIF} if bUse_madCodeHook_ then CollectHooks; // AddInterceptAPI(@ozCreateFileA, @CreateFileA, @CreateFileAHook, 'CreateFileA', 'kernelbase.dll'); AddInterceptAPI(@ozCreateFileW, @CreateFileW, @CreateFileWHook, 'CreateFileW', 'kernelbase.dll'); AddInterceptAPI(@ozCloseHandle, @CloseHandle, @CloseHandleHook, 'CloseHandle', 'kernelbase.dll'); if bUse_madCodeHook_ then FlushHooks; bInitDrm_ := true; end; end; procedure TBS1Hook.InitContentsFlowHook; begin if bUse_madCodeHook_ then CollectHooks; AddInterceptAPI(@ozCreateFileW, @CreateFileW, @CreateFileWHook, 'CreateFileW', 'kernelbase.dll'); AddInterceptAPI(@ozCloseHandle, @CloseHandle, @CloseHandleHook, 'CloseHandle', 'kernelbase.dll'); AddInterceptAPI(@ozDeviceIoControl, @DeviceIoControl, @DeviceIoControlHook, 'DeviceIoControl', 'kernelbase.dll'); AddInterceptAPI(@ozCreateFileMappingW, @CreateFileMappingW, @CreateFileMappingWHook, 'CreateFileMappingW', 'kernelbase.dll'); AddInterceptAPI(@ozReadFile, @ReadFile, @ReadFileHook, 'ReadFile', 'kernelbase.dll'); HookAPI('Ws2_32.dll', 'WSASend', @WSASendHook, @ozWSASend); if bUse_madCodeHook_ then FlushHooks; DVLOG('InitContentsFlowHook: Success',[]); end; procedure TBS1Hook.InitPrtProcess(aCtrlOpt: TAppCtrlOpt); begin if bInitPrt_ then exit; if bUse_madCodeHook_ then CollectHooks; AddInterceptAPI(@ozCreateDC, @CreateDC, @CreateDCHook, 'CreateDC', 'gdi32.dll'); AddInterceptAPI(@ozCreateDCA, @CreateDCA, @CreateDCAHook, 'CreateDCA', 'gdi32.dll'); AddInterceptAPI(@ozCreateDCW, @CreateDCW, @CreateDCWHook, 'CreateDCW', 'gdi32.dll'); AddInterceptAPI(@ozStartDocA, @StartDocA, @StartDocAHook, 'StartDocA', 'gdi32.dll'); AddInterceptAPI(@ozStartDocW, @StartDocW, @StartDocWHook, 'StartDocW', 'gdi32.dll'); AddInterceptAPI(@ozStartPage, @StartPage, @StartPageHook, 'StartPage', 'gdi32.dll'); AddInterceptAPI(@ozEndPage, @EndPage, @EndPageHook, 'EndPage', 'gdi32.dll'); AddInterceptAPI(@ozEndDoc, @EndDoc, @EndDocHook, 'EndDoc', 'gdi32.dll'); if (Helper_.CurAppType <> catkvHelper) and aCtrlOpt.bPrtCollect and (aCtrlOpt.sPrtEmfOutDir <> '') then begin AddInterceptAPI(@ozExtTextOutA, @ExtTextOutA, @ExtTextOutAHook, 'ExtTextOutA', 'gdi32.dll'); // notepad++ AddInterceptAPI(@ozExtTextOutW, @ExtTextOutW, @ExtTextOutWHook, 'ExtTextOutW', 'gdi32.dll'); // notepad++ AddInterceptAPI(@ozSetWorldTransform, @SetWorldTransform, @SetWorldTransformHook, 'SetWorldTransform', 'gdi32.dll'); // 좌표값 추출 AddInterceptAPI(@ozModifyWorldTransform, @ModifyWorldTransform, @ModifyWorldTransformHook, 'ModifyWorldTransform', 'gdi32.dll'); // 좌표값 추출, 이거 켜면 PPT에서 텍스트 위치가 꼬인다 25_1001 22:00:24 kku AddInterceptAPI(@ozRectangle, @Rectangle, @RectangleHook, 'Rectangle', 'gdi32.dll'); AddInterceptAPI(@ozSelectObject, @SelectObject, @SelectObjectHook, 'SelectObject', 'gdi32.dll'); AddInterceptAPI(@ozStretchDIBits, @StretchDIBits, @StretchDIBitsHook, 'StretchDIBits', 'gdi32.dll'); // chrome 필수 AddInterceptAPI(@ozSetStretchBltMode, @SetStretchBltMode, @SetStretchBltModeHook, 'SetStretchBltMode', 'gdi32.dll'); AddInterceptAPI(@ozSetPolyFillMode, @SetPolyFillMode, @SetPolyFillModeHook, 'SetPolyFillMode', 'gdi32.dll'); AddInterceptAPI(@ozBeginPath, @BeginPath, @BeginPathHook, 'BeginPath', 'gdi32.dll'); // chrome 필수 AddInterceptAPI(@ozMoveToEx, @MoveToEx, @MoveToExHook, 'MoveToEx', 'gdi32.dll'); // chrome 필수 AddInterceptAPI(@ozPolyBezierTo, @PolyBezierTo, @PolyBezierToHook, 'PolyBezierTo', 'gdi32.dll'); // chrome 필수 AddInterceptAPI(@ozLineTo, @LineTo, @LineToHook, 'LineTo', 'gdi32.dll'); // chrome 필수 AddInterceptAPI(@ozCloseFigure, @CloseFigure, @CloseFigureHook, 'CloseFigure', 'gdi32.dll'); AddInterceptAPI(@ozEndPath, @EndPath, @EndPathHook, 'EndPath', 'gdi32.dll'); // chrome 필수 AddInterceptAPI(@ozFillPath, @FillPath, @FillPathHook, 'FillPath', 'gdi32.dll'); // chrome 필수 AddInterceptAPI(@ozLPtoDP, @LPtoDP, @LPtoDPHook, 'LPtoDP', 'gdi32.dll'); AddInterceptAPI(@ozDPtoLP, @DPtoLP, @DPtoLPHook, 'DPtoLP', 'gdi32.dll'); AddInterceptAPI(@ozFillRect, @FillRect, @FillRectHook, 'FillRect', 'user32.dll'); AddInterceptAPI(@ozRestoreDC, @RestoreDC, @RestoreDCHook, 'RestoreDC', 'gdi32.dll'); AddInterceptAPI(@ozSaveDC, @SaveDC, @SaveDCHook, 'SaveDC', 'gdi32.dll'); AddInterceptAPI(@ozIntersectClipRect, @IntersectClipRect, @IntersectClipRectHook, 'IntersectClipRect', 'gdi32.dll'); AddInterceptAPI(@ozBitBlt, @BitBlt, @BitBltHook, 'BitBlt', 'gdi32.dll'); AddInterceptAPI(@ozSetPixel, @SetPixel, @SetPixelHook, 'SetPixel', 'gdi32.dll'); AddInterceptAPI(@ozPlgBlt, @PlgBlt, @PlgBltHook, 'PlgBlt', 'gdi32.dll'); AddInterceptAPI(@ozPatBlt, @PatBlt, @PatBltHook, 'PatBlt', 'gdi32.dll'); AddInterceptAPI(@ozStretchBlt, @StretchBlt, @StretchBltHook, 'StretchBlt', 'gdi32.dll'); AddInterceptAPI(@ozEllipse, @Ellipse, @EllipseHook, 'Ellipse', 'gdi32.dll'); AddInterceptAPI(@ozTextOutA, @TextOutA, @TextOutAHook, 'TextOutA', 'gdi32.dll'); AddInterceptAPI(@ozTextOutW, @TextOutW, @TextOutWHook, 'TextOutW', 'gdi32.dll'); AddInterceptAPI(@ozSetTextAlign, @SetTextAlign, @SetTextAlignHook, 'SetTextAlign', 'gdi32.dll'); AddInterceptAPI(@ozSetBkMode, @SetBkMode, @SetBkModeHook, 'SetBkMode', 'gdi32.dll'); AddInterceptAPI(@ozSetViewportOrgEx, @SetViewportOrgEx, @SetViewportOrgExHook, 'SetViewportOrgEx', 'gdi32.dll'); AddInterceptAPI(@ozExtSelectClipRgn, @ExtSelectClipRgn, @ExtSelectClipRgnHook, 'ExtSelectClipRgn', 'gdi32.dll'); AddInterceptAPI(@ozSelectClipRgn, @SelectClipRgn, @SelectClipRgnHook, 'SelectClipRgn', 'gdi32.dll'); AddInterceptAPI(@ozSetMapMode, @SetMapMode, @SetMapModeHook, 'SetMapMode', 'gdi32.dll'); AddInterceptAPI(@ozSetWindowOrgEx, @SetWindowOrgEx, @SetWindowOrgExHook, 'SetWindowOrgEx', 'gdi32.dll'); AddInterceptAPI(@ozSelectPalette, @SelectPalette, @SelectPaletteHook, 'SelectPalette', 'gdi32.dll'); AddInterceptAPI(@ozSetGraphicsMode, @SetGraphicsMode, @SetGraphicsModeHook, 'SetGraphicsMode', 'gdi32.dll'); AddInterceptAPI(@ozSetBkColor, @SetBkColor, @SetBkColorHook, 'SetBkColor', 'gdi32.dll'); AddInterceptAPI(@ozSetBrushOrgEx, @SetBrushOrgEx, @SetBrushOrgExHook, 'SetBrushOrgEx', 'gdi32.dll'); AddInterceptAPI(@ozSetDIBits, @SetDIBits, @SetDIBitsHook, 'SetDIBits', 'gdi32.dll'); AddInterceptAPI(@ozSetROP2, @SetROP2, @SetROP2Hook, 'SetROP2', 'gdi32.dll'); AddInterceptAPI(@ozSetColorSpace, @SetColorSpace, @SetColorSpaceHook, 'SetColorSpace', 'gdi32.dll'); AddInterceptAPI(@ozExcludeClipRect, @ExcludeClipRect, @ExcludeClipRectHook, 'ExcludeClipRect', 'gdi32.dll'); AddInterceptAPI(@ozSetViewportExtEx, @SetViewportExtEx, @SetViewportExtExHook, 'SetViewportExtEx', 'gdi32.dll'); AddInterceptAPI(@ozSetWindowExtEx, @SetWindowExtEx, @SetWindowExtExHook, 'SetWindowExtEx', 'gdi32.dll'); AddInterceptAPI(@ozScaleViewportExtEx, @ScaleViewportExtEx, @ScaleViewportExtExHook, 'ScaleViewportExtEx', 'gdi32.dll'); AddInterceptAPI(@ozSetTextColor, @SetTextColor, @SetTextColorHook, 'SetTextColor', 'gdi32.dll'); AddInterceptAPI(@ozSetDCBrushColor, @SetDCBrushColor, @SetDCBrushColorHook, 'SetDCBrushColor', 'gdi32.dll'); AddInterceptAPI(@ozSetDCPenColor, @SetDCPenColor, @SetDCPenColorHook, 'SetDCPenColor', 'gdi32.dll'); AddInterceptAPI(@ozCreateHalftonePalette, @CreateHalftonePalette, @CreateHalftonePaletteHook, 'CreateHalftonePalette', 'gdi32.dll'); AddInterceptAPI(@ozCreateDIBSection, @CreateDIBSection, @CreateDIBSectionHook, 'CreateDIBSection', 'gdi32.dll'); AddInterceptAPI(@ozSetBoundsRect, @SetBoundsRect, @SetBoundsRectHook, 'SetBoundsRect', 'gdi32.dll'); AddInterceptAPI(@ozSetSystemPaletteUse, @SetSystemPaletteUse, @SetSystemPaletteUseHook, 'SetSystemPaletteUse', 'gdi32.dll'); AddInterceptAPI(@ozRealizePalette, @RealizePalette, @RealizePaletteHook, 'RealizePalette', 'gdi32.dll'); AddInterceptAPI(@ozSetDIBColorTable, @SetDIBColorTable, @SetDIBColorTableHook, 'SetDIBColorTable', 'gdi32.dll'); AddInterceptAPI(@ozSetMapperFlags, @SetMapperFlags, @SetMapperFlagsHook, 'SetMapperFlags', 'gdi32.dll'); AddInterceptAPI(@ozSetColorAdjustment, @SetColorAdjustment, @SetColorAdjustmentHook, 'SetColorAdjustment', 'gdi32.dll'); AddInterceptAPI(@ozPolyBezier, @PolyBezier, @PolyBezierHook, 'PolyBezier', 'gdi32.dll'); AddInterceptAPI(@ozPolygon, @Polygon, @PolygonHook, 'Polygon', 'gdi32.dll'); AddInterceptAPI(@ozPolyline, @Polyline, @PolylineHook, 'Polyline', 'gdi32.dll'); AddInterceptAPI(@ozPolyLineTo, @PolyLineTo, @PolyLineToHook, 'PolyLineTo', 'gdi32.dll'); AddInterceptAPI(@ozPolyPolyline, @PolyPolyline, @PolyPolylineHook, 'PolyPolyline', 'gdi32.dll'); AddInterceptAPI(@ozPolyPolygon, @PolyPolygon, @PolyPolygonHook, 'PolyPolygon', 'gdi32.dll'); AddInterceptAPI(@ozSetPixelV, @SetPixelV, @SetPixelVHook, 'SetPixelV', 'gdi32.dll'); AddInterceptAPI(@ozColorCorrectPalette, @ColorCorrectPalette, @ColorCorrectPaletteHook, 'ColorCorrectPalette', 'gdi32.dll'); AddInterceptAPI(@ozSetICMProfileA, @SetICMProfileA, @SetICMProfileAHook, 'SetICMProfileA', 'gdi32.dll'); AddInterceptAPI(@ozSetICMProfileW, @SetICMProfileW, @SetICMProfileWHook, 'SetICMProfileW', 'gdi32.dll'); AddInterceptAPI(@ozSetTextJustification, @SetTextJustification, @SetTextJustificationHook, 'SetTextJustification', 'gdi32.dll'); AddInterceptAPI(@ozScaleWindowExtEx, @ScaleWindowExtEx, @ScaleWindowExtExHook, 'ScaleWindowExtEx', 'gdi32.dll'); AddInterceptAPI(@ozAngleArc, @AngleArc, @AngleArcHook, 'AngleArc', 'gdi32.dll'); AddInterceptAPI(@ozRoundRect, @RoundRect, @RoundRectHook, 'RoundRect', 'gdi32.dll'); AddInterceptAPI(@ozArc, @Arc, @ArcHook, 'Arc', 'gdi32.dll'); AddInterceptAPI(@ozChord, @Chord, @ChordHook, 'Chord', 'gdi32.dll'); AddInterceptAPI(@ozPie, @Pie, @PieHook, 'Pie', 'gdi32.dll'); AddInterceptAPI(@ozExtFloodFill, @ExtFloodFill, @ExtFloodFillHook, 'ExtFloodFill', 'gdi32.dll'); AddInterceptAPI(@ozArcTo, @ArcTo, @ArcToHook, 'ArcTo', 'gdi32.dll'); AddInterceptAPI(@ozPolyDraw, @PolyDraw, @PolyDrawHook, 'PolyDraw', 'gdi32.dll'); AddInterceptAPI(@ozSetMiterLimit, @SetMiterLimit, @SetMiterLimitHook, 'SetMiterLimit', 'gdi32.dll'); AddInterceptAPI(@ozStrokeAndFillPath, @StrokeAndFillPath, @StrokeAndFillPathHook, 'StrokeAndFillPath', 'gdi32.dll'); AddInterceptAPI(@ozStrokePath, @StrokePath, @StrokePathHook, 'StrokePath', 'gdi32.dll'); AddInterceptAPI(@ozFlattenPath, @FlattenPath, @FlattenPathHook, 'FlattenPath', 'gdi32.dll'); AddInterceptAPI(@ozWidenPath, @WidenPath, @WidenPathHook, 'WidenPath', 'gdi32.dll'); AddInterceptAPI(@ozSelectClipPath, @SelectClipPath, @SelectClipPathHook, 'SelectClipPath', 'gdi32.dll'); AddInterceptAPI(@ozAbortPath, @AbortPath, @AbortPathHook, 'AbortPath', 'gdi32.dll'); AddInterceptAPI(@ozFillRgn, @FillRgn, @FillRgnHook, 'FillRgn', 'gdi32.dll'); AddInterceptAPI(@ozFrameRgn, @FrameRgn, @FrameRgnHook, 'FrameRgn', 'gdi32.dll'); AddInterceptAPI(@ozInvertRgn, @InvertRgn, @InvertRgnHook, 'InvertRgn', 'gdi32.dll'); AddInterceptAPI(@ozPaintRgn, @PaintRgn, @PaintRgnHook, 'PaintRgn', 'gdi32.dll'); AddInterceptAPI(@ozMaskBlt, @MaskBlt, @MaskBltHook, 'MaskBlt', 'gdi32.dll'); AddInterceptAPI(@ozPolyTextOutA, @PolyTextOutA, @PolyTextOutAHook, 'PolyTextOutA', 'gdi32.dll'); AddInterceptAPI(@ozPolyTextOutW, @PolyTextOutW, @PolyTextOutWHook, 'PolyTextOutW', 'gdi32.dll'); AddInterceptAPI(@ozUpdateColors, @UpdateColors, @UpdateColorsHook, 'UpdateColors', 'gdi32.dll'); AddInterceptAPI(@ozOffsetViewportOrgEx, @OffsetViewportOrgEx, @OffsetViewportOrgExHook, 'OffsetViewportOrgEx', 'gdi32.dll'); AddInterceptAPI(@ozOffsetWindowOrgEx, @OffsetWindowOrgEx, @OffsetWindowOrgExHook, 'OffsetWindowOrgEx', 'gdi32.dll'); AddInterceptAPI(@ozSetDeviceGammaRamp, @SetDeviceGammaRamp, @SetDeviceGammaRampHook, 'SetDeviceGammaRamp', 'gdi32.dll'); AddInterceptAPI(@ozColorMatchToTarget, @ColorMatchToTarget, @ColorMatchToTargetHook, 'ColorMatchToTarget', 'gdi32.dll'); AddInterceptAPI(@ozPtVisible, @PtVisible, @PtVisibleHook, 'PtVisible', 'gdi32.dll'); AddInterceptAPI(@ozRectVisible, @RectVisible, @RectVisibleHook, 'RectVisible', 'gdi32.dll'); AddInterceptAPI(@ozSetPixelFormat, @SetPixelFormat, @SetPixelFormatHook, 'SetPixelFormat', 'gdi32.dll'); AddInterceptAPI(@ozOffsetClipRgn, @OffsetClipRgn, @OffsetClipRgnHook, 'OffsetClipRgn', 'gdi32.dll'); AddInterceptAPI(@ozSetArcDirection, @SetArcDirection, @SetArcDirectionHook, 'SetArcDirection', 'gdi32.dll'); AddInterceptAPI(@ozSetTextCharacterExtra, @SetTextCharacterExtra, @SetTextCharacterExtraHook, 'SetTextCharacterExtra', 'gdi32.dll'); AddInterceptAPI(@ozEnumICMProfilesA, @EnumICMProfilesA, @EnumICMProfilesAHook, 'EnumICMProfilesA', 'gdi32.dll'); AddInterceptAPI(@ozEnumICMProfilesW, @EnumICMProfilesW, @EnumICMProfilesWHook, 'EnumICMProfilesW', 'gdi32.dll'); AddInterceptAPI(@ozSetICMMode, @SetICMMode, @SetICMModeHook, 'SetICMMode', 'gdi32.dll'); AddInterceptAPI(@ozSetDIBitsToDevice, @SetDIBitsToDevice, @SetDIBitsToDeviceHook, 'SetDIBitsToDevice', 'gdi32.dll'); AddInterceptAPI(@ozDrawEscape, @DrawEscape, @DrawEscapeHook, 'DrawEscape', 'gdi32.dll'); AddInterceptAPI(@ozEnumFontsA, @EnumFontsA, @EnumFontsAHook, 'EnumFontsA', 'gdi32.dll'); AddInterceptAPI(@ozEnumFontsW, @EnumFontsW, @EnumFontsWHook, 'EnumFontsW', 'gdi32.dll'); AddInterceptAPI(@ozEnumFontFamiliesA, @EnumFontFamiliesA, @EnumFontFamiliesAHook, 'EnumFontFamiliesA', 'gdi32.dll'); AddInterceptAPI(@ozEnumFontFamiliesW, @EnumFontFamiliesW, @EnumFontFamiliesWHook, 'EnumFontFamiliesW', 'gdi32.dll'); AddInterceptAPI(@ozSetMetaRgn, @SetMetaRgn, @SetMetaRgnHook, 'SetMetaRgn', 'gdi32.dll'); AddInterceptAPI(@ozPlayEnhMetaFile, @PlayEnhMetaFile, @PlayEnhMetaFileHook, 'PlayEnhMetaFile', 'gdi32.dll'); AddInterceptAPI(@ozPlayEnhMetaFileRecord, @PlayEnhMetaFileRecord, @PlayEnhMetaFileRecordHook, 'PlayEnhMetaFileRecord', 'gdi32.dll'); // AddInterceptAPI(@ozTransparentBlt, @TransparentBlt, @TransparentBltHook, 'TransparentBlt'); // AddInterceptAPI(@ozGradientFill, @GradientFill, @GradientFillHook, 'GradientFill'); // AddInterceptAPI(@ozFrameRect, @FrameRect, @FrameRectHook, 'FrameRect'); // AddInterceptAPI(@ozFloodFill, @FloodFill, @FloodFillHook, 'FloodFill'); // 훅 제외 // AddInterceptAPI(@ozDrawTextExA, @DrawTextExA, @DrawTextExAHook_DW, 'DrawTextExA'); // AddInterceptAPI(@ozDrawTextExW, @DrawTextExW, @DrawTextExWHook_DW, 'DrawTextExW'); // AddInterceptAPI(@ozTabbedTextOutA, @TabbedTextOutA, @TabbedTextOutAHook, 'TabbedTextOutA'); // AddInterceptAPI(@ozTabbedTextOutW, @TabbedTextOutW, @TabbedTextOutWHook, 'TabbedTextOutW'); // AddInterceptAPI(@ozGetTextCharsetInfo, @GetTextCharsetInfo, @GetTextCharsetInfoHook, 'GetTextCharsetInfo'); // 훅 제외 // AddInterceptAPI(@ozGetGlyphIndicesA, @GetGlyphIndicesA, @GetGlyphIndicesAHook, 'GetGlyphIndicesA') // 훅 제외; // AddInterceptAPI(@ozGetGlyphIndicesW, @GetGlyphIndicesW, @GetGlyphIndicesWHook, 'GetGlyphIndicesW'); // 훅 제외 // AddInterceptAPI(@ozGetFontLanguageInfo, @GetFontLanguageInfo, @GetFontLanguageInfoHook, 'GetFontLanguageInfo'); // 훅 제외 // AddInterceptAPI(@ozGetCharacterPlacementA, @GetCharacterPlacementA, @GetCharacterPlacementAHook, 'GetCharacterPlacementA'); // 훅 제외 // AddInterceptAPI(@ozGetCharacterPlacementW, @GetCharacterPlacementW, @GetCharacterPlacementWHook, 'GetCharacterPlacementW'); // 훅 제외 // AddInterceptAPI(@ozGetFontData, @GetFontData, @GetFontDataHook, 'GetFontData'); // 훅 제외 // AddInterceptAPI(@ozGetGlyphOutlineA, @GetGlyphOutlineA, @GetGlyphOutlineAHook, 'GetGlyphOutlineA'); // 훅 제외 // AddInterceptAPI(@ozGetGlyphOutlineW, @GetGlyphOutlineW, @GetGlyphOutlineWHook, 'GetGlyphOutlineW'); // 훅 제외 // AddInterceptAPI(@ozResetDCA, @ResetDCA, @ResetDCAHook, 'ResetDCA'); // 사용하지 않음 // AddInterceptAPI(@ozResetDCW, @ResetDCW, @ResetDCWHook, 'ResetDCW'); // 사용하지 않음 // AddInterceptAPI(@ozAlphaBlend, @AlphaBlend, @AlphaBlendHook, 'AlphaBlend'); // 훅 제외 // AddInterceptAPI(@ozGetTextMetricsA, @GetTextMetricsA, @GetTextMetricsAHook, 'GetTextMetricsA'); // 훅 제외 // AddInterceptAPI(@ozGetTextMetricsW, @GetTextMetricsW, @GetTextMetricsWHook, 'GetTextMetricsW'); // 훅 제외 // AddInterceptAPI(@ozGetTextExtentPoint32A, @GetTextExtentPoint32A, @GetTextExtentPoint32AHook, 'GetTextExtentPoint32A'); // 훅 제외 // AddInterceptAPI(@ozGetTextExtentPoint32W, @GetTextExtentPoint32W, @GetTextExtentPoint32WHook, 'GetTextExtentPoint32W'); // 훅 제외 // AddInterceptAPI(@ozGdiComment, @GdiComment, @GdiCommentHook, 'GdiComment'); // 훅 제외 // AddInterceptAPI(@ozGetCharABCWidthsA, @GetCharABCWidthsA, @GetCharABCWidthsAHook, 'GetCharABCWidthsA'); // 훅 제외 // AddInterceptAPI(@ozGetCharABCWidthsW, @GetCharABCWidthsW, @GetCharABCWidthsWHook, 'GetCharABCWidthsW'); // 훅 제외 // AddInterceptAPI(@ozExtEscape, @ExtEscape, @ExtEscapeHook, 'ExtEscape'); // 훅 제외 // AddInterceptAPI(@ozCreateCompatibleDC, @CreateCompatibleDC, @CreateCompatibleDCHook, 'CreateCompatibleDC'); // 훅 제외 // AddInterceptAPI(@ozCreateCompatibleBitmap, @CreateCompatibleBitmap, @CreateCompatibleBitmapHook, 'CreateCompatibleBitmap'); // 훅 제외 // 이거 활성화 하면 프린트 창이 안뜨고 죽는다 25_1001 19:27:29 kku // AddInterceptAPI(@ozDrawTextA, @DrawTextA, @DrawTextAHook, 'DrawTextA'); // AddInterceptAPI(@ozDrawTextW, @DrawTextW, @DrawTextWHook, 'DrawTextW'); end; if bUse_madCodeHook_ then FlushHooks; bInitPrt_ := true; // if aOpt.bPrintMasking then // begin // AddInterceptAPI(@ozStartDocA, @StartDocA, @StartDocAHook, 'StartDocA'); // AddInterceptAPI(@ozStartDocW, @StartDocW, @StartDocWHook, 'StartDocW'); // AddInterceptAPI(@ozEndDoc, @EndDoc, @EndDocHook, 'EndDoc'); // // AddInterceptAPI(@ozExtTextOutA, @ExtTextOutA, @ExtTextOutAHook, 'ExtTextOutA'); // notepad++, WORD등.. 대부분 여기서 처리됨 24_0524 13:23:03 kku // AddInterceptAPI(@ozExtTextOutW, @ExtTextOutW, @ExtTextOutWHook, 'ExtTextOutW'); // notepad++, WORD등.. 대부분 여기서 처리됨 24_0524 13:23:03 kku // // AddInterceptAPI(@ozDrawTextA, @DrawTextA, @DrawTextAHook, 'DrawTextA'); // AddInterceptAPI(@ozDrawTextW, @DrawTextW, @DrawTextWHook, 'DrawTextW'); // AddInterceptAPI(@ozDrawTextExA, @DrawTextExA, @DrawTextExAHook, 'DrawTextExA'); // AddInterceptAPI(@ozDrawTextExW, @DrawTextExW, @DrawTextExWHook, 'DrawTextExW'); // AddInterceptAPI(@ozTextOutA, @TextOutA, @TextOutAHook, 'TextOutA'); // AddInterceptAPI(@ozTextOutW, @TextOutW, @TextOutWHook, 'TextOutW'); // AddInterceptAPI(@ozPolyTextOutA, @PolyTextOutA, @PolyTextOutAHook, 'PolyTextOutA'); // AddInterceptAPI(@ozPolyTextOutW, @PolyTextOutW, @PolyTextOutWHook, 'PolyTextOutW'); // AddInterceptAPI(@ozTabbedTextOutA, @TabbedTextOutA, @TabbedTextOutAHook, 'TabbedTextOutA'); // AddInterceptAPI(@ozTabbedTextOutW, @TabbedTextOutW, @TabbedTextOutWHook, 'TabbedTextOutW'); // end; end; procedure TBS1Hook.ProcessAppCtrlOpt(aOpt: TAppCtrlOpt); begin try DVLOG('ProcessAppCtrlOpt, hRcvWnd(%d), FileUseBlock(%d), bUseContentFilter(%d), ShFileCrMon.nKind(%d)', [DWORD(aOpt.hRcvWnd), DWORD(aOpt.FileUseBlock), DWORD(aOpt.bUseContentFilter), aOpt.ShFileCrMon.nKind]); // DoInterceptRemove; aOpt.bMtpWB := aOpt.bMtpWB and (Helper_.CurAppType = catExplorer); // 탐색기에서만 활성화 되도록 24_0604 15:23:45 kku if aOpt.dwCustomerType = CUSTOMER_KOCES then begin Helper_.NoDrmUse; Helper_.bEndDocProc_ := CompareText('excel.exe', ModuleName) <> 0; // 엑셀에서 이렇게 하면 워터마크가 뒤로 밀리는 문제가 있음..23_0410 15:52:34 kku end; if Helper_.CurAppType <> catWebb then // 브라우저는 실시간으로 적용/해제 하고 있어서 여기서 처리하지 않음 25_1113 15:12:01 kku begin begin if (aOpt.hCltWnd <> 0) and (CapBlockWndList_.Count = 0) then begin // 화면 캡쳐 차단 설정 AddCapBlockWnd(aOpt.hCltWnd); end else if (aOpt.hCltWnd = 0) and (CapBlockWndList_.Count <> 0) then begin // 화면 캡쳐 차단 해제 ClearCapBlockWnd; end; end; end; if aOpt.sDrmPass <> '' then aOpt.sDrmPass := DecText(aOpt.sDrmPass); Helper_.CtrlOpt := aOpt; if Helper_.IsDrmSupport and (aOpt.DrmAccessKind <> dakNone) and not bInitDrm_ then InitDrmProcess; if (aOpt.FileUseBlock <> fubNone) or (aOpt.bMtpWB and (Helper_.CurAppType = catExplorer)) then begin if bUse_madCodeHook_ then CollectHooks; AddInterceptAPI(@ozCreateFileA, @CreateFileA, @CreateFileAHook, 'CreateFileA', 'kernelbase.dll'); AddInterceptAPI(@ozCreateFileW, @CreateFileW, @CreateFileWHook, 'CreateFileW', 'kernelbase.dll'); if bUse_madCodeHook_ then FlushHooks; end; if Helper_.CurAppType = catExplorer then begin if aOpt.ShFileCrMon.nKind <> 0 then begin SplitString(UpperCase(Helper_.CtrlOpt.ShFileCrMon.sExpLst), '|', Helper_.FoExpList, false, true); InstallFileOperationHooks; end else UninstallFileOperationHooks; end; if (Helper_.CurAppType <> catExplorer) and (aOpt.bPrintSecu or aOpt.bPrintWater) and not bInitPrt_ then InitPrtProcess(aOpt); Helper_.CtrlOpt := aOpt; except // .. end; end; procedure TBS1Hook.ProcessNoti(nNotiCode: Integer; sPath: String; nFType: Integer; bDirect: Boolean = false); var llInfo: LONGLONG; Send: ISendPacket; begin try // if Helper_.CtrlOpt.hRcvWnd = 0 then // exit; if nNotiCode = NOTI_HOOK_OPEN_DRM then begin if DrmFList_.IndexOf(sPath) <> -1 then exit; DrmFList_.Add(sPath); end; case nNotiCode of NOTI_HOOK_MONITOR_ATTACH, NOTI_HOOK_BLOCK_ATTACH : begin // 첨부 파일 차단의 경우 어디서 차단됐는지 정보도 추가해줌 22_1028 14:02:22 kku llInfo := Integer(Helper_.CurAppType); end; else llInfo := 0; end; Send := TTgPacket.Create(ACC_NOTI_MSG); Send.I['Noti'] := nNotiCode; Send.S['MdName'] := ModuleName; Send.I['PID'] := PID; Send.S['FPath'] := sPath; Send.I['FType'] := nFType; // 0 : 없는 파일, 1: 존재 파일, 2 : 네트워크 파일, 3 : 특수 경로 파일 Send.I['Info'] := llInfo; if bDirect and (Helper_.CtrlOpt.hRcvWnd <> 0) then begin SendCopyData(Helper_.CtrlOpt.hRcvWnd, HPCMD_HOOK_NOTI, Send.ToJsonString); end else Client_.SendPacket(Send); except // ... end; end; procedure TBS1Hook.DoInterceptRemove; procedure RemoveAPI(var aProc: Pointer); var nRet: Integer; begin if aProc <> nil then begin if bUse_madCodeHook_ then UnhookAPI(aProc) else begin nRet := InterceptRemove(aProc); aProc := nil; end; // Log('DoInterceptRemove() .. RemoveAPI() .. nRet=' + IntToStr(nRet)); end; end; var i: Integer; begin Log('DoInterceptRemove()'); if bUse_madCodeHook_ then CollectHooks; for i := 0 to ProcList_.Count - 1 do RemoveAPI(ProcList_[i]^); ProcList_.Clear; if bUse_madCodeHook_ then FlushHooks; // {$IFDEF USE_BOXAPP} // BoxedAppSDK_Exit; // {$ENDIF} end; procedure TBS1Hook.AddInterceptAPI(var aProcDest: Pointer; aProcSrc, aProcHook: Pointer; sProcName, sDllName: AnsiString; bCHFH: Boolean = false); begin if bIgnoreHook_ then exit; if bUse_madCodeHook_ then begin if bCHFH then CollectHooks; try if HookAPI(PAnsiChar(sDllName), PAnsiChar(sProcName), aProcHook, aProcDest) then begin if aProcDest <> nil then ProcList_.Add(@aProcDest); Log(Format('>>> AddInterceptAPI(mad) - %s <<<', [sProcName])); OutputDebugStringW(PChar(Format('>>> AddInterceptAPI(mad) - %s <<<', [sProcName]))); end else Log(Format('>>> Fail .. AddInterceptAPI(mad) - %s <<<', [sProcName])); finally if bCHFH then FlushHooks; end; end else begin if aProcDest = nil then begin aProcDest := InterceptCreate(aProcSrc, aProcHook); if aProcDest <> nil then begin ProcList_.Add(@aProcDest); Log(Format('>>> AddInterceptAPI() - %s <<<', [sProcName])); end else Log(Format('>>> Fail .. AddInterceptAPI() - %s <<<', [sProcName])); end; end; end; procedure TBS1Hook.Log(sLog: String); begin if Trace_ <> nil then begin _bLogProcessing := true; Trace_.T('(%s) %s', [ModuleName, sLog]); _bLogProcessing := false; end; end; procedure TBS1Hook.Log(const sFormat: string; const Args: array of const); var str: String; begin FmtStr(str, sFormat, Args); Log(str); end; procedure TBS1Hook.AddCreateFile(hFile: THandle; sPath: String); begin try // Lock; try if RFileList_.IndexOf(sPath) = -1 then RFileList_.AddObject(sPath, TObject(hFile)); finally // Unlock; end; except // .. end; end; procedure TBS1Hook.DelCloseFile(hFile: THandle); var i: Integer; begin try Lock; try for i := 0 to RFileList_.Count - 1 do if hFile = THandle(RFileList_.Objects[i]) then begin RFileList_.Delete(i); exit; end; finally Unlock; end; except // .. end; end; function TBS1Hook.GetRFilePath(sFName: String): String; var i: Integer; begin Result := ''; try sFName := UpperCase(sFName); Lock; try for i := 0 to RFileList_.Count - 1 do if Pos(UpperCase(ExtractFileName(RFileList_[i])), sFName) > 0 then begin Result := RFileList_[i]; exit; end; finally Unlock; end; except // .. end; end; end.