tCA Cracking Tutorial 
*********************


Written by TiVe
***************



Hi folks welcome to a new cracking tutorial. This time we gonna crack 

						Soldier of Fortune 1.04
						-----------------------

Now you will say, that Bug_Error already wrote a tutorial about Soldier of Fortune ( short SoF ). Thats true, but Raven changed their protection style a little bit. In my opinion it's even more stupid, but thats another topic...
You have to see this tutorial as an add-on to Bug_Errors tutorial.


Ok, here we go...You need the following things :

- W32Dasm 8.93
- SoftIce 3.2x better 4.0x
- HIEW 6.xx


-----


Ok, at first we must find out where SoF checks for the CD. Insert a cd ( can be everything ) and start the game to check out where the game seems to check for the CD. We see and hear that SoF checks the CD right before the Parental Warining Message appears. But perhaps there is another place where it checks...try to start a game and ... nothing the first place seems to be the only place where SoF checks for the CD. Ok, now let's find out the address where the CD check gets performed.
we do it like in Bug's tutorial. But first start the game again. If the screen turns black push CTRL+D to get Softice appear. Now set a breakpoint on GetDriveTypeA ( bpx getdrivetypea ). Seconds later we should find ourselfs back in SoftIce. SWEET :)
Now we should see this lines of code :

* Reference To: KERNEL32.GetDriveTypeA, Ord:0104h
                                  |
:2006C68B 8B2D68F11720            mov ebp, dword ptr [2017F168]

* Reference To: WINMM.mciSendCommandA, Ord:0033h
                                  |
:2006C691 8B3D40F31720            mov edi, dword ptr [2017F340]
:2006C697 895C2410                mov dword ptr [esp+10], ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:2006C79F(C)
|
:2006C69B 8A4C2410                mov cl, byte ptr [esp+10]
:2006C69F 8D542440                lea edx, dword ptr [esp+40]
:2006C6A3 80C141                  add cl, 41
:2006C6A6 52                      push edx
:2006C6A7 884C2444                mov byte ptr [esp+44], cl
:2006C6AB C64424453A              mov [esp+45], 3A
:2006C6B0 C64424465C              mov [esp+46], 5C
:2006C6B5 885C2447                mov byte ptr [esp+47], bl
:2006C6B9 FFD5                    call ebp
:2006C6BB 83F805                  cmp eax, 00000005    <-- AHA !! CD-ROM !!
:2006C6BE 0F85CF000000            jne 2006C793	       <-- If CD content is right, do NOT jump 	 
:2006C6C4 33C0                    xor eax, eax
:2006C6C6 8A4C2440                mov cl, byte ptr [esp+40]
:


Ok, so we found the point in the code where the CD contents get read out. Its seems , we are on the right way :D

Now disassemble the file Sof.exe and serach for KERNEL32.GetDriveTypeA and the code below this imported function ( should be the second GetDriveTypeA call ). Ok, now lets have a look what happens if the CD content is wrong or not available ( NO CD ).
Point the cursor on 2006C6BE and push "-->" on the keyboard. You now are at the place wgere this jumps leads to :

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:2006C6BE(C), :2006C71B(C), :2006C758(C), :2006C76A(C) <-- Hmm very interesting...
|
:2006C793 8B442410                mov eax, dword ptr [esp+10]
:2006C797 40                      inc eax
:2006C798 83F81A                  cmp eax, 0000001A
:2006C79B 89442410                mov dword ptr [esp+10], eax
:2006C79F 0F8CF6FEFFFF            jl 2006C69B
:2006C7A5 5F                      pop edi
:2006C7A6 5E                      pop esi
:2006C7A7 5D                      pop ebp
:2006C7A8 33C0                    xor eax, eax
:2006C7AA 5B                      pop ebx
:2006C7AB 81C434050000            add esp, 00000534


As we see at the code above there are three more conditional jumps which points to this location ... It's not logic that a program points four times to this location if the CD is right. So this might be the place where we don't want to land.
Lets keep this fact in mind. It seems, that we have to kill all four conditional jumps. Here are the adresses from the jumps:

:2006C6BE 0F85CF000000            jne 2006C793  ( Hex-Offset : 6C6BE )
:2006C71B 7576                    jne 2006C793  ( Hex-Offset : 6C71B )
:2006C758 7539                    jne 2006C758  ( Hex-Offset : 6C758 )
:2006C76A 7527                    jne 2006C793  ( Hex-Offset : 6C76A ) 


So far so good. If we kill the four conditional jumps we get sooner or later to this location :

:2006C773 7E1A                    jle 2006C78F <-- Number one ...
:2006C775 33C9                    xor ecx, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:2006C78D(C)
|
:2006C777 8BB40C4C030000          mov esi, dword ptr [esp+ecx+0000034C]
:2006C77E 3BB40C4C010000          cmp esi, dword ptr [esp+ecx+0000014C]
:2006C785 7508                    jne 2006C78F <-- Number two ...
:2006C787 40                      inc eax
:2006C788 83C104                  add ecx, 00000004
:2006C78B 3BC2                    cmp eax, edx
:2006C78D 7CE8                    jl 2006C777 <-- a little loop ... not important


