Entwickler-Ecke

Windows API - Kernel Hooks


Flamefire - Sa 31.10.09 14:24
Titel: Kernel Hooks
Hi,
nachdem ich mich seit längeren mit "normalen" Hooks beschäftigt habe, bin ich vor einer Weile auf Kernel Hooks gestoßen.
Speziell ging es darum, dass ein Kernel Hook (ich vermute zumindest, dass es einer ist) mir dadurch aufgefallen ist, dass er u.a. WriteProcessMemory verhindert, mit dem ich meinen Hook/Patch integrieren wollte. (Geht darum, die Sprache eines Programms zu verändern, was leider nicht wirklich vorgesehen ist)
Ok nachdem ich ne Weile gesucht und nichts gefunden habe, was mir da weiterhilft, habe ich es aufgegeben.

Jetzt kam aber in der Uni u.a. Kernel Mode, Ring0... dran
Da habe ich mich wieder an mein Problem erinnert und mich gewundert, was da los ist.

Kernel Mode i.A. ist dafür da, damit nicht jeder Prozess beliebig was an anderen Prozessen, OS-Fkt u.ä. machen kann. Wenn es aber so einfach ist, in den KernelMode zu kommen, INTx BP zu hooken und auf eigene Funktionen umzuleiten, wodurch man unbeschränkten (KernelMode) Zugriff hat, was bringt der dann?

Dann noch was produktives:
Wie lassen sich Kernel Hooks erkennen und vl beseitigen?
Kann mir jemand etwas zu lesen oder ein Tutorial zu Kernel Hooks empfehlen, wie das mit dem kernel genau funktioniert?
Soweit ich das verstanden habe, wäre ein Ablauf so:
Bsp: OpenProcess()
UserMode:
1)Parameter vorbereiten, INT auslösen
-->Kernel Mode
2)Stack prüfen, feststellen was es für eine Funktion ist, die aufgerufen werden soll
und NTOpenProcess aufrufen (OS-Fkt)
3) Rückkehr in den UserMode

Wenn ich jz also verhindern wöllte, dass jemand was mit meinem Prozess macht, hooke ich NTOpenProcess und gucke ob die PID mein ist. Wenn ja-->return -1

oder ist NTOpenProcess noch im UserMode eine OS-Fkt, die dann nen INT auslöst, wo dann die eigendlich Behandlung gemacht wird?


uall@ogc - Sa 31.10.09 15:24

Der Ablauf ist wie folgt (wenn ich mich jetzt nicht ganz irre, ist schon 2 Jahre her wo ich damit mal was gemacht habe):
kernel32.OpenProcess -> ntdll.NtOpenProcess -> sysenter/syscall/int (je nach Prozessor und Betriebssystem) [wechsel user -> kernelmode] -> Lookup in der SSDT -> win32k.NtOpenProcess -> IRET

"Normalerweise" hat man nur mit nem Teiber Zugriff auf kernelmode und Treiber können "normalerweise" nur vom Admin geladen werden. D.h. Ein Virus etc. kann die Funktionen nciht hooken weil der erst gar net in den kernel mode kommt. NtOpenProcess/writeProceessMemory etc. wird eigentlich von jedem AntiVirus Programm gehookt um das Beenden des AV zu unterbinden und z.B. bei einem NtCreateFile
aufruf wird die Datei gescannt.

In meinen HookUnits ist ein Ring0 hook eingebaut für Delphi ohne Treiber (funktioniert aber nur unter 2k/XP) und nicht in einer VM.
http://uall.cheat-project.com/uallCollection/

Edit1:
Mein Fireshield (ebenfals unter dem Link unter Examples) zeigt dir die Hooks an.
Ansonsten empfehle ich dir IceSword.

Für solche Sachen sollte dir http://www.rootkit.com weiterhelfen, glaub es gibt da auch ein gutes Buch zu (was ich allerdings nie gelesen habe)


Flamefire - Sa 31.10.09 16:29

was ist der unterschied zwischen den beiden ntOpenProcess?

dein fireshield hab ich mir angeguckt. musste zum compilieren n paar units von dir includen und ualldiasmneu rausnehmen, da nicht vorhanden
dann sagt er mir, dass angeblich alle einträge in der SSDT(1) gehookt sind (kann ich kaum glauben)
außerdem bekomme ich n paar fehler im Log:
"Error while initialzing rin0 modules"
"No export name" bei Ntoskrnl

und EProcess ist leer. (abbruch in der zeile: if (not ReadKernelMemory(@myEProcess,Pointer(fs124+EProcessOffset),SizeOf(DWord),False)) then
in uallring0)


SAiBOT - Sa 31.10.09 20:04

Unbedingt folgendes Buch anschauen!
[url=http://www.amazon.de/gp/product/3827325080?ie=UTF8&tag=evil03-21&linkCode=as2&camp=1638&creative=6742&creativeASIN=3827325080]user defined image[/url]


Timosch - So 01.11.09 00:01

Moderiert von user profile iconNarses: Komplett-Zitat des letzten Beitrags entfernt.

Kann ich nur zustimmen. Hab ich auch; ist ein sehr gutes Buch, wenn man sich mal tiefer mit der Materie befassen will. Der Titel ist recht einseitig und somit etwas irreführend. Das ist vermutlich auch das Buch, von dem uall@ogc gesprochen hat.


uall@ogc - So 01.11.09 15:26

Ja das meinte ich, außerdem sollte das Buch
Windows 2000 Internals noch ganz gut sein. Ist von Mark Russinovich (derjenige der bei MS die Sysinternals Programme programmiert).
Soviel ich weiß gobts noch ein 2. Buch von Greg Houghland (oder wie der heißt von Rootkits) heißt irgendwie GameHacking. Soll auch gut sein.
Hab die alle zwar nie gelesen aber nut gutes von gehört :)

