I would like to say a few words at the start of this file as I feel that it is necessary to do so
Over the last year or so I have been looking at Fravia+'s site, and thinking that it was good thing that somebody has taken the effort to tutor the new generation.
I started taking other peoples code apart in 1983, yet I have been retired for around five/six years... Why did I decide to return ?
Well I think this will be a bit of a one off to be honest.
There seems to be a shortage of good information on reversing CD based protection systems, I don't know if this counts as good information but it may help somebody.
After checking out Fravia+'s site every once in a while I thought I should add a tutorial, to give something back for the pleasure I have had from reading some of the essays.
During the summer I finally moved on from my old 486 to a decent spec system, and also got myself a CD-R.
Well after playing about with it for a while, I started to look into what the best mastering software was, and found the CD-R discussion forum at
کد:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
, where everybody had been complaining about how they couldn't copy certain games.
Well amongst the usual no brain postings there where a few interesting reports, such as about CDs over 75 minutes, illegal Table of Contents and large files on disk.
Whenever you saw a patch listed it seemed that the inhabitants of the message board, thought of the author as some sort of supernatural creature.
The reality is that our brains are wired a little differently, to everybody else.
Most of the protection schemes have the following simple structure:
Is the drive a CD ?
Does a file exist ?
Can that drive be written to ?
That's about it, a bit lame really, perhaps even hiding this inside a DLL, if they are in an ugly mood.
Well considering I wanted Thief (I collect as much as I can afford by ex Infocom staff), and Eidos used what looked like a "mean" protection system. I bought Thief.
Well... it was quite a disappointment to tell the truth (not the game, I may add it puts a whole new spin on the Doom/Quake genre, but the protection itself).
The protection system used for Thief relies upon :
1: More than 75 mins of data on the CD
2: An invalid TOC, Data, Audio, Audio, Data
3: Four Fake files on the first data track, each of approx. 515 MB, KXEP.AFP, AZXP.AFP, TFJB.AFP & IGYQ.AFP.
4: Mixed case in the CD Volume name.
Anyway the Eidos TOC is only to make a straight copy difficult, as the two audio tracks aren't used at all and the other tracks isn't even checked for.
This is real dumb as all the necessary functions are there in MSCDEX.
Without these three tracks, 74 minutes is more than enough to hold the real data track.
The four fake .AFP files are not used properly within the protection system, although they deter casual copying, there is a 4KB block loaded, and I think they even check it's the correct data, it is not necessary for the program to actually run.
Obviously it would have been easy enough to copy each of the 4096 byte blocks to separate files and simply seek to offset 0 (rather than 696406016, 496444928, 696514560 or 696346624, as actually used), and then read the 4096 bytes each time, but it would have slowed me down.
To be honest it did slow me down because I was convinced that they would not be so stupid and lazy not to use this data (I was wrong).
I don't even think they check for the mixed case in the CD volume label.
Tools used:
Filemon, W32Dasm and hiew
Using filemon, I watched as thief.exe opened each of these hidden .AFP files where opened and a seek was carried out to around 696496016 bytes into the file, 4096 bytes read and then the file closed.
This occurred for each of the .AFP files, with various (but similar seek values).
After that I cut a CD with all the files except the .AFP fakes, and as the software I was using wouldn't allow me to use mixed case volume labels
I used W32Dasm to disassemble thief.exe.
I searched for .AFP and found that one large subroutine was used to open them, this made life easier.
The routine was at 00526100 through to 526274 and was called from 3 addresses, all within a 4KB region of RAM.
Then I searched for GetDriveTypeA which lives between 0050d720 to 0050d735
It called from 0050d773 and 0050da5e
The call to 0050d773 is placed within a routine (between 0050d740 to 0050d78f)
Appeared to be reserved for scanning through drives D: to Z; looking for CD drives.
Not very interesting
The call from 0050da5e looked much more interesting as it seemed to test the return value of GetDriveTypeA.
Six instructions after this call to GetDriveTypeA was a call to 00526100 the .AFP read routine.
A few instructions further on a second call to the .AFP routine took place and some testing of eax the routine did a ret
This routine is called from 0050dadc
The other call to the .AFP read appears to trace back to 0050dad5
This was the region that the tests on the invisible .AFP files are called from
This means that the all AFP reads and protection checks take place from an area separated by 2 bytes.
Just like this
:0050DAD5 E8E6FEFFFF call 0050D9C0 ; First Call
:0050DADA EB05 jmp 0050DAE1
:0050DADC E82FFFFFFF call 0050DA10; Second and third calls
To quote Homer Simpson DOH!
The Subroutine this is in looks just like this
* Referenced by a CALL at Address:00414FCC
:0050DAC0 6A00 push 00000000
:0050DAC2 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"only_check_path"
:0050DAC4 68E0BF6000 push 0060BFE0
:0050DAC9 E862AF0300 call 00548A30
:0050DACE 83C40C add esp, 0000000C
:0050DAD1 84C0 test al, al
:0050DAD3 7507 jne 0050DADC
:0050DAD5 E8E6FEFFFF call 0050D9C0
:0050DADA EB05 jmp 0050DAE1
* Referenced by a Jump at Address:0050DAD3(C)
:0050DADC E82FFFFFFF call 0050DA10
* Referenced by a Jump at Address: 0050DADA(U)
:0050DAE1 85C0 test eax, eax
:0050DAE3 7405 je 0050DAEA
:0050DAE5 E986FBFFFF jmp 0050D670
* Referenced by a Jump at Address: 0050DAE3(C)
:0050DAEA 33C0 xor eax, eax
:0050DAEC C3 ret
Well doesn't :00414FCC look a bit out of place in all this, and just look at this
:0050DAC0 6A00 push 00000000
:0050DAC2 6A00 push 00000000
Looks like some .OBJ code has been linked, and they wanted to make sure of some free space on the stack.
Well if we look at 00414FCC, we could nop the call and see what happens.
But I wont.
Why ?
Well assuming that the protection code called is not written by Looking Glass (the authors of Thief), as all the Eidos stuff on release, has similar (if not the same) protection.
They won't check the internal code of the protection routines.
However they may check their own code, including the call to the disk protection.
So rather than using four NOPs to delete the call 0050DAC0, I chose to add a RET (C3) at 0050DAC0, that way all the code by Looking Glass is totally intact.
So fire up a hex editor and search for
6A,00,6A,00,68,E0,BF,60,00
Change the (first) 6A to C3, it is the only occurrence of these hex values, and write the data back to disk.
The file offset is 10CEC0, (if you are using hiew then it is 50DAC0, in the other offset mode)