Hooks Theorie

Hallo - ich versuch gerade die verschiedenen hook möglichkeiten zu verstehen.
Ich hoffe jemand hilft mir mal bei der Theorie, damit ich die methoden unterscheiden kann.

1. Import hook:
Hier werden bei allen .dlls die die zu hookende funktion verwenden die imports verbogen.
also:
getprocadress(original funktion)
dann vergleichen the thunks in der import table aller .dlls die die funktion importieren.
und die thunk adresse überschreiben - vorher die originale merken, damit man die auch aufrufen kann.

Hab ich das mal richtig verstanden?

2. memory patching - oder code hook:
hier wird dirrekt an der funktion basis also an der einsprungadresse ein jump auf die hook funktion gemacht.
dann wird die überschriebene zeile in der hook funktion auch ausgeführt und der jump wieder zurück in die originale funktion.

Stimmt das?

3. Was ist im gegenzug dazu ein Base hook? - versteh hier den terminus nicht :)

Wäre nett, wenn mir das jemand erklären könnte, ich möchte einfach mal die Theorie verstehen.
Danke!

Verucca
 
ich kenne zwar die Begriffe nicht, aber es gibt da mehrere Methoden, wenn man von den OS-Hoocks mal absieht ;)

Z.B Tyny "Firewall" patcht direkt die Funktionen im Kernel, so überwacht diese Software z.B den "CreateRemoteThread". Hierzu werden wie erwähnt im Kernel (also ab 7ffxxx) die jeweiligen Adressen, wo eben der API Aufruf landet, mit einem JMP gepatcht, der auf den Tiny-eigenen Modul umleitet. Diese Methode lässt sich auch auf "GetProcAddress" andwenden - in dem man diese im Kernel patcht und alle Aufrufe darauf eben auf sein Modul umleitet, welches dann natürlich eine Tabelle mit "Originalaufrufen" machen sollte ;) .

Das Memory Patching ist an sich etwas aufwendig - da aber in der Regel kaum aus der Memory auf die API gesprungen wird, sondern ein "Zwichenjump" in die Importtabelle erfolgt, wir eben diese Importtabelle gepatcht - also im Prinzip nichts anderes als Import hook. Wenn man die Hooks macht, sollte man im klaren sein welche Parameterübergabe benutzt wird und wer den Stack aufräumt.Es gibt Funktionen bei einigen DLLs die auch Register dazu benutzen, die STDCALL erwartet dagegen nur alles auf dem Stack und die aufrufende Prozedur räumt diesen auf. PASCAL Übergabe sollte dasselbe sein, nur dass die Parameter im Stack "andersrum" liegen. Die cdecl die z.B bei variablen Parameterlisten vorkommt (C- Beispiel: printf) verlangt vom Aufrufer die räumung.
Wenn man da also beim Hooken nicht aufpasst, wird es schnell Fehler regnen.

zu Base hooks liefert google irgendwie nur C++/NET bezogene Sachen "base hook class". Es wäre vielleicht hilfreich wenn Du die Quelle mal postest.
 
Hallo
Also in dem Forum wird ständig von einem base hook gesprochen, deshalb frag ich was damit gemeint sein könnte:
http://forum.game-deception.com

Dann stimmen meine Ausführungen also so halbwegs?
Das patchen der Api functionen finde ich aber sehr interessant.
Ich dachte immer eine Api muß in dem aufrufenden prozess gepatcht werden?
Besonderes interesse hätte ich an callback api functions
wie getfirst/nextmodulehandle die ja gerne für processhiding benutzt werden.
wenn ich aus meinem programm getfirstmodulehandle aufrufe, wie ist dann der ablauf? also wohin geht dann der aufruf und wohin dann der callback?

Auch hab ich gelesen, daß der handle für kernel32.dll zum beispiel für alle prozesse gleich ist - allerdings wird wohl wie bei allen modulen nur die shared section in allen prozessen gleich sein im falle eines hooks zum beispiel - was dann wieder bedeutet, man muß wirklich global hooken, also alle prozesse auch für kernel32.dll und die api's

Wäre nett wenn du mir das etwas erklären könntest.
Danke
Verucca
 
