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. |
![]() |
#1 | Link |
Registered User
Join Date: Jun 2007
Posts: 95
|
Finally handling BD+ (?)
Now that MKBv7 is public I think it's time to concentrate on BD+. I can't imagine that SlySoft is the only one to manage that protection. So how do they do it? Magic? I don't think so! And obviously they didn't reverse engineer PowerDVD - this was the third time that AnyDVD handles BD+ but PowerDVD can't. PowerDVD users had to wait for an update. So, did they kill a player? Could be easier. Did anyone ever tried something like this? What's the current status of BD+?
Let's wind up and find a strategy. How can hardware players help? Has anyone any information about BD+ (beside that marketing crap from Macrovision)? Only productive posts welcome. |
![]() |
![]() |
![]() |
#2 | Link |
Guest
Posts: n/a
|
Could be an implementation problem in powerdvd. For example you could accidentally do if (some_array[123] == 0x01) {...} and some_array is an array of integers (32 bit). You were supposed to compare one BYTE of the array and not 4. As long as there are enough zeros following the 01 you will never notice the bug. For some discs that is not true so they fail to playback because of that bug. Normally you will notice such mistakes when you reverse engineer the code.
Is there a list of BD+ discs so i could choose which one to buy? ![]() Edit: here are some: 28 Days Later 28 Weeks Later August Rush Cast Away Dan in Real Life Die Hard 1-4 Dogma Fantastic 4 ROSS From Hell (Region A) Gattaca Hitman I Robot Independence Day Man on Fire Master and Commander Mr & Mrs Smith Mr Brooks No Country For Old Men Rescue Dawn Robocop Ronin Sleuth Sunshine The Day After Tomorrow The Simpsons Movie and almost all recent releases: http://bluray.highdefdigest.com/rele...istorical.html Last edited by Oopho2ei; 24th August 2008 at 15:36. |
![]() |
![]() |
#3 | Link |
Registered User
Join Date: Jun 2007
Posts: 95
|
I doubt that PowerDVD can implement their own BD+ code - they surely get a library from Macrovision. Closed source. Everything else would be extremely stupid. So the bug is in Macrovision's library. That would encourage my opinion that SlySoft has something in the loop with hardware players.
Last edited by gioowe; 24th August 2008 at 17:06. |
![]() |
![]() |
![]() |
#4 | Link | |
SlySoft Team Member
Join Date: May 2007
Posts: 173
|
Quote:
![]()
__________________
SlySoft Inc. |
|
![]() |
![]() |
![]() |
#5 | Link | |
Guest
Posts: n/a
|
Quote:
|
|
![]() |
![]() |
#6 | Link | |
Registered User
Join Date: Jun 2007
Posts: 95
|
Quote:
Anyway, if AnyDVD can play all BD+ and PowerDVD requires an update - that's something very, very interesting. |
|
![]() |
![]() |
![]() |
#8 | Link |
Guest
Posts: n/a
|
I am guessing he means that because bd+ enforces a certain memory footprint (e.g. keys, video etc have to be at a certain fix virtual memory address) he can use a memory dump of the virtual machine interpreter and include it in anydvd as precompiled code module. He would only have to make sure the remaining data vm opcode/keys/video content is at the correct address.
|
![]() |
![]() |
#9 | Link | |
SlySoft Team Member
Join Date: May 2007
Posts: 173
|
Quote:
![]() Actually you'd have to know how BD+ really works, to know what I meant (and even then you probably wouldn't ). But if I start unraveling that, I'd be finding myself looking for a new job by next week ![]() So, I'll better shut up from this point on - should have done that in the first place, sorry... ![]()
__________________
SlySoft Inc. |
|
![]() |
![]() |
![]() |
#10 | Link | |
Registered User
Join Date: Jun 2007
Posts: 95
|
Quote:
|
|
![]() |
![]() |
![]() |
#11 | Link | |||
Guest
Posts: n/a
|
Quote:
Quote:
Quote:
Last edited by Oopho2ei; 25th August 2008 at 08:13. |
|||
![]() |
![]() |
#12 | Link | |
Guest
Posts: n/a
|
I made some notes of what i was able to find out about BD+ browsing the web. Maybe this helps to clear things up and avoid misunderstandings:
Quote:
Last edited by Oopho2ei; 24th August 2008 at 20:33. |
|
![]() |
![]() |
#13 | Link |
Guest
Posts: n/a
|
I have had a look at the difference of the output of dumphd and anydvd for a bd+ movie. Using vbindiff i compared the 00001.m2ts:
Code:
- 072D4764: C3 7C 9C 9C 95 + 072D4764: AA 2D 40 8E 4A - 072D85F1: 0A 0E BC E9 99 + 072D85F1: 4D EF 4B 6B E5 - 0736ED6A: FB 51 33 7A 48 + 0736ED6A: B6 F7 78 EC CB - 0736FA18: 2F 03 43 31 2E + 0736FA18: 7E 61 A3 C6 C1 - 073C83B4: EC E9 4D A4 39 + 073C83B4: 06 F3 AA 7C 59 ... |
![]() |
![]() |
#14 | Link |
Registered User
Join Date: Aug 2007
Posts: 17
|
Is there a certain file on bd+ discs that contains the bd+ code? How does the vm in hw/sw player extract the information that the disc requires to play?
Edit: found better explanations for the vm: http://securityevaluators.com/pdf/spdc_aacs_2005.pdf http://appft1.uspto.gov/netacgi/nph-...DN/20070033419 That last one is a gold mine of information about the vm instructions used. Wish I had a bd+ disc to test with. Last edited by chavonbravo; 26th August 2008 at 06:25. |
![]() |
![]() |
![]() |
#15 | Link | |
Registered User
Join Date: Sep 2004
Location: Near LA, California, USA
Posts: 1,545
|
Quote:
![]()
__________________
Pirate: Now how would you like to die? Would you like to have your head chopped off or be burned at the stake? Curly: Burned at the stake! Moe: Why? Curly: A hot steak is always better than a cold chop. |
|
![]() |
![]() |
![]() |
#16 | Link | ||
Guest
Posts: n/a
|
Quote:
Quote:
After the long header the data looks very random. So it is possibly encrypted (with the media key mabe?). I currently try to figure this out. Well if you know the instruction set you can simply attach a compatible debugger to her brain when she misbehaves to see what is going on in her mind. ![]() ![]() Btw the DLX processor architecture is very primitive. Usually it is being used in university to demonstrate some basic principles of processor architecture as vhdl/verilog code. Last edited by Oopho2ei; 26th August 2008 at 19:00. |
||
![]() |
![]() |
#17 | Link |
Guest
Posts: n/a
|
A note about the files stored in the BDSVM directory: 00000.svm, 00001.svm and 00002.svm. They all have a size of exactly 20MB and each file consists of exactly 10 sections. Every section has the same size of 2MB.
The first section starts with: Code:
0000:0000 42 44 53 56 4d 5f 43 43 01 00 00 00 01 07 d7 0b 0000:0010 06 00 00 00 00 07 ec e4 Code:
b3 ff ff fc 00 00 ... lots of zeros .. some data ... zeros Code:
XXX0:0010 42 44 53 56 4d 5f 43 43 01 00 00 00 01 07 d7 0b XXX0:0010 06 00 00 00 00 1f ff c0 The beginning of the last file (00002.svm) has a visible pattern (vector table?): Code:
0000:0000 42 44 53 56 4d 5f 43 43 01 00 00 00 01 07 d7 0b 0000:0010 06 00 00 00 00 1f ff c0 00 24 00 00 00 01 01 53 0000:0020 00 00 05 54 00 00 05 58 00 00 0f 84 00 00 1f c8 0000:0030 00 00 2e 54 00 00 3c f4 00 00 4b 94 00 00 59 80 0000:0040 00 00 69 4c 00 00 78 c8 00 00 84 ac 00 00 91 1c 0000:0050 00 00 9c ec 00 00 a8 80 00 00 b4 3c 00 00 c0 5c 0000:0060 00 00 cc 40 00 00 d7 20 00 00 e2 b4 00 00 ee 84 0000:0070 00 00 f8 24 00 01 02 28 00 01 0e e8 00 01 1c c0 0000:0080 00 01 29 44 00 01 35 00 00 01 40 bc 00 01 4c c8 0000:0090 00 01 5a 78 00 01 66 48 00 01 72 cc 00 01 7f 28 0000:00a0 00 01 8a 80 00 01 95 38 00 01 a2 0c 00 01 ae 68 0000:00b0 00 01 bc 2c 00 01 ca 68 00 01 d7 dc 00 01 e4 10 0000:00c0 00 01 f1 70 00 01 fe 1c 00 02 0a 78 00 02 17 38 0000:00d0 00 02 24 20 00 02 32 34 00 02 3d 78 00 02 49 fc 0000:00e0 00 02 56 6c 00 02 60 ac 00 02 6b f0 00 02 79 28 0000:00f0 00 02 85 70 00 02 92 6c 00 02 9f 18 00 02 ac f0 0000:0100 00 02 b9 74 00 02 c5 58 00 02 d1 00 00 02 da 14 0000:0110 00 02 e5 bc 00 02 ef c0 00 02 fb 40 00 03 05 08 0000:0120 00 03 13 94 00 03 20 68 00 03 2b ac 00 03 36 8c 0000:0130 00 03 45 7c 00 03 52 14 00 03 5f 24 00 03 6a e0 0000:0140 00 03 77 f0 00 03 86 7c 00 03 93 78 00 03 9f 0c 0000:0150 00 03 ad 34 00 03 b8 3c 00 03 c3 1c 00 03 cc bc 0000:0160 00 03 da a8 00 03 e4 48 00 03 ed e8 00 03 f9 68 0000:0170 00 04 08 d0 00 04 15 04 00 04 20 ac 00 04 2d 30 0000:0180 00 04 37 d4 00 04 44 6c 00 04 50 dc 00 04 5e 28 0000:0190 00 04 6c 8c 00 04 7a dc 00 04 88 c8 00 04 94 5c 0000:01a0 00 04 a0 2c 00 04 ac 24 00 04 b7 f4 00 04 c2 70 0000:01b0 00 04 ce e0 00 04 da d8 00 04 e8 74 00 04 f5 d4 0000:01c0 00 05 01 e0 00 05 0f 40 00 05 1c 28 00 05 26 90 0000:01d0 00 05 31 c0 00 05 3d 7c 00 05 49 c4 00 05 56 c0 0000:01e0 00 05 61 dc 00 05 6d 84 00 05 7b fc 00 05 86 a0 0000:01f0 00 05 93 38 00 05 9d 8c 00 05 a8 e4 00 05 b2 d4 0000:0200 00 05 bf 30 00 05 cb 50 00 05 d6 1c 00 05 df 80 0000:0210 00 05 ea 10 00 05 f7 84 00 06 02 3c 00 06 0f 88 0000:0220 00 06 1c 84 00 06 26 b0 00 06 32 6c 00 06 3e c8 0000:0230 00 06 4d cc 00 06 5b 54 00 06 68 a0 00 06 73 08 0000:0240 00 06 7d c0 00 06 89 18 00 06 94 20 00 06 9d d4 0000:0250 00 06 a9 90 00 06 b3 08 00 06 bd 5c 00 06 c8 78 ... Edit: If your section headers look different please post them! ![]() Last edited by Oopho2ei; 26th August 2008 at 22:17. |
![]() |
![]() |
#19 | Link |
Guest
Posts: n/a
|
I have looked at section 2 of 000001.svm. It is decrypted with some sort of stream cipher. I have uploaded the first 64 kb of the decrypted section payload (skipping the 0x17 header bytes): http://uploaded.to/?id=59db0f
Note that the byte order for every dword has be reversed before application (xor) of the bitstream from the stream cipher (big endian <--> little endian conversion). So Code:
0000:0000 c4 4e e6 65 00 01 00 00 02 00 00 00 Code:
0000:0000 65 e6 4e c4 00 00 01 00 00 00 00 02 Last edited by Oopho2ei; 27th August 2008 at 23:16. |
![]() |
![]() |
#20 | Link |
Guest
Posts: n/a
|
The VM is at least involved (if not doing it all alone) in the decryption of those sections.
An typical instruction I (32 bit) is decoded like that: Code:
Instruction I: C R[X], R[Y], R[Z] C = I >> 0x1A X = ((I >> 0x13) & 0x7C) >> 2 Y = ((I >> 0x0E) & 0x7C) >> 2 Z = ((I >> 0x09) & 0x7C) >> 2 The machine: - 32 registers each 32 bit long - probably big endian - 4MB address space (first 128 bytes are register?) instruction/command decoding: Code:
cmd00: NOP cmd01: ADD R[X],R[Y],R[Z] -> R[X] = R[Y] + R[Z] cmd02: SUB R[X],R[Y],R[Z] -> R[X] = R[Y] - R[Z] cmd03: MUL R[X],R[Y],R[Z] -> R[X] = R[Y] * R[Z] cmd04: IDIV R[X],R[Y],R[Z] -> R[X] = unsigned(R[Y]) / R[Z] cmd05: DIV R[X],R[Y],R[Z] -> R[X] = signed(R[Y]) / R[Z] cmd06: SHL R[X],R[Y],R[Z] -> R[X] = R[Y] << (R[Z] & 0x1F) cmd07: SHR R[X],R[Y],R[Z] -> R[X] = R[Y] >> (R[Z] & 0x1F) cmd08: SAR R[X],R[Y],R[Z] -> R[X] = signed(R[Y]) >> (R[Z] & 0x1F) cmd09: AND R[X],R[Y],R[Z] -> R[X] = R[Y] & R[Z] cmd0A: OR R[X],R[Y],R[Z] -> R[X] = R[Y] | R[Z] cmd0B: XOR R[X],R[Y],R[Z] -> R[X] = R[Y] ^ R[Z] cmd0C: EQU R[X],R[Y],R[Z] -> if (R[Y] == R[Z]) R[X] = 1 else R[X] = 0 cmd0D: NEQU R[X],R[Y],R[Z] -> if (R[Y] != R[Z]) R[X] = 1 else R[X] = 0 cmd0E: LESS R[X],R[Y],R[Z] -> if (signed(R[Y]) < signed(R[Z])) R[X] = 1 else R[X] = 0 cmd0F: BLW R[X],R[Y],R[Z] -> if (unsigned(R[Y]) < unsigned(R[Z])) R[X] = 1 else R[X] = 0 cmd10: GRE R[X],R[Y],R[Z] -> if (signed(R[Y]) > signed(R[Z])) R[X] = 1 else R[X] = 0 cmd11: ABV R[X],R[Y],R[Z] -> if (unsigned(R[Y]) > unsigned(R[Z])) R[X] = 1 else R[X] = 0 cmd12: LEQ R[X],R[Y],R[Z] -> if (signed(R[Y]) <= signed(R[Z])) R[X] = 1 else R[X] = 0 cmd13: BEQ R[X],R[Y],R[Z] -> if (unsigned(R[Y]) <= unsigned(R[Z])) R[X] = 1 else R[X] = 0 cmd14: GEQ R[X],R[Y],R[Z] -> if (signed(R[Y]) >= signed(R[Z])) R[X] = 1 else R[X] = 0 cmd15: AEQ R[X],R[Y],R[Z] -> if (unsigned(R[Y]) >= unsigned(R[Z])) R[X] = 1 else R[X] = 0 cmd16: JMP R[Y] -> PC = R[Y] cmd17: CALL R[Y] -> R[0x1F] = PC; PC = R[Y] cmd18: ADDE R[X],R[Y],C -> C = sign_extend(I & 0xFFFF); R[X] := R[Y] + C cmd19: ADD R[X],R[Y],C -> C = I & 0xFFFF; R[X] := R[Y] + C cmd1A: SUBE R[X],R[Y],C -> C = sign_extend(I & 0xFFFF); R[X] := R[Y] - C cmd1B: SUB R[X],R[Y],C -> C = I & 0xFFFF; R[X] := R[Y] - C cmd1C: SHL R[X],R[Y],C -> C = I & 0x1F; R[X] = unsigned(R[Y]) << C cmd1D: SHR R[X],R[Y],C -> C = I & 0x1F; R[X] = unsigned(R[Y]) >> C cmd1E: SAR R[X],R[Y],C -> C = I & 0x1F; R[X] = signed(R[Y]) >> C cmd1F: AND R[X],R[Y],C -> C = I & 0xFFFF; R[X] = R[Y] & C cmd20: OR R[X],R[Y],C -> C = I & 0xFFFF; R[X] := R[Y] | C cmd21: XOR R[X],R[Y],C -> C = I & 0xFFFF; R[X] := R[Y] ^ C cmd22: EQU R[X],R[Y],C -> C = sign_extend(I & 0xFFFF); if (R[Y] == C) R[X] = 1 else R[X] = 0 cmd23: NEQU R[X],R[Y],C -> C = sign_extend(I & 0xFFFF); if (R[Y] != C) R[X] = 1 else R[X] = 0 cmd24: GRE R[X],R[Y],C -> C = sign_extend(I & 0xFFFF); if (signed(C) > signed(R[Y])) R[X] = 1 else R[X] = 0 cmd25: ABV R[X],R[Y],C -> C = I & 0xFFFF; if (unsigned(C) > unsigned(R[Y])) R[X] = 1 else R[X] = 0 cmd26: LESS R[X],R[Y],C -> C = sign_extend(I & 0xFFFF); if (signed(C) < signed(R[Y])) R[X] = 1 else R[X] = 0 cmd27: BLW R[X],R[Y],C -> C = I & 0xFFFF; if (unsigned(t0) < unsigned(R[Y])) R[X] = 1 else R[X] = 0 cmd28: GEQ R[X],R[Y],C -> C = sign_extend(I & 0xFFFF); if (signed(C) >= signed(R[Y])) R[X] = 1 else R[X] = 0 cmd29: AEQ R[X],R[Y],C -> C = I & 0xFFFF; if (unsigned(C) >= unsigned(R[Y])) R[X] = 1 else R[X] = 0 cmd2A: LEQ R[X],R[Y],C -> C = sign_extend(I & 0xFFFF); if (signed(C) <= signed(R[Y])) R[X] = 1 else R[X] = 0 cmd2B: BEQ R[X],R[Y],C -> C = I & 0xFFFF; if (unsigned(C) <= unsigned(R[Y])) R[X] = 1 else R[X] = 0 cmd2C: JMP C -> C = PC + signed(unsigned(I) << 6) >> 6; PC = C cmd2D: CALL C -> C = PC + signed(unsigned(I) << 6) >> 6; R[0x1F] = PC; PC = C cmd2E: JZ R[Y], C -> C = PC + sign_extend(I & 0xFFFF); if (R[Y] == 0) PC = C cmd2F: JNZ R[Y], C -> C = PC + sign_extend(I & 0xFFFF); if (R[Y] != 0) PC = C cmd30: STR R[X] -> R[X] = I << 0x10 cmd31: LBSE R[X],R[Y] -> R[X] = sign_extended(mem[((R[Y] + sign_extended(I & 0xFFFF)) & 0x3FFFFF) ^ 0x03] & 0xFF) cmd32: LB R[X],R[Y] -> R[X] = mem[((R[Y] + sign_extended(I & 0xFFFF)) & 0x3FFFFF) ^ 0x03] & 0xFF cmd33: LWSE R[X],R[Y] -> R[X] = sign_extended(mem[((R[Y] + sign_extended(I & 0xFFFF)) & 0x3FFFFE) ^ 0x02] & 0xFFFF) cmd34: LW R[X],R[Y] -> R[X] = mem[((R[Y] + sign_extended(I & 0xFFFF)) & 0x3FFFFE) ^ 0x02] & 0xFFFF) cmd35: LDW R[X],R[Y] -> R[X] = mem[(R[Y] + sign_extended(I & 0xFFFF)) & 0x3FFFFC] cmd36: MOVB R[X],[R[Y]+C] -> C = sign_extended(I & 0xFFFF); mem[((R[Y]+C) & 0x3FFFFF) ^ 0x03] = (unsigned char) R[X] cmd37: MOVW R[X],[R[Y]+C] -> C = sign_extended(I & 0xFFFF); mem[((R[Y]+C) & 0x3FFFFE) ^ 0x02] = (unsigned int16) R[X] cmd38: MOVDW R[X],[R[Y]+C] -> C = sign_extended(I & 0xFFFF); mem[(R[Y]+C) & 0x3FFFFC] = (unsigned int32) R[X] cmd39: TRAP C -> trap[immediate] cmd3A: SWDC R[Y] -> watch_cat_counter = R[Y]; cmd3B-cmd3F: NOP PC = program counter C = a constant (part of instruction word) I = the instruction word (uint32) watchcat_counter = some counter which is set by cmd3A and decremented by every instruction by a command specific value. As long as the counter is > 0 program execution continues. mem[] = the virtual machine memory R[X] = register number X (uint32 R[32]) sign_extend(V) = MSB(V) ? 0xFFFF0000 | V : V; MSB() = get the most significant bit signed() = make it a signed integer (int32) unsigned() = make it an unsigned integer (uint32) Note that by the time the command handler is called the program counter (pc) has already been incremented by 4 (pointing at the next instruction). It would be great if someone could start implementing the command interpreter (open source please). Please feel free to ask for more details. I will post the purpose of the remaining commands soon. Last edited by Oopho2ei; 3rd September 2008 at 17:38. Reason: added some commands; fixed some mistakes; |
![]() |
![]() |
Thread Tools | Search this Thread |
Display Modes | |
|
|