-
Notifications
You must be signed in to change notification settings - Fork 30
/
README.technical
234 lines (186 loc) · 12.2 KB
/
README.technical
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
FriiDump Techincal info
===============================================================================
This document is a reworking and unification of information found all over the
net, regarding the structure of Nintendo Gamecube/Wii Optical Discs and how to
read them on an ordinary DVD-ROM drive. All the due credits can be found in the
AUTHORS file.
===============================================================================
Nintendo Gamecube/Wii Optical Disc (GOD/WOD) structure
===============================================================================
In order to understand how a Gamecube or WII Optical Disk is made, let us
first take a look at a standard DVD-ROM. The complete standard is explained in
the ECMA-267 Standard.
The user data stored on the DVD is divided in blocks, each 2048 bytes long.
Each 2048-byte block is then encapsulated in a 2064-byte structure, adding some
other data needed for error-correction and head positioning. A 2064-byte block
is called a "Data frame", and its logical layout is as follows:
4bytes 2bytes 6bytes 2048bytes 4bytes
- - - - - - - - - - - - - - - - - - - - - - - - - -
| ID | IED | CPR_MAI | User Data Frame | EDC |
- - - - - - - - - - - - - - - - - - - - - - - - - -
- Identification Data (ID): Contains the PSN (Physical Sector Number), info
about the sector itself, like the layer, reflectivity, zone, etc.
- ID Error Detection Code (IED)
- Copyright Management Information (CPR_MAI): Its use is application-specific,
for instance it can be used to store a sector key in videos that use CSS, or
a scrambling key in the XBox and XBox360 Security Sectors.
- User Data: This is the data available for the end user.
- Error Detection Code (EDC): It is the checksum data for all the fields above,
its polinomial is x^32 + x^31 + x^4 + 1.
For various reasons (not related to copy protection), the User Data Frame is
XOR'ed with a stream cipher generated by an 15bits LFSR (Linear Feedback Shift
Register), with bits 10 and 14 used as taps. The seeds are obtained from a
table of the ECMA-267 standard, the index of the seed is the 4 MSB of the last
byte of the "ID" field of the Data Frame. The same stream cipher is then used
by 16 consecutive Data Frames: for this and other reasons (again related to
error correction), data from the DVD are always read in 16-data frame blocks.
4bytes 2bytes 6bytes 2048bytes 4bytes
- - - - - - - - - - - - - - - - - - - - - - - - - -
| ID | IED | CPR_MAI | User Data Frame | EDC |
- - - - - - - - - - - - - - - - - - - - - - - - - -
^ | 2048bytes cipher stream |
^ - - - - - - - - - -
Scrambling
seed index
Now, the first problem when dealing with Gamecube/Wii Optical Discs is that
they use a different (and yet unknown) set of seeds. This means that when an
ordinary DVD-ROM drive tries to read a GOD/WOD disc, it will unscramble the
User Data Frame with the wrong seed, causing the EDC check to fail and a read
error to be reported to the operating system, which means the inability to read
the disc.
Furthermore, Gamecube/Wii Optical Disks use a slightly different structure for
the Data Frame, as shown in the following figure:
4bytes 2bytes 2048bytes 6bytes 4bytes
- - - - - - - - - - - - - - - - - - - - - - - - - -
| ID | IED | User Data Frame | CPR_MAI | EDC |
- - - - - - - - - - - - - - - - - - - - - - - - - -
| 2048bytes cipher stream |
- - - - - - - - - -
Basically, the User Data Frame and the CPR_MAI fields are swapped, while the
scrambled bytes remain the same.
===============================================================================
Tricks used to read a GOD/WOD on a standard DVD-ROM drive.
===============================================================================
To cope with the above-mentioned problems, some methods have been suggested by
many people on the net. They vary in performance, but the basic idea is always
the same:
1. Issue a read command for the sector of interest (this is actually a
16-sector block, not a single sector, as stated above).
2. Let the read return failure.
3. At this moment, the DVD-ROM drive must have cached the data read from the
disc somewhere in its internal memory, to be able to unscramble them and to
check the EDC. So, we can dump the data from the drive's internal RAM.
Unfortunately, this is not as easy as it seems, due to the fact that there is
no standard "Dump drive memory" command. This is probably implemented in many
drives for firmware debugging purposes, but, as such, it is a vendor-specific
command, which are usually undocumented and vary from vendor to vendor (or even
from drive model to drive model).
This is where the work that many hackers around the world have done, in order
to crack the Microsoft XBox360 console, becomes useful. They needed some way to
read and write data to the XBox360 drive's internal memory, so they
disassembled the drive's firmware and patiently tried to understand what each
of the vendor-specific commands did. This way, they discovered that a certain
command could be used to read an arbitrary portion of the drive's internal RAM.
They also managed to map the RAM addresses, so that it is known where data
read from the disc are temporarily stored.
Fortunately, the XBox360 drive is not too different from some retail DVD-ROM
drives, namely some models from LG, which means that the discovered command
works on them as well. Hence, we now have some sort of access to the disc data.
Although, this comes at the price of speed: dumping the drive's internal memory
is a slow process, as it uses Programmed I/O (PIO) instead of Direct Memory
Access (DMA) to transfer data from the drive to the computer's memory. For this
reason, some have proposed the use of the "streaming read" command: it is a
standard command thought for those applications where the constant flow of data
is more important than its absolute correctness, such as audio or video
applications. Thus, this command does not perform the EDC on the data read from
the disc, but returns it immediately. Anyway, the command will only return the
User Data Frame, which means that only a portion of the data will be read this
way, while the rest (i.e.: the first 12 and the last 4 bytes) will have to be
read using the memory dump method. Nevertheless, this combined method will be
faster overall, as only some dozens of bytes have to be transfered through PIO,
instead of the whole sectors.
We still have to cope with the unknown seeds. This problem can be easily solved
through the use of brute force: as there are only 15 bits to try (and commonly
only 17 seeds per GOD/WOD), this approach only takes about 30 seconds. The
bruteforce process is very simple: the LFSR is seeded from 0 to 7FFFh and for
each seed the corresponding stream cipher is generated and XOR'ed with the
proper section of the Data Frame and the EDC is computed. If the EDC is the same
as the one in the EDC field then we have the correct seed.
===============================================================================
The FriiDump approach
===============================================================================
FriiDump can use four different disc dump methods. They have been developed
gradually, empirically and heuristically, by experimenting with the PLScsi tool
and comparing the retrieved data with a known-good dump. In this section the
inner working of every dump method will be described. The code implementing the
different methods can be found in the "disc_read_sector_X" functions of disc.c.
Please note that the desibed behaviour is that of my LG GDR8164B drive, which I
assume to be shared by similar drives. Other, more different drives, might
behave differently and require totally different methods.
Also note that all of the methods read 16-sector blocks.
Method 1
This method is very slow. So slow that I have never dumped a whole disc with
it. Although, it served me to prove that I was going in the right direction and
that my efforts could eventually come to a working end. It also showed me that
the first versions of RawDump create bad dumps, sometimes.
Basically this method is the same used by those early versions of RawDump,
which took 50+ hours to dump a whole disc. It works like this:
1. Issue a read command for the required sector. This will cause the 16-sector
block to which the sector belongs to be placed at the beginning of the
drive's cache memory. Do not even bother to see what the read command
returns, as it will surely be a data read error.
2. Dump the 16-sector block.
Method 2
Method 2 is similar to method 1, but uses the above-mentioned "streaming read"
method, which somehow allows us to dump 5 blocks at a time.
1. Issue a "streaming read" command for the required sector. This will cause
the 16-sector block to which the sector belongs to be placed at the
beginning of the drive's cache memory, together with the 4 following
16-sector blocks. Do not bother to see what the read command returns.
2. Dump the 5 16-sector blocks.
Method 3
This is similar to the previous method, but instead of dumping the whole
sectors from memory, it uses the (not EDC checked) data returned by the
"streaming read" command. and completes it dumping only the missing bits from
memory.
1. Issue a "streaming read" command for the required sector. This will cause
the 16-sector block to which the sector belongs to be placed at the
beginning of the drive's cache memory, together with the 4 following
16-sector blocks.
2. For each sector of each block, reconstruct the whole Data Frame, as follows:
- Dump 12 bytes from memory.
- Use 2048 bytes returned by the read command.
- Dump 4 more bytes from memory.
Note that this method has a small issue, as sometimes the beginning of the
cache will be dirty and contain invalid data, needing the sector to be read
again. As this seems to happen quite often, we always read a dummy sector
before the requested sector.
Method 4
Method 4 is just method 3 with a trick to use a single dump command for every
sector that has to be reconstructed, instead of two. It is the faster dump
method currently supported and, as such, the default one.
1. Issue a "streaming read" command for the required sector. This will cause
the 16-sector block to which the sector belongs to be placed at the
beginning of the drive's cache memory, together with the 4 following
16-sector blocks.
2. For each sector of each block, reconstruct the whole Data Frame, as follows:
- If this is the first sector of a block, dump 12 bytes from memory.
Otherwise, use the last 12 bytes of the preceding dump.
- Use 2048 bytes returned by the read command.
- Dump 16 bytes from memory, and use the first 4. This leaves 12 bytes to be
used for the reconstruction of the next sector.
Note that the issue of method 3 applies to this method, too.
===============================================================================
How to add support for a new drive
===============================================================================
If you read all the above stuff, it should be clear that, in order to add
support for a new DVD-ROM drive, all that is needed is a way to dump the
drive's internal memory, in particular the portion where the data read from the
disc is cached. As explained above, this function might not be present in all
drives, and might not be easy to find or to use. In case you manage to discover
it, just copy the file "hitachi.c" to a new one, and modify it opportunely.
Some modifications will also be needed in "dvd_drive.c", in order to add
autodetection for the new drive, in the "dvd_assign_functions" function.
Apart from this, the cache behaviour of the new drive might not be the same
as that of the currently supported models, so the program architecture might
need radical changes. In this case, please report.