Difference between revisions of "XDVDFS"

From xboxdevwiki
Jump to: navigation, search
(Volume descriptor)
(Volume descriptor)
 
(23 intermediate revisions by 2 users not shown)
Line 12: Line 12:
 
=== Volume descriptor ===
 
=== Volume descriptor ===
  
32 sectors which are zero-filled.
+
The Volume descriptor islocated at Sector #32 and #33 of the game partition.
The Volume descriptor is 4096 bytes, but split into 2x 2048 sections.
 
  
* '''Section 1:''' The first data is the magic at sector 32. It is always "MICROSOFT*XBOX*MEDIA". {{FIXME|reason=How does this work?}}
+
* '''Sector #32:'''
* '''Section 2:''' The first data is the magic at sector 32. It is always "MICROSOFT*XBOX*MEDIA". {{FIXME|reason=Describe version information}}
+
{| class="wikitable"
 +
! Offset !! Type !! Field !! Notes
 +
|-
 +
|0x0 || ascii_char[20] || MAGIC|| MICROSOFT*XBOX*MEDIA
 +
|-
 +
|0x14 || u32 || Root Directory Table Sector || Multiply with 0x800 for offset
 +
|-
 +
|0x18 || u32 || Root Directory Table Size || Size in bytes. Always multiple of 0x800
 +
|-
 +
|0x1C || u64 || || Timestamp (LDAP/Win32 FILETIME)
 +
|-
 +
|0x7EC || ascii_char[20] || MAGIC|| MICROSOFT*XBOX*MEDIA
 +
|}
 +
 
 +
* '''Sector #33:''' The first 24 Bits is the magic. It is always "XBOX_DVD_LAYOUT_TOOL_SIG". {{FIXME|reason=Describe version information}}
  
 
==== Examples ====
 
==== Examples ====
  
* [[Azurik - Rise of Perathia]] (NTSC)
+
<!-- The "Wave n" is not a standard naming and I just made it up myself; we should confirm these and possibly find a better name - JayFoxRox -->
 +
{{FIXME|reason=The tool names appearing in this section are guessed by me, we should confirm each of these - JayFoxRox}}
 +
{{FIXME|reason=This lacks a couple of XDK versions}}
 +
{{FIXME|reason=The byte offsets of each version field are missing}}
 +
 
 +
===== Wave 1 =====
 +
 
 +
Developers used xblayout to create DVD layout.
 +
Then generated the final image using xbpremaster.
 +
The final image was submitted to Microsoft.
 +
 
 +
* [[Azurik: Rise of Perathia]] (NTSC)
 
** xblayout version: 1.0.3926.1
 
** xblayout version: 1.0.3926.1
 
** xbpremaster version: 1.0.3926.1
 
** xbpremaster version: 1.0.3926.1
** Starting bruteforce
 
** Found seed 0x7EA870D7
 
** Completed bruteforce (Success)
 
 
* [[Genma Onimusha]] (PAL)
 
* [[Genma Onimusha]] (PAL)
 
** xblayout version: 1.0.4039.1
 
** xblayout version: 1.0.4039.1
 
** xbpremaster version: 1.0.4039.2
 
** xbpremaster version: 1.0.4039.2
** Starting bruteforce
 
** Found seed 0x25BAB84C
 
** Completed bruteforce (Success)
 
 
* [[Max Payne]] (PAL)
 
* [[Max Payne]] (PAL)
 
** xblayout version: 1.0.4134.1
 
** xblayout version: 1.0.4134.1
 
** xbpremaster version: 1.0.4242.1
 
** xbpremaster version: 1.0.4242.1
** Starting bruteforce
 
** Found seed 0x62BBC340
 
** Completed bruteforce (Success)
 
 
* [[Petit Copter]] (Japanese)
 
* [[Petit Copter]] (Japanese)
 
** xblayout version: 1.0.4361.1
 
** xblayout version: 1.0.4361.1
 
** xbpremaster version: 1.0.4361.2
 