Ich muß ehrlich sagen, dass ich Fireshield lange nicht mehr benutzt habe (gab sogar mal ne 2. Version) und hab wegem Zocken nur Vista drauf, kann dir also da im Moment nicht weiterhelfen.


Flamefire - So 01.11.09 18:33

ok ich werde mal zusehen, wo ich das herbekomme. klingt zumindest sehr intressant

als beispiel werde ich mal versuchen, mittels kernel hooks einen prozess nicht öffnen zu lassen (Openprocess immer -1) und das dann mit einem anderen programm umgehen.
denke wird ne gute übung sein...freu mich schon auf die BSODs xD

aber erstmal n bissl was lesen

Edit: habs bekommen :-)
anfang ist schon mal gut geschrieben. mal sehn wies weitergeht

Edit2:
Mal ne Frage an uall: woher hast du deine kenntnisse über den kernel? wie hast du deine hooks gemacht? mit welchem debugger kommt man in den Kernel (sysenter) rein?

Edit3:
Ich hab das hier gefunden: http://rootkit.com/blog.php?newsid = 958 (sry der link geht nicht direkt)
sehr intressent. zwar kein Kerneldebugger, aber er erkennt kernel Hooks, kann den kernel dasm und die hooks rückgängig machen.
Würde mich ja mal intressieren, wie der den hook erkennt und sogar rückgängig macht. *zu uall schiel*


Flamefire - Mi 04.11.09 11:18

ok also das buch ist echt relativ gut. auch wenn der code dazu mehr erklärt werden könnte. geht aber

dann aber ne frage:
ist es mit delphi SINNVOLL möglich treiber zu programmieren?
hab das DDDK 0.0.4 gefunden, aber da fehlen die meisten funktionen.
samples waren auch dazu. z.b. eins, dass zwOpenProcess hookt. funktioniert auch, nur leider fehlen wirklich viele funktionen und deklarationen. z.b. PSCurrentProcessId und mir ist es nicht gelungen, diese funktion einzubinden und auszuführen (BSOD)
Aber das WDK ist 2GB groß...Ohne VS oder andere IDE

desweiteren zum verständnis: mit uAllRing0 kann man mit einem UserMode Programm funktionen im KernelMode ausführen.
SSDT hooks dürften da aber ziemlich gefährlich sein. wenn das programm abstürzt oder unsauber beendet wird, zeigt der hook auf falschen speicher und man kriegt nen BS

Darum 3 Fragen dazu:
1) Kann man das ändern? Also iwo speicher allozieren, dort funktionen und Daten reinladen und von dort aus den Kernel hooken? Kann man den Code dann auch wieder entfernen, für den fall, dass das Programm abgestürzt ist?
2) Wie ist das überhaupt mit Daten bei nem KernelHook? Könnte ich auf globale Variablen meines Programms zugreifen, dass den SSDT hook gemacht wird?
Wie ist das dort mit den Virtuellen Adressen? woher weiß der SSDT handler, in welchem Kontext er die virtuellen adressen auflösen muss?
3) Hieß es im Buch, dass der Speicher eines Prozesses zum Teil auch KernelMode speicher ist. D.h. man kann in den KernelMode speicher schreiben, und die Adresse entspricht dann aber einer UserMode Adresse. Wie ist die Umrechnung?


uall@ogc - Mi 04.11.09 20:09

Treiber in Delphi sind nicht wirklich sinnvoll, rin theoretisch geht es (siehe DDDK) aber wie du sicherlich siehst musst du die meisten Funktionen selbst Deklarieren.
Wenn du Informatik studierst solltest du ja VS über MSDNAA bekommen, 2GB ist ja net nur der Source.

uallRing0 schreibt die Exe in den Kernelmode, so dass die gehookten Funktionen im Kernel sind und auch nach dem beenden des Programms funktionieren. Speicher wird dorch auch reserviert (weiß gerade den Namen der Funktion nicht). Zum reservieres des Speichers wird ein Teil zuerst ein Teil der win32k.sys überschrieben mit einem LoaderCode überschreiben (natürlich vorher gesichert). Dann wird ein Hook von zwOpenProcess erstellt (in der SSDT) der auf diesen Speicher verweist. Im Anschluss wird Openprocess mit einem speziellen Parameter aufgerufen, den der Loadercode abfängt (und somit weiß das es sich um den uallProcess handelt) und springt in den Code der EXE (d.h. der Code wird im Ring0 ausgeführt). Deser übernimmt die eigentlich Allozierung von Kernel Speicher und kopiert die Exe dorthin. Zm Schluss wird der OpenProcess hook entfernt und die win32k.sys komplett wieder hergestellt. Es ist ein wirlkicher Hack, den ich mir damals dafür ausgedacht habe es soll auch nur demonstrieren, dass man Code im Kernel ausführen kann.

Ein Umrechnung von Virtuellem und Physischen Speicher solte ebenfalls in uallRing0 vorhanden sein, auch im Kernel kannst du mit PSCurrentProcessID z.B. die akutelle ID von dem Prozess rausfinden der die zw* Funktion auferufen hat. Mit der EProcess Liste (ebenfalls in uallRin0 genauer erklärt) kannst du dann auf die einzelen Handles usw. zugreifen und sogar deinen Prozess daraus ausklinken (somit nicht mehr sichtbar). uallRing0 liest außerdem die ShadowTabelle aus (u.a. verweisen da die user32.dll und gdi32.dll Funktionen darauf). D.h. du kannst z.B. BitBlt hooken und verändern bzw. ExtEscape (opengl).


