22.07.2012, 21:33
(Dieser Beitrag wurde zuletzt bearbeitet: 22.07.2012, 21:36 von FPS-Player.)
Heiliger Odin! :exclamation:
Danke für die ausführliche Antwort.
Ok, das meiste habe ich vom schematischen Ablauf her verstanden.
Ja, danke, das hatte ich mir schon mal angesehen und auch begriffen, wie die Funktion einer Codecave ist/wie sie funktioniert.
Ok, das habe ich "technisch" auch verstanden. Ob ich es auch selbst umsetzen kann (bei anderen Spielen) ist eine andere Geschichte...aber das muß ich halt lernen.
Verstehe. Das Spiel geht zwar ganz normal auf den Wert des Timers "movss [esi+40],xmm0", welcher aber im Prinzip eine Codezeile weiter durch unseren max. Zeitwert wieder zurückgesetzt wird. Also fängt er quasi immer wieder neu an zu zählen...
Ok, auch verstanden! Aber woher weiß ich, das der Originalcode 5 Bytes groß war/ist?
Gut, ich weiß nicht, ob ich es schaffe, das umzusetzen, aber ich werds auf jeden fall versuchen. Hmm, trotz CE oder AM muß man ja tatsächlich ein bisschen Programmieren können (oder zumindest etwas davon verstehen)... Junge Junge...
Danke für die ausführliche Antwort.
Ok, das meiste habe ich vom schematischen Ablauf her verstanden.
(22.07.2012, 20:21)sILeNt heLLsCrEAm schrieb: Irgendwie scheint mir das Du dich zu sehr auf Pointer fixiert hast?!?Hähä, ich kenne mich nicht mal gut genug damit aus, um irgendwas draus zu machen
Von diesem Gedanken solltest Du dich ganz schnell trennen, denn nicht immer ist ein Spiel nur mit Pointern zu bescheißen...
Zitat:In erster Linie solltest Du Dir auch das Codecave Tutorial von Acubra zu Gemüte führen... Das findest Du HIER
Ja, danke, das hatte ich mir schon mal angesehen und auch begriffen, wie die Funktion einer Codecave ist/wie sie funktioniert.
Zitat:Bei diesem Code gibts nichts auseinanderzupflücken...Aha! Das habe ich verstanden. Gilt denn die Basisadresse 0x400000h nur für Just cause 2 oder generell für jedes Spiel?
[code=ASM]JustCause2.exe+4103F0 - F3 0F11 46 40 - movss [esi+40],xmm0[/code]
Der erste Teil beschreibt die Position wo diese Anweisung zu finden ist. Und da sehen wir das diese Anweisung in der "JustCause2.exe" an Adresse "JustCause2.exe+4103F0" zu finden ist. Und da die Basisadresse der EXE Datei im Speicher immer diesselbe ist, nämlich 0x400000h, so könnte ich auch statt "JustCause2.exe+4103F0" auch einfach nur "008103F0" schreiben. Weil, wenn ich zur Basisadresse von 0x400000h den Wert 0x4203F0h addiere ich eben den HEX Wert 008103F0 erhalte.
Zitat:Mit der Anweisung "movss [esi+40], xmm0" wird also eine Gleitkommazahl aus dem XMM0 Register in den Speicher an Adresse [ESI+40] kopiert. Wenn jetzt z.B. ESI den Wert 0x400400h enthält dann wird also der Wert des Registers in den Speicher an Adresse 0x400400h + 0x40h = 0x400440h kopiert.
Der zusammengerechnete Wert von [ESI+40] ist in diesem Falle die Adresse die den Wert des Timers enthält. Also quasi wieviel Zeit wir noch haben bevor das Minigame als gescheitert gilt. Wenn also diese Adresse z.B. die "16BF06A2" ist, dann kann man auch zurückrechnen welcher Wert in ESI stehen muss. Wir ziehen also von dieser Timeradresse den Wert 0x40h ab. Also muss im ESI Register der Hexadezimale Wert "16BF0662" stehen.
Ok, das habe ich "technisch" auch verstanden. Ob ich es auch selbst umsetzen kann (bei anderen Spielen) ist eine andere Geschichte...aber das muß ich halt lernen.
Zitat:Die Anweisung die unsere Timer Adresse beschreibt ist genau 5 Bytes groß bzw. lang. Und unser reiner Cheatcode ist im Endeffekt 10 Bytes lang...Halt! Überschreiben können wir den Code ja nicht, da sonst das Spiel abschmiert. Du meinst sicherlich, das wir sozusagen einen Bypass zu diesem Code legen - unsere Codecave...oder?
[code=ASM]F3 0F 10 46 44 - movss xmm0,[esi+44]
F3 0F 11 46 40 - movss [esi+40],xmm0[/code]
Also muss eben eine Codecave her. Und da wir durch den Sprung zu dieser Codecave den Originalcode "movss [esi+40],xmm0" überschreiben da können wir uns diesen auch gleich zu unseren Zwecken ausnutzen.
Zitat:Und wie ich da bereits sagte wird in [ESI+40], was unsere Timer Adresse ist, immer wieder der Wert des XMM0 Registers kopiert. Die Zeit nimmt also ab. Aber direkt neben der Adresse des tatsächlichen Zeitwertes befindet sich auch die Adresse mit dem maximalen Zeitwert bzw. dem Zeitwert bei vollem Balken.Ah, also wäre - nur zur Verdeutlichung - der Timer, bzw. die Adresse [ESI+30] --> sprich ablaufende Zeit, müsste ich, wenn ich den max. Zeitwert einstellen wollte immer (also in jedem Fall/Spiel) 4 Bytes dazurechnen, so das ich dann auf [ESI+30+4] käme, also [ESI+34], richtig?
Also...
[ESI+40] = Tatsächlicher Zeitwert
Timer Adresse + 4 Bytes = Maximaler Zeitwert
Man könnte das auch so schreiben
[ESI+40+4] aber [ESI+44] ist ja dasselbe
Zitat:Und mit dem Befehl "movss xmm0,[esi+44]" kopieren wir immer den maximal möglichen Zeitwert in das XMM0 Register. Und dort alleine nützt der uns nix also müssen wir das Spiel dazu bringen das es immer nur diesen Wert an der Adresse für den tatsächlichen Zeitwert hat. Das realisieren wir dann mit dem Befehl, welches auch der Originalcode ist, "movss [esi+40],xmm0".
Verstehe. Das Spiel geht zwar ganz normal auf den Wert des Timers "movss [esi+40],xmm0", welcher aber im Prinzip eine Codezeile weiter durch unseren max. Zeitwert wieder zurückgesetzt wird. Also fängt er quasi immer wieder neu an zu zählen...
Zitat:Der Sprung zur Codecave war an Adresse "JustCause2.exe+4103F0", oder anders geschrieben an Adresse "008103F0". Da der Sprung, genauso wie der Originalcode, 5 Bytes lang/groß ist addieren wir zu dieser Adresse 5 Bytes hinzu. Also müssen wir zu Adresse "JustCause2.exe+4103F5", oder anders geschrieben zu Adresse "008103F5" zurückspringen.
Ok, auch verstanden! Aber woher weiß ich, das der Originalcode 5 Bytes groß war/ist?
Zitat:Noch etwas zum Abschluss... Eine Codecave ist kein vordefinierter Bereich innerhalb des Speichers. Eine Codecave befindet sich immer innerhalb des Spiels zur Verfügung stehenden Speichers. Dies kann feststehender Speicher innerhalb des Moduls sein, also der EXE. Oder man stellt dem Spiel Speicher zur Verfügung so das es diesen nutzen kann. Und genau das macht Cheat Engine mit dem Befehl oder der Option "Allocate Memory". Weiterhin darf sich aber die Codecave nicht innerhalb eines Bereiches befinden der vom Spiel explizit gebraucht wird.Klar, ich lagere also quasi meinen Code in einen ungenutzen, freien Speicherbereich aus und muß dem Originacode halt nur sagen, wo er unsere eingebaute Umleitung findet. "Springe ab Zeile 5 zu Zeile 20, führe Zeile 20 (welche normalerweise nicht genutzt wird) aus und fahre dann mit Zeile 6 fort" - vereinfacht ausgedrückt.
Bestes Beispiel z.B. da wo sich der Originalcode befindet. Würde man da wild eine Codeinjection schreiben stürzt das Spiel unweigerlich ab weil es Daten bekommt die es nicht erwartet. Die Register kriegen falsche Werte, der Stack wird durcheinander gewürfelt. Letzenendes stimmt der komplette Programmablauf nicht mehr.
Zitat:Aber eines muss man auch dazu sagen... Die oben gezeigte Codecave ist noch die einfachste Form. Sowas gibts noch viel komplexer und umfangreicher...Äh, danke, reicht fürs erste
Gut, ich weiß nicht, ob ich es schaffe, das umzusetzen, aber ich werds auf jeden fall versuchen. Hmm, trotz CE oder AM muß man ja tatsächlich ein bisschen Programmieren können (oder zumindest etwas davon verstehen)... Junge Junge...