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
75
76
77
78
79
80
81
82
83
//! PE Factory module for creating PE binaries from scratch
use lief_ffi as ffi;
use crate::common::{AsFFI, FromFFI, into_optional};
use crate::pe;
/// Factory for creating PE binaries from scratch
///
/// ```
/// use lief::pe;
///
/// if let Some(mut factory) = pe::Factory::create(pe::PE_TYPE::PE32_PLUS) {
/// let section = pe::Section::new_with_name(".text");
/// factory.add_section(§ion);
/// factory.set_entrypoint(0x1000);
/// if let Some(binary) = factory.get() {
/// // use binary
/// }
/// }
/// ```
pub struct Factory {
ptr: cxx::UniquePtr<ffi::PE_Factory>,
}
impl FromFFI<ffi::PE_Factory> for Factory {
fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_Factory>) -> Self {
Self { ptr }
}
}
impl Factory {
/// Create a new factory for the given PE type (PE32 or PE32+)
pub fn create(pe_type: pe::PE_TYPE) -> Option<Factory> {
into_optional(ffi::PE_Factory::create(pe_type.into()))
}
/// Add a section to the PE being built
pub fn add_section(&mut self, section: &pe::Section) {
self.ptr.pin_mut().add_section(section.as_ffi());
}
/// Set the target architecture
pub fn set_arch(&mut self, arch: pe::headers::MachineType) {
self.ptr.pin_mut().set_arch(arch.into());
}
/// Set the entry point address
pub fn set_entrypoint(&mut self, ep: u64) {
self.ptr.pin_mut().set_entrypoint(ep);
}
/// Build and return the PE binary
pub fn get(&mut self) -> Option<pe::Binary> {
into_optional(self.ptr.pin_mut().get())
}
/// Whether the factory is creating a 32-bit PE
pub fn is_32bit(&self) -> bool {
self.ptr.is_32bit()
}
/// Whether the factory is creating a 64-bit PE
pub fn is_64bit(&self) -> bool {
self.ptr.is_64bit()
}
/// Return the section alignment
pub fn section_align(&self) -> u32 {
self.ptr.section_align()
}
/// Return the file alignment
pub fn file_align(&self) -> u32 {
self.ptr.file_align()
}
}
impl std::fmt::Debug for Factory {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Factory").finish()
}
}