Programm Reversen. Problem mit this*

08/17/2015 16:32 Daifoku#1
Ich möchte eine executable komplett Reversen und in C++ schreiben.

Wie fange ich damit an ?


Assembly um den <ModuleEntryPoint> anschauen und analysieren.
Das Programm springt anschließend in__tmainCRTStartup().
Meine Vermuting ist einfach mal, dass von dort aus main() aufgerufen wird.

die Funktion in__tmainCRTStartup:

Ich bin zu dem entschluss gekommen, dass ich bei WinMain starte... der Rest der Funktion __tmainCRTStartup sollte durch ein neues VC++ Windows Project von alleine kommen. Richtig ?
ist das der richtige Startpunkt oder bin ich da falsch ?
08/17/2015 20:52 Omdi#2
Ist bisher so richtig.

Edit: Was hast du denn konkret vor :)?
08/17/2015 21:08 Daifoku#3
Danke für die Rückmeldung Omdihar,

Also...Ich hab eine Informationsseite zu einem Spiel am laufen und muss, um an die Daten zu kommen (für ein Update der Infos), die großen Binären Dateien Entpacken.
Das Virtuelle Datei System von diesem Spiel ist kein Problem und mein Programm entpackt diese auch zuverlässig, allerdings ist es nervig, wenn ich immer wieder alles vom Server laden muss.

Ich möchte an die Daten gelangen ohne den Clienten auf dem PC haben zu müssen.

Die Dateien liegen einzeln auf dem Server und ich kann diese per HTTP Request einfach herunter laden. Leider sind diese dann verschlüsselt. Der Launcher entschlüsselt diese und legt sie anschließend in das eigene Virtuelle FileSystem ab.

Ich habe den Algorithmus zum entschlüsseln lokalisieren können (im Launcher), leider sind meine Kenntnisse nicht ausreichend, um daraus eine Stand-Alone Version zu bauen. Es scheitert an den _thiscalls ... Ich bekomme einfach nicht raus, wie die Struktur dahin genau aussieht.

Also dachte ich mir, dass ich das Programm grundlegend von vorne Reverse.
Das ist wahrscheinlich zu viel des Guten aber ich kann es einfacher nicht anders :c
08/17/2015 22:36 Omdi#4
Quote:
Ich habe den Algorithmus zum entschlüsseln lokalisieren können (im Launcher), leider sind meine Kenntnisse nicht ausreichend, um daraus eine Stand-Alone Version zu bauen.
Es wäre denke ich mal besser sich auf diesen Teil zu konzentrieren. Könntest du vielleicht Ausschnitte vom Algorithmus hier posten? Ich bin mir sicher, dass wir dir da helfen können ;)
08/17/2015 23:01 Daifoku#5
okay :)
Ich erstelle fix eine Klasse zur besseren Übersicht, kommentiere meinen bisherigen Code mit Ungewissheiten und poste dann gleich in ein paar Minuten die Klasse

Das ganze ist schon enorm vereinfacht, normal waren die Aufrufe über mehrere Funktionen verteilt.

bei decodeBuffer(void *pthis, int DataSource); liegt mein Problem. pthis+4 wird verwendet und ich weiß nicht, was pthis sein könnte. Das ist der erste __thiscall und ich bin schon am verzweifeln ^^

header


.cpp
08/17/2015 23:46 Omdi#6
Du musst ja theoretisch die Klasse nicht eins zu eins nachbauen, sondern einfach nur den Algorithmus implementieren. So wie ich das sehe, ist unk1 die einzige noch fehlende Unbekannte. Geh doch einfach mit einem Debugger ran und schau was sich dahinter verbirgt :)
08/18/2015 00:19 Daifoku#7
Ich schau mal, ob ich das hin bekomme ^^
Kann mir leider nicht wünschen, welche Datei mein Launcher lädt und jeder Dateityp hat eine andere decode-routine :D Habe nur die für ini-Dateien reversed. Hab den downloader schon 10 Minuten am laufen aber bisher noch kein Break :c

