Ich versuche, etwas über Reverse Engineering zu lernen, indem ich Minesweeper als Beispielanwendung verwende. Ich habe diesen MSDN-Artikel in einem einfachen WinDbg-Befehl gefunden, der alle Minen enthüllt, aber er ist alt, wird nicht im Detail erklärt und ist wirklich nicht das, wonach ich suche.
Ich habe IDA Pro Disassembler und den WinDbg-Debugger und ich habe winmine.exe in beide geladen. Kann jemand einige praktische Tipps für eines dieser Programme geben, um den Ort der Datenstruktur zu finden, die das Minenfeld darstellt?
In WinDbg kann ich Haltepunkte setzen, aber es fällt mir schwer, mir vorzustellen, an welchem Punkt ein Haltepunkt gesetzt werden soll und an welchem Speicherort. Wenn ich den statischen Code in IDA Pro ansehe, bin ich mir nicht sicher, wo ich überhaupt anfangen soll, die Funktion oder Datenstruktur zu finden, die das Minenfeld darstellt.
Gibt es Reverse Engineers bei Stackoverflow, die mich in die richtige Richtung weisen können?
quelle
Antworten:
Teil 1 von 3
Wenn Sie sich ernsthaft mit Reverse Engineering beschäftigen, vergessen Sie Trainer und Cheat-Engines.
Ein guter Reverse Engineer sollte zuerst das Betriebssystem, die Kernfunktionen der API, die allgemeine Programmstruktur (was ist eine Ausführungsschleife, Windows-Strukturen, Routinen zur Ereignisbehandlung) und das Dateiformat (PE) kennenlernen. Petzolds Klassiker "Programming Windows" können helfen (www.amazon.com/exec/obidos/ISBN=157231995X) sowie Online-MSDN.
Zuerst sollten Sie sich überlegen, wo die Minenfeld-Initialisierungsroutine aufgerufen werden kann. Ich dachte an Folgendes:
Ich beschloss, den F2-Beschleunigerbefehl zu überprüfen.
Um den Code für die Handhabung von Beschleunigern zu finden, müssen Sie die Prozedur für die Behandlung von Fensternachrichten (WndProc) suchen. Es kann durch CreateWindowEx- und RegisterClass-Aufrufe zurückverfolgt werden.
Lesen:
Öffnen Sie das IDA-Fenster "Importe", suchen Sie "CreateWindow *", springen Sie dorthin und verwenden Sie den Befehl "Jump xref to operand (X)", um zu sehen, wo es aufgerufen wird. Es sollte nur einen Anruf geben.
Suchen Sie oben nach der RegisterClass-Funktion und ihrem Parameter WndClass.lpfnWndProc. In meinem Fall habe ich bereits die Funktion mainWndProc benannt.
Drücken Sie die Eingabetaste für den Funktionsnamen (verwenden Sie 'N', um ihn in etwas Besseres umzubenennen).
Nun schauen Sie sich an
Dies ist die Nachrichten-ID, die bei Drücken der Taste F2 den Wert WM_COMMAND enthalten sollte. Sie müssen herausfinden, wo es mit 111h verglichen wird. Dies kann entweder durch Aufspüren von edx in IDA oder durch Festlegen eines bedingten Haltepunkts erfolgen in WinDbg und Drücken von F2 im Spiel erfolgen.
So oder so führt zu so etwas
Klicken Sie mit der rechten Maustaste auf 111h und verwenden Sie "Symbolische Konstante" -> "Standardmäßige symbolische Konstante verwenden", geben Sie WM_ und Enter ein. Das solltest du jetzt haben
Es ist eine einfache Möglichkeit, Nachrichten-ID-Werte herauszufinden.
Informationen zum Handling des Gaspedals finden Sie unter:
Es ist ziemlich viel Text für eine einzelne Antwort. Wenn Sie interessiert sind, kann ich noch ein paar Beiträge schreiben. Langes, kurzes Minenfeld, gespeichert als Array von Bytes [24x36], 0x0F zeigt, dass Byte nicht verwendet wird (kleineres Feld spielen), 0x10 - leeres Feld, 0x80 - Mine.
Teil 2 von 3
Ok, lass uns mit der F2-Taste weitermachen.
Gemäß Verwenden von Tastaturbeschleunigern, wenn die Taste F2 gedrückt wird, wndProc-Funktion
Ok, wir haben bereits gefunden, wo WM_COMMAND verarbeitet wird, aber wie kann der entsprechende wParam-Parameterwert ermittelt werden? Hier kommt der Resource Hacker ins Spiel. Füttere es mit Binär und es zeigt dir alles. Wie Beschleunigertisch für mich.
Alternativtext http://files.getdropbox.com/u/1478671/2009-07-29_161532.jpg
Sie können hier sehen, dass die F2-Taste 510 in wParam entspricht.
Kommen wir nun zum Code zurück, der WM_COMMAND behandelt. Es vergleicht wParam mit verschiedenen Konstanten.
Verwenden Sie das Kontextmenü oder die Tastenkombination 'H', um Dezimalwerte anzuzeigen, und Sie können unseren Sprung sehen
Es führt zu einem Codeblock, der einen Prozess aufruft und wndProc beendet.
Ist das die Funktion, die ein neues Spiel initiiert? Finden Sie das im letzten Teil heraus! Bleib dran.
Teil 3 von 3
Werfen wir einen Blick auf den ersten Teil dieser Funktion
Es gibt zwei Werte (dword_10056AC, uValue), die in die Register eax und ecx eingelesen und mit zwei weiteren Werten verglichen werden (dword_1005164, dword_1005338).
Sehen Sie sich die tatsächlichen Werte mit WinDBG an ('bp 01003696'; bei Pause 'p eax; p ecx') - sie schienen mir Minenfelddimensionen zu sein. Das Spielen mit der benutzerdefinierten Minenfeldgröße zeigte, dass das erste Paar neue Dimensionen und das zweite aktuelle Dimensionen sind. Setzen wir neue Namen.
Wenig später werden neue Werte zum Überschreiben von Strom und Unterprogramm aufgerufen
Und als ich es sah
Ich war mir völlig sicher, dass ich ein Minenfeld-Array gefunden habe. Ursache des Zyklus, der ein Array mit einer Länge von 360 Stunden (dword_1005340) mit 0xF einleitet.
Warum 360h = 864? Es gibt einige Hinweise darunter, dass die Zeile 32 Bytes benötigt und 864 durch 32 geteilt werden kann, sodass das Array 27 * 32 Zellen enthalten kann (obwohl die Benutzeroberfläche maximal 24 * 30 Felder zulässt, wird das Array für Ränder mit einem Byte aufgefüllt).
Der folgende Code generiert obere und untere Minenfeldränder (0x10 Byte). Ich hoffe, Sie können Schleifeniteration in diesem Durcheinander sehen;) Ich musste Papier und Stift verwenden
Und der Rest des Unterprogramms zeichnet linke und rechte Grenzen
Durch die intelligente Verwendung von WinDBG-Befehlen erhalten Sie einen coolen Minenfeld-Dump (benutzerdefinierte Größe 9x9). Schauen Sie sich die Grenzen an!
Hmm, es sieht so aus, als würde ich einen weiteren Beitrag brauchen, um das Thema zu schließen
quelle
Es scheint, als würden Sie versuchen, die Quelle zu zerlegen, aber Sie müssen sich nur den Speicherplatz des laufenden Programms ansehen. Der Hex-Editor HxD verfügt über eine Funktion, mit der Sie genau das tun können .
Sobald Sie sich im Speicherbereich befinden, müssen Sie Schnappschüsse des Speichers erstellen, während Sie mit dem Board herumspielen. Isolieren Sie, was sich ändert und was nicht. Wenn Sie der Meinung sind, dass Sie wissen, wo sich die Datenstruktur im Hex-Speicher befindet, versuchen Sie, sie zu bearbeiten, während sie sich im Speicher befindet, und prüfen Sie, ob sich die Karte dadurch ändert.
Der gewünschte Prozess ist nicht anders als der Aufbau eines "Trainers" für ein Videospiel. Diese basieren normalerweise darauf, herauszufinden, wo Werte wie Gesundheit und Munition im Gedächtnis leben, und sie im laufenden Betrieb zu ändern. Möglicherweise finden Sie einige gute Tutorials zum Erstellen von Spieltrainern.
quelle
Schauen Sie sich diesen Artikel zum Codeprojekt an, er ist etwas ausführlicher als der von Ihnen erwähnte Blog-Beitrag.
http://www.codeproject.com/KB/trace/minememoryreader.aspx
Bearbeiten
Und dieser Artikel, obwohl nicht direkt über Minensuchboot, gibt Ihnen eine gute Schritt-für-Schritt-Anleitung zum Durchsuchen des Speichers mit WinDbg:
http://www.codingthewheel.com/archives/extracting-hidden-text-with-windbg
Bearbeiten 2
Auch hier geht es nicht um Minensuchboot, aber es hat mir definitiv einige Denkanstöße für mein Speicher-Debugging gegeben. Hier gibt es eine Fülle von Tutorials:
http://memoryhacking.com/forums/index.php
Laden Sie auch CheatEngine (von Nick D. erwähnt) herunter und arbeiten Sie das mitgelieferte Tutorial durch.
quelle
Genau!
Nun, Sie können nach Routinen wie random () suchen, die während der Erstellung der Minentabelle aufgerufen werden. Dieses Buch hat mir sehr geholfen, als ich mit Reverse Engineering experimentiert habe. :) :)
Gute Orte zum Setzen von Haltepunkten sind im Allgemeinen Aufrufe von Meldungsfeldern, Aufrufe zum Abspielen eines Sounds, Timer und andere Win32-API-Routinen. Übrigens scanne
ich gerade mit OllyDbg Minensuchboot .
Update: nemo erinnerte mich an ein großartiges Tool, Cheat Engine von Eric "Dark Byte" Heijnen.
Cheat Engine (CE) ist ein großartiges Tool zum Beobachten und Ändern des Speicherplatzes anderer Prozesse. Über diese grundlegende Funktion hinaus verfügt CE über weitere spezielle Funktionen wie das Anzeigen des zerlegten Speichers eines Prozesses und das Einfügen von Code in andere Prozesse.
(Der wahre Wert dieses Projekts besteht darin, dass Sie den Quellcode -Delphi- herunterladen und sehen können, wie diese Mechanismen implementiert wurden - das habe ich vor vielen Jahren getan: o)
quelle
Ein ziemlich guter Artikel zu diesem Thema ist bei Uninformed zu finden . Es behandelt das Umkehren von Minesweeper (als Einführung in das Reverse Engineering von Win32-Apps) sehr detailliert und ist eine großartige Ressource.
quelle
Diese Website könnte hilfreicher sein:
http://www.subversity.net/reversing/hacking-minesweeper
Der allgemeine Weg, dies zu tun, ist:
Als Antwort auf Bounty
Nun, in einer zweiten Lesung scheint es, als wollten Sie eine Anleitung zur Verwendung eines Debuggers wie WinDBG anstelle der üblichen Frage zum Reverse Engineering. Ich habe Ihnen bereits die Website gezeigt, auf der die Werte angegeben sind, nach denen Sie suchen müssen. Die Frage ist also, wie suchen Sie danach?
In diesem Beispiel verwende ich Notepad, da Minesweeper nicht installiert ist. Aber die Idee ist dieselbe.
Du tippst
Drücken Sie "?" Und dann "s", um die Hilfe anzuzeigen.
Sobald Sie das gewünschte Speichermuster gefunden haben, können Sie Alt + 5 drücken, um den Speicher-Viewer für eine schöne Anzeige aufzurufen.
WinDBG ist gewöhnungsbedürftig, aber es ist so gut wie jeder andere Debugger da draußen.
quelle
Ein guter Punkt, um mit der Ablaufverfolgung im Debugger zu beginnen, ist die Maus hoch. Finden Sie also die Hauptfensterprozedur (ich denke, Tools wie spyxx können die Fenstereigenschaften überprüfen, und die Adresse des Ereignishandlers ist eine davon). Brechen Sie ein und finden Sie heraus, wo Mausereignisse behandelt werden - es wird einen Schalter geben, wenn Sie ihn im Assembler erkennen können (sehen Sie sich den Wert von WM_XXX für die Maus in windows.h an).
Setzen Sie dort einen Haltepunkt und treten Sie ein. Irgendwann zwischen dem Loslassen der Maustaste und dem Aktualisieren des Bildschirms greift das Opfer auf die gesuchte Datenstruktur zu.
Seien Sie geduldig, versuchen Sie herauszufinden, was zu einem bestimmten Zeitpunkt getan wird, aber schauen Sie nicht zu tief in den Code, von dem Sie vermuten, dass er für Ihr aktuelles Ziel uninteressant ist. Es kann mehrere Läufe im Debugger dauern, um es festzunageln.
Kenntnisse über den normalen Workflow von Win32-Anwendungen sind ebenfalls hilfreich.
quelle
Die Minen werden wahrscheinlich in einer Art zweidimensionaler Anordnung gelagert. Dies bedeutet, dass es sich entweder um ein Array von Zeigern oder um ein einzelnes Array von Booleschen Werten im C-Stil handelt.
Immer wenn das Formular ein Mouse-Up-Ereignis empfängt, wird auf diese Datenstruktur verwiesen. Der Index wird unter Verwendung der Mauskoordinate berechnet, wahrscheinlich unter Verwendung einer Ganzzahldivision. Das bedeutet, dass Sie wahrscheinlich nach einer
cmp
oder einer ähnlichen Anweisung suchen sollten , bei der einer der Operanden mit einem Offset berechnet wird undx
bei derx
das Ergebnis einer Berechnung mit ganzzahliger Division ist. Der Offset ist dann der Zeiger auf den Anfang der Datenstruktur.quelle
Es ist ziemlich vernünftig anzunehmen, dass Informationen über Minen zumindest für Zeilen zusammenhängend im Speicher angeordnet sind (dh es handelt sich um ein 2D-Array oder ein Array von Arrays). Daher würde ich versuchen, mehrere benachbarte Zellen in derselben Zeile zu öffnen, Speicherauszüge des Prozesses zu erstellen, diese dann zu differenzieren und nach sich wiederholenden Änderungen in demselben Speicherbereich zu suchen (dh 1 Byte wurde im ersten Schritt, im nächsten geändert Byte im nächsten Schritt auf genau denselben Wert geändert usw.).
Es besteht auch die Möglichkeit, dass es sich um ein gepacktes Bit-Array handelt (3 Bits pro Mine sollten ausreichen, um alle möglichen Zustände aufzuzeichnen - geschlossen / offen, Mine / keine Mine, markiert / nicht markiert), also würde ich auch darauf achten ( Die Muster wären auch wiederholbar, wenn auch schwerer zu erkennen. Aber es ist keine bequeme Struktur, mit der man sich befassen muss, und ich glaube nicht, dass die Speichernutzung ein Engpass für Minesweeper war, daher ist es unwahrscheinlich, dass so etwas verwendet wird.
quelle
Cheat Engine ist zwar nicht unbedingt ein "Reverse Engineer's Tool" und eher ein Spielzeug, das selbst ein Idiot wie ich benutzen könnte . Es macht es etwas einfach zu verfolgen, welche Teile des Speichers sich wann geändert haben, und es gibt sogar Vorkehrungen zum Verfolgen der geänderten Speicherteile durch Zeiger (obwohl Sie das wahrscheinlich nicht benötigen). Ein schönes interaktives Tutorial ist enthalten.
quelle