Line data Source code
1 : //! Module for the PE file format support in LIEF.
2 : //!
3 : //! The [`Binary`] structure exposes the main API to inspect a PE file. It can be instantiated,
4 : //! using either: [`crate::pe::parse`], [`crate::pe::Binary::parse`] or [`crate::Binary::parse`]
5 : //!
6 : //! ```
7 : //! let pe = lief::pe::parse("demo.exe").unwrap();
8 : //! for section in pe.sections() {
9 : //! println!("section: {}", section.name());
10 : //! }
11 : //! ```
12 :
13 : use std::path::Path;
14 : use lief_ffi as ffi;
15 :
16 : pub mod binary;
17 : pub mod data_directory;
18 : pub mod debug;
19 : pub mod delay_import;
20 : pub mod export;
21 : pub mod headers;
22 : pub mod import;
23 : pub mod load_configuration;
24 : pub mod relocation;
25 : pub mod resources;
26 : pub mod rich_header;
27 : pub mod section;
28 : pub mod signature;
29 : pub mod tls;
30 : pub mod code_integrity;
31 : pub mod builder;
32 : pub mod exception;
33 : pub mod exception_x64;
34 : pub mod exception_aarch64;
35 : pub mod chpe_metadata_arm64;
36 : pub mod chpe_metadata_x86;
37 : pub mod dynamic_relocation;
38 : pub mod dynamic_fixups;
39 : pub mod enclave_configuration;
40 : pub mod volatile_metadata;
41 : pub mod parser_config;
42 :
43 : #[doc(inline)]
44 : pub use binary::Binary;
45 : #[doc(inline)]
46 : pub use data_directory::DataDirectory;
47 : #[doc(inline)]
48 : pub use delay_import::DelayImport;
49 : #[doc(inline)]
50 : pub use export::Export;
51 : #[doc(inline)]
52 : pub use headers::{DosHeader, Header, OptionalHeader};
53 : #[doc(inline)]
54 : pub use relocation::Relocation;
55 : #[doc(inline)]
56 : pub use resources::Manager as ResourcesManager;
57 : #[doc(inline)]
58 : pub use resources::Node as ResourceNode;
59 : #[doc(inline)]
60 : pub use rich_header::{RichEntry, RichHeader};
61 : #[doc(inline)]
62 : pub use section::Section;
63 : #[doc(inline)]
64 : pub use tls::TLS;
65 : #[doc(inline)]
66 : pub use import::Import;
67 : #[doc(inline)]
68 : pub use signature::Signature;
69 : #[doc(inline)]
70 : pub use exception::{RuntimeExceptionFunction, ExceptionInfo};
71 : #[doc(inline)]
72 : pub use load_configuration::{LoadConfiguration, CHPEMetadata};
73 : #[doc(inline)]
74 : pub use dynamic_relocation::DynamicRelocation;
75 : #[doc(inline)]
76 : pub use dynamic_fixups::DynamicFixup;
77 : #[doc(inline)]
78 : pub use enclave_configuration::{EnclaveConfiguration, EnclaveImport};
79 : #[doc(inline)]
80 : pub use volatile_metadata::VolatileMetadata;
81 : #[doc(inline)]
82 : pub use parser_config::Config as ParserConfig;
83 :
84 : use crate::common::AsFFI;
85 :
86 : #[allow(non_camel_case_types)]
87 984 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
88 : pub enum Algorithms {
89 : SHA_512,
90 : SHA_384,
91 : SHA_256,
92 : SHA_1,
93 : MD5,
94 : MD4,
95 : MD2,
96 : RSA,
97 : EC,
98 : MD5_RSA,
99 : SHA1_DSA,
100 : SHA1_RSA,
101 : SHA_256_RSA,
102 : SHA_384_RSA,
103 : SHA_512_RSA,
104 : SHA1_ECDSA,
105 : SHA_256_ECDSA,
106 : SHA_384_ECDSA,
107 : SHA_512_ECDSA,
108 : UNKNOWN(u32),
109 : }
110 :
111 :
112 : impl From<u32> for Algorithms {
113 984 : fn from(value: u32) -> Self {
114 984 : match value {
115 0 : 0x00000001 => Algorithms::SHA_512,
116 0 : 0x00000002 => Algorithms::SHA_384,
117 456 : 0x00000003 => Algorithms::SHA_256,
118 192 : 0x00000004 => Algorithms::SHA_1,
119 36 : 0x00000005 => Algorithms::MD5,
120 0 : 0x00000006 => Algorithms::MD4,
121 0 : 0x00000007 => Algorithms::MD2,
122 240 : 0x00000008 => Algorithms::RSA,
123 0 : 0x00000009 => Algorithms::EC,
124 0 : 0x0000000a => Algorithms::MD5_RSA,
125 0 : 0x0000000b => Algorithms::SHA1_DSA,
126 0 : 0x0000000c => Algorithms::SHA1_RSA,
127 60 : 0x0000000d => Algorithms::SHA_256_RSA,
128 0 : 0x0000000e => Algorithms::SHA_384_RSA,
129 0 : 0x0000000f => Algorithms::SHA_512_RSA,
130 0 : 0x00000010 => Algorithms::SHA1_ECDSA,
131 0 : 0x00000011 => Algorithms::SHA_256_ECDSA,
132 0 : 0x00000012 => Algorithms::SHA_384_ECDSA,
133 0 : 0x00000013 => Algorithms::SHA_512_ECDSA,
134 0 : _ => Algorithms::UNKNOWN(value),
135 :
136 : }
137 984 : }
138 : }
139 :
140 : impl From<Algorithms> for u32 {
141 156 : fn from(value: Algorithms) -> u32 {
142 156 : match value {
143 0 : Algorithms::SHA_512 => 0x00000001,
144 0 : Algorithms::SHA_384 => 0x00000002,
145 156 : Algorithms::SHA_256 => 0x00000003,
146 0 : Algorithms::SHA_1 => 0x00000004,
147 0 : Algorithms::MD5 => 0x00000005,
148 0 : Algorithms::MD4 => 0x00000006,
149 0 : Algorithms::MD2 => 0x00000007,
150 0 : Algorithms::RSA => 0x00000008,
151 0 : Algorithms::EC => 0x00000009,
152 0 : Algorithms::MD5_RSA => 0x0000000a,
153 0 : Algorithms::SHA1_DSA => 0x0000000b,
154 0 : Algorithms::SHA1_RSA => 0x0000000c,
155 0 : Algorithms::SHA_256_RSA => 0x0000000d,
156 0 : Algorithms::SHA_384_RSA => 0x0000000e,
157 0 : Algorithms::SHA_512_RSA => 0x0000000f,
158 0 : Algorithms::SHA1_ECDSA => 0x00000010,
159 0 : Algorithms::SHA_256_ECDSA => 0x00000011,
160 0 : Algorithms::SHA_384_ECDSA => 0x00000012,
161 0 : Algorithms::SHA_512_ECDSA => 0x00000013,
162 0 : Algorithms::UNKNOWN(_) => 0,
163 :
164 : }
165 156 : }
166 : }
167 :
168 : /// Parse a PE file from the given file path
169 0 : pub fn parse<P: AsRef<Path>>(path: P) -> Option<Binary> {
170 0 : Binary::parse(path)
171 0 : }
172 :
173 : /// Parse a PE file from the given file path and configuration
174 0 : pub fn parse_with_config<P: AsRef<Path>>(path: P, config: &ParserConfig) -> Option<Binary> {
175 0 : Binary::parse_with_config(path, config)
176 0 : }
177 :
178 : /// Check that the layout of the given binary is correct from the Windows loader
179 : /// perspective
180 0 : pub fn check_layout(binary: &Binary) -> Result<(), String> {
181 0 : cxx::let_cxx_string!(error = "");
182 0 : unsafe {
183 0 : if ffi::PE_Utils::check_layout(binary.as_ffi(), error.as_mut().get_unchecked_mut()) {
184 0 : return Ok(());
185 0 : }
186 0 : }
187 0 : Err(error.to_string())
188 0 : }
|