Game Reverse Engineering_Android liest und schreibt Spielinhalte

1. Hintergrund

Die Implementierung von Android-Plugins erfordert das Lesen und Schreiben entsprechender Spielinhalte. Lesen und schreiben Sie Spielinhalte, einschließlich Code und Daten

Für verschiedene Lese- und Schreibobjekte bestehen die allgemeinen Schritte darin, die Objektadresse (Standort) zu ermitteln → die entsprechende Berechtigung zu erhalten → Lesen und Schreiben. Die Umsetzung wird im Folgenden näher beschrieben.

2. Implementierungsmethode

Implementierungen können in zwei Kategorien unterteilt werden: injizierte und nicht injizierte.

Injektion: Es muss in den entsprechenden Spielprozessraum injiziert werden. Die übliche Methode besteht darin, über Ptrace und Zygote zu injizieren.

Nicht-Injektion: Es muss nicht in den Spielprozessraum injiziert werden, und der Spielinhalt wird über den Android-Systemmechanismus von anderen Orten gelesen und geschrieben.

Abhängig von der Art des Spielinhalts, der gelesen und geschrieben werden muss, können unterschiedliche Ansätze verwendet werden. Der Injektionstyp eignet sich zum Lesen und Schreiben dynamischer Daten, wie z. B. während des Spiels berechnete Zwischenvariablen (Schaden usw.), dynamisch geladene Attribute (Lebenswert usw.), Spielstatus (Erfolgsflag usw.) und dynamisch kompilierter Code (Unity, Lua-Skripte usw.). Nicht-Injektion eignet sich besser zum Ändern von statischem Code, Ressourceninformationen usw. (Bei Spielen mit Anti-Injektionsschutz kann Nicht-Injektion auch zum Abrufen dynamischer Daten verwendet werden).

(1) Nicht-Injektionstyp:

1. Datenänderung im privaten Ordner von /data/data/$PackageName, z. B. Änderung von SO im lib-Verzeichnis (tatsächliches Laden der SO-Bibliothek, wenn das Spiel läuft). Nachdem Sie die ROOT-Berechtigung erhalten haben, können Sie den darin enthaltenen Inhalt ändern. Um beispielsweise das Hauptlogikmodul zu ändern, verwenden Sie zum Ändern und Speichern direkt einen Hexadezimaleditor (UltraEdit und andere Tools).

2. Verwenden Sie direkt Tools wie APKTOOL, um die APK-Datei zu entschlüsseln und einige Spielressourceninformationen abzurufen. Die gängigen Dateiverzeichnisse von APK werden wie folgt vorgestellt:

AndroidManifest.xml Jede Anwendung muss über Paketnamen, Berechtigungen, Aktivitäten und andere verwandte Informationen verfügen.

META-INF Die Signaturinformationen der Anwendung werden in diesem Verzeichnis gespeichert;

Res In diesem Verzeichnis werden Ressourcendateien (Bildzeichenfolgen usw.) gespeichert.

Lib Dieses Verzeichnis speichert SO-Dateien;

Assets In diesem Verzeichnis werden Konfigurationsdateien gespeichert (der Prozess enthält jedoch Ressourcendateiinformationen).

Classes.dex Java-Bytecode-Datei (kompiliert aus Java-Quellcode);

resources.arsc Kompilierte binäre Ressourcendatei.

Es ist ersichtlich, dass auf diese Weise viele Spielinhalte erhalten werden können. Beispielsweise werden die Lua-Skripte einiger Lua-Engine-Handyspiele mit schlechter Sicherheit im Klartext im Assets-Verzeichnis gespeichert (normalerweise mit Lua- oder skriptbezogenen Zeichen benannt). Ein weiteres Beispiel ist das Unity-Spiel, wie in Abbildung 1 dargestellt. Die kompilierte DLL des C#-Skripts wird in asset/bin/Data/Managed/Assembly-CSharp.dll gespeichert, und der Spielskriptcode kann mithilfe von Tools wie z. B. direkt dekompiliert werden als ILSpy (ungefähr Die Hilfs- oder Crackversion von Unity hat die Funktion, den Inhalt dieser Datei direkt zu ändern).
Fügen Sie hier eine Bildbeschreibung ein
3. Mithilfe des /proc-Dateisystems verfügt jeder Prozess über eine entsprechende Datei in diesem Ordner (der erwähnte Prozess ist natürlich nur während des laufenden Prozesses verfügbar), die einige wichtige Dateien enthält, wie in Abbildung 2 dargestellt. Einige wichtige Dokumente werden wie folgt vorgestellt:

/proc/$pid/cmdline der Befehl, der zum Starten des Prozesses verwendet wird;

/proc/$pid/cwd Ein Link zum Arbeitsverzeichnis des aktuellen Prozesses;

/proc/$pid/environ Liste der verfügbaren Prozessumgebungsvariablen;

/proc/$pid/exe Link zum Programm, das im Prozess ausgeführt wird;

/proc/$pid/fd/ Link zu jeder vom Prozess geöffneten Datei;

/proc/$pid/mem Der Inhalt des Prozesses im Speicher;

