Entwickler-Ecke

Windows API - MessageBoxA Hook


Flamefire - Sa 15.09.07 14:08
Titel: MessageBoxA Hook
Hab ein Problem mit nem Pointer.
Ich habe die API-Funktion MessageBoxA gehooked.
so wird sie aufgerufen:

Delphi-Quelltext
1:
newMessageBoxA(0 , 'Test', 'Titel', 0);                    

wird gesetzt mit:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var
  origMessageBoxA: function (hWnd: HWND; lpText, lpCaption: String; uType: Integer): Integer; stdcall;
  newMessageBoxA: function (hWnd: HWND; lpText, lpCaption: String; uType: Integer): Integer; stdcall;

  @origMessageBoxA :=GetProcAddress(LoadLibrary('user32.dll'), 'MessageBoxA');
  HookCode(@origMessageBoxA, @callbackMessageBoxA, @newMessageBoxA);


das problem: es kommt immer eine zugriffverletzung beim Aufruf


Moderiert von user profile iconNarses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Sa 15.09.2007 um 23:59


BenBE - Sa 15.09.07 23:44

MessageBoxA will zwei PChars, anstatt zwei Strings haben. Das is ne WinAPI ;-)


Flamefire - So 16.09.07 15:11

passiert das gleiche...
das hatte ich ja vorher...hab dann die deklaration aus der windows.pas genommen...

aber geht beides nicht


uall@ogc - So 16.09.07 15:13

1) von wem ist die hook unit? (madshi, flocke, von mir etc)
2) Wie sieht die Callback funktion aus?
3) nimm die deklarationen von der windows.pas deine sind definitiv falsch


BenBE - So 16.09.07 15:16

@uall: Dem Code nach zu Urteilen nimmt er deine.
@2.: Wär definitiv interessant
@3.: Sag ich doch ;-)


Flamefire - Mo 17.09.07 09:11

die callback hat einfach nur "return 1"
ja es ist deine
definition muss ich mal gucken

EDIT: hab die definition aus der windows.pas kopiert...trotzdem das gleiche


uall@ogc - Mo 17.09.07 15:31

zeig mal den vollständigen Code (Hook, Funktionsdeklarierung und Callbackfunktion)


Flamefire - Mo 17.09.07 18:32


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:
library xx; 
 
uses 
  SysUtils, 
  Windows, 
  WinInet, 
  uallHook, 
  Dialogs; 
 
var 
  origMessageBoxA: function (hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;
  newMessageBoxA: function (hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;
  origInternetReadFile: function (hFile: HINTERNET; lpBuffer: Pointer; dwNumberOfBytesToRead: DWORD; var lpdwNumberOfBytesRead: DWORD): BOOL; stdcall;
  newInternetReadFile: function (hFile: HINTERNET; lpBuffer: Pointer; dwNumberOfBytesToRead: DWORD; var lpdwNumberOfBytesRead: DWORD): BOOL; stdcall;  
 
function callbackMessageBoxA(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: Cardinal): Integer; stdcall; 
begin
    Result :=MessageDlg(lpText,mterror,[mbOK],-1); 
end; 
 
function callbackInternetReadFile(hFile:HINTERNET;lpBuffer:Pointer;dwNumberOfBytesToRead:DWORD;var lpdwNumberOfBytesRead:DWORD):BOOL;stdcall;
begin 
  Result :=newInternetReadFile(hFile, lpBuffer, dwNumberOfBytesToRead, lpdwNumberOfBytesRead);
  newMessageBoxA(0,'a','b',1);
end; 
 
procedure DLLMain(); 
begin 
  @origMessageBoxA :=GetProcAddress(LoadLibrary('user32.dll'), 'MessageBoxA'); 
  HookCode(@origMessageBoxA, @callbackMessageBoxA, @newMessageBoxA);
  @origInternetReadFile :=GetProcAddress(LoadLibrary('wininet.dll'), 'InternetReadFile');
  HookCode(@origInternetReadFile, @callbackInternetReadFile, @newInternetReadFile);
end;
 
begin 
  DLLMain(); 
end.


BenBE - Di 18.09.07 20:32

@uall: Müsste hier nicht noch ein UnhookCode beim Entladen der DLL ausgeführt werden, da sonst die Pointer Invalid werden für die Routinen?


uall@ogc - Di 18.09.07 23:37

@BenBE: Wenn die dll vom kernel entladen wird ist es egal, sonst sollte man das so machen.

@Flamefire:
1) versuch nur mal MessageBoxA zu hooken (d.h. die andere Funktion nicht)
2) benutzt in einer Callbackfunktion niemals VCL code, der könnte u.U. wieder die besagte Funktion aufrufen und das ganze endet in einer Endlosschleife, ausserdem ist der nicht Threadsave.
Um zu sehen obs funktioniert, gibt einfach etwas mit nextMessageBoxA aus.