Flamefire - Mi 04.11.09 21:40

aber muss man nicht schon im kernel mode sein, um die win32k.sys und die SSDT zu überschreiben?

nja ich denke das beste bleibt, mit VS treiber zu erstellen.

BTW: es gibt ja auch den borland c++ builder
eignet sich der auch?

wie verwende ich das WDK mit der IDE?


Timosch - Mi 04.11.09 21:49

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:

nja ich denke das beste bleibt, mit VS treiber zu erstellen.

BTW: es gibt ja auch den borland c++ builder
eignet sich der auch?

Zum Treiber programmieren verwendet man das DDK von Microsoft.


SAiBOT - Do 05.11.09 08:26

Oder "Visual Studio" in Verbindung mit dem DDKWizard [http://ddkwizard.assarbad.net/]


uall@ogc - Do 05.11.09 20:32

Den Trick den ich benutze ist, dass man auf den kompletten Arbeitspeicher auch per CreateFileA / MemoryMapping zugreifen kann (\\PhysicalMemory). Dort kann man dann alles abändern (u.a. auch die win32k.sys). DIe muss man nur im Speicher finden.


Flamefire - Do 05.11.09 21:11

jo danke uall
habs gesehn.
hab mir heute mal die ganze unit angeguckt und für D2009 umgeschrieben (WideStrings >.<)
funktioniert auch soweit. gute idee mit dem memory scan für nach den dlls/treibern ;-)

nur aus irgendeinem grund funktioniert der scan nach den seitentabellen nicht (mehr)
findet sie nicht.
aber das ist für meine zwecke erst mal unwichtig.
de fakto kann ich mit dieser unit kernelspeicher allozieren, meinen code da rein kopieren und hooks dahin schreiben...brauch man ja keine treiber mehr ;-)

werd mir das mit den treiber trptzdem ma angucken. wie richtie ich VS für das WDK ein?


Flamefire - Fr 06.11.09 20:59

sry uall, muss speziell dich nochmal mit ner frage belästigen:
zur funktionsweise von EnterRing0viaSSDT

was ich daran sehe ist:
-funktionspointer in globale variable
-callbackfunktion in den pe-header der kerneldatei im speicher laden
-adresse und originalwert aus der ssdt in der funktion umändern
-funktion als nicht auslagerbar markieren
-ssdt eintrag ändern
-funktion im kernel aufrufen-->callback

-zurückschreiben des originalwertes und aufrufen der funktion (im kernelmodus)
-prüfen, ob alles ok und wiederherstellen des pe-headers

damit ist die funktion an sich doch aber nicht im kernelspeicher, sondern immernoch im process-speicher.
demzufolge ist die adresse der funktion eine virtuelle des prozesses.

warum funktioniert das dann? wie kann der im kernelmodus die virtuelle adresse auflösen? (besonders die der globalen variablen (die die funktion möglicherweise benutzt), die könnten ja sogar ausgelagert werden, oder?)
und selbst wenn der context im kernelmodus für diesen aufruf der des prozesses ist, würde das nicht abstürzen, wenn ein andrer prozess zufällig grade da die funktion aufruft (auch wenn unwahrscheinlich)?

dann die frage: gibts ne doku zu den funktionen?
bei der loadasdriver sehe ich, dass es eine dll,exe,sys in den kernelspeicher lädt (mit korrekten relocs)
nur, wie benutze ich das, und wie benutze ich dann die dll?
wäre es z.b. möglich eine dll zu schreiben, damit zu laden, dann eine funktion der dll aufzurufen, die dann andre funktionen hookt?
die dll müsste ja dann im kernelmodus laufen, oder kann die nur im kernelmodus aufgerufen werden (wodurch sie dann im kernelmodus läuft)?
was müsste ich da beachten (winapi calls werden ja dort dann nicht funktionieren, oder?)

PS: in dem zusammenhang bitte auch beachten [http://www.delphi-forum.de/viewtopic.php?p=583850#583850]


uall@ogc - Sa 07.11.09 13:03

Hi, wie gesagt ist lange her, ich hab mir gerade den code mal angeschaut:
EnterRing0viaSSDT

führt eine lokale Funktion aus (mit Virtuellen Adressen). Das Funktioniert deshalb, da der eigene Code in den Kernel springt. Dies wird über ProcessPriorität gemacht und über den Check über

Result := OpenProcess($1337, False, $1337) = $1337;

Wie erwähnt hooke ich OpenProcess in der SSDT, diese springt dann in die win32k.syss (die teilweise überschrieben wurde) dort ist ein check auf die parameter $1337 und nur wenn das stimmt wird die eigentliche Funktion aufgerufen (lokale funktion). Da es im selben Prozess funktioniert es. Im Grunde wird das aber nur verwendet um mittels MmAllocateContiguousMemorySSDT kernelspeicher zu holen. Der wird in LoadAsDriver verwendet um die eigene EXE dann in den Kernelspeicher zu schreiben (mit virtuellen Adressen > 0x80000000, eben Kernelmem). Ich weiß jetzt allerdings nicht ob diese dann direkt aufgelöst werden (sodass der Code dann im jeden Prozess funktioniert). Ist schon zulange her :) Zum ddk hab ich leider keine Ahnung :/


