Autor Beitrag
Mr_Sven
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38


D7 Prof., C# (VS 2008)
BeitragVerfasst: Mo 11.05.09 12:02 
Hallo Leute,

Habe ein problem mit zwei geHookten WIn API Funktionen (ExtTextOutW und TextOutW).
Ich will von einem Programm die Textausgabe abfangen, da es keine Handles erzeugt, die man auslesen kann.

Also habe ich die beiden funktionen gehookt, leider schmiert das Progamm ab und zu mit einer Access Violation ab.

Vieleicht könnt ihr mit ja helfen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
function MyExtTextOutW (DC: HDC; X, Y: Integer; Options: Longint; Rect: PRect; Str: PWideChar; Count: Longint; Dx: PInteger): BOOL; stdcall;
var
 st:string;
begin        
 if Count > 0 then
  begin
   log('ExtTextOutW');
   st := Str;              //  <<<---- Access Violation
   if (length(st) >= Count) then
    ProcessText(substr(st,0,Count));
  end;        
 result:= TExtTextOutW(oldExtTextOutW)(dc, x, y, options, rect, str, count, dx);
end;
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mo 11.05.09 12:05 
Bitte WideString verwenden ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Mr_Sven Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38


D7 Prof., C# (VS 2008)
BeitragVerfasst: Mo 11.05.09 13:37 
ok, habs mal abgeändert, aber der fehler tritt wieder an der selben stelle auf.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function MyExtTextOutW (DC: HDC; X, Y: Integer; Options: Longint; Rect: PRect; Str: PWideChar; Count: Longint; Dx: PInteger): BOOL; stdcall;
var
 st:string;
 wst:widestring;
begin
 if Count > 0 then
  begin
   wst := Str;              //  <<<---- Access Violation
   st := WideStringToString(wst,CP_ACP);
   if (length(st) >= Count) then
    ProcessText(substr(st,0,Count));
  end;
 result:= TExtTextOutW(oldExtTextOutW)(dc, x, y, options, rect, str, count, dx);
end;
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 11.05.09 13:46 
Und wenn Du Str mal anders benennst?
Mr_Sven Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38


D7 Prof., C# (VS 2008)
BeitragVerfasst: Mo 11.05.09 13:52 
Ändert glaube ich nix, habe den funktionsaufruf direkt aus dern WIndows.pas kopiert
ausblenden Delphi-Quelltext
1:
2:
3:
{$EXTERNALSYM ExtTextOutW}
function ExtTextOutW(DC: HDC; X, Y: Integer; Options: Longint;
  Rect: PRect; Str: PWideChar; Count: Longint; Dx: PInteger): BOOL; stdcall;


Kann ich irgentwie überprüfen ob ich den Pointer zu Str lesen darf oder nicht?
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mo 11.05.09 13:55 
VirtualQuery oder IsBadReadPtr. Das ist aber keine Lösung, sondern allein ein Mittel zum Debuggen ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Mr_Sven Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38


D7 Prof., C# (VS 2008)
BeitragVerfasst: Mo 11.05.09 14:07 
Also so ungefähr?

werde es erstmal probiern.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
function MyExtTextOutW (DC: HDC; X, Y: Integer; Options: Longint; Rect: PRect; Str: PWideChar; Count: Longint; Dx: PInteger): BOOL; stdcall;
var
 st:string;
 wst:widestring;
begin
 if Count > 0 then
  begin
   if IsBadReadPtr(Str,count) then
    log('IsBadReadPtr')
   else
    begin
     wst := Str;              //  <<<---- Exception
     st := WideStringToString(wst,CP_ACP);
     if (length(st) >= Count) then
      ProcessText(substr(st,0,Count));
    end;
  end;
 result:= TExtTextOutW(oldExtTextOutW)(dc, x, y, options, rect, str, count, dx);
end;


---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Funktioniert auch nicht.
Xentar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: Mo 11.05.09 14:47 
Wie rufst du die denn auf? Vielleicht stimmt da schcon irgendwas nicht.

_________________
PROGRAMMER: A device for converting coffee into software.
Mr_Sven Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38


D7 Prof., C# (VS 2008)
BeitragVerfasst: Mo 11.05.09 14:53 
So wie ich es gepostet habe
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mo 11.05.09 16:07 
Ich sehe keine Aufrufe in deinen Posts. Nur Implementierungen.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Mr_Sven Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38


D7 Prof., C# (VS 2008)
BeitragVerfasst: Mo 11.05.09 16:09 
Du meinst wie ich die Funktion MyExtTextOutW aufrufe?

ausblenden Delphi-Quelltext
1:
2:
 HookCode(GetProcAddr(GetModuleHandle('Gdi32.dll'),'ExtTextOutW'),@MyExtTextOutW,oldExtTextOutW);
 HookCode(GetProcAddr(GetModuleHandle('Gdi32.dll'),'TextOutW'),   @MyTextOutW,   oldTextOutW);
Mr_Sven Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38


D7 Prof., C# (VS 2008)
BeitragVerfasst: Di 12.05.09 09:32 
Ok, also IsBadStringPtrW funtioniert auch nicht.

Habe jetzt mal WideCharToString genommen und das ganze mal in einem Debugger an geschaut.

Der Fehler tritt in der Prozedur _LStrFromPWChar auf:
ausblenden 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:
unit System;
.........
procedure _LStrFromPWChar(var Dest: AnsiString; Source: PWideChar);
asm
        XOR     ECX,ECX
        TEST    EDX,EDX
        JE      @@5
        PUSH    EDX
