1 2 /*************************************************************************** 3 * __ __ _ ___________ * 4 * \ \ / /| |____ ____| * 5 * \ \ / / | | | | * 6 * \ \ /\ / / | | | | * 7 * \ \/ \/ / | | | | * 8 * \ /\ / | | | | * 9 * \/ \/ |_| |_| * 10 * * 11 * Wiimms ISO Tools * 12 * http://wit.wiimm.de/ * 13 * * 14 *************************************************************************** 15 * * 16 * This file is part of the WIT project. * 17 * Visit http://wit.wiimm.de/ for project details and sources. * 18 * * 19 * Copyright (c) 2009-2013 by Dirk Clemens <wiimm@wiimm.de> * 20 * * 21 *************************************************************************** 22 * * 23 * This program is free software; you can redistribute it and/or modify * 24 * it under the terms of the GNU General Public License as published by * 25 * the Free Software Foundation; either version 2 of the License, or * 26 * (at your option) any later version. * 27 * * 28 * This program is distributed in the hope that it will be useful, * 29 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 31 * GNU General Public License for more details. * 32 * * 33 * See file gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt * 34 * * 35 ***************************************************************************/ 36 37 #ifndef FILE_FORMATS_H 38 #define FILE_FORMATS_H 39 40 // some info urls: 41 // - http://wiibrew.org/wiki/Wii_Disc 42 // - http://wiibrew.org/wiki/Ticket 43 // - http://wiibrew.org/wiki/Tmd_file_structure 44 // - http://hitmen.c02.at/files/yagcd/yagcd/chap13.html -> GameCube 45 46 // 47 /////////////////////////////////////////////////////////////////////////////// 48 /////////////// setup /////////////// 49 /////////////////////////////////////////////////////////////////////////////// 50 51 #include "tools.h" 52 53 int validate_file_format_sizes ( int trace_sizes ); 54 55 // 56 /////////////////////////////////////////////////////////////////////////////// 57 /////////////// constants /////////////// 58 /////////////////////////////////////////////////////////////////////////////// 59 60 enum // some constants 61 { 62 HD_SECTOR_SIZE = 0x200, // classic HD sector size 63 HD_BLOCK_SIZE = 0x1000, // good HD block value 64 65 WII_SECTOR_SIZE_SHIFT = 15, 66 WII_SECTOR_SIZE = 1 << WII_SECTOR_SIZE_SHIFT, 67 WII_SECTOR_SIZE4 = WII_SECTOR_SIZE >> 2, 68 WII_SECTORS_PER_MIB = 1024*1024/WII_SECTOR_SIZE, 69 70 WII_SECTOR_IV_OFF = 0x3d0, 71 WII_SECTOR_HASH_SIZE = 0x400, 72 WII_SECTOR_HASH_SIZE4 = WII_SECTOR_HASH_SIZE >> 2, 73 WII_SECTOR_DATA_SIZE = WII_SECTOR_SIZE - WII_SECTOR_HASH_SIZE, 74 WII_SECTOR_DATA_SIZE4 = WII_SECTOR_DATA_SIZE >> 2, 75 76 WII_HASH_SIZE = 20, 77 WII_H0_DATA_SIZE = 0x400, 78 WII_H3_SIZE = 0x18000, 79 WII_N_ELEMENTS_H0 = WII_SECTOR_DATA_SIZE/WII_H0_DATA_SIZE, 80 WII_N_ELEMENTS_H1 = 8, 81 WII_N_ELEMENTS_H2 = 8, 82 WII_N_ELEMENTS_H3 = WII_H3_SIZE/WII_HASH_SIZE, 83 WII_MAX_PART_SECTORS = WII_N_ELEMENTS_H1 84 * WII_N_ELEMENTS_H2 85 * WII_N_ELEMENTS_H3, 86 87 WII_GROUP_SECTORS = WII_N_ELEMENTS_H1 * WII_N_ELEMENTS_H2, 88 WII_GROUP_SIZE = WII_GROUP_SECTORS * WII_SECTOR_SIZE, 89 WII_GROUP_SIZE4 = WII_GROUP_SIZE >> 2, 90 WII_GROUP_HASH_SIZE = WII_GROUP_SECTORS * WII_SECTOR_HASH_SIZE, 91 WII_GROUP_HASH_SIZE4 = WII_GROUP_HASH_SIZE >> 2, 92 WII_GROUP_DATA_SIZE = WII_GROUP_SECTORS * WII_SECTOR_DATA_SIZE, 93 WII_GROUP_DATA_SIZE4 = WII_GROUP_DATA_SIZE >> 2, 94 95 WII_N_HASH_SECTOR = WII_N_ELEMENTS_H0 96 + WII_N_ELEMENTS_H1 97 + WII_N_ELEMENTS_H2, 98 WII_N_HASH_GROUP = WII_N_HASH_SECTOR * WII_GROUP_SECTORS, 99 100 WII_CERT_ALIGN = 0x40, // alignment in Wii certificates 101 102 WII_TICKET_SIZE = 0x2a4, 103 WII_TICKET_SIG_OFF = 0x140, // do SHA1 up to end of ticket 104 WII_TICKET_KEY_OFF = 0x1bf, 105 WII_TICKET_IV_OFF = 0x1dc, 106 WII_TICKET_ID4_OFF = 0x1e0, // offset of ID4 107 WII_TICKET_BRUTE_FORCE_OFF = 0x24c, // this u32 will be iterated 108 109 WII_TMD_GOOD_SIZE = 0x208, // tmd with 1 content (usual) 110 WII_TMD_SIG_OFF = 0x140, // do SHA1 up to end of tmd 111 WII_TMD_ID4_OFF = 0x190, // offset of ID4 112 WII_TMD_BRUTE_FORCE_OFF = 0x19a, // this u32 will be iterated 113 WII_PARTITION_BIN_SIZE = 0x20000, 114 115 WII_SECTORS_SINGLE_LAYER = 143432, 116 WII_SECTORS_DOUBLE_LAYER = 2 * WII_SECTORS_SINGLE_LAYER, 117 WII_MAX_SECTORS = WII_SECTORS_DOUBLE_LAYER, 118 WII_MAX_U32_SECTORS = 0x40000000/WII_SECTOR_SIZE4, 119 120 WII_MAGIC = 0x5d1c9ea3, 121 WII_MAGIC_DELETED = 0x2a44454c, 122 WII_MAGIC_OFF = 0x18, 123 WII_MAGIC_LEN = 0x04, 124 125 WII_MAGIC2 = 0xc3f81a8e, 126 WII_MAGIC2_OFF = 0x4fffc, 127 WII_MAGIC2_LEN = 0x04, 128 129 WII_TITLE_OFF = 0x20, 130 WII_TITLE_SIZE = 0x40, 131 132 WII_KEY_SIZE = 16, 133 WII_FILE_PATH_SIZE = 1000, 134 135 WII_MAX_PTAB = 4, // maximal partition tables 136 WII_PTAB_REF_OFF = 0x40000, // disc offset of partition table ref 137 WII_PTAB_SECTOR = WII_PTAB_REF_OFF / WII_SECTOR_SIZE, 138 // sector index of partition table 139 WII_MAX_PTAB_SIZE = 0x400, // maximal size of all ptabs + entries 140 WII_MAX_PARTITIONS = WII_MAX_PTAB_SIZE / 8 - WII_MAX_PTAB, 141 // maximal supported partitions 142 143 WII_REGION_OFF = 0x4e000, 144 WII_REGION_SIZE = 0x20, 145 146 WII_BOOT_OFF = 0, 147 WII_BI2_OFF = 0x440, 148 WII_APL_OFF = 0x2440, 149 WII_BOOT_SIZE = WII_BI2_OFF - WII_BOOT_OFF, 150 WII_BI2_SIZE = WII_APL_OFF - WII_BI2_OFF, 151 WII_BI2_REGION_OFF = 0x18, 152 153 WII_PART_OFF = 0x50000, 154 WII_GOOD_DATA_PART_OFF = 0xf800000, 155 156 GC_MAGIC = 0xc2339f3d, 157 GC_MAGIC_OFF = 0x1c, 158 GC_MAGIC_LEN = 0x04, 159 GC_DISC_SIZE = 1459978240, // standard GameCube disc size 160 161 GC_MULTIBOOT_PTAB_OFF = 0x40, 162 GC_MULTIBOOT_PTAB_SIZE = 0x100 - GC_MULTIBOOT_PTAB_OFF, 163 GC_MULTIBOOT_MAX_PART = GC_MULTIBOOT_PTAB_SIZE/4, 164 GC_GOOD_PART_ALIGN = 0x20000, // alignment (= min off) of GC partitions 165 166 DOL_N_TEXT_SECTIONS = 7, 167 DOL_N_DATA_SECTIONS = 11, 168 DOL_N_SECTIONS = DOL_N_TEXT_SECTIONS + DOL_N_DATA_SECTIONS, 169 DOL_HEADER_SIZE = 0x100, 170 171 WBFS_MAX_SECTORS = 0x10000, // max number of sectors 172 WBFS_MIN_SECTOR_SHIFT = 6, // needed for wbfs_calc_size_shift() 173 WBFS_MAX_SECTOR_SHIFT = 11, // needed for wbfs_calc_size_shift() 174 WBFS_MIN_SECTOR_SIZE = 1 << WBFS_MIN_SECTOR_SHIFT + WII_SECTOR_SIZE_SHIFT, 175 WBFS_MAX_SECTOR_SIZE = 1 << WBFS_MAX_SECTOR_SHIFT + WII_SECTOR_SIZE_SHIFT, 176 177 WBFS_INODE_INFO_VERSION = 1, 178 WBFS_INODE_INFO_HEAD_SIZE = 12, 179 WBFS_INODE_INFO_CMP_SIZE = 10, 180 WBFS_INODE_INFO_OFF = 0x80, 181 WBFS_INODE_INFO_SIZE = 0x100 - WBFS_INODE_INFO_OFF, 182 183 LOADER_MAX_FRAGMENTS = 20000, 184 }; 185 186 #define WII_MAX_DISC_SIZE ((u64)WII_MAX_SECTORS*(u64)WII_SECTOR_SIZE) 187 188 // 189 /////////////////////////////////////////////////////////////////////////////// 190 /////////////// enum wd_disc_type_t /////////////// 191 /////////////////////////////////////////////////////////////////////////////// 192 193 typedef enum wd_disc_type_t 194 { 195 //********************************************************************** 196 //*** never change this values, because they are used in archives! *** 197 //********************************************************************** 198 199 WD_DT_UNKNOWN = 0, // unknown disc type 200 WD_DT_GAMECUBE, // GameCube disc 201 WD_DT_WII, // Wii disc 202 203 WD_DT__N // number of defined disc types 204 205 } wd_disc_type_t; 206 207 // 208 /////////////////////////////////////////////////////////////////////////////// 209 /////////////// enum wd_disc_attrib_t /////////////// 210 /////////////////////////////////////////////////////////////////////////////// 211 212 typedef enum wd_disc_attrib_t 213 { 214 //--- disc type attributes, detected by get_header_disc_type() 215 216 WD_DA_GAMECUBE = 1 << WD_DT_GAMECUBE, 217 WD_DA_WII = 1 << WD_DT_WII, 218 219 220 //--- real attributes, detected by get_header_disc_type() 221 222 WD_DA_GC_MULTIBOOT = 0x0100, // gamecube multiboot disc 223 WD_DA_GC_DVD9 = 0x0200, // gc-mb disc with DVD9 part-tab 224 225 226 //--- more real attributes 227 228 WD_DA_GC_START_PART = 0x0400, // gc-mb disc with valid start partition 229 230 } wd_disc_attrib_t; 231 232 // 233 /////////////////////////////////////////////////////////////////////////////// 234 /////////////// enum wd_compression_t /////////////// 235 /////////////////////////////////////////////////////////////////////////////// 236 237 typedef enum wd_compression_t 238 { 239 //********************************************************************** 240 //*** never change this values, because they are used in archives! *** 241 //********************************************************************** 242 243 WD_COMPR_NONE = 0, // data is not compressed 244 WD_COMPR_PURGE, // a WDF like compression: manage holes 245 246 WD_COMPR_BZIP2, // use BZIP2 compression 247 WD_COMPR_LZMA, // use LZMA compression 248 WD_COMPR_LZMA2, // use LZMA2 compression 249 250 WD_COMPR__N, // number of compressions 251 252 WD_COMPR__FIRST_REAL = WD_COMPR_BZIP2, // first real compression 253 #ifdef NO_BZIP2 254 WD_COMPR__FAST = WD_COMPR_LZMA, // a fast compression 255 #else 256 WD_COMPR__FAST = WD_COMPR_BZIP2, // a fast compression 257 #endif 258 WD_COMPR__GOOD = WD_COMPR_LZMA, // a good compression 259 WD_COMPR__BEST = WD_COMPR_LZMA, // the best compression 260 WD_COMPR__DEFAULT = WD_COMPR_LZMA, // the default compression 261 262 } wd_compression_t; 263 264 //----------------------------------------------------------------------------- 265 266 ccp wd_get_compression_name 267 ( 268 wd_compression_t compr, // compression method 269 ccp invalid_result // return value if 'compr' is invalid 270 ); 271 272 ccp wd_print_compression 273 ( 274 char * buf, // result buffer 275 // If NULL, a local circulary static buffer is used 276 size_t buf_size, // size of 'buf', ignored if buf==NULL 277 wd_compression_t compr_method, // compression method 278 int compr_level, // compression level 279 u32 chunk_size, // compression chunk size, multiple of MiB 280 int mode // 1=number, 2=name, 3=number and name 281 ); 282 283 // 284 /////////////////////////////////////////////////////////////////////////////// 285 /////////////// struct dol_header_t /////////////// 286 /////////////////////////////////////////////////////////////////////////////// 287 288 typedef struct dol_header_t 289 { 290 /* 0x00 */ u32 sect_off [DOL_N_SECTIONS]; // file offset 291 /* 0x48 */ u32 sect_addr[DOL_N_SECTIONS]; // virtual address 292 /* 0x90 */ u32 sect_size[DOL_N_SECTIONS]; // section size 293 /* 0xd8 */ u32 bss_addr; 294 /* 0xdc */ u32 bss_size; 295 /* 0xe0 */ u32 entry_addr; 296 /* 0xe4 */ u8 padding[DOL_HEADER_SIZE-0xe4]; 297 } 298 __attribute__ ((packed)) dol_header_t; 299 300 void ntoh_dol_header ( dol_header_t * dest, const dol_header_t * src ); 301 void hton_dol_header ( dol_header_t * dest, const dol_header_t * src ); 302 303 //----------------------------------------------------------------------------- 304 305 typedef struct dol_record_t 306 { 307 u32 addr; // virtual address of data 308 u32 size; // size of data 309 u32 xsize; // extended size 310 u32 delta; // file_offset := 'addr' - 'delta' 311 char name[4]; // section name 312 } 313 dol_record_t; 314 315 uint calc_dol_records 316 ( 317 dol_record_t *rec, // pointer to at least DOL_N_SECTIONS records 318 bool term_null, // true: add a NULL record at end of list 319 const dol_header_t *dol_head // source DOL header 320 ); 321 322 const dol_record_t * search_dol_record 323 ( 324 dol_record_t *rec, // pointer to at least records 325 uint n_rec, // number of records, set it to DOL_N_SECTIONS 326 // if record lsit is NULL termianted 327 u32 addr, // address to search 328 u32 size // size of object, if NULL, ignore it 329 ); 330 331 // 332 /////////////////////////////////////////////////////////////////////////////// 333 /////////////// struct wbfs_inode_info_t /////////////// 334 /////////////////////////////////////////////////////////////////////////////// 335 336 typedef struct wbfs_inode_info_t 337 { 338 // A complete copy of the first WBFS_INODE_INFO_HEAD_SIZE (12) bytes 339 // of the WBFS header. The first WBFS_INODE_INFO_CMP_SIZE (10) 340 // bytes can be used to validate the existence of this info block. 341 // They are also good for recovery. 342 343 be32_t magic; // the magic (char*)"WBFS" 344 be32_t n_hd_sec; // total number of hd_sec in this partition 345 u8 hd_sec_sz_s; // sector size in this partition 346 u8 wbfs_sec_sz_s; // size of a wbfs sec 347 348 u8 wbfs_version; // informative version number 349 u8 head_padding; 350 351 // The version number of this data structure. 352 // I may be important for future extensions 353 354 be32_t info_version; // == WBFS_INODE_INFO_VERSION 355 356 // 64 bit time stamps: They are only informative but nice to have. 357 // - itime is ths disc inserting time. 358 // If 2 discs uses the same wbfs block a repair function knows 359 // which one disc are newer and which is definitly bad. 360 // - mtime is a copy of the mtime of the source file. 361 // It is also changed if the the ISO-header is modified (renamed). 362 // While extrating the mtime of dest file is set by this mtime. 363 // - ctime is updated if adding, renaming. 364 // - atime can be updated by usb loaders when loading the disc. 365 // - dtime is only set for deleted games. 366 367 be64_t itime; // the disc insertion time 368 be64_t mtime; // the last modification time (copied from source) 369 be64_t ctime; // the last status changed time 370 be64_t atime; // the last access time 371 be64_t dtime; // the deletion time 372 373 // there is enough space for more information like a game load counter 374 // or other statistics and game settings. This infos can be share across 375 // usb loaders. 376 377 // EXAMPLES: 378 // be32_t load_count; 379 // u8 favorite 380 // u8 ios 381 382 // padding up to WBFS_INODE_INFO_SIZE bytes, always filled with zeros 383 384 u8 padding[ WBFS_INODE_INFO_SIZE - WBFS_INODE_INFO_HEAD_SIZE 385 - 0 /* num of 8 bit parameters */ * sizeof(u8) 386 - 0 /* num of 16 bit parameters */ * sizeof(be16_t) 387 - 1 /* num of 32 bit parameters */ * sizeof(be32_t) 388 - 5 /* num of 64 bit parameters */ * sizeof(be64_t) ]; 389 390 } 391 __attribute__ ((packed)) wbfs_inode_info_t; 392 393 void ntoh_inode_info ( wbfs_inode_info_t * dest, const wbfs_inode_info_t * src ); 394 void hton_inode_info ( wbfs_inode_info_t * dest, const wbfs_inode_info_t * src ); 395 396 // 397 /////////////////////////////////////////////////////////////////////////////// 398 /////////////// struct wd_header_128_t /////////////// 399 /////////////////////////////////////////////////////////////////////////////// 400 401 typedef struct wd_header_128_t 402 { 403 // -> http://www.wiibrew.org/wiki/Wiidisc#Header 404 405 /* 0x00 */ char disc_id; 406 /* 0x01 */ char game_code[2]; 407 /* 0x03 */ char region_code; 408 /* 0x04 */ char marker_code[2]; 409 410 /* 0x06 */ u8 disc_number; 411 /* 0x07 */ u8 disc_version; 412 413 /* 0x08 */ u8 audio_streaming; 414 /* 0x09 */ u8 streaming_buffer_size; 415 416 /* 0x0a */ u8 unknown1[0x0e]; 417 /* 0x18 */ u32 wii_magic; // off=WII_MAGIC_OFF, val=WII_MAGIC 418 /* 0x1c */ u32 gc_magic; // off=GC_MAGIC_OFF, val=GC_MAGIC 419 420 /* 0x20 */ char disc_title[WII_TITLE_SIZE]; // off=WII_TITLE_OFF 421 422 /* 0x60 */ u8 diable_hash; 423 /* 0x61 */ u8 diable_encryption; 424 425 /* 0x62 */ u8 padding[0x1e]; 426 427 } __attribute__ ((packed)) wd_header_128_t; 428 429 //----------------------------------------------------------------------------- 430 431 void header_128_setup 432 ( 433 wd_header_128_t * dhead, // valid pointer 434 const void * id6, // NULL or pointer to ID 435 ccp disc_title, // NULL or pointer to disc title (truncated) 436 bool is_gc // true: GameCube setup 437 ); 438 439 //----------------------------------------------------------------------------- 440 441 wd_disc_type_t get_header_128_disc_type 442 ( 443 wd_header_128_t * dhead, // valid pointer 444 wd_disc_attrib_t * attrib // not NULL: store disc attributes 445 ); 446 447 // 448 /////////////////////////////////////////////////////////////////////////////// 449 /////////////// struct wd_header_t /////////////// 450 /////////////////////////////////////////////////////////////////////////////// 451 452 typedef struct wd_header_t 453 { 454 // -> http://www.wiibrew.org/wiki/Wiidisc#Header 455 456 /* 0x00 */ char disc_id; 457 /* 0x01 */ char game_code[2]; 458 /* 0x03 */ char region_code; 459 /* 0x04 */ char marker_code[2]; 460 461 /* 0x06 */ u8 disc_number; 462 /* 0x07 */ u8 disc_version; 463 464 /* 0x08 */ u8 audio_streaming; 465 /* 0x09 */ u8 streaming_buffer_size; 466 467 /* 0x0a */ u8 unknown1[0x0e]; 468 /* 0x18 */ u32 wii_magic; // off=WII_MAGIC_OFF, val=WII_MAGIC 469 /* 0x1c */ u32 gc_magic; // off=GC_MAGIC_OFF, val=GC_MAGIC 470 471 /* 0x20 */ char disc_title[WII_TITLE_SIZE]; // off=WII_TITLE_OFF 472 473 /* 0x60 */ u8 diable_hash; 474 /* 0x61 */ u8 diable_encryption; 475 476 /* 0x62 */ u8 padding[0x1e]; 477 478 /* 0x80 */ wbfs_inode_info_t iinfo; // off=WBFS_INODE_INFO_OFF 479 480 } __attribute__ ((packed)) wd_header_t; 481 482 //----------------------------------------------------------------------------- 483 484 void header_setup 485 ( 486 wd_header_t * dhead, // valid pointer 487 const void * id6, // NULL or pointer to ID 488 ccp disc_title, // NULL or pointer to disc title (truncated) 489 bool is_gc // true: GameCube setup 490 ); 491 492 //----------------------------------------------------------------------------- 493 494 wd_disc_type_t get_header_disc_type 495 ( 496 wd_header_t * dhead, // valid pointer 497 wd_disc_attrib_t * attrib // not NULL: store disc attributes 498 ); 499 500 // 501 /////////////////////////////////////////////////////////////////////////////// 502 /////////////// struct wd_boot_t /////////////// 503 /////////////////////////////////////////////////////////////////////////////// 504 505 typedef struct wd_boot_t 506 { 507 /* 0 */ wd_header_t dhead; 508 /* 0x100 */ u8 unknown1[0x420-sizeof(wd_header_t)]; 509 /* 0x420 */ u32 dol_off4; 510 /* 0x424 */ u32 fst_off4; 511 /* 0x428 */ u32 fst_size4; 512 /* 0x42c */ u32 max_fst_size4; // >= fst_size4 (max of multi discs) 513 /* 0x430 */ u8 unknown2[WII_BOOT_SIZE-0x430]; 514 } 515 __attribute__ ((packed)) wd_boot_t; 516 517 void ntoh_boot ( wd_boot_t * dest, const wd_boot_t * src ); 518 void hton_boot ( wd_boot_t * dest, const wd_boot_t * src ); 519 520 // 521 /////////////////////////////////////////////////////////////////////////////// 522 /////////////// enum wd_age_rating_t /////////////// 523 /////////////////////////////////////////////////////////////////////////////// 524 525 typedef enum wd_age_rating_t 526 { 527 WD_AGE_JAPAN, 528 WD_AGE_USA, 529 WD_AGE_UNKNOWN, 530 WD_AGE_EUROPE1, 531 WD_AGE_EUROPE2, 532 WD_AGE_EUROPE3, 533 WD_AGE_EUROPE4, 534 WD_AGE_EUROPE5, 535 WD_AGE_EUROPE6, 536 WD_AGE_KOREA, 537 538 WD_AGE__N 539 540 } wd_age_rating_t; 541 542 //----------------------------------------------------------------------------- 543 544 ccp wd_print_age_rating 545 ( 546 char * buf, // result buffer 547 // If NULL, a local circulary static buffer is used 548 size_t buf_size, // size of 'buf', ignored if buf==NULL 549 u8 * age_rating // valid buffer of 'WD_AGE__N' bytes 550 ); 551 552 // 553 /////////////////////////////////////////////////////////////////////////////// 554 /////////////// struct wd_region_t /////////////// 555 /////////////////////////////////////////////////////////////////////////////// 556 557 typedef struct wd_region_t 558 { 559 /* 0 */ u32 region; 560 /* 0x04 */ u8 padding1[12]; 561 /* 0x10 */ u8 age_rating[WD_AGE__N]; 562 u8 padding2[0x10-WD_AGE__N]; 563 } 564 __attribute__ ((packed)) wd_region_t; 565 566 // 567 /////////////////////////////////////////////////////////////////////////////// 568 /////////////// struct wd_ptab_info_t /////////////// 569 /////////////////////////////////////////////////////////////////////////////// 570 571 typedef struct wd_ptab_info_t 572 { 573 u32 n_part; // number of partitions in this table 574 u32 off4; // offset/4 of partition table relative to disc start 575 } 576 __attribute__ ((packed)) wd_ptab_info_t; 577 578 // 579 /////////////////////////////////////////////////////////////////////////////// 580 /////////////// struct wd_ptab_entry_t /////////////// 581 /////////////////////////////////////////////////////////////////////////////// 582 583 typedef struct wd_ptab_entry_t 584 { 585 u32 off4; // offset/4 of partition relative to disc start 586 u32 ptype; // partitions type 587 } 588 __attribute__ ((packed)) wd_ptab_entry_t; 589 590 // 591 /////////////////////////////////////////////////////////////////////////////// 592 /////////////// struct wd_ptab_t /////////////// 593 /////////////////////////////////////////////////////////////////////////////// 594 595 typedef struct wd_ptab_t // example for a good partition table 596 { 597 /* 0 */ wd_ptab_info_t info[WII_MAX_PTAB]; 598 /* 0x20 */ wd_ptab_entry_t entry[WII_MAX_PARTITIONS]; 599 } 600 __attribute__ ((packed)) wd_ptab_t; 601 602 // 603 /////////////////////////////////////////////////////////////////////////////// 604 /////////////// struct wd_ticket_t /////////////// 605 /////////////////////////////////////////////////////////////////////////////// 606 607 typedef struct wd_ticket_t 608 { 609 // --> http://wiibrew.org/wiki/Ticket 610 611 /* 0x000 */ u32 sig_type; // signature type (always 0x10001 for RSA-2048) 612 /* 0x004 */ u8 sig[0x100]; // signature by a certificate's key 613 /* 0x104 */ u8 sig_padding[0x3c]; // always 0 614 615 // the signature calculations starts here (WII_TICKET_SIG_OFF) 616 617 /* 0x140 */ u8 issuer[0x40]; // signature issuer 618 /* 0x180 */ u8 unknown1[0x3f]; // always 0, unless it is a VC game 619 /* 0x1bf */ u8 title_key[0x10]; // encrypted title key, offset=WII_TICKET_KEY_OFF 620 /* 0x1cf */ u8 unknown2; // ? 621 /* 0x1d0 */ u8 ticket_id[8]; // ticket ID 622 /* 0x1d8 */ u8 console_id[4]; // console ID 623 /* 0x1dc */ u8 title_id[8]; // title ID, offset=WII_TICKET_IV_OFF 624 /* 0x1e4 */ u16 unknown3; // unknown, mostly 0xFFFF 625 /* 0x1e6 */ u16 n_dlc; // amount of bought DLC contents 626 /* 0x1e8 */ u8 unknown4; // ERROR in http://wiibrew.org/wiki/Ticket 627 /* 0x1e9 */ u8 unknown5[0x08]; // ? 628 /* 0x1f1 */ u8 common_key_index; // 1=Korean Common key, 0="normal" Common key 629 /* 0x1f2 */ u8 unknown6[0x30]; // Is all 0 for non-VC, for VC, all 0 except last byte is 1 630 /* 0x222 */ u8 unknown7[0x20]; // always 0xff (?) 631 /* 0x242 */ u8 padding2[2]; // always 0 632 /* 0x244 */ u32 enable_time_limit; // 1=enabled, 0=disabled 633 /* 0x248 */ u32 time_limit; // seconds (what is the epoch?) 634 /* 0x24c */ u8 fake_sign[0x58]; // padding, always 0 => used for fake signing 635 636 } 637 __attribute__ ((packed)) wd_ticket_t; 638 639 //----- encryption helpers 640 641 extern const char not_encrypted_marker[]; 642 643 void ticket_setup ( wd_ticket_t * ticket, const void * id4 ); 644 645 void ticket_clear_encryption ( wd_ticket_t * ticket, int mark_not_encrypted ); 646 bool ticket_is_marked_not_encrypted ( const wd_ticket_t * ticket ); 647 u32 ticket_fake_sign ( wd_ticket_t * ticket, u32 ticket_size ); 648 bool ticket_is_fake_signed ( const wd_ticket_t * ticket, u32 ticket_size ); 649 650 // 651 /////////////////////////////////////////////////////////////////////////////// 652 /////////////// struct wd_part_header_t /////////////// 653 /////////////////////////////////////////////////////////////////////////////// 654 655 typedef struct wd_part_header_t 656 { 657 /* 0x000 */ wd_ticket_t ticket; 658 /* 0x2a4 */ u32 tmd_size; 659 /* 0x2a8 */ u32 tmd_off4; 660 /* 0x2ac */ u32 cert_size; 661 /* 0x2b0 */ u32 cert_off4; 662 /* 0x2b4 */ u32 h3_off4; 663 /* 0x2b8 */ u32 data_off4; 664 /* 0x2bc */ u32 data_size4; 665 } 666 __attribute__ ((packed)) wd_part_header_t; 667 668 void ntoh_part_header ( wd_part_header_t * dest, const wd_part_header_t * src ); 669 void hton_part_header ( wd_part_header_t * dest, const wd_part_header_t * src ); 670 671 // 672 /////////////////////////////////////////////////////////////////////////////// 673 /////////////// struct wd_tmd_content_t /////////////// 674 /////////////////////////////////////////////////////////////////////////////// 675 676 typedef struct wd_tmd_content_t 677 { 678 /* 0x00 */ u32 content_id; 679 /* 0x04 */ u16 index; 680 /* 0x06 */ u16 type; 681 /* 0x08 */ u64 size; 682 /* 0x10 */ u8 hash[WII_HASH_SIZE]; // SHA1 hash 683 } 684 __attribute__ ((packed)) wd_tmd_content_t; 685 686 // 687 /////////////////////////////////////////////////////////////////////////////// 688 /////////////// struct wd_tmd_t /////////////// 689 /////////////////////////////////////////////////////////////////////////////// 690 691 typedef struct wd_tmd_t 692 { 693 // --> http://wiibrew.org/wiki/Tmd_file_structure 694 695 /* 0x000 */ u32 sig_type; 696 /* 0x004 */ u8 sig[0x100]; 697 /* 0x104 */ u8 sig_padding[0x3c]; 698 699 // the signature calculations starts here (WII_TMD_SIG_OFF) 700 701 /* 0x140 */ u8 issuer[0x40]; 702 /* 0x180 */ u8 version; 703 /* 0x181 */ u8 ca_crl_version; 704 /* 0x182 */ u8 signer_crl_version; 705 /* 0x183 */ u8 padding2; 706 /* 0x184 */ u64 sys_version; // system version (the ios that the title need) 707 /* 0x18c */ u8 title_id[8]; 708 /* 0x194 */ u32 title_type; 709 /* 0x198 */ u16 group_id; 710 /* 0x19a */ u8 fake_sign[0x3e]; // padding => place of fake signing 711 /* 0x1d8 */ u32 access_rights; 712 /* 0x1dc */ u16 title_version; 713 /* 0x1de */ u16 n_content; 714 /* 0x1e0 */ u16 boot_index; 715 /* 0x1e2 */ u8 padding3[2]; 716 /* 0x1e4 */ wd_tmd_content_t content[0]; // n_contents elements 717 } 718 __attribute__ ((packed)) wd_tmd_t; 719 720 //----- encryption helpers 721 722 void tmd_setup ( wd_tmd_t * tmd, u32 tmd_size, const void * id4 ); 723 724 void tmd_clear_encryption ( wd_tmd_t * tmd, int mark_not_encrypted ); 725 bool tmd_is_marked_not_encrypted ( const wd_tmd_t * tmd ); 726 u32 tmd_fake_sign ( wd_tmd_t * tmd, u32 tmd_size ); 727 bool tmd_is_fake_signed ( const wd_tmd_t * tmd, u32 tmd_size ); 728 729 // 730 /////////////////////////////////////////////////////////////////////////////// 731 /////////////// struct wd_part_control_t /////////////// 732 /////////////////////////////////////////////////////////////////////////////// 733 734 typedef struct wd_part_control_t 735 { 736 u8 part_bin[WII_PARTITION_BIN_SIZE]; // this is the real data 737 738 // this are pointers into part_bin 739 740 wd_part_header_t * head; // pointer to header 741 wd_tmd_t * tmd; // pointer to tmd 742 wd_tmd_content_t * tmd_content; // NULL or pointer to first tmd content 743 u8 * cert; // pointer to cert 744 u8 * h3; // pointer to h3 745 746 // the following values are informative; format is host endian 747 748 int is_valid; // is structure valid 749 750 u32 head_size; // always sizeof(wd_part_header_t) 751 u32 tmd_size; // set by user 752 u32 cert_size; // set by user 753 u32 h3_size; // always WII_H3_SIZE 754 755 u64 data_off; // = sizeof(part_bin) if cleared 756 u64 data_size; // set by user 757 } 758 wd_part_control_t; // packing not needed 759 760 //----- setup 761 762 // 0:ok, 1:error, sizes to large 763 int clear_part_control 764 ( wd_part_control_t * pc, u32 tmd_size, u32 cert_size, u64 data_size ); 765 766 // 0:ok, 1:error => pc->part_bin must be valid content 767 int setup_part_control ( wd_part_control_t * pc ); 768 769 //----- encryption helpers 770 771 u32 part_control_fake_sign ( wd_part_control_t * pc, int calc_h4 ); 772 int part_control_is_fake_signed ( const wd_part_control_t * pc ); 773 774 // 775 /////////////////////////////////////////////////////////////////////////////// 776 /////////////// struct wd_part_sector_t /////////////// 777 /////////////////////////////////////////////////////////////////////////////// 778 779 typedef struct wd_part_sector_t 780 { 781 /* 0x000 */ u8 h0 [WII_N_ELEMENTS_H0][WII_HASH_SIZE]; 782 /* 0x26c */ u8 padding0[0x14]; 783 /* 0x280 */ u8 h1 [WII_N_ELEMENTS_H1][WII_HASH_SIZE]; 784 /* 0x320 */ u8 padding1[0x20]; 785 /* 0x340 */ u8 h2 [WII_N_ELEMENTS_H2][WII_HASH_SIZE]; 786 /* 0x3e0 */ u8 padding2[0x20]; 787 788 /* 0x400 */ u8 data[WII_N_ELEMENTS_H0][WII_H0_DATA_SIZE]; 789 } 790 __attribute__ ((packed)) wd_part_sector_t; 791 792 // 793 /////////////////////////////////////////////////////////////////////////////// 794 /////////////// struct wd_fst_item_t /////////////// 795 /////////////////////////////////////////////////////////////////////////////// 796 797 typedef struct wd_fst_item_t 798 { 799 union 800 { 801 u8 is_dir; 802 u32 name_off; // mask with 0x00ffffff 803 }; 804 805 u32 offset4; 806 u32 size; 807 } 808 __attribute__ ((packed)) wd_fst_item_t; 809 810 // 811 /////////////////////////////////////////////////////////////////////////////// 812 /////////////// struct wbfs_head_t /////////////// 813 /////////////////////////////////////////////////////////////////////////////// 814 815 typedef struct wbfs_head_t 816 { 817 /* 0 */ be32_t magic; // the magic (char*)"WBFS" 818 819 // the 3 main parameters -> they are used to calculate the geometry 820 821 /* 0x04 */ be32_t n_hd_sec; // total number of hd_sec in this partition 822 /* 0x08 */ u8 hd_sec_sz_s; // sector size in this partition 823 /* 0x09 */ u8 wbfs_sec_sz_s; // size of a wbfs sec 824 825 // more parameters 826 827 /* 0x0a */ u8 wbfs_version; // informative version number 828 /* 0x0b */ u8 padding; 829 /* 0x0c */ u8 disc_table[0]; // size depends on hd sector size 830 } 831 __attribute__ ((packed)) wbfs_head_t; 832 833 // 834 /////////////////////////////////////////////////////////////////////////////// 835 /////////////// struct wbfs_disc_info_t /////////////// 836 /////////////////////////////////////////////////////////////////////////////// 837 838 typedef struct wbfs_disc_info_t 839 { 840 /* 0 */ u8 dhead[0x100]; 841 /* 0x100 */ be16_t wlba_table[0]; // wbfs_t::n_wbfs_sec_per_disc elements 842 843 } 844 __attribute__ ((packed)) wbfs_disc_info_t; 845 846 // 847 /////////////////////////////////////////////////////////////////////////////// 848 /////////////// wit patch files /////////////// 849 /////////////////////////////////////////////////////////////////////////////// 850 851 // The data structure of a patch file is designed to allow reading 852 // and writing streams (pipe support, no file seek needed). 853 // The TOC (table of content) is placed at end of file and is only 854 // needed for search and for fast list operations. 855 856 // file layout: 857 // 858 // +-----------------------+ 859 // | patch header | 860 // +-----------------------+ 861 // | file manipulations | 862 // +-----------------------+ 863 // | toc file list | 864 // +-----------------------+ 865 // | toc header | 866 // +-----------------------+ 867 868 /////////////////////////////////////////////////////////////////////////////// 869 870 #define WIT_PATCH_MAGIC "WIT-PATCHER" 871 872 //----------------------------------------------------- 873 // Format of version number: AABBCCDD = A.BB | A.BB.CC 874 // If D != 0x00 && D != 0xff => append: 'beta' D 875 //----------------------------------------------------- 876 877 #define WIT_PATCH_VERSION 0x00010000 // current writing version 878 #define WIT_PATCH_COMPATIBLE 0x00010000 // down compatible 879 #define WIT_PATCH_READ_COMPATIBLE 0x00010000 // read compatible 880 881 extern const char wpat_magic[12]; 882 883 // 884 /////////////////////////////////////////////////////////////////////////////// 885 /////////////// enum wpat_type_t /////////////// 886 /////////////////////////////////////////////////////////////////////////////// 887 888 typedef enum wpat_type_t 889 { 890 //--- patch file header 891 892 WPAT_HEADER = 1, // wpat_header_t 893 894 //--- data records 895 896 WPAT_COMMENT, // wpat_comment_t 897 WPAT_DATA, // wpat_data_t 898 899 //--- file manipulation records 900 901 WPAT_DELETE_FILE, // wpat_filename_t 902 WPAT_CREATE_FILE, // wpat_filename_t -> wpat_data_t 903 WPAT_MOVE_FILE, // wpat_filenames_t 904 WPAT_COPY_FILE, // wpat_filenames_t 905 WPAT_LINK_FILE, // wpat_filenames_t 906 WPAT_PATCH_FILE, // wpat_patch_file_t -> wpat_data_t 907 908 //--- masks and flags 909 910 WPAT_M_ID = 0x3f, // mask of ID bits 911 WPAT_F_TOC = 0x40, // toc marker 912 913 //--- toc records 914 915 WPAT_TOC_HEADER = WPAT_F_TOC|WPAT_HEADER, // wpat_toc_header_t 916 WPAT_TOC_DELETE_FILE = WPAT_F_TOC|WPAT_DELETE_FILE, // wpat_toc_file_t 917 WPAT_TOC_CREATE_FILE = WPAT_F_TOC|WPAT_CREATE_FILE, // wpat_toc_file_t 918 WPAT_TOC_MOVE_FILE = WPAT_F_TOC|WPAT_MOVE_FILE, // wpat_toc_file_t 919 WPAT_TOC_COPY_FILE = WPAT_F_TOC|WPAT_COPY_FILE, // wpat_toc_file_t 920 WPAT_TOC_LINK_FILE = WPAT_F_TOC|WPAT_LINK_FILE, // wpat_toc_file_t 921 WPAT_TOC_PATCH_FILE = WPAT_F_TOC|WPAT_PATCH_FILE, // wpat_toc_file_t 922 } 923 __attribute__ ((packed)) wpat_type_t; 924 925 //----------------------------------------------------------------------------- 926 927 ccp wpat_get_type_name ( wpat_type_t type, ccp return_if_invalid ); 928 929 // 930 /////////////////////////////////////////////////////////////////////////////// 931 /////////////// union wpat_size_t /////////////// 932 /////////////////////////////////////////////////////////////////////////////// 933 934 typedef union wpat_size_t 935 { 936 wpat_type_t type; // type of patch record 937 u32 size4; // size of record, 938 // -> mask with 0xffffff, multiply with 4 939 } 940 __attribute__ ((packed)) wpat_size_t; 941 942 //----------------------------------------------------------------------------- 943 944 u32 wpat_get_size ( wpat_size_t type_size ); 945 wpat_size_t wpat_calc_size ( wpat_type_t type, u32 size ); 946 947 // 948 /////////////////////////////////////////////////////////////////////////////// 949 /////////////// struct wpat_header_t /////////////// 950 /////////////////////////////////////////////////////////////////////////////// 951 952 typedef struct wpat_header_t 953 { 954 /* 0x00 */ u8 magic[12]; // always 'WIT_PATCH_MAGIC' 955 // magic is *not* counted in 'type_size' 956 957 /* 0x0c */ wpat_size_t type_size; // type (WPAT_HEADER) and record size 958 /* 0x10 */ u32 version; // patch file version 959 /* 0x14 */ u32 compatible; // patch file down compatible to version 960 /* 0x18 */ char reserved[0]; // reserved for future extensions 961 } 962 __attribute__ ((packed)) wpat_header_t; 963 964 // 965 /////////////////////////////////////////////////////////////////////////////// 966 /////////////// struct wpat_comment_t /////////////// 967 /////////////////////////////////////////////////////////////////////////////// 968 969 typedef struct wpat_comment_t 970 { 971 /* 0x00 */ wpat_size_t type_size; // type (WPAT_COMMENT) and record size 972 /* 0x04 */ u8 comment[0]; // comment string 973 } 974 __attribute__ ((packed)) wpat_comment_t; 975 976 // 977 /////////////////////////////////////////////////////////////////////////////// 978 /////////////// struct wpat_data_t /////////////// 979 /////////////////////////////////////////////////////////////////////////////// 980 981 typedef struct wpat_data_t 982 { 983 /* 0x00 */ wpat_size_t type_size; // type (WPAT_DATA) and record size 984 /* 0x04 */ u32 file_offset; // offset in files 985 /* 0x08 */ u32 data_size; // used length of patch 'data' 986 /* 0x0c */ u8 data[0]; // patch or source data 987 988 // - WPAT_PATCH_FILE: 989 // patch data is XORed with orig data 990 // if >src_size: use cyclic 'src_hash' to XOR 991 // - WPAT_CRATE_FILE: 992 // 1:1 source data 993 } 994 __attribute__ ((packed)) wpat_data_t; 995 996 // 997 /////////////////////////////////////////////////////////////////////////////// 998 /////////////// struct wpat_filename_t /////////////// 999 /////////////////////////////////////////////////////////////////////////////// 1000 1001 typedef struct wpat_filename_t 1002 { 1003 /* 0x00 */ wpat_size_t type_size; // type and record size 1004 /* 0x04 */ char fname[0]; // filename, size always multiple of 4 1005 } 1006 __attribute__ ((packed)) wpat_filename_t; 1007 1008 // 1009 /////////////////////////////////////////////////////////////////////////////// 1010 /////////////// struct wpat_filenames_t /////////////// 1011 /////////////////////////////////////////////////////////////////////////////// 1012 1013 typedef struct wpat_filenames_t 1014 { 1015 /* 0x00 */ wpat_size_t type_size; // type and record size 1016 /* 0x04 */ u32 src_file_off; // offset in 'fnames' of source filename 1017 /* 0x08 */ char fnames[0]; // 2 filenames, size always multiple of 4 1018 // -> dest_filname, src_filename 1019 } 1020 __attribute__ ((packed)) wpat_filenames_t; 1021 1022 // 1023 /////////////////////////////////////////////////////////////////////////////// 1024 /////////////// struct wpat_patch_file_t /////////////// 1025 /////////////////////////////////////////////////////////////////////////////// 1026 1027 typedef struct wpat_patch_file_t 1028 { 1029 /* 0x00 */ wpat_size_t type_size; // type (WPAT_PATCH_FILE) and record size 1030 /* 0x04 */ u32 src_file_size; // size of source file, 0=new file 1031 /* 0x08 */ u32 dest_file_size; // size of destination file 1032 /* 0x0c */ sha1_hash_t src_hash; // SHA1 hash of source file 1033 /* 0x20 */ sha1_hash_t dest_hash; // SHA1 hash of destination file 1034 /* 0x34 */ char fname[0]; // filename, size always multiple of 4 1035 } 1036 __attribute__ ((packed)) wpat_patch_file_t; 1037 1038 // 1039 /////////////////////////////////////////////////////////////////////////////// 1040 /////////////// struct wpat_toc_header_t /////////////// 1041 /////////////////////////////////////////////////////////////////////////////// 1042 1043 typedef struct wpat_toc_header_t 1044 { 1045 /* 0x00 */ wpat_size_t type_size; // type (WPAT_TOC_HEADER) and record size 1046 /* 0x04 */ u32 entry_offset4; // file offset/4 of first entry 1047 /* 0x0c */ u32 n_entires; // number of 'wpat_toc_file_t' entries 1048 /* 0x10 */ u8 magic[12]; // always 'WIT_PATCH_MAGIC' 1049 /* 0x1c */ 1050 } 1051 __attribute__ ((packed)) wpat_toc_header_t; 1052 1053 // 1054 /////////////////////////////////////////////////////////////////////////////// 1055 /////////////// struct wpat_toc_file_t /////////////// 1056 /////////////////////////////////////////////////////////////////////////////// 1057 1058 typedef struct wpat_toc_file_t 1059 { 1060 /* 0x00 */ wpat_size_t type_size; // type (WPAT_F_TOC set) and record size 1061 /* 0x04 */ u32 item_offset4; // file offset/4 of file item 1062 /* 0x0c */ char fname[0]; // filename, size always multiple of 4 1063 // informative only 1064 } 1065 __attribute__ ((packed)) wpat_toc_file_t; 1066 1067 // 1068 /////////////////////////////////////////////////////////////////////////////// 1069 /////////////// consts & vars /////////////// 1070 /////////////////////////////////////////////////////////////////////////////// 1071 1072 extern const char skeleton_marker[10]; 1073 1074 // 1075 /////////////////////////////////////////////////////////////////////////////// 1076 /////////////// E N D /////////////// 1077 /////////////////////////////////////////////////////////////////////////////// 1078 1079 #endif // FILE_FORMATS_H 1080