Code Cave in Ollydbg (MessageBox anzeigen)

06/29/2012 21:18 2n0w#1
Nen Abend, war gerade dabei die lena-Reversingtutorials durchzumachen, da habe ich Lust bekommen so eine Codecave zu verwenden, nachdem ich jetzt weiß was das ist ^.^
Habe dabei aber einige Probleme, und hoffe ihr könnt bzw. wollt mir dabei helfen :)
Habe eine Konsolen-Anwendung mit VS11 in C++ erstellt, die einen String einlist, denn dann mit einem Passwort vergleicht und eben eine Ausgabe macht ob die Eingabe übereinstimmt.
Mein Ziel ist es, falls das Passwort falsch war, eine MessageBox anzuzeigen.
Der Vergleich Eingabe mit Passwort sieht jetzt so aus (circa natürlich):
Code:
MOV EDX, xxxx ;ASCII "Richtiges Passwort"
TEST EAX, EAX
JE Ausgabe
MOV EDX, xxxxx ;ASCII "Falsches Passwort"
Ausgabe
Da hatte ich vor das MOV durch ein JMP zu meiner Codecave zu ersetzen.
Da habe ich schon das Problem, wohin jmpen?
Hatte einfach runtergescrollt bis zu freiem Speicher, das geht aber leider nicht da der freie Speicher ja bei jedem Neustart wo anderst anfängt, wie ich nach einem Crash von Olly bemerkt habe ;/
Ok, hätte ich mir denken können.
Die Idee die mir gerade eingefallen ist, wäre Speicher per VirtualAllocEx zu reservieren, sieht aber nach Arbeit aus.
Gibt's da einen einfacheren Weg? In C gebe es ja auch noch die Alloc Funktion, die sieht einfacher aus ^^
Um dann die MessageBox anzuzeigen muss ich wohl zuerst per LoadLibrary User32.dll laden, dann per GetModuleHandle und GetProcAdress die Adresse irgendwo speichern, danach mit CALL EAX oder so ähnlich ausführen, davor die Parameter in der umgekehrten Reihenfolge wie in der ApiHelp-Datei angegeben pushen. Die Konstanten wie MB_OK sind zum Glück eh auf msdn zu finden :)
Die ganzen Strings die daür notwendig werden, wollte ich auch in meinem dann reservierten Speicher unterbringen.
Die Frage ist jetzt, ist wie ich den reservieren soll, und ob mein Ansatz so auch stimmt.
Wobei mir gerade einfällt das ich da komplett falsch gedacht habe, wie soll ich den beim Erstellen dann wissen wohin mit dem Code? xD
Wird ja logischerweiße zur Laufzeit reserviert. *self-facepalm*
Danke schonmal im Voraus :)

mfg, 2n0w
06/30/2012 10:31 tnd0#2
Per CreateRemoteThreadEx eine lib injecten, die reserviert Speicher mittels VirtualAlloc und schreibt die opcodes darein. Dann VirtualProtect um den Speicher ausführbar zu machen. Und am ende dann mittels WriteProcessMemory den code oben durch einen call dahin ersetzen. Vorher ggf. auf die register achten. Sicherster und einfachster Weg.

Ohne Injection musst du halt mittels ReadProcessMemory dynamisch auf freien Speicher scannen.
06/30/2012 10:59 2n0w#3
Danke :)
Werde mir das nochmal anschauen und mich dann wieder melden.
Wobei ich mich gerade frage wo das CreateRemoteThread hin soll. Da hätte ich ja dann noch eine zweite Anwendung und die dll. Das bekomme ich also nicht alles in eine Datei, so wie ich das verstanden habe?
Und da habe ich noch ein weiteres Problem, ich ersetze hier ja dann das pushen von "Falsches Passwort", das wollte ich in der Codecave dann noch machen, scheitert aber daran das die Adresse die gepusht wird nach einem Neustart anders ist. Kann ich die irgendwie berechnen?
06/30/2012 11:21 MrSm!th#4
Warte, willst du nun eine Dll injizieren oder ne Codecave machen?
Bei Codecaves macht man sich doch nicht so ne riesen Arbeit alleine für die Allokation oO Einfach n Olly Plugin suchen, dass dir freien Speicher im Image sucht bzw. anlegt, das sollte nicht das Problem sein.

Was deine API Calls angeht: Da ist das Problem, dass du APIs halt nur mit der IAT callen kannst oder über das fs Register. Also entweder machst du es über den letzteren Shellcode-Weg oder du guckst dir an, an welcher Stelle in der IAT die API steht, die du suchst und nutzt halt das Offset.

Olly zeigt dir API Calls ja auch nur aus Analysezwecken mit Namen an, eigentlich steht da etwas wie call dword ptr [address] (siehst du auch, wenn du mal die Instruction bearbeiten willst).
Ich glaube, Olly übersetzt sogar zurück, man kann quasi bekannte APIs wie IsDebuggerPresent in der Form call Kernel32.IsDebuggerPresent callen und Olly setzt dann automatisch die entsprechende IAT Adresse ein, sodass du die nichtmal selbst nachsehen musst.

Ansonsten halt der Shell Code weg mit dem Register [fs:0x30], welches auf den TEB zeigt, über den du an den PEB kommst, welcher eine Liste mit den geladenen Dlls enthält.


Quote:
Danke
Werde mir das nochmal anschauen und mich dann wieder melden.
Wobei ich mich gerade frage wo das CreateRemoteThread hin soll. Da hätte ich ja dann noch eine zweite Anwendung und die dll. Das bekomme ich also nicht alles in eine Datei, so wie ich das verstanden habe?
Und da habe ich noch ein weiteres Problem, ich ersetze hier ja dann das pushen von "Falsches Passwort", das wollte ich in der Codecave dann noch machen, scheitert aber daran das die Adresse die gepusht wird nach einem Neustart anders ist. Kann ich die irgendwie berechnen?
Ja, er hat der quasi empfohlen, das ganze in einer Hochsprache entweder per Dll Injection oder per Code Injection via WriteProcessMemory zu machen. Kann sein, dass er nicht verstanden hat, dass du im Grunde das Image patchen willst.
06/30/2012 11:27 2n0w#5
Nein, ich will eine sinnlose MessageBox anzeigen und dann das Programm normal weiterlaufen lassen, und das per Codecave. :D
Und beim Jmp zur Codecave ersetze ich das mov von "Falsches Passwort" wodurch mir nach dem Anzeigen der sinnlosen MessageBox trotz falschen Passworts "Richtiges Passwort" angezeigt werden würde. Daher muss ich in meiner Codecave auch wieder "Falsches Passwort" in ecx moven. Hab da ein bisschen was durcheinanergebracht und pushen geschrieben ^^
Danke für den Tipp, werd mir so ein Plugin suchen.

Leider reserviert mein Plugin nur zur Laufzeit, muss ich erstmal ein anderes suchen.
Wegen dem API Call, würde ich schon gern per CALL MessageBoxA machen, lese gerade ein Tutorial wie man manuell den IAT verändert, damit ich das machen kann. Das kann ja noch kompliztiert werden, 25 Seiten ^^
So weit wie ich das bis jetzt verstanden habe, kann ich ja doch per LoadLibrary User32.dll laden, und dann per GetModuleHandle & GetProcAdress die Api ausführen?

Mir reicht's jetzt erstmal mit dem Zeugs, ich glaube ich mach lieber die Tutorials weiter ^^
Melde mich dann eventuell später wieder.
06/30/2012 13:04 tnd0#6
Stimmt, hatte jetzt gedacht er will es zur runtime patchen, me sorry.

Finde es leichter erst zu patchen wenn das image der PE im memory ist. Dann kann man immernoch jedes Byte einzeln ändern. Und man kann das Programm erstmal laufen lassen, so dass es sich entpackt oder decryptet, und muss sich nicht mit dem decrypten auseinandersetzen.
Außerdem muss man auch keine verbiegungen machen, wenn man methoden aus libraries detouren muss, weil man keine veränderte lib mitliefern muss sondern die einfach patcht, nachdem sie in den Speicher gemapped wurde (dank copy on write).

Und mit nur einem geringen Mehraufwand kann man den 'Patcher' und die Ziel-PE mergen, sodass der User kein extra Programm zum patchen starten muss.
06/30/2012 14:08 2n0w#7
Wie merge ich die denn? ^^
06/30/2012 14:46 tnd0#8
Mit der Windows command line z.B.:

Code:
> copy /b /y "a.exe" +"b.exe" "c.exe"
/b sagt dem copy Programm, dass wir Binärfiles kopieren
/y unterdrückt die ja/nein/vielleicht Abfrage ("Datei ersetzen? ja/nein/alle")
a.exe ist dein patcher
b.exe das zu patchende Programm
c.exe die gemergede exe

