Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
28th September 2008, 21:02 | #181 | Link |
Guest
Posts: n/a
|
|
29th September 2008, 00:19 | #182 | Link |
Guest
Posts: n/a
|
Thanks.
TRAP_PrivateKey: I was able to trace both the obfuscated key (~ 96 byte) and the hash result to the heavily obfuscated code (virtualized, lot's of garbage,...). Not sure if i can do it. You would probably kill me if i convert this mess to c code. Looks like i have to record a instruction trace and then somehow analyze it automatically. I need to think about it. Edit: Any idea of how the result of TRAP_PrivateKey is verified? It's obviously a 320-bit signature which is probably not created by the RSA algorithm. The footer of every section of in the 0000?.svm files is 40 bytes long too. Note that the signatures used in the AACS authentication process are 40 bytes long as well. The way the result of of TRAP_PrivateKey is verified would give us a vital clue of what algorithm created the signature. Edit: When the hash is all zero the resulting signature is also all zero. If i overwrite the key with zeros i get stack overflows (wtf?) Last edited by Oopho2ei; 29th September 2008 at 20:42. |
29th September 2008, 21:32 | #183 | Link |
Guest
Posts: n/a
|
Actually, until trap-call ~5000, this trap is called just once with real parameters (for both movies). All other calls of this trap have bogus parameters and return 0x80000001.
And for this one real call, the program directly calls DeviceDiscovery(1,3) afterwards. The 40 bytes which are written by this call of TRAP_PrivateKey are (according to 'data read breakpoint' of the debugger) not accessed in the next 20 million instructions. Furthermore, before overwriting the register which is holding the adress of these 40 bytes, the progam writes this same adress to two places in memory which are also not accessed in the next 20 million instructions. So to me it seems as if this result is not verified at all (or maybe way later in the BD+ initialization). I will try and check a bit more, whether I can find any code accessing the 40 bytes. |
29th September 2008, 21:59 | #184 | Link |
Guest
Posts: n/a
|
Just like i expected: the unknown algorithm produces different results for the same hash (and the same key). It furthermore always produces a signature consisting entirely of zeros (wtf?) when the input hash is all zero. So now it is even more likely that it's some elliptic-curve signature algorithm like the one used in AACS. I now need to find the third (random) parameter...
Do the data read breakpoints work reliable yet? Maybe they are cleared when a new snapshot is loaded? Or maybe the result (40 bytes) is not accessed by the content code (instructions) and instead another trap call reads them? There must be a check somewhere... Last edited by Oopho2ei; 29th September 2008 at 22:15. |
30th September 2008, 08:27 | #186 | Link |
Guest
Posts: n/a
|
Hm, if I find some time, I will look into the breakpoint-system of the debugger.
On another note, some info on trap 0x550: It is not called in "DAT" v1.02, but it is called three times in "I Robot" v1.02. It takes as first parameter a pointer to these strings: 1) "BDSVM/00002.svm" 2) "AACS/MKB_RO.inf" 3) "BDMV/STREAM/000012.mts" The second parameter is the length of this string. Parameter three holds 0x00, 0x00 and 0x05. Fourth parameter is either 0x00 or a big value (>0x3FFFFFF) - this is not a pointer, but four bytes of data. The fifth parameter is a pointer to 0x200. The sixth parameter is the destination pointer (this trap seems to always write 20 bytes). I assume this trap is computing some kind of hash of the file. Could be CRC or SHA, my bet is on SHA since that outputs 20 bytes anyway. The values in parameters three, four and five should be additional inputs to this hashing algorithm. |
30th September 2008, 13:40 | #187 | Link |
Guest
Posts: n/a
|
According to your description Trap#0550 would be something like:
UINT32 TRAP_MediaHashFile(UINT8 *FileName, UINT32 FileNameLen, UINT32 Unknown, UINT32 Unknown, UINT32 *len, UINT8 *dst); When you look at the parameter checking you will see that it doesn't always produce 20 bytes. Instead it writes 20 * ( mem[len] / 0x200 ) bytes. Also the filename/path length may not exceed 1024 (!) bytes. One of the two unknown parameters could be a file offset. schluppo: could you please fix the data breakpoint problem? I need the value of n for testing (see ECDSA). Edit: Someone gave me a hint how to fix the problem with the data breakpoints. I have pushed the fix in the repository. Last edited by Oopho2ei; 30th September 2008 at 18:04. |
30th September 2008, 23:12 | #188 | Link |
Guest
Posts: n/a
|
I currently don't have the curve parameters (and therefor can't present a real example) but i don't want to withhold anything. The signature is created with ECDSA and consists of two 20 byte long numbers: r followed by s. How the signing process works is explained here.
You can forge signatures without the curve parameters simply by using a fixed point on the curve all the time which means your random number k and r (first 20 bytes) are constants. So these are all the constants you need: Code:
r = 7c7d84d310c42436daff10af116f80448dc3f88b k = 7AA9A10C3E90AA8FDAF34DD28F665D3C609CACD7 d_A = 735E0356EA6356E099AD83152E2D81EA1164A866 (keyID == 0) n = 96609d9e935e52c683dafdc49216143f9a24373d Code:
e = 1111111111111111111111111111111111111111 The result is: Code:
s = 532b4944f80565075ea9b8894e61c692ed71f3c8 Edit: you need the extended euclidean algorithm to calculate 1/k. The result is "1/k = 210974BC85725B5FB0E04FA473FD988001F89088h". So simply multiply with that value. Edit: There were problems with the previous values so this is a new example and a new private key. It has been tested and should work fine. Edit: If you the signature verification fails then TRAP_DeviceDiscovery will be called instead of TRAP_Aes after TRAP_PrivateKey (first call of TRAP_PrivateKey in DAT v1.02) Edit: That's the second private key: Code:
d_A = 87E22D06A699EE311CD73F19B91E67414C44F4F5 (keyID == 1) Edit: We have found the remaining curve parameters: Code:
q = 96609D9E935E52C683DBFC3A7D783EA942BDE8CB a = 96609D9E935E52C683DBFC3A7D783EA942BDE8C8 = -3 (mod q) b = 3E567D8DEC27873BCF86F5FBB595DB288C62C721 x_G = 05FC5B0B2360AC50A76E1511BC5C9AF67A004D0D y_G = 09B0D43F319B09A5B679CCF264E1ABA4D56594EA Code:
x_Q = 31dbb17fea9d7d0eb8bfbb6b8d29ac938c13b599 y_Q = 2465dd38f4214edee4da4e7f62b77a41ce962757 Code:
x_Q = 57305D64D1013FFFA4D72355B4C70B27A815A343 y_Q = 05E22B42F88A5C1AC5E70DF466353BDB0A83228A Last edited by Oopho2ei; 8th October 2008 at 14:11. |
1st October 2008, 08:01 | #189 | Link |
Guest
Posts: n/a
|
Regarding Trap#0550 i was told that the fourth parameter is the file offset and that this trap really calculates the SHA-1 hash.
Code:
UINT32 TRAP_MediaHashFile(UINT8 *FileName, UINT32 FileNameLen, UINT32 FileOffsetHigh, UINT32 FileOffsetLow, UINT32 *len, UINT8 *dst); Edit: The file offset is 64 bit (FileOffsetHigh << 32 | FileOffsetLow). A 32 bit address is too small for those large files (00001.m2ts is > 20GB). Edit: TRAP_MediaHashFile is fully analyzed now and i have updated the documentation in svn Edit: We need proper names for Trap#0540 and Trap#0550. In alphabetical order name(Trap#0540) has to stand before name(Trap#0550) which is currently not true: Code:
name(Trap#0540) = TRAP_MediaReadFile <-- maybe change in TRAP_MediaFileRead ? name(Trap#0550) = TRAP_MediaHashFile <-- or maybe change this in TRAP_MediaSHA1HashFile Edit: The naming issue is solved. The "official" name for Trap#0550 is TRAP_MediaSHAFileHash Last edited by Oopho2ei; 2nd October 2008 at 19:30. |
2nd October 2008, 04:49 | #190 | Link |
Guest
Posts: n/a
|
Great work on TRAP_PrivateKey!
Trap 0x550 is implemented now. Works fine (for the two files that I have ). I named it 'trapMediaHashFile' in my code but do not care about the name actually. Just change it to whatever you think is appropriate. trap 0x320 is trapMemSearch, will implement it soon. is it possible to code trapPrivateKey yet or should I wait until you posted some more examples / parameters? Only big thing remaining now is trap 0x530 aka DiscoveryRAM. This is called around 500 times, taking memory from lots of different areas of the player's RAM. Maybe we need a memory dump and let the trap-emulation read from that dump-file or something like that. I checked a few example trap-calls with identical parameters and did not see differing results. Maybe this trap is just asking for areas of the RAM which are constant throughout execution? |
2nd October 2008, 12:30 | #191 | Link | ||
Guest
Posts: n/a
|
Are the parameters identical to the TRAP_MemSearch() in the patent?
Quote:
Quote:
|
||
2nd October 2008, 16:03 | #193 | Link | |
Guest
Posts: n/a
|
Quote:
Code:
if ( Dst & 0x03 != 0 ) return 0x80000001 The implementation would look like this: you load the first snapshot and compare as usual and continue execution but keep the last snapshot in memory. For the next snapshot you use the previous snapshot (saved in memory) and the difference to the previous snapshot (which is stored on disc now). A sample implementation of how to handle the "differential snapshots" is given here I have updated the trap documentation of TRAP_Memsearch and made some minor changes to wbaes. Also what traps actually return a value (write to r01)? According to the documentation most of them return "UINT32". I was only guessing. Has anyone verified that? Edit: All traps for which the parameters are checked return a value. I have corrected the documentation and also renamed Trap#0550. The "official" name is now TRAP_MediaSHAFileHash. Thanks again to our anonymous contributers Last edited by Oopho2ei; 2nd October 2008 at 19:23. |
|
2nd October 2008, 23:46 | #194 | Link |
Guest
Posts: n/a
|
Now that the instruction processing seems to work without problems and only very few traps still have to be explored it is time to start looking at events. The event passing and handling will be quite a challenge not only because it's barely documented but also because events are somewhat nondeterministic. It should also be the last thing left to do.
These are some useful informations which are given by the pdf:
Observations of event handling we have already made:
A great deal of the above observations were made by our anonymous contributers. Last edited by Oopho2ei; 3rd October 2008 at 00:19. |
4th October 2008, 01:37 | #195 | Link |
Guest
Posts: n/a
|
I would like to introduce a new snapshot file format for our event analysis. The structure is shown below:
Code:
struct { uint32 pc; uint32 if; uint32 regs[32]; uint32 event_area[1024]; } snapshot_t struct { snapshot_t snapshot0 snapshot_t snapshot1 } event_snapshot_file_t As you can see each snapshot contains the program counter, the instruction filter, all 32 registers and most importantly the first 1000h bytes of vm memory (address space 0x000000-0x000FFF). The filenames have the format "epa_diff_%06d.bin". You can write a program which analyses all the differences made by the player in the dedicated memory space (Event Parameter area) and finally creates a list/summary of all changes. Aim is to identify the section where the event id and the event parameters are stored and to create a list of all event types. A snapshot package of that kind will be available soon. Edit: This is a sample package: http://uploaded.to/?id=rfr3ew Edit: That's the event snapshot package i have promised you: http://uploaded.to/?id=6ca19v It seems every time i fast forwards or rewind a event is created. During the movie playback i have noticed about every 30s a new event. Last edited by Oopho2ei; 5th October 2008 at 11:42. |
5th October 2008, 02:12 | #196 | Link |
Guest
Posts: n/a
|
There are still some other minor issues apart from event passing/handling. For example there is still no exception handling for cases like "division by zero", "arithmetic overflow" etc. The literature says a trap call would handle the exception but in the case of BD+ they seem to have defined the result of a division (both signed and unsigned) by zero to be zero. I had expected that our debugger would crash in this case but it didn't. Instead a message box with the text "/ by zero" is displayed.
I will look at the other cases soon and upload a list to the repository. Edit: the documentation can be found here Last edited by Oopho2ei; 5th October 2008 at 15:30. |
6th October 2008, 01:58 | #197 | Link |
Guest
Posts: n/a
|
I have looked at the remaining Traps #0020 and #0530 (TRAP_DiscoveryRAM).
Trap#0020 has two parameters which are both vm memory addresses from which the player is reading a lot of data. I don't know what is done with the data yet. This is probably related to TRAP_Finished because both traps are in the same group. We still need a name for this trap which fits in alphabetically between TRAP_Finished and TRAP_MediaReadFile. For TRAP_DiscoveryRAM the player fills a section of memory with some pattern and then loads the data which the content code is expecting from different places and thereby overwrites parts of the pattern again. I don't know if the pattern is really needed or just some sort of vendor specific countermeasure against memory analysis by malicious content code. The memory organization can be found here (work in progress) Last edited by Oopho2ei; 6th October 2008 at 02:07. |
6th October 2008, 14:45 | #198 | Link |
Guest
Posts: n/a
|
Implementation of trap_0x320 (TRAP_MemSearch) finished, works fine (for the few examples).
The title's VolumeID is now taken from a file called "volume_id.bin" which has to be in the same dir as the .jar. When trap_0x520(..,..,1,3) (TRAP_DeviceDiscovery) is called, the VolumeID is inserted into the result. Works fine for the two movies. Things to code / fix: - trap_20 (TRAP_EventGet??) is still untreated. - trap_120 (TRAP_PrivateKey) is still untreated. - trap_140 (TRAP_Sha) intermediate results are still wrong. I will fix this soon. - trap_510 (TRAP_DeviceAccess?) is still untreated - there are just two calls of this trap in the 5000 snapshots for both movies. They both don't change memory. - trap_520 (TRAP_DeviceDiscovery) - for parameters 1,3 there needs to be a timestamp in the result. Currently the timestamp is static, I will fix this soon. - trap_530 (TRAP_DiscoveryRAM) - is still untreated, I am planning to look at this later today. - trap_560 (TRAP_RunNative?) - there are no example calls for this yet. Will upload new sources to the repository later today. Edit: They are in the repository now. Also contain a try at TRAP_PrivateKey. Up to the end of the SHA-part, it works fine. Feel free to bugfix Edit2: Timestamp added to the result of TRAP_DeviceDiscovery(...,...,1,3); Should be fine now. Edit3: TRAP_DiscoveryRAM is now reading <len> bytes from a file called "RAM.bin", starting at <offset>. It then writes this data to <pDst>. It would be convenient to have a player memory-dump of the first 4mb to read from. Since that's probably not possible, I am working on a different solution now. Last edited by schluppo; 7th October 2008 at 03:20. |
6th October 2008, 15:21 | #199 | Link | ||
Guest
Posts: n/a
|
I was told that there is no TRAP_EventGet (see posting #145). The event passing is likely done via a dedicated memory area (probably 0x000000-0x000FFF). The implementation of this trap is a bit strange. Some details can be found in posting #197
We are still trying to figure out the curve parameters but i was told it works fine with the fixed (k,r) pair from posting #188. Quote:
Quote:
Have a look here to see what i changed to make the data breakpoints work. Please only upload the source code (*.java files) to the repository because we have only 200MB disc space and all revisions are stored. When you upload a snapshot (to uploaded.to or whatever) could you please include a description of what files have to be present and in which directory? The output of "find *" will probably be enough. Last edited by Oopho2ei; 6th October 2008 at 15:47. |
||
7th October 2008, 13:36 | #200 | Link | ||
Guest
Posts: n/a
|
There are no updates visible in the repository for the latest changes you announced. Also for some reason you have deleted all sources in revision 48 and added new sources in revision 49 and 50. One revision later (51) you have finally added the description of what files are needed.
The result (revision 51) is correct but the way you work with the repository (it's not a ftp server!) has to be improved. First of all to upload your latest changes you need a single simple command: Code:
svn commit -m 'this is a little description of what i have changed' I think people are discouraged from doing that because the latest version of the repository is already outdated (you have made other changes): Quote:
Quote:
Also you don't have to edit the postings to announce your changes. People can read the latest changes here. Anyway thanks for your work and the updates. Edit: i make daily backups of TRAC and SNV so we can quickly move if necessary. But reverse engineering for interoperability (bd+ for linux) is normally considered legal so i doubt there will be any problems. Last edited by Oopho2ei; 7th October 2008 at 14:12. |
||
|
|