Skip to content

Commit bff990c

Browse files
committed
Parse DVD ROM for Region info
1 parent a97e8fb commit bff990c

File tree

2 files changed

+31
-12
lines changed

2 files changed

+31
-12
lines changed

README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
A tool to dump the DVD player executable from the DVD playback kit.
1+
A tool to dump the ROM of the Xbox DVD Movie Playback Kit dongle.
2+
3+
The ROM is prefixed with version information and the length of the contained XBE.
4+
The XBE certificate region is the allowed DVD playback region.
5+
The section of the XBE is compressed using LZX, 128kiB window size, 32kiB blocks.

main.py

+26-11
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,57 @@
55
import usb1
66
import struct
77

8-
BUFFER_SIZE = 200
9-
108
with usb1.USBContext() as context:
119

1210
vid = 0x045e
1311
pid = 0x0284
14-
INTERFACE = 1
12+
interface = 1
1513

1614
handle = context.openByVendorIDAndProductID(vid, pid, skip_on_error=True)
1715
if handle is None:
1816
# Device not present, or user is not allowed to access device.
1917
print("oops?!")
2018

2119
rom_info = 1
22-
info = handle.controlRead(usb1.REQUEST_TYPE_VENDOR | usb1.RECIPIENT_INTERFACE, rom_info, 0, INTERFACE, 6)
20+
info = handle.controlRead(usb1.REQUEST_TYPE_VENDOR | usb1.RECIPIENT_INTERFACE, rom_info, 0, interface, 6)
2321

2422
(version, code_length) = struct.unpack("<HI", info)
25-
print("version %X.%X" % (version >> 8, version & 0xFF))
26-
print(str(code_length - 6) + " bytes")
23+
print("Version: %X.%X" % (version >> 8, version & 0xFF))
24+
print("Size: " + str(code_length) + " bytes")
2725

28-
with open('default.xbe', 'wb') as f:
26+
with open("dvd-dongle-rom.bin", 'wb') as f:
2927

3028
rom_download = 2
3129
remaining = code_length
3230
cursor = 0
31+
32+
xbe = bytes([])
33+
3334
while(remaining > 0):
3435
chunkSize = min(remaining, 1024)
35-
data = handle.controlRead(usb1.REQUEST_TYPE_VENDOR | usb1.RECIPIENT_INTERFACE, rom_download, cursor >> 10, INTERFACE, chunkSize)
36+
data = handle.controlRead(usb1.REQUEST_TYPE_VENDOR | usb1.RECIPIENT_INTERFACE, rom_download, cursor >> 10, interface, chunkSize)
3637
assert(chunkSize == len(data))
3738
# The first block contains a copy of the (version, code_length)
3839
if cursor == 0:
3940
assert(data[0:6] == info)
40-
data = data[6:]
41+
xbe += data[6:]
42+
else:
43+
xbe += data
4144
f.write(data)
4245
remaining -= chunkSize
4346
cursor += chunkSize
4447

45-
46-
48+
# Do some sanity checks and print out DVD region
49+
50+
BaseAddress = struct.unpack('I', xbe[260:264])[0]
51+
Certificate = struct.unpack('I', xbe[280:284])[0] - BaseAddress
52+
SectionHeaders = struct.unpack('I', xbe[288:292])[0] - BaseAddress
53+
SizeOfImage = struct.unpack('I', xbe[268:272])[0]
54+
assert((6 + SizeOfImage) == code_length) # SizeOfImage
55+
assert(struct.unpack('I', xbe[Certificate+156:Certificate+160])[0] == 0x00000100) # AllowedMediaTypes == DONGLE
56+
assert(struct.unpack('I', xbe[Certificate+172:Certificate+176])[0] == version) # Version
57+
RawData = struct.unpack('I', xbe[SectionHeaders+12:SectionHeaders+16])[0]
58+
SizeOfRawData = struct.unpack('I', xbe[SectionHeaders+16:SectionHeaders+20])[0]
59+
assert(RawData + SizeOfRawData == SizeOfImage)
60+
GameRegion = struct.unpack('I', xbe[Certificate+160:Certificate+164])[0]
61+
print("Region: " + str(GameRegion))

0 commit comments

Comments
 (0)