Sicherheitstest zum Erkunden des Windows-Spiels Minesweeper

Autor:  Wan Yuxin von Jingdong Industry

Ich glaube, dass viele Leute seit ihrer Jugend Minesweeper-Spiele gespielt haben. In der Zeit, als es noch nicht viele Computerspiele gab, wurde Minesweeper zu einem der beliebtesten Spiele. Später hatte ich auch den Drang, es einmal zu tun. Durch dynamisches Debugging, Reverse Engineering und C zum Schreiben eines Minesweeper-Hilfstools zur Verbesserung der Reverse Engineering- und Codierungsfähigkeiten.

Dynamisches Debugging (Analyse)

Führen Sie zunächst ein dynamisches Debugging (Analyse) des Minesweeper-Programms durch:

Öffnen Sie OD ( ollydebug tool), ziehen Sie Minesweeper in OD , F9 zum Ausführen; Strg+G , um den folgenden Ausdruck einzugeben, geben Sie rand ein , klicken Sie auf [OK], um zum Funktionsaufruf zu springen, F2 , um einen Haltepunkt zu setzen, dies The Zweitens ist es, einen Durchbruch durch die API-Rand- Funktion zu finden. Klicken Sie auf eine beliebige Position im Minenfeld des Minesweeper-Fensters (wo im Bild 2 erscheint ) und klicken Sie dann auf Wiederherstellen (Schaltfläche [Smiley] - ), wie in der Abbildung unten gezeigt:



Zu diesem Zeitpunkt bricht die OD am Haltepunkt am gerade eingestellten Rand , wie in der folgenden Abbildung gezeigt:



 

Durch das Auffinden der Zufallsfunktion rand wird der folgende Stack zurückverfolgt und kehrt zur übergeordneten Funktion zurück, um die Parameter von push (push into the stack) zu finden, d. h. die Zufallsgenerierungsfunktion ( rand ) ist eine zufällig generierte Höhe, Breite und Donner. Klicken Sie auf K (Call-Stack), um das K- Call-Stack-Fenster anzuzeigen , die Informationen des Stack-Fensters anzuzeigen, die Rücksendeadresse zu finden, im K- Call-Stack-Fenster auf die Rücksendeadresse zu doppelklicken und zur vorherigen Ebene zurückzukehren Stack-Backtracking. Beachten Sie genau die Stack-Informationen 010036D2 (Rücksprungadresse) in der Abbildung unten .







Einzelschritt F8 , beobachten Sie die Register-, Datenfenster- und Stapelfensteränderungen, dword ptr ss:[esp+0x4] oder dword ptr ds:[XXX] Datenfenster-Verfolgungswert ( 000DFC44 Wert ist 09 ), wie unten gezeigt:

Nachdem Sie zur übergeordneten Funktion zurückgekehrt sind, analysieren Sie die darin enthaltenen Anweisungen und kennen die Breite ( 09 ), die gerade von random rand generiert wird , wie in der folgenden Abbildung gezeigt. Achten Sie auf die Adresse 010036C7 .

Analysieren Sie zuerst eax anhand des von dieser Funktion zurückgegebenen Ergebnisses . Nach einem einzigen Schritt können Sie sehen, dass eine Zahl 09 in den Stack (Adresse 010036D2 ) geschoben wird , wie in der folgenden Abbildung gezeigt:



Durch die obige Analyse kann grundsätzlich vermutet werden, dass die umgebende Randgenerierung der Zufallsfunktion eine hohe Donnerzahl ist. Sie können versuchen, die Minensucheinstellungen (benutzerdefinierte Minenfelder) zu ändern, wie in der Abbildung unten gezeigt, um die Randfunktion genau zu lokalisieren und Parameter zu übergeben, klicken Sie auf [OK] und dann auf die Schaltfläche [Wiederherstellen (Smiley - )].



 

Beachten Sie den OD , wie in der Abbildung unten gezeigt:



 

Es wird festgestellt, dass push 0C ( der Wert von 000DFC84 ist 0C ) bestimmt werden kann, dass push 0C dieser Randfunktion die Höhe des Minenfelds ist. Gleichzeitig sieht man im Speicherbereich deutlich eine grobe Minenfeld-Grafik, durch die obige Methode lässt sich grob erahnen, dass 0x80 ein Minenfeld ist. Oder analysieren Sie zusammen mit IDA , durch statische Analyse können Sie die Programmlogik intuitiver sehen. Holen Sie sich die folgenden Daten: Basisadresse, Minennummer und andere Informationen, wie in der folgenden Abbildung gezeigt:







 

