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. |
23rd September 2008, 08:12 | #161 | Link | |
Guest
Posts: n/a
|
Quote:
Code:
uint32 ringsize = 0x40000; unit32 ringbuffer[ringsize]; uint32 i = 0; // entry pointer in trace file fopen(...) // initialize the buffer fread(ringbuffer, sizeof(uint32), ringsize, trace_file); while (1) { printf("current pc is: %08d\n", ringbuffer[i % ringsize]); i++; // switch to next pc entry // usually we could write and read at the same time (two threads) // i assume only one thread so i refresh/write the entire buffer at once if( i % ringsize == 0) // check if are back to our starting point (walked the ring all the way around). if so refresh the buffer { // read the next MB into the buffer fread(ringbuffer, sizeof(uint32), ringsize, trace_file); } } Last edited by Oopho2ei; 23rd September 2008 at 16:31. Reason: added missing "== 0" |
|
23rd September 2008, 20:51 | #162 | Link | |
Guest
Posts: n/a
|
Quote:
Run the program given in posting #158. It outputs 4 dwords: "3817007A 0D652D45 0A23A6B0 95876211" so the decrypted key is: Code:
7A 00 17 38 45 2D 65 0D B0 A6 23 0A 11 62 87 95 Code:
21 BB 37 02 E1 CF F6 EE 92 82 3F B5 A0 A1 35 00 3D 97 95 F0 AB F6 41 86 9D 51 07 D7 E9 80 7F BC B8 94 BB 0D 7F 72 34 C4 16 4C 6B 40 BC 8F 92 2C Code:
openssl aes-128-ecb -d -K 7A001738452D650DB0A6230A11628795 -iv 00000000000000000000000000000000 -in enc_data.bin -out decr_data.bin Code:
d2 8a e3 fd 2e 66 63 55 b7 64 01 6e 4a da 41 2c dc 7d fb e9 46 13 4b 76 5c 83 27 1c c6 6b 38 6a 00 00 00 00 00 00 00 00 00 00 00 01 00 00 44 22 |
|
23rd September 2008, 22:42 | #163 | Link |
Guest
Posts: n/a
|
Those are the keys which can be used by Trap_AES (you already knew key 4 from the source code):
Code:
Key 0: B0 BF 21 C3 5C 19 A2 A1 E3 93 71 5F 4A BA F7 BD Key 1: 90 13 DA 1D 3D F3 34 F9 D5 F1 7C 31 17 25 40 AC Key 2: 3A CA 33 02 80 3E 29 F8 BD C0 21 24 B3 09 40 BC Key 3: 3A E5 B0 C1 8D 32 04 85 32 CC 7C 4C BC 87 37 22 Key 4: DA 15 85 51 1B DF 6F EC D2 30 A5 4E 85 B4 57 2E Key 5: 2E AD EA A1 96 D1 BC 7D F0 4B E0 51 DB D0 FA C0 Key 6: D5 A7 3B 9E 18 15 C4 D1 0E FD D0 BC 21 C0 86 D3 This should be all you need to implement Trap_AES for the remaining parameters now. I will probably look at parameter checking next. Good luck with your implementations! Edit: the obfuscation scheme has been broken. Below are the keys you can use with your default/plain aes implementations: Code:
key00 = 6C1AC6780E996094F04AEA2B12CCC382 key01 = B2E16A58560F8AF59E47881D037B5CDF key02 = AD08B3F2571247488B1AB975137B707B key03 = 6E8B9CF22A3F4B45E347B5FA8D0CFE74 key04 = FEBE6C124354A6D3E19E491A816CCD4D key05 = 0ED1D4E6D287A85EFEDB32386FC1A913 key06 = 3100DE1D7EFF6CD013EB84C67CBDB9E9 Last edited by Oopho2ei; 20th October 2008 at 00:36. |
24th September 2008, 01:04 | #164 | Link |
Guest
Posts: n/a
|
Debugger problems solved:
- Using "java.exe -Xms128m -Xmx768m -jar Debugger.jar" allows for loading the 150mb of pc-trace, so this problem is solved (for now without using a ringbuffer or similar). Thanks for the hint. - The INSTF instruction was not correctly implemented. I corrected this and now the debugger goes without problems past trap #2044 (I Robot)/#2029 (DAT). On another note: Great work on the AES-trap! Edit: Yet another bug in the basic VM: for DAT v1.02, at IC=37079238, PC=0x357680, instruction 0xB00DFA1C is executed. This should be "JMP 0x370A0" but is interpreted as "JMP 0x4370A0". The first is a jump backwards 0x3205E0 bytes, the second is a jump forwards 0xDFA20. 0x3205E0 is (more or less) the 2's complement of 0xDFA20. So... the current debugger's VM doesn't handle long backward jumps right. I am no bitshifter, so could someone help out? Current code: Code:
long i = IF ^ unsigned(mem32.get(pc / 4)); ... int JimmS = ((int)(i << 6)) >> 6; // Jump constant signed ... case 0x2C: pc += JimmS; break; // J Last edited by schluppo; 24th September 2008 at 03:22. |
24th September 2008, 08:20 | #165 | Link |
Guest
Posts: n/a
|
You forgot the "AND 0x3FFFFC" (see posting #24). You have to do this for every address otherwise content code can break out of your sandbox environment and potentially execute arbitrary code on your computer.
Last edited by Oopho2ei; 24th September 2008 at 08:26. |
24th September 2008, 19:00 | #166 | Link |
Guest
Posts: n/a
|
Ok, I got this fixed along with a few other bugs in the debugger's basic VM. It's staying in sync with PC till trap-call #2676 now (all the following is for DAT v1.02 - but I Robot v1.02 behaves quite similar).
The VM seems to self-check itself starting around trap-call #2000. It does some INSTF-tampering, but changes INSTF back to 0 and keeps it at 0 after a few hundred instructions. Further, it does very long / backward jumps or execute non-jump instructions at 0x003FFFFC afterwards resuming execution at 0x00000000. Around trap-call #2100, the bad parameter trap-calls are starting, such as reading from slot 0xFFFFFFFF (which does not exist) or reading (writing) from (to) memory outside of range for several traps. I fixed some of those, but some others remain to be treated. Trap-call #2676 is finally the first call of trap_0x10(0); And soon, I will upload that promised new debugger-edit and also logs of the first ~2700 trap-calls for both movies. Edit: new version of the debugger: http://uploaded.to/?id=z3gq5g, logs: http://uploaded.to/?id=71kv7r Last edited by schluppo; 24th September 2008 at 20:57. |
24th September 2008, 23:33 | #167 | Link |
Guest
Posts: n/a
|
I have pushed some documentation into our repository: http://svn.assembla.com/svn/bdplus
To checkout the repository use: Code:
svn co http://svn.assembla.com/svn/bdplus Last edited by Oopho2ei; 24th September 2008 at 23:35. |
25th September 2008, 00:54 | #168 | Link |
Guest
Posts: n/a
|
Things are getting more interesting, I modified the debugger to get past the first few calls of trap_0x10 and the consequent breaks using the break_snapshots.
Traps 0x20 (GetEvent?), 0x510 (MediaReadRequest?), TRAP_Memset (?), TRAP_AddWithCarry (?), TRAP_MemMove (?) appear. |
25th September 2008, 17:27 | #169 | Link | |
I swallow bugs!
Join Date: Jan 2007
Location: Whitehouse corner Office
Posts: 49
|
Quote:
Dam good work. Slysoft, Is still the best investment out there! |
|
25th September 2008, 17:54 | #170 | Link | |
Guest
Posts: n/a
|
Quote:
Btw it's not only me and schluppo. There are other people hiding behind my back which have so far helped me a lot. Big |
|
25th September 2008, 18:26 | #171 | Link |
Guest
Posts: n/a
|
I added parameter checking for the following traps to the debugger:
0x140 (Trap_Sha) 0x210 (Trap_AddWithCarry) 0x220 (Trap_MemSearch?) 0x230 (Trap_XorBlock) 0x310 (Trap_MemMove) 0x320 Edit: new debugger: http://uploaded.to/?id=mq66ms - Allows to load timer-trace-file (watchdog-trace). shows actual and expected watchdog-counter value. allows to manually set wd. - Added option to set post_break_snapshot directory. If watchdog reaches 0, automatically load post_break_snapshot and compare registers + memory (same as with traps). - Added break counter which is increased everytime, when post_break_snapshot needs to be loaded. - Manually set trap-counter, instruction counter and break counter. Here's an example of how to use this. I will load the machine to the state after trap-call #2676 in DAT v1.02. So, put DAT v1.02 00000.svm, 00001.svm and 00002.svm inside the dir where Debugger.jar is. Start the debugger like this: java -Xms128m -Xmx768m -jar Debugger.jar. Load DAT v1.02 00000.svm. Load DAT v1.02 pc_trace.bin, Load DAT v1.02 timer_trace.bin. Load Memory: DAT v1.02 post_trap_mem_002675.bin, Load Registers: DAT v1.02 post_trap_reg_002675.bin. Set IC to 0x2382BDA (37235674), set PC to 0x1AC00, set TC to 0xA74 (2676). Now everything is set to the state past trap-call #2676 in DAT v1.02. - Note: This debugger-edit also contains a non-working port of Oophoo's modified whitebox aes to java (functions XAES_SetKey(), XAES_Decrypt(), XAES_Block() and so on). I am no AES-expert, so I would appreciate any help in getting these non-working functions to work. Edit 2: Player key AES-decryption added to the debugger - works fine now (thanks to Oopho). Lots of small bugs fixed. Will upload new version of the debugger soon. Edit 3: Here it is: http://uploaded.to/?id=xbayxh. You can go to trap-call #3943 (DAT v1.02) / #3968 (I Robot v1.02) with PC/WD in sync. Trap-call logs up to this point: http://uploaded.to/?id=oe3azr Last edited by schluppo; 26th September 2008 at 01:02. |
26th September 2008, 15:09 | #172 | Link |
Guest
Posts: n/a
|
A few things which really need to be improved/changed:
Code:
private int trapXorBlock(int pDst, int pSrc, long len) { if ( (pDst & 0x3FFFFC) >= MEMSIZE ) return 0x80000001; ... if (((pDst & 0x3FFFFC) & 0x03) != 0 ) return 0x80000001; ... The dword,word and byte masks (0x3FFFFC, 0x3FFFFE, 0x3FFFFF) can be derived from the memory size: Code:
uint32 memsize = 0x400000; uint32 MASK_DW = (memsize - 1) & 0xFFFFFFFC; uint32 MASK_W = (memsize - 1) & 0xFFFFFFFE; uint32 MASK_B = (memsize - 1) & 0xFFFFFFFF; Finally please remove the case statement from Trap_AES and use something like: Code:
if (opOrKeyID < 0xFFF10000) { If (opOrKeyID >= player_keys_count) BUG("TRAP_0110: unavailable key accessed") // some self checks (player_keys_count is currently 7) ... ... player_key[opOrKeyID] ... ... return ... ; } if (opOrKeyID == 0xFFF10000) { ... return ... ; } if (opOrKeyID == 0xFFF10001) { ... return ... ; } // if the below statement is executed there is a bug in the parameter checking BUG("TRAP_0110: invalid opOrKeyID"); If one of the BUG("...") statements is executed the parameter checking is wrong/incomplete. Thanks for your new release. Edit: and please only use spaces to format your code (no tabs). My obfuscated aes implementation looks really messed up (another layer of obfuscation added )... Edit: added some more details to my suggestions Last edited by Oopho2ei; 26th September 2008 at 16:19. |
26th September 2008, 17:24 | #173 | Link |
Guest
Posts: n/a
|
I integrated your requests.
Furthermore, guided execution reached the end of both snap-shot packages (with PC/WD in sync). So far, the implementations of TRAP_XorBlock and TRAP_Aes behave fine for every call. Will add / fix parameter checking of other traps now. Note that there remain several problematic traps which are not treated yet, such as 0x530, 0x550, 0x120. Edit: Fixed TRAP_Random, TRAP_MemSet and TRAP_MemMove. They behave nice now for all calls (parameter checking ok too). Edit2: TRAP_AddWithCarry implemented and it behaves nicely for all calls (parameter checking ok). There's a small bug in the parameter-checking from the repository though: Code:
if ( dst + 4*len > src & dst <= src + 4*len & dst != src) return 0x80000001; (correct) vs. if ( dst + 4*len > src & dst >= src + 4*len & dst != src) return 0x80000001; (wrong) Edit 3: Trap 0x220 was in fact not TRAP_MemSearch but TRAP_MultiplyWithRipple(int pDst, int pSrc, int len, int multiplicator). It's implemented now, parameter check is ok and all calls of this trap behave nicely. Last edited by schluppo; 27th September 2008 at 10:24. |
26th September 2008, 20:48 | #174 | Link |
Guest
Posts: n/a
|
Thanks.
I have finished the documentation of the parameter check for trap groups 01XX, 02XX and 03XX: http://svn.assembla.com/svn/bdplus/t...s/param_check/ Group 04XX and 05XX will follow soon. Btw trap #0120 is almost certainly UINT32 TRAP_PrivateKey(UINT32 keyID, UINT8 *dst, UINT8 *src, UINT32 srcLen, UINT32 controlWord); |
27th September 2008, 13:46 | #175 | Link | |||
Guest
Posts: n/a
|
Quote:
Quote:
Quote:
Edit: can you make a list of possible status return codes for every call? When i write "return 0x80000001" it doesn't necessarily mean that 0x80000001 is written into r01. Edit: i am done documenting the parameter checks. The next step is TRAP_PrivateKey() Last edited by Oopho2ei; 27th September 2008 at 20:35. |
|||
27th September 2008, 22:04 | #176 | Link |
Guest
Posts: n/a
|
I added the other cases (SHA_init, SHA_finish, SHA_update) and parameter checking to TRAP_Sha. Intermediate results do not match yet, but results after SHA_finish match (patent says, intermediate results are undefined but "can be used to store data"). Apart from intermediate results, TRAP_Sha is fine for every call.
My guess for trap 0x320 is TRAP_MemSearch, will look into that soon. Edit: Here's a new version (including parameter checks for all traps, feel free to bugfix or edit it yourself ): debugger: http://uploaded.to/?id=jtslin, logs: http://uploaded.to/?id=ave7c7 Traps 0x120 and 0x530 seem to be most important to me now (since they require player-data to be emulated). The fixing of the problems with other traps (0x320, 0x140, 0x4*0, 0x520) just takes some more time to implement. Last edited by schluppo; 28th September 2008 at 05:23. |
28th September 2008, 11:57 | #177 | Link |
Guest
Posts: n/a
|
1. You should work more with our repository so it contains always the latest version. Only upload source and documentation there and no files which can be derived from the source like binaries and logfiles.
I have updated the source in the repository now. You can still upload the binaries to "uploaded.to" for a daily/weekly snapshot. 2. In my parameter checking there is no bit masking and still you use this "MASK_UNS" which masks the most significant bit. All the checks should work perfectly as they are. If they don't please report the problem and we will see how to fix it. 3. You should store the player keys in an array of arrays so you can access them like this OBF_PLAYER_KEY[opOrKeyID] together with a range check. Code:
if (((int)opOrKeyID) == 0x00000000){ return(obfAES(OBF_PLAYER_KEY0,pDst,pSrc,len,pKey)); } if (((int)opOrKeyID) == 0x00000001){ return(obfAES(OBF_PLAYER_KEY1,pDst,pSrc,len,pKey)); } if (((int)opOrKeyID) == 0x00000002){ return(obfAES(OBF_PLAYER_KEY2,pDst,pSrc,len,pKey)); } if (((int)opOrKeyID) == 0x00000003){ return(obfAES(OBF_PLAYER_KEY3,pDst,pSrc,len,pKey)); } if (((int)opOrKeyID) == 0x00000004){ return(obfAES(OBF_PLAYER_KEY4,pDst,pSrc,len,pKey)); } if (((int)opOrKeyID) == 0x00000005){ return(obfAES(OBF_PLAYER_KEY5,pDst,pSrc,len,pKey)); } if (((int)opOrKeyID) == 0x00000006){ return(obfAES(OBF_PLAYER_KEY6,pDst,pSrc,len,pKey)); } 4. I would like to see a separate file for each of those: - instruction processing - decoding of cmd39, parameter fetching, parameter checking, return code interpretation - trap implementations - obfuscated aes implementation and player keys So the code looks well structured and we don't squeeze everything into BDVM.java which will grow larger over time. I am working on TRAP_PrivateKey() (#0120) Last edited by Oopho2ei; 28th September 2008 at 12:18. |
28th September 2008, 16:20 | #178 | Link |
Guest
Posts: n/a
|
For the first call of UINT32 TRAP_PrivateKey(UINT32 keyID, UINT8 *dst, UINT8 *src, UINT32 srcLen, UINT32 controlWord) in dat with parameters:
Code:
keyID = 00000000 dst = 00005514 src = 00002348 srcLen = 00000010 controlWord = 00000000 Code:
42 44 53 56 4d 5f 50 4b 00 00 00 00 00 00 00 10 <-- header "BDSVM_PK".... 35 52 B5 2A F2 7D BA 60 97 93 9C 66 5F 5C 84 F3 <-- 16 byte from src Code:
b99b5c49 af55cb7e 9b1e7d90 6846d720 2b9c2908 *sha_in.bin Edit: I have modified the example so it matches the DAT v1.02 snapshots. Last edited by Oopho2ei; 3rd October 2008 at 10:51. |
28th September 2008, 17:57 | #179 | Link |
Guest
Posts: n/a
|
1. Will do.
2. There were a few bugs in your parameter checking (usually mixup of '<' and '>' or '>=' instead of '>' etc.). I fixed those that came to my eyes. Some are still left - see the logs. And concerning MASK_UNS: Java interprets integers as signed numbers. So when doing this: Code:
int bla = 0xFFFFFFFF; if (bla>0x10) return 0x80000001; return 0; 3. Done 4. Will do so, if I find the time. On another note: What you said so far about TRAP_PrivateKey can easily be coded |
28th September 2008, 19:50 | #180 | Link | ||
Guest
Posts: n/a
|
Quote:
Quote:
I have hit heavy obfuscation. It almost looks like the rsa procedure is executed on another virtual machine with a lot of garbage code. This will take some time... |
||
|
|