Sam Hocevar’s .plan
This is an experimental blog engine. RSS feeds: everything | blog | Debian (DPL only) | VideoLAN | GNOME | Mono
Suspicious Activity? Indeed
Posted on Mon, 21 Nov 2005 02:26:13 +0100 - Keywords: devel, videolan
I spent the whole weekend looking for a DRM-encumbered Sony CD so that I could check for myself whether my code was really being redistributed without permission. I eventually found one: Suspicious Activity?, by The Bad Plus. A rather enjoyable post-modern jazz album. I am lucky, it could have been Céline Dion.
As expected, installing the CD’s custom player also installed a stealth aries.sys driver along with a few other interesting files such as $sys$DRMServer.exe, all hidden in a $sys$filesystem directory. I rapidly got rid of this cruft and started studying the really important file, ECDPlayerControl.ocx. It is the file Sebastian Porst and Matti Nikki found to be containing parts of mpglib, LAME, faad2, VLC...
Evidence that the DRMS code comes from VLC
There are of course obvious similarities between some functions and structures of ECDPlayerControl.ocx and the ones in VLC’s source. However, given how precise the implementation of a cryptographic protocol needs to be, the possibility that two separate implementations show many similarities must not be dismissed. The data structures and constant tables especially are likely to be identical. I think however that I found strong enough evidence that this is not the case here.
The original drms.c was written by Jon on 01/05/04. I then hacked on that file on 01/18/04 and reorganised it, also replacing the reverse-engineered MD5 and AES functions with clean implementations, then Jon added DRMSv2 support on 05/05/04 and I reorganised the code again on 05/08/04. Some of these changes were specific to VLC (not in that they made the code unusable outside of VLC, but rather that they made it possible to use an external MD5 hash provider, for instance), so they were the bits I was looking for in ECDPlayerControl.ocx.
For instance, Jon’s original code had the following instruction:
p_acei[ 4 ] = 0x5476212A;
Since all bytes of this long word are comprised between 0x20 and 0x7f, it was later rewritten like this:
char p_secret1[] = "Tv!*";
This change makes the code more human-readable because many other secrets in the Apple DRMS protocol are ASCII strings. Also, I know how to look for binaries that use the string "Tv!*", but it takes me some more time to think of a way to find binaries that use 0x5476212A. And the Sony rootkit uses the following (only relevant lines shown):
.text:100883B8 mov cl, byte ptr ds:xxxxx+4 ; 0 .text:100883C2 mov eax, dword ptr ds:xxxxx ; "Tv!*" .text:100883C8 mov [esp+70h+yyyyy], eax .text:100883DC mov [esp+7Ch+zzzzz], cl
The use of xxxxx+4 shows that ECDPlayerControl.ocx uses a string instead of a 32 bits integer to store the secret, disregarding the fact that the 5th character of the string (a null char) is never used.
Another example: in this commit I reorganised the DoExtShuffle() function, merging FourthPass() and FifthPass() and discarding a structure allocated on the stack. What is important here is that DoExtShuffle() was built by a complex combination of choices, the main purpose of which being to reduce the size of the C functions:
static void DoExtShuffle( uint32_t * p_bordel ) { uint32_t i_ret; i_ret = FirstPass( p_bordel ); SecondPass( p_bordel, i_ret ); ThirdPass( p_bordel ); FourthPass( p_bordel ); }
Note how i_ret is not reused and could be merged into the p_bordel array, or maybe SecondPass() merged into FirstPass(). This choice is definitely a legacy of how the code evolved. And the Sony equivalent: a perfect match.
.text:10089F3C xxxxx: .text:10089F3C mov ecx, esi .text:10089F3E call yyyyy .text:10089F43 push eax .text:10089F44 mov eax, esi .text:10089F46 call zzzzz .text:10089F4B add esp, 4 .text:10089F4E call ttttt .text:10089F53 call uuuuu
After having studied the Sony code for a while, I have of course gathered dozens of such examples. But I also discovered a few new things.
Where does the DRMS code come from?
The code undoubtedly comes originally from VLC, but it has traveled a lot. I would be surprised if it came directly from VLC, as no other part of VLC is included with the rootkit. And although there are parts of FAAC in the Sony code and FAAC includes VLC’s drms.c, the version currently in the FAAC CVS is horribly outdated.
Sebastian Porst also noticed a few obvious differences between the Sony code and the version of drms.c present in VLC. The most obvious being this one:
if( p_shuffle->i_version == 0x01000300 ) { DoExtShuffle( p_bordel ); }
Which became:
.text:10089F2E cmp eax, 1000300h .text:10089F33 jz short DoExtShuffle .text:10089F35 cmp eax, 1000400h .text:10089F3A jnz short skip .text:10089F3C DoExtShuffle: .text:10089F3C ... .text:10089F58 skip: .text:10089F58 ...
That 0x01000400 is a version check for 4th generation iPods firmwares. I also discovered at least 40 KB of new lookup tables that seem to be used for more buffer shuffling. At first I thought it was simply F4I’s DRM implementation, but the shuffling calls are nested with iPod hardware information retrieval from our DRMS code, so they’re really part of drms.c.
Sony distributing a DRMSv3 descrambler?
The only explanation I can think of is that someone took the VLC code, added support for an upcoming Apple DRMS format version and redistributed the software without letting the VLC authors know, probably violating the GPL (I only say that because I have not found the software yet, but I feel pretty safe in saying it).
Since it is based on GPL software, I was already entitled to ask Sony for the source code of ECDPlayerControl.ocx. But as the copyright holder of a significant part of the software they counterfeited, maybe I have a greater chance of being heard.
Not that it would be difficult to reverse-engineer it yet another time, but it would be awesome if the next opensource iTunes Music Store file player was contributed by Sony!