ch dachte immer eine Api muß in dem aufrufenden prozess gepatcht werden?
Besonderes interesse hätte ich an callback api functions
Hab mich etwas unklar ausgerückt - natürlich ist die Memory in jedem Prozess gemeint. Sonst müsste man wirklich viel zu tief im System graben. Aber man kann eben im Prozess selber jeden aufruf patchen, die Importtale patchen oder eben die Zieladresse wo der API Aufruf landet,
Da aber jedem Prozess 4GB adressierbaren, (virtuellen) Speicher zur verfügung stehen und ab ca. 7fxxxxx die "Systemsachen" anfangen, ist es wohl einfacher diese zu bearbeiten.
wie getfirst/nextmodulehandle die ja gerne für processhiding benutzt werden.
die kenne ich nicht ;), meinst Du eventuell Module32Firs/ &Co vom CreateToolhelp32Snapshot ? Wenn Du die meinst, dann geht der Aufruf in den "Kernelbereich" der das ganze erledigt. Bei einem Callback wird eine Fuktionsadresse übergeben auf die dann jedesmall gesprungen wird, wenn ein Ereignis eintrifft.
AFAIK ist zwar der Handle zu den Systemdlls immer gleich - weil diese beim Start der Applikation in den Speicher "miteingeblendet" werden. Aber Änderungen aller Art wirken sich (zumindest im Ring3) nur auf den jeweiligen Prozessspeicher aus.Wenn Du also "Global" patchen willst um alle Prozesse zu überwachen, dann könntest Du dir entweder die Windowshooks anschauen ;), deine eigene DLL jedesmal mitladen lassen (z.B Appinitdll in der Registry) oder es mit einem eigenen Treiber versuchen.
Besonderes interesse hätte ich an callback api functions
Wie meinst Du das? alles über die eigene Routine laufen lassen (mit weiterleitung an die richtige Funkton ? Ich kann Dir leider nicht so viel zur Theorie erzählen - eher zur Praxis und praktischer Anwendung. Im Forum habe ich mich übrigends nicht registriert - aber ohne Registrierung kann man auch keine Beiträge lesen.
 
aber ohne Registrierung kann man auch keine Beiträge lesen.
Ich weiß - ist auch unnötig - ich hab nichts gefunden das mir hinweise liefert was ein base hook sein soll. - vermutlich ist das ein terminus der sich dort eingebürgert hat.

meinst Du eventuell Module32Firs/ &Co vom CreateToolhelp32Snapshot ?
ja klar mein ich das
Bei einem Callback wird eine Fuktionsadresse übergeben...
ich hab mich nicht klar ausgedrückt - wie man die apis verwendet weiß ich genau - hab schon viel damit gearbeitet - keine ahnung wie ich auf getfirst/nextmodulehandle komme aber ich bin meißtens abends ziemlich müde lol.

Ich versuch vor allem zu begreifen wie windows das macht und was eben gehookt wird wenn zum beispiel versucht wird einen prozess zu verstecken.
Eigentlich hab ich nur nicht verstanden was du gemeint hast mit alle aufrufe landen in einem bestimmten adressbereich.
wenn du damit einfach nur die gemapte kernel32.dll meinst, daß die immer am gleichen ort liegt, dann ists mir klar :).

Mich interessieren die genauen abläufe wenn ich eine exportierte funktion in mein oder ein programm importiere ( kernel32.dll und die apis sag ich mal funktionieren dann wohl genau so)

1. wann gibt es eine import table - nur bei .dll's oder auch in .exe programmen?
( hab wenig erfahrung damit - hab nur mal teile der struktur ausgelesen).
2. wenn ich eine importierte function benutze, was passiert dann genau - es wird ja über den umweg der import table die funktion aufgerufen - was ja hooken erst möglich macht - mir ist einfach der ablauf hier nicht klar.

hoffentlich ergibt das sinn - ich bin tot müde und geh wohl schlafen :) gute nacht

Verucca
 
wenn du damit einfach nur die gemapte kernel32.dll meinst, daß die immer am gleichen ort liegt, dann ists mir klar smile .
Jep, das ist auch gemeint.