Wenn du jetzt c.exe startest, startet im Prinzip a.exe.
a.exe musst du jetzt noch so programmieren, dass es nach start sich selbst erneut via CreateProcess im suspended mode startet und dann vom ersten Prozess aus das b.exe aus sich selbst laden und via WriteProcessMemory in den gespawnten Prozess schreiben. Dann patchen und dann den Prozess resumen. Ggf. dann als debugger registrieren und breakpoints setzen um den neuen Prozess nur bis zu einem bestimmten Punkt laufen zu lassen (z.b. darauf zu warten dass er sich selbst decrypted hat) und wieder patchen,resumen. Dann kann sich der erste a.exe Prozess beenden und der 2te a.exe Prozess denkt er wäre b.exe.


Edit: lieber einen resourcecompiler benutzen als dos copy.
06/30/2012 16:35 MrSm!th#9
Ist zwar alles möglich (ich bevorzuge Runtime Patching auch), aber der TE macht ja nunmal gerade Olly Tutorials und will dementsprechend lernen, wie man Codecaves damit macht und das ist nunmal statisch.
Außerdem sollte sich ein Anfänger noch nicht um Packer etc. sorgen müssen.
06/30/2012 20:01 2n0w#10
Quote:
Originally Posted by MrSm!th View Post
Bei Codecaves macht man sich doch nicht so ne riesen Arbeit alleine für die Allokation oO Einfach n Olly Plugin suchen, dass dir freien Speicher im Image sucht bzw. anlegt, das sollte nicht das Problem sein.
Das ist jetzt doch das Problem, falls ich die statische Methode verwende.
Hab nur ein Addon gefunden das zur Laufzeit anlegt, da kann ich dann nicht speichern, oder verwendet man dafür so ein Dump-Plugin?
06/30/2012 23:14 MrSm!th#11
Könnte man. Aber es soll keine anlegen, sondern eine im Image finden (gibt immer mal Stellen, die nicht ausgefüllt sind).
Notfalls ließe sich sowas mit ein paar Informationen über das PE Format auch selbst basteln. Musst ja nur ein paar 0en an die Code Section anhängen und die Größe der Section im Header erhöhen und dann patchst du da halt deinen ASM Code rein (oder du machst direkt nen Patcher daraus und machst das ganze nicht per Olly, sondern schreibst sofort deinen Code da rein).
07/01/2012 13:06 tnd0#12
Also CodeCaves sind dinge wie Löcher. Ein Loch ist ja nichts, sondern das Fehlen von etwas. Welcher compiler würde absichtlich seine Executable aufblähen mit Code, den man ruhigen Gewissens überschreiben kann? Keiner, zwar werden ab und zu kleine Lücken gelassen um eben am 4K PageSize aligned zu sein, aber die sind oft nicht als Executable geflaggt oder zu kleine oder werden sogar vom Memory Manager des Programms für Daten benutzt. Und wenn erstmal ein Packer drübergelaufen ist, hast du eh keine chance mehr darauf.

Beim File patching müsstest du also die Executable erstmal anpassen um Platz für deinen eigenen Code dareinzubringen (merke: Code, nicht irgendwelche Daten, denn es geht ja darum, dass der Windows Image Loader deinen Code als solchen erkennt und ihn als Executable in den Speicher lädt, sonst hagelt es Access Violations). File patching ist vom Aufwand her also nur sinnvoll, wenn man am Ende weniger oder genau gleichviel Code hat (weniger kann man ja einfach mit NOP's füllen). Vielleicht findest du ja Code den du mit deinem Code ersetzen kannst? Oft vergessen Programmierer ihre Debugroutinen bei Release zu entfernen, die kann man immer ganz gut überschreiben.
07/01/2012 17:42 2n0w#13
Quote:
Originally Posted by tnd0 View Post
Vielleicht findest du ja Code den du mit deinem Code ersetzen kannst? Oft vergessen Programmierer ihre Debugroutinen bei Release zu entfernen, die kann man immer ganz gut überschreiben.
Du weißt schon noch das ich das Programm selbst geschrieben habe? ^^
Meinst du ich sollte eine Funktion einfügen die nicht ausgeführt wird oder so?
Dann könnte ich Optimierung ausschalten dann hätte ich Platz.. naja, das bringts auch nicht. Im Moment hab ich leider nicht viel Zeit, melde mich dann in ein par Tagen wieder.
07/01/2012 20:24 MrSm!th#14
Doch, MSVC zb. platziert gerne 5 (?) int3's zwischen Subroutinen.
Macht das Debugging leichter, weil man schneller Ende und Anfang von Funktionen sieht und man hat halt teilweise Platz für Codecaves.

Es gibt auch schonmal die ein oder andere Stelle die nur aus 0en besteht und trotzdem ausführbar ist (keine Daten). Hab ich selbst schon für Codecaves genutzt.