edit1:

:) Danke dir ! Komme nun weiter, mal sehen wie weit

edit2:

unk1 ist ein weiterer Table ._. habe die Routine zur Erstellung des Tables (vermutlich) gefunden...

vermutlich folgender Code
Werde die Routine mal im Debugger weiter untersuchen ..

edit3: ist die Routine, kann sie direkt nach C++ porten :)
08/18/2015 18:31 Omdi#8
Quote:
Originally Posted by Daifoku View Post
Ich schau mal, ob ich das hin bekomme ^^
Kann mir leider nicht wünschen, welche Datei mein Launcher lädt und jeder Dateityp hat eine andere decode-routine :D Habe nur die für ini-Dateien reversed. Hab den downloader schon 10 Minuten am laufen aber bisher noch kein Break :c

edit1:

:) Danke dir ! Komme nun weiter, mal sehen wie weit

edit2:

unk1 ist ein weiterer Table ._. habe die Routine zur Erstellung des Tables (vermutlich) gefunden...

vermutlich folgender Code
Werde die Routine mal im Debugger weiter untersuchen ..

edit3: ist die Routine, kann sie direkt nach C++ porten :)
Freut mich zu hören :)
Wie unterscheidet sich denn die Verschlüsselung für andere Dateitypen? Ich nehme mal an, dass da lediglich die Table abweicht oder hast du dir das noch nicht genauer angesehen?
08/18/2015 21:55 Daifoku#9
Es gibt insgesamt 4 verschiedene Methoden zum entschlüsseln, wobei eine davon die Dateitypen behandeln, die nicht verschlüsselt sind (xml, dds, models). Diese werden dort einfach mit bz2 entpackt.

zwei Methoden behandeln das entschlüsseln der Datei (das ist die Klasse, die ich oben kurz angerissen habe). Gleiche Methoden aber zwei andere Table und ein anderes secret

die letzte Methode, soweit ich das auf den ersten Blick sehe, ist was komplett anderes. Kann ich nichts zu sagen und weiß grad auch nicht wofür die ist ;)

Ich muss jetzt erstmal die Routine zur Generierung von unk1 reversen, das reverste Ergebnis von IDA führt leider ins leer : /

Ich stoße grad ins leere.

Code:
MOV EAX,ECX
SHR EAX,1	
TEST CL,0x1
JE SHORT 00426C43 
XOR EAX,0xEDB88320
TEST AL,0x1
Durch welchen Aufruf wird AL gesetzt ?
edit:
Habe es nun hinbekommen

mich würde aber trotzdem interessieren, was in AL/CL genau liegt und wo diese gesetzt werden.
und hat das obige Verfahren der Tabellengenerierung evtl einen Namen?

und noch ein edit:
Kann nun heruntergeladene Dateien entschlüsseln :)
08/19/2015 06:51 Omdi#10
Verbessert mich wenn ich falsch liege, aber die letzte Instruction, die AL setzt müsste XOR EAX,0xEDB88320 sein. Um herrauszufinden, was AL für einen Wert besitzt, müsste man schon wissen was in ECX ist.
08/19/2015 07:23 Daifoku#11
der Wert ist egal, wollte nur generell wissen, wie AL gesetzt wird und wodurch :) Mir fehlt da das Basiswissen ;-) Ich habe nun folgendes herausgefunden:

AL ist ein 8bit Register von EAX
Angenommen in EAX liegt der Wert 0x12345678, dann müsste in AL 0x78 liegen.

In meinem Beispiel würde somit der Befehl XOR EAX,0xEDB88320 in C++ wie folgt aussehen:

eax ^= 0xEDB88320;
int AL = eax & (DWORD)0xFF;

kannst du oder jemand anderes das bestätigen ?
08/19/2015 08:30 Omdi#12
Ist richtig :)