           WIE MAN .EXE DATEIEN, DIE MIT WWPACK GEPACKT WURDEN, ENTPACKEN KANN
                                                      von ultraschall/blizzard
------------------------------------------------------------------------------



Einfhrung.
------------------------------------------

Ich werde dir mit diesem kleinen Tutorial zeigen, wie man alle mit WWPACK
gepackten .exe Dateien entpacken kann - ohne ProcDump und dergleichen
natrlich ;)
Unser Ziel ist es, die ausfhrbare Datei des Spieles "Diamond Caves II" zu
entpacken (www.diamond-pro.com).



Tools, die wir brauchen werden.
------------------------------------------

SoftICE, HIEW (Hexeditor), Taschenrechner mit Untersttzung fr Hexzahlen
(ich habe den CASIO fx-922s) oder halt irgendeinen Softwaretaschenrechner,
dann brauchen wir noch pesplit.exe und pejoin.exe, und schlielich noch
einen SoftIce Memory Dumper (z.b. meinen).

Den SoftIce Memory Dumper, pesplit und pejoin (= peutils) bekommt ihr hier:
http://musik.freepage.de/xtended_base/sidump.zip
http://musik.freepage.de/xtended_base/peutils.zip



Essay.
------------------------------------------

Wie alle .exe Pack- respektive Verschlsselungsprogramme fgt auch WWPACK
eine neue Section in die .exe Datei ein: ".WWP32".
Diese Section enthlt ausfhrbaren Code. Dieser Code entpackt alle gepackten
Sections (in unserem Fall nur die CODE-Section), und bergibt dem eigentlichen
Programm die Kontrolle (d.h. nach dem entpacken wird zum eigentlichen Programm-
start gesprungen). Es ist klar, da die .WWP32 Section zuerst ausgefhrt werden
mu, weil der eigentliche CODE ja noch nicht ausfhrbar ist, aufgrund des
komprimierten Zustandes. Demnach muss WWPACK den Einsprungspunkt ("EP") zur 
.WWP32-Section umgelenkt haben.

Der aktuelle EP ist:
(z.B. mit HIEW zu ermitteln: dc2.exe laden,Hexmodus,F8):

   0x6BB000 (absolute Addresse [im Speicher])

Jedoch wird in HIEW diese Addresse nicht direkt angezeigt, man mu Sie selber
berechnen:

   Entrypoint RVA:   0x2BB000
   Image base....: + 0x400000
                     --------
		     0x6BB000

(Oder man kann auf auf F5 (glaub ich) drcken, dann springt HIEW zum 
EP. Dann kann man diese Addresse auch links ablesen.)

OK, wir wissen jetzt wo der EP ist. Jetzt weck mal SoftIce auf und starte
den SoftIce Symbol Loader und mach folgendes:

   File/Open Module --> DC2.exe auswhlen
   und dann Module/Load

Jetzt noch die nachfolgende Messagebox mit JA besttigen und SoftIce sollte
jetzt aufpoppen, und zwar an Offset 0x6BB000:

(Disassemblat von IDA PRO v3.8b, mit ein paar Vernderungen von mir)
006BB000                 push    ebx
006BB001                 push    ebp
006BB002                 mov     ebp, eax
006BB004                 xor     ebx, ebx
006BB006                 jmp     6BB068
006BB006 
  ...
006BB068 loc_0_6BB068:
006BB068                 call    6BB06D  ; ruft den nchsten Offset auf
					 ; --> wegen delta-offset Berechnung
					 ; aber unwichtig hier.
006BB06D                 pop     ebp
006BB06E                 cmp     byte ptr ds:[ebp+32h], 0E8h
006BB073                 jz      6BB2C1  ; interessante Ziel-Location, relativ
                                         ; weit unten!
006BB079                 pusha
006BB07A                 sub     ebp, 6Dh
006BB07D                 xor     eax, eax
006BB07F                 xor     ecx, ecx
006BB081                 mov     cx, 9Ch

usw...

