![]() |
Globaler API-Hook funktioniert nicht
Hi,
Ich versuche gerade eine API zu hooken, nämlich FindFileNext. Das hooken der Funktion selbst funktioniert, aber nicht im Zusammenhang mit einem (globalen) Hook. Hier die Hook-DLL:
Delphi-Quellcode:
Das Programm, was den Hook installiert:
library FindNextFileHook;
uses Windows, SysUtils; var Hook: hHook; FNCode: Pointer; function Dummy(code: Integer; wparam: wParam; lparam: lParam): LRESULT; stdcall; begin Result := CallNextHookEx(Hook,Code,wparam,lparam); end; function MyFindNextFile(hFindFile: THandle; var lpFindFileData: TWIN32FindData): BOOL; stdcall; var CurrFile: String; begin Result := FindNextFileA(hFindFile,lpFindFileData); CurrFile := PChar(@lpFindFileData.cFileName[0]); if ExtractFileExt(CurrFile) = '.txt' then MessageBox(0,'Textdatei gefunden!','FindNextFileHook',MB_OK); end; procedure HookFindNext; var hProc: THandle; br: Cardinal; jmp: Pointer; begin GetMem(jmp,6); hProc := OpenProcess(PROCESS_ALL_ACCESS,false,GetCurrentProcessID); try // Auslesen / Sichern FNCode := VirtualAllocEx(hProc,nil,6,MEM_COMMIT,PAGE_EXECUTE_READWRITE); ReadProcessMemory(hProc,@FindNextFile,FNCode,6,br); // Schreiben PByte(jmp)^ := $E9; inc(PByte(jmp)); PCardinal(jmp)^ := Cardinal(@MyFindNextFile) - Cardinal(@FindNextFile) - 5; inc(PCardinal(jmp)); PByte(jmp)^ := $E9; dec(PByte(jmp),5); WriteProcessMemory(hProc,@FindNextFile,jmp,6,br); finally FreeMem(jmp); CloseHandle(hProc); end; end; function InstallHook: Boolean; stdcall; begin Result := False; if Hook = 0 then begin Hook := SetWindowsHookEx(WH_GETMESSAGE,@Dummy, HInstance,0); Result := true; end; end; function UninstallHook: Boolean; stdcall; begin Result := UnhookWindowsHookEx(Hook); Hook := 0; end; exports InstallHook, UnInstallHook; begin HookFindNext; end.
Delphi-Quellcode:
Also ehrlichgesagt kann ich da leider auch nicht viel mehr zu sagen als: "Funktioniert nicht!"... :roll:
unit StartDLL;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button3Click(Sender: TObject); private { Private declarations } public lib: hModule; end; THookProc = function: Boolean; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var install: THookProc; begin lib := LoadLibrary('FindNextFileHook.dll'); if lib <> INVALID_HANDLE_VALUE then begin install := GetProcAddress(lib,'InstallHook'); if Assigned(install) then install; end; end; procedure TForm1.Button2Click(Sender: TObject); var un: THookProc; begin if lib <> 0 then begin un := GetProcAddress(lib,'UnInstallHook'); if Assigned(un) then un; end; FreeLibrary(lib); end; procedure TForm1.FormDestroy(Sender: TObject); var un: TUninstall; begin if lib <> 0 then begin un := GetProcAddress(lib,'UnInstallHook'); if Assigned(un) then un; end; FreeLibrary(lib); end; end. In der DLL wird HookFindNext ausgeführt und ich habe mir zu Debug-Zwecken auch nach fast jeder Zeile
Delphi-Quellcode:
anzeigen lassen. Aber ich gehe eher davon aus, das da ein Hook-Verständnisproblem vorliegt...
ShowMessage(SysErrorMessage(GetLastError));
Gruß Neutral General |
Re: Globaler API-Hook funktioniert nicht
Es fallen gleich zu Anfang von HookFindNext einige sehr seltsame Dinge auf, die nahelegen, dass du das Speicherkonzept von Windows nicht ganz verstanden hast.
Zitat:
Zitat:
Zitat:
Danach überschreibst du @FindNextFile. Das Problem dabei ist, dass diese Adresse nicht zur Compile-Zeit aufgelöst werden kann, weshalb der Linker eine Weiterleitungsfunktion (die nur von der Bibliothek verwendet wird und daher nicht zum Hooken verwendet werden kann) einfügt und diese FindNextFile nennt (diese sieht so aus: jmp [Adresse, an die der Windows-Loader die echte Adresse von Kernel32.dll.FindNextFile einfügt]). Du musst dir aus dieser die echte Adresse von FindNextFile holen, oder aber mit GetProcAdress, was einfacher sein dürfte. Der Rest der Funktion ist halbwegs korrekt, auch wenn man sich das WriteProcessMemory sparen könnte. In der Ersatzfunktion hast du es dir zu einfach gemacht. FindNextFileA hast du ja gerade gehookt, was zu einem rekursiven Aufruf führt. Du musst sicherstellen, dass du eine ganze Zahl von Befehlen ausgelesen hast (und nicht etwa der zweite Maschinensprache Befehl bei Byte 4 beginnt und zwei Bytes lang ist) und zur Not mehr als 5 Bytes auslesen. Die überschriebenen Befehl musst du dann wieder aufrufen und dann zu Byte 6 (oder weiter, auf jeden Fall an eine Stelle, wo ein neuer Befehl beginnt) springen. Wenn ich diese Hooking-Technik verwende, mache ich das immer so:
Delphi-Quellcode:
Die nops werden dann in HookFindNext überschrieben. AfterFindNextFile ist dabei die eigentlich Hook-Funktion, die ruhig in Delphi geschrieben werden darf - du musst allerdings mit Parametern und Aufrufkonvention aufpassen (und solltest außerdem eax, welches den Rückgabewert der Originalfunktion erhält, erhalten - also am besten ein kurzes Stück Assembler am Anfang der Funktion).
procedure FindNextFileReplace; //falsche Signatur, damit kein Stackframe generiert wird!
asm nop nop nop nop nop //falls du die Parameter noch brauchst, kopieren! mov eax, SavedFindNextFile //aus GetProcAddress add eax, 5 jmp/call eax //call nur, falls noch etwas folgt jmp AfterFindNextFile end; Abschließend weise ich darauf hin, dass diese Hooking-Technik nicht verwendet werden sollte, da es Probleme gibt, falls ein Thread FindNextFile aufruft während du gerade hookst. Stattdessen überschreibt man gewöhnlich für jedes Modul einzeln die vom Windows-Loader an eine bestimmte, in der PE-Datei angegebene Stelle eingefügte Adresse der zu hookenden Funktion. |
Re: Globaler API-Hook funktioniert nicht
Hi,
Zitat:
Zitat:
Zitat:
Das ich 99,8% verschwende war mir nicht so direkt bewusst, aber jetzt wo dus sagst: Jaa.. man reserviert ganze Memory-Pages... also mindestens 4096 Bytes... PAGE_EXECUTE_READWRITE... :stupid: Das ich 6, anstelle von 5 Bytes reservieren wollte, liegt daran, das ich mal in einer früheren Version 6 Bytes benötigt habe. Auuußerdem war ein guter Grund: Der Befehl, der ursprünglich an der zu hookenden Stelle stand, war folgender: FF25E4124500 jmp dword ptr [Adresse von Kernel32.FindNextFile] Dieser Befehl ist 6 Bytes groß und ich laß mal im Internet, das man Befehle möglichst nicht zerreißen sollte... Dummerweiße habe ich vergessen noch ein nop; zu schreiben... :roll: Wobei du Recht hast, wenn du sagst, dass es in diesem Fall nicht so schlimm ist, wenn ich den Befehl zerreiße weil der nachfolgende Befehl ja (höchstwahrscheinlich) nie ausgeführt wird. Zitat:
Zitat:
Das war mehr oder weniger beabsichtigt... Denn ich bekomme auf FindNextFileA keinen Schreibzugriff.. Per VirtualProtect(Ex) erhalte ich auch maximal nur PAGE_EXECUTE_WRITECOPY oder PAGE_WRITECOPY ,was mir ja nicht weiterhilft, deswegen hooke ich halt dieser Weiterleitfunktion... Zitat:
Zitat:
Vorher habe ich tatsächlich die ersten 6 gesicherten Bytes aufgerufen, aber das führte bei mir immer zu AVs weil die Parameter in FindNextFileA nicht richtig ankamen. Die Lösung dafür hast du aber ja unten gepostet ;) Zitat:
Zitat:
Aber danke für deine ausführliche Antwort :) Gruß Neutral General |
Re: Globaler API-Hook funktioniert nicht
Zitat:
Um zu hooken, reicht PAGE_EXECUTE_WRITECOPY aus. PAGE_EXECUTE_READWRITE würde bedeuten, dass du auch in allen anderen Prozessen in einem Rutsch hooken kannst (denn deren Pages, in denen Kernel32.dll liegt, sind die selben, in denen bei dir Kernel32.dll liegt - eine enorme Speicherersparnis), was aus Sicherheitsgründen äußerst fragwürdig wäre. PAGE_EXECUTE_WRITECOPY genügt, um ausschließlich in deinem Prozess Speicher zu überschreiben - dein Prozess erhält eine private Kopie der vorher gemeinsam genutzten Speicherseite. Zitat:
Zitat:
|
Re: Globaler API-Hook funktioniert nicht
Zitat:
Aber so einfach wie du dir das hier vorstellst ist es wirklich nicht. Schau dir mal einige Hook implementationen an, oder benutzt bereits fertige. Für das was du da jetzt so machst, kannst du eigentlich auch ImportHooking verwenden. |
Re: Globaler API-Hook funktioniert nicht
Hi,
bin schon ein ganzes Stück weitergekommen :) Aber es gibt da noch ein kleines Problem... Also erst mal der Code:
Delphi-Quellcode:
Das Problem an den markierten *)-Stellen ist, dass nie der Prozess nie mehr zurück nach FindNextHooked kommt, nachdem ich call eax aufgerufen habe. Daher wird jmp AfterFindNext auch nie aufgerufen. Ich dachte/glaube, dass in esi die Rücksprungadresse gespeichert wird, und daher habe ich die Adresse von FindNextHooked ins esi-Register kopiert. Leider funktioniert das nicht. Mein Verdacht: Innerhalb von FindNextFileA wird (u.a) auch FindNextFileW aufgerufen und daher "vergisst" er, dass er zurück zu FindNextHooked kommen soll (auf Deutsch: meine eingestellte Rücksprungadresse wird überschrieben).
procedure TForm1.FormCreate(Sender: TObject);
var lib: hModule; begin lib := LoadLibrary('Kernel32.dll'); if Lib <> INVALID_HANDLE_VALUE then try FindNextOld := GetProcAddress(Lib,'FindNextFileA'); finally FreeLibrary(lib); end; end; procedure TForm1.Button7Click(Sender: TObject); var hProc: THandle; br,old: Cardinal; jmp: Pointer; begin GetMem(jmp,5); hProc := GetCurrentProcess; try // Sicherung anlegen und in FinNextHooked schreiben VirtualProtect(@FindNextOld,5,PAGE_EXECUTE_WRITECOPY,old); GetMem(Sicherung,5); ReadProcessMemory(hProc,@FindNextOld,Sicherung,5,br); WriteProcessMemory(hProc,@FindNextHooked,Sicherung,5,br); // Schreiben PByte(jmp)^ := $E9; inc(PByte(jmp)); PCardinal(jmp)^ := Cardinal(@FindNextHooked) - Cardinal(@FindNextOld) - 5; dec(PByte(jmp)); WriteProcessMemory(hProc,@FindNextOld,jmp,5,br); finally FreeMem(jmp); CloseHandle(hProc); end; end; // geht nur mit globalen variablen irgendwie.. o.O var param1: THandle; param2: PWin32FindData; procedure FindNextHooked; asm nop // 5 Bytes für den gesicherten FindNextFileA-Code nop nop nop nop // Parameter1 (THandle) sichern mov Param1,eax // Parameter2 (PWin32FindData) sichern push esi mov esi,[ebp+$0C] mov Param2, esi pop esi // Parameter ablegen mov eax, Param2 push eax mov eax, Param1 push eax // Adresse von FindNextFileA ab Byte 6 in eax schieben mov eax,FindNextOld add eax,5 // Rücksprungadresse = Hier hin zurück! *) lea esi, FindNextHooked // FindNextFileA (ab Byte 6) aufrufen call eax // AfterFindNext aufrufen *) jmp AfterFindNext end; // Darin will ich die Ergebnisse von FindNext auswerten/verändern function AfterFindNext(hFindFile: THandle; var lpFindFileData: TWIN32FindData): BOOL; stdcall; begin Result := true; // debug ShowMessage('hi!'); // debug end; Was mach ich da? Gruß Neutral General |
Re: Globaler API-Hook funktioniert nicht
Ich habe die Methode etwas umgeändert und so braucht man die Größe der Befehle nicht kennen. Ich überschreibe genau wie du die 5 Bytes, speichere die alten ab und überschreibe dann meinen jmp-Befehl mit den alten 5 Bytes, wenn ich die ursprüngliche Funktion wieder aufrufen möchte. Bis jetzt hat dies bei mir mit allen Funktionen geklappt.
|
Re: Globaler API-Hook funktioniert nicht
Hi Wotan89,
Ja das Problem bei der Methode müsste doch sein, dass du dann nach jedem Aufruf wieder neu hooken musst.. Also nachdem du die Originalbytes zurückgeschrieben hast und die Funktion aufgerufen hast, müsstest du ja eigentlich nochmal den Jmp Befehl rüberkopieren. Das ist irgendwie ein ziemlich übles hin-und-her.. Vorteil ist halt wie gesagt, dass du jedesmal nur genau 5 Bytes brauchst, egal wie die Funktion aussieht, das stimmt.. Aber das ist ja im Moment nicht relevant. Das würde ja mein Problem nicht lösen oder doch? (warum sollte es?) |
Re: Globaler API-Hook funktioniert nicht
Klar muss ich hin und her hooken. Deswegen habe ich mir einfach 2 Funktionen(PatchAddress und UnpatchAddress) dafür geschrieben. So entfällt das ganze Nop-Array und man muss nicht debuggen um die Größe der Funktion/Prozedur herauszufinden. Ich denke jeder der in der Lage ist einen halbwegs übersichtlichen Quelltext zu schreiben wird das schon schaffen.
|
Re: Globaler API-Hook funktioniert nicht
Hi,
Ja ich verstehe deine Idee schon, und sie wird auch ihre Vorteile haben etc, aber es löst ja nicht mein Problem ;) |
Re: Globaler API-Hook funktioniert nicht
FindNextHooked ist quatsch... 1 param ist eax? ganz sicher net :)
globale Variablen für parameter benutzen oO? so sollte es gemacht werden (pseudocode): origfunction: 00000 JMP hooked 00005 restlicher code (darf nicht zerteilt sein) deinefunktion: 0000 irgendwas 00xx call nexthook 00xx irgendwas 00xx ret nexthook: 00000 5bytes der orig funktion 00000 JMP origfunction@00005 die Funktion HookCodeNt von ![]() |
Re: Globaler API-Hook funktioniert nicht
brechi verteilt wieder seine Sourcen :P
Aber die Sammlung ist in Sachen Hooking echt was feines... |
Re: Globaler API-Hook funktioniert nicht
Zitat:
Zitat:
Code:
:arrow:
mov eax, Form1.Variable
eax = 0 deswegen musste ich zwangsweise auf globale Variablen setzen. so sollte es gemacht werden (pseudocode): Zitat:
So siehts bei mir ja auch aus. Das Problem ist ja, dass ich meinen Code nach dem Original Code ausführen will... also so:
Delphi-Quellcode:
// origfunction:
00000 JMP hooked 00005 restlicher code (darf nicht zerteilt sein) // hooked 00000 5 Bytes der origfunktion ab 00005: Parameter der Originalfunktion sichern ab 0000X: call originalfunktion +5 ab 0000Y: Auswertung der Ergebnisse der Originalfunktion // <--- geht nicht Zitat:
Gruß Neutral General |
Re: Globaler API-Hook funktioniert nicht
Also davon auszugehen, dass die ersten fünf Bytes einer jeden Win32-API-Funktion IMMER vollständige Befehle sind (also nicht z.B. ein Befehl von Byte vier bis sieben geht) finde ich schon sehr gewagt. Es gibt fertige Disassemblermodule die einem die Länge des Assemblerbefehls an einer beliebigen Speicheradresse zurückliefern, mit denen kann man dann so viele Bytes kopieren wie notwendig sind, um nicht einen Assemblerbefehl zu schreddern. Dabei kommen sonst nämlich oft genug die seltsamsten Pseudobefehle heraus... Dass der Prozess sich dann seltsam verhält oder falsche Ergebnisse liefert, darf nicht verwundern.
Also: Nicht immer davon ausgehen, dass "fünfe gerade ist" ;) Das kann derb ins Auge gehen. Einfach Opcodelängen zählen und die notwendige Anzahl Bytes kopieren. Und BTW: Das Gejammer über eine allozierte Speicherpage mehr ist echt kindisch. Speicher wird immer nur in kompletten Pages alloziert, selbst wenn man nur ein Byte über die Pagegrenze kommt. Das ist Windows echt total schnurz, also einfach eine page allozieren, Anfang der API-Funktion wie oben beschrieben rüberkopieren, absoluten Jump hinter den kopierten Bytes einfügen und dann mittels WriteProcessMemory den Anfang der API-Funktion überschreiben. Achtung beim prozessübergreifenden Hooking: Viele "Kopierschutz"-Tools checken APIs oder zumindest deren Anfang auf bekannte Manipulationen (EB FE, CC, etc.) und verweigern dann die Benutzung der "geschützten" Software. |
Re: Globaler API-Hook funktioniert nicht
Ich habe extra geschrieben, dass FindNextHook ohne Parameter und besondere Aufrufkonvention notiert wird, damit kein Stackframe generiert wird. Das bedeutet aber auch, dass ebp nicht neu gesetzt wird, man muss also relativ zu esp zugreifen.
In meinem Beispielcode ist aber auch ein Fehler. Falls man eine Nachbearbeitung der Parameter durchführen will, ist es nicht mehr so einfach wie beim Jump (ich habe bisher nur diesen verwendet, daher bitte ich den Fehler zu entschuldigen). Denn die Rückkehradresse wird so ja erst nach den ersten Befehlen gepusht, was tödlich sein kann, falls die ersten Befehle irgend etwas am Stack verändern. Die richtige Variante sähe ungefähr so aus:
Delphi-Quellcode:
Das ist alles aus dem Kopf getippt und nicht getestet.
procedure FindNextFileReplace;
asm push [esp+8] push [esp+8] call @@GetReturnAdress @@GetReturnAdress: add [esp], 14 //4 Byte: Opcode, ModR/M, SIB, Immediate nop nop nop nop nop jmp offset FindNextFile + 5 //5 Byte jmp MyFindNextFile end; Die Länge der Befehle am Anfang der Routine musst du von Hand abzählen, um die Position der Nops zu erhalten. |
Re: Globaler API-Hook funktioniert nicht
Hi,
Also bei mir siehts im Moment so aus:
Delphi-Quellcode:
*) jmp offset FindNextOld + 5 compiliert nicht:
// beim Hooken:
WriteProcessMemory(hProc,Pointer(Integer(@FindNextHooked)+17),Sicherung,5,br); procedure FindNextHooked; asm push [esp+8] push [esp+8] call @@GetReturnAdress @@GetReturnAdress: add [esp], 14 //4 Byte: Opcode, ModR/M, SIB, Immediate nop nop nop nop nop add FindNextOld, 5 jmp FindNextOld // * jmp AfterFindNext end; [Error] Unit1.pas(66): Invalid combination of opcode and operands deswegen habe ich es durch Zitat:
Delphi-Quellcode:
Hat bis eben so nicht funktioniert, weil ich nicht wusste (und immernoch nicht genau weiß, was diese Zeile bewirkt, aber ich habe herausgefunden das ich die 14 durch eine 17 ersetzten muss damit es funktioniert...
add [esp], 14 // wird da die Adresse von esp um 14 erhöht? wenn ja warum?
Gruß Neutral General |
Re: Globaler API-Hook funktioniert nicht
FindNextHooked ist fürn popo.
Machs so wie ichs gesagt habe, so wirds in fast allen hooks gemacht und das hat auch seinen Grund. |
Re: Globaler API-Hook funktioniert nicht
Hi brechi,
Ok ich habe es mal so gemacht:
Delphi-Quellcode:
mein TestCode sieht so aus:
procedure NextHook;
asm nop nop nop nop nop add FindNextOld,5 call FindNextOld end; procedure FindNextHooked; asm push [esp+8] // Sonst kommen die falschen parameter in FindNextOld an push [esp+8] // ... call nexthook sub FindNextOld,5 ret end;
Delphi-Quellcode:
FindNext sieht so aus:
procedure TForm1.Button3Click(Sender: TObject);
var sr: TSearchRec; begin FindFirst('C:\*.*',faAnyFile,sr); FindNext(sr); end;
Delphi-Quellcode:
... und das gibt dann eine AV.
push ebx
mov ebx,eax lea eax,[ebx+$18] push eax mov eax,[ebx+$14] push eax call FindNextFile // <--- springt zu FindNextFileA, ist gehooked // hier macht er weiter wenn das ret aus FindNextHooked aufgerufen wird test eax,eax jz +$09 mov eax,ebx call FindMatchingFile pop ebx ret // <--- hier, call GetLastError pop ebx ret // oder hier müsste er wieder in Button3Click springen, er springt aber (soweit ich das beurteilen kann) irgendwo in die pampa Gruß Neutral General |
Re: Globaler API-Hook funktioniert nicht
In NextHook sollte es Jmp und nicht Call heißen. Wie ich bereits bemerkt habe, verändert die Rückkehradresse sonst den Stack. Außerdem solltest du die Veränderung an FindNextOld direkt beim Einrichten des Hooks vornehmen, sonst gibt es Probleme mit mehreren Threads.
Meine Lösung ist übrigens praktisch identisch mit Brechis. :wink: Um nochmal zu deiner Frage zu meinem Code zurückzukommen: add [esp], 14 verändert nicht esp selbst, sondern den Integer, auf den esp zeigt. Das ist zufällig die Zahl, welche zuoberst auf dem Stack liegt. Welche ist das in diesem Fall? Genau, die Adresse, die durch den Call auf den Stack geschoben wurde. Diese zeigte vorher auf @@GetReturnAddress und wird nun auf den Befehl nach dem Jump rejustiert (durch das Add stimmen die 14 Bytes übrigens nicht mehr - bei diesen Adress-Geschichten ist der Inline-Assembler leider immer ein bisschen pingelig, ich sehe ehrlich gesagt kein Problem darin, zu der Adresse einer Funktion 5 zu addieren). Ich gestehe allerdings, bezüglich des jmp offset FindNextFile + 5 nicht mitgedacht zu haben - wir verwenden hier mal wieder die Weiterleitungsfunktion und nicht jene in Kernel32.dll, aber du hast das ja schon richtig mit einer globalen Variablen korrigiert. Wir legen also für die originale FindNext-Funktion eine künstliche Rückkehradresse an. Im Prinzip ist das das selbe, was in Brechis Code mit zwei Routinen gemacht wird. |
Re: Globaler API-Hook funktioniert nicht
richtigerweise würde nexthook so aussehen:
Delphi-Quellcode:
function FindNext(var F: TSearchRec): Integer;
asm nop nop nop nop nop add FindNextOld,5 jmp FindNextOld end; |
Re: Globaler API-Hook funktioniert nicht
Hi,
Im Moment funktionierts nicht so ganz. Also die Delphi IDE ballert mich dauernd mit ShowMessages zu aber sonst siehts mager aus. Hier mal die ganze DLL (wobei ShowMessage zum Debuggen gedacht ist ;) )
Delphi-Quellcode:
Gruß
library FindNextFileHook;
uses Windows, SysUtils, Dialogs; type TFindNext = function (hFindFile: THandle; var lpFindFileData: TWIN32FindData): BOOL; stdcall; var Hook: hHook; function Dummy(code: Integer; wparam: wParam; lparam: lParam): LRESULT; stdcall; begin Result := CallNextHookEx(Hook,Code,wparam,lparam); end; var FindNextOld: TFindNext = nil; tmp: THandle = INVALID_HANDLE_VALUE; function MyFindNextFile(hFindFile: THandle; var lpFindFileData: TWIN32FindData): BOOL; stdcall; var s: String; begin s := lpFIndFileData.cFileName; if ExtractFileExt(s) = '.txt' then ShowMessage('Erwischt!'); end; function NextHook(var F: TSearchRec): Integer; asm nop nop nop nop nop add FindNextOld,5 jmp FindNextOld end; procedure FindNextHooked; asm push [esp+8] push [esp+8] call nexthook sub FindNextOld,5 jmp MyFindNextFile ret end; procedure HookFindNext; var hProc: THandle; br,old: Cardinal; jmp: Pointer; Sicherung: Pointer; lib: hModule; begin if @FindNextOld = nil then begin Lib := LoadLibrary('kernel32.dll'); FindNextOld := GetProcAddress(lib,'FindNextFileA'); FreeLibrary(lib); end; GetMem(jmp,5); hProc := OpenProcess(PROCESS_ALL_ACCESS,false,GetCurrentProcessID); try // Auslesen / Sichern VirtualProtectEx(hProc,@FindNextOld,5,PAGE_EXECUTE_WRITECOPY,old); GetMem(Sicherung,5); ReadProcessMemory(hProc,@FindNextOld,Sicherung,5,br); WriteProcessMemory(hProc,@NextHook,Sicherung,5,br); // Schreiben PByte(jmp)^ := $E9; inc(PByte(jmp)); PCardinal(jmp)^ := Cardinal(@FindNextHooked) - Cardinal(@FindNextOld) - 5; dec(PByte(jmp)); WriteProcessMemory(hProc,@FindNextOld,jmp,5,br); finally FreeMem(jmp); CloseHandle(hProc); end; end; function InstallHook: Boolean; stdcall; begin Result := False; if Hook = 0 then begin Hook := SetWindowsHookEx(WH_GETMESSAGE,@Dummy, HInstance,0); Result := true; end; end; function UninstallHook: Boolean; stdcall; begin Result := UnhookWindowsHookEx(Hook); Hook := 0; end; exports InstallHook, UnInstallHook; begin HookFindNext; end. Neutral General |
Re: Globaler API-Hook funktioniert nicht
Hast du mal probiert, die DLL in ein eigenes Programm zu laden und dann einfach mal durchzusteppen?
|
Re: Globaler API-Hook funktioniert nicht
Hi,
Ich merke gerade, das es in Delphiprogrammen funktioniert. Also in meinem Testprogramm zumindest... Im Explorer funktioniert es allerdings nicht... Kann es sein, dass der Explorer FindNextFileW benutzt? |
Re: Globaler API-Hook funktioniert nicht
Ich bin mir diesbezüglich sogar ziemlich sicher.
|
Re: Globaler API-Hook funktioniert nicht
Neutral General:
Hast du nun versucht, die FindNextFileW zu hooken - bzw hat es funktioniert ? MfG |
Re: Globaler API-Hook funktioniert nicht
Hi,
Ehm das ist schon lange her.. Ich weiß gar nicht :mrgreen: Entweder hab ichs nicht probiert oder es hat nicht funktioniert. Würde ich mal tippen. :stupid: |
Re: Globaler API-Hook funktioniert nicht
Mist :(
Ich versuche auch schon seit ca ner 1/2 h FindFirstFileW zu hooken, nur misslingt mir das Hooken mit der injizierten Dll in Explorer.exe Wäre schon, wenn irgendein andere mir sagen könnte, wie / womit genau Windows die Dateien auflistet / findet. EDIT: Am besten erstell ich nen eigenen Thread dafür :) MfG |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:58 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz