use crate::{BinaryError, BinaryFormat as Format, BinaryFormatParser, Result};
#[cfg(feature = "elf")]
pub mod elf;
#[cfg(feature = "java")]
pub mod java;
#[cfg(feature = "macho")]
pub mod macho;
#[cfg(feature = "pe")]
pub mod pe;
#[cfg(feature = "wasm")]
pub mod wasm;
pub mod raw;
pub fn detect_format(data: &[u8]) -> Result<Format> {
if data.is_empty() {
return Err(BinaryError::invalid_data("Empty data"));
}
#[cfg(feature = "elf")]
if data.len() >= 4 && &data[0..4] == b"\x7fELF" {
return Ok(Format::Elf);
}
#[cfg(feature = "pe")]
if data.len() >= 2 && &data[0..2] == b"MZ" {
return Ok(Format::Pe);
}
#[cfg(feature = "macho")]
if data.len() >= 4 {
let magic_le = u32::from_le_bytes([data[0], data[1], data[2], data[3]]);
let magic_be = u32::from_be_bytes([data[0], data[1], data[2], data[3]]);
match magic_le {
0xfeedface | 0xfeedfacf | 0xcefaedfe | 0xcffaedfe => {
return Ok(Format::MachO);
}
_ => {}
}
match magic_be {
0xfeedface | 0xfeedfacf | 0xcefaedfe | 0xcffaedfe => {
return Ok(Format::MachO);
}
_ => {}
}
}
if data.len() >= 4 && &data[0..4] == b"\xca\xfe\xba\xbe" {
return Ok(Format::Java);
}
#[cfg(feature = "java")]
if data.len() >= 4 && &data[0..4] == b"PK\x03\x04" {
use std::io::Cursor;
if let Ok(mut archive) = zip::ZipArchive::new(Cursor::new(data)) {
for i in 0..archive.len() {
if let Ok(file) = archive.by_index(i) {
if file.name().ends_with(".class") {
return Ok(Format::Java);
}
}
}
}
}
if data.len() >= 4 && &data[0..4] == b"\x00asm" {
return Ok(Format::Wasm);
}
Ok(Format::Raw)
}
pub fn parse_binary(data: &[u8], format: Format) -> crate::types::ParseResult {
match format {
#[cfg(feature = "elf")]
Format::Elf => elf::ElfParser::parse(data),
#[cfg(not(feature = "elf"))]
Format::Elf => Err(BinaryError::unsupported_format("ELF".to_string())),
#[cfg(feature = "pe")]
Format::Pe => pe::PeParser::parse(data),
#[cfg(not(feature = "pe"))]
Format::Pe => Err(BinaryError::unsupported_format("PE".to_string())),
#[cfg(feature = "macho")]
Format::MachO => macho::MachOParser::parse(data),
#[cfg(not(feature = "macho"))]
Format::MachO => Err(BinaryError::unsupported_format("MachO".to_string())),
#[cfg(feature = "java")]
Format::Java => java::JavaParser::parse(data),
#[cfg(not(feature = "java"))]
Format::Java => Err(BinaryError::unsupported_format("Java".to_string())),
#[cfg(feature = "wasm")]
Format::Wasm => wasm::WasmParser::parse(data),
#[cfg(not(feature = "wasm"))]
Format::Wasm => Err(BinaryError::unsupported_format("Wasm".to_string())),
Format::Raw => raw::RawParser::parse(data),
Format::Unknown => Err(BinaryError::unsupported_format("Unknown".to_string())),
}
}