OK, unsere erste Aufgabe ist es den ursprnglichen EP zu finden. Wir knnten
jetzt den Code tracen bis wir es rausfinden, oder wir knnten nach JMPs/CALLs
suchen, die aus der .WWP32 Section rausspringen! Der Entpacker mu alle 
gepackten Sections entpacken bevor er aus der eigenen Section rausspringen 
darf. Die .WWP32 Section beginnt an Offset 0x6BB000 (zu ermitteln mit HIEW:
Datei laden,Hexmodus,F8,F6,Image Base (400000) + RVA Wert, der in der .WWP32-
Zeile eingezeigt wird). OK, um uns die ganze .WWP32 Section anschauen zu knnen
mssen wir noch ein paar Zeilen tracen, weil diese Section zum Teil 
verschlsselt ist. Ich erspare dir die Suche: Trace bis zum Offset 0x6BB097.
Dann wird die .WWP32 Section vllig entschlsselt sein.

Jetzt mssen wir nach JMPs/CALLs suchen, die aus der .WWP32-Section 
rausspringen:

006BB2B2 loc_0_6BB2B2:                          
006BB2B2                 pop     eax
006BB2B3                 mov     ebp, eax
006BB2B5                 add     eax, cs:[ebp+2C4h]
006BB2BC                 add     eax, 2C8h
006BB2C1
006BB2C1 loc_0_6BB2C1:                        
006BB2C1                 pop     ebp
006BB2C2                 pop     ebx
006BB2C3                 jmp     4B90DC   <--- hier wird die .WWP32 verlassen!!

Setze nun ein Breakpoint an 0x6bb2ca.
OK, jetzt diesen JMP ausfhren und wir landen in der CODE Section!
Folgerung: CODE Section ist zu diesem Zeitpunkt vollstndig entpackt und
           0x4b90dc ist der ursprngliche EP der Datei.

Unsere zweite Aufgabe ist es, die entpackte CODE Section in einer Datei 
festzuhalten. Jetzt kommt mein Memory Dumper zum Zuge.
Zuerst brauchen wir aber noch ein paar Informationen zur CODE Section.
Fhre dazu pesplit.exe mit dc2.exe als Parameter aus:
  pesplit dc2.exe
  
Das Programm wird mehrere .bin- und eine .pe Datei erzeugen. ffne die
.pe Datei (dc2.exe.pe) mit einem Texteditor und scoll so lange runter,
bis du folgendes siehst:

(Datei: dc2.exe.pe)
Sections
Name	VSize	 RVA	  Size	   Offset   Rel	Lines #Rel #Line Flags	   ...
CODE	0xb8410	 0x1000	  0x50c00  0x400    0x0	0x0   0x0  0x0	0xe0000020 ...
DATA	0x15f0	 0xba000  0x1600   0x51000  0x0	0x0   0x0  0x0	0xc0000040 ...
BSS	0x9679	 0xbc000  0x0	   0x52600  0x0	0x0   0x0  0x0	0xc0000000 ...
.idata	0x228a	 0xc6000  0x2400   0x52600  0x0	0x0   0x0  0x0	0xc0000040 ...
.tls	0x8	 0xc9000  0x0	   0x54a00  0x0	0x0   0x0  0x0	0xc0000000 ...
.rdata	0x18	 0xca000  0x200	   0x54a00  0x0	0x0   0x0  0x0	0xd0000040 ...
.reloc	0xa42c	 0xcb000  0x200	   0x54c00  0x0	0x0   0x0  0x0	0xd0000040 ...
.rsrc	0x1e4800 0xd6000  0x1e4800 0x54e00  0x0	0x0   0x0  0x0	0xd0000040 ...
.WWP32	0x580e   0x2bb000 0x5a00   0x239600 0x0	0x0   0x0  0x0	0xc0000040 ...

VSize (Virtual Size): Gre der Section im Speicher
Size (Physical Size): Gre der Section in der Datei
Offset (Physical Offset): Dateioffset des ersten Bytes der Section
Der Rest ist unwichtig.

Name	VSize	 RVA	  Size	   Offset   
CODE	0xb8410	 0x1000	  0x50c00  0x400

