Line data Source code
1 : use lief_ffi as ffi;
2 :
3 : use super::elf;
4 : use super::macho;
5 : use super::pe;
6 : use super::coff;
7 : use crate::common::FromFFI;
8 : use std::path::Path;
9 : use std::io::{Read, Seek};
10 :
11 0 : #[derive(Debug)]
12 : /// Enum that wraps all the executable formats supported by LIEF
13 : pub enum Binary {
14 : /// An ELF binary
15 : ELF(elf::Binary),
16 :
17 : /// A PE binary
18 : PE(pe::Binary),
19 :
20 : /// A Mach-O (FAT) binary
21 : MachO(macho::FatBinary),
22 :
23 : /// A COFF binary object
24 : COFF(coff::Binary)
25 : }
26 :
27 : impl Binary {
28 : /// Parse form a file path
29 : ///
30 : /// ```
31 : /// if let Some(Binary::ELF(elf)) = Binary::parse("/bin/ls") {
32 : /// // ...
33 : /// }
34 : /// ```
35 26 : pub fn parse<P: AsRef<Path>>(path: P) -> Option<Binary> {
36 26 : let path_str = path.as_ref().to_str().unwrap();
37 26 : if ffi::ELF_Utils::is_elf(path_str) {
38 10 : if let Some(elf) = elf::Binary::parse(path) {
39 10 : return Some(Binary::ELF(elf));
40 0 : }
41 0 : return None;
42 16 : }
43 16 : if ffi::PE_Utils::is_pe(path_str) {
44 0 : if let Some(pe) = pe::Binary::parse(path) {
45 0 : return Some(Binary::PE(pe));
46 0 : }
47 0 : return None;
48 16 : }
49 16 : if ffi::MachO_Utils::is_macho(path_str) {
50 16 : if let Some(fat) = macho::FatBinary::parse(path) {
51 16 : return Some(Binary::MachO(fat));
52 0 : }
53 0 : return None;
54 0 : }
55 0 :
56 0 : if ffi::COFF_Utils::is_coff(path_str) {
57 0 : if let Some(coff) = coff::Binary::parse(path) {
58 0 : return Some(Binary::COFF(coff));
59 0 : }
60 0 : return None;
61 0 : }
62 0 : None
63 26 : }
64 : /// Parse from an input that implements `Read + Seek` traits
65 : ///
66 : /// ```
67 : /// let mut file = std::fs::File::open("C:/test.ext").expect("Can't open the file");
68 : /// if let Some(Binary::PE(pe)) = Binary::from(&mut file) {
69 : /// // ...
70 : /// }
71 : /// ```
72 33 : pub fn from<R: Read + Seek>(reader: &mut R) -> Option<Binary> {
73 33 : let mut buffer = std::vec::Vec::new();
74 33 : if reader.read_to_end(&mut buffer).is_err() {
75 0 : return None;
76 33 : }
77 33 :
78 33 : let mut ffi_stream =
79 33 : unsafe { ffi::RustStream::from_rust(buffer.as_mut_ptr(), buffer.len()) };
80 33 : buffer.clear();
81 33 :
82 33 : if ffi_stream.is_elf() {
83 8 : return Some(Binary::ELF(elf::Binary::from_ffi(
84 8 : ffi_stream.pin_mut().as_elf(),
85 8 : )));
86 25 : }
87 25 : if ffi_stream.is_macho() {
88 13 : return Some(Binary::MachO(macho::FatBinary::from_ffi(
89 13 : ffi_stream.pin_mut().as_macho(),
90 13 : )));
91 12 : }
92 12 : if ffi_stream.is_pe() {
93 12 : return Some(Binary::PE(pe::Binary::from_ffi(
94 12 : ffi_stream.pin_mut().as_pe(),
95 12 : )));
96 0 : }
97 0 :
98 0 : if ffi_stream.is_coff() {
99 0 : return Some(Binary::COFF(coff::Binary::from_ffi(
100 0 : ffi_stream.pin_mut().as_coff(),
101 0 : )));
102 0 : }
103 0 : None
104 33 : }
105 : }
|