/proc/$pid/stat Statusinformationen des Prozesses;

/proc/$pid/statm Informationen zur Speichernutzung verarbeiten;

/proc/$pid/maps Verarbeitet Informationen zur Nutzung des virtuellen Adressraums.

Über diese Dateien können die entsprechenden Spielinformationen abgerufen werden. Unter anderem kann die MEM-Datei das Speicherbild des Spiels abrufen, was bedeutet, dass der Zweck der Änderung des Inhalts des Spielprozessraums durch Änderung der Datei erreicht werden kann. Beispielsweise implementiert der Huluxia-Modifikator die allgemeine Modifikatorfunktion über diese Nicht-Injektionsmethode (der Beispielcode in „Debug Hacks“, wie in Abbildung 3 dargestellt, kann Funktionen wie Lesen und Schreiben direkt verwenden, um Prozessinhalte zu lesen und zu schreiben. Im Allgemeinen , es muss die Basisadressinformationen des Moduls mit dem Inhalt in den Karten abrufen.)
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
(2) Injektion:

Das injizierte Lesen und Schreiben hat einen starken Zweck, das heißt, es wurde durch statisches oder dynamisches Debuggen festgestellt, dass die Inhaltsadresse an einem bestimmten Ort abgerufen werden kann, und dann ist es erforderlich, den entsprechenden Adressinhalt während des dynamischen Betriebs zu lesen und zu schreiben des Spiels (einschließlich Lesen und Schreiben des Speichers) Vorgänge wie Memset, Memcpy, MMAP, Strcpy und andere Funktionen). Seine spezifische Implementierung ist wie folgt:

1. Ändern Sie nach der Injektion in den Spielprozessraum direkt die Montageanweisungen an bestimmten Stellen, um die Lese- und Schreiblogik für bestimmte Adressen zu ändern. Beispielsweise kann die Methode zum Ändern von Funktionsparametern, die üblicherweise in Spiel-Plug-Ins verwendet wird, auf diese Weise realisiert werden: Suchen Sie nach der Analyse und Lokalisierung einer bestimmten Funktion einen Parameterverwendungspunkt im ersten Assembler-Anweisungssegment davon und ändern Sie seine Zuweisung. Wie in Abbildung 4 dargestellt, stellt ein Funktionsparameter R1 eines bestimmten Spiels den Energiewert dar. Durch Umschreiben der Anweisung der Adresse im roten Feld in FF25 (MOVS R5, #0xFF) kann der Zweck der dynamischen Änderung des Funktionsparameters auf 0xFF erreicht werden (um eine konstante Energie und volle Plug-in-Funktion zu erreichen).

Diese Methode muss die allgemeinen Lese- und Schreibanweisungen von Montageanweisungen wie ARM und Thumb verstehen. Bei der Schreiboperation lautet beispielsweise der Opcode der ARM-Assembly-Anweisung MOV R3, #0 00 30 A0 E3.
Fügen Sie hier eine Bildbeschreibung ein
2. Die obige Methode ist tatsächlich die grundlegendste injektive Schreibmethode mit der einfachsten Logik: Statische Analyse der Adresse → Umschreiben des Seitenattributs (die mprotect-Funktion schreibt das Attribut neu) → direkte Änderung des Inhalts. Wenn außerdem einige Lese- und Schreibvorgänge eine große Anzahl von Bytes belegen müssen und die entsprechenden Assembleranweisungen nicht an der Originaladresse erstellt werden können, ist die HOOK-Technologie erforderlich. Hier gibt es zwei Arten: Eine besteht darin, MSHOOKFUNCTION, GOT-Tabellenersetzung usw. zu verwenden, um die Ersetzung von Funktionsadressen zu realisieren, und die andere darin, Inline Hook zu verwenden, um einen Funktionszwischenprozesssprung zu realisieren. Da es sich bei diesem Artikel nicht um einen HOOK-Themenartikel handelt, lautet eine relativ einfache Einführung in diese Methoden wie folgt:

A. MSHOOKFUNCTION, GOT-Tabellenersetzung und andere Methoden können durch einfaches Aufrufen von Funktionen implementiert werden, was bequemer ist. Es weist jedoch starke Einschränkungen auf und kann die Zwischenvariablendaten der Funktion nicht abrufen und ist auf das Lesen und Schreiben von Parametern und Rückgabewerten beschränkt.

B. Die Inline-Hook-Methode ist komplizierter zu implementieren, hat aber offensichtliche Vorteile: Sie kann die Zwischenoperationsdaten der Funktion lesen und schreiben. Das Spiel verfügt beispielsweise über eine große Angriffsberechnungsfunktion, die die Berechnung von Schaden und Verteidigungskraft umfasst. Der Schadenswert ist nur eine temporäre Variable. Zu diesem Zeitpunkt ist es erforderlich, den Speicherort des Schadenswerts (welcher) statisch zu analysieren Register ist welche Position), und dann kann der Inline-Hook die entsprechenden Daten lesen und schreiben.

Supongo que te gusta

Origin blog.csdn.net/douluo998/article/details/130113203
Recomendado
Clasificación