diff --git a/Cargo.lock b/Cargo.lock index 41d517a..76b90cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,19 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "const-random", + "once_cell", + "version_check", + "zerocopy 0.7.35", +] + [[package]] name = "autocfg" version = "1.4.0" @@ -35,12 +48,6 @@ version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "byteorder-lite" version = "0.1.0" @@ -53,11 +60,31 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] @@ -71,6 +98,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crunchy" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" + [[package]] name = "crypto-common" version = "0.1.6" @@ -99,22 +132,23 @@ dependencies = [ [[package]] name = "editpe" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cede2bb1b07dd598d269f973792c43e0cd92686d3b452bd6e01d7a8eb01211" +checksum = "7a7ef4fd9152764fe33ef270a380032555744da2f264a5634ae22003fcbba4e5" dependencies = [ + "ahash", "debug-ignore", "indexmap", "log", "thiserror", - "zerocopy", + "zerocopy 0.8.24", ] [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "fdeflate" @@ -145,11 +179,22 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "image" @@ -165,9 +210,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", "hashbrown", @@ -175,9 +220,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.155" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libsui" @@ -188,20 +233,20 @@ dependencies = [ "libc", "sha2", "windows-sys", - "zerocopy", + "zerocopy 0.8.24", ] [[package]] name = "log" -version = "0.4.22" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "miniz_oxide" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff70ce3e48ae43fa075863cef62e8b43b71a4f2382229920e0df362592919430" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" dependencies = [ "adler2", "simd-adler32", @@ -216,6 +261,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + [[package]] name = "png" version = "0.17.16" @@ -231,18 +282,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -266,9 +317,9 @@ checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "syn" -version = "2.0.71" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -277,41 +328,56 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "typenum" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "windows-sys" @@ -385,8 +451,16 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ - "byteorder", - "zerocopy-derive", + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +dependencies = [ + "zerocopy-derive 0.8.24", ] [[package]] @@ -399,3 +473,14 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zerocopy-derive" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index cf80c11..5afeee0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,8 +10,8 @@ repository = "https://github.com/denoland/sui" [dependencies] image = { version = "0.25", default-features = false, features = ["bmp", "ico", "png"] } libc = "0.2" -editpe = { version = "0.1.0", default-features = false } -zerocopy = { version = "0.7", features = ["derive"] } +editpe = { version = "0.2.1", features = ["std"], default-features = false } +zerocopy = { version = "0.8", features = ["derive"] } sha2 = "0.10" # object = { version = "0.36.1", features = ["build"] } diff --git a/apple_codesign.rs b/apple_codesign.rs index be19430..3cc8779 100644 --- a/apple_codesign.rs +++ b/apple_codesign.rs @@ -24,12 +24,12 @@ */ use sha2::{Digest, Sha256}; use zerocopy::byteorder::big_endian; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, FromZeros, Immutable, IntoBytes, KnownLayout}; use crate::{Error, Header64, SegmentCommand64, LC_CODE_SIGNATURE, LC_SEGMENT_64}; use core::mem::size_of; -#[derive(Debug, Clone, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Clone, FromBytes, IntoBytes, Immutable)] #[repr(C)] struct SuperBlob { magic: big_endian::U32, @@ -37,7 +37,7 @@ struct SuperBlob { count: big_endian::U32, } -#[derive(Debug, Clone, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Clone, FromBytes, IntoBytes, Immutable)] #[repr(C)] struct Blob { typ: big_endian::U32, @@ -45,7 +45,7 @@ struct Blob { } #[repr(C)] -#[derive(Debug, Clone, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Clone, FromBytes, IntoBytes, Immutable)] struct CodeDirectory { magic: big_endian::U32, // magic number (CSMAGIC_CODEDIRECTORY) length: big_endian::U32, // total length of CodeDirectory blob @@ -70,7 +70,7 @@ struct CodeDirectory { exec_seg_flags: big_endian::U64, } -#[derive(FromBytes, FromZeroes, AsBytes, Debug)] +#[derive(FromBytes, IntoBytes, KnownLayout, Debug)] #[repr(C)] struct LinkeditDataCommand { cmd: u32, @@ -101,8 +101,8 @@ const CS_EXECSEG_MAIN_BINARY: u64 = 0x1; // executable segment denotes main bina impl MachoSigner { pub fn new(obj: Vec) -> Result { - let header = Header64::read_from_prefix(&obj) - .ok_or(Error::InvalidObject("Invalid Mach-O header"))?; + let (header, _body) = Header64::read_from_prefix(&obj) + .map_err(|_| Error::InvalidObject("Invalid Mach-O header"))?; let mut offset = size_of::(); let mut sig_off = 0; @@ -126,15 +126,15 @@ impl MachoSigner { ); if cmd == LC_CODE_SIGNATURE { - let cmd = LinkeditDataCommand::read_from_prefix(&obj[offset..]) - .ok_or(Error::InvalidObject("Failed to read linkedit data command"))?; + let (cmd, _body) = LinkeditDataCommand::read_from_prefix(&obj[offset..]) + .map_err(|_| Error::InvalidObject("Failed to read linkedit data command"))?; sig_off = cmd.dataoff as usize; sig_sz = cmd.datasize as usize; cs_cmd_off = offset; } if cmd == LC_SEGMENT_64 { - let segcmd = SegmentCommand64::read_from_prefix(&obj[offset..]) - .ok_or(Error::InvalidObject("Failed to read segment command"))?; + let (segcmd, _body) = SegmentCommand64::read_from_prefix(&obj[offset..]) + .map_err(|_| Error::InvalidObject("Failed to read segment command"))?; // Convert fixed size array terminated by null byte to string let segname = String::from_utf8_lossy(&segcmd.segname); let segname = segname.trim_end_matches('\0'); @@ -173,15 +173,15 @@ impl MachoSigner { if self.sig_sz != sz { // Update the load command - let cs_cmd = LinkeditDataCommand::mut_from_prefix(&mut self.data[self.cs_cmd_off..]) - .ok_or(Error::InvalidObject("Failed to read linkedit data command"))?; + let (cs_cmd, _body) = LinkeditDataCommand::mut_from_prefix(&mut self.data[self.cs_cmd_off..]) + .map_err(|_| Error::InvalidObject("Failed to read linkedit data command"))?; cs_cmd.datasize = sz as u32; // Update __LINKEDIT segment let seg_sz = self.sig_off + sz - self.linkedit_seg.fileoff as usize; - let linkedit_seg = + let (linkedit_seg, _body) = SegmentCommand64::mut_from_prefix(&mut self.data[self.linkedit_off..]) - .ok_or(Error::InvalidObject("Failed to read linkedit segment"))?; + .map_err(|_| Error::InvalidObject("Failed to read linkedit segment"))?; linkedit_seg.filesize = seg_sz as u64; linkedit_seg.vmsize = seg_sz as u64; } diff --git a/lib.rs b/lib.rs index e8a74cc..8703005 100644 --- a/lib.rs +++ b/lib.rs @@ -53,7 +53,7 @@ use editpe::{ use image::{imageops::FilterType::Lanczos3, ImageFormat, ImageReader}; use std::io::Cursor; use std::io::Write; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, FromZeros, Immutable, IntoBytes, KnownLayout}; pub mod apple_codesign; @@ -205,7 +205,7 @@ impl<'a> PortableExecutable<'a> { .to_rgba8() .write_to(&mut Cursor::new(&mut data), ImageFormat::Ico)?; - let mut entry = IconDirectoryEntry::read_from_prefix(&data[6..20]).unwrap(); + let (mut entry, _body) = IconDirectoryEntry::read_from_prefix(&data[6..20]).unwrap(); entry.id = id as u16; icon_directory_entries.push(entry); data[22..].to_owned() @@ -328,7 +328,7 @@ mod pe { } #[repr(C)] -#[derive(Debug, Clone, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Clone, FromBytes, IntoBytes, Immutable, KnownLayout)] pub(crate) struct SegmentCommand64 { cmd: u32, cmdsize: u32, @@ -343,7 +343,7 @@ pub(crate) struct SegmentCommand64 { flags: u32, } -#[derive(FromBytes, FromZeroes, AsBytes)] +#[derive(FromBytes, IntoBytes, Immutable)] #[repr(C)] pub(crate) struct Header64 { magic: u32, @@ -357,7 +357,7 @@ pub(crate) struct Header64 { } #[repr(C)] -#[derive(Debug, Clone, FromBytes, FromZeroes, AsBytes)] +#[derive(Debug, Clone, FromBytes, IntoBytes, Immutable)] pub(crate) struct Section64 { sectname: [u8; 16], segname: [u8; 16], @@ -425,8 +425,8 @@ pub(crate) const SEGNAME: [u8; 16] = *b"__SUI\0\0\0\0\0\0\0\0\0\0\0"; impl Macho { pub fn from(obj: Vec) -> Result { - let header = Header64::read_from_prefix(&obj) - .ok_or(Error::InvalidObject("Failed to read header"))?; + let (header, _body) = Header64::read_from_prefix(&obj) + .map_err(|_| Error::InvalidObject("Failed to read header"))?; let mut commands: Vec<(u32, u32, usize)> = Vec::with_capacity(header.ncmds as usize); let mut offset = size_of::(); @@ -445,8 +445,8 @@ impl Macho { ); if cmd == LC_SEGMENT_64 { - let segcmd = SegmentCommand64::read_from_prefix(&obj[offset..]) - .ok_or(Error::InvalidObject("Failed to read segment command"))?; + let (segcmd, _body) = SegmentCommand64::read_from_prefix(&obj[offset..]) + .map_err(|_| Error::InvalidObject("Failed to read segment command"))?; if segcmd.segname[..SEG_LINKEDIT.len()] == *SEG_LINKEDIT { linkedit_cmd = Some(segcmd); } @@ -525,7 +525,7 @@ impl Macho { for (cmd, _, offset) in self.commands.iter_mut() { match *cmd { LC_SYMTAB => { - #[derive(FromBytes, FromZeroes, AsBytes)] + #[derive(IntoBytes, KnownLayout, FromBytes)] #[repr(C)] pub struct SymtabCommand { pub cmd: u32, @@ -536,13 +536,13 @@ impl Macho { pub strsize: u32, } - let cmd = SymtabCommand::mut_from_prefix(&mut self.data[*offset..]) - .ok_or(Error::InvalidObject("Failed to read symtab command"))?; + let (cmd, _body) = SymtabCommand::mut_from_prefix(&mut self.data[*offset..]) + .map_err(|_| Error::InvalidObject("Failed to read symtab command"))?; shift_cmd!(cmd.symoff); shift_cmd!(cmd.stroff); } LC_DYSYMTAB => { - #[derive(FromBytes, FromZeroes, AsBytes)] + #[derive(FromBytes, IntoBytes, KnownLayout)] #[repr(C)] pub struct DysymtabCommand { pub cmd: u32, @@ -567,8 +567,8 @@ impl Macho { pub nlocrel: u32, } - let cmd = DysymtabCommand::mut_from_prefix(&mut self.data[*offset..]) - .ok_or(Error::InvalidObject("Failed to read dysymtab command"))?; + let (cmd, _body) = DysymtabCommand::mut_from_prefix(&mut self.data[*offset..]) + .map_err(|_| Error::InvalidObject("Failed to read dysymtab command"))?; shift_cmd!(cmd.tocoff); shift_cmd!(cmd.modtaboff); shift_cmd!(cmd.extrefsymoff); @@ -584,7 +584,7 @@ impl Macho { | LC_LINKER_OPTIMIZATION_HINT | LC_DYLD_EXPORTS_TRIE | LC_DYLD_CHAINED_FIXUPS => { - #[derive(FromBytes, FromZeroes, AsBytes)] + #[derive(FromBytes, IntoBytes, KnownLayout)] #[repr(C)] struct LinkeditDataCommand { cmd: u32, @@ -592,13 +592,13 @@ impl Macho { dataoff: u32, datasize: u32, } - let cmd = LinkeditDataCommand::mut_from_prefix(&mut self.data[*offset..]) - .ok_or(Error::InvalidObject("Failed to read linkedit data command"))?; + let (cmd, _body) = LinkeditDataCommand::mut_from_prefix(&mut self.data[*offset..]) + .map_err(|_| Error::InvalidObject("Failed to read linkedit data command"))?; shift_cmd!(cmd.dataoff); } LC_DYLD_INFO | LC_DYLD_INFO_ONLY => { - #[derive(FromBytes, FromZeroes, AsBytes)] + #[derive(FromBytes, IntoBytes, KnownLayout)] #[repr(C)] pub struct DyldInfoCommand { pub cmd: u32, @@ -614,8 +614,8 @@ impl Macho { pub export_off: u32, pub export_size: u32, } - let dyld_info = DyldInfoCommand::mut_from_prefix(&mut self.data[*offset..]) - .ok_or(Error::InvalidObject("Failed to read dyld info command"))?; + let (dyld_info, _body) = DyldInfoCommand::mut_from_prefix(&mut self.data[*offset..]) + .map_err(|_| Error::InvalidObject("Failed to read dyld info command"))?; shift_cmd!(dyld_info.rebase_off); shift_cmd!(dyld_info.bind_off); shift_cmd!(dyld_info.weak_bind_off); @@ -640,8 +640,8 @@ impl Macho { for (cmd, cmdsize, offset) in self.commands.iter_mut() { if *cmd == LC_SEGMENT_64 { - let segcmd = SegmentCommand64::read_from_prefix(&self.data[*offset..]) - .ok_or(Error::InvalidObject("Failed to read segment command"))?; + let (segcmd, _body) = SegmentCommand64::read_from_prefix(&self.data[*offset..]) + .map_err(|_| Error::InvalidObject("Failed to read segment command"))?; if segcmd.segname[..SEG_LINKEDIT.len()] == *SEG_LINKEDIT { writer.write_all(self.seg.as_bytes())?; writer.write_all(self.sec.as_bytes())?;