Wie man unschwer sehen kann ist VSize grer als Size. 
Q: Aber was steckt dahinter?
A: Die (Physikalische) Gre der komprimierten CODE Section betrgt 0x50c00,
und wenn sie entpackt wird, wird sie ja logischerweise grer. Die Gre
wird dann 0xb8410 betragen.
Also, wir wissen jetzt wie gro die entpackte CODE Section ist; wir mssen
also 0xb8410 Bytes der CODE Section in eine Datei speichern.
Bevor wir dies tun knnen mssen wir noch den Speicheroffset des ersten
Bytes der Section berechnen:
  RVA    + IMAGE BASE 
  0x1000 + 0x400000   = 0x401000

OK, starte nun den Memory Dumper und gib einen Dateinamen 
(z.b. codesection.bin) und Filesize (b8410) ein. Jetzt auf "Initialize"
klicken und den Offset, der ganz unten bei "Copy the memory block to this 
offset" angezeigt wird aufschreiben. DEN DUMPER NOCH NICHT SCHLIEEN !!!!

Jetzt dc2.exe laden warten, da SoftIce an unserem Breakpoint aufpoppt
(falls SoftIce nicht aufpoppen sollte, mut du die Datei wieder mit dem
Symbol Loader laden und dann in SoftIce "g 6bb2c3" eingeben).
So, jetzt folgendes in SoftIce eingeben:

    m 401000 l b8410 82952000
                     ^^^ diesen Offset durch dem vom Dumper zurckgelieferten
		     ersetzen !!!!

Die CODE Section ist nun in der Datei gespeichert. OK, raus aus SoftIce und
beim Memory Dumper auf "Quit" klicken.

Unsere dritte Aufgabe ist es, die gepackte CODE Section durch unsere gerade
gedumpte CODE Section zu ersetzen. berschreibe nun section0.bin 
(wurde von pesplit erstellt) mit der Datei die vom Dumper erstellt wurde.
ffne dc2.exe.pe mit einem Texteditor und scroll an die Stelle an der wir 
vorhin schon waren. Wir mssen jetzt die Start-Offsets der einzelnen Sections
neu berechnen.

(File: dc2.exe.pe)
Sections
Name	VSize	 RVA	  Size	   Offset   Rel	Lines #Rel #Line Flags	   ...
CODE	0xb8410	 0x1000	  0x50c00  0x400    0x0	0x0   0x0  0x0	0xe0000020 ...
DATA	0x15f0	 0xba000  0x1600   0x51000  0x0	0x0   0x0  0x0	0xc0000040 ...
BSS	0x9679	 0xbc000  0x0	   0x52600  0x0	0x0   0x0  0x0	0xc0000000 ...
.idata	0x228a	 0xc6000  0x2400   0x52600  0x0	0x0   0x0  0x0	0xc0000040 ...
.tls	0x8	 0xc9000  0x0	   0x54a00  0x0	0x0   0x0  0x0	0xc0000000 ...
.rdata	0x18	 0xca000  0x200	   0x54a00  0x0	0x0   0x0  0x0	0xd0000040 ...
.reloc	0xa42c	 0xcb000  0x200	   0x54c00  0x0	0x0   0x0  0x0	0xd0000040 ...
.rsrc	0x1e4800 0xd6000  0x1e4800 0x54e00  0x0	0x0   0x0  0x0	0xd0000040 ...
.WWP32	0x580e   0x2bb000 0x5a00   0x239600 0x0	0x0   0x0  0x0	0xc0000040 ...

Erst einmal folgende Frage:
Q: Was hat sich verndert?
A: Die physikalische Gre der CODE Section (--> entpackt)

Ersetze 0x50c00 durch 0xb8410 (= Dateigre von section0.bin).

Jetzt mssen wir die Physikalischen Offsets neu berechnen:

Name  ...  Size  ...  Offset 
CODE       0xb8410    0x400    
DATA       0x1600     0x51000  
BSS        0x0        0x52600  
.idata     0x2400     0x52600  
.tls       0x0        0x54a00  
.rdata     0x200      0x54a00  
.reloc     0x200      0x54c00  
.rsrc      0x1e4800   0x54e00  
.WWP32     0x5a00     0x239600