** xbpremaster version: 1.0.4361.2
** Starting bruteforce
 
** Found seed 0xF401863E
 
** Completed bruteforce (Success)
 
 
* [[007 - Agent Under Fire]] (PAL)
 
* [[007 - Agent Under Fire]] (PAL)
 
** xblayout version: 1.0.4432.1
 
** xblayout version: 1.0.4432.1
 
** xbpremaster version: 1.0.4432.1
 
** xbpremaster version: 1.0.4432.1
** Starting bruteforce
+
 
** Found seed 0x1796C12A
+
===== Wave 2 =====
** Completed bruteforce (Success)
+
 
 +
{{FIXME|reason=This is a theory. Confirm please}}.
 +
Developers used a new version of xblayout and submitted the layout + content to Microsoft
 +
 
 +
Microsoft generated the final image.
 +
 
 +
Sometime during this wave, the new padding algorithm got introduced. Judging from the examples below, the padding algorithm does not seem to be bound to the xblayout version or to a specific date.
 +
 
 
* [[Metal Gear Solid 2 - Substance]] (NTSC)
 
* [[Metal Gear Solid 2 - Substance]] (NTSC)
** xblayout version: 1.0.4721.1
+
** xblayout version: 1.0.4721.1 (old algorithm)
** Starting bruteforce
+
* [[Hitman 2 - Silent Assassin]] (France) (Original)
** Found seed 0xFACBB379
+
** xblayout version: 1.0.4721.1 (new algorithm)
** Completed bruteforce (Success)
+
** DMI Timestamp: 2002/09/18
 +
* [[Hitman 2 - Silent Assassin]] (France) (Classic Edition)
 +
** xblayout version: 1.0.4721.1 (old algorithm)
 +
** DMI Timestamp: 2002/12/03
 +
* [[Blade II]] (NTSC)
 +
** xblayout version: 1.0.4808.1 (old algorithm)
 
* [[Battle Engine Aquila]] (PAL)
 
* [[Battle Engine Aquila]] (PAL)
** xblayout version: 1.0.4831.1
+
** xblayout version: 1.0.4831.1 (new algorithm)
** Starting bruteforce
+
Other Examples of games with 1.0.4721.1 version that don't use the old algorithm: Mat Hoffman's Pro BMX 2 (France), MLB SlugFest 2003 (USA), NCAA Football 2003 (USA), Phantom Crash (USA), Syberia (USA, Europe)
** Completed bruteforce (Failure)
+
 
 +
===== Wave 3 =====
 +
 
 +
{{FIXME|reason=This is a theory. Confirm please}}.
 +
Same as wave 2
 
* [[Metal Gear Solid 2 - Substance]] (PAL)
 
* [[Metal Gear Solid 2 - Substance]] (PAL)
 
** xblayout version: 1.0.5120.1
 
** xblayout version: 1.0.5120.1
** Starting bruteforce
 
** Completed bruteforce (Failure)
 
 
* [[Shenmue II]] (PAL)
 
* [[Shenmue II]] (PAL)
 
** xblayout version: 1.0.5120.1
 
** xblayout version: 1.0.5120.1
** Starting bruteforce
+
 
** Completed bruteforce (Failure)
+
===== Wave 4 =====
 +
 
 +
{{FIXME|reason=This is a theory. Confirm please}}.
 +
Same as wave 3, but developers now had to use the xbgamedisc tool instead of xblayout.
 +
The mastering tool used by microsoft also leaves a version identifier now.
 +
 
 
* [[Star Wars - Knights of the Old Republic]] (PAL)
 
* [[Star Wars - Knights of the Old Republic]] (PAL)
 
** xbgamedisc version: 2.1.0.5233.1
 
** xbgamedisc version: 2.1.0.5233.1
 
** mastering tool version: 2.1.0.5233.1
 
** mastering tool version: 2.1.0.5233.1
** Starting bruteforce
 
