1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#![forbid(unsafe_code)]
#![allow(clippy::single_match)]
#![allow(clippy::while_let_loop)]
#![allow(clippy::single_char_pattern)]
#![allow(clippy::many_single_char_names)]
#![allow(clippy::skip_while_next)]
pub mod ar;
pub mod demangle;
pub mod elf32;
pub mod elf64;
pub mod macho;
pub mod pe;
mod parser;
mod error;
pub use crate::error::ParseError;
pub use crate::parser::UnexpectedEof;
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum ByteOrder {
LittleEndian,
BigEndian,
}
pub enum Format {
Elf32 {byte_order: ByteOrder},
Elf64 {byte_order: ByteOrder},
Macho,
PE,
Unknown,
}
pub fn detect_format(data: &[u8]) -> Format {
if data.len() < 8 {return Format::Unknown};
let macho_signatures = [
b"\xCA\xFE\xBA\xBE",
b"\xFE\xED\xFA\xCE",
b"\xFE\xED\xFA\xCF",
b"\xCE\xFA\xED\xFE",
b"\xCF\xFA\xED\xFE",
];
if data.starts_with(b"\x7FELF") {
let byte_order = match data[5] {
1 => ByteOrder::LittleEndian,
2 => ByteOrder::BigEndian,
_ => return Format::Unknown,
};
return match data[4] {
1 => Format::Elf32{byte_order},
2 => Format::Elf64{byte_order},
_ => Format::Unknown,
};
} else if data.starts_with(b"MZ") {
return Format::PE;
} else {
for signature in &macho_signatures {
if data.starts_with(*signature) {
return Format::Macho;
}
}
}
Format::Unknown
}