Assarbad - Mi 02.12.09 07:28

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
Kernel Mode i.A. ist dafür da, damit nicht jeder Prozess beliebig was an anderen Prozessen, OS-Fkt u.ä. machen kann. Wenn es aber so einfach ist, in den KernelMode zu kommen, INTx BP zu hooken und auf eigene Funktionen umzuleiten, wodurch man unbeschränkten (KernelMode) Zugriff hat, was bringt der dann?
Wie definierst Du "einfach"?

Es werden bestimmte Privilegien benötigt um überhaupt Treiber installieren zu können. Lieschen Müller als Normalnutzer hat da keine Chance, wenn der liebe Admin es nicht will. Für x64 (ab Vista) gibt es dann noch den Zwang zu signiertem Code. Und MS hat verfügt, daß diese Zertifikate nicht an Normalbürger rausgegeben werden.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
Wie lassen sich Kernel Hooks erkennen und vl beseitigen?
Kommt auf die Methode an. Beseitigen geht nicht (nicht == nicht ohne mit sehr hoher Wahrscheinlichkeit das System zum Absturz zu bringen).

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
Kann mir jemand etwas zu lesen oder ein Tutorial zu Kernel Hooks empfehlen, wie das mit dem kernel genau funktioniert?
"... damit ich mir endlich mein obercooles eigenes Rootkit basteln kann!" ???

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
Wenn ich jz also verhindern wöllte, dass jemand was mit meinem Prozess macht, hooke ich NTOpenProcess und gucke ob die PID mein ist. Wenn ja-->return -1
Ähem ... ein "falscher Schritt" und du hast nen schönen blauen Bildschirmschoner. Die entsprechenden Funktionen zum Testen ob es sich um gültigen Speicher handelt, funktionieren auch nicht immer und auf jedem IRQL. Aber für Malware reichts allemal. Stabilität ist da keine Anforderung. Weiß ich aus Erfahrung.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
oder ist NTOpenProcess noch im UserMode eine OS-Fkt, die dann nen INT auslöst, wo dann die eigendlich Behandlung gemacht wird?
Die Methode über Interrupts wurde mit Windows XP abgelöst. Intel (und AMD) haben dazu entsprechende Opcodes (siehe SYSENTER) bereitgestellt.

user profile iconuall@ogc hat folgendes geschrieben Zum zitierten Posting springen:
Der Ablauf ist wie folgt (wenn ich mich jetzt nicht ganz irre, ist schon 2 Jahre her wo ich damit mal was gemacht habe):
kernel32.OpenProcess -> ntdll.NtOpenProcess -> sysenter/syscall/int (je nach Prozessor und Betriebssystem) [wechsel user -> kernelmode] -> Lookup in der SSDT -> win32k.NtOpenProcess -> IRET
Fast. NTDLL "kennt" den Index in die SSDT, daher kein "Lookup". Ist auch eine der Methoden um die Indizes zu ermitteln ;)

user profile iconuall@ogc hat folgendes geschrieben Zum zitierten Posting springen:
NtOpenProcess/writeProceessMemory etc. wird eigentlich von jedem AntiVirus Programm gehookt um das Beenden des AV zu unterbinden und z.B. bei einem NtCreateFile aufruf wird die Datei gescannt.
Nicht von unserm. Und das absichtlich. Denn nicht nur den Virus hindert's, sondern auch den Admin. Ach ja ... und eigentlich ist es ohnehin Humbug, da die goldene Regel unter uns AVlern lautet: wenn ein System infiziert ist, ist's eh zu spät. Aber man versucht halt (im Rahmen des Möglichen) noch was zu machen.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
was ist der unterschied zwischen den beiden ntOpenProcess?
Das eine ist ein Stub und das andere die Implementierung. ZwOpenProcess und NtOpenProcess sind in der NTDLL die gleiche Funktion. in NTOSKRNL aber nicht. Dort überprüft die eine Funktion ob der Aufrufer aus dem Usermode kommt.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
dann sagt er mir, dass angeblich alle einträge in der SSDT(1) gehookt sind (kann ich kaum glauben)
Glaub's ruhig. In KAV habe ich aufgrund eines Themas in der Delphipraxis einen Bug gefunden und gemeldet. Dabei ging es um einen schlecht implementierten SSDT-Hook. Wenn du mehr wissen willst, solltest du bspw. auf Skywing's Blog nachlesen.

user profile iconTimosch hat folgendes geschrieben Zum zitierten Posting springen:
Kann ich nur zustimmen. Hab ich auch; ist ein sehr gutes Buch, wenn man sich mal tiefer mit der Materie befassen will. Der Titel ist recht einseitig und somit etwas irreführend. Das ist vermutlich auch das Buch, von dem uall@ogc gesprochen hat.
Eigentlich ist das Buch nicht sonderlich tiefgreifend. Als es rauskam wußten alljene die sich damit beschäftigt hatten schon die Methoden zu nutzen bzw. zu bekämpfen. Allein, nach der Veröffentlichung gab es einen sprunghaften Anstieg von Malware die sich mithilfe der dort beschriebenen Methoden versteckt. Juhu ... freies Wissen gibt's eben auch für kriminelle Idioten.

user profile iconuall@ogc hat folgendes geschrieben Zum zitierten Posting springen:
Ja das meinte ich, außerdem sollte das Buch
Windows 2000 Internals noch ganz gut sein. Ist von Mark Russinovich (derjenige der bei MS die Sysinternals Programme programmiert).
Ich hab's mir irgendwann bei Terrashop gekauft gehabt und es ist total oberflächlich. Klar, wenn man noch keinen Überblick über das System hat, dann hat man damit einen Volltreffer. Aber für alle die schon etwas tiefer in der Materie stecken ist es nicht zu gebrauchen. Üblicherweise werden die dort besprochenen Themen - grob gesagt - im ersten Kapitel der tiefergehenden Bücher "wiederholt" ;)

