mirror of https://github.com/encounter/nod-rs.git
Extract Wii region.bin
This commit is contained in:
parent
d99ef72fe9
commit
f4638369d1
|
@ -441,7 +441,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nod"
|
name = "nod"
|
||||||
version = "1.4.1"
|
version = "1.4.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"adler",
|
"adler",
|
||||||
"aes",
|
"aes",
|
||||||
|
@ -464,7 +464,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nodtool"
|
name = "nodtool"
|
||||||
version = "1.4.1"
|
version = "1.4.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argp",
|
"argp",
|
||||||
"base16ct",
|
"base16ct",
|
||||||
|
@ -1033,18 +1033,18 @@ checksum = "6a5cbf750400958819fb6178eaa83bee5cd9c29a26a40cc241df8c70fdd46984"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "df7885ffcb82507a0f213c593e77c5f13d12cb96588d4e835ad7e9423ba034db"
|
checksum = "dd2e5ce961dea177d282ec084dca2aa411b7411199a68d79eb1beacb305a6cd9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerocopy-derive",
|
"zerocopy-derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy-derive"
|
name = "zerocopy-derive"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "930ad75608219e8ffdb8962a5433cb2b30064c7ccb564d3b76c2963390b1e435"
|
checksum = "b06304eeddb6081af98ac59db08c868ac197e586086b996d15a86ed70e09a754"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
@ -9,7 +9,7 @@ strip = "debuginfo"
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "1.4.1"
|
version = "1.4.2"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.74"
|
rust-version = "1.74"
|
||||||
authors = ["Luke Street <luke@street.dev>"]
|
authors = ["Luke Street <luke@street.dev>"]
|
||||||
|
|
|
@ -214,6 +214,7 @@ pub(crate) fn read_part_meta(
|
||||||
raw_apploader: raw_apploader.into_boxed_slice(),
|
raw_apploader: raw_apploader.into_boxed_slice(),
|
||||||
raw_fst,
|
raw_fst,
|
||||||
raw_dol: raw_dol.into_boxed_slice(),
|
raw_dol: raw_dol.into_boxed_slice(),
|
||||||
|
raw_region: None,
|
||||||
raw_ticket: None,
|
raw_ticket: None,
|
||||||
raw_tmd: None,
|
raw_tmd: None,
|
||||||
raw_cert_chain: None,
|
raw_cert_chain: None,
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub(crate) mod wii;
|
||||||
|
|
||||||
pub use fst::{Fst, Node, NodeKind};
|
pub use fst::{Fst, Node, NodeKind};
|
||||||
pub use streams::{FileStream, OwnedFileStream, WindowedStream};
|
pub use streams::{FileStream, OwnedFileStream, WindowedStream};
|
||||||
pub use wii::{SignedHeader, Ticket, TicketLimit, TmdHeader};
|
pub use wii::{SignedHeader, Ticket, TicketLimit, TmdHeader, REGION_SIZE};
|
||||||
|
|
||||||
/// Size in bytes of a disc sector.
|
/// Size in bytes of a disc sector.
|
||||||
pub const SECTOR_SIZE: usize = 0x8000;
|
pub const SECTOR_SIZE: usize = 0x8000;
|
||||||
|
@ -365,6 +365,8 @@ pub struct PartitionMeta {
|
||||||
pub raw_fst: Box<[u8]>,
|
pub raw_fst: Box<[u8]>,
|
||||||
/// Main binary (main.dol)
|
/// Main binary (main.dol)
|
||||||
pub raw_dol: Box<[u8]>,
|
pub raw_dol: Box<[u8]>,
|
||||||
|
/// Disc region info (region.bin, Wii only)
|
||||||
|
pub raw_region: Option<Box<[u8; REGION_SIZE]>>,
|
||||||
/// Ticket (ticket.bin, Wii only)
|
/// Ticket (ticket.bin, Wii only)
|
||||||
pub raw_ticket: Option<Box<[u8]>>,
|
pub raw_ticket: Option<Box<[u8]>>,
|
||||||
/// TMD (tmd.bin, Wii only)
|
/// TMD (tmd.bin, Wii only)
|
||||||
|
|
|
@ -21,7 +21,10 @@ use crate::{
|
||||||
KeyBytes,
|
KeyBytes,
|
||||||
},
|
},
|
||||||
static_assert,
|
static_assert,
|
||||||
util::{div_rem, read::read_box_slice},
|
util::{
|
||||||
|
div_rem,
|
||||||
|
read::{read_box, read_box_slice},
|
||||||
|
},
|
||||||
Error, OpenOptions, Result, ResultContext,
|
Error, OpenOptions, Result, ResultContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,6 +34,12 @@ pub(crate) const HASHES_SIZE: usize = 0x400;
|
||||||
/// Size in bytes of the data block in a Wii disc sector (excluding hashes)
|
/// Size in bytes of the data block in a Wii disc sector (excluding hashes)
|
||||||
pub(crate) const SECTOR_DATA_SIZE: usize = SECTOR_SIZE - HASHES_SIZE; // 0x7C00
|
pub(crate) const SECTOR_DATA_SIZE: usize = SECTOR_SIZE - HASHES_SIZE; // 0x7C00
|
||||||
|
|
||||||
|
/// Size of the disc region info (region.bin)
|
||||||
|
pub const REGION_SIZE: usize = 0x20;
|
||||||
|
|
||||||
|
/// Offset of the disc region info
|
||||||
|
pub const REGION_OFFSET: u64 = 0x4E000;
|
||||||
|
|
||||||
// ppki (Retail)
|
// ppki (Retail)
|
||||||
const RVL_CERT_ISSUER_PPKI_TICKET: &str = "Root-CA00000001-XS00000003";
|
const RVL_CERT_ISSUER_PPKI_TICKET: &str = "Root-CA00000001-XS00000003";
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
@ -270,6 +279,7 @@ pub struct PartitionWii {
|
||||||
sector: u32,
|
sector: u32,
|
||||||
pos: u64,
|
pos: u64,
|
||||||
verify: bool,
|
verify: bool,
|
||||||
|
raw_region: Box<[u8; REGION_SIZE]>,
|
||||||
raw_tmd: Box<[u8]>,
|
raw_tmd: Box<[u8]>,
|
||||||
raw_cert_chain: Box<[u8]>,
|
raw_cert_chain: Box<[u8]>,
|
||||||
raw_h3_table: Box<[u8]>,
|
raw_h3_table: Box<[u8]>,
|
||||||
|
@ -287,6 +297,7 @@ impl Clone for PartitionWii {
|
||||||
sector: u32::MAX,
|
sector: u32::MAX,
|
||||||
pos: 0,
|
pos: 0,
|
||||||
verify: self.verify,
|
verify: self.verify,
|
||||||
|
raw_region: self.raw_region.clone(),
|
||||||
raw_tmd: self.raw_tmd.clone(),
|
raw_tmd: self.raw_tmd.clone(),
|
||||||
raw_cert_chain: self.raw_cert_chain.clone(),
|
raw_cert_chain: self.raw_cert_chain.clone(),
|
||||||
raw_h3_table: self.raw_h3_table.clone(),
|
raw_h3_table: self.raw_h3_table.clone(),
|
||||||
|
@ -304,6 +315,10 @@ impl PartitionWii {
|
||||||
let block_size = inner.block_size();
|
let block_size = inner.block_size();
|
||||||
let mut reader = PartitionGC::new(inner, disc_header)?;
|
let mut reader = PartitionGC::new(inner, disc_header)?;
|
||||||
|
|
||||||
|
// Read region
|
||||||
|
reader.seek(SeekFrom::Start(REGION_OFFSET)).context("Seeking to region offset")?;
|
||||||
|
let raw_region: Box<[u8; REGION_SIZE]> = read_box(&mut reader).context("Reading region")?;
|
||||||
|
|
||||||
// Read TMD, cert chain, and H3 table
|
// Read TMD, cert chain, and H3 table
|
||||||
let offset = partition.start_sector as u64 * SECTOR_SIZE as u64;
|
let offset = partition.start_sector as u64 * SECTOR_SIZE as u64;
|
||||||
reader
|
reader
|
||||||
|
@ -333,6 +348,7 @@ impl PartitionWii {
|
||||||
sector: u32::MAX,
|
sector: u32::MAX,
|
||||||
pos: 0,
|
pos: 0,
|
||||||
verify: options.validate_hashes,
|
verify: options.validate_hashes,
|
||||||
|
raw_region,
|
||||||
raw_tmd,
|
raw_tmd,
|
||||||
raw_cert_chain,
|
raw_cert_chain,
|
||||||
raw_h3_table,
|
raw_h3_table,
|
||||||
|
@ -482,6 +498,7 @@ impl PartitionBase for PartitionWii {
|
||||||
fn meta(&mut self) -> Result<Box<PartitionMeta>> {
|
fn meta(&mut self) -> Result<Box<PartitionMeta>> {
|
||||||
self.seek(SeekFrom::Start(0)).context("Seeking to partition header")?;
|
self.seek(SeekFrom::Start(0)).context("Seeking to partition header")?;
|
||||||
let mut meta = read_part_meta(self, true)?;
|
let mut meta = read_part_meta(self, true)?;
|
||||||
|
meta.raw_region = Some(self.raw_region.clone());
|
||||||
meta.raw_ticket = Some(Box::from(self.partition.header.ticket.as_bytes()));
|
meta.raw_ticket = Some(Box::from(self.partition.header.ticket.as_bytes()));
|
||||||
meta.raw_tmd = Some(self.raw_tmd.clone());
|
meta.raw_tmd = Some(self.raw_tmd.clone());
|
||||||
meta.raw_cert_chain = Some(self.raw_cert_chain.clone());
|
meta.raw_cert_chain = Some(self.raw_cert_chain.clone());
|
||||||
|
|
|
@ -152,18 +152,21 @@ fn extract_sys_files(
|
||||||
fs::create_dir_all(&disc_dir)
|
fs::create_dir_all(&disc_dir)
|
||||||
.with_context(|| format!("Creating directory {}", display(&disc_dir)))?;
|
.with_context(|| format!("Creating directory {}", display(&disc_dir)))?;
|
||||||
extract_file(&header.as_bytes()[..0x100], &disc_dir.join("header.bin"), quiet)?;
|
extract_file(&header.as_bytes()[..0x100], &disc_dir.join("header.bin"), quiet)?;
|
||||||
}
|
if let Some(region) = data.raw_region.as_deref() {
|
||||||
if let Some(ticket) = data.raw_ticket.as_deref() {
|
extract_file(region, &disc_dir.join("region.bin"), quiet)?;
|
||||||
extract_file(ticket, &out_dir.join("ticket.bin"), quiet)?;
|
}
|
||||||
}
|
if let Some(ticket) = data.raw_ticket.as_deref() {
|
||||||
if let Some(tmd) = data.raw_tmd.as_deref() {
|
extract_file(ticket, &out_dir.join("ticket.bin"), quiet)?;
|
||||||
extract_file(tmd, &out_dir.join("tmd.bin"), quiet)?;
|
}
|
||||||
}
|
if let Some(tmd) = data.raw_tmd.as_deref() {
|
||||||
if let Some(cert_chain) = data.raw_cert_chain.as_deref() {
|
extract_file(tmd, &out_dir.join("tmd.bin"), quiet)?;
|
||||||
extract_file(cert_chain, &out_dir.join("cert.bin"), quiet)?;
|
}
|
||||||
}
|
if let Some(cert_chain) = data.raw_cert_chain.as_deref() {
|
||||||
if let Some(h3_table) = data.raw_h3_table.as_deref() {
|
extract_file(cert_chain, &out_dir.join("cert.bin"), quiet)?;
|
||||||
extract_file(h3_table, &out_dir.join("h3.bin"), quiet)?;
|
}
|
||||||
|
if let Some(h3_table) = data.raw_h3_table.as_deref() {
|
||||||
|
extract_file(h3_table, &out_dir.join("h3.bin"), quiet)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue