Hi,
For those interrested, here's a FAQs about my SafeDisc support
implementation.
Feel free to comment.
Laurent Pinchart
-------------- next part --------------
SafeDisc FAQs
What is SafeDisc ?
=================
SafeDisc is a CD copy protection system designed for Microsoft Windows. It is
widely used, especially to protect games. There are currently 2 main versions
of SafeDisc around: SafeDisc 1 and SafeDisc 2.
Is my program protected by SafeDisc ?
====================================
Look at the root directory of the program CD. The following files are present
on SafeDisc 1 protected programs:
secdrv.sys
drvmgt.dll
clcd16.dll
clcd32.dll
clokspl.exe
dplayerx.dll (not present on the very first version of SafeDisc)
In addition to these files, a .icd file contains the encrypted binary, while
the main executable (usually game.exe) is only a wrapper used to load and
decrypt the .icd file.
For SafeDisc 2, only secdrv.sys and drvmgt.dll can be found on the CD. The
encrypted binary and dplayerx.dll are now stored inside the wrapper (usually
game.exe).
How do I run SafeDisc protected programs with Wine ?
===================================================
If your version of SafeDisc is supported (see below), your program will run
out-of-the-box (at least for SafeDisc related code :-) if you use NT mode
(--winver nt40, --winver win2k or --winver winxp). Pick the version of NT that
your program is the most likely to support (winxp with a 5 years old program
isn't a good idea).
How do I find out which version of SafeDisc my program uses ?
============================================================
There is no publicaly available version numbering for SafeDisc. However, it
seems that the version number is stored in the executable as 3 unsigned 32-bit
integers. Using an hexadecimal editor, locate the following byte pattern in
the wrapper (game.exe)
> 426f475f 202a3930 2e302621 21202059 BoG_ *90.0&!! Y
> 793e0000 y>..
There should be 3 unsigned integers right after that, which are respectively
the version, subversion an revision number.
On some versions of SafeDisc there are 3 null integers following the pattern,
before the version number. You'll then have to look at the 3 unsigned 32-bit
integers right after
> 426f475f 202a3930 2e302621 21202059 BoG_ *90.0&!! Y
> 793e0000 00000000 00000000 00000000 y>..............
Don't forget to convert the version number from hexadecimal to decimal.
For SafeDisc 1 you can alternatively check the size of the dplayerx.dll file.
dplayerx.dll size SafeDisc version number
-------------------------------------------------------
165.888 bytes 1.35.0
Another very important information is the secdrv.sys version number.
secdrv.sys size secdrv.sys version number
---------------------------------------------------------
14.368 bytes 1.3.0 (SafeDisc 1.35.0)
18.768 bytes 2.2.0 (SafeDisc 2.5.30)
(If you have another version of SafeDisc please contribute to these tables).
Which version of SafeDisc are currently supported ?
==================================================
This hasn't been determined yet. SafeDisc support for Wine has been
developped
using a game protected with SafeDisc 1.35.0. SafeDisc versions which use
secdrv.sys 1.3.0 or lower might work. Some other versions might work too.
SafeDisc 2 is not supported yet.
How does SafeDisc 1 work ?
=========================
SafeDisc encrypts the real executable into a .icd file, and uses a wrapper to
decrypt the executable.
The wrapper contains 3 code sections: `.text', `.txt' and `.txt2'.
`.txt' is
encrypted.
The wrapper starts by decrypting itself, using the checksum of `.text', the
binary content of `.txt2' and some values which depend on debugger detection
tests. If a debugger is loaded, if a software breakpoint is set in the first 8
bytes of any of the kernel32.dll functions, or if the `.text' and
`.txt2'
sections have been modified (this includes setting a software breakpoint in
the code), the `.txt' section won't be decrypted correctly and a crash
will
occur.
On NT, the process of detecting a debugger involves loading the kernel-space
driver secdrv.sys, which I implemented as a user-space code for Wine. On
Windows 95, 98 or Me, it involves executing arbitrary code in ring 0 mode
(kernel mode). This is not supported by Wine (as the underlying OS isn't as
broken as win9x), so that's why you have to use NT mode.
When the `.txt' section has been decrypted, the wrapper will then check for
the CD key using direct SCSI operations on the CD driver. If the CD key
doesn't match the expected value, a message box pops up to ask you to insert
the original CD in the drive.
The wrapper then loads and starts clokspl.exe for a still unknown purpose.
The last stage consists in creating the game.icd in a suspended state. The
suspended process memory is then written with some initialization code, and
SetThreadContext is called to jump to that code. The initialization code will
load dplayerx.dll (which is encrypted in the same way as the wrapper, with 3
code sections), and will decrypt the main executable. Control is then
transfered to the main executable, and the game starts.
Have you ever tried to rename game.icd to game.exe, and run it ? It will
crash, because WinMain is encrypted. It needs to be decrypted by the
initialization code, which is found in the wrapper and in dplayerx.dll.
That's pretty much all I know about SafeDisc. Don't ask me how to remove
SafeDisc from a game. I don't know how to do so.
If you have more information, especially about debugger detection and
secdrv.sys, please let me know.
My version of SafeDisc is not supported. What should I do ?
==========================================================
Implement support for it :-)
For unsupported SafeDisc 1 versions you will probably 'only' need to
implement
the secdrv.sys that comes with your program. For SafeDisc 2 things could be
more difficult as I haven't tried any SafeDisc 2 protected program yet.