Empfehlen würde ich definitiv: "Windows NT/2000 Native API Reference" von Nebbett (stammt noch aus der Zeit als die Doku von MS karg war) und "Undocumented Windows 2000 Secrets" von Sven B. Schreiber, welches dieser in PDF-Form auf seiner Webseite anbietet. Die Bücher von OSR sind auch zu empfehlen.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
Soviel ich weiß gobts noch ein 2. Buch von Greg Houghland (oder wie der heißt von Rootkits) heißt irgendwie GameHacking. Soll auch gut sein.
"Exploiting Software" und "Exploiting Online Games".

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
mit welchem debugger kommt man in den Kernel (sysenter) rein?
Mit dem in Windows eingebauten. WinDbg ist dein Freund. SoftIce ist schon lange nicht mehr unterstützt und für meinen Geschmack sind alle Alternativen (es sei denn Du hast IDA schon gekauft) einfach schlecht.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
Würde mich ja mal intressieren, wie der den hook erkennt und sogar rückgängig macht. *zu uall schiel*
Guckst Du einfach mal in den System Virginity Verifier von Joanna Rutkowska. Es gibt noch dutzende andere Tools, oft auch mit Quellen. Und rückgängig ... naja ... jetzt schiel ich gleich.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
ok also das buch ist echt relativ gut. auch wenn der code dazu mehr erklärt werden könnte.
Dazu gibt es (und gab es auch schon 2005) ausreichende Quellen im Internet.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
ist es mit delphi SINNVOLL möglich treiber zu programmieren?
Nein.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
Aber das WDK ist 2GB groß...Ohne VS oder andere IDE
Es ist etwas mehr als 600 MiB und, ja, ohne IDE. Aber auch dein normaler Compiler kommt gut ohne IDE aus. Probier's mal ... (übrigens: sogar Delphi's Compiler kommt ohne IDE aus ;))

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
SSDT hooks dürften da aber ziemlich gefährlich sein. wenn das programm abstürzt oder unsauber beendet wird, zeigt der hook auf falschen speicher und man kriegt nen BS
Ach, und das ist es bei einem Multi-Threading, Multi-Core, Multi-Processor nicht? :lol:

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
woher weiß der SSDT handler, in welchem Kontext er die virtuellen adressen auflösen muss?
Auch hier hilft Nachlesen!

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
3) Hieß es im Buch, dass der Speicher eines Prozesses zum Teil auch KernelMode speicher ist. D.h. man kann in den KernelMode speicher schreiben, und die Adresse entspricht dann aber einer UserMode Adresse. Wie ist die Umrechnung?
Die funktioniert über MDLs ;) ... Nachlesen!

user profile iconuall@ogc hat folgendes geschrieben Zum zitierten Posting springen:
uallRing0 schreibt die Exe in den Kernelmode, [...], dass man Code im Kernel ausführen kann.
Klingt nach Exploit-Methoden :D ... so kennt man Brechi :wink:

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
aber muss man nicht schon im kernel mode sein, um die win32k.sys und die SSDT zu überschreiben?
Ja.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
nja ich denke das beste bleibt, mit VS treiber zu erstellen.
Nein! Bist Du des Teufels? Genau dazu gibt es die Compiler in den DDKs und WDKs. Und die unterscheiden sich in einigen Kleinigkeiten von denen in VS. Während Du also mit dem Compiler aus'm WDK gut auch UM-Code kompilieren kannst, solltest andersrum auf alle Fälle vermeiden.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
BTW: es gibt ja auch den borland c++ builder
eignet sich der auch?
Aaaaaargh!!!

user profile iconSAiBOT hat folgendes geschrieben Zum zitierten Posting springen:
Oder "Visual Studio" in Verbindung mit dem [url=http://ddkwizard.assarbad.net/]DDKWizard[/URL]
DDKWizard basiert aber auf den Diensten von DDKBUILD.CMD, welches wiederum das angeforderte DDK/WDK benutzt. Ob man nun aber VS oder was anderes als IDE nimmt, ist egal. Ich nehme mal an daher die Anführungszeichen?

user profile iconuall@ogc hat folgendes geschrieben Zum zitierten Posting springen:
Den Trick den ich benutze ist, dass man auf den kompletten Arbeitspeicher auch per CreateFileA / MemoryMapping zugreifen kann (\\PhysicalMemory). Dort kann man dann alles abändern (u.a. auch die win32k.sys). DIe muss man nur im Speicher finden.
... und Zugriff haben ;)

user profile iconuall@ogc hat folgendes geschrieben Zum zitierten Posting springen:
[...] in den Kernelspeicher zu schreiben (mit virtuellen Adressen > 0x80000000, eben Kernelmem). Ich weiß jetzt allerdings nicht ob diese dann direkt aufgelöst werden (sodass der Code dann im jeden Prozess funktioniert).
Ja, sollte.


Flamefire - Mi 02.12.09 11:44

danke nochmal für die (lange) antwort.

hab schon meine ersten bsp treiber geschrieben, kann damit kommunizieren und z.b. die SSDT hooken und fremde hooks entfernen (ok entfernen geht zugegebenermaßen auch mit uallring0 aus dem usermode ;-) )
aber hab halt alles mal als treiber gemacht.

mir gehts tatsächlich nicht um ein eigenes rootkit, sondern zum eigenen schutz bzw fremden schutz zun entfernen (über gamehacking lernt es sich halt am besten, da man da motivation hat und gleich was sieht ;-) )

