Autor Beitrag
randydom
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Fr 13.04.12 14:01 
Hi , i've this component that i want to use it in a DLL to achieve a system-wide hook :

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
unit ClipboardHook;
interface
uses
  Windows, SysUtils, Classes, ExtCtrls;
type
 TFOnOpenClipboard = procedure(Sender:TObject; hWndNewOwner:HWND; var opContinue:Boolean) of object;
 TFOnSetClipboardData = procedure(Sender:TObject; hWndNewOwner:HWND; uFormat:DWord; hMem:THandle; var opContinue:Boolean) of object;
type
  TClipboardHook = class(TComponent)
  private
    { Private declarations }
    FOnOpenClipboard:TFOnOpenClipboard;
    FOnSetClipboardData:TFOnSetClipboardData;
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    //------------------------------------------------
  published
    { Published declarations }
    property OnOpenClipboard:TFOnOpenClipboard read FOnOpenClipboard write FOnOpenClipboard;
    property OnSetClipboardData:TFOnSetClipboardData read FOnSetClipboardData write FOnSetClipboardData;
  end;
implementation
type
 TcOpen=function(hWndNewOwner:HWND):Bool; stdcall;
 TscData=function(uFormat:DWord; hMem:Thandle):THandle; stdcall;
 TOP_H = packed record
  Push:Byte;
  Address:DWord;
  Ret:Byte;
 end
var OC_Addr,SCD_Addr:Pointer;
    OP:DWord;
    cOpen,rcOpen,scData,rscData:TOP_H;
    WPM:DWord;
    sComponent:TObject;
{***************************Start:TClipboardHook***************************}
function Open_Clipboard(hWndNewOwner:HWND):Bool; stdcall;
var c:Boolean;
begin
 c:=true;
 if Assigned(TClipboardHook(sComponent).FOnOpenClipboard) then
  TClipboardHook(sComponent).FOnOpenClipboard(sComponent,hWndNewOwner,c);
 if c then
  begin
   WriteProcessMemory(OP,OC_Addr,@rcOpen,SizeOf(rcOpen),WPM);
   Result:=TcOpen(OC_Addr)(hWndNewOwner);
   WriteProcessMemory(OP,OC_Addr,@cOpen,SizeOf(cOpen),WPM);
  end else Result:=false;
end;
function Set_ClipboardData(uFormat:DWord; hMem:THandle):THandle; stdcall;
var c:Boolean;
    Win:DWord;
begin         
 c:=true;
 Win:=GetOpenClipboardWindow();
 if (Win<>0)and(Assigned(TClipboardHook(sComponent).FOnSetClipboardData)) then
  TClipboardHook(sComponent).FOnSetClipboardData(sComponent,Win,uFormat,hMem,c);
 if c then
  begin
   WriteProcessMemory(OP,SCD_Addr,@rscData,SizeOf(rscData),WPM);
   Result:=TscData(SCD_Addr)(uFormat,hMem);
   WriteProcessMemory(OP,SCD_Addr,@scData,SizeOf(scData),WPM);
  end else Result:=0;
