If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Snuffel daar eens rond zou ik zeggen. Er staan voor bijna alles wat je zoekt interfaces en sample codes
Maar het heeft niets met IExplorer te maken. Elk ander programma heeft het zelfde probleem.
Het heeft te maken met het hooken (capture.dll)
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
We adore chaos because we like to restore order - M.C. Escher
Maar ik moet wel zeggen dat de 1e gestartte app het prima doet he.
Die wordt wel gehooked
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
We adore chaos because we like to restore order - M.C. Escher
Hij kan maar 1 window 'observer'en.
1
2
3
4
5
6
| procedure TForm2.StartHooking; begin if FWantClose or FWantStopHooking or (FSubClassedCount > 0) then Exit; SetObserver(Handle); SetHook; end; |
Als ik die FSubClassedCount uitschakel bij deze if, dan voert hij de 2 functies (Set..) ook de 2e keer uit, en dan hangt hij bij SetHook
En wel hier:
In de dll staat dit:
1
2
3
4
5
6
7
8
9
| procedure SetHook;
begin
with GHookRecPtr^ do
begin
RWantProcessID := 0;
RObservedWindow := 0;
RHookID := SetWindowsHookEx(WH_CBT, @HookProc, HInstance, 0);
end;
end; |
En dan hangt hij bij RHookID := SetWindowsHookEx
Ik hoop dat je hiermee iets kan?
Ik puzzel weer verder
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
.oiyson had mij de vorige keer een heel end geholpen. Ben jij er nog?
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Als je in dezelfde instantie werkt dan overschrijf je de oude id, en dus weet je programma niet meer welke bedoelt wordt. Misschien is een array een oplossing? Echter, ik weet niet zo heel veel van Delphi in het algemeen of jouw code in het bijzonder, dus vertrouw niet blind op me
Gebruik je een 'system wide hook' ?
zo ja dan moet je zorgen dat de keyhook in shared memory zit.
Vb code van een system wide keyboard hook (ik weet dus niet of je uberhaupt gebruik maakt van API hooking).
PS TJclSwapFileMapping komt uit de Jedi JCL library
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
| library keyhook; uses Windows, Messages, SysUtils, Classes, JclFileUtils; {$R *.RES} type TSharedRec = record FKeyHook : HHOOK; FNotifyWindow : HWND; FMsg : UINT; end; PSharedRec = ^TSharedRec; var GSharedRec : PSharedRec; GFileMapping : TJclSwapFileMapping; GFileViewIdx : Integer; HookCreated : Boolean; function KeyboardProc(nCode : Integer; wParam : WPARAM; lParam : LPARAM) : LRESULT; stdcall; begin if nCode < 0 then begin Result := CallNextHookEx(GSharedRec.FKeyHook, nCode, wParam, lParam); Exit; end; if nCode = HC_ACTION then begin SendNotifyMessage(GSharedRec.FNotifyWindow, GSharedRec.FMsg, wParam, lParam); end; Result := 0; end; function CreateHook(NotifyWindow : HWND; Msg : UINT) : Boolean; stdcall; begin Result := True; if HookCreated then Exit; GSharedRec.FNotifyWindow := NotifyWindow; GSharedRec.FMsg := Msg; GSharedRec.FKeyHook := SetWindowsHookEx(WH_KEYBOARD, @KeyboardProc, HInstance, 0); if GSharedRec.FKeyHook <> 0 then begin HookCreated := True; end else begin MessageBox(0, 'hook = 0', 'error', MB_OK); HookCreated := False; Result := False; end; end; function UnHook : Boolean; stdcall; begin if not HookCreated then begin Result := False; Exit; end; Result := UnHookWindowsHookEx(GSharedRec.FKeyHook); HookCreated := False; end; procedure DLLHandler(Reason: Integer); begin case Reason of DLL_PROCESS_DETACH: begin UnHook; GFileMapping.Free; end; end; // end case end; exports CreateHook, UnHook; begin try {disable DLL_THREAD_ATTACH and DLL_THREAD_DETACH notifications} DisableThreadLibraryCalls(HInstance); GFileMapping := TJclSwapFileMapping.Create('stigmergy_simple_keyhook', PAGE_READWRITE, SizeOf(TSharedRec), nil); GFileViewIdx := GFileMapping.Add(FILE_MAP_WRITE, SizeOf(TSharedRec), 0); GSharedRec := PSharedRec(GFileMapping.Views[GFileViewIdx].Memory); {initialize SharedRec for the first time} if not GFileMapping.Existed then begin GSharedRec.FKeyHook := 0; GSharedRec.FNotifyWindow := 0; end; DllProc := @DLLHandler; except on E : EJclFileMappingError do begin MessageBox(0, 'Create mapping error', 'error', MB_OK); Halt(1); end; end; end. |
Ik denk dat die variablen idd in een array moeten komen te staan. Ik zal eens kijken in hoeverre ik dat voorelkaar kan krijgen.
En ik ga nu even kijken naar dit voorbeeld hierboven.
edit: Voor het gemak maar even de DLL code hierneer gezet:
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
| library Capture;
uses
Windows,
CommCtrl,
Messages,
SysUtils;
{$R *.RES}
type
PHookRec = ^THookRec;
THookRec = record
RObserver: THandle;
RObservedWindow: THandle;
RHookID: HHOOK;
RWantProcessID: DWORD;
end;
const
CM_NotifyObserver = WM_USER + 1;
CM_NotifyObserverMsg = WM_USER + 2;
WM_HCBT_MINMAX = WM_USER + 285;
NO_BeginSubClassed = 0;
NO_EndSubClassed = 1;
NO_ProcessIDFound = 2;
NO_ClosePrevented = 3;
NO_StartProcess = 4;
NO_EndProcess = 5;
var
{ Alle instanties van de dll die geinjecteerd worden in een window
krijgen eigen instanties van de volgende vars: }
{ Pointer naar de data die alle dll instanties delen }
GHookRecPtr: PHookRec = nil;
{ Handle naar de filemapping object }
GMapObject: THandle = 0;
{ Pointer naar oude wndproc }
GOldWndProc: Pointer = nil;
{ Handle naar Window die gesubclassed is }
GHandle: THandle = 0;
procedure NotifyObserver(Msg, SubMsg: Integer);
begin
PostMessage(GHookRecPtr.RObserver, CM_NotifyObserver, Msg, SubMsg);
end;
procedure UnSubClass {(Handle: HWnd)};
begin
if (GOldWndProc <> nil) and (GHandle > 0) then
begin
SetWindowLongW(GHandle, GWL_WNDPROC, Longint(GOldWndProc));
NotifyObserver(NO_EndSubClassed, LongInt(GHandle));
GOldWndProc := nil;
GHandle := 0;
end;
end;
function WndProc(Wnd: HWND; Msg, WParam, LParam: Longint): Longint; stdcall;
var
PID: DWORD;
begin
with GHookRecPtr^ do
begin
// OutputDebugString(PChar(IntToStr(RObservedWindow)));
if (RObservedWindow = 0) and (RWantProcessID > 0) then
begin
GetWindowThreadProcessId(Wnd, @PID);
if PID <> RWantProcessID then
begin
Result := CallWindowProcW(GOldWndProc, Wnd, Msg, WParam, LParam);
UnSubClass {(Wnd)};
Exit;
end
else
begin
//if (RObservedWindow = 0) Then
RObservedWindow := Wnd;
// else RObservedWindow2 := Wnd
//NotifyObserver(NO_ProcessIDFound, LongInt(Wnd));
end;
end;
case Msg of
WM_NULL:
if (WParam = $15) and (LParam = $15) then
begin
UnSubClass;
Result := 0;
Exit;
end;
WM_SYSCOMMAND:
Begin
if (WParam = SC_CLOSE) or (WParam = 61539) then
begin
NotifyObserver(NO_ClosePrevented, LongInt(Msg));
Result := 0;
Exit;
end else
If (WParam = SC_MINIMIZE) Then
Begin
// PostMessage(GHookRecPtr.RObserver, WM_HCBT_MINMAX, Wnd, lParam);
End;
End;
WM_COMMAND:
if (WParam = 40993) or (WParam = 106529) then
begin
NotifyObserver(NO_ClosePrevented, LongInt(Msg));
Result := 0;
Exit;
end;
end;
Result := CallWindowProcW(GOldWndProc, Wnd, Msg, WParam, LParam);
end;
end;
procedure SubClass(Handle: Hwnd);
begin
GHandle := Handle;
GOldWndProc := Pointer(GetWindowLong(Handle, GWL_WNDPROC));
SetWindowLongW(Handle, GWL_WNDPROC, Longint(@WndProc));
NotifyObserver(NO_BeginSubClassed, LongInt(Handle));
end;
procedure SetObserver(Handle: HWnd);
begin
GHookRecPtr.RObserver := Handle;
end;
function GetClassNameWnd(Wnd: HWND): string;
begin
SetLength(Result, 80);
SetLength(Result, GetClassName(Wnd, PChar(Result), Length(Result)));
end;
function HookProc(Code: Integer; WParam, LParam: Longint): Longint;
stdcall;
var
ExStyle: LongInt;
begin
if (Code = HCBT_CREATEWND) and (GHookRecPtr.RObservedWindow = 0) Then
//((GHookRecPtr.RObservedWindow = 0) or (GHookRecPtr.RObservedWindow2 = 0)) then
begin
ExStyle := GetWindowLong(WParam, GWL_EXSTYLE);
if (ExStyle = 256) and (CompareText(GetClassNameWnd(WParam), 'ieframe') = 0)
then
begin
SubClass(WParam);
// OutputDebugString(PChar(IntToSTr(WParam)));
End;
end;
Result := CallNextHookEx(GHookRecPtr.RHookID, Code, WParam, LParam)
end;
procedure SetWantProcessID(AProcessID: DWORD);
begin
GHookRecPtr.RWantProcessID := AProcessID;
end;
procedure SetHook;
begin
with GHookRecPtr^ do
begin
RWantProcessID := 0;
RObservedWindow := 0;
RHookID := SetWindowsHookEx(WH_CBT, @HookProc, HInstance, 0);
end;
end;
procedure UnSetHook;
begin
UnHookWindowsHookEx(GHookRecPtr.RHookID);
end;
function getProcessID : Integer;
Begin
Result := GHookRecPtr^.RWantProcessID;
End;
function getHandle : THandle;
Begin
Result := GHookRecPtr^.RObservedWindow;
End;
exports
SetHook,
UnSetHook,
SetObserver,
getHandle,
getProcessID,
SetWantProcessID;
procedure EntryPointProc(Reason: Integer);
begin
case reason of
DLL_PROCESS_ATTACH:
begin
GMapObject := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
SizeOf(THookRec), 'CaptureDesktopEvents');
GHookRecPtr := MapViewOfFile(GMapObject, FILE_MAP_WRITE, 0, 0, 0);
NotifyObserver(NO_StartProcess, 0);
end;
DLL_PROCESS_DETACH:
begin
UnSubClass;
NotifyObserver(NO_EndProcess, 0);
try
if GHookRecPtr <> nil then
UnMapViewOfFile(GHookRecPtr);
if GMapObject <> 0 then
CloseHandle(GMapObject);
except
end;
end;
end;
end;
begin
DllProc := @EntryPointProc;
EntryPointProc(DLL_PROCESS_ATTACH);
end. |
[ Voor 90% gewijzigd door Guillome op 09-12-2003 23:22 ]
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
In Platform SDK staat bij CBTProc :
Ik jouw code zie ik niet dat je checked op nCode < 0 en dat onmiddelijk CallNextHookEx aan roept. Ik weet niet wat de consequentie is van het altijd (zoals jij doet) aanroepen van CallNextHookEx maar je zou kunnen kijken of dat wat uit maakt. Het is ook aan te raden om DisableThreadLibraryCalls(HInstance) in je dll entry proc te zetten vanwege een bug in Delphi.[in] Specifies a code that the hook procedure uses to determine how to process the message. If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| function HookProc(Code: Integer; WParam, LParam: Longint): Longint;
stdcall;
var
ExStyle: LongInt;
begin
if (Code = HCBT_CREATEWND) and (GHookRecPtr.RObservedWindow = 0) Then
//((GHookRecPtr.RObservedWindow = 0) or (GHookRecPtr.RObservedWindow2 = 0)) then
begin
ExStyle := GetWindowLong(WParam, GWL_EXSTYLE);
if (ExStyle = 256) and (CompareText(GetClassNameWnd(WParam), 'ieframe') = 0)
then
begin
SubClass(WParam);
// OutputDebugString(PChar(IntToSTr(WParam)));
End;
end;
if (code < 0) then Result := CallNextHookEx(GHookRecPtr.RHookID, Code, WParam, LParam)
end; |
Dan hangt de computer helemaal.
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
The value returned by the hook procedure determines whether the system allows or prevents one of these operations. For operations corresponding to the following CBT hook codes, the return value must be 0 to allow the operation, or 1 to prevent it:
HCBT_ACTIVATE
HCBT_CREATEWND
HCBT_DESTROYWND
HCBT_MINMAX
HCBT_MOVESIZE
HCBT_SETFOCUS
HCBT_SYSCOMMAND
[ Voor 60% gewijzigd door martijn_brinkers op 11-12-2003 14:48 ]
Alleen nu is er iets anders vaags. Ik laat eerst de code even zien:
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
| library Capture;
uses
Windows,
CommCtrl,
Messages,
SysUtils;
{$R *.RES}
type
PHookRec = ^THookRec;
THookRec = record
RObserver: THandle;
RObservedWindow: THandle;
RHookID: HHOOK;
WHandle: HWND;
RWantProcessID: DWORD;
end;
const
CM_NotifyObserver = WM_USER + 1;
CM_NotifyObserverMsg = WM_USER + 2;
WM_HCBT_MINMAX = WM_USER + 285;
NO_BeginSubClassed = 0;
NO_EndSubClassed = 1;
NO_ProcessIDFound = 2;
NO_ClosePrevented = 3;
NO_StartProcess = 4;
NO_EndProcess = 5;
TotalInstances = 3;
var
{ Alle instanties van de dll die geinjecteerd worden in een window
krijgen eigen instanties van de volgende vars: }
{ Pointer naar de data die alle dll instanties delen }
GHookRecPtr: array[0..3] of PHookRec;
{ Handle naar de filemapping object }
GMapObject: THandle = 0;
{ Pointer naar oude wndproc }
GOldWndProc: Pointer = nil;
{ Handle naar Window die gesubclassed is }
GHandle: THandle = 0;
{ Laatst gebruikte Instance }
LastUsed : Integer;
procedure NotifyObserver(Msg, SubMsg: Integer);
begin
PostMessage(GHookRecPtr[LastUsed].RObserver, CM_NotifyObserver, Msg, SubMsg);
end;
procedure UnSubClass {(Handle: HWnd)};
begin
if (GOldWndProc <> nil) and (GHandle > 0) then
begin
SetWindowLongW(GHandle, GWL_WNDPROC, Longint(GOldWndProc));
NotifyObserver(NO_EndSubClassed, LongInt(GHandle));
GOldWndProc := nil;
GHandle := 0;
end;
end;
function getLastUsed : Integer;
Begin
Result := LastUsed;
End;
function WndProc(Wnd: HWND; Msg, WParam, LParam: Longint): Longint; stdcall;
var
ID, PID: DWORD;
begin
For ID := 0 to TotalInstances do
Begin
If GHookRecPtr[ID].WHandle = Wnd Then
Begin
LastUsed := ID;
Break;
End;
End;
with GHookRecPtr[LastUsed]^ do
begin
OutputDebugString(PChar(IntToStr(LastUsed)));
if (RObservedWindow = 0) and (RWantProcessID > 0) then
begin
GetWindowThreadProcessId(Wnd, @PID);
if PID <> RWantProcessID then
begin
Result := CallWindowProcW(GOldWndProc, Wnd, Msg, WParam, LParam);
UnSubClass {(Wnd)};
Exit;
end
else
begin
RObservedWindow := Wnd;
NotifyObserver(NO_ProcessIDFound, LongInt(Wnd));
end;
end;
//OutputDebugString(PChar(IntToStr(LastUsed)));
case Msg of
WM_NULL:
if (WParam = $15) and (LParam = $15) then
begin
UnSubClass;
Result := 0;
Exit;
end;
WM_SYSCOMMAND:
Begin
if (WParam = SC_CLOSE) or (WParam = 61539) then
begin
//OutputDebugString(PChar(IntToStr(LastUsed)));
NotifyObserver(NO_ClosePrevented, LongInt(Msg));
Result := 0;
Exit;
end else
If (WParam = SC_MINIMIZE) Then
Begin
// PostMessage(GHookRecPtr.RObserver, WM_HCBT_MINMAX, Wnd, lParam);
End;
End;
WM_COMMAND:
if (WParam = 40993) or (WParam = 106529) then
begin
NotifyObserver(NO_ClosePrevented, LongInt(Msg));
Result := 0;
Exit;
end;
end;
Result := CallWindowProcW(GOldWndProc, Wnd, Msg, WParam, LParam);
end;
end;
procedure SubClass(Handle: Hwnd);
begin
GHandle := Handle;
GOldWndProc := Pointer(GetWindowLong(Handle, GWL_WNDPROC));
SetWindowLongW(Handle, GWL_WNDPROC, Longint(@WndProc));
NotifyObserver(NO_BeginSubClassed, LongInt(Handle));
end;
procedure SetObserver(Handle: HWnd);
begin
GHookRecPtr[LastUsed].RObserver := Handle;
end;
function GetClassNameWnd(Wnd: HWND): string;
begin
SetLength(Result, 80);
SetLength(Result, GetClassName(Wnd, PChar(Result), Length(Result)));
end;
function HookProc(Code: Integer; WParam, LParam: Longint): Longint;
stdcall;
var
ExStyle: LongInt;
begin
if (Code = HCBT_CREATEWND) and (GHookRecPtr[LastUsed].RObservedWindow = 0) Then
begin
ExStyle := GetWindowLong(WParam, GWL_EXSTYLE);
if (ExStyle = 256) and (CompareText(GetClassNameWnd(WParam), 'ieframe') = 0)
then
begin
SubClass(WParam);
GHookRecPtr[LastUsed].WHandle := WParam;
End;
end;
if (code <= 0) then Result := CallNextHookEx(GHookRecPtr[LastUsed].RHookID, Code, WParam, LParam) else result := 0;
end;
procedure SetWantProcessID(ID: Integer; AProcessID: DWORD);
begin
GHookRecPtr[ID].RWantProcessID := AProcessID;
end;
procedure SetHook;
Var ID : Integer;
begin
for ID := 0 to TotalInstances do
Begin
if GHookRecPtr[ID].RHookID = 0 Then
Begin
LastUsed := ID;
break;
End;
End;
with GHookRecPtr[LastUsed]^ do
begin
RWantProcessID := 0;
RObservedWindow := 0;
RHookID := SetWindowsHookEx(WH_CBT, @HookProc, HInstance, 0);
end;
end;
procedure UnSetHook;
begin
UnHookWindowsHookEx(GHookRecPtr[LastUsed].RHookID);
end;
function getProcessID : Integer;
Begin
Result := GHookRecPtr[LastUsed]^.RWantProcessID;
End;
function getHandle(ID: Integer) : THandle;
Begin
Result := GHookRecPtr[ID]^.RObservedWindow;
End;
exports
SetHook,
UnSetHook,
SetObserver,
getHandle,
getLastUsed,
getProcessID,
SetWantProcessID;
procedure EntryPointProc(Reason: Integer);
begin
case reason of
DLL_PROCESS_ATTACH:
begin
GMapObject := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
SizeOf(THookRec), 'CaptureDesktopEvents');
GHookRecPtr[0] := MapViewOfFile(GMapObject, FILE_MAP_WRITE, 0, 0, 0);
GHookRecPtr[1] := MapViewOfFile(GMapObject, FILE_MAP_WRITE, 0, 0, 0);
GHookRecPtr[2] := MapViewOfFile(GMapObject, FILE_MAP_WRITE, 0, 0, 0);
GHookRecPtr[3] := MapViewOfFile(GMapObject, FILE_MAP_WRITE, 0, 0, 0);
NotifyObserver(NO_StartProcess, 0);
end;
DLL_PROCESS_DETACH:
begin
UnSubClass;
NotifyObserver(NO_EndProcess, 0);
try
if GHookRecPtr[0] <> nil then
UnMapViewOfFile(GHookRecPtr[0]);
if GHookRecPtr[1] <> nil then
UnMapViewOfFile(GHookRecPtr[1]);
if GHookRecPtr[2] <> nil then
UnMapViewOfFile(GHookRecPtr[2]);
if GHookRecPtr[3] <> nil then
UnMapViewOfFile(GHookRecPtr[3]);
if GMapObject <> 0 then
CloseHandle(GMapObject);
except
end;
end;
end;
end;
begin
DllProc := @EntryPointProc;
EntryPointProc(DLL_PROCESS_ATTACH);
DisableThreadLibraryCalls(HInstance);
end. |
Je zit dat ik nu de GHookRecPtr in een array heb staan, dus kunnen er meerdere instances worden geobserveerd. Opzich wil dit al goed maar...
In de functie SetHook:
RHookID := SetWindowsHookEx(WH_CBT, @HookProc, HInstance, 0);
Bij deze regel, regel 192, zet hij niet alleen de RHookID van de
with GHookRecPtr[LastUsed]^ do
Op de resultwaarde, maar van alle array-items zet hij de HookID op die waarde. Waardoor het allemaal fout gaat.
Hoe kan dat?? Dat hij meteen alles veranderd?
Ik heb dus GHookRecPtr[0] tm GHookRecPtr[3] maar hij past meteen alle RHookID`s aan.
Ook als ik dit heb:
GHookRecPtr[0].RHookID := 10;
wordt GHookRecPtr[1].RHookID ook 10, en 2 en 3 ook
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
1
2
3
4
5
6
| GMapObject := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
SizeOf(THookRec), 'CaptureDesktopEvents');
GHookRecPtr[0] := MapViewOfFile(GMapObject, FILE_MAP_WRITE, 0, 0, 0);
GHookRecPtr[1] := MapViewOfFile(GMapObject, FILE_MAP_WRITE, 0, 0, 0);
GHookRecPtr[2] := MapViewOfFile(GMapObject, FILE_MAP_WRITE, 0, 0, 0);
GHookRecPtr[3] := MapViewOfFile(GMapObject, FILE_MAP_WRITE, 0, 0, 0); |
even uit de losse pols (dus niet getest)
1
2
3
4
5
6
7
8
9
10
| TPartHookRec = record
RObserver: THandle;
RObservedWindow: THandle;
RHookID: HHOOK;
RWantProcessID: DWORD;
end;
THookRec = record
Hooks : array[0..2] of TPartHookRec
end; |
Maar still met probleempjes
Ik heb het nu zo aangepast dus:
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
| library Capture;
uses
Windows,
CommCtrl,
Messages,
SysUtils;
{$R *.RES}
type
PHookRec = ^THookRec;
TPartHookRec = record
RObserver: THandle;
RObservedWindow: THandle;
RHookID: HHOOK;
WHandle: HWND;
RWantProcessID: DWORD;
end;
THookRec = record
Hooks : Array[0..1] of TPartHookRec;
end;
const
CM_NotifyObserver = WM_USER + 1;
CM_NotifyObserverMsg = WM_USER + 2;
WM_HCBT_MINMAX = WM_USER + 285;
NO_BeginSubClassed = 0;
NO_EndSubClassed = 1;
NO_ProcessIDFound = 2;
NO_ClosePrevented = 3;
NO_StartProcess = 4;
NO_EndProcess = 5;
TotalInstances = 2;
var
{ Alle instanties van de dll die geinjecteerd worden in een window
krijgen eigen instanties van de volgende vars: }
{ Pointer naar de data die alle dll instanties delen }
GHookRecPtr: PHookRec;
{ Handle naar de filemapping object }
GMapObject: THandle = 0;
{ Pointer naar oude wndproc }
GOldWndProc: Pointer = nil;
{ Handle naar Window die gesubclassed is }
GHandle: THandle = 0;
{ Laatst gebruikte Instance }
LastUsed : Integer;
procedure NotifyObserver(Msg, SubMsg: Integer);
begin
PostMessage(GHookRecPtr.Hooks[0].RObserver, CM_NotifyObserver, Msg, SubMsg);
end;
procedure UnSubClass {(Handle: HWnd)};
begin
if (GOldWndProc <> nil) and (GHandle > 0) then
begin
SetWindowLongW(GHandle, GWL_WNDPROC, Longint(GOldWndProc));
NotifyObserver(NO_EndSubClassed, LongInt(GHandle));
GOldWndProc := nil;
GHandle := 0;
end;
end;
function getLastUsed : Integer;
Begin
Result := LastUsed;
End;
Function getSetLastUsed(Wnd: HWND): Word;
Var ID: Word;
Begin
For ID := 0 to TotalInstances - 1 do
Begin
If GHookRecPtr.Hooks[ID].WHandle = Wnd Then
Begin
Result := ID;
// OutputDebugString(PChar('SET LastUsed to: ' + IntToStr(ID)));
Break;
End;
End;
End;
function WndProc(Wnd: HWND; Msg, WParam, LParam: Longint): Longint; stdcall;
var
PID: DWORD;
LocalLastUsed: Word;
begin
LocalLastUsed := getSetLastUsed(Wnd);
with GHookRecPtr^.Hooks[LocalLastUsed] do
begin
//OutputDebugString(PChar(IntToStr(LastUsed)));
if (RObservedWindow = 0) and (RWantProcessID > 0) then
begin
GetWindowThreadProcessId(Wnd, @PID);
if PID <> RWantProcessID then
begin
Result := CallWindowProcW(GOldWndProc, Wnd, Msg, WParam, LParam);
UnSubClass {(Wnd)};
Exit;
end
else
begin
RObservedWindow := Wnd;
NotifyObserver(NO_ProcessIDFound, LongInt(Wnd));
end;
end;
//OutputDebugString(PChar(IntToStr(LastUsed)));
case Msg of
WM_NULL:
if (WParam = $15) and (LParam = $15) then
begin
UnSubClass;
Result := 0;
Exit;
end;
WM_SYSCOMMAND:
Begin
if (WParam = SC_CLOSE) or (WParam = 61539) then
begin
//OutputDebugString(PChar(IntToStr(LastUsed)));
NotifyObserver(NO_ClosePrevented, LongInt(Msg));
Result := 0;
Exit;
end else
If (WParam = SC_MINIMIZE) Then
Begin
// PostMessage(GHookRecPtr.RObserver, WM_HCBT_MINMAX, Wnd, lParam);
End;
End;
WM_COMMAND:
if (WParam = 40993) or (WParam = 106529) then
begin
NotifyObserver(NO_ClosePrevented, LongInt(Msg));
Result := 0;
Exit;
end;
end;
Result := CallWindowProcW(GOldWndProc, Wnd, Msg, WParam, LParam);
end;
end;
procedure SubClass(Handle: Hwnd);
begin
GHandle := Handle;
GOldWndProc := Pointer(GetWindowLong(Handle, GWL_WNDPROC));
SetWindowLongW(Handle, GWL_WNDPROC, Longint(@WndProc));
NotifyObserver(NO_BeginSubClassed, LongInt(Handle));
end;
procedure SetObserver(Handle: HWnd);
begin
GHookRecPtr.Hooks[LastUsed].RObserver := Handle;
end;
function GetClassNameWnd(Wnd: HWND): string;
begin
SetLength(Result, 80);
SetLength(Result, GetClassName(Wnd, PChar(Result), Length(Result)));
end;
function HookProc(Code: Integer; WParam, LParam: Longint): Longint;
stdcall;
var
ExStyle: LongInt;
Begin
OutputDebugString(PChar(IntToStr(LastUsed) + ' - ' +
IntToStr(GHookRecPtr.Hooks[LastUsed].RObservedWindow) + ' - ' +
IntToStr(Code)));
if (Code = HCBT_CREATEWND) and (GHookRecPtr.Hooks[LastUsed].RObservedWindow = 0) Then
begin
ExStyle := GetWindowLong(WParam, GWL_EXSTYLE);
if (ExStyle = 256) and (CompareText(GetClassNameWnd(WParam), 'ieframe') = 0) then
begin
SubClass(WParam);
GHookRecPtr.Hooks[LastUsed].WHandle := WParam;
Result := 0;
Exit;
// OutputDebugString(PChar(IntToStr(GHookRecPtr.Hooks[LastUsed].WHandle)));
End;
end;
if (code <= 0) then
Result := CallNextHookEx(GHookRecPtr.Hooks[LastUsed].RHookID, Code, WParam, LParam)
else result := 0;
end;
procedure SetHook;
Var ID : Integer;
begin
for ID := 0 to TotalInstances do
Begin
if GHookRecPtr.Hooks[ID].RHookID = 0 Then
Begin
LastUsed := ID;
break;
End;
End;
with GHookRecPtr^.Hooks[LastUsed] do
begin
OutputDebugString(PChar('SetHook: ' + IntToStr(LastUsed)));
RWantProcessID := 0;
RObservedWindow := 0;
RHookID := SetWindowsHookEx(WH_CBT, @HookProc, HInstance, 0);
End;
end;
procedure SetWantProcessID(ID: Integer; AProcessID: DWORD);
begin
GHookRecPtr.Hooks[ID].RWantProcessID := AProcessID;
end;
procedure UnSetHook;
begin
UnHookWindowsHookEx(GHookRecPtr.Hooks[LastUsed].RHookID);
end;
function getProcessID : Integer;
Begin
Result := GHookRecPtr^.Hooks[LastUsed].RWantProcessID;
End;
function getHandle(ID: Integer) : THandle;
Begin
Result := GHookRecPtr^.Hooks[ID].RObservedWindow;
End;
exports
SetHook,
UnSetHook,
SetObserver,
getHandle,
getLastUsed,
getProcessID,
SetWantProcessID;
procedure EntryPointProc(Reason: Integer);
begin
case reason of
DLL_PROCESS_ATTACH:
begin
GMapObject := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
SizeOf(THookRec), 'CaptureDesktopEvents');
GHookRecPtr := MapViewOfFile(GMapObject, FILE_MAP_WRITE, 0, 0, 0);
NotifyObserver(NO_StartProcess, 0);
end;
DLL_PROCESS_DETACH:
begin
UnSubClass;
NotifyObserver(NO_EndProcess, 0);
try
if GHookRecPtr <> nil then
UnMapViewOfFile(GHookRecPtr);
if GMapObject <> 0 then
CloseHandle(GMapObject);
except
end;
end;
end;
end;
begin
DllProc := @EntryPointProc;
EntryPointProc(DLL_PROCESS_ATTACH);
DisableThreadLibraryCalls(HInstance);
end. |
Ik heb de functie getSetLastUsed die de variabele lastUsed op de waarde zet die hij moet hebben.
Dat doet hij aan de hand van de window handle, die ook opgeslagen zit in het Hook record. Op die manier gebruikt hij het goede array element.
Maar hij doet iets niet goed.
Als ik kijk met OutPutDebugString dan blijft hij lastUsed op 0 zetten als de 'code' in de HookProc 3 is (Code = HCBT_CREATEWND).
Dus dan wordt hij niet nog een keer gehooked. Heel raar, maar hij blijft die lastUsed op 0 zetten. Als hij wel op 1 wordt gezet is dus de Code <> HVBT_CREATEWND, dus wordt hij ook niet gehooked. Ik hoop dat jullie het snappen. Hier een screenshot:
logfile
De waardes zijn: lastUsed - GHookRecPtr.Hooks[LastUsed].RObservedWindow) - IntToStr(Code)));
op regel 170 - 172
Daar ze je (op regel 2) dat die goed is: 0 - 0 - 3 (lastUsed op 0, ObservedWindow op 0 en Code = 3)
Maar vanaf SetHook: 1 gaat het mis. Daar zou het 1 - 0 - 3 moeten zijn, maar omdat hij daar lastUsed op 0 heeft staan, krijgt hij ook de verkeerde ObservedWindow, maar ik krijg de lastUsed dan dus niet goed.
Terwijl hij in setHook zeker wel op 1 wordt gezet. Je ziet ook dat hij verderop wel op 1 komt te staan.
Ik weet dat die 2 procedures (Hookproc en winproc) constant doorlopen, maar als de 2e window gemaakt wordt, dan moet hij toch zien dat hij het 2e record van het array moet pakken omdat daar de windowhandle het zelfde is? (getSetLastUsed)
[ Voor 19% gewijzigd door Guillome op 13-12-2003 14:35 ]
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
[ Voor 100% gewijzigd door Guillome op 13-12-2003 14:35 ]
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Op de een of andere manier wordt de variabele te laat op 1 gezet. Komt dat omdat deze hook door blijft gaan met zijn 1e aanroep zeg maar?[/quote]
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
een ander mogelijk probleem (hoewel dat in jouw geval niet op treedt) is
1
| RHookID := SetWindowsHookEx(WH_CBT, @HookProc, HInstance, 0); |
Als SetWindowsHookEx failed dat returned hij 0. Je controleerd daar niet op. Sterker, je gebruikt dat later om te zien of die ID al in gebruik is
1
| if GHookRecPtr.Hooks[ID].RHookID = 0 Then |
Als nou SetWindowsHookEx 0 returned dan blijft hij zeg maar altijd dezlfde ID gebruiken en zal nooit 'verder' komen
Hoe kan ik dan die variable geshared maken?
En over je 2e punt:
Ik controleer dat hiermee toch?
1
2
3
| if (code <= 0) then
Result := CallNextHookEx(GHookRecPtr.Hooks[LastUsed].RHookID, Code, WParam, LParam)
else result := 0; |
En moet ik ipv
1
| if GHookRecPtr.Hooks[ID].RHookID = 0 Then |
Dit gebruiken?
1
| if GHookRecPtr.Hooks[ID].RObservedWindow = 0 Then |
Of iets dergelijks?
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Door hem een member te maken van THookRec. Doordat je gebruik maakt van een memory mapped file is de instantie van THookRec geshared tussen applicaties. Ik weet dus niet of dat jouw bedoeling is omdat je hem nl expliciet niet in THookRec had gezet.Hoe kan ik dan die variable geshared maken?
1
2
3
4
| THookRec = record
Hooks : Array[0..1] of TPartHookRec;
LastUsed : Integer;
end; |
Nu is LastUsed een member van THookRec en zal elke applicatie die jouw dll geinjecteerd heeft gekregen dezelfde waarde gebruiken. Waar je wel op moet letten is dat omdat je een shared memory blok gebruikt je problemen gaat krijgen met multiple threads. Je hoort dus eigenlijk de access naar het shared memory te 'beveiligen' met een Mutex.
Wat ik bedoel is het volgende. In onderstaande code (uit SetHook) kijk je niet of SetWindowsHookEx 0 returned. 0 betekend dat het mis is gegaan.En over je 2e punt:
Ik controleer dat hiermee toch?
1
2
3
4
5
6
7
| with GHookRecPtr^.Hooks[LastUsed] do
begin
OutputDebugString(PChar('SetHook: ' + IntToStr(LastUsed)));
RWantProcessID := 0;
RObservedWindow := 0;
RHookID := SetWindowsHookEx(WH_CBT, @HookProc, HInstance, 0);
End; |
echter in dezelfe routine ( SetHook) doe je
1
2
3
4
5
6
7
8
| for ID := 0 to TotalInstances do
Begin
if GHookRecPtr.Hooks[ID].RHookID = 0 Then
Begin
LastUsed := ID;
break;
End;
End; |
Je kijkt dus of er 0 in staat. Zo ja dan gebruik je hem. Echter als SetWindowsHookEx mis gaat is het altijd 0. Op zich hoeft dat niet erg te zijn want hij blijft dan steeds dezelde gebruiken. Het is echter beter om te controleren of SetWindowsHookEx 0 returned zodat je weet dat er wat mis gaat. Wat ik al zei is dat het niet verkeerd is wat je doet. Het is alleen handiger om te zien dat SetWindowsHookEx fout gaat.
Hij werkt nu prima
Inderdaad door LastUsed in de GHookRecPtr te zetten. Nu wertk hij prima.
Maar aangezien ik niet veel thuis ben (was
Wat voor soort problemen? Wanneer heb ik multiple threads? En wat is een mutex?Waar je wel op moet letten is dat omdat je een shared memory blok gebruikt je problemen gaat krijgen met multiple threads. Je hoort dus eigenlijk de access naar het shared memory te 'beveiligen' met een Mutex.
Echt enorm bedantk alvast!!! Superb!
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
intro threads en Delphi (aanrader)
http://www.pergolesi.demon.co.uk/prog/threads/ToC.html
Nu nog 1 klein vraagje, maar ik zie zelf de oplossing niet.
Ik heb nu ook een scherm gemaakt waarin je alle geopende internet explorer vensters ziet, met de windowhandle. (dus niet alleen de door-mijn-app-geopende-ievensters, maar ook die al open waren etc)
En nu wil ik dat ik zo`n al-geopende-Internet explorere kan laten 'observeren' door mijn programma. Maar ik zie niet echt hoe de dll de net-geopende (door mijn prog) IE pakt.
Is het de HInstance in
1
| RHookID := SetWindowsHookEx(WH_CBT, @HookProc, HInstance, 0); |
in setHook die het hem doet? En dat dat dus niet kan met een IE die door de gebruiker zelf gestart is?
[ Voor 30% gewijzigd door Guillome op 14-12-2003 23:24 ]
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
1
| GetWindowLong(hWnd, GWL_WNDPROC) |
Hoe kan dat? Geen enkele GetWindow___ (functie werkt (getwindowlong, getwindowstyle etc)
Hoe kan dat? GetLastError geeft 5. Ik kan daar de betekenis niet van vinden, omdat er in windows.pas alleen foutnummers van 1400 tot 1420 ofzo staan.
Ik had eerst 1400, en dat is het verkeerde windowhandle, en dat klopte wel. Maar nu die goed is gezet geeft hij 5, en doet het nog steeds niet.
Mijn IE-list code:
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
| unit IEList;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, ImgList, ExtCtrls;
type
TfIEList = class(TForm)
Button1: TButton;
IExplorers: TListView;
ImageList1: TImageList;
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure getList;
procedure IExplorersDblClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
fIEList: TfIEList;
implementation
uses capture2;
{$R *.DFM}
procedure SubClass(Handle: Hwnd); external 'Capture.dll';
procedure SetHook; external 'Capture.dll';
procedure makeObserverable(ProcessId: Integer; Handle: HWND); external 'Capture.dll';
Function EnumWindProc(hWnd: Thandle; lParam: LPARAM): BOOL; stdcall;
function ItemExists(hWnd: Integer): Boolean;
var Item : TListItem;
Begin
Result := false;
Item := fIEList.IExplorers.Items[0];
While Item <> nil do
Begin
If Item.SubItems[0] = IntToStr(hWnd) Then
Begin
Result := True;
Exit;
End;
Item := fIEList.IExplorers.GetNextItem(Item, sdAll, [isNone]);
End;
End;
var s: array[byte] of Char;
s2: string;
Item: TListItem;
ProcessId: Integer;
begin
GetWindowText(hWnd, @s, 255);
s2 := s;
If (pos(' - Microsoft Internet Explorer', s2) > 0) and (not ItemExists(hWnd)) Then
Begin
Item := fIEList.IExplorers.Items.Add();
SetLength(s2, Length(s2) - 30);
Item.Caption := s2;
Item.SubItems.Add(IntToStr(hWnd));
GetWindowThreadProcessId(hWnd, @ProcessId);
Item.SubItems.Add(IntToStr(ProcessId));
End;
Result := True;
end;
Procedure TfIEList.getList;
var Item : TListItem;
ItemIndex: Word;
s: array[byte] of Char;
s2: string;
ProcessId: Integer;
Begin
Item := fIEList.IExplorers.Items[0];
While Item <> nil do
Begin
ProcessId := GetWindowThreadProcessId(StrToInt(Item.SubItems[0]), nil);
If (ProcessId = 0) Then
Begin
ItemIndex := Item.Index;
Item.Delete;
Item := fIEList.IExplorers.Items[ItemIndex];
End else
Begin
GetWindowText(StrToInt(Item.SubItems[0]), @s, 255);
s2 := s;
SetLength(s2, Length(s2) - 30);
If (Item.Caption <> s2) then Item.Caption := s2;
End;
Item := fIEList.IExplorers.GetNextItem(Item, sdAll, [isNone]);
End;
EnumWindows(@EnumWindProc, 0);
End;
procedure TfIEList.Timer1Timer(Sender: TObject);
begin
getList;
end;
procedure TfIEList.FormCreate(Sender: TObject);
begin
getList;
end;
procedure TfIEList.IExplorersDblClick(Sender: TObject);
Var Style: Integer;
begin
If IExplorers.Selected = nil Then Exit;
//ShowMessage(IntToStr(GetWindowLong(StrToInt(IExplorers.Selected.SubItems[0]), GWL_STYLE)));
Style := GetWindowLong(StrToInt(IExplorers.Selected.SubItems[0]), GWL_STYLE);
If (Style = 114229248) or (Style = 919535616) or (Style = 651100160) Then
ShowWindow(StrToInt(IExplorers.Selected.SubItems[0]), SW_SHOWNORMAL or SW_RESTORE);
SetForegroundWindow(StrToInt(IExplorers.Selected.SubItems[0]));
end;
procedure TfIEList.Button1Click(Sender: TObject);
var wHandle: Integer;
s: array[byte] of char;
begin
wHandle := StrToInt(IExplorers.Selected.SubItems[0]);
GetWindowText(wHandle, @s, 255);
ShowMessage(IntToStr(GetWindowLong(FindWindow('ieframe', nil), GWL_WNDPROC)));
ShowMessage(IntToStr(GetWindowLong(wHandle, GWL_WNDPROC)));
makeObserverable(StrToInt(IExplorers.Selected.SubItems[1]), StrToInt(IExplorers.Selected.SubItems[0]));
end;
end. |
Wat zie ik over het hoofd?
Hier de files incl .exe:
http://xlerator.beefhole.nl/webstuff/hooking.rar
[ Voor 8% gewijzigd door Guillome op 15-12-2003 00:52 ]
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
- hardware always changes.. -
En dus de wndProc?
Blah
Ik zie dat het wel zou moeten kunnen met CreateRemoteThread, maar ik snap nix van hoe ik een functie in die thread kan zetten.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| procedure TfIEList.Button1Click(Sender: TObject);
var wHandle, pId: Integer;
InitDataAddr, WriteAddr: Pointer;
TheadID: DWord;
// s: array[byte] of char;
begin
wHandle := StrToInt(IExplorers.Selected.SubItems[0]);
pId := StrToInt(IExplorers.Selected.SubItems[1]);
OpenProcess(PROCESS_CREATE_THREAD, false, pId);
CreateRemoteThread(pId, nil, 0, WriteAddr, InitDataAddr, 0, TheadID);
// SendMessage(wHandle, WM_GETICON
// GetWindowText(wHandle, @s, 255);
//ShowMessage(IntToStr(GetWindowLong(FindWindow('ieframe', nil), GWL_WNDPROC)));
// ShowMessage(IntToStr(GetWindowLong(wHandle, GWL_WNDPROC)));
makeObserverable(StrToInt(IExplorers.Selected.SubItems[1]), StrToInt(IExplorers.Selected.SubItems[0]));
end; |
Maar nu? Ik heb op google gezocht, op GoT en op Pascal gebruikers groep. Maar geen resultaat
edit2: en uiteraard de help
[ Voor 88% gewijzigd door Guillome op 15-12-2003 22:23 ]
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Een voorbeeld van CreateRemoteThread staat op:
http://www.codeproject.com/system/hooksys.asp
Nadeel is wel dat het alleen werkt onder WINNT, 2K (XP denk ik ook)
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
| procedure TfIEList.Button1Click(Sender: TObject);
var wHandle, pId: Integer;
pfnLoadLibrary: Pointer;
ThreadID, Tmp, dllModule: DWord;
Process: THandle;
dllpath: array[0..255] of Char;
begin
wHandle := StrToInt(IExplorers.Selected.SubItems[0]);
pId := StrToInt(IExplorers.Selected.SubItems[1]);
dllpath := 'D:\\Data\\DELPHI\\testshellcatch3\\capture.dll';
OpenProcess(PROCESS_ALL_ACCESS, false, pId);
pfnLoadLibrary := VirtualAllocEx(pId, nil, sizeof(dllpath), MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(pId, pfnLoadLibrary, @dllpath, sizeof(dllpath), Tmp);
Process := CreateRemoteThread(Process, nil, 0, GetProcAddress(GetModuleHandle('Kernel32'), 'LoadLibraryA'),
pfnLoadLibrary, 0, ThreadID);
WaitForSingleObject(Process, INFINITE);
GetExitCodeThread(Process, dllModule);
CloseHandle(Process);
VirtualFreeEx(Process, pfnLoadLibrary, sizeof(dllpath), MEM_RELEASE);
// SendMessage(wHandle, WM_GETICON
// GetWindowText(wHandle, @s, 255);
//ShowMessage(IntToStr(GetWindowLong(FindWindow('ieframe', nil), GWL_WNDPROC)));
// ShowMessage(IntToStr(GetWindowLong(wHandle, GWL_WNDPROC)));
ShowMessage(IntToStr(ThreadID));
makeObserverable(StrToInt(IExplorers.Selected.SubItems[1]), StrToInt(IExplorers.Selected.SubItems[0]));
end; |
Maar ik kan nergens vinden hoe ik nu een functie kan starten in de ge-attachte dll
[ Voor 156% gewijzigd door Guillome op 16-12-2003 17:13 ]
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Voordat ik uren ermee bezig ben lijkt het me handig om te vragen of dit is wat het doet. Het kwam van een duitse site
http://www.delphipraxis.net/topic13066,45.html
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
| type
PHookData = ^THookData;
THookData = packed record
WndProc: array[0..255] of Byte;
ThreadProc: array[0..255] of Byte;
GetWindowLong: function(Wnd: hWnd; Index: Integer): Pointer; stdcall;
SetWindowLong: function(Wnd: hWnd; Index: Integer; Value: Pointer): Pointer; stdcall;
ExitThread: procedure(ExitCode: DWord); stdcall;
CallWindowProc: function(PrevFunc: Pointer; Wnd: hWnd; Msg,wParam,lParam: Integer): Integer; stdcall;
VirtualFree: function(Address: Pointer; Size,FreeType: DWord): Bool; stdcall;
MessageBox: function(Wnd: hWnd; Text,Caption: PChar; Flag: DWord): Integer; stdcall;
SaveWindowProc: Pointer;
Wnd: hWnd;
MsgText,MsgTitle: array[0..127] of Char;
end;
function GetProcAddr(Module: hModule; Name: PChar): Pointer;
asm
XOR ECX,ECX // except frame
PUSH OFFSET @@6
PUSH DWord Ptr FS:[ECX]
MOV FS:[ECX],ESP
PUSH EBP
PUSH EBX
MOV EBP,EDX
AND EAX,not 3
PUSH EDI
MOV EDX,[EAX + 03Ch]
PUSH ESI
TEST EBP,EBP
JZ @@5
CMP Word Ptr [EAX + EDX],'EP'
MOV EDX,[EAX + EDX + 078h]
JNZ @@5
ADD EDX,EAX
TEST EBP,0FFFF0000h
MOV EBX,EAX
JZ @@3 // import by ordinal ??
MOV EAX,[EDX + 018h]
MOV ECX,[EDX + 020h]
NOT EAX
@@1: INC EAX
MOV ESI,EBP
JZ @@4
MOV EDI,[EBX + ECX]
ADD ECX,4
ADD EDI,EBX
@@2: CMPSB
JNE @@1
CMP Byte Ptr [ESI - 1],0
JNE @@2
ADD EAX,[EDX + 018h]
MOV ECX,[EDX + 024h]
ADD ECX,EBX
MOVZX EBP,Word Ptr [ECX + EAX * 2]
INC EBP
@@3: MOV ECX,[EDX + 01Ch]
DEC EBP
ADD ECX,EBX
MOV EAX,[ECX + EBP * 4]
ADD EAX,EBX
@@4: POP ESI
POP EDI
POP EBX
POP EBP
POP DWord Ptr FS:[0]
POP ECX
RET
@@5: XOR EAX,EAX
JMP @@4
@@6: MOV EAX,[ESP + 00Ch] // except handler
PUSH OFFSET @@5
POP DWord Ptr [EAX + 0B8h]
SUB EAX,EAX
end;
function MyWndProc(Memory: PHookData; Wnd: hWnd; Msg,wParam,lParam: Integer): Integer; stdcall; forward;
procedure WndProcDispatcher;
asm
CALL @@1
@@1: POP EAX
SUB EAX,5
POP EDX
PUSH EAX
PUSH EDX
JMP MyWndProc
end;
function MyWndProc(Memory: PHookData; Wnd: hWnd; Msg,wParam,lParam: Integer): Integer; stdcall;
const
MemorySize = SizeOf(THookData);
begin
if Msg = wm_Destroy then
begin
Result := Memory.CallWindowProc(Memory.SaveWindowProc, Wnd, Msg, wParam, lParam);
asm
MOV EAX,Memory
POP EBX // Delphi push it
POP EBP // Delphi stackframe
POP EDX // Return address caller
POP ECX // 5 paramters Memory,Wnd,Msg,wParam,lParam
POP ECX
POP ECX
POP ECX
POP ECX
PUSH EAX // VirtualFree() params
PUSH MemorySize
PUSH 0
PUSH EDX // VirtualFree() returns back to our caller
JMP [EAX].THookData.VirtualFree
end;
end else
if (Msg = wm_Close) or (Msg = wm_Quit) then
begin
Result := 0;
Memory.MessageBox(0, Memory.MsgText, Memory.MsgTitle, 0);
end else
Result := Memory.CallWindowProc(Memory.SaveWindowProc, Wnd, Msg, wParam, lParam);
end;
function ThreadProc(Memory: PHookData): DWord; stdcall;
const
MemorySize = SizeOf(THookData);
begin
Memory.SaveWindowProc := Memory.GetWindowLong(Memory.Wnd, gwl_WndProc);
if Memory.SaveWindowProc <> nil then // hier eventuell Param für ExitThread setzen
Memory.SetWindowLong(Memory.Wnd, gwl_WndProc, Memory);
Memory.ExitThread(0);
end;
procedure SubClass(Wnd: hWnd);
var
CodeSize: Integer;
Process: THandle;
ProcessID: DWord;
Thread: THandle;
ThreadID: DWord;
Memory: PHookData;
DLL: hModule;
Temp: THookData;
Bytes: DWord;
begin
if not IsWindow(Wnd) then Exit;
GetWindowThreadProcessID(Wnd, @ProcessID);
if ProcessID = 0 then Exit;
Process := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_CREATE_THREAD, False, ProcessID);
if Process <> 0 then
begin
Memory := VirtualAllocEx(Process, nil, SizeOf(THookData), MEM_COMMIT, PAGE_READWRITE);
if Memory <> nil then
begin
CodeSize := PChar(@ThreadProc) - PChar(@WndProcDispatcher);
Move(WndProcDispatcher, Temp.WndProc, CodeSize);
CodeSize := PChar(@SubClass) - PChar(@ThreadProc);
Move(ThreadProc, Temp.ThreadProc, CodeSize);
DLL := GetModuleHandle('user32.dll');
Temp.GetWindowLong := GetProcAddr(DLL, 'GetWindowLongA');
Temp.SetWindowLong := GetProcAddr(DLL, 'SetWindowLongA');
Temp.CallWindowProc := GetProcAddr(DLL, 'CallWindowProcA');
Temp.MessageBox := GetProcAddr(DLL, 'MessageBoxA');
DLL := GetModuleHandle('kernel32.dll');
Temp.ExitThread := GetProcAddr(DLL, 'ExitThread');
Temp.VirtualFree := GetProcAddr(DLL, 'VirtualFree');
Temp.Wnd := Wnd;
Temp.MsgText := 'Want close';
Temp.MsgTitle := 'Test';
if WriteProcessMemory(Process, Memory, @Temp, SizeOf(THookData), Bytes) then
begin
Thread := CreateRemoteThread(Process, nil, 0, @Memory.ThreadProc, Memory, 0, ThreadID);
if Thread <> 0 then
begin
WaitForSingleObject(Thread, INFINITE);
// hier eventuell ExitCode vom Thread auswerten
MessageBox(Application.Handle, 'Hooked successfull', 'SubClass()', 0);
CloseHandle(Thread);
end;
end else
begin
VirtualFreeEx(Process, Memory, SizeOf(THookData), 0);
end;
end;
CloseHandle(Process);
end;
end;
procedure TestSubClass;
function MyEnum(Wnd: hWnd; Return: PInteger): Bool; stdcall;
var
ClassName: String;
ProcessID: DWord;
begin
Result := True;
SetLength(ClassName, MAX_PATH);
SetLength(ClassName, GetClassname(Wnd, PChar(ClassName), Length(ClassName)));
if ClassName = 'TConsoleMainForm' then
begin
GetWindowThreadProcessID(Wnd, @ProcessID);
if GetCurrentProcessID <> ProcessID then
begin
Return^ := Wnd;
Result := False;
end;
end;
end;
var
Wnd: Integer;
begin
Wnd := 0;
EnumWindows(@MyEnum, Integer(@Wnd));
SubClass(Wnd);
end; |
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Ik kom er zelf echt niet meer uit hoor
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
http://www.madshi.net
Nou kan het zijn dat je zelf alle code-hooking wil doen (ik weet niet precies wat je doel is) maar zoals je hebt ondervonden is dat vrij lastig. Als ik nog tijd heb zal ik nog even naar je probleem kijken hoewel het vrij lastige materie is en ik niet heel veel tijd heb (sterker ik ga dinsdag op vakantie
En mijn doel? Ik wil dit programma werkend hebben omdat ik het zelf wil gebruiken, en ook op internet wil verspreiden als Freeware, net als HandyFTP (zie sig voor website) en RegRunner.
Ik ben zo`n iemand die al zijn code het liefst zelf maakt. Ik heb bijna alles wat ik gemaakt heb zelf geschreven. Maar zoals dit.... dit is voor mij op dit moment nog niet te doen, dus ik zal kijken naar die pagina. Heel erg bedankt alvast en ik hoop dat je me straks verder kan helpen
Maar eerst veel plezier dindsdag!
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Zo werkt hij nog steeds niet:
1
2
3
4
5
6
7
8
9
10
| procedure TfIEList.Button1Click(Sender: TObject);
var t: procedure;
begin
If (IExplorers.Selected = nil) Then Exit;
InjectLibrary(StrToInt(IExplorers.Selected.SubItems[1]), 'capture.dll', 7000);
@t := GetProcAddress(GetModuleHandle('capture.dll'), 'makeObservable');
t;
//makeObservable(StrToInt(IExplorers.Selected.SubItems[1]), StrToInt(IExplorers.Selected.SubItems[0]));
UninjectLibrary(StrToInt(IExplorers.Selected.SubItems[1]), 'capture.dll', 7000);
end; |
dll:
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
| ...
...
...
function makeObservable(pId, wHandle: Integer): Boolean;
Begin
OutputDebugString(PChar('asd' + IntTostr(GetWindowLong(wHandle, GWL_WNDPROC))));
End;
exports
makeObservable,
..,
..;
procedure EntryPointProc(Reason: Integer);
begin
case reason of
DLL_PROCESS_ATTACH:
begin
GMapObject := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
SizeOf(THookRec), 'CaptureDesktopEvents');
GHookRecPtr := MapViewOfFile(GMapObject, FILE_MAP_WRITE, 0, 0, 0);
NotifyObserver(NO_StartProcess, 0);
end;
DLL_PROCESS_DETACH:
begin
UnSubClass;
NotifyObserver(NO_EndProcess, 0);
try
if GHookRecPtr <> nil then
UnMapViewOfFile(GHookRecPtr);
if GMapObject <> 0 then
CloseHandle(GMapObject);
except
end;
end;
end;
end;
begin
DllProc := @EntryPointProc;
EntryPointProc(DLL_PROCESS_ATTACH);
DisableThreadLibraryCalls(HInstance);
end. |
[ Voor 4% gewijzigd door Guillome op 22-12-2003 00:41 ]
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Je moet nl subclassen in je hook dll omdat winproc adres etc. alleen maar valide is in het process dat je wil hooken. Nou zijn er verschillende manieren voor om dat voor elkaar te krijgen. Een daarvan is dat je de subclassing doet in je hookproc als je ziet dat je nog niet hebt gesubclassed (volgens mij doe je dat in je hook dll). Wat ik niet zo goed snap is wat je wil met makeObserverable. Daarin roep je nl weer SubClass aan. Het probleem hiermee is dat subclass dan wordt aangeroepen in de context van jouw applicatie en niet van IE. Je moet er dus op de een of andere manier voor zorgen dat je kan communiceren met de dll instanties die geinjecteerd zijn in de verschillende processen zodat je per dll kan 'vertellen' wat er moet gebeuren. Je moet onthouden dat het injecteren van een dll in een ander process ervoor zorgt dat er ook daadwerkelijk verschillende instanties zijn van de hook dll.
Ik roep in mijn app "setHook" aan in de dll, en vanuit daar wordt er ge-setWindowHook-t, en gesubclassed.
Alleen als ik nu injectLibrary doe, dan wil die makeObservable nog niet.
Er staat nu alleen nog maar een regel getWindowLong in om te kijken of hij dat pakt. Zo ja, dan wil de rest ook wel. Maar hij blijft `m uitvoeren vanuit mijn eigen app, dus returnt getWindowLong altijd 0
Met MakeObservable wil ik een bestaande IE venster ook gesubclassed krijgen.
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Maar het gaat om de vensters die (nog) niet gesubclassed zijn he?MakeObservableMessage sturen naar de window handle die je al had gesubclassed
Of bedoel jij dat getWindowLong op deze manier (vanuit de overige IE processen) wel werkt?
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Ik kan met mijn programma IE instancies opstarten (createProcess), en met die vensters kan ik met getWindowLong de wndProc opvragen, en vervangen met SetWindowLong.
Alleen, vensters die ik niet geopend heb met mijn programma, maar die opgestart zijn door de gebruiker zelf, daarvan kan ik de wndProc niet opvragen met getWindowLong.
Vandaar dat mijn DLL dan geinjecteerd moet worden in dat IExplorer venster, en dan subclassen.
Maar ik weet niet ik een functie moet starten van de geinjecteerde dll, of wat de dll doet als hij geinjecteerd wordt.
Hier m`n programmatje tot nu toe, dan heb je misschien even een iets helderder beeld
http://xlerator.beefhole.nl/webstuff/IE starter.rar
Start een IE in het menu (IE venster openen), en dan in het menu op de naam klikken.
[ Voor 22% gewijzigd door Guillome op 22-12-2003 16:13 ]
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Als je nou IE opstart nadat je jouw programma (Starter) hebt gestart dan zie je wel dat je dll is geinjecteerd. Maar ook nu kan ik het IE window nog closen. Of je window is niet ge-subclassed of er gaat was mis in je HookProc.
Het 1e probleem kan je oplossen door gebruik te maken van een andere manier van Hooken. Bijv. door de Madshi library of door WH_GETMESSAGE hook want elke app heeft in iedergeval een message queue.
PS. Om te zien of jouw dll is geinjecteerd kan je gebruik maken van 'attach process' in Delphi. Je kiest dan IExplorer.exe en attach. Je kan nu mbv vies->debug windows->modules alle dll's zien die in het process zijn geladen. Nadeel is dat als je je app in delphi dan closed je ook de attached proc closed.
Klopt, dit staat ook niet in de codeTijnFLiP schreef op 22 december 2003 @ 17:25:
Ik zie twee 'problemen' met jouw code. Als er al IE windows open zijn voordat je jouw programma opstart dan wordt jouw dll (nog) niet geinjecteerd in de al bestaande IE processen (kan je zien mbv attach process in delphi en dan show modules).
Dat komt zeker omdat de vensters die het progje zelf opent, bezig is met starten, en daardoor de hookproc aanroept? Want dat werkt allemaal wel gewoon goed.Echter wanneer je dan een window opent in het al bestaande IE process (bijv. Tools->Internet Options) dan wordt de dll wel geinjecteerd. De rede hiervan is dat de WH_CBT hook pas iets doet wanneer er iets gebeurd met windows (kan ook zijn dat minimize van het IE window al voldoende is).
Hij start eerst het hooken, daarna start hij IE pas op.
Het subclassen bij al bestaande IE vensters gaat niet omdat hij de wndProc niet kan getten en setten met get/setWindowLong.Echter als dan de dll is geinjecteerd dan lijkt het nog niks te doen. Ik weet niet wat er dan precies mis gaat want op zich denk ik wel dat je de window dan al wel hebt ge-subclassed. Je zou kunnen kijken of je met DebugOutputMessage kan zien of hij ge-subclassed is.
[/quote]Als je nou IE opstart nadat je jouw programma (Starter) hebt gestart dan zie je wel dat je dll is geinjecteerd. Maar ook nu kan ik het IE window nog closen. Of je window is niet ge-subclassed of er gaat was mis in je HookProc.
Het 1e probleem kan je oplossen door gebruik te maken van een andere manier van Hooken. Bijv. door de Madshi library of door WH_GETMESSAGE hook want elke app heeft in iedergeval een message queue.
PS. Om te zien of jouw dll is geinjecteerd kan je gebruik maken van 'attach process' in Delphi. Je kiest dan IExplorer.exe en attach. Je kan nu mbv vies->debug windows->modules alle dll's zien die in het process zijn geladen. Nadeel is dat als je je app in delphi dan closed je ook de attached proc closed.
Ik zie dat hij 'UNKNOWN MODULE' heeft geadd, als ik `m attach aan een bestaande IExplorer venster. Klopt dat wel?
Even voor de duidelijkheid wat er gedaan moet worden:
Normaal gesproken gaat het als volgd:
StartHook -> Start IE -> Subclassen -> SetWantProcessID (aangeven welk venster).
Omdat je de rechten hebt om de wndProc te benaderen met get/setWindowLong bij een process dat door je eigen app is gestart, werkt dit allemaal prima.
Maar die rechten heb je niet bij een venster dat al geopend is, dus moet ik de dll injecteren in dat proces.
Maar wat ik nu niet snap is hoe ik dan SetHook kan aanroepen in de DLL.
Als test gebruikte ik hiervoor makeObservable, maar uiteindelijk moet dat setHook zijn.
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Ik dacht dat ik `m nu helemaal af had (nog steeds met dit laatste probleem overigens), maar nu werkt hij niet goed meer.
Het loskoppelen gaat niet goed bij meerdere vensters, en hij is gewoon niet stabiel.
Dit was toch wat te hoog gegrepen. Dus voor de liefhebbers, zeg het maar
edit
Hij werkt nu 100% goed
[ Voor 13% gewijzigd door Guillome op 04-02-2004 21:08 ]
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router