|---------------------------------------------------------------|
|                                                               |
| tutorial written by R!SC sometime in 1999 . (c) R!SC aswell . |
| dont distribute in any other form except this zip it came it. |
|                                                               |
|   http://csir.cjb.net for all my l33t tutorials on cracking   |
|                                                               |
|---------------------------------------------------------------|



C-Dilla, the wrong way to crack it.. r.e tiberian sun v1.08 (sales version)

(old c-dilla now :(  they updated it with tiberian sun v1.13, see eof for info)

hi, i wanted to do this tutorial ever since i cracked Tiberian Sun, so, here it is

things i expect from you, the pupil's.. please have read Black Check's tutorial on
C-Dilla, and make sure you understand it, you to have read @ least one pe document,
explaining the pe file format, to 0wn softice + icedump, and if you need to, read
int68.txt for how to bypass some anti softice..

i use softice3.23 with modified pagein command (which takes no extra paramaters,
unlike the newer icedump..) , ProcDump, HexWorkshop & pesplit.

Down to business then.

Part 1: Study our target.

use procdump or pesplit to get our info on section addresses and RAW size's so we know
where to dump from, and how much to dump

Sections information for game.icd
Name    RVA         Size
.text   0x1000      0x297000
.rdata  0x298000    0x23000
.data   0x2bb000    0x55000
.rsrc   0x437000    0x4000

EntryPoint 0x2854e3


right, we already know the imagebase is 00400000h dont we? good, so add this to the
RVA's from the pe-header, and you know where to dump from.. the program entry point is
6854e3, so we have to bpx 6854e3.. but.. first run game.exe, wait for the pretty
splash picture to go, then bpx freelibrary & display the entry point in your data
window (d 6854e3). wait for Softice to break on FreeLibrary. when it does, hit F11,
and check the data window, see if the program has decrypted yet.. if not, F5, and try
again.. if it has.. clear/disable the FreeLibrary breakpoint, and set a breakpoint on
the entry point (bpx 6854e3). F5 and wait a few milliseconds..

the program breaks, everything is decrypted, but the .rdata section is a little
screwy.. no matter, dump all other sections to seperate files.. (using softice) (bd*
before though.. dont want a dump with breakpoints in it..)

pagein 401000 297000 c:\ts.text.bin
pagein 6bb000 55000 c:\ts.data.bin
pagein 837000 4000 c:\ts.rsrc.bin

k, sorted.. 50% done.. now we do a little research into the fux0red up api calls.
Trace into one of the calls that call dword ptr [in my .rdata section].

006854E3  55                  PUSH    EBP  <-- entry point, where it breaks..
006854E4  8BEC                MOV     EBP,ESP
006854E6  6AFF                PUSH    FF
006854E8  68D87D6A00          PUSH    006A7DD8
006854ED  68084F6800          PUSH    00684F08
006854F2  64A100000000        MOV     EAX,FS:[00000000]
006854F8  50                  PUSH    EAX
006854F9  64892500000000      MOV     FS:[00000000],ESP
00685500  83EC58              SUB     ESP,58
00685503  53                  PUSH    EBX
00685504  56                  PUSH    ESI
00685505  57                  PUSH    EDI
00685506  8965E8              MOV     [EBP-18],ESP
00685509  FF1554826900        CALL    [00698254] <-- first api call (trace into this)
0068550F  33D2                XOR     EDX,EDX
00685511  8AD4                MOV     DL,AH

tracing into this call, we find this code.. 

00AD4143  60                  PUSHAD
00AD4144  6867000000          PUSH    00000067     <-- api wanted
00AD4149  6800000000          PUSH    00000000     <-- from which library?
00AD414E  FF156441AD00        CALL    [00AD4164]   <-- call [c-dilla]
00AD4154  83C408              ADD     ESP,08
00AD4157  61                  POPAD
00AD4158  FF255E41AD00        JMP     [00AD415E]
00AD415E  0000                ADD     [EAX],AL
00AD4160  0000                ADD     [EAX],AL

if you trace over the CALL [00AD4164], you see the JMP [00AD415E] change into JMP
[KERNEL32!GetVersion] .. this is good, so you know push 0 means kernel, so push 1 will
be user.

figure out the amount of kernel and user api's used by the program.. (you can scroll
the code window, look for the last pushes before it changes onto user api's, then
scroll looking for the last push before all the code ends.. or you could count them in
the wdasm listing of game.icd.. or just count them in the physical .rdata section from
the *.icd file..)

well, in the rdata section.
kernel calls start @ offset B8h and end @ offset 31Ch
this is 264h bytes / 4 (each api address is a dword.) == 99h 
user calls start @ offset 358h and end @ offset 4C8h
this is 170h bytes / 4 == 5Ch

or scrolling the code window..

00AD4858  60                  PUSHAD
00AD4859  6898000000          PUSH    00000098     <-- last kernel api used
00AD485E  6800000000          PUSH    00000000     <-- last push 0
00AD4863  FF157948AD00        CALL    [00AD4879]
00AD4869  83C408              ADD     ESP,08
00AD486C  61                  POPAD
00AD486D  FF257348AD00        JMP     [00AD4873]
00AD4873  0000                ADD     [EAX],AL
00AD4875  0000                ADD     [EAX],AL
00AD4877  0000                ADD     [EAX],AL
00AD4879  D0E9                SHR     CL,1
00AD487B  A800                TEST    AL,00
00AD487D  0000                ADD     [EAX],AL
00AD487F  00540D00            ADD     [ECX+EBP+00],DL
00AD4883  A060680000          MOV     AL,[00006860]
00AD4888  0000                ADD     [EAX],AL
00AD488A  6801000000          PUSH    00000001     <-- first push 1