** Completed bruteforce (Failure)
 
 
* [[Indiana Jones and the Emperor's Tomb]] (PAL)
 
* [[Indiana Jones and the Emperor's Tomb]] (PAL)
 
** xbgamedisc version: 2.1.0.5233.1
 
** xbgamedisc version: 2.1.0.5233.1
 
** mastering tool version: 2.1.0.5233.1
 
** mastering tool version: 2.1.0.5233.1
** Starting bruteforce
 
** Completed bruteforce (Failure)
 
 
* [[Dynasty Warriors 4]] (PAL)
 
* [[Dynasty Warriors 4]] (PAL)
 
** xbgamedisc version: 2.1.0.5344.1
 
** xbgamedisc version: 2.1.0.5344.1
 
** mastering tool version: 2.1.0.5344.1
 
** mastering tool version: 2.1.0.5344.1
** Starting bruteforce
 
** Completed bruteforce (Failure)
 
 
* [[The Matrix - Path of Neo]] (PAL)
 
* [[The Matrix - Path of Neo]] (PAL)
 
** xbgamedisc version: 2.1.0.5849.1
 
** xbgamedisc version: 2.1.0.5849.1
 
** mastering tool version: 2.1.0.5849.1
 
** mastering tool version: 2.1.0.5849.1
** Starting bruteforce
 
** Completed bruteforce (Failure)
 
 
* [[The Suffering - Ties That Bind]]
 
* [[The Suffering - Ties That Bind]]
 
** xbgamedisc version: 2.1.0.5849.1
 
** xbgamedisc version: 2.1.0.5849.1
 
** mastering tool version: 2.1.0.5849.1
 
** mastering tool version: 2.1.0.5849.1
** Starting bruteforce
 
** Completed bruteforce (Failure)
 
 
* [[Reservoir Dogs]] (PAL)
 
* [[Reservoir Dogs]] (PAL)
 
** xbgamedisc version: 2.1.0.5849.1
 
** xbgamedisc version: 2.1.0.5849.1
 
** mastering tool version: 2.1.0.5849.1
 
** mastering tool version: 2.1.0.5849.1
** Starting bruteforce
 
** Completed bruteforce (Failure)
 
  
 
=== Directory Entry ===
 
=== Directory Entry ===
Line 118: Line 137:
 
=== Random blocks ===
 
=== Random blocks ===
  
==== Version 4361 <!-- Game: Petit Copter --> ====
+
==== Version 3926 - 4808 ====
  
 
Seeded and then starting to emit bytes in data area.
 
Seeded and then starting to emit bytes in data area.
Filled with algorithm 1 (2048 bytes at a time, even buffer address).
+
Filled with the following algorithm:
 +
 
 +
<pre>
 +
// State
 +
uint32_t a;
 +
uint32_t b;
 +
uint32_t c;
 +
 
 +
// Helper
 +
static uint32_t Value(void) {
 +
  uint64_t result;
 +
  result = c;
 +
  result += 1;
 +
  result *= b;
 +
  result %= 0xFFFFFFFB;
 +
  c = result & 0xFFFFFFFF;
 +
  return c ^ a;
 +
}
 +
 
 +
// buffer must be at even address, length must be multiple of 2
 +
void Fill(uint16_t* buffer, size_t length) {
 +
  while(length >= 2) {
 +
    *buffer++ = Value() >> 8;
 +
    length -= 2;
 +
  }
 +
}
 +
 
 +
void Seed() {
 +
  const uint32_t b_seeds[8] = {
 +
    0x52F690D5,
 +
    0x534D7DDE,
 +
    0x5B71A70F,
 +
    0x66793320,
 +
    0x9B7E5ED5,
 +
    0xA465265E,
 +
    0xA53F1D11,
 +
    0xB154430F
 +
  };
 +
 
 +
  FILETIME ft;
 +
  GetSystemTimeAsFileTime(&ft);
 +
  uint32_t seed = ft.dwLowDateTime ^ ft.dwHighDateTime;
 +
  a = 0;
 +
  b = b_seeds[seed & 7];
 +
  c = seed;
 +
  a = Value();
 +
}
 +
</pre>
 +
 
 +
The RNG is seeded when the mastering tool / wizard is started.
 +
The first portion of the code to use this random number generator is the code which generates layer 0 and layer 1.
 +
 
 +
==== Version 4831 - 5849 ====
 +
 
 +
The algorithm was switched to RC4-256-drop-2048.
 +
 
 +
<pre>
 +
 
 +
#include <openssl/rc4.h>
 +
 
 +
RC4_KEY rc4key;
 +
 
 +
void Fill(uint8_t* buffer, size_t length) {
 +
  // We need a zero buffer as OpenSSL will want to XOR the keystream with data.
 +
  // The XDVDFS random data is the keystream without changes, so we let XOR OpenSSL XOR with 0x00 bytes.
 +
  uint8_t zero_buffer[length];
 +
  memset(zero_buffer, 0x00, length);
 +
  RC4(&rc4key, length, zero_buffer, buffer);
 +
}
 +
 
 +
void Seed() {
 +
  union {
 +
    uint8_t raw[16];
 +
    struct {
 +
      struct _FILETIME SystemTimeAsFileTime; // first 8 bytes, little-endian
 +
      uint64_t tsc; // later 8 bytes, little-endian
 +
    };
 +
  } key;
 +
 
 +
  // Initialize seed
 +
  key.tsc = rdtsc();
 +
  GetSystemTimeAsFileTime(&key.SystemTimeAsFileTime);
 +
  RC4_set_key(&rc4key, 16, &key);
 +
 
 +
  // Drop the first 2048 bytes of the RC4 keystream
 +
  uint8_t discard_buffer[2048];
 +
  Fill(discard_buffer, 2048);
 +
}
 +
</pre>
 +
 
 +
The RNG is seeded when the mastering tool / wizard is started.
 +
The first portion of the code to use this random number generator is the code which generates layer 0 and layer 1.
 +
 
 +
Edit: This assumption is not true, at least not for all instances. For example, all region variants of Conker Live & Reloaded share the same padding stream.
  
 
=== Security blocks ===
 
=== Security blocks ===

Latest revision as of 15:47, 6 March 2022

XDVDFS (Also known as XISO) is the image format used for Xbox Game Discs. It is stored in the data area.

Format

Each sector is 2048 bytes.

Filesystem

[FIXME]

Volume descriptor

The Volume descriptor islocated at Sector #32 and #33 of the game partition.

  • Sector #32:
Offset Type Field Notes
0x0 ascii_char[20] MAGIC MICROSOFT*XBOX*MEDIA
0x14 u32 Root Directory Table Sector Multiply with 0x800 for offset
0x18 u32 Root Directory Table Size Size in bytes. Always multiple of 0x800
0x1C u64 Timestamp (LDAP/Win32 FILETIME)
0x7EC ascii_char[20] MAGIC MICROSOFT*XBOX*MEDIA
  • Sector #33: The first 24 Bits is the magic. It is always "XBOX_DVD_LAYOUT_TOOL_SIG". [FIXME]

Examples

[FIXME] [FIXME] [FIXME]

Wave 1

Developers used xblayout to create DVD layout. Then generated the final image using xbpremaster. The final image was submitted to Microsoft.

  • Azurik: Rise of Perathia (NTSC)
    • xblayout version: 1.0.3926.1
    • xbpremaster version: 1.0.3926.1
  • Genma Onimusha (PAL)
    • xblayout version: 1.0.4039.1
    • xbpremaster version: 1.0.4039.2
  • Max Payne (PAL)
    • xblayout version: 1.0.4134.1
    • xbpremaster version: 1.0.4242.1
  • Petit Copter (Japanese)
    • xblayout version: 1.0.4361.1
    • xbpremaster version: 1.0.4361.2
  • 007 - Agent Under Fire (PAL)
    • xblayout version: 1.0.4432.1
    • xbpremaster version: 1.0.4432.1
Wave 2

[FIXME]. Developers used a new version of xblayout and submitted the layout + content to Microsoft

Microsoft generated the final image.

Sometime during this wave, the new padding algorithm got introduced. Judging from the examples below, the padding algorithm does not seem to be bound to the xblayout version or to a specific date.

Other Examples of games with 1.0.4721.1 version that don't use the old algorithm: Mat Hoffman's Pro BMX 2 (France), MLB SlugFest 2003 (USA), NCAA Football 2003 (USA), Phantom Crash (USA), Syberia (USA, Europe)

Wave 3

[FIXME]. Same as wave 2

Wave 4

[FIXME]. Same as wave 3, but developers now had to use the xbgamedisc tool instead of xblayout. The mastering tool used by microsoft also leaves a version identifier now.

Directory Entry

Version 4361

File entry flags:

  • READONLY = 0x01
  • HIDDEN = 0x02
  • SYSTEM = 0x04
  • DIRECTORY = 0x10
  • ARCHIVE = 0x20
  • NORMAL = 0x80

File data blocks

Version 4361

Incomplete sectors are padded with 0x00 bytes.

Random blocks

Version 3926 - 4808

Seeded and then starting to emit bytes in data area. Filled with the following algorithm:

// State
uint32_t a;
uint32_t b;
uint32_t c;

// Helper
static uint32_t Value(void) {
  uint64_t result;
  result = c;
  result += 1;
  result *= b;
  result %= 0xFFFFFFFB;
  c = result & 0xFFFFFFFF;
  return c ^ a;
}

// buffer must be at even address, length must be multiple of 2
void Fill(uint16_t* buffer, size_t length) {
  while(length >= 2) {
    *buffer++ = Value() >> 8;
    length -= 2;
  }
}

void Seed() {
  const uint32_t b_seeds[8] = {
    0x52F690D5,
    0x534D7DDE,
    0x5B71A70F,
    0x66793320,
    0x9B7E5ED5,
    0xA465265E,
    0xA53F1D11,
    0xB154430F
  };

  FILETIME ft;
  GetSystemTimeAsFileTime(&ft);
  uint32_t seed = ft.dwLowDateTime ^ ft.dwHighDateTime;
  a = 0;
  b = b_seeds[seed & 7];
  c = seed;
  a = Value();
}

The RNG is seeded when the mastering tool / wizard is started. The first portion of the code to use this random number generator is the code which generates layer 0 and layer 1.

Version 4831 - 5849

The algorithm was switched to RC4-256-drop-2048.


#include <openssl/rc4.h>

RC4_KEY rc4key;

void Fill(uint8_t* buffer, size_t length) {
  // We need a zero buffer as OpenSSL will want to XOR the keystream with data.
  // The XDVDFS random data is the keystream without changes, so we let XOR OpenSSL XOR with 0x00 bytes.
  uint8_t zero_buffer[length];
  memset(zero_buffer, 0x00, length);
  RC4(&rc4key, length, zero_buffer, buffer);
}

void Seed() {
  union {
    uint8_t raw[16];
    struct {
      struct _FILETIME SystemTimeAsFileTime; // first 8 bytes, little-endian
      uint64_t tsc; // later 8 bytes, little-endian
    };
  } key;

  // Initialize seed
  key.tsc = rdtsc();
  GetSystemTimeAsFileTime(&key.SystemTimeAsFileTime);
  RC4_set_key(&rc4key, 16, &key);

  // Drop the first 2048 bytes of the RC4 keystream
  uint8_t discard_buffer[2048];
  Fill(discard_buffer, 2048);
}

The RNG is seeded when the mastering tool / wizard is started. The first portion of the code to use this random number generator is the code which generates layer 0 and layer 1.

Edit: This assumption is not true, at least not for all instances. For example, all region variants of Conker Live & Reloaded share the same padding stream.

Security blocks

Version 4361

Treated like random block.

Tools