diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..a91a19f --- /dev/null +++ b/src/main.rs @@ -0,0 +1,70 @@ +use std::io::{Cursor, Read, Write, Seek, SeekFrom}; +use std::fs::File; +use std::error::Error; +use std::env; + +use memmap2::MmapOptions; +use byteorder::{BigEndian, ReadBytesExt}; + +use osx::{Macho}; + +fn main() -> Result<(), Box> { + let args = env::args().collect::>(); + let ref filename = args.get(1).ok_or("No argument specified")?; + let mut file = unsafe { + File::open(filename) + .and_then(|f| MmapOptions::new().map(&f)) + .map(|m| Cursor::new(m)) + }.or(Err(format!("Cannot read file {}", filename)))?; + + let macho = Macho::from(&mut file)?; + macho.commands.iter().for_each(|ref cmd| { + println!("{}", cmd); + }); + + let codedata = { + let codesignature = macho.codesignature().ok_or("Binary does not have signature")?; + let mut codedata = vec![0u8; codesignature.datasize as usize]; + file.seek(SeekFrom::Start(codesignature.dataoff as u64))?; + file.read_exact(&mut codedata)?; + codedata + }; + + let sig = { + let mut file = Cursor::new(codedata); + + let magic = file.read_u32::()?; + let length = file.read_u32::()?; + let count = file.read_u32::()?; + let blobs = std::iter::repeat_with(|| { + let styp = file.read_u32::(); + let soffset = file.read_u32::(); + match (styp, soffset) { + (Ok(typ), Ok(offset)) => Some((typ, offset)), + _ => None + } + }) + .take_while(|x| x.is_some()) + .take(count as usize) + .filter_map(|x| x) + .collect::>(); + + blobs + .iter() + .filter(|(typ, _)| *typ == 0x10000) + .find_map(|(_, offset)| { + file.seek(SeekFrom::Start(*offset as u64)).ok()?; + let magic = file.read_u32::().ok()?; + let length = file.read_u32::().ok()?; + let mut buf = vec![0u8; length as usize]; + file.read_exact(&mut buf).ok()?; + Some(buf) + }) + .ok_or("Cannot parse signature")? + }; + + // let mut sigfile = File::create("signature.p7b")?; + // sigfile.write_all(&sig)?; + + Ok(()) +}