1. wann gibt es eine import table - nur bei .dll's oder auch in .exe programmen?
Bei beiden. AFAIk muss eine "minimaltabelle" Vorhanden sein, sonst wird man auch nicht GetProcadress nutzen können - es sei denn man springt direkt die Kerneladresse an (was wegen den Unterschieden bei verschiedenen Windowsen nicht ganz so einfach und sehr Versions und SP-Abhängig ist). Die Tabelle wird vom PE-Loader ausgefüllt, praktisch gesagt kümmert sich das OS um die Adressen. Das geschieht bei allen "statisch" verlinkten DLLs - im Hexeditor kann man dann den Namen der Funktion und der DLL sehen. Dann lädt so zu sagen der Loader die DLL "vor" und importiert die Funktion - oder man macht es "manuell" und benutzt die GetProcAddress und LoadLibriary. Der Unterschied besteht im Prinzip nur darin, dass bei statisch verlinkten DLLs der windowseigene Loader diese Lädt und bei einem Fehler die ganze Aktion abbricht (so dass die Exe nicht startet). In der "ZiellApplikation" gibts ja die Exporttabelle wo eben die Namen/Ordinanzzahlen und die Adressen verzeichnet sind. Wenn man also eine Exportierte Funktion in seine eigene DLL/Exe importiert, dann schaut entweder der PE-Loader ober eben die GetProcAddr darin nach. http://win32assembly.online.fr/pe-tut7.html sagt was zum Thema - nach der Lektüre kann man auch einen eigenen Importer schreiben ;). In den Systemeignenen Kernels sieht es nicht anders aus (gerade mit dem Hexeditor meine Parallelinstallation geöffnet) - eine große Exporttabelle mit den Funktionen und Adressen dazu.

. wenn ich eine importierte function benutze, was passiert dann genau - es wird ja über den umweg der import table die funktion aufgerufen - was ja hooken erst möglich macht - mir ist einfach der ablauf hier nicht klar.
Beispiel: man benutzt VB oder MFC Dll. Die Funktionen kann man jetzt folgendermaßen aufrufen - per "normaler" Verlinkung (ich sag zwar immer statisch dazu, ist wohl aber falsch ), jedenfalls DLL mit Libs einbinden). Dann hat die Exe im Importtable die Einträge auch zu dieser DLL und deren Funktionen - die dann vom PE-Loader ausgefüllt werden. Dieser lädt/mappt auch die DLL mit in den App-Speicher.
Oder man benutzt LoadLibriary und GetProcAdress. In diesem Fall verwahrt man die Adressen selber auf in eigenen Variablen/tabellen. In beiden Fällen ist die DLL im Speicher der Applikation sichtbar (i.d.R. ab 1000000h).
so, jetzt liegt z.B die gewünschte Funktion auf Adresse 10001200. Im ersten Fall hat der PE-Loader das in der Tabelle eingetragen im zweiten Fall wird es von GetProcAddr zurückgegeben.
Wenn man jetzt diese Funkton benutzt, wird im ersten Fall zuerst in den Eintrag in der Importtable gecallt - da der Linker ja nicht weiß wo die DLL später im Speicher landet, kann er sie auch bei einer LIB nicht "fix" verlinken. Aus der Importtable wird erst zu der richtigen Funktion gejumpt. Dank der Rücksprungsadresse auf dem Stack kommt der Call aus der DLL wieder zu dem Aufrufer zurück.
Im zweiten Fall hat man die Adresse in einer eigenen Variable vorliegen und kann deshalb direkt auf die richtige Adresse callen.
Jetzt zurück zum Hooken - wenn man Fall eins hat, kann man die Importtabelle überschreiben, beim Fall zwei auch - nur eben bei der GetProcAddr, die man auf "sich selbst" umleitet und dann eben selber durchführt, nur dass man bei gewünschten Funktionen eignene Adressen zurückgibt. Z.B wenn GetProcAddress,VBmodulhandle,_vbaCmpStr kommt, liefert man einfach die Adresse der eigenen Funktion zurück, und schon landet der Aufruf von dieser Funktiion erstmal bei uns. In beiden Fällen muss man im Speicher des "Ziel"Prozesses operieren.

was eben gehookt wird wenn zum beispiel versucht wird einen prozess zu verstecken.
Das ist ein heikles und schwieriges Thema (soweit man mehr machen will als nur Modu32lFirst hooken), vielleicht hilft Dir erstmals dieser Link weiter:http://www.buha.info/board/showthread.php?t=46275
 