Der Offset der CODE Section verndert sich nicht, das ist ja logisch.
Jetzt brauchen wir den Taschenrechner:

 0x400   + 0xb8410  = 0xb8810  -> Offset von DATA   durch diesen Wert ersetzen
 0xb8810 + 0x1600   = 0xb9e10  -> Offset von BSS    durch diesen Wert ersetzen
 0xb9e10 + 0x0      = 0xb9e10  -> Offset von .idata durch diesen Wert ersetzen
 0xb9e10 + 0x2400   = 0xbc210  -> Offset von .tls   durch diesen Wert ersetzen
 0xbc210 + 0x0      = 0xbc210  -> Offset von .rdata durch diesen Wert ersetzen
 0xbc210 + 0x200    = 0xbc410  -> Offset von .reloc durch diesen Wert ersetzen
 0xbc410 + 0x200    = 0xbc610  -> Offset von .rsrc  durch diesen Wert ersetzen
 0xbc610 + 0x1e4800 = 0x2a0e10 -> Offset von .WWP32 durch diesen Wert ersetzen

Die Offsets sind aber noch nicht ganz gefixt!
Wir mssen alles, wie in fileAlign angegeben, ausrichten:

NTOptionalHeader
	magic 0x10b
	linkerMajor 0x2
	linkerMinor 0x19
	codeSize 0xb8400
	initDataSize 0x1f2a00
	uninitDataSize 0x0
	entryPoint 0xb90dc
	codeBase 0x1000
	dataBase 0xba000
	imageBase 0x400000
	sectionAlign 0x1000
	fileAlign 0x200  <- Immer 0x200 Byte boundaries

Jetzt noch folgendes mit der CODE Section machen:

 0xb8410 / 0x200 = 0x5c2  -> 0xb8410 - (0x5c2 * 0x200) = +0x10 (16 bytes vom Ende der
                                                                Datei section0.bin lschen!)

Und dann mssen wir noch jeweils 0x10 (= 16) von den Physikalischen Offsets der
Sections abziehen:

 Offset von Data  : 0x0b8810 - 0x10 = 0x0b8800
 Offset von BSS   : 0x0b9e10 - 0x10 = 0x0b9e00
 Offset von .idata: 0x0b9e10 - 0x10 = 0x0b9e00
 Offset von .tls  : 0x0bc210 - 0x10 = 0x0bc200
 Offset von .rdata: 0x0bc210 - 0x10 = 0x0bc200
 Offset von .reloc: 0x0bc410 - 0x10 = 0x0bc400
 Offset von .rsrc : 0x0bc610 - 0x10 = 0x0bc600
 Offset von .WWP32: 0x2a0e10 - 0x10 = 0x2a0e00

Jetzt noch die alten Werte durch diese ersetzen und die Offsets sind gefixt.

Unsere letzte Aufgabe ist es den EP wieder in den ursprnglichen Zustand zu
versetzen:

NTOptionalHeader
	magic 0x10b
	linkerMajor 0x2
	linkerMinor 0x19
	codeSize 0xb8400
	initDataSize 0x1f2a00
	uninitDataSize 0x0
	entryPoint 0x2bb000  <-- Entry Point RVA
	codeBase 0x1000
	dataBase 0xba000
	imageBase 0x400000

Wir haben ja rausgefunden, da 0x4b90dc der ursprngliche EP ist. Aber
diese Addresse ist eine absolute Addresse im Speicher. Wir brauchen
jedoch einen RVA Wert. Um dies zu bekommen, mssen wir folgendes berechnen:

     EP       - IMAGE BASE = EP RVA
     0x4B90DC - 0x400000   = 0xb90dc

OK, jetzt 0x2bb000 durch 0xb90dc ersetzen, die Datei speichern und den 
Texteditor beenden.

Jetzt noch pejoin wie folgt starten:
  pejoin dc2.exe.pe dc2unp.exe
                       ^ ziel .exe dateiname

dc2unp.exe ist nun die entpackte Version des Spiels. Wenn du die Datei
ausfhrst solltest du eine Fehlermeldung bekommen, die sagt, die Datei
sei durch einen Virus beschdigt worden. Das ist der .exe-Check des
Spiels und hat mit meinem Thema nichts zu tun.

                                                                 regards,
								 ultraschall
