Main Menu
Home
Join
Members
Allies
Downloads
Net Lingo
Chat Page
Links
Contact
Age of Empires
Cheats
Strategies
Civilizations
Technologies
Screenshots
Units
Buildings
Other Info
How to Crack Age of Empires
Age of Kings
Cheats
Civilizations
Technologies
Units
Buildings
Formations
Site Search:


I'm back :P I hope you will like this tutorial since it's my first one for a game. This tutorial is not as usual, this time i'm gonna teach you how to crack a game - Age of Empires. This one is not as easy as my "old" tutorials and therefor I included quite a lot of code. I also put a lot of comments, to make it easier for you. (newbie cough cough) :) For all of you to understand this I will advice you to read it several times and understand all of it.

TOOLS:
SoftIce 3.24
HIEW 5.92

Please do not ask for instructions as to where to download these programs, please search for them yourselves.

This game has, as you probably already know, a cd-check when it's launched. This we don't like and we're therefore going to find a way around it.

Normally we would only use W32Dasm when cracking this kind of protection, but not in this case. Actually it's just as easy in SoftIce (at least I think so). Of course you could try using W32Dasm and if you decide to do this I will give you a small hint. When programming it Microsoft did not use a normal text-box, they used graphic. So now you know ;)

Ok..let's start. If you're a newbie go through this step by step.

1. Before using SoftICE you'll have to modify the WINICE.DAT file. Just delete the semi-colons before the EXP instructions, where USER32, GDI32, KERNEL32

are mentioned. Now SoftICE will load these export functions.

2. Launch SoftICE and open EMPIRES.EXE
3. Load it. (Modules->load) and ignore irrelevant error messages.
4. Soft-ICE pops up. Set a breakpoint on the function GetDriveTypeA (returns eax=5 if CDROM,eax=3 if Fixed HDD) by typing : bpx getdrivetypea [ENTER]

The 'a' on the end of the function means, that we are talking about a 32-Bit application. Getdrivetype would work for a 16-Bit App.

5. Hit [CONTROL-D] to go back to the game. If SoftICE pops up again - ignore it. Just push [CONTROL-D] until you get to the main menu.
6. So now you are at the main menu - hit the 'Single Player' Button.
7. If you've done everything right - Soft-ICE pops up at the desired function. Hit [F11].
8. Now you're at the place, where GetDriveTypeA has been called from !. Look around a bit.([CONTROL-(],[CONTROL-(])
9. Here is what you should see :
:004D65F6
FF1554267000
Call [Kernel32!GetDriveTypeA] -> calls the function
:004D65FC
83F805
cmp eax, 00000005 -> If CDROM - drive resent
:004D65FF
7404
je 004D6605 -> jump to ...
:004D6601
33C0
xor eax, eax -> if not : eax=0 ..
:004D6603
EB53
jmp 004D6658 -> ... and return.
:004D6605
8D84241C010000
lea eax, dword ptr [esp+0000011C] -> Volume-check ...
:004D660C
6800010000
push 00000100
:004D6611
8D4C241C
lea ecx, dword ptr [esp+1C]
:004D6615
50
push eax
:004D6616
8D54241C
lea edx, dword ptr [esp+1C]
:004D661A
51
push ecx
:004D661B
8D44241C
lea eax, dword ptr [esp+1C]
:004D661F
52
push edx
:004D6620
8D4C242C
lea ecx, dword ptr [esp+2C]
:004D6624
50
push eax
:004D6625
6800010000
push 00000100
:004D662A
51
push ecx
:004D662B
57
push edi
:004D662C
FF1558267000
Call [Kernel32!GetVolumeInformationA] -> Volume-check
:004D6632
85C0
test eax, eax -> is a CD-ROM in the drive ?
:004D6634
B800000000
mov eax, 00000000 -> eax=0
:004D6639
741D
je 004D6658 -> no ! return with eax=0 !
:004D663B
8B460C
mov eax, dword ptr [esi+0C]
:004D663E
8D4C241C
lea ecx, dword ptr [esp+1C] -> ecx = CD-ROM label
:004D6642
05FD020000
add eax, 000002FD -> eax = Label (AOE)
:004D6647
50
push eax
:004D6648
51
push ecx
:004D6649
E802D60500
call 00533C50 -> very interesting call ...
:004D664E
83C408
add esp, 00000008
:004D6651
83F801
cmp eax, 00000001 -> if eax=1 ... set register flags
:004D6654
1BC0
sbb eax, eax -> eax=eax-(eax+c)
:004D6656
F7D8
neg eax -> 'invert' eax
:004D6658
5D
pop ebp
:004D6659
5F
pop edi
:004D665A
5E
pop esi
:004D665B
5B
pop ebx
:004D665C
81C40C020000
add esp, 0000020C
:004D6662
C20400
ret 0004 -> ... and return

You can step through the code (execute it line by line) by pressing [F10] and trace into a call (going into a function) by pressing [F8].You can view the 'contents' of a variable by typing d [variable] (e.g. d eax). You can also set variables, by typing r [variable]=[value] (e.g.r eax=1). You can also toggle register-flags, by typing r fl [register] (e.g.r fl z -> inverts result of a compare (cmp)).