Ah danke ich bin mir noch nicht sicher, ob ich es jetzt genau hab, aber ich denke so ergibt das alles sinn.

Kurz gesagt:
1. Die Import tabelle wird immer vom loader erstellt - egal ob ich "statisch" oder "manuell" lade.
2. Über die Imort tabelle wird aber nur gelinkt, wenn ich "statisch" auf die funktion zugreifen will - sonst mach ich den einsprung dirrekt.
3. GetProcAdress bekommt die position der funktion dann dirrekt aus der export tabelle der lib? - irgenwoher muß die api das ja auch wissen???
4. um sowohl die "statische" also auch die "manuelle" methode zu hooken muß man sowohl die importtabelle als auch die api funktionen hooken? - oder könnte man auch die export tabelle der .dll patchen und beides in einem machen?

Ich hab es inzwischen mal geschafft aus der import tabelle einer lib die importierten .dlls auszulesen - ich steh ja noch am anfang :).
Allerdings finde ich es interessant, daß ein spiel das ich damit dann überprüft hab die opengl32.dll garnicht importiert, aber trotzdem benutzt.
Ich hab dann nochmal mit dependiant walker nachgeschaut und meine funktion hat recht.
Wie geht das wieder? - Ich dachte eben die Import tabelle wird auf jeden fall erstellt auch wenn das spiel dirrekt mit getprocadress arbeitet? - wie soll man sonst auch einen hook machen?

Als letztes hab ich beobachtet, das der import struct scheinbar wie seiten hintereinander im speicher liegt. - also man immer den gesammten import struct überspingen muß um die nächste inportierte library zu bekommen.
Die rva der funktionen (thunks) aber dirrekt im jeweiligen record liegen. - Speichermäßig blick ich bei der konstruktion nicht ganz durch - ich weiß das es so ist aber es ist schwer zu begreifen :).

Ich schau mir mal das tut an
Danke
Verucca

Edit:
Ich hab jetzt mal versucht anstatt der module im prozess selbst die import table zu überprüfen.
Ich hab mir gedacht, ich könnte damit api hooks auf Modul32first umgehen.
Allerdings fehlt mir leider die erfahrung und auch ob man das überhaupt so kann.
in Delphi hätte ich versucht die ersten 1000 bytes des prozesses in den speicher zu laden, und mir dann den import sturct zu suchen.
Soweit bin ich garnicht gekommen, weil ich nicht weiß wo der prozess überhaupt anfängt :).

buf := VirtualAlloc(nil,$1000,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
ReadProc := OpenProcess(PROCESS_ALL_ACCESS,false,Pid);
ReadProcessMemory(ReadProc,pointer(Pid),buf,$1000,read);
CheckImports(buf);

was nicht stimmt ist wohl
hier bräuchte ich hald die startadresse von dem prozess.

Ist das jetzt kompletter unsinn :) oder eine gute idee?

Edit2:
Es ist eine blöde idee für alle die das mitlesen :)
Der Loader hat es nicht notwendig den header des prozesses selbst in den speicher zu laden - wozu auch lol.
Also das letzte edit vergessen!

Verucca
 
Kurz gesagt:
1. Die Import tabelle wird immer vom loader erstellt - egal ob ich "statisch" oder "manuell" lade.
ja (nicht erstellt, sondern ausgefüllt, wenn mans kleinlich nimmt ;) )
Über die Imort tabelle wird aber nur gelinkt, wenn ich "statisch" auf die funktion zugreifen will - sonst mach ich den einsprung dirrekt.
ja
3. GetProcAdress bekommt die position der funktion dann dirrekt aus der export tabelle der lib? - irgenwoher muß die api das ja auch wissen???
Wenn Du Lib=DLL meinst dann ja, ansonsten ist die Lib nur für den Linker da, wenn man die Funktonen "statisch" verlinkt.
Die Exporttabelle der DLL landet mit im Speicher. Ich weiß jetzt nicht mehr wie genau man diese findet(PE-mäßig meine ich), aber wenn Du eine miniDLL erstellst und sie lädst, wirst Du im Speicher die Exportierten Funktonen samt Adressen entdecken. Sieh auch meinen Link vorher. Vereinfachtes Bild wäre:
Code:
FunkAdresse1, FunkAdresse2, FunkAdresse3

