From c7ab4da1a7c0ecb9508d585075b88c173948642c Mon Sep 17 00:00:00 2001 From: angie Date: Thu, 11 Jan 2024 15:40:18 -0300 Subject: [PATCH] CICKind.get_entrypoint --- CHANGELOG.md | 5 +++++ bindings/c/include/ipl3checksum/cickinds.h | 2 ++ src/ipl3checksum/cickinds.pyi | 8 +++++++ src/rs/checksum.rs | 6 +----- src/rs/cickinds.rs | 25 ++++++++++++++++++++++ 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0078400..a9e94e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- `CICKind.get_entrypoint`: Returns the entrypoint address that would be used + on runtime. + ### Changed - Rewrite the checksum algorithm for readability and simplicity. diff --git a/bindings/c/include/ipl3checksum/cickinds.h b/bindings/c/include/ipl3checksum/cickinds.h index bed923c..6f4d7f7 100644 --- a/bindings/c/include/ipl3checksum/cickinds.h +++ b/bindings/c/include/ipl3checksum/cickinds.h @@ -29,6 +29,8 @@ uint32_t ipl3checksum_cickind_get_seed(Ipl3Checksum_CICKind self); uint32_t ipl3checksum_cickind_get_magic(Ipl3Checksum_CICKind self); +uint32_t ipl3checksum_cickind_get_entrypoint(Ipl3Checksum_CICKind self, uint32_t header_entrypoint); + /** * Returns the md5 hash for the specified CIC kind. * diff --git a/src/ipl3checksum/cickinds.pyi b/src/ipl3checksum/cickinds.pyi index 1a86808..8d309a2 100644 --- a/src/ipl3checksum/cickinds.pyi +++ b/src/ipl3checksum/cickinds.pyi @@ -20,6 +20,7 @@ class CICKind(): def getSeed(self) -> int: """ Seed value set by the PIF ROM before the CPU (and the IPL3) is executed. + https://n64brew.dev/wiki/PIF-NUS#IPL3_checksum_algorithm """ @@ -28,6 +29,13 @@ class CICKind(): Magic value hardcoded inside the IPL3 itself """ + def getEntrypoint(self, header_entrypoint: int) -> int: + """ + Calculates the actual entrypoint address based on the entrypoint specified on the header. + + CIC 7102 is a notable case since its IPL3 hardcodes it, ignoring the entrypoint from the header. + """ + def getHashMd5(self) -> str: """ Expected md5 hash of the IPL3 blob diff --git a/src/rs/checksum.rs b/src/rs/checksum.rs index 2cca1ab..e0cbf56 100644 --- a/src/rs/checksum.rs +++ b/src/rs/checksum.rs @@ -7,11 +7,7 @@ use crate::{detect, error::Ipl3ChecksumError, utils}; fn get_entrypoint_addr(rom_bytes: &[u8], kind: CICKind) -> Result { let entrypoint_addr: u32 = utils::read_u32(rom_bytes, 8)?; - match kind { - CICKind::CIC_X103 | CICKind::CIC_5101 => Ok(entrypoint_addr.wrapping_sub(0x100000)), - CICKind::CIC_X106 => Ok(entrypoint_addr.wrapping_sub(0x200000)), - _ => Ok(entrypoint_addr), - } + Ok(kind.get_entrypoint(entrypoint_addr)) } const HEADER_IPL3_SIZE: usize = 0x1000; diff --git a/src/rs/cickinds.rs b/src/rs/cickinds.rs index 998aa0c..d0b3661 100644 --- a/src/rs/cickinds.rs +++ b/src/rs/cickinds.rs @@ -27,6 +27,9 @@ pub enum CICKind { } impl CICKind { + /// Seed value set by the PIF ROM before the CPU (and the IPL3) is executed. + /// + /// https://n64brew.dev/wiki/PIF-NUS#IPL3_checksum_algorithm pub fn get_seed(&self) -> u32 { match self { Self::CIC_6101 | Self::CIC_6102_7101 | Self::CIC_7102 => 0x3F, @@ -37,6 +40,7 @@ impl CICKind { } } + /// Magic value hardcoded inside the IPL3 itself pub fn get_magic(&self) -> u32 { match self { Self::CIC_6101 | Self::CIC_6102_7101 | Self::CIC_7102 | Self::CIC_X105 => 0x5D588B65, @@ -44,6 +48,18 @@ impl CICKind { } } + /// Calculates the actual entrypoint address based on the entrypoint specified on the header. + /// + /// CIC 7102 is a notable case since its IPL3 hardcodes it, ignoring the entrypoint from the header. + pub fn get_entrypoint(&self, header_entrypoint: u32) -> u32 { + match self { + CICKind::CIC_7102 => 0x80000480, + CICKind::CIC_X103 | CICKind::CIC_5101 => header_entrypoint.wrapping_sub(0x100000), + CICKind::CIC_X106 => header_entrypoint.wrapping_sub(0x200000), + _ => header_entrypoint, + } + } + pub fn get_hash_md5(&self) -> &'static str { match self { Self::CIC_6101 => "900b4a5b68edb71f4c7ed52acd814fc5", @@ -163,6 +179,10 @@ mod python_bindings { self.get_magic() } + pub fn getEntrypoint(&self, header_entrypoint: u32) -> u32 { + self.get_entrypoint(header_entrypoint) + } + pub fn getHashMd5(&self) -> &str { self.get_hash_md5() } @@ -226,6 +246,11 @@ mod c_bindings { kind.get_magic() } + #[no_mangle] + pub extern "C" fn ipl3checksum_cickind_get_entrypoint(kind: CICKind, header_entrypoint: u32) -> u32 { + kind.get_entrypoint(header_entrypoint) + } + #[no_mangle] pub extern "C" fn ipl3checksum_cickind_get_hash_md5( kind: CICKind,