|
You last visited: Today at 06:32
Advertisement
Programm Reversen. Problem mit this*
Discussion on Programm Reversen. Problem mit this* within the General Coding forum part of the Coders Den category.
08/17/2015, 16:32
|
#1
|
elite*gold: 0
Join Date: Mar 2010
Posts: 360
Received Thanks: 132
|
Programm Reversen. Problem mit this*
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:
Code:
signed int __cdecl __tmainCRTStartup()
{
HANDLE v0; // eax@1
LPVOID v1; // eax@1
LPVOID v2; // esi@1
HANDLE v3; // eax@4
int v4; // edi@5
HANDLE v5; // eax@5
int v6; // eax@17
CHAR *v7; // eax@19
int v8; // ecx@20
int v9; // eax@22
signed int result; // eax@4
struct _STARTUPINFOA StartupInfo; // [sp+10h] [bp-70h]@1
int v12; // [sp+58h] [bp-28h]@5
int v13; // [sp+5Ch] [bp-24h]@5
int v14; // [sp+60h] [bp-20h]@5
int v15; // [sp+64h] [bp-1Ch]@22
CPPEH_RECORD ms_exc; // [sp+68h] [bp-18h]@1
ms_exc.registration.TryLevel = 0;
GetStartupInfoA(&StartupInfo);
ms_exc.registration.TryLevel = -2;
v0 = GetProcessHeap();
v1 = HeapAlloc(v0, 0, 0x94u);
v2 = v1;
if ( !v1 )
fast_error_exit(18);
*(_DWORD *)v1 = 148;
if ( GetVersionExA((LPOSVERSIONINFOA)v1) )
{
v14 = *((_DWORD *)v2 + 4);
v13 = *((_DWORD *)v2 + 1);
v12 = *((_DWORD *)v2 + 2);
v4 = *((_DWORD *)v2 + 3) & 0x7FFF;
v5 = GetProcessHeap();
HeapFree(v5, 0, v2);
if ( v14 != 2 )
v4 |= 0x8000u;
dword_4B9804 = v14;
dword_4B980C = v12 + (v13 << 8);
dword_4B9810 = v13;
dword_4B9814 = v12;
dword_4B9808 = v4;
v14 = check_managed_app();
if ( !_heap_init(1) )
fast_error_exit(28);
if ( !_mtinit() )
fast_error_exit(16);
sub_47C754();
ms_exc.registration.TryLevel = 1;
if ( _ioinit() < 0 )
_amsg_exit(27);
dword_4BB484 = GetCommandLineA();
dword_4B9850 = (char *)__crtGetEnvironmentStringsA();
if ( _setargv() < 0 )
_amsg_exit(8);
if ( _setenvp() < 0 )
_amsg_exit(9);
v6 = _cinit(1);
if ( v6 )
_amsg_exit(v6);
v7 = (CHAR *)_wincmdln();
if ( StartupInfo.dwFlags & 1 )
v8 = StartupInfo.wShowWindow;
else
v8 = 10;
v9 = WinMain(&_ImageBase, 0, v7, v8);
v15 = v9;
if ( !v14 )
exit(v9);
_cexit();
result = v15;
}
else
{
v3 = GetProcessHeap();
HeapFree(v3, 0, v2);
result = 255;
}
return result;
}
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
|
#2
|
elite*gold: 103616
Join Date: Apr 2010
Posts: 13,737
Received Thanks: 14,990
|
Ist bisher so richtig.
Edit: Was hast du denn konkret vor ?
|
|
|
08/17/2015, 21:08
|
#3
|
elite*gold: 0
Join Date: Mar 2010
Posts: 360
Received Thanks: 132
|
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
|
#4
|
elite*gold: 103616
Join Date: Apr 2010
Posts: 13,737
Received Thanks: 14,990
|
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
|
#5
|
elite*gold: 0
Join Date: Mar 2010
Posts: 360
Received Thanks: 132
|
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
Code:
class decode {
private:
int bufferSize = 0x800;
char secret[9] = "holy_elf";
char dTable[12];
int unk1;
int xorTable(int OnecharOfSecret);
void xorBuffer(int DataSource, int bufferSize);
int getByte();
public:
decode();
void decodeBuffer(void *pthis, int DataSource);
};
.cpp
Code:
decode::decode() {
/* set decode Table */
*(_DWORD *)dTable = 0x12345678;
*(_DWORD *)(dTable + 4) = 0x23456789;
*(_DWORD *)(dTable + 8) = 0x34567890;
}
void decode::decodeBuffer(void *pthis, int DataSource)
{
unk1 = *(_DWORD *)(*(_DWORD *)pthis + 4);
for (char &i : decode::secret)
xorTable(i);
xorBuffer(DataSource, bufferSize);
}
void decode::xorBuffer(int DataSource, int bufferSize)
{
for (int i = 0; i < bufferSize; ++i)
{
*(_BYTE *)(i + DataSource) ^= decode::getByte();
xorTable(*(_BYTE *)(i + DataSource));
}
}
int decode::xorTable(int OnecharOfSecret)
{
int result; // eax@1
int v4; // ecx@1
unsigned int v5; // edx@1
int v6; // ecx@1
result = OnecharOfSecret;
v4 = *(_DWORD *)(dTable + 4)
+ (unsigned __int8)((*(_WORD *)dTable >> 8) ^ *(_BYTE *)(unk1
+ 4
* (unsigned __int8)(OnecharOfSecret ^ (unsigned __int8)*(_DWORD *)dTable)));
*(_DWORD *)dTable = (*(_DWORD *)dTable >> 8) ^ *(_DWORD *)(unk1
+ 4
* (unsigned __int8)(OnecharOfSecret ^ (unsigned __int8)*(_DWORD *)dTable));
v5 = *(_DWORD *)(dTable + 8);
v6 = 134775813 * v4 + 1;
*(_DWORD *)(dTable + 4) = v6;
*(_DWORD *)(dTable + 8) = *(_DWORD *)(unk1 + 4 * (unsigned __int8)(v5 ^ BYTE3(v6))) ^ (v5 >> 8);
return result;
}
int decode::getByte(){
int v2 = (*(_DWORD *)(dTable + 8) & 0xFFFD | 2) * ((*(_DWORD *)(dTable + 8) & 0xFFFD | 2) ^ 1);
return BYTE1(v2);
}
|
|
|
08/17/2015, 23:46
|
#6
|
elite*gold: 103616
Join Date: Apr 2010
Posts: 13,737
Received Thanks: 14,990
|
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
|
#7
|
elite*gold: 0
Join Date: Mar 2010
Posts: 360
Received Thanks: 132
|
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 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
Code:
v1 = this;
*(_DWORD *)(this + 4) = operator new(0x400u);
v2 = 0;
do
{
v3 = v2 >> 1;
if ( v2 & 1 )
v3 ^= 0xEDB88320u;
if ( v3 & 1 )
v4 = (v3 >> 1) ^ 0xEDB88320;
else
v4 = v3 >> 1;
if ( v4 & 1 )
v5 = ((unsigned int)v4 >> 1) ^ 0xEDB88320;
else
v5 = (unsigned int)v4 >> 1;
if ( v5 & 1 )
v6 = ((unsigned int)v5 >> 1) ^ 0xEDB88320;
else
v6 = (unsigned int)v5 >> 1;
if ( v6 & 1 )
v7 = ((unsigned int)v6 >> 1) ^ 0xEDB88320;
else
v7 = (unsigned int)v6 >> 1;
if ( v7 & 1 )
v8 = ((unsigned int)v7 >> 1) ^ 0xEDB88320;
else
v8 = (unsigned int)v7 >> 1;
if ( v8 & 1 )
v9 = ((unsigned int)v8 >> 1) ^ 0xEDB88320;
else
v9 = (unsigned int)v8 >> 1;
if ( v9 & 1 )
result = ((unsigned int)v9 >> 1) ^ 0xEDB88320;
else
result = (unsigned int)v9 >> 1;
*(_DWORD *)(*(_DWORD *)(v1 + 4) + 4 * v2++) = result;
}
while ( (signed int)v2 < 256 );
Werde die Routine mal im Debugger weiter untersuchen ..
edit3: ist die Routine, kann sie direkt nach C++ porten
|
|
|
08/18/2015, 18:31
|
#8
|
elite*gold: 103616
Join Date: Apr 2010
Posts: 13,737
Received Thanks: 14,990
|
Quote:
Originally Posted by Daifoku
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 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
Code:
v1 = this;
*(_DWORD *)(this + 4) = operator new(0x400u);
v2 = 0;
do
{
v3 = v2 >> 1;
if ( v2 & 1 )
v3 ^= 0xEDB88320u;
if ( v3 & 1 )
v4 = (v3 >> 1) ^ 0xEDB88320;
else
v4 = v3 >> 1;
if ( v4 & 1 )
v5 = ((unsigned int)v4 >> 1) ^ 0xEDB88320;
else
v5 = (unsigned int)v4 >> 1;
if ( v5 & 1 )
v6 = ((unsigned int)v5 >> 1) ^ 0xEDB88320;
else
v6 = (unsigned int)v5 >> 1;
if ( v6 & 1 )
v7 = ((unsigned int)v6 >> 1) ^ 0xEDB88320;
else
v7 = (unsigned int)v6 >> 1;
if ( v7 & 1 )
v8 = ((unsigned int)v7 >> 1) ^ 0xEDB88320;
else
v8 = (unsigned int)v7 >> 1;
if ( v8 & 1 )
v9 = ((unsigned int)v8 >> 1) ^ 0xEDB88320;
else
v9 = (unsigned int)v8 >> 1;
if ( v9 & 1 )
result = ((unsigned int)v9 >> 1) ^ 0xEDB88320;
else
result = (unsigned int)v9 >> 1;
*(_DWORD *)(*(_DWORD *)(v1 + 4) + 4 * v2++) = result;
}
while ( (signed int)v2 < 256 );
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
|
#9
|
elite*gold: 0
Join Date: Mar 2010
Posts: 360
Received Thanks: 132
|
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
Code:
void decode::generateXorTable() {
unsigned int vars[8];
int xval= 0xEDB88320;
for (int index = 0; index < 64; index++) {
vars[0] = index >> 1;
if (index & 1) vars[0] ^= xval;
for (int i = 0; i < 7;i++)
vars[i+1] = (vars[i] & 1) ? (vars[i] >> 1) ^ xval : vars[i] >> 1;
decode::xTable[index] = vars[7];
}
}
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
|
#10
|
elite*gold: 103616
Join Date: Apr 2010
Posts: 13,737
Received Thanks: 14,990
|
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
|
#11
|
elite*gold: 0
Join Date: Mar 2010
Posts: 360
Received Thanks: 132
|
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
|
#12
|
elite*gold: 103616
Join Date: Apr 2010
Posts: 13,737
Received Thanks: 14,990
|
Ist richtig
|
|
|
|
Similar Threads
|
3D File Types reversen
09/04/2014 - General Coding - 2 Replies
Hallo,
hat hier jemand Erfahrung im Reversen von 3D Model Datei Typen?
Ist ein Byte Format, kein Text Format (wie .x bspw).
Dadurch dass es ein eigenes Format ist, wird es da wohl keine allgemeine Lösung geben, aber eventuell kann mir hier jemand ja ein paar Tipps geben wie es möglicherweise aufgebaut sein kann oder wie ich dabei vorgehen kann.
Vermutlich wird jeder Vertex mit 3 Koordinaten gespeichert, innerhalb eines blocks von 3 Vertices für 1 Polygon?
Macht man das so?
UV Map...
|
Bit-Operatoren Reversen
06/30/2014 - General Coding - 2 Replies
Hallo EPVP,
Ich brauchte mal eure hilfe bei einem Kleinen Problem.
Und zwar bräuchte ich für
(0x7f-($color>>25)<<24)|($color&0 xffffff)
den umgekehrten Algorithmus.
Wäre euch sehr dank bar.
|
Verschlüsselung reversen?
12/23/2013 - General Coding - 10 Replies
Hi,
ich würde gerne wissen wie man am besten an eine Packetverschlüsselung rangeht um diese zu reversen. Ich weiß, dass die von Nostale z.B. nicht sehr schwer zu knacken ist und mithilfe eines Sessionkeys encrypted wird, ab der Channelauswahl.
Jemand ne Idee wie ich das am besten lernen kann?
Aus
88226
wird (in HEX)
9A AC E4 90 DB 75 AF 0E
|
Mit Olly reversen und in C++ Hooken
12/15/2011 - C/C++ - 22 Replies
Guten Tag Gemeinde ;)
Ich hoffe der Titel is einigermaßen io, mir is einfach nichts besseres eingefallen ^^
Wie ich ja schon in einem anderen Thread beschrieben habe möchte ich Tastenanschläge an das Spiel DAOC senden, jedoch werden die Funktionen (Send- & Postmessage und co) geblockt, bzw die Virtuellen Inputs.
Headpuster gab mir diesen Hinweis, bzw diese Hilfe:
Ich dachte mir ich mach mal n neuen Thread auf, da es ja jetzt in den Bereich C/C++ geht und nicht mehr .Net.
Ich bin...
|
All times are GMT +1. The time now is 06:32.
|
|