As we see, there are two jumps which points to the same code location : 2006C78F. Lets have a look at this piece of code :

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:2006C773(C), :2006C785(C)
|
:2006C78F 3BC2                    cmp eax, edx
:2006C791 741F                    je 2006C7B2


Hmm, what a stupid code. This lines do nothing except a compare. So I thought a bit. After some time ( a coke and a hamburger  :) I decided to change 

:2006C773 jle 2006C78F 			
		        	TO
:2006C773 JMP 2006C7B2		( Hex-Offset : 6C773 )


This change forces the pürogram to jump directly to the good end of the cd copy protection. Hmm, sounds good theoretically, but lets proof it ... 

Fire up HIEW and open the sof.exe ( or better a backup copy of it ) and push F4 --> Decode and F5 type in the hexoffset from the first JNE 2006C793 ( 6C6BE ). Now push F3 to go to edit mode. Simply type in 90 90 90 90 90 90 ( 6X NOP ). NOP means No OPeration.
The bad JNE is away :9 Nopw do exactly the same with other three JNE'S I wrote above.
Now go to the Hex-Offset 6C773 and push F3 and then F2 ! You can now directly input the changes you want to make. 
Change the JLE at the beginning into a JMPS ( JMPS = this jump only needs 2 bytes !! ) and the 6C78F into 6C7B2. Ok, now push ESC and F9. At last F10 ! Now lets try to play the game without the CD ...

It works :) Congratulations !!!

Now we can play the game without CD. Lets gonna play a few level with blood and gore ( yeah ). Go into the Violence lock menu and try to enable the options... WHAT ?? You can't enable the options ? HMMM...perhaps you are playing the german version of this game ( or the updated US Version on a german computer ). Without the blood and gore I don't have as much fun as with splatter. Let's try to fix this bug.

Open Sof.exe again in W32DASM and think a bit how we can bypass this detection. The program has to look in which country we live. I looked in my API references and I found a Function called GetLocalInfoA. Lets have a look if this function is called ... Look in the Imported functios list in W32DASM. You should find this function. Doubleclick on it and you should see this :

* Reference To: KERNEL32.GetLocaleInfoA, Ord:011Ch
                                  |
:200544DC 8B3554F11720            mov esi, dword ptr [2017F154]
:200544E2 6800040000              push 00000400
:200544E7 50                      push eax
:200544E8 6A05                    push 00000005
:200544EA 6800080000              push 00000800
:200544EF 32DB                    xor bl, bl
:200544F1 FFD6                    call esi
:200544F3 8D4C240C                lea ecx, dword ptr [esp+0C]
:200544F7 51                      push ecx
:200544F8 E80EBD0F00              call 2015020B
:200544FD 83C404                  add esp, 00000004
:20054500 83F831                  cmp eax, 00000031
:20054503 7508                    jne 2005450D
:20054505 B301                    mov bl, 01
:20054507 881D74544C20            mov byte ptr [204C5474], bl

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:20054503(U)
|
:2005450D 8D54240C                lea edx, dword ptr [esp+0C]
:20054511 6800040000              push 00000400
:20054516 52                      push edx
:20054517 6802100000              push 00001002
:2005451C 6800080000              push 00000800
:20054521 FFD6                    call esi
:20054523 8D44240C                lea eax, dword ptr [esp+0C]

* Possible StringData Ref from Data Obj ->"Germany" <-- OHHHHHHH ... seems we are right here :)
                                  |
:20054527 6898371C20              push 201C3798
:2005452C 50                      push eax

Ok, now it gets a bit diffucult, because there are many JNE's and there are many combinations...I can't really describe how I made it ( If I am precise, it was try and error ). the first thing I made was to change all JNE's in this section. These are the following :

20054503 	jne 2005450D   ( Hex-Offset : 54503 )
20054537        jne 20054541   ( Hex-Offset : 54537 )
2005456B        jne 20054577   ( Hex-Offset : 5456B )


I changed them Into JMP'S ( JMPS ). Do do this go into HIEW and change the three offsets. Change the 75 into an EB. Now save again and try to enable the violence...it works. It's all enabled :)


Now you cracked the program completly and you have ( as a bonus ) all blood and gore enabled :) 

OK, I hope I could teach you a little bit how you can crack an easy CD-Protection sheme.





Greetings fly out to :     All tCA members, all Laxity members. 
Special Greetings fly out to the following people : Bug Error ;), NADA, WAXWeael and NecroNob. You guys are very cool :)


If you have any suggestions, questions or ideas which could make my tutorials better, then feel free to write an e-mail to :
TiVe@@gmx.de

														-TiVe