Checksums Part 2 or “How to crack The Settlers”
A tutorial by StingRay written for www.flashtro.com
At the end of my last tutorial about checksums I mentioned that you could try
your luck with “The Settlers” as that game uses checksums too. Well, I
thought it might be a good idea to write a tutorial about how to crack this
very game and that’s actually the reason why you are reading this now.
As I want to have somewhat interesting tutorials, I’ll try to crack
this game without actually starting it one time, i.e. only by looking
at the ReSourced code and using my instinct and maybe a bit of luck. 🙂
You might remember excellent crackers like Phil Douglas, it’s said he
cracked games without being able to run them. This is what I want to do in
this tutorial too. I will exactly describe all of my steps, that means, even
if I’ll do something that didn’t help to crack the game or was just plain
wrong, I’ll write it here! So even I don’t know yet how this tutorial will
look like at the end. 🙂 But enough of this preamble, let’s get to work!
To follow this tutorial, you’ll need the following things:
- The game (I have used CAPS/SPS 143 here)
- ReSource
- An assembler, I’ll use Asm-Pro here
- An Amiga or emulator like WinUAE
Let’s get things rolling. Looking at the first disk I couldn’t find a file
called “Settlers” or “TheSettlers” so the mainfile is probably on another
disk. And indeed, on disk 3 we can find a “The Settlers” file which is only
15 bytes so it’s probably just a tiny shellscript which starts the game.
We can also find a file called “TheSettlers” with a size of 192.700 bytes.
Now that looks very much like it would be the game file. Let’s just load
it into ReSource to check it. And indeed, it looks like 68k code to me.
Ok then, let’s try to find where the protection routine is located. I just
entered “please” in the “Search” requester (you can find the “Search” button
in the lower part of the screen) as most games that have a novella (i.e.
manual) protection ask you kindly to “please enter word xxx” or something
similar. So, the word “please” should be a good search string to find such
texts I think. So let’s enter this search string and press the “Forwards”
button. And lo and behold, at offset $388d ReSource found a text saying
“Please identify the symbols on”.
It looks promising because this
text is referenced directly which we can see because ReSource
already created a label for it. So let’s just continue our search
to see where this label is used. With a bit of luck we are already
in the protection routine then. ReSource finds the next occurrence
at offset $65cc. Let’s examine the code a bit deeper, could that be
the protection routine? Short answer, definitely not, it just looks like
a generic “Print Text” routine. We can easily see that by just scrolling
down a bit, at offset $660e another text is loaded into register a2
and the same routine that was called after a2 was loaded with the “please
identify the symbols on” text is executed. To me it looks like the routine
(lbC026B58) takes 3 parameters:
a2: ptr to text to print d0: x position d1: y position
That of course is all guess work and I could be totally wrong here. However,
we don’t have to care about this, we know this routine doesn’t have anything
to do with the protection so we can ignore it! Hmm, too bad, what now?
I have this habit to check the areas of code that could have anything to do
with protections a bit deeper. So I’ll do the same here too.
Let’s scroll down a bit to see if we can find anything of interest.
And indeed, at offset $68f4 there is a line of code that loads “PAGE.MSG”
into register a2, loads register d0/d1 like before but instead of calling
the routine at offset $26b58 now a routine at offset $6bf6 is called.
Could it be that the game prepares the texts for the manual protection here?
Maybe it gets a random number and then creates a text like “from PAGE number
25” where 25 would be the converted random value? Let’s look a bit further.
The next thing that catched my interest is the “cmp.w #3,d6” instruction at
offset $6a10. I can’t really explain why but I have a certain feeling this
is the “check the number of wrong answers” code. So I scroll up a bit and
see something that looks like a classic “copy graphics to screen” loop at
offset $69e8. Scrolling up a bit more I see that my feeling was wrong, d6
is used to calculate an offset in the destination bitmap. Now, I remember
the “symbols” part in the text I found before. Could it be that game
copies 3 symbols to the screen here? I scroll down again to check what
happens after this “copy graphics” loop. At offset $6a18 register a1 is
loaded with a pointer to something, then some calculations are performed
and 2 bytes from the area that a1 points to are moved into register d0
and the last instruction before the rts is a “cmp.w d0,d5” and a branch
to offset $6806 if the comparison fails, i.e. both registers contain
different values. I don’t know about you but I am pretty sure that this
is the actual “manual check”! I guess, if we would just remove the branch
after the compare, we could enter whatever we want at the protection check.
Why do I think that? Well, if we check where it branches to if the compare
failed, we’ll see it is right before the “prepare the page number” routine
and generally, it all looks like it’s the protection routine to me. It is
easier to see than to explain, if you look at the screenshot (or load the
game into ReSource yourself), you’ll see what I mean. Also, if we check
the data at $6a64 (remember the code at offset $6a18? a1 is loaded with
a ptr to data at offset $6a64 there), we’ll see nothing that looks like
useful data, it more or less looks to me like some crypted or otherwise
pre-processed data. Most probably the right answers are hidden there
and to avoid that they are visible when loading the exe into an hex
editor, they have been protected. That’s my guess at least. Anyway, so
far I think if we remove the bne.w lbC006806 instruction at offset $6a4a,
we could enter whatever we want at the protection routine.
Now let’s see if that routine is protected in any way. Let’s go back
to the start of the file and search for lbC006806. ReSource only finds
2 occurrences, one is the routine itself and the other one is the branch
at offset $6a4a. Ok, so obviously the game doesn’t directly access this
routine from anywhere else. Now, let’s check for eor instructions. Why
that you may ask. Well, if you’ve seen your fair share of checksum routines
you know that MANY of them use the eor instruction in the loop to calculate
the checksum. So, let’s just check for that instruction and see if we can
find something interesting. And indeed, ReSource finds something. The
first occurence is at offset $52e but that loop doesn’t look very interesting
so we’ll continue searching. Next one is found at offset $224e but it does’t
look interesting either, looks like normal game code to me, no loop, no
compare with a checksum etc. So to make it short, I’ll ignore that one too
and continue searching. Same for the one that is found at offset $225c as
it looks pretty similar to the one we just found. The next one at $67c2
looks a little bit more interesting but as there is no obvious check of a
checksum and stuff, I decide to ignore that one too. Same for the ones
at offset $67d0, $8c28, $8c7a, $8cc8, $a0f4, they all don’t catch my
interest either. However, the next one found at offset $ba80 does!
What is going on there? In the loop some value is calculated and then
at offset $ba8a there is a compare with a constant, somehow that looks
very very suspicious to me! Apparently the start of the routine is
at offset $ba66, there a0 points to offset $e338 and some lines below,
at offset $ba70, the value $7ba4 is subtracted from a0 so it points
to $e338-$7ba4=$6794. Let’s check the code at offset $6794! It looks
like that is the start of the protection routine! So something is very
very fishy! Let’s go back to offset $ba80 and save the code for the
checksum routine so we can try it out in our Assembler. I set offset
$BA6C as start and $ba8e as end. However, before I save the routine
using ReSource’s “Save Asm->Partial” function I first create the missing
label at offset $ba88 using the “Create single->Label – fwd ref”
function in the “LABELS” menu.
Once done I loaded that routine in AsmPro
and adapted it a bit, i.e. I removed the “sub.l #$7ba4,a0″ instruction
and replaced it with “lea data+32+$6794,a0″. The reason for that should be
clear, originally the routine calculated the offset to the start address,
as we already know that one, we don’t have to do that anymore. The “+32”
is, as mentioned in my last tutorial, to skip the hunk header. Now, after
executing this routine, d2 will have the value $7f60 and I can’t say
I’m surprised about that. 🙂
Now let’s see what happens when we remove the branch at offset $6A4A, my
bet is the checksum will be different and it would prove my theory that
this was the protection check. As I’m old and lazy I usually avoid
every extra work and so instead of writing one line of code (hard! :D)
to remove the branch, I just assemble the source again but before typing
‘j’ to execute it, I type ‘d data+32+$6a4a’ to disassemble the code
at that offset. Then I simply press ‘DEL’ to remove (i.e. nop out) the
code. Having done that I press ‘ESC’ to return to normal mode and execute
the code with ‘j’ as usual. d2 now has the value $b898 so that means
it’s checked if we have modified the code at offset $6a4a. Somehow that
doesn’t surprise me much either. 🙂
Now just for fun I continue searching to see if there are more checksum
routines. But as said, that’s just done for fun, I already know there
is at least one so I’ll have to code a loader for the game.
And as expected, there is another checksum routine at offset $c370.
This time it starts with a “lea START+ffffd480,a2” instruction.
What does that mean? It just means, a2 is loaded with a ptr to an
address that is outside the executable, $ffffd480 is a negative number
(-11136 in decimal) and we know that “START” is the beginning of
the executable, i.e. offset 0. Thus, a2 will point to the address
that is 0-11136 bytes in front of the exe. 2 lines below at offset
$c37a the value $9314 is added to a2, so the final offset is:
-11136+9314=$6794. That offset looks familiar, doesn’t it? 🙂
Let’s continue searching just for fun, I’m curious to see how many
more checksum routines there are in the game. I find 2 more at offsets
$cca0 and $25704. So there are at least 4 checksum routines in the
game but as I didn’t look very thoroughly (because there is no need to),
there are probably more! The checksum routines all contain slightly
different code btw, this is probably to avoid them being detected
by searching for a single opcode. However, in my opinion this was
a wasted effort as all of them use the “eor” instruction. You remember
the search term I’ve used? So even if the code is different in the
checksum routines, I could still find them by just looking for eor
instructions. I suppose the coder thought that if the bad guy who’s
attempting to crack the game found one checksum, he would just do
a simple opcode search to find more checksum routines. And that would
fail. Like f.e. in the first checksum routine we found, “eor.w d1,d2”
is used in the loop to calculate the checksum value. This instruction
has the opcode $B342. So one could think searching for all $B342 opcodes
would reveal all the checksum routines. That approach is bound to fail
however as the next checksum routine uses “eor.w d3,d1” which apparently
has a different opcode ($B741), another one uses “eor.w d2,d1 ($B541) and
the one after that uses “eor.w d4,d5” ($BB44). I think you get the point.
Ok, so now that we know the game doesn’t want us to mess with the protection
routine we have to find a way around that. What we have to do is clear:
- remove the protection check at offset $6a4a with 2 nops, another approach
would be to change the “cmp.w d0,d5” instruction at offset $6a48 to
“moveq #0,d5”, that way we ensure the branch below would never be taken.
And since that is just a 2 byte modification as opposed to the 4 byte nop
hack, I’ll use that. I like to avoid nops whenever I can, don’t really know
why though. 🙂 - after the protection routine is passed, we need to restore the original
code as quickly as possible so the checksum checks won’t fail
That doesn’t sound too complicated I think so let’s go. First we need
to know from where the protection routine is called. So let’s go
to offset $6794 as that is where the checksum routines start checking
the code. Who said those routines can’t be helpful? 🙂
To jump to a specified offset you can use the “Absolute->Specify offset”
function that you can find in ReSource’s “CURSOR” menu. As this is a
pretty useful function I recommend creating a hotkey for it. Anyway,
ReSource will open a requester where you can enter the offset you want
to jump to then. In this case we would simply enter “$6794″, notice
the “$” prefix which is used for hexadecimal offsets. After pressing
“OK” ReSource will jump to offset $6794. Now we have to find the real
start of the routine. This is at offset $6578. There is no general
approach how to do this, here it is simple as we see an “rts” instruction
at offset $6576. That means another routine ends there and a new one
starts at offset $6578. Now let’s enter “lbC006578” as search string
and see where the routine is called. Remember to go back to offset 0, i.e.
the beginning of the file before starting the search. ReSource return
offset $FF6, we see a “bsr lbC006794” there. Below that is a branch
to offset $392e so let’s see what happens there. To quickly jump
to a branch destination within ReSource you can use the
“Absolute->Forward reference” function in the “CURSOR” menu.
In my version of ReSource the hotkey for that function is “cursor right”
but as I did set up ReSource to suit my needs more than a decade ago,
I can’t remember if that’s a default setting or not. 😉
At offset $392e we see a jsr to another routine and that’s actually
totally great for us as it helps us to achieve our evil plan of
doing a proper crack for the game. Now, why is that? The code at
this offset is not pc relative, that means we can safely place
a patch at this position and don’t have to fear that a checksum
routine will detect that! In ReSource we see “jsr lbC026826”, this
means it is an absolute address. Thus the code here, once the
game has been loaded, will always look different as AmigaDOS
adds the offset to the current memory location at runtime, this is
known as “relocating”. This is not a totally correct explanation
but should give you an idea why the code can’t be checked by a
checksum routine.
Now that we know that, we can start coding a loader for the game.
This loader will have to do the following:
- load the game using LoadSeg
- remove the manual check at offset $6a48
- place a patch that will restore the original code in the protection
routine to please “Mr. Checksum” 🙂 at offset $392e - last not least, start the game 🙂
Ok, let’s code that then. The core of my patch looks like:
Patch move.l a0,-(a7) move.l 4(a7),a0 ; get return address move.w #$ba40,$6a48-$3934(a0) ; restore original code add.l #$26826-$3934,a0 ; excute original routine jsr (a0) move.l (a7)+,a0 rts
Now, that looks cute and tiny, doesn’t it? If you have followed
the tutorial carefully, you should not have any problems to understand
what I do here. The only thing you might wonder about is the
“move.l 4(a7),a0”, it actually is just to get the current return
address so I can use that as a base address then. As you may know,
before a subroutine is executed, the return address is pushed on the
stack. And because I save a0 on the stack, I have to add 4 bytes to
get the correct return address. This might sound complicated but
it is in fact pretty simple. If you have problems to understand it,
just experiment a little in Asm1/Pro and watch the registers. Call
a subroutine with a jsr instruction and look at the stack. You’ll
surely see how it works then.
Ok, now that I’ve coded the cute and tiny loader for the game, it’s time
to test it. Let’s quickly load the startup-sequence in Asm-Pro’s editor
and change it so it would execute our loader instead of the game.
Now, looking at it, we see the game is called with a parameter “-f”.
That means, I have to adapt my loader a bit, I’ll simply “pass through”
the commandline given to my loader to the game, thus “emulating” the
original behaviour. 🙂 This is very easily done, I only have to save
registers d0 (length of commandline) and a0 (ptr to commandline string)
and restore them just before calling the game. It’s as simple as it sounds,
not even 30 seconds of work. 🙂
After I have done that, I simply change the startup-sequence so it
contains a “loader -f” as the first command and simply comment out the original “run nil: nil: TheSettlers nil: nil: -f” line.
Now the time has come to actually test my work. Let’s boot the disk
and see what happens. 🙂 For some reason I’m pretty confident it
will work as expected, i.e. the protection is removed and we can
start the game. This might sound arrogant but it is not meant like
that. The reason why I’m confident is that I think I understood how
the core of the protection works and thus I’m sure I’ve disabled
it. But we’ll see in some minutes when the game has finished loading.
Well, seems my feeling was right. 🙂 The game did let me enter anything
at the protection check and I could start it.
Now there’s only one thing I need to test. It could be that the game
executes some of the checksum routines before the protection routine
is called. That would mean some of the checksum checks might fail
because we restore the code AFTER the protection routine has been run.
It’s unlikely but well, I want to be sure. 🙂 To easily check this,
I’ll just place an “illegal” instruction in every checksum routine
that I’ve found. If the game executes them, it will crash. So if
the game won’t crash before we see the protection screen, it means
our crack should be perfect. So I quickly adapt the loader and start
the game again. And it seems it’s my lucky day, I can still pass the
protection screen without a crash so none of the checksum routines
have been executed before. 🙂 You might like to know what I would have
done if the opposite would’ve happened, i.e. one of the checksum
routines would have been executed. Well, I would have done the same
I did to find a place for the “restore code” patch. That means, I would
have checked the protection routine (easy as I already know the start
and end of it) and would have tried to find a place where I could have
placed a “crack game” patch, i.e. instead of removing the protection
check before the game is started, I would crack it “on the fly” and
then execute the “clean up” patch afterwards. This could be an
exercise for you, dear reader of this tutorial, try to crack the game
using that approach.
So I guess that concludes my second tutorial. I hope you had fun reading
it and I could show you something new. Actually, my aim was to give away
some general tips about cracking a game as contrary to the self-proclaimed
world’s best coder/cracker/hd patcher called Codetapper I like to give
background information, not just “you can use tool xyz to do task zyx”.
That was the reason why I have
cracked the game the way I did, i.e. without checking it until all of
the work was done. I always admired crackers like Phil Douglas and back
then I thought that it must be pretty damn hard to crack a game without
having a possibility to test it. I hope I could show that it is not as
hard as it may sound, as long as you know what you are doing, everything
is possible! 🙂 This game had a pretty nice protection but I actually
didn’t find it very hard to crack, the opposite rather, but only because
I knew about the “where/how/why”. And with these wise words you have
reached the end of another tutorial, see you in the next one.
P.S.: As usual I have included the full source code for the loader.
StingRay, still in August 2007 (yes, even I am amazed ;D)
I cracked The Settlers when it was released and I didn’t use the method above. My Method was a little more complex as it requires some knowledge of the executable file structure and relocation tables, but it doesn’t suffer with the potential issue you could have faced. (ie. checksum routines being executed before the manual check, or other hidden checksum rotuines which don’t use an eor instruction). What I did was to modify the protection code so that it instead of checking the entry code, it jumped to an extra hunk that I added to the executable. This hunk would… Read more »
Great tutorial Stingray!
Mr.Spiv/DLFRSILVER : Thanks. 🙂 TCB: Nice story with Seek and Destroy AGA. 🙂 He was a truely excellent cracker, one of the best, at least in my opinion. And about cracking PC games on an Amiga only, well, it is possible as long as you have at least a disassembler for x86 code that runs on your Amiga. However, I don’t think a plain A500+ is suitable for this task. 🙂 Do you know what Phil Douglas is doing these days? Gonthar: Actually I guess most good crackers can do that, imho it’s an essential skill if you want to… Read more »
Our cracker could "read" code the way I can read a sentence. I am no coder/cracker myself, but he was able to crack protections in no time! Amazing guy. Never had a nickname, like we all had, but he was one of the most talented guys around in the scene at the end of the 80’s.
About Phil D., I’ve heard the same stories and I believe them to be true.
I can confirm that "myth" of Phil cracking without running the game even once. I believe it was "Seek & Destroy AGA" which he cracked on his Amiga 500+ ; for obvious reasons he could not test it 🙂 – he sent us a copy to do a trainer.
This is the same time where he _supposedly_ cracked Pc games on his amiga too ; I never heard him mention it personally so this might be one of these urban legends.
Thanks again Stingray for the tut!
Just forgot to say that using reloc stuff to avoid checksums is the most excellent idea.
Applause!! 😀