Line data Source code
1 : //! PE Factory module for creating PE binaries from scratch
2 :
3 : use lief_ffi as ffi;
4 :
5 : use crate::common::{into_optional, AsFFI, FromFFI};
6 : use crate::pe;
7 :
8 : /// Factory for creating PE binaries from scratch
9 : ///
10 : /// ```
11 : /// use lief::pe;
12 : ///
13 : /// if let Some(mut factory) = pe::Factory::create(pe::PE_TYPE::PE32_PLUS) {
14 : /// let section = pe::Section::new_with_name(".text");
15 : /// factory.add_section(§ion);
16 : /// factory.set_entrypoint(0x1000);
17 : /// if let Some(binary) = factory.get() {
18 : /// // use binary
19 : /// }
20 : /// }
21 : /// ```
22 : pub struct Factory {
23 : ptr: cxx::UniquePtr<ffi::PE_Factory>,
24 : }
25 :
26 : impl FromFFI<ffi::PE_Factory> for Factory {
27 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_Factory>) -> Self {
28 0 : Self { ptr }
29 0 : }
30 : }
31 :
32 : impl Factory {
33 : /// Create a new factory for the given PE type (PE32 or PE32+)
34 0 : pub fn create(pe_type: pe::PE_TYPE) -> Option<Factory> {
35 0 : into_optional(ffi::PE_Factory::create(pe_type.into()))
36 0 : }
37 :
38 : /// Add a section to the PE being built
39 0 : pub fn add_section(&mut self, section: &pe::Section) {
40 0 : self.ptr.pin_mut().add_section(section.as_ffi());
41 0 : }
42 :
43 : /// Set the target architecture
44 0 : pub fn set_arch(&mut self, arch: pe::headers::MachineType) {
45 0 : self.ptr.pin_mut().set_arch(arch.into());
46 0 : }
47 :
48 : /// Set the entry point address
49 0 : pub fn set_entrypoint(&mut self, ep: u64) {
50 0 : self.ptr.pin_mut().set_entrypoint(ep);
51 0 : }
52 :
53 : /// Build and return the PE binary
54 0 : pub fn get(&mut self) -> Option<pe::Binary> {
55 0 : into_optional(self.ptr.pin_mut().get())
56 0 : }
57 :
58 : /// Whether the factory is creating a 32-bit PE
59 0 : pub fn is_32bit(&self) -> bool {
60 0 : self.ptr.is_32bit()
61 0 : }
62 :
63 : /// Whether the factory is creating a 64-bit PE
64 0 : pub fn is_64bit(&self) -> bool {
65 0 : self.ptr.is_64bit()
66 0 : }
67 :
68 : /// Return the section alignment
69 0 : pub fn section_align(&self) -> u32 {
70 0 : self.ptr.section_align()
71 0 : }
72 :
73 : /// Return the file alignment
74 0 : pub fn file_align(&self) -> u32 {
75 0 : self.ptr.file_align()
76 0 : }
77 : }
78 :
79 : impl std::fmt::Debug for Factory {
80 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81 0 : f.debug_struct("Factory").finish()
82 0 : }
83 : }
|