As you can see, the program checks if you have a CD-ROM drive and returns the drive letter if so.
Then it retrieves various info about the inserted CD-ROM (if it is inserted). If an error occurs it sets eax=0 and returns.
All right. What now? Let's take a quick look into the mysterious call (only at the end of it) :

:00533C50
55
push ebp
:00533C51
8BEC
mov ebp, esp
:00533C53
57
push edi
:00533C54
56
push esi
:00533C55
53
push ebx
:00533C56
8B750C
mov esi, dword ptr [ebp+0C]
:00533C59
8B7D08
mov edi, dword ptr [ebp+08]
:00533C5C
8D05D08E5600
lea eax, dword ptr [00568ED0]
:00533C62
83780800
cmp dword ptr [eax+08], 00000000
:00533C66
753B
jne 00533CA3
:00533C68
B0FF
mov al, FF
:00533C6A
...
8BC0
mov eax, eax
:00533CC6
E845070000
call 00534410
:00533CCB
83C404
add esp, 00000004
:00533CCE
38C3
cmp bl, al
:00533CD0
74DA
je 00533CAC
:00533CD2
1BC0
sbb eax, eax
:00533CD4
83D8FF
sbb eax, FFFFFFFF
:00533CD7
5B
pop ebx
:00533CD8
5E
pop esi
:00533CD9
5F
pop edi
:00533CDA
C9
leave
:00533CDB
C3
ret

The above function is rather complicated. You wouldn't want to know what it does... ;-)
Anyway, if you go through it several times, changing some variables and flags, you'll arrive at the conclusion, that the value of eax (when the call returns) can be either 0, FFFFFFFF or 1.(If you inserted the wrong CD - it is 1 or FFFFFFFF).

We can assume at this point, that the value 0 means, that we have inserted the right CD ... let's try it out !
When you are debugging and you are at the end of the function (e.g. 533CDA) type: r eax=0 [ENTER] and press [CONTROL-D] in order to let it go on.It works, you've made it !

Well, if you're not so sure about this business (WHY did it work ???) go on reading ... if you are sure or just don't care - jump to the cracking section.

Okay, so you want to be a cracker...Lets assume, you haven't changed anything (and have inserted the wrong CD), then the call will return eax=1.Let's look again at the code after the call returns :

:004D664E
83C408
add
esp, 00000008
:004D6651
83F801
cmp
eax, 00000001 -> if eax=1 . set Z ;or C if eax=0
:004D6654
1BC0
sbb
eax, eax -> eax=1-1 => eax=0
:004D6656
F7D8
neg
eax -> 'invert' eax => eax=0
:004D6658
5D
pop
ebp
:004D6659
5F
pop
edi
:004D665A
5E
pop
esi
:004D665B
5B
pop
ebx
:004D665C
81C40C020000
add
esp, 0000020C
:004D6662
C20400
ret
0004 -> ... and return

So the whole function returns an eax=0 if the CD is wrong...Hmmm.... Usually, when looking at simple protections, you'll see that when an eax=0 means WRONG then an eax=1 will mean ALL RIGHT.
Let's see, what happens if the call returns with an eax=0 ....

:004D6651 83F801
cmp eax, 00000001
-> if eax=1 ... (set C=1)
:004D6654 1BC0
sbb eax, eax
-> eax=eax-(eax+c) => eax=0-1=FFFFFFFF
:004D6656 F7D8
neg eax
-> 'invert' eax => eax=1

Looks like this is another simple protection-scheme ... Now you have basically two ways to crack this game:

You can set eax=1 in the function or you can set eax=0 in the call. It is possible, that the game might make a check during the gameplay with this call but with another function.
Considering this, it would be best to insert a 'mov eax=0' instruction into the call, somewhere at the end (or beginning, followed by a 'return'). But this game won't make a check ! (You can try it out ...) So you can just as well insert a 'mov eax=1' instruction in the function, somewhere at the end (or beginning, followed by a 'return'). It is up to you. I've chosen the first possibility.

I'll try to explain how to do it:

1. The easiest way is to write down a long sequence of the hexadecimal-code, in order to locate this fragment in the exe-file.(e.g. 8D05D08E560083780800 -this is taken from 533C5C to 533C62) You could just as well read the local offset from SoftICE - it can be a bit confusing though.

  1. Launch hiew (HIEW EMPIRES.EXE), press [F4] and then [F2], in order to view the text in hex-mode.
  2. Search for the string, you've written down.([F7])
  3. Now switch to decode-mode ([F4],[F3]) - you're right there - shortly after the beginning of the call.
  4. Go to the 'mov esi,[ebp][0000C]' instruction (it will be overwritten, but that doesn't matter)
  5. Press [F3] followed by [TAB]
  6. Now you can type the command 'mov eax,0h' - you surely remember why, don't you. The hex-code of this command should look like : B800000000 Now it should jump to the end of the call - type ‚jmp xxxxxx' , where xxxx represents the end of the call.The adress will vary so you have to look for it yourself.In our listing, it is at 533CD7.Look at this code and look for it in hiew. Then you'll have the needed address...
  7. Press [ESC] to end assembly, [F9] to save it, quit HIEW and launch the game...
  8. It works !!!!

I hope I made myself a bit clear and that you understand just 80% of it.

This crack could without a doubt be done more elegantly, but I'll leave it up to you to find the easiest way.

All for now....