Der obige Code bedeutet wahrscheinlich, dass die Variablen der globalen Breite 0x09 , der Höhe 0x0C und der Donnerzahl 0x0A zuerst gesetzt werden und die Breite und Höhe zufällig generiert werden, indem zwei Ebenen von Schleifen beurteilt werden. Kartenbasisadresse abrufen: 0x01005340 . Durch die Analyse der folgenden Abbildung wissen wir, dass keine Mine 0x0F , meine 0x8F und die Wand 0x10 ist .







 

Durch die Breiten- und Höhenangaben werden der Minensuchbereich und die Anzahl der Minen aufgedruckt, Seitenwände und Minen lassen sich intuitiver unterscheiden.

Beginnen wir als Nächstes damit, herauszufinden, wie Lei markiert werden kann.Indem wir davon ausgehen, dass die GetDC- Funktion in WinProc zu sehen ist (Rückverfolgung durch den Stack zur Message-Callback-Funktion) wird grob vermutet, dass Bitblt verwendet wird.Geben Sie in OD den Ausdruck ein gefolgt von ctrl+g , und geben Sie " BitBlt " ein, drücken Sie F2 , um einen Haltepunkt festzulegen, klicken Sie auf eine beliebige Position im Minensuchbereich, und das OD wird an der BitBlt- Position unterbrochen .

In BitBlt gibt es auch eine BitBlt- Funktion , die nach vorläufigem Urteil doppelt gepuffert zeichnet.

BitBlt(hDestDC,// Ziel- DC XDest, // Ziel- x -Koordinate YDest, // Ziel- y- Koordinate 10, // 10, // Höhe und Breite des Neuzeichnungsbereichs hSrcDC, // Quell- DC 0, 0, SRCCOPY); / / Geben Sie die Betriebsmethode an, um die Koordinaten der Mine zu berechnen (klicken Sie auf das erste Minenräumquadrat, um die Koordinaten anzuzeigen), Sie müssen auf die Seitenwand achten, wie unten gezeigt:







 

Subtrahieren Sie den Wert der Seitenwände:

-0x04=0x0C(12)-0x10(16)

0x27=0x37(55)-0x10(16)

Holen Sie sich die Koordinatenformel: x ( XDest:12 ) =1*0x10(16)-0x04(4) , y ( YDest:55 ) =1*0x10(16)+0x27(39).

Code schreiben

Durch die obige grobe Analyse kann der Code geschrieben werden,





 





 

Leistung





 

Betreten Sie 3 Landminenstandorte, um Landminen zu erhalten ( 10 Wände, 8F Landmine, 0F keine Mine)





 

Geben Sie 2 ein , um Minen automatisch zu räumen, Minen zu markieren und die Karte zu öffnen





 

Durch dieses kleine Projekt wurde erstens eine Art umgekehrtes Denken über die Software verstärkt, wie zum Beispiel: Wenn ich diese Art von Panel sehe, habe ich wahrscheinlich vermutet, dass es mit einem Array implementiert ist, und zweitens ist das Layout von mir zufällig generiert und dann durch dynamisches Debugging können wir die Implementierungsmethode (eine Implementierungsidee des Entwicklers) verstehen, die Schlüsselbasisadresse finden, mehrere Zustände (kein Donner, Donner, Wand), die letzte Codierungsstufe verstehen können Betrieb des Speichers, mehrere wichtige APIs, FindWindow, um das Handle zu erhalten , OpenProcess öffnet das Handle, ReadProcessMemory liest Speicherinformationen, PostMessage asynchroner Nachrichtenmodus, CloseHandle schließt das Handle. Einige der Analysen sind falsch oder nicht vorhanden, bitte schießen Sie nach Ziegeln. Umgekehrt ist die Analyse des Codes sehr hilfreich, Sie können nicht nur Ihr Denken und Ihr Programmier- und Testniveau erweitern, sondern auch Lücken im Programm entdecken, entwickeln und ausnutzen oder das Programm patchen usw. Ich hoffe, dass meine Freunde auf dieser langen und beschwerlichen Reise hart arbeiten und sich gegenseitig Mut machen.

{{o.name}}
{{m.name}}

Ich denke du magst

Origin my.oschina.net/u/4090830/blog/8590989
Empfohlen
Rangfolge