Desperados: Wanted Dead Or Alive Crack
TUTORIAL about Laserlock v5.00.06 (Desperados : Wanted Dead Or Alive) :
Commercial protection : Laserlock v5.00.06 (http://www.laserlock.com/)
Editor : Infogrames
Release date : FR April 27, 2001
http://www.jeuxvideo.com/articles/0000/00001354_test.htm
Official site :http://www.spellbound.de/web/en/sb.php?m0=p_d1&r0=p_d1r&id=10&id2=1
Cracking level : [x] easy [x] intermediate [ ] confirmed [ ] expert
It would be better if you have already cracked protections like Safedisc/SecuROM, before reading this tutorial. (It also requiresknowledge about PE format, manual unpacking and imports rebuilding).
Tools needed :
Softice 4.01
Icedump
Procdump/LordPE
Hiew/Hex Workshop
W32Dasm
Adump
Masm v8
You must have the original disc of this game or a functional clone (there is a Laserlock profile in Alcohol 120%) to be able to apply the 1st part of this tutorial…
It is nevertheless possible to crack this protection without CD ;-)
Moreover, it is the French version of Desperados:Wanted Dead Or Alive..
OS : Win98 SE.
This tutorial can be easily transposed on others debuggers (OllyDbg, for example) and other OS.
Note:I know that there is a very good tutorial on Laserlock v5 (Messiah) by GáDiX & SkUaTeR, but it is in Spanish and this tutorial is not just a simple translation :p
This tutorial is detailed in the following way:
A) Introduction and general information
B) Fixing the call Laserlock
C) Restoring the Import Table
D) Generalization and conclusion
E) Greetings
A) Introduction and general information :
Game Overview At the time it was released in 2001, Desperados: Wanted Dead or Alive was a huge deal. This is a strategy game that shows, you can have a great deal of action and cinematic flair with a strategy game. I am a huge fan of this series and pretty much anything that is set in the Old West. Desperados: Wanted Dead Or Alive. Strategy Guide/Walkthrough/FAQ. What is CelebrityGamerZ? While playing the game, press Left Shift + F11, then. 4) Go to Steam folder of Desperados C: Program Files (x86) Steam steamapps common Desperados Wanted Dead or Alive 5) Paste the three files into this folder you just opened. 6) Open the folder DXWNS v2.03.44. 7) Run dxwnd.exe as Administrator. 8) Right click on Desperados and hit Modify. MegaGames - founded in 1998, is a comprehensive hardcore gaming resource covering PC, Xbox One, PS4, Wii U, Mobile Games, News, Trainers, Mods, Videos, Fixes, Patches. Game Overview At the time it was released in 2001, Desperados: Wanted Dead or Alive was a huge deal. This is a strategy game that shows, you can have a great deal of action and cinematic flair with a strategy game. I am a huge fan of this series and pretty much anything that is set in the Old West.
Diablo II Character Skills Diablo II Character SkillsWell, I did say I would list the character skills in a separatetable, and I guess I've put it off long enough. So here it is!There are two numbers shown for each character skill. One isthe offset into thesection of the. The other is the skill ID used in some ofthe (i.e., '+2 to Bash (Barbarian Only)', 'level 3 FireBolt (33/33 Charges)', etc.), and in the. The common skill ID's are only used in button actions. Energy- None.
Laserlock is a commercial protection created by MLS LaserLock Inc.
It is characterized by a Laserlok folder on CD's root.
It contains a file laserlok.in, also hidden..
Protection is based on file(s), protected against copy (only in a conventional way).
So, protection has just to check presence of this file, to determine whether it is disc copy or not.
Different types of protections :
Checks of files integrity, such as the executable and the protection dll (checksums).
Partial ciphering of gamedll.dll text section (executable file is not packed !).
Redirection of game.exe APIs (call API replaced by call Laserlock).
No anti-debugging.
The different steps of this protection :
1. Loading of game.dll (ciphered by parts)
2. Redirection of APIs towards gamedll.dll to check game.exe and gamedll.dll integrity
If Laserlock (gamedll.dll) detects a change, returned API address is bad
3. Always via gamedll.dll (and thus by redirection of APIs) appears the logo :
4. Then the protection itself starts (it reads CD's physical structure, set up by protection), always via the dll of Laserlock.
If CD authentification failed, the following box appears :
5. APIs are redirected progressively and at each time, Laserlockmakes checksum(s) on gamedll.dll and especially on the routine, which computes and returns the good address of redirected API..
6. Up to a certain time, Laserlock replaces at runtime, call Laserlock into call APIs (as it was, before protection implementation), to increase execution speed ..
B) Fixing the call Laserlock :
If we take a look at the PE, by using a PE Editor like Procdump, we will not notice anything strange.
There is no problem to disassemble game.exe with W32Dasm.
We have all String References..
File is not packed.
But there is no information about imports..
A look at OEP give us this :
We can already see, that all API call are replaced bycall dword ptr [0067A2A0].
This is an API redirection.
(They will be named 'call Laserlock').
Thus, we launch SoftIce to see what there is inside..
We arrive in gamedll.dll..
So, protection uses a dll for the APIs redirection.
After the jmp [10017A68], and tracing some nop, we finally arrive at the 'Laserlock' code , in charge of API address computation, in order to execute it..
Always with example of the call dword ptr [0067A2A0] in 006201E4, let us trace this routine in step over (F10). Once arrived in 100025B1, we execute the ret and go in GetVersion API (Kernel) located at address BFF92F1B.. (addresses, which vary, depending on the OS version).
A F12 brings us back, after our call Laserlock of 006201E4.
Let us seek whether this address is not ingame.exe IAT, by a s 0 l FFFFFFFF 1B, 2F, F9, BF command.
Occurrence is found at 00652198 (.rdata section).
We must thus replace call Laserlock by call API..
Here, we have just to replace FF15A0A26700 by FF1598216500.
e 006201E6 98,21,65,00.
One call fixed ;).
We have just to automate what we have done manually, by a small routine (a 'call-fixer').
But before, we have to understand the JZ 100025B2 in 100025A0 of previous routine.
For this, let us put a bpx in 100025B2 (bp in Ollydbg), as the jump is executed so little times..
We start again (F5), disc checking…
And a crash…
We are located at a strange address (ABFABFF7) after call Laserlock execution (the one on 62725E) instead of a bpx break. Thus, Laserlock should not like modifications ; it makes us jump somewhere but not on the API, as it should be..
So, we will test a bpm 100025B2 X (hardware breakpoint).
We break and if we take a look at the stack, we find 0062B44E as address.
We can start again and put a bpm atthis address.
Before executing the call Laserlock in 0062B44E, esp=0099FD68
Inside this call (step into = F8), esp=0099FD64
At the ret of address 100025C0, esp=0099FD64
After executing it, we arrive in the API with esp=0099FD68
The ret of the API brings us in 0062B28A and not in 0062B454 as it should be if it was a call API..
So, call Laserlock in 0062B44E corresponds thus to a jmp API and not to a call API, which explains the conditional jump in Laserlock routine…
Now, we can write our 'Call-fixer' :)
What our routine does :To start, it patches gamedll.dll in 10002596 by a jmp EDI to redirect to our Call-fixer, once the call Laserlock is emulated..
Then we retrieve our Call-fixer address, loaded in Adump (especially the routine here1) to store it in edi.
Search_loop seeks all call Laserlock occurences in the game.exe code (.text section).
Once a call Laserlock is located, we emulate it to make believe that the game is executed normally (in order to retrieve the API by the address pushed on stack)..
(occurences are stored in edx).
We jump at the beginning of Laserlock routine by a jmpdword ptr [67A2A0].
The jmp edi in 10002596 enables us to retrieve the API address.
It jumps at here1. The API address is stored by Laserlock in ebp+08h.
We can now use it..
Then we determine whether the call Laserlock corresponds toa call API or to a jmp API.
To do this, we simply rip the corresponding instruction of Laserlock routine, e.g. the cmp byte ptr [10017A18], 01.
If it is a jmp API, we replace opcode FF15 by FF25 (corresponding to a jmp [API]).
Then, we give good value to eax to go back to our routine after the ret of Laserlock routine.
For a call API, we'll have to go back to here2.
For a jmp API, we'll have to go back to here2+1, at the popad (and thus to avoid the pop eax).
Then we jump in _ RoutinePatch+03 to let the program continue.
At the 1st ret, we directly go to here2.
The try_again allows the search for other occurrences, until we arrive at the end of the .text section.
Call-fixer (desperados.asm):
Desperados Wanted Dead Or Alive Crack
title call_fixer.386
.model small, stdcall
option casemap :none
.code
_TextOffset equ 00401000h
_TextSize equ 00251000h
_RoutinePatch equ 10002596h
_RoutineCompare equ 10017A18h
start:
pushad
mov esi,_RoutinePatch
mov word ptr [esi],0E7FFh
call @1
@1:
pop edi
add edi, offset here1-offset @1
mov edx, _TextOffset
mov ecx, _TextSize
search_loop:
cmp word ptr [edx], 15FFh
jne try_again
cmp dword ptr [edx+2], 0067A2A0h
jne try_again
lea eax, [edx+6]
pushad
push eax
;jmp dword ptr [67A2A0]
db 0FFh,25h,0A0h,0A2h,67h,0
here1:
mov edx, dword ptr [ebp+08h]
mov dword ptr [edx-4], eax
mov eax, edi
mov ebx, _RoutineCompare
cmp byte ptr [ebx], 01
jne @2
mov byte ptr [edx-5], 25h
inc eax
@2: add eax, offset here2-offset here1
mov esi, _RoutinePatch+03
jmp esi
here2:
pop eax
popad
try_again:
inc edx
dec ecx
jne search_loop
popad
int 03
end start
By typing r in adump, we obtain the address where we can load our routine..
We assemble and load this routine in memory bythe l command of adump.
Note : Adump was a binary, which allocated some memory in order to load some routines (or anything else), on Softice.
With OllyDbg, you can copy this routine just after PE. It is also possible to allocate some memory to do this on OllyDbg (Alt+M to see the Memory map, then a right click > Allocate Memory).
We break thus on the OEP of game.exe and modify eip to execute our routine.
We cannot end our routine by a int 03 and stop it by the 'i3here on' command, because of the int 03 interferences with Nomouse.com execution.
So, we put an infinite loop. More simply, we can put a bpx in Adump addresses..
Once the routine is finished, we go to OEP, by a r eip OEP.
We launch and it lamentably crashes..
Oh yeah..
We have modified gamedll.dll and Laserlock don't seem to appreciate.
It has not returned good values..
A bpr 10002596 10002598 R (memory breakpoint) brings us to thisroutine :
[ebp-08] corresponds to the counter (location in the block to check).
[ebp+0C] stores size of block.
[ebp+08] stores beginning of block.
[ebp-04] stores checksum's result..
The comparison in 1000A2FA determines whether check of the block is finished (counter = size of the block ?).
The instruction in 1000A331 makes possible to read the block byte by byte. Then eax (checksum result), to which a AND EAX, 0000FFFF is previously applied, is added to dl to be stored in [ebp-04]. Counter is incremented and so on..
This routine is executed x time (x being enough big to discourage us to patch)…
Moreover, this routine does not check exactly the same part of code of gamedll.dll at each call.
Thus it is necessary to use another technique more subtle than a patch on the Laserlock routine…
As GáDiX (Thanks to him) suggested it, it is possible to circumvent the difficulty with a bpm and a small macro:
BPM 10002596 X do 'r eip here1;g;'
with the good value of here1, e.g. its address in Adump.
With Ollydbg, it's easier to use a script in that case.
We try again with the same routine, but without the patch of Laserlock code (by a jmp edi) and by typing the previous macro.
As the routine is finished, we return to OEP, by a r eip OEP.
We launch and boom : a crash again, always with badlyfixed calls …
We modified nothing in Laserlock routine !!!
If we did not have modified anything in gamedll.dll, we modified game.exe progressively.
In fact, a routine in gamedll.dll also checks if something was modified in game.exe code :
It is the checksum done on the .text section, with block starting from 401000, with a size of 25009.
The routine is almost identical to the previous one except for one thing. The AND EAX, 0000FFFF is not executed on the checksum result before the addition byte by byte…
But this time, we have more chance :)
This is executed only four times (when the logo appears).
Thus, we just have to wait the 4th check to execute our 'call-fixer'.
We can visually locate the checks end, by the logo disappearance.. (when we are in 627264, checks are finished and we can redirect to our routine).
We start again a last time and this time, it works.
All call were correctly fixed :)
We can make a dump of .text section by /DUMP 401000 251000 text_dump.dat command.
Then, we have just to replace game.exe file code by the dump.
We can also include in our Call-fixer, a routine which returns good values to the routine in charge of gamedll.dll integrity checks.
In this case, we don't need use of a macro. We always have to wait for the fourth integrity check on executable.
title call_fixer
.386
.model small, stdcall
option casemap :none
.code
_TextOffset equ 00401000h
_TextSize equ 00251000h
_RoutinePatch equ 10002596h
_RoutineCompare equ 10017A18h
_gamedll_check equ 1000A331h
start:
Desperados Wanted Dead Or Alive Crack Download
pushadmov esi,_RoutinePatch
mov word ptr [esi],0E7FFh
call @1
@1:
pop edi
mov esi, _gamedll_check
mov byte ptr [esi], 68h
mov byte ptr [esi+05], 0C3h
mov dword ptr [esi+01], edi
add dword ptr [esi+01], offset here3-offset @1
add edi, offset here1-offset @1
mov edx, _TextOffset
mov ecx, _TextSize
search_loop:
cmp word ptr [edx], 15FFh
jne try_again
cmp dword ptr [edx+2], 0067A2A0h
jne try_again
lea eax, [edx+6]
pushad
push eax
;jmp dword ptr [67A2A0]
db 0FFh,25h,0A0h,0A2h,67h,0
here1:
mov edx, dword ptr [ebp+08h]
mov dword ptr [edx-4], eax
mov eax, edi
mov ebx, _RoutineCompare
cmp byte ptr [ebx], 01
jne @2
mov byte ptr [edx-5], 25h
inc eax
@2: add eax, offset here2-offset here1
mov esi, _RoutinePatch+03
jmp esi
here2:
pop eax
popad
try_again:
inc edx
dec ecx
jne search_loop
popad
; jmp eip
db 0EBh,0FEh
here3:
push ebx
lea ebx, dword ptr [ecx+eax]
cmp ebx, _RoutinePatch+01
ja @a_
cmp ebx, _RoutinePatch
jb @b_
sub ebx, _RoutinePatch
add ebx, edi
add ebx, offset here4-offset here1+1
mov dl, byte ptr [ebx]
jmp @c_
@a_:
cmp ebx, _gamedll_check+05
ja @b_
cmp ebx, _gamedll_check
jb @b_
sub ebx, _gamedll_check
add ebx, edi
add ebx, offset here4-offset here1+3
mov dl, byte ptr [ebx]
jmp @c_
@b_:
mov dl, byte ptr [ecx+eax]
@c_:
pop ebx
mov eax, dword ptr [ebp-04]
push _gamedll_check+06
here4:
ret
db 3Eh,8Bh
db 8Ah,14h,08h,8Bh,45h,0FCh
end start
Lastly, in order to circumvent checksums on Laserlock routines, it is possible to incorporate these in your Call-fixer
(see the tutorial of GáDiX & SkUaTeR [Karpoff Spanish Tutor 1999-2002]).
And to circumvent those on the .text section of game.exe, we can create a table with 3 entries, one indicating address to patch
in .text, another by what we have to patch (addresses corresponding in the IAT) and the last, which indicates if it is an API call or an API jmp…
This table can then be used later and independently from gamedll.dll routines execution..
C) Restauring Import Table :
Now we will remove dependency of game.exe toward gamedll.dll.
There are two possibilities, but here's a brief remind about Import Table structure..
Ravenfield mods mac. Image Import Descriptor ou Import Table (read 'peering inside the PE 'from Matt Pietrek!) :
An entry (a DLL and all its functions) consists of 5 Dwords in the Image Import Descriptor .
Dword 1 - Characteristics (hint name array)
This dword is a pointer towards the first elementof a pointers table.
Each pointer of this table points towards the hint name, followedby the name of a function.
Dword 2 - TimeDateStamp
Dword 3 - ForwarderChain
Dword 4 - DLL’s name
This dword is a pointer towards the name of the DLL (null terminated ASCII string)
Dword 5 - Import Address Counts
This dword is a pointer towards the first element of anadresses table.
This adresses table functions in parallel with the one, of the pointers towards the hint names (names of the functions).
extracted from Import Function tutorial.doc / Import-Function in section RDATA.doc by El.CaRaCoL.
Thank you to him ;-)
First possibility :
We remove this dll from the Import Table (the one created by Laserlock)
For that, we seek occurrence of gamedll.dll in the executable file.
We find it at 0027A2DE. (library name)
As the VO correspond to the RO (no shift on sections), we have just to seek DEA22700, to find the corresponding pointer in the (IT) Import Table..
It is just below..
Thus, IT created by Laserlock goes from 0027A2F8 to 0027A3FC (size 0x104).
When we open the executable file with LordPE (EP Editor) and look at Directories, we have 0027A2F8 (RVA) and 00000118 (Size) for the Import Table. We have a size of 00000118, because we include 10 null words, indicating the end of the Import Table.
To remove this .dll from IT, we have just to modify the beginning of this table, by making it start at 0027A30C (e.g. with KERNEL32.dll).
In LordPE, we put 0027A30C as RVA and 00000104 as Size, for the Import Table.
Here's the Import Table generated by Laserlock :
Second possiblity:
We can find the original Import Table to replace the one created by Laserlock, and then modify its address in the directories. It is located in 00278CB8 with a size of 00000104. The IT created by Laserlock is in fact just a copy of this one, the difference being addition of gamedll.dll in the table !!! So, we make modifications in LordPE.
Now, we can remove this .dll, it is useless :)
And the game launches perfectly…
Rem : it remains a 'CD-check'.
But there is another story ;)
In any case, it doesn't prevent us from cracking Laserlock.
Launch the game without inserting CD.
There is a pretty box, which appears and requires insertion ofdisc :(
We kill with the Burn Process of LordPE or the Kill Task of Procdump, much more effective than this shit of Ctrl+Alt+Delete of Windows…
First of all, we have to be sure that all game filesare copied on the hard disk, even if you have choosen themaximum installation. (No need to spend an hour for this :p).
When we compare C:Program FilesInfogramesDesperadosGameData with F:GAMEData, we can remark that the Cinematics folder 'was deliberately forgotten'.
We will copy it where it should be :)
This log of API Spy confirms…
005B5783:CreateFileA(LPSTR:01DE69A1:'DataCinematicsinfogrames.bik',DWORD:80000000,DWORD:00000001,LPDATA:00000000,DWORD:00000003,DWORD:00000080,HANDLE:00000000)
005B5789:CreateFileA = FFFFFFFF (GAME.EXE)
005A0601:MessageBoxA(HWND:00000000,LPSTR:01DE68F1:'Please insert the CD',LPSTR:00000000,DWORD:00000015)
We launch the game and no more problem. It is thus not a 'CD-check' (to be strictly exact).
A real CD-check requires disc, when all datais present on hard disk..
D) Conclusion:
In fact, there is a big fault in Laserlock..
First of all, the routine located in 10001DAD, called by 1000258D (Gamedll.dll), is not only used to compute redirected APIs adresses.
It displays the logo, checks disc, computes the various checksums and other things..
The 1st call Laserlock displays the logo.
The 2nd call Laserlock checks authenticity of the inserted disc.
If original CD is not inserted, a box appears andexecution of game.exe stops.
If original CD is inserted, the logo disappears and execution of game.exe continues (and thus the game launches).
The fault is due to the fact that, from a certain time, gamedll.dll patches itself : call Laserlock of game.exe are transformed into callAPI (as it should be and it was before application of Laserlock on this executable..).
It makes the same thing as our call-fixer..
Now put a Breakpoint on memory range (bpr) on the code (.text section) to detect any attempt to write.
We get this instruction : 100024D5 mov dword ptr [ecx], eax.
The example on which I got :
ecx = 004563D1 (address to patch)
eax = 006520D4 (address in the IAT where the concerned API is)
The call Laserlock was then transformed into call GetLocalTime.
Rem: SecuROM v2 also used this technique (cf FIFA99).
If we look at the listing of disassembled gamedll.dll inW32Dasm, we see at this same address :
No doubt that it is ciphered !!!
In fact, only the .text section of gamedll.dll is ciphered and it is in parts (significant parts).
In order to study it, we can dump the .text section and paste it in the DLL.
There will be then a comprehensible listing :)
First, let's study PE of this .dll using LordPE.
The .text section goes from the offset 400(RO) to 400(RO)+FC00(RS)=10000(RO) in the file.
It goes from 10000000(Image Base)+1000(VO)=10001000 to 10011000,in memory.
To dump the section, let's launch the game.
Once in the menu, let's minimize it.
Always with LordPE, let's choose game.exe in processes, right click, Dump area…
In Dump Information, we put 10001000 as Address and00010000 as Size, then we click on Dump. Our .text section is now dumped.
We have just to paste it in the .dll from offset 400.
Rem: There is a few junk code, but it is not hard.
The .dll obtained is not functional of course, since it will try to decipher code already deciphered, unless the many checksums prevent it …
Now we have this : it is definitely better ;)
Rem: this deciphered gamedll.dll (included in this tutorial) contains lots of information :)
There is already much more String References.
The version of protection is now known : 'v5.00.06 Compile:06/09/2000', this protection was made by a certain 'Petros Skalkos **' (a Greek) and there is various interesting information like 'LASERLOKLASERLOK.IN', '_ * NTCDFound *', etc…
There is even a copyright for this anti-copy protection :o
'* LASERLOK * Copyright (c) 1992-1996'..
But, what is very interesting, it is what we can find above :
And more precisely, the comparison in 1000248A and the conditional jump in 1000248D, which processes the call Laserlock patch.
In fact, a counter determines number of times, that Laserlock routine was called by the call Laserlock.
When it was called a certain number of times, here 0x32 e.g. 50 (into decimal system), Laserlock estimates that after all its checks, it can patch call Laserlock, this for a saving of time andthus better performances.
In anyway, a cracker can not arrive here after so many checks ;)
Checksums on the Laserlock routine are always executed …
You see certainly where I want to go now :)
By putting 0x32 in 100155F0 at game.exe launch, you will skip the logo display, 'Laserlocked' CD checks (which are excessively long), the various integrity checks, etc…
And Laserlock will fix us all the call Laserlock at our place.
Rem: Putting 0x33 in 100155F0 makes crash the program…
We can thus modify our first routine as follows :
.386
.model small, stdcall
option casemap :none
.code
_TextOffset equ 00401000h
_TextSize equ 00251000h
_RoutineCompare equ 10017A18h
start:
pushad
call @1
@1:
pop edi
add edi, offset here1-offset @1
mov edx, _TextOffset
mov ecx, _TextSize
search_loop:
cmp word ptr [edx], 15FFh
jne try_again
cmp dword ptr [edx+2], 0067A2A0h
jne try_again
lea eax, [edx+6]
pushad
push eax
;jmp dword ptr [67A2A0]
db 0FFh,25h,0A0h,0A2h,67h,0
here1:
mov eax, edi
mov ebx, _RoutineCompare
cmp byte ptr [ebx], 01
jne @2
inc eax
@2: add eax, offset here2-offset here1
mov esi, _RoutinePatch+03
jmp esi
here2:
pop eax
popad
try_again:
inc edx
dec ecx
jne search_loop
popad
; jmp eip
db 0EBh,0FEh
end start
We have to use the macro, because of the checksums on the Laserlock routine.
There are no more checksums on the game.exe .text section :)
We break thus on game.exe OEP, we trace untilthe 1st call Laserlock (in 006201E4), corresponding to Call GetVersion.Before executing it, we put 0x32 in 100155F0.
After this step over (F10), we can redirect to our routine, without forgetting the macro use :
BPM 10002596 X do 'R eip here1;g;'
Rem : First, we execute a call Laserlock, in order to initialize some values…
Moreover, this first call is not patched into call GetVersion…

