An overview of Safedisc versions
by ArthaXerXès
Published by +Tsehp June 2001
Mise au point
(taken from Safedisc® User Guide)
- Can the SafeDisc technology be hacked?
- The developers of SafeDisc, Ç-Dilla Labs, has investigated all known
methods and tools used by hackers to compromise the encryption or the
authentication code. SafeDisc will disrupt any attempt to use disassemblers
and debuggers to isolate or patch any of the SafeDisc code. Many other
techniques are used in order to increase the time, expense, and expertise
required to compromise a SafeDisc protected title. These substantial
disincentives will assure that the commercial value of the title has been
fully exploited before any risk of compromising the security
arises.
Macrovision has maintained the effectiveness of its home video
copy-protection technology to the satisfaction of the major Hollywood studios
for the last 15 years. Our unique experience in the copy-protection business
and our technical expertise will assure that the quality and effectiveness of
the SafeDisc technology will be constantly improved in order to maintain its
effectiveness against piracy.
The truth :
- The Safedisc technology does not prevent piracy since the CDs can be
copied by someone with a DAO RAW capable CDR and who is able to operate a CD
recording software.
- We have totally reversed the "encryption" and "authentication code", we
have even developped easy-to-use software to automatically remove Safedisc
from any program.
- The great majority of software is pirated and distributed unprotected in
their full version the day it hits the stores (sometimes even before !).
- Macrovision home video copy-protection can be defeated either by a cheap
electronic device or by a program for those who have a computer with video-in.
Spare your money, do not buy protections schemes. There are cheaper
and more efficient ways to fight piracy.
Introduction
Although I have noted a decreased use of CD protection
(most of them are defeated by a kid with CloneCD), they are still strongly
present (and strongly annoying).
Safedisc is probably the most used,
thanks to an agressive marketing and a clever price policy, and also the fact it
is easy of use and (almost) transparent to the end user. However, from a
technical point of view the protection is disappointing. In my humble opinion,
it is just a collection of hacks, nothing really clever or outstanding. The code
is dirty and inefficient, somehow I wonder how the makers are able to maintain
it (and understand why there is no real improvement since the first
version).
In this short essay, I will review the various Safedisc
versions, from 1.6.0 to 2.05.30. Consider this essay as a mise en
bouche for a forthcoming essay that will be a detailed reverse engineering
of Safedisc 2, something much more advanced than my previous essay on
Safedisc.
If you find this document to be inaccurate or incomplete, feel
free to inform me. I would also like to thank Black Check, Booo, dec0de12,
Icydee, Knulla, Lord Crass, Moelch, Portia, r!sc and many other Fravias I
forgot (or wish to remain anonymous) who kindly and selflessly shared their
insights.
How to determine the Safedisc version
In order to determine the Safedisc
version, you have to search for this string in the executable (icd for 1.x.x,
exe for 2.x.x) : "BoG_ *90.0&!! Yy>". Just
after there should be three unsigned longs, that are respectively the version,
subversion and revision numbers. Safedisc 2 executables can be recognized by the
presence of sections named "stxt???" (where ? is any figure), dll placed in the
temp directory during execution and appended data at the end of the executable.
Revision history
Note that I do not consider anti-debugging features
here, I am only writing about unwrapping. Anti-debugging becomes heavier and
heavier with each new version, you should be very careful with your breakpoints
and carefully monitor the secdrv.sys device driver under NT.
And by no
mean this should be considered as an introduction to Safedisc. You need to have
a minimum of experience with the protection, and a real experience of reverse
engineering under Windows. I am neither going to explain the technical terms nor
detailing the PE format (for example).
- 1.6.0
- The first released version. Sections are ciphered using the TEA algorithm
with a 128 bits key in the form aaaa where a is a 32 bits number. The key is
red from the CD or computed from hidden data in the loader if this is
impossible (CD reader failure). The imports are simply mixed using a Monte
Carlo algorithm, you need to demangle them with the TEA key and then update
the first thunk. Note that only kernel32.dll and user32.dll imports are
modified.
- 1.7.0
- There is an additional step to perform prior to reorder the imports, you
have to decrypt the ASCIIs, the algorithm is actually quite simple, you also
have to remove the "hint".
Here is the algorithm used to decipher the ASCII
(taken from Safedisc annihilator) :
// key is the
128 bits TEA key
ascii_key = (unsigned char)((key >> 24) ^ 0xAB); //
will be needed to decipher the ASCII
for(k = 2, cur_ascii_key =
ascii_key; ; k++)
{
buffer =
ascii_pointer[k];
ascii_pointer[k] ^= cur_ascii_key; // xor
character using key
cur_ascii_key = buffer; // key is unxored
character
if (ascii_pointer[k] ==
0)
break;
} // end ascii
deciphering
- 1.11.0
- Safedisc now supports Windows NT, it will automatically install/uninstall
a NT driver called secdrv.sys.
- 1.30.0
- Now the imports' RVAs are xored using the lower 32 bits of the TEA key,
this helps you to quickly find the TEA key (an idea of Black Check). Why ?
Simply because there are imports stored in loader.exe (you will find 4 dwords
in the loader in this form a a b b just after a 0x00000000) and instead
0x00000000 is stored in the icd. If we xor the ciphered 0x00000000 with one of
the dword found in the loader, we will obtain the TEA key (well the lowest 32
bits dword, but since the key is of the form aaaa, you can extrapolate the
full key most easily) ! All you have to do is to try for each import
dword.
- 1.40.4
- Things are becoming more complicate here. Now the calls (well, a certain
kind of call only, Ç-dilla did not implement a disassembler in Safedisc) are
modified and need to be fixed. Here is the solution r!sc found and that I also
used (this is actually a mimic of Safedisc) :
- Look for 0xff15 in the code section(s)
- Compute a remainder (the way it is computed will change in
other version). This remainder is the way Ç-dilla found to apply their
algorithm only on calls. Pretty lame I must say.
- If the remainder is equal to a certain value (again this changes), then
proceed with "deciphering".
- Deciphering pseudo code :
- determine if this is a call to user32 or kernel32
- call_pointer -= api_thunk_start
- call_pointer += (current_section_offset + key) % number_of_apis
- call_pointer = (call_pointer + number_of_apis) % number_of_apis
- call_pointer = (call_pointer << 2) + api_thunk_start +
pe_image_base
- 1.41.0
- The only change here is that the calls remainder is computed in a
different fashion.
- 1.42.0
- Macromedia Director Files can be protected using Safedisc.
- 1.45.11
- Things changed here. To me, it sounds like Ç-dilla found out about our
generic unwrappers. ;-) Well they did two things to counter us (but it did not
work of course).
Problems :
- They fixed the TEA key weakness (the fact that it is 4 times the same
dword), the key is now a real 128 bits number (do not worry we found a way
around).
- To prevent automatic unwrapping, they use code inside dplayerx.dll for
the modified calls. This code changes with every protected program, and thus
you cannot write a generic algorithm (again, we found a way around :-).
Solutions :
- Well, I do not like to despise other programmer's work, but this move
was pretty worthless. At first we were a little bit concerned by this, but
eventually someone (I think it is r!sc) discovered that the 128 bits key is
actually computed from various values we can easily retrieve (instead of
reading 128 bits from the CD, which would have been more
secure...).
Using our magic 32 bits value :
inc_entry_point = entry_point + 0x2d8; // entry_point is the
icd entry point
x_val = ((TEA_key1 - inc_entry_point) ^ checksum) ^
raw_key[0];
full_TEAkey[0] = TEA_key1;
full_TEAkey[1] = (x_val ^
raw_key[1]) + inc_entry_point;
full_TEAkey[2] = (x_val ^ raw_key[2]) +
inc_entry_point;
full_TEAkey[3] = (x_val ^ raw_key[3]) +
inc_entry_point;
The raw key is stored in loader.exe, look for
"DECRPE\0\0". In future version they added an offset, but it is still
located in the same place.
Another result of this feature is that we
started to wonder if there was actually any data red off the CD. I knew
there was some data actually red from the CD (this was partially correct),
but later I learnt that this data is also present in the loader (to make the
protection work on poor CD readers), which means that you can generate the
full key without any brute forcing and without the original CD.
- Well, this was a more clever move. I had to implement a dplayerx.dll
loader (and also had to fight against some nasty problems under 2k), get the
pointer to the magic routines and apply them. Note that the call
deciphering routine is still the same (logical), this is the way
used to determine if a call must be fixed or not that changed. It is not a
remainder any more, we apply an eax modifier (a routine that
modifies the value of the eax register) stolen from dplayerx.dll. This is
the only reasonable way, since the eax modifier changes with each
different dplayerx.dll.
- 1.50.20
- One big new feature here, a second layer of encryption is applied on the
ICD using a mundane algorithm. Also the address for the dplayerx.dll routines
changed. The second layer of encryption has to be removed before brute forcing
of course. And yes, the second layer uses a routine from dplayerx.dll. Here is
the algorithm for a block of data :
bool
__fastcall icd_rebuilding::new_decipher_block(void *p, unsigned long
size)
{
unsigned long done,
i_size;
unsigned long buf1, buf2;
unsigned long
*ptr;
done = 0;
i_size = size >>
2;
ptr = (unsigned long *)p;
while(done
< i_size)
{
buf2 = (done <<
0x18) | (done << 0x10) | (done << 0x08) |
done;
buf1 = ptr[done] ^
buf2;
buf1 =
m_dplayerx->execute_eax_modifier(0x65be, buf1) ^
buf2;
ptr[done++] =
m_dplayerx->execute_eax_modifier(0x65be + 0x63,
buf1);
}
return
true;
}
- 2.05.30
- The real news are (taken from SafeDisc® Release Notes) :
- SafeDisc API
The SafeDisc API provides extra security
features. These are implemented by inserting macros, from the SafeDisc API,
into the product code. After the product has been protected with SafeDisc,
the macros enable SafeDisc security routines to be performed whilst the
protected product is being run.
- Protection of DLLs
SafeDisc can be used to protect DLLs as
well as EXEs.
But really, what changed ? From the outside, many
things have changed since everything seems to be held in one executable
file.
Internally ? Almost nothing.
2.05.30 from an unwrapping point
of view is strictly 1.50.20. What is boring though is the heavier
anti-debugging features payload. Also, as I said above, everything is now
packed in one executable. You need to extract the data from this executable.
It is appended at the end of the executable (not even stored in a
section...).
Since I have not really worked a lot on Safedisc 2, I
cannot tell you the exact nature of the algorithms, but I suspect them to be
quite simple. Portia posted about them on my message board, but I have
discarded the message (I told you I was not a god ! :-).
To unwrap
2.05.30 you will probably have to do the following :
- extract dplayerx.dll and the "loader" from the main executable.
- extract the "icd" from the main executable.
- Unwrap the icd.
- fix the entry point (it points to Safedisc code) of the icd. The
original entry point is hidden "under" the main SD2 routine, it is very easy
to find with IDA. Also fix the data directory (for the imports).
I have not yet performed an in-depth reversing of the Safedisc
API, but I suspect it can be fully and automatically disabled quite easily.
The key is probably to find and disable the hub that all protected
functions use. One could either reverse the hub to restore the
functions, or modify the hub to unconditionally operate.
Conclusion
There are also more recent version of Safedisc 2 available,
but I have stopped working on Safedisc since 2.05.30 (other projects to attend),
and I am just getting back to it. If you have additional information to share,
please be my guest. Ihope that you found that document useful.
If you
find information about Safedisc hard to come by, this is because of the bad
spirit of competition in the warez scene. Most of the "big" groups have
unsafedisc-like programs and really do not want other groups to have
them, therefore they keep secret what they know about the protection. I do not
think they realize that everybody would benefit from cooperation.
"He who controls the unwrapping controls the warez".
;-)
And before you ask me : yes, there is a version of Safedisc
Annihilator to support Safedisc 2 in the works, and no, I do not know when it
will be released (I have many other tasks that require my attention).
ArthaXerXès --
06/16/2001