Entwickler-Ecke

Windows API - Hooks - MyProcedure, NextProcedure, OldProcedure Problem


F34r0fTh3D4rk - So 12.06.05 13:03
Titel: Hooks - MyProcedure, NextProcedure, OldProcedure Problem
Hallo, ich habe das problem, wenn ich einen process hooke und zb messageboxA durch meine eigene ersetze, stürzt das program ab, sobald diese ausgeführt wird, hier mal 2 beispiele:

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:
library hook;

uses
  windows,
  uallHook,
  sysutils;

var oldMessageBoxA, nextMessageBoxA: function(a: integer; b, c: pchar; d: integer): integer; stdcall;

function reverse(Pc: PChar): Pchar;
var
  i: integer;
  str : string;
begin
  result := '';
  for i := length(pc) downto 1 do
    str := str + pc[i];
  result := pchar(str);
end;

function myMessageBoxA(a: integer; b, c: pchar; d: integer): integer; stdcall;
var
  str: pchar;
begin
  str := reverse(str);
  result := oldmessageBoxA(a, b, str, d);
end;

procedure injectmain;
var h: integer;
begin
  h :=  GetModuleHandle('user32.dll');
  if h > 0 then
  begin
    @oldMessageBoxA := GetProcAddress(h, 'MessageBoxA');
    if @oldMessageBoxA <> nil then
      uallHook.HookCode(@oldMessageBoxA, @myMessageBoxA, @nextMessageBoxA);
  end;
end;

procedure uninjectmain;
begin
  uallHook.UnhookCode(@nextMessageBoxA);
end;

procedure dllmain(dwReason: integer);
begin
  case dwreason of
    DLL_PROCESS_ATTACH:
      injectmain;
    DLL_PROCESS_DETACH:
      uninjectmain;
  end;
end;

begin
  DLLProc := @DLLMain;
  DLLMain(1);
end.


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:
library hook;

uses
  windows,
  uallHook in '..\..\source\uallHook.pas',
  sysutils,
  inifiles;

var
  oldTerminateProcess, nextTerminateProcess: function(hProcess: THandle; UExitCode: UInt): BOOL; stdcall;
  programtitle: string;

function myTerminateProcess(hProcess: THandle; UExitCode: UInt): boolean;
var
  ini: tinifile;
begin
  ini := tinifile.Create(ExtractFilePath(paramstr(0)) + 'WindowName.ini');
  try
    programtitle := ini.readstring('Main''Name''');
  finally
    ini.free;
  end;
  if hProcess <> findwindow(nil, pchar(programtitle)) then
    oldTerminateProcess(hProcess, UExitCode);
end;

procedure injectmain;
var
  h: integer;
begin
  h :=  GetModuleHandle('kernel32.dll');
  if h > 0 then
  begin
    @oldTerminateProcess := GetProcAddress(h, 'TerminateProcess');
    if @oldTerminateProcess <> nil then
      uallHook.HookCode(@oldTerminateProcess, @myTerminateProcess, @nextTerminateProcess);
  end;
end;

procedure uninjectmain;
begin
  uallHook.UnhookCode(@nextTerminateProcess);
end;

procedure dllmain(dwReason: integer);
begin
  case dwreason of
    DLL_PROCESS_ATTACH:
      injectmain;
    DLL_PROCESS_DETACH:
      uninjectmain;
  end;
end;

begin
  MessageBox(0'Hook.dll succesfully injected!''Info'0);
  DLLProc := @DLLMain;
  DLLMain(1);
end.

hab extra vorhandene hooks von uall genommen und bearbeitet, um funktionalität zu gewährleisten, aber sobald messagebox oder terminateprocess aufgerufen wird, von den gehookten programmen, stürzen diese ab, warum ?


retnyg - So 12.06.05 13:08

du musst vorsichtig sein, du kannst z.b. einen messageboxA hook nur verwenden, wenn der "opfer-prozess" selber auch die user32.dll verwendet !
drum kannst du auch keine standard-kompos von delphi verwenden, weil diese meistens irgendwelche system-dll's mit einbeziehen, die der opfer-prozess nicht geladen hat.
am besten wäre es, in der dll sogar ganz auf strings zu verzichten (nur pchar's) und nur api-funktionen der kernel32.dll zu verwenden, was die ganze sache natürlich erschwert.


F34r0fTh3D4rk - So 12.06.05 13:11

das mit der messagebox, habe ich ein programm geschrieben, welches mit messagebox einfach nur ne messagebox auf buttonklick ausgibt, das andere ist der taskmanager :idea:


retnyg - So 12.06.05 13:15

du darfst aber kein tinifile verwenden. und rate mal warum ualls reverse-prozedur in assembler geschrieben ist - damit er keine strings verwenden muss und direkt den vorhandenen buffer umsortieren kann.


F34r0fTh3D4rk - So 12.06.05 13:26

joah chef, werd mal gucken :)

das problem scheint nicht bei den strings zu liegen, der gleiche fehler auch hier:

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:
library hook;

uses
  windows,
  uallHook,
  sysutils;

var oldMessageBoxA, nextMessageBoxA: function(a: integer; b, c: pchar; d: integer): integer; stdcall;

function myMessageBoxA(a: integer; b, c: pchar; d: integer): integer; stdcall;
begin
  result := oldmessageBoxA(a, b, 'I was hooked :)', d);
end;

procedure injectmain;
var h: integer;
begin
  h :=  GetModuleHandle('user32.dll');
  if h > 0 then
  begin
    @oldMessageBoxA := GetProcAddress(h, 'MessageBoxA');
    if @oldMessageBoxA <> nil then
      uallHook.HookCode(@oldMessageBoxA, @myMessageBoxA, @nextMessageBoxA);
  end;
end;

procedure uninjectmain;
begin
  uallHook.UnhookCode(@nextMessageBoxA);
end;

procedure dllmain(dwReason: integer);
begin
  case dwreason of
    DLL_PROCESS_ATTACH:
      injectmain;
    DLL_PROCESS_DETACH:
      uninjectmain;
  end;
end;

begin
  DLLProc := @DLLMain;
  DLLMain(1);
end.