..

00AD4884  60                  PUSHAD
00AD4885  6800000000          PUSH    00000000
00AD488A  6801000000          PUSH    00000001     <-- same push 1 as before..
00AD488F  FF15A548AD00        CALL    [00AD48A5]
00AD4895  83C408              ADD     ESP,08
00AD4898  61                  POPAD
00AD4899  FF259F48AD00        JMP     [00AD489F]

..

00AD55AB  60                  PUSHAD
00AD55AC  685B000000          PUSH    0000005B     <-- last user api used
00AD55B1  6801000000          PUSH    00000001     <-- last push 1
00AD55B6  FF15CC55AD00        CALL    [00AD55CC]
00AD55BC  83C408              ADD     ESP,08
00AD55BF  61                  POPAD
00AD55C0  FF25C655AD00        JMP     [00AD55C6]
00AD55C6  0000                ADD     [EAX],AL
00AD55C8  0000                ADD     [EAX],AL
00AD55CA  0000                ADD     [EAX],AL     <-- see? no more code
00AD55CC  D0E9                SHR     CL,1
00AD55CE  A800                TEST    AL,00


okay, from this way, we still get the same results..

015F:00AD4859  6898000000          PUSH    00000098

the first push is always 0, so, 0-98h == 99h kernel api's used

015F:00AD55AC  685B000000          PUSH    0000005B

same here.. == 5Ch user api's used..

k, now the messy bit is over, we start to have a bit of fun.. recall the first call we
came across? we borrow the address that this calls (the rva to the c-dilla routine)
and use it to fix our rdata section.. since we dont have write access to our rdata
section, copy it into the data section .. then code where ever u like.. (btw, its best
to exit the program, and re-run it, breaking on the entry point again.. then trying to
fix the rdata section)

m 698000 l 23000 6c0000 (698000 is the rva of our rdata section.. 23000 is the RAW
size of it, and 6c0000 is in the data section, just , 6c0000 is nicer to work with
than 6bb000..)

then code this..

00 pushad
01 push ebx
02 push 0
04 call [00AD4164]  ;borrowed from c-dilla routine
0A add esp,8
0D mov edx, 6c0000  ;address where we copied our .rdata section to
12 cmp eax,[edx]    ;eax == addr of the c-dilla routine that should have called this code
14 je 20
16 inc edx
17 cmp edx, 6c0000+23000
1D jne 12
1F int 03           ;safty, if it found no match, break here.
20 mov [edx],ecx    ;ecx == actual api address
22 popad
23 inc ebx
24 cmp ebx, 99      ;how many kernel api's to fix
2A jne 00
2C int 03

k, set ebx to 0, set your eip to line 0 ,i3here on, run it, hope u break on 2C .. if
so, you have to set ebx back to 0, change line 02 to read 'push 1', change line 24 to
'cmp ebx, usercount' (5C..) and set the eip back line 0. run it again. if all goes
well, dump the new rdata section to disk..

pagein 6c0000 23000 c:\ts.rdata.bin

we have everything now, but the pe header.. so hexedit game.icd, copy the pe header
(1000h bytes from offset 0.) and paste it into a new file 'ts.header.bin' and save.

bah. fuck. worst part of c-dilla now, make the file work. the first c-dilla game i
cracked, it would only run on win98, cause my rdata section contained the address's of
all the functions from win98 (the os i cracked it on) trying to rebuild it with
procdump didnt work, so i had to research pe files, and came up with a *real* dodgy
solution.. see iat_fix.asm .. then i'll take you through what it *tries* to do.


we can skip this part for now . 

you should have 5 files..

copy or move them to your work directory, and run a dos prompt here ..

copy /b ts.header.bin + ts.text.bin + ts.rdata.bin + ts.data.bin + ts.rsrc.bin mygame.exe

if mygame.exe runs you are lucky . if it doesnt run, dont ph34r, u can fix it . 

right, use pesplit on game.icd . take the rdata section, probably called section1.bin,
rename it ts.rdata.icd . hex edit it . the first dword value in it is the first rva in
the first thunk, pointing to RegCloseKey. copy the 4 bytes @ offset 0, and search for
another match for them . you should find one @ offset 20960, this should be the
original first thunk .

r.e. dword @ offset 0 == 1C9D2B00 == 002b9d1c .
002b9d1c - 00298000 (rva of rdata section) == 21d1c (our file offset.)

21d1c --> dw 015bh  ; hint
          db 'RegCloseKey',0    ; asciiz

the first thunk rva's & orig first thunk rva's that point to the kernel32 & user32
asciiz's are messed up in the *.icd file . but all other rva's are ok, so iat_fix.asm
will hunt through your asciiz hint table in ts.rdata.icd, get every procaddress it
can, and search for a match in our dumped ts.rdata. if it finds one, it will calculate
the file offset to the match, then the correct rva to the asciiz it is for, then it
modifies ts.rdata.icd, replacing the fake rva's in the first & original thunks.

hopefully you understand . sometimes their is an api address in dumped rdata section
that their is no asciiz for . if so, you will have to hunt it down by hand, and add it
to your ts.rdata.new section, by hand . this sucks . but i have coded a fully working
one since v0.03 . requires a bit more pe knowledge to use though . ack ..

C-Dilla, the wrong way to crack it.. its all over!



r.e new cdilla . hehe . top secret information :d go figure