end;
{****************************End:TClipboardHook****************************}
{##############################################################################}
constructor TClipboardHook.Create(AOwner:TComponent);
var Dll:DWord;
begin
 inherited Create(Aowner);
 if (csDesigning in ComponentState) then exit;
 sComponent:=Self;
 DLL:=LoadLibrary('user32.dll');
 if DLL<>0 then
  begin
   OC_Addr:=GetProcAddress(DLL,'OpenClipboard');
   SCD_Addr:=GetProcAddress(DLL,'SetClipboardData');
   if (OC_Addr<>nil)or(SCD_Addr<>nilthen
    begin      
     OP:=OpenProcess(PROCESS_ALL_ACCESS,false,GetCurrentProcessID);
     if OP<>0 then
      begin
       if OC_Addr<>nil then
        begin
         cOpen.Push:=$68;
         cOpen.Address:=DWord(@Open_Clipboard);
         cOpen.Ret:=$C3;
         ReadProcessMemory(OP,OC_Addr,@rcOpen,SizeOf(rcOpen),WPM);
         WriteProcessMemory(OP,OC_Addr,@cOpen,SizeOf(cOpen),WPM);
        end;
       if SCD_Addr<>nil then
        begin
         scData.Push:=$68;
         scData.Address:=DWord(@Set_ClipboardData);
         scData.Ret:=$C3;
         ReadProcessMemory(OP,SCD_Addr,@rscData,SizeOf(rscData),WPM);
         WriteProcessMemory(OP,SCD_Addr,@scData,SizeOf(scData),WPM);
        end;
      end;
    end;
   FreeLibrary(Dll);
  end;
end;
destructor TClipboardHook.destroy;
begin
 if (OC_Addr<>nilthen WriteProcessMemory(OP,OC_Addr,@rcOpen,SizeOf(rcOpen),WPM);
 if OP<>0 then CloseHandle(OP);
 inherited destroy;
end;
{##############################################################################}
end.


can someone help me in putting all these stuffs into a DLL ( without the Component ) ,i mean only the functions .

many thanks
randydom Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Sa 14.04.12 03:23 
Hello i did it in this way :
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
library HookDll;

uses
  Windows;


type
 TcOpen=function(hWndNewOwner:HWND):Bool; stdcall;
 TscData=function(uFormat:DWord; hMem:Thandle):THandle; stdcall;
 TOP_H = packed record
  Push:Byte;
  Address:DWord;
  Ret:Byte;
 end
var OC_Addr,SCD_Addr:Pointer;
    OP:DWord;
    cOpen,rcOpen,scData,rscData:TOP_H;
  
  
function Open_Clipboard(hWndNewOwner:HWND):Bool; stdcall;
var c:Boolean;
begin
 c:=true;
 if c then
  begin
   WriteProcessMemory(OP,OC_Addr,@rcOpen,SizeOf(rcOpen),WPM);
   Result:=TcOpen(OC_Addr)(hWndNewOwner);
   WriteProcessMemory(OP,OC_Addr,@cOpen,SizeOf(cOpen),WPM);
  end else Result:=false;
end;

function Set_ClipboardData(uFormat:DWord; hMem:THandle):THandle; stdcall;
var c:Boolean;
    Win:DWord;
begin    
 c:=true;
 if c then
  begin
   WriteProcessMemory(OP,SCD_Addr,@rscData,SizeOf(rscData),WPM);
   Result:=TscData(SCD_Addr)(uFormat,hMem);
   WriteProcessMemory(OP,SCD_Addr,@scData,SizeOf(scData),WPM);
  end else Result:=0;
end;

function HookClipboardOperations: Boolean;
var Dll:DWord;
begin
 DLL:=LoadLibrary('user32.dll');
 if DLL<>0 then
  begin
   OC_Addr:=GetProcAddress(DLL,'OpenClipboard');
   SCD_Addr:=GetProcAddress(DLL,'SetClipboardData');
   if (OC_Addr<>nil)or(SCD_Addr<>nilthen
    begin      
     OP:=GetCurrentProcess;
     //OpenProcess(PROCESS_ALL_ACCESS,false,GetCurrentProcessID);
     if OP<>0 then
      begin
       if OC_Addr<>nil then
        begin
         cOpen.Push:=$68;
         cOpen.Address:=DWord(@Open_Clipboard);
         cOpen.Ret:=$C3;
         ReadProcessMemory(OP,OC_Addr,@rcOpen,SizeOf(rcOpen),WPM);
         WriteProcessMemory(OP,OC_Addr,@cOpen,SizeOf(cOpen),WPM);
        end;
       if SCD_Addr<>nil then
        begin
         scData.Push:=$68;
         scData.Address:=DWord(@Set_ClipboardData);
         scData.Ret:=$C3;
         ReadProcessMemory(OP,SCD_Addr,@rscData,SizeOf(rscData),WPM);
         WriteProcessMemory(OP,SCD_Addr,@scData,SizeOf(scData),WPM);
        end;
      end;
    end;
   FreeLibrary(Dll);
  end;
end;

function HookProc(code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  if FHook <> 0 then
  begin
    if code < HC_ACTION then
      Result := CallNextHookEx(FHook,code,wParam,lParam)
    else
    begin
      if (not FHooked) and (code >= HC_ACTION) then
      begin
        FHooked := true;
        HookClipboardOperations;
      end;
      Result := CallNextHookEx(FHook,code,wParam,lParam);
    end;
  end
  else
    Result := 0;
end;

procedure InstallHook; stdcall;
begin
 FHook := SetWindowsHookEx(WH_GETMESSAGE,HookProc,hInstance,0);
end;

procedure UnInstallHook; stdcall;
begin
  if FHook <> 0 then
    UnhookWindowsHookEx(FHook);
   if (OC_Addr<>nilthen WriteProcessMemory(OP,OC_Addr,@rcOpen,SizeOf(rcOpen),WPM);
 if OP<>0 then CloseHandle(OP); 
end;

procedure EntryPointProc(reason: integer);
var
  str: pChar;
begin
  case reason of
    DLL_PROCESS_ATTACH:
      begin
        InstallHook();
      end;
    DLL_THREAD_ATTACH:
      begin
      end;
    DLL_PROCESS_DETACH:
      begin
      UnInstallHook();
      end;
    DLL_THREAD_DETACH:
      begin
      end;
  end;
end;
exports
  InstallHook,
  UnInstallHook,
  HookProc;
begin
  DllProc := @EntryPointProc;
  EntryPointProc(DLL_PROCESS_ATTACH);
end.


When i inject the DLL i can Intercept and hook SetClipboardData API , but the Problem is when i close the application( the injector ) after calling UnInstallHook of course the DLL is not Uninjected from the system that means each time a Paste operation is called/invoked the active window ( that's calling Paste operation ) is hanged .

please any solution for this ?

many thanks
mandras
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 429
Erhaltene Danke: 107

Win 10
Delphi 6 Prof, Delphi 10.4 Prof
BeitragVerfasst: Sa 14.04.12 10:03 
Maybe after Line 110 something like

ausblenden Delphi-Quelltext
1:
  if (SCD_Addr<>nilthen WriteProcessMemory(OP,SCD_Addr,@rscData,SizeOf(rscData),WPM);					


is missing?