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