und treiber erstelle ich mit "Visual Studio"...bzw: schreiben in VS und compilieren mit WDK


Assarbad - Mi 02.12.09 14:57

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
hab schon meine ersten bsp treiber geschrieben, kann damit kommunizieren und z.b. die SSDT hooken und fremde hooks entfernen (ok entfernen geht zugegebenermaßen auch mit uallring0 aus dem usermode ;-) )
Auch uallring0 muß den Code erstmal in den KM schaufeln und ihn dort ausführen. Nur an eine im KM verfügbare Adresse zu springen bringt reineweg garnix. Daher macht (sehr wahrscheinlich) auch uallring0 die relevanten Dinge im KM. Da solche Hacks im allgemeinen nur funktionieren bis die jeweilige "Lücke" behoben ist, beschäftige ich mich mit ihnen nur wenn ich muß :lol:

ABER: zum Thema Hooks entfernen. Soll ich mich wiederholen oder liegt Dir die Stabilität deines Systems (oder dessen auf dem Dein Code läuft) nicht am Herzen?

Hier mal nur ein paar wenige Fehlerquellen. Wir nehmen an, daß Du einen SSDT-Hook implementiert hast. Der Zeiger am entsprechenden Index zeigt aber, da Du ja vorsichtig bist/warst, nicht direkt auf deine Funktion sondern bspw. auf ein Jumppad (einfach allozierter Speicher den Du nie wieder freigibst oder eine Lücke in einem Kernelmodul, bspw. NTOSKRNL).

Beim Hooken oder davor könntest Du folgende Probleme haben:


Nach dem Hooken, bzw. beim Entfernen:


Und hier noch der Direktlink [http://www.nynaeve.net/?p=210] auf Skywing's Blog auf den ich Dich schon zuvor verwies. Und jetzt kommst Du!

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
mir gehts tatsächlich nicht um ein eigenes rootkit, sondern zum eigenen schutz bzw fremden schutz zun entfernen (über gamehacking lernt es sich halt am besten, da man da motivation hat und gleich was sieht ;-) )
Überprüfen kann ich es nicht und letztendlich ist es mir vermutlich auch egal. Ich habe nur eben wöchentlich mit Rootkits zu tun und die meisten davon sind einfach nur schlecht programmiert. Es gibt allerdings auch durchaus elegante ...


cisum - Mi 02.12.09 15:57

user profile iconSAiBOT hat folgendes geschrieben Zum zitierten Posting springen:
Unbedingt folgendes Buch anschauen!
[url=http://www.amazon.de/gp/product/3827325080?ie=UTF8&tag=evil03-21&linkCode=as2&camp=1638&creative=6742&creativeASIN=3827325080]user defined image[/url]


Leider konnte ich bisher keinen Shop finden, in dem dieses Buch noch verfügbar ist.
kennt ihr vielleicht einen, in dem es das Buch noch gibt oder will vielleicht jemand dieses Buch loswerden?

Vielen Dank im Vorraus!


Flamefire - Mi 02.12.09 16:44

sry aber ich bin echt neu in dem gebiet...darum bisher kein spinlock verwendet
spinlock ist doch dafür da, dass man mehrere threads synchronisiert.
durch interlockedexchange macht das doch aber das betriebssystem, oder irre ich mich da?

so viel zum hooken, jetzt zum unhooken von der SSDT, die unbekannt gehookt ist:

die originalfunktionsadresse (also der pointer, der in der SSDT stehen müsste) ist bekannt (auslesen aus der kernel-exe)
-->kein problem, den pointer auf ungültigen mist zu setzen
-spinlock unnötig, basierend auf obiger annahme
-wenn jmd andres vorher entfernt hat, änder ich nix mehr
-originaladresse bekannt->kein prob
-gegen solche annahmen, wie dass eine gehookte funktion auf einer andren gehookt basiert, kann ich nix machen.
einzige variante um das halbwegs auszumerzen wäre, alle prozessoren zu locken (IRQL erhöhen) und dann erst zu enthooken
bringt immer noch probleme, wenn ein aufruf gerade mittendrin ist...in meinen problemen bisher aber kein thema. ich kann annehmen, dass das nicht der fall ist.

"Rootkit" ist i.A. ja schon ein treiber, der bestimmten zugriff verhindert. ich versuche derzeit das "rootkit" XTrap auszuschalten...

was (leider) auch viel zu einfach möglich war, ist den antivir service zu beenden (aus usermode ohne treiber, aber mit adminrechten unter xpSP3), was ich als test mal gemacht hatte. antivir hat mein programm nicht bemängelt o.ä. nichtmal als verdächtig

und zu uallring0: es ging um das entfernen. und da reicht es schreibzugriff auf kernelspeicher zu erhalten. und das geht mit adminrechten über mapping recht elegant. im internet kursieren noch einige anleitungen zu ähnlichen vorgehensweisen über \\physicalmemory (oder so)

PS: das buch hab ich z.b. aus der slub geliehen ;-)