FunkName1 ,FunkName2,FunkName3,
Und GetProcAddress sucht nur nach dem String den man übergibt.

Ich hab es inzwischen mal geschafft aus der import tabelle einer lib die importierten .dlls auszulesen - ich steh ja noch am anfang smile .
Allerdings finde ich es interessant, daß ein spiel das ich damit dann überprüft hab die opengl32.dll garnicht importiert, aber trotzdem benutzt.
Ich hab dann nochmal mit dependiant walker nachgeschaut und meine funktion hat recht.
Wie geht das wieder? - Ich dachte eben die Import tabelle wird auf jeden fall erstellt auch wenn das spiel dirrekt mit getprocadress arbeitet? - wie soll man sonst auch einen hook machen?
Da liegt ein Missverständiss vor: mit der "Importtabelle die auf jedenfall estellt wird", meinte ich dass eine Exe diese auch dann eine besitzt wenn sie alles über GetProcAddress macht - weil eben die GetProcAddress auch importiert werden muss. Aber in dieser findet sich dann eben nur der Eintrag für GetProcAddress. Der Rest ist dann "manuell". Man muss ja nur die LoadLibriary aufrufen, den Handle irgendwo verstauen und dann mit GetProcAddress die Adresse rausfinden.

Ich hatte eben in den Crackmes eine ähnliche Methode zum Hooken der VB Funktionen benutzt. Code und Anleitung stehen da.

Edit2:
Es ist eine blöde idee für alle die das mitlesen smile
Der Loader hat es nicht notwendig den header des prozesses selbst in den speicher zu laden - wozu auch lol.:
Sicher? Öffne Deine Exe im Olly und klick unten im Dumpfenster auf Goto->Expression, 400000h, Du wird überascht sein ;)
 
Also du hast recht auf adress 40000h befindet sich der header :)
aber trotzdem ist es dann sinnlos zu versuchen die importtable dirrekt aus dem prozess auszulesen, wenn man mit einem process hide programm ein verstecktes modul finden will.
eben nur der Eintrag für GetProcAddress.
was du mir damit ja auch bestätigt hast.

Um mir die hooks und den umgang mit den header files genauer vorstellen zu können, würde ich gerne ein programm schreiben, daß ITA (import table adress) hooks erkennt ( einen hook in einem anderen programm).

Daszu müsste ich doch eigentlich nur mit loadlibrary und getprocadress die .dll und die function in mein eigenes programm nachladen, danach die import tabelle aller geladenen .dll files in einem anderen prozess überprüfen.
1. ob die zu überprüfende .dll von einer anderen "hook.dll" geladen wurde
2. ob die adresse der funktion die ich überprüfen will die selbe ist, die ich selbst über getprocadress bekommen hab.

die Frage ist ob es theoretisch möglich wäre das zu vergleichen.
getprocadress liefert ja dirrekt die einsprungadresse der func.
die import table sollte eigentlich auch die gleiche adress liefern - wenn kein hook gemacht wurde.

Könnte das hinkommen?
Verucca

edit:
naja wenn ich drüber nachdenke dann ist es wohl doch besser die .dll aus dem zu prüfenden prozess auszulesen und in der import table zu schauen ob die adresse der function innerhalb der .dll liegt oder ausserhalb - veilleicht ist das der richtige ansatz...
 
Original von Verucca
aber ohne Registrierung kann man auch keine Beiträge lesen.
Ich weiß - ist auch unnötig - ich hab nichts gefunden das mir hinweise liefert was ein base hook sein soll. - vermutlich ist das ein terminus der sich dort eingebürgert hat.

meinst Du eventuell Module32Firs/ &Co vom CreateToolhelp32Snapshot ?
ja klar mein ich das
Bei einem Callback wird eine Fuktionsadresse übergeben...
ich hab mich nicht klar ausgedrückt - wie man die apis verwendet weiß ich genau - hab schon viel damit gearbeitet - keine ahnung wie ich auf getfirst/nextmodulehandle komme aber ich bin meißtens abends ziemlich müde lol.