Another fault (but this time, at the hardware level) ???
It relates to the CD physical protection.
Not only, we can crack the game without CD, but even without being a cracker, it would be possible to break the protection.
It could be done by opening the hidden file named LASERLOK.IN with a hexadecimal editor and saving it (even if editor indicates onlya partial reading of the file).
Then we would copy the CD content except for the LASERLOK.IN ('copy protected') and we would take instead of it, the file obtained previously, in order to circumvent protection…
I tested this easy way with this game : it does not work. Perhaps, does it work only with older versions of this protection?
Rem: There is all the same a partial reading of file LASERLOK.IN with a hexadecimal editor, since we recovers file contents up to address 3FD000, while size is 1388000 (the rest being occupied by zero)…
(file LASERLOK.IN of desperados game, obtained by the use of Alcohol120% is included).
Generalization :
We will see now that it is easy to imagine a generic unpacker, just by looking at differences with another game, havingsame protection.
We'll take the example of Worms : World Party (thank you NaG-SCRiM).
Moreover, it is the same version of protection! (I thoughtbesides that this game had a quite higher version of Laserlock, e.g. with SPEEnc…).
In fact, 'differences' are rather visual that another thing, lol…
Laserlok folder on disc rootcontains two other files with Laserlok.in :
The logo also changes (but it is less original..) :
Lastly, the dll of protection has the soft name of wwpdll32.dll ;-)
More seriously, the addresses in this .dll are exactly the same ones (the .dll made besides the same size as that of Desperados)…
It is not very clever..
Locating the call Laserlock seems to be harder, here, since on OEP, we find call MSVCRT (no redirection of these APIs) :
To locate them, we have to look after the end of imported functions asciis :
We have just to seek FF1570C36800 hexadecimal chain, in the .text section to find some..
To find the 1st call Laserlock executed (the 1st diverted API), we have just to place a bpx somewhere in the executable file, hang on the redirection crash and look at the pushed address on stack :-)
Here, it is at 004B52A8 address :
Addresses are exactly the same (compared to the Desperados .dll) :
It is also the case of the counter (notice the position which it occupiescompared to the string 'Please insert the original Cd-rom indrive') : thus it can be used as a 'marker' to make a generic unpacker..
It is a little bit harder to determine the originalIT, since sections are shifted..
IT created by Laserlock starts in 1BE3C8 in thewwp.exe file (Raw Offset), but starts in 28C3C8 in memory (Virtual Offset) with a size of 12C.
In memory, it is obviously necessary to take care of ImageBase..
Original IT (diverted) starts in 1BCB00 in the file(Raw Offset), in memory it will thus start in 28c3c8-1be3c8+1bcb00, which gives us 28AB00 (Virtual Offset) to put in Directories with a size of 118..
Here, you have enough information to make your own unpacker ;-)
Moreover, [NtSC] / UNPACKiNG GODS did it (an excellent one).
Finally, this protection is not hard..
There will be a second tutorial about Laserlock (the packed version with SPEEnc, from 2003 to now, which is much more interesting..)
Removing WWP CD-check :
It doesn't concern directly Laserlock.. but, as we begun the crack, we could finish the job :)
I'm too lazy to insert a CD/DVD to launch a game..
1st observation :
The game take 36,7 Mo on hard disk, which is ridiculous in comparison with the size of WWP CD (643 Mo).
2nd observation :
The routine, which checks disc insertion is not very hard to find.
By debugging or by disassembling wwp.exe and seeking imports like GetDriveTypeA/GetVolumeInformationA, we findthis :
Let us analyse this routine :
- API GetLogicalDrives gives us drives we own.
- Among those, GetDriveTypeA determines which ones are CD/DVD drives.
Instead of using the famous cmp eax, 00000005, it is done indirectly, since the routine first eliminates Remote Drive (Network)
by a cmp dword ptr [ebp-30], 00000004, then hard disks, and finally 'RAM drives'..
So, it remains only CD/DVD drives.
- When a CD drive is detected, API GetVolumeInformationA determines the media volume (if there is) inserted in this CD drive..
- Finally the function strcmp compares the character string of the volume previously recovered with 'WWP'.
Here's a log of APISpy :
Created by APIS32 v. 2.5
0046E2FA:GetLogicalDrives()
0046E300:GetLogicalDrives = 3D (WWP.EXE)
0046E340:GetDriveTypeA(LPSTR:00B9FD20:'C:')
0046E346:GetDriveTypeA = 3 (WWP.EXE)
0046E340:GetDriveTypeA(LPSTR:00B9FD20:'D:')
0046E346:GetDriveTypeA = 5 (WWP.EXE)
0046E379:GetVolumeInformationA(LPSTR:00B9FD20:'D:',LPSTR:00B9FD28:' ',DWORD:00000010,LPDATA:00000000,LPDATA:00B9FD38,LPDATA:00B9FD40,LPSTR:00000000,DWORD:00000000)
0046E37F:GetVolumeInformationA = 0 (WWP.EXE)
0046E340:GetDriveTypeA(LPSTR:00B9FD20:'E:')
0046E346:GetDriveTypeA = 5 (WWP.EXE)
0046E379:GetVolumeInformationA(LPSTR:00B9FD20:'E:',LPSTR:00B9FD28:' ',DWORD:00000010,LPDATA:00000000,LPDATA:00B9FD38,LPDATA:00B9FD40,LPSTR:00000000,DWORD:00000000)
0046E37F:GetVolumeInformationA = 0 (WWP.EXE)
0046E340:GetDriveTypeA(LPSTR:00B9FD20:'F:')
0046E346:GetDriveTypeA = 5 (WWP.EXE)
0046E379:GetVolumeInformationA(LPSTR:00B9FD20:'F:',LPSTR:00B9FD28:' ',DWORD:00000010,LPDATA:00000000,LPDATA:00B9FD38,LPDATA:00B9FD40,LPSTR:00000000,DWORD:00000000)
0046E37F:GetVolumeInformationA = 0 (WWP.EXE)
..
We could think that this CD-check is cracked by nopping conditional jumps in 0046E381 and 0046E3A7 (as it is mostly for CD-checks).. That's not the case..
There will be loading errors, followed by a nice crash..
Why?
If you insert the game CD in one of your CD drives, the routine retrieve its letter (the mov byte ptr [ebp-08], al in 0046E3AF, then the mov al, byte ptr [ebp-08] in 0046E3C2) to load files..
And if you force the jumps, the game will attempt to load some files from your 1st CD drive..
Some examples :
Here's my configuration in drives : a diskette drive A:, a hard disk C:, a DVD drive D: and a DVD burner E:.
By forcing the jumps, the game will load files from D: .
To preserve the CD structure and to make easy, I initially copied the Data folder from CD to the root of my hard disk (C:). So, we have just to correct the al value so that it coincides with the hard disk where Data folder has been copied. Thus, I transformed the add eax, 00000041 into add eax, 00000040 in 0046E3AC (with the two previous jumps nopped) and there is no more problem :)
I know that it is not subtle and generic but this manipulation is fast and effective.
Of course, it is not the only way to crack this CD-check..
Appendix :
____________________________________________________________________________________________
GetLogicalDrives(A)
____________________________________________________________________________________________
The GetLogicalDrives function returns a bitmask representing the currently available disk drives.
DWORD GetLogicalDrives(VOID);
Return Value
If the function succeeds, the return value is a bitmask representing the currently available disk drives. Bit position 0 (the least-significant bit) is drive A, bit position 1 is drive B, bit position 2 is drive C, and so on.
If the function fails, the return value is zero.
____________________________________________________________________________________________
GetDriveType(A)
____________________________________________________________________________________________
The GetDriveType function determines whether a disk drive is a removable, fixed, CD-ROM, RAM disk, or network drive.
UINT GetDriveType(LPCTSTR lpRootPathName);
lpRootPathName // adresse racine (chemin d'accès)
Pointe vers une chaîne de carctères (terminée par zéro), qui spécifie le répertoire racine du disque pour obtenir des informations dessus. Si lpRootPathName est nul, la fonction utilise la racine du répertoire actuel.
Code de retour : La valeur de retour spécifie le type de 'lecteur/disque'. Elle peut avoir les valeurs suivantes :
Value Meaning
0 The drive type cannot be determined.
1 The root directory does not exist.
2 DRIVE_REMOVABLE The drive can be removed from the drive.
3 DRIVE_FIXED The disk cannot be removed from the drive.
4 DRIVE_REMOTE The drive is a remote (network) drive.
5 DRIVE_CDROM The drive is a CD-ROM drive.
6 DRIVE_RAMDISK The drive is a RAM disk.
E) Some greetings :
Greetz :
ACiD BuRN, ArthaXerXès, Black Check, cdkiller (ProtectionID), CyberBob Jr, ^DAEMON^, Dark-Angel, DecOde12, diablo2oo2, Duelist, El-Caracol, EliCZ, Elraizer, evlncrn8, Fravia+, +Frog's Print, KeopS, Gádix, GRim@, G-RoM, Iczelion, kilby, Laxity, Lorian, LutiN NoIR, MackT, MrOcean, NeuRaL NoiSE, Neutral AtomX, Ni2, Nody, [NtSC], +ORC, Pedro, Peex, PEiD (snaker, Qwerton, Jibz), Psyché, Pulsar, +Pumqara, Ricardo Narvaja, Skuater, +Spath, +splaj, Stone, TeeJi, The Owl, tHeRaiN, TaMaMBoLo, +Tsehp, Tola, woodmann, +Xoanon, [yAtes], yoda .. and all I forgot and who contribute actively to the scene by their tutorials, tools and others..
all the icedump team, ARTeam, CracksLatinos, DREAD, FRET, ShmeitCorp, UCF2000, UNPACKiNG GODS, TMG, all game groups..
All +HCU Students
All ppl of RCE Messageboard
these great sites :
http://207.218.156.34/krobar/index.html
http://arteam.accessroot.com/
http://tuts4you.com/
http://www.woodmann.net/forum/index.php
http://www.woodmann.net/yates/index.htm
http://www.exetools.com/forum/
Special Greetz :
Christal: Thank you for all thatyou did for the French scene and your also great implication. Mybest regards :)
R!SC: Thanks, Master, for your tuts about commercial CD-Rom protections, like Safedisc, SecuROM, VOB ProtectCD, etc.. :-)
All members of FFF ;-)
Final words :
I hope that you will have had pleasure to read this tutorial.
If you want to study this protection, I can upload these tutorial targets. So, mail me at :
dWx5c3NlMjAwOV9mckB5YWhvby5mcg
(base64 encoded)
Desperados: Wanted Dead Or Alive is my favorite game :-)
It is an excellent tactical game (a Commandos-like game), but much more better than its by its superb western ambience, its humour and the judicious sequence of the missions through a 'true' history. As for tactical dimension, it will give you trouble..
'If you like a game, Buy it !'
uLysse, on 14 / 01 / 2007
'There is a crack, a crack in everything.. That's how the light gets in.'
Copyright © uLysse_31