Assarbad - Mi 02.12.09 18:37

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
sry aber ich bin echt neu in dem gebiet...darum bisher kein spinlock verwendet
spinlock ist doch dafür da, dass man mehrere threads synchronisiert.
Spinlocks sind dazu da, dass kein anderer Prozessor (oder Kern) zu diesem Zeitpunkt was machen kann.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
durch interlockedexchange macht das doch aber das betriebssystem, oder irre ich mich da?
Implementiert wird das auf CPU-Ebene indem der Adressbus fuer die Dauer eines Opcodes gesperrt wird, wenn ich mich recht entsinne.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
die originalfunktionsadresse (also der pointer, der in der SSDT stehen müsste) ist bekannt (auslesen aus der kernel-exe)
Aus welcher "kernel-exe" [http://en.wikipedia.org/wiki/Ntoskrnl#Names_of_kernel]?

Zum Rest auessere ich mich nicht mehr. Es scheint sinnlos zu sein. Viel "Erfolg".


Flamefire - Mi 02.12.09 19:49

öhm. sry. wollte dich nicht vergraulen. ich hab nur einen teil gelesen und leite daraus (für mich) logische schlüsse ab.
wenn ich mich in irgendeinem punkt vertan habe, dann würde ich mich schon über berichtigungen freuen.

denn z.b. wozu brauche ich ein spinlock, wenn der komplette adressbus gesperrt ist? besser kann man doch kaum schützen, oder?
spinlocks basieren eh auf den interlocked-funktionen (oder auf vergleichbaren, da sonst die sperrvariable zum problem wird)

mit "kernel-exe" meinte ich die derzeit geladenen. das ermittle ich per QuerySystemInformation. wollte damit eben genau das andeuten, dass ich auch die richtige nehme.

das einzige problem bei enthooken sehe ich nur, dass ein laufender aufruf von einem anderen abhängt, der gerade entfernt wurde

wie gesagt: nimm bitte meine äußerungen nicht als "was du sagst intressiert mich nicht" o.ä. sondern ich versuche nur, darzustellen und zu erklären, was ich bisher kenne.


Assarbad - Mi 02.12.09 20:43

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
denn z.b. wozu brauche ich ein spinlock, wenn der komplette adressbus gesperrt ist? besser kann man doch kaum schützen, oder?
Ich konkretisiere:

user profile iconAssarbad hat folgendes geschrieben Zum zitierten Posting springen:
Implementiert wird das auf CPU-Ebene indem der Adressbus fuer die Dauer eines Opcodes gesperrt wird, wenn ich mich recht entsinne.


Sowas sieht dann so [http://ref.x86asm.net/geek.html#xF0] aus:

Quelltext
1:
lock xadd [ecx], eax                    


user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
spinlocks basieren eh auf den interlocked-funktionen (oder auf vergleichbaren, da sonst die sperrvariable zum problem wird)
Das ist hardware-spezifisch und daher im HAL. Fuer x86 basiert der Teil auf BTS [http://ref.x86asm.net/geek.html#x0FAB] (mit LOCK Praefix). Und wenn ich das in IDA jetzt auf die Schnelle korrekt gesehen habe, wird danach der PAUSE-Opcode [http://cache-http://www.intel.com/cd/00/00/01/76/17689_w_spinlock.pdf] benutzt um den Prozessor schlafenzulegen.

Zitat:
Description
Improves the performance of spin-wait loops. When executing a “spin-wait loop,” a Pentium 4 or Intel Xeon processor suffers a severe performance penalty when exiting the loop because it detects a possible memory order violation. The PAUSE instruction provides a hint to the processor that the code sequence is a spin-wait loop. The processor uses this hint to avoid the memory order violation in most situations, which greatly improves processor performance. For this reason, it is recommended that a PAUSE instruction be placed in all spin-wait loops.
An additional function of the PAUSE instruction is to reduce the power consumed by a Pentium 4 processor while executing a spin loop. The Pentium 4 processor can execute a spin-wait loop extremely quickly, causing the processor to consume a lot of power while it waits for the resource it is spinning on to become available. Inserting a pause instruction in a spin-wait loop greatly reduces the processor’s power consumption.
This instruction was introduced in the Pentium 4 processors, but is backward compatible
with all IA-32 processors. In earlier IA-32 processors, the PAUSE instruction operates like a NOP instruction. The Pentium 4 and Intel Xeon processors implement the PAUSE instruction as a pre-defined delay. The delay is finite and can be zero for some processors. This instruction does not change the architectural state of the processor (that is, it performs essentially a delaying no-op operation).
This instruction’s operation is the same in non-64-bit modes and 64-bit mode.
([url=http://www.intel.com/Assets/pdf/manual/253667.pdf]Quelle[/url])


user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
mit "kernel-exe" meinte ich die derzeit geladenen. das ermittle ich per QuerySystemInformation. wollte damit eben genau das andeuten, dass ich auch die richtige nehme.
Dann ist der Teil i.O.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
das einzige problem bei enthooken sehe ich nur, dass ein laufender aufruf von einem anderen abhängt, der gerade entfernt wurde
Und wie willst Du das unter Kontrolle bekommen? Und vor allem sollte der Beitrag von Skywing [http://www.nynaeve.net/?p=210] hier vielleicht mal bei Dir gesunde Zweifel an dem was Du versuchst aufkommen lassen (irgendwie zweifelst Du scheinbar zuerst an Fakten oder Aussagen anderer und dann an Deinen Ideen). Dazu vielleicht nochmal direkt der Link [http://www.osronline.com/showThread.cfm?link=56683#T2] zur NTDEV-Liste wo ich 2004 (also bevor ich beruflich mit Treibern zu tun hatte) von Don Burn zusammengeschissen wurde. Das Thema hat Skywing von seinem Beitrag aus verlinkt. Also: einfach mal zuerst das NTDEV-Thema von 2004 und danach den Blogbeitrag von Skywing zu Gemuete fuehren und danach reden wir weiter.


Flamefire - Do 03.12.09 00:00

was ist der nutzen eines spinlocks gegenüber der interlocked operation beim enthooken unabhängiger funktionen (also ohne den sonderfall, das eine gehookte funktion, von einer anderen abhängig ist)

den sonderfall unter Kontrolle zu bekommen, ist, (denke ich) nicht möglich. AFAIK ist es nicht möglich, festzustellen, ob ein prozess gerade in einer funktion ist, und wenn ja, diesen daraus zu "entlassen" und dann erst weiterzumachen (ok...alle PEB->unterstrukturen auf EIP prüfen und ggfls warten wäre ne variante aber immer noch unsicher)

den blogbeitrag hab ich gelesen. recht intressant, auch wenn ich bei einigen teilen nicht ganz mitkomme.

z.B. den teil, warum ein SSDT hook per pointer modification zu nem deadlock führt

i.A. sind die fehler im code zu ca 50% synchronisierungsprobleme...die hat man fast immer ;-)
der rest ist...unvorsichtiges zeug. also zb das mit dem status, und dem kernel handle

aber echt nicht schlecht. an vieles denkt man wirklich nicht so schnell


Assarbad - Do 03.12.09 01:44

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
was ist der nutzen eines spinlocks gegenüber der interlocked operation beim enthooken unabhängiger funktionen (also ohne den sonderfall, das eine gehookte funktion, von einer anderen abhängig ist)
Die Tatsache, dass das Entfernen kaum mit einer einzigen Aktion (also einem Opcode) geschehen kann. Oder habe ich was verpasst?

Wie gesagt, wenn es sich um was handelt was deine Rechner nie verlaesst, ist die Stabilitaet ja auch zweitrangig. Aber beim Kunden brauchste auch mit einer Sicherheitsanwendung nicht antanzen wenn bei deren Benutzung u.U. der Server blau macht ... und wie oft oeffentlich zugaenglicher aber nur prototypenreifer Code mal eben in kommerziellen Anwendungen landet will ich garnicht wissen. ... auch nicht an wievielen der kommerziellen Anwendungen Menschenleben haengen.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
i.A. sind die fehler im code zu ca 50% synchronisierungsprobleme...die hat man fast immer ;-)
... nur dass sie im Kernelmode zu einem Systemabsturz fuehren, im Usermode aber "nur" zu einem Programmabsturz. Und deine bisherigen Einwuerfe klangen nicht danach dass Du auch nur die "offensichtlichen" Probleme alle erkannt haettest ;)


Flamefire - Do 03.12.09 08:30

ähm...das entfernen läuft so:
-herausfinden der adresse des eintrags in der ssdt (offset)
-herausfinden des originalptr
-schreiben das originalptr an die adresse

kritischer abschnitt ist das letzte. durch interlocked funktioniert das. rest kann nicht verändert werden
damit habe ich nur einen opcode, oder?

ja ich weiß...programmfehler im treiber-->bsod
hatte ich oft genug. aber probier ja noch rum um erst mal gut reinzukommen. inzwischen krieg ich aber die teile recht gut hin ohne bsod. bisher noch ohne validation aber das kommt ja noch. und für meine anwendung wird das ding nicht sehr groß, wodurch es da (hoffentlich) kaum probleme zu suchen gibt.


Assarbad - Do 03.12.09 15:48

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
ähm...das entfernen läuft so:
-herausfinden der adresse des eintrags in der ssdt (offset)
-herausfinden des originalptr
-schreiben das originalptr an die adresse

kritischer abschnitt ist das letzte. durch interlocked funktioniert das. rest kann nicht verändert werden
damit habe ich nur einen opcode, oder?
Und wo bleibt das Überprüfen ob jemand schon vor Dir dran rumgefummelt hat? Nichtmal InterlockedCompareExchange bekommt das hin. Das Ergebnis des Vergleichs bekommst Du so höchstens nach der Austauschaktion. Aber ist ja okay, war ja nur ein kleines Detail von dutzenden die man übersehen könnte ...

So, das war jetzt mein letzter Beitrag zum Thema . Wir haben es lange genug durchgekaut. Das Szenario mit dem Überprüfen vor Austausch übrigens auch, aber das hattest Du innerhalb weniger Beiträge wieder "vergessen".

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
bisher noch ohne validation aber das kommt ja noch. und für meine anwendung wird das ding nicht sehr groß, wodurch es da (hoffentlich) kaum probleme zu suchen gibt.
Eins noch. Wenn Du Validierung über's WHQL meinst, informier Dich lieber vorher nochmals, sonst könnte Dein Geschäftsmodell infrage stehen. Treiber für VIsta und neue müssen übrigens immer als x86 und x64 bereitstehen, was mit KM-Hooks und Patchguard ab Vista x64 nicht mehr so einfach ist.


Flamefire - Do 03.12.09 17:54

als validierung meinte ich hier eine mehr oder weniger vollständige analyse des codes auf fehler wie den besprochenen, bzw im blog genannten.

ich verstehe immer noch nicht, was ich denn bei der SSDT überprüfen sollte?

ich lese. vergleiche den gelesenen wert mit dem original. alles in meinem speicher, den ich einfach mal als konsistent und nicht von außen veränderlich ansehe. (man kann ja davon ausgehen, dass niemand grade in seinem laufenden programm variablen ändert, und wenn doch, ist das nicht mein problem)
wenn vergleich negativ-->ssdt eintrag gehookt-->enthooken
ob den da schon jmd vorher enthookt hat, ist mir doch egal. dann überschreibe ich halt den originaleintrag mit dem originaleintrag...passiert doch nix, oder?

darum habe ich das nicht vergessen, sondern mit obiger argumentation als nicht sinnvoll angesehn.