Ich versuch vor allem zu begreifen wie windows das macht und was eben gehookt wird wenn zum beispiel versucht wird einen prozess zu verstecken.
Eigentlich hab ich nur nicht verstanden was du gemeint hast mit alle aufrufe landen in einem bestimmten adressbereich.
wenn du damit einfach nur die gemapte kernel32.dll meinst, daß die immer am gleichen ort liegt, dann ists mir klar :).

Mich interessieren die genauen abläufe wenn ich eine exportierte funktion in mein oder ein programm importiere ( kernel32.dll und die apis sag ich mal funktionieren dann wohl genau so)

1. wann gibt es eine import table - nur bei .dll's oder auch in .exe programmen?
( hab wenig erfahrung damit - hab nur mal teile der struktur ausgelesen).
2. wenn ich eine importierte function benutze, was passiert dann genau - es wird ja über den umweg der import table die funktion aufgerufen - was ja hooken erst möglich macht - mir ist einfach der ablauf hier nicht klar.

hoffentlich ergibt das sinn - ich bin tot müde und geh wohl schlafen :) gute nacht

Verucca


also ein base hook ist folgendes:
das ist nicht eine besondere art des hookens, sondern es ist der haupthook von einem hack, auf den alles aufgebaut wird.

wie schon gesagt es ist keine spezielle art!!!!


eine frage noch: woher willst du denn die import tables bekommen?

greetz
 
Daszu müsste ich doch eigentlich nur mit loadlibrary und getprocadress die .dll und die function in mein eigenes programm nachladen, danach die import tabelle aller geladenen .dll files in einem anderen prozess überprüfen.
1. ob die zu überprüfende .dll von einer anderen "hook.dll" geladen wurde
2. ob die adresse der funktion die ich überprüfen will die selbe ist, die ich selbst über getprocadress bekommen hab.
du vergisst aber, dass jemand die GetProcAddress selber hooken könnte und Dir somit auch da immer die falschen Adressen übergibt. Außerdem könnte jemand auch meinen die Zieladressen (also wo der Call landet) zu patchen und hier würde so eine überprüfung auch nichts nutzen ;) weil ja die Sprungadressen stimmen.
Wenn Du es trotzdem machen willst, brauchst Du im Prinzip nur je nach Compiler/Linker die Funktionen direkt zu bentutzen (zumindest die WinAPIs) um diese in die ITA zu bekommen.
Dann kannst Du ja auf 400000h gehen und dank PE die ITA finden (oder noch einfacher: mein MASM aktzeptiert auch so was:
mov eax,MessageBoxA
jetzt hat man eignetlich die Adresse von wo aus gejumpt wird (AFAIK auf die ITA tabelle)
also einen Zeiger auf JUMP XXXX (intern). in Hex FF 25 xx xx xx
also ein
add eax,2
mov eax,[eax]
mov eax,[eax]
liefert die Kerneladresse von MessageBox
am besten nachzuvollziehn im Olly.

Zu deinem Edit: ist auch eine nette Idee, aber man könnte wiederum die Zieladressen mit einem jmp patchen - und erst da, am ziel, auf seine Funktion umleiten.

eine frage noch: woher willst du denn die import tables bekommen?
Auslesen:
http://win32assembly.online.fr/pe-tut7.html
Oder eben den kleinen netten Trick mit dem import verwenden.
 
dass jemand die GetProcAddress selber hooken könnte
stimmt natürlich, aber dafür gibts natürlich auch gegenstrategien.
man könnte native apis verwenden, oder einen eigenen treiber.
die besste idee die ich bisher gehört habe ist, die ntdll.dll nochmal in den prozess laden unter anderem namen sozusagen und die dann einfach benutzen lol...

Zieladressen (also wo der Call landet) zu patchen
Ja stimmt, das wäre dann ein patchen der code section.
naja die code section kann man ja genauso prüfen - ich muß mir ja nur die adresse der function holen und die dann auslesen aus dem prozess und dann eben mit meiner selbst geladenen vergleichen.

Ganz ehrlich den rest hab ich nicht verstanden :).
Ich bin nicht sehr bewandert in den dingen - in c bin schlecht und ASM kenn ich grad mal die basis befehle :).

Naja ich bin ab morgen ne woche weg, aber danach würde ich das gerne ausprobieren was es da so an möglichkeiten gibt.

Verucca
 
Zurück
Oben