| Autor |
Beitrag |
Mr_Sven
      
Beiträge: 38
D7 Prof., C# (VS 2008)
|
Verfasst: 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:
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; if (length(st) >= Count) then ProcessText(substr(st,0,Count)); end; result:= TExtTextOutW(oldExtTextOutW)(dc, x, y, options, rect, str, count, dx); end; |
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: 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 
      
Beiträge: 38
D7 Prof., C# (VS 2008)
|
Verfasst: Mo 11.05.09 13:37
ok, habs mal abgeändert, aber der fehler tritt wieder an der selben stelle auf.
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; 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
|
Verfasst: Mo 11.05.09 13:46
Und wenn Du Str mal anders benennst?
|
|
Mr_Sven 
      
Beiträge: 38
D7 Prof., C# (VS 2008)
|
Verfasst: Mo 11.05.09 13:52
Ändert glaube ich nix, habe den funktionsaufruf direkt aus dern WIndows.pas kopiert
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
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: 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 
      
Beiträge: 38
D7 Prof., C# (VS 2008)
|
Verfasst: Mo 11.05.09 14:07
Also so ungefähr?
werde es erstmal probiern.
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; 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 Narses: Beiträge zusammengefasst---
Funktioniert auch nicht.
|
|
Xentar
      
Beiträge: 2077
Erhaltene Danke: 2
Win XP
Delphi 5 Ent., Delphi 2007 Prof
|
Verfasst: 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 
      
Beiträge: 38
D7 Prof., C# (VS 2008)
|
Verfasst: Mo 11.05.09 14:53
So wie ich es gepostet habe
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: 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 
      
Beiträge: 38
D7 Prof., C# (VS 2008)
|
Verfasst: Mo 11.05.09 16:09
Du meinst wie ich die Funktion MyExtTextOutW aufrufe?
Delphi-Quelltext 1: 2:
| HookCode(GetProcAddr(GetModuleHandle('Gdi32.dll'),'ExtTextOutW'),@MyExtTextOutW,oldExtTextOutW); HookCode(GetProcAddr(GetModuleHandle('Gdi32.dll'),'TextOutW'), @MyTextOutW, oldTextOutW); |
|
|
Mr_Sven 
      
Beiträge: 38
D7 Prof., C# (VS 2008)
|
Verfasst: 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:
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] 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
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: 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 
      
Beiträge: 38
D7 Prof., C# (VS 2008)
|
Verfasst: 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:
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
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: 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 
      
Beiträge: 38
D7 Prof., C# (VS 2008)
|
Verfasst: 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:
Delphi-Quelltext 1: 2:
| s := s + char(pointer^); inc(pointer); |
|
|
Mr_Sven 
      
Beiträge: 38
D7 Prof., C# (VS 2008)
|
Verfasst: Di 12.05.09 11:43
ich glaube ich habe das problem gelößt,
Habe den code mal wie folgt um gebaut:
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
      
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: 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 
      
Beiträge: 38
D7 Prof., C# (VS 2008)
|
Verfasst: 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
|
|
|