@@0:    CMP     CX,[EDX+0]      //  <<<---- Access Violation
        JE      @@4
        CMP     CX,[EDX+2]
        JE      @@3
        CMP     CX,[EDX+4]
        JE      @@2
        CMP     CX,[EDX+6]
        JE      @@1
        ADD     EDX,8
        JMP     @@0
@@1:    ADD     EDX,2
@@2:    ADD     EDX,2
@@3:    ADD     EDX,2
@@4:    MOV     ECX,EDX
        POP     EDX
        SUB     ECX,EDX
        SHR     ECX,1
@@5:    JMP     _LStrFromPWCharLen
end;
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 12.05.09 09:40 
Kannst Du bitte mal mit dem CPU-Fenster schauen, wie die Ursprüngliche Register-Belegung beim Prozedureinsprung ist und was auf dem Stack liegt (obersten 32 Einträge).

Ach ja: Warum machst Du einen Code Hook, statt einem IAT-Hook auf die besagten APIs? Welche Version der uallCollection nutzt Du?

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Mr_Sven Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38


D7 Prof., C# (VS 2008)
BeitragVerfasst: Di 12.05.09 10:03 
Problem nummer 1: ich kann leider nur die Exeption Reports des gehookten Programms verwenden.
Problem nummer 2: In dem Report sind die ganzen Entrypoints andere, habe ne weile gebraucht bis ich die fehlerhafte stelle im Code gefunden habe.
Problem nummer 3: Der Stack dump der da angezeigt wird ist irgendwie nicht das was ich erwartet habe.

Aber:

Habe den Code ein wenig umgebaut:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
   log('MyExtTextOutW');
   logW(Str,Count);
   log('MyExtTextOutW 1');
   st := WideCharToString(Str);
   log('MyExtTextOutW 2');


Das Steht in meinem Log File:

Normaler Eintrag ohne Exception:
MyExtTextOutW
b l a h
MyExtTextOutW 1
MyExtTextOutW 2

Eintrag mit Exception:

MyExtTextOutW
b l a h
MyExtTextOutW 1

Also Str kann ich über nen FileStream ohne Exception in eine Datei Schreiben.

Die Version der uallCollection finde ich leider nirgens.

Was meinst du mit IAT-Hook?
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 12.05.09 10:20 
IAT = Import Address Table.
Code Hooks waren bei uall die, die den Source umgeschrieben haben, während IAT nur die Import Address Table angepasst haben. IAT sind etwas schonender für das Programm was verbogen wird.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Mr_Sven Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38


D7 Prof., C# (VS 2008)
BeitragVerfasst: Di 12.05.09 10:43 
Hm, habe für nen IAT-Hook nicht wirklich nen beispiel gefunden.

Ich bin gerade am überlegen, ob ich die Umwandlung von dem PWideChar in einen String mal testweise über einen Stream mache, aber das ist natürlich ganz schön aufwendig.

oder ob man das irgentwie über inc(pointer) machen kann, so etwa:
ausblenden Delphi-Quelltext
1:
2:
s := s + char(pointer^);
inc(pointer);
Mr_Sven Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38


D7 Prof., C# (VS 2008)
BeitragVerfasst: Di 12.05.09 11:43 
ich glaube ich habe das problem gelößt,
Habe den code mal wie folgt um gebaut:

ausblenden 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:
function PWideCharToString(pwch:PWideChar;count:integer):string;
var
 i:integer;
begin
 result:='';
 for i:=0 to count - 1 do
  begin
   result:=result+pwch^;
   inc(pwch);
  end;
end;

function MyExtTextOutW (DC: HDC; X, Y: Integer; Options: Longint; Rect: PRect; Str: PWideChar; Count: Longint; Dx: PInteger): BOOL; stdcall;
var
 st:string;
begin
 if Count > 0 then
  begin
   log('MyExtTextOutW');
   logW(Str,Count);
   log('MyExtTextOutW 1');
   st := PWideCharToString(Str,Count);
   log('MyExtTextOutW 2');        
   st := WideCharToString(Str);
   log('MyExtTextOutW 3');
   if (length(st) >= Count) then
    ProcessText(substr(st,0,Count));
  end;
 result:= TExtTextOutW(oldExtTextOutW)(dc, x, y, options, rect, str, count, dx);
end;


Bei der Exception sah das file dann so aus:

MyExtTextOutW
b l a h
MyExtTextOutW 1
MyExtTextOutW 2

Ich lass das jetzt mal eine weile laufen und melde mich wenns klappt
Boldar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: Di 12.05.09 15:13 
Es gab da mal ein Beispiel eines shellhooks glaube ich, google doch mal danach...

Edit:
Hier wars

(Nur zum Thema, wie man dass sonst noch machen kann, dass geht auch in Richtung IAT-Hook)
Mr_Sven Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38


D7 Prof., C# (VS 2008)
BeitragVerfasst: Di 12.05.09 16:33 
So, habe das problem nun gelöst,
ich denke das WideCharToString damit nicht klar kommt, weil der PWideChar Wert in ExtTextOutW und TextOutW nicht mit #0 endet, dadurch kann er die länge nicht bestimmen und läuft manchmal in einen Speicherbereich den er nicht lesen darf.

Da bei ExtTextOutW und TextOutW glücklicherweise die länge des Textes übergeben wird, kann ich das über PWideCharToString(Str,Count) sauber umwandeln.

Gruß Sven