|
5 | 5 | import usb1
|
6 | 6 | import struct
|
7 | 7 |
|
8 |
| -BUFFER_SIZE = 200 |
9 |
| - |
10 | 8 | with usb1.USBContext() as context:
|
11 | 9 |
|
12 | 10 | vid = 0x045e
|
13 | 11 | pid = 0x0284
|
14 |
| - INTERFACE = 1 |
| 12 | + interface = 1 |
15 | 13 |
|
16 | 14 | handle = context.openByVendorIDAndProductID(vid, pid, skip_on_error=True)
|
17 | 15 | if handle is None:
|
18 | 16 | # Device not present, or user is not allowed to access device.
|
19 | 17 | print("oops?!")
|
20 | 18 |
|
21 | 19 | 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) |
23 | 21 |
|
24 | 22 | (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") |
27 | 25 |
|
28 |
| - with open('default.xbe', 'wb') as f: |
| 26 | + with open("dvd-dongle-rom.bin", 'wb') as f: |
29 | 27 |
|
30 | 28 | rom_download = 2
|
31 | 29 | remaining = code_length
|
32 | 30 | cursor = 0
|
| 31 | + |
| 32 | + xbe = bytes([]) |
| 33 | + |
33 | 34 | while(remaining > 0):
|
34 | 35 | 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) |
36 | 37 | assert(chunkSize == len(data))
|
37 | 38 | # The first block contains a copy of the (version, code_length)
|
38 | 39 | if cursor == 0:
|
39 | 40 | assert(data[0:6] == info)
|
40 |
| - data = data[6:] |
| 41 | + xbe += data[6:] |
| 42 | + else: |
| 43 | + xbe += data |
41 | 44 | f.write(data)
|
42 | 45 | remaining -= chunkSize
|
43 | 46 | cursor += chunkSize
|
44 | 47 |
|
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