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