pelite/wrap/
pe.rs

1use crate::*;
2use super::Wrap;
3
4/// The specific alignment used by the view.
5///
6/// See [the module-level documentation](index.html#getting-started) for more information.
7#[derive(Copy, Clone, Debug, Eq, PartialEq)]
8pub enum Align {
9	/// The view uses file alignment, typically 512 bytes.
10	File,
11	/// The view uses section alignment, typically 4 KiB.
12	Section,
13}
14
15pub(crate) fn get_section_bytes<'a>(image: &'a [u8], section_header: &image::IMAGE_SECTION_HEADER, align: Align) -> Result<&'a [u8]> {
16	let (address, size) = match align {
17		Align::File => (section_header.PointerToRawData, section_header.SizeOfRawData),
18		Align::Section => (section_header.VirtualAddress, section_header.VirtualSize),
19	};
20	if address == 0 {
21		return Err(Error::Null);
22	}
23	let start = address as usize;
24	let end = address.wrapping_add(size) as usize;
25	image.get(start..end).ok_or(Error::Bounds)
26}
27
28impl<'a, Pe32: pe32::Pe<'a>, Pe64: pe64::Pe<'a>> Wrap<Pe32, Pe64> {
29	#[inline]
30	pub fn image(&self) -> &'a [u8] {
31		match self {
32			Wrap::T32(pe32) => pe32.image(),
33			Wrap::T64(pe64) => pe64.image(),
34		}
35	}
36	#[inline]
37	pub fn align(&self) -> Align {
38		match self {
39			Wrap::T32(pe32) => pe32.align(),
40			Wrap::T64(pe64) => pe64.align(),
41		}
42	}
43	#[inline]
44	pub fn as_ref(&self) -> Wrap<&Pe32, &Pe64> {
45		match self {
46			Wrap::T32(pe32) => Wrap::T32(pe32),
47			Wrap::T64(pe64) => Wrap::T64(pe64),
48		}
49	}
50
51	//----------------------------------------------------------------
52
53	#[inline]
54	pub fn dos_header(&self) -> &'a image::IMAGE_DOS_HEADER {
55		match self {
56			Wrap::T32(pe32) => pe32.dos_header(),
57			Wrap::T64(pe64) => pe64.dos_header(),
58		}
59	}
60	#[inline]
61	pub fn dos_image(&self) -> &'a [u8] {
62		match self {
63			Wrap::T32(pe32) => pe32.dos_image(),
64			Wrap::T64(pe64) => pe64.dos_image(),
65		}
66	}
67	#[inline]
68	pub fn nt_headers(&self) -> Wrap<&'a image::IMAGE_NT_HEADERS32, &'a image::IMAGE_NT_HEADERS64> {
69		match self {
70			Wrap::T32(pe32) => Wrap::T32(pe32.nt_headers()),
71			Wrap::T64(pe64) => Wrap::T64(pe64.nt_headers()),
72		}
73	}
74	#[inline]
75	pub fn file_header(&self) -> &'a image::IMAGE_FILE_HEADER {
76		match self {
77			Wrap::T32(pe32) => pe32.file_header(),
78			Wrap::T64(pe64) => pe64.file_header(),
79		}
80	}
81	#[inline]
82	pub fn optional_header(&self) -> Wrap<&'a image::IMAGE_OPTIONAL_HEADER32, &'a image::IMAGE_OPTIONAL_HEADER64> {
83		match self {
84			Wrap::T32(pe32) => Wrap::T32(pe32.optional_header()),
85			Wrap::T64(pe64) => Wrap::T64(pe64.optional_header()),
86		}
87	}
88	#[inline]
89	pub fn data_directory(&self) -> &'a [image::IMAGE_DATA_DIRECTORY] {
90		match self {
91			Wrap::T32(pe32) => pe32.data_directory(),
92			Wrap::T64(pe64) => pe64.data_directory(),
93		}
94	}
95	#[inline]
96	pub fn section_headers(&self) -> &'a super::sections::SectionHeaders {
97		match self {
98			Wrap::T32(pe32) => pe32.section_headers(),
99			Wrap::T64(pe64) => pe64.section_headers(),
100		}
101	}
102
103	//----------------------------------------------------------------
104
105	#[inline]
106	pub fn slice(&self, rva: u32, min_size: usize, align: usize) -> Result<&'a [u8]> {
107		match self {
108			Wrap::T32(pe32) => pe32.slice(rva, min_size, align),
109			Wrap::T64(pe64) => pe64.slice(rva, min_size, align),
110		}
111	}
112	#[inline]
113	pub fn slice_bytes(&self, rva: u32) -> Result<&'a [u8]> {
114		match self {
115			Wrap::T32(pe32) => pe32.slice_bytes(rva),
116			Wrap::T64(pe64) => pe64.slice_bytes(rva),
117		}
118	}
119	#[inline]
120	pub fn get_section_bytes(&self, section_header: &image::IMAGE_SECTION_HEADER) -> Result<&'a [u8]> {
121		get_section_bytes(self.image(), section_header, self.align())
122	}
123
124	//----------------------------------------------------------------
125
126	#[inline]
127	pub fn derva<T>(&self, rva: u32) -> Result<&'a T> where T: Pod {
128		match self {
129			Wrap::T32(pe32) => pe32.derva(rva),
130			Wrap::T64(pe64) => pe64.derva(rva),
131		}
132	}
133	#[inline]
134	pub fn derva_copy<T>(&self, rva: u32) -> Result<T> where T: Copy + Pod {
135		match self {
136			Wrap::T32(pe32) => pe32.derva_copy(rva),
137			Wrap::T64(pe64) => pe64.derva_copy(rva),
138		}
139	}
140	#[inline]
141	pub fn derva_into<T>(&self, rva: u32, dest: &mut T) -> Result<()> where T: ?Sized + Pod {
142		match self {
143			Wrap::T32(pe32) => pe32.derva_into(rva, dest),
144			Wrap::T64(pe64) => pe64.derva_into(rva, dest),
145		}
146	}
147	#[inline]
148	pub fn derva_slice<T>(&self, rva: u32, len: usize) -> Result<&'a [T]> where T: Pod {
149		match self {
150			Wrap::T32(pe32) => pe32.derva_slice(rva, len),
151			Wrap::T64(pe64) => pe64.derva_slice(rva, len),
152		}
153	}
154	#[inline]
155	pub fn derva_slice_f<T, F>(&self, rva: u32, f: F) -> Result<&'a [T]> where T: Pod, F: FnMut(&'a T) -> bool {
156		match self {
157			Wrap::T32(pe32) => pe32.derva_slice_f(rva, f),
158			Wrap::T64(pe64) => pe64.derva_slice_f(rva, f),
159		}
160	}
161	#[inline]
162	pub fn derva_slice_s<T>(&self, rva: u32, sentinel: T) -> Result<&'a [T]> where T: PartialEq + Pod {
163		match self {
164			Wrap::T32(pe32) => pe32.derva_slice_s(rva, sentinel),
165			Wrap::T64(pe64) => pe64.derva_slice_s(rva, sentinel),
166		}
167	}
168	#[inline]
169	pub fn derva_c_str(&self, rva: u32) -> Result<&'a util::CStr> {
170		match self {
171			Wrap::T32(pe32) => pe32.derva_c_str(rva),
172			Wrap::T64(pe64) => pe64.derva_c_str(rva),
173		}
174	}
175	#[inline]
176	pub fn derva_string<T>(&self, rva: u32) -> Result<&'a T> where T: util::FromBytes + ?Sized {
177		match self {
178			Wrap::T32(pe32) => pe32.derva_string(rva),
179			Wrap::T64(pe64) => pe64.derva_string(rva),
180		}
181	}
182
183	//----------------------------------------------------------------
184
185	#[inline]
186	pub fn headers(&self) -> Wrap<pe32::headers::Headers<Pe32>, pe64::headers::Headers<Pe64>> {
187		match self {
188			Wrap::T32(pe32) => Wrap::T32(pe32.headers()),
189			Wrap::T64(pe64) => Wrap::T64(pe64.headers()),
190		}
191	}
192	#[inline]
193	pub fn rich_structure(&self) -> Result<rich_structure::RichStructure<'a>> {
194		match self {
195			Wrap::T32(pe32) => pe32.rich_structure(),
196			Wrap::T64(pe64) => pe64.rich_structure(),
197		}
198	}
199	#[inline]
200	pub fn exports(&self) -> Result<Wrap<pe32::exports::Exports<'a, Pe32>, pe64::exports::Exports<'a, Pe64>>> {
201		match self {
202			Wrap::T32(pe32) => pe32.exports().map(Wrap::T32),
203			Wrap::T64(pe64) => pe64.exports().map(Wrap::T64),
204		}
205	}
206	#[inline]
207	pub fn imports(&self) -> Result<Wrap<pe32::imports::Imports<'a, Pe32>, pe64::imports::Imports<'a, Pe64>>> {
208		match self {
209			Wrap::T32(pe32) => pe32.imports().map(Wrap::T32),
210			Wrap::T64(pe64) => pe64.imports().map(Wrap::T64),
211		}
212	}
213	#[inline]
214	pub fn iat(&self) -> Result<Wrap<pe32::imports::IAT<'a, Pe32>, pe64::imports::IAT<'a, Pe64>>> {
215		match self {
216			Wrap::T32(pe32) => pe32.iat().map(Wrap::T32),
217			Wrap::T64(pe64) => pe64.iat().map(Wrap::T64),
218		}
219	}
220	#[inline]
221	pub fn base_relocs(&self) -> Result<crate::base_relocs::BaseRelocs<'a>> {
222		match self {
223			Wrap::T32(pe32) => pe32.base_relocs(),
224			Wrap::T64(pe64) => pe64.base_relocs(),
225		}
226	}
227	#[inline]
228	pub fn load_config(&self) -> Result<Wrap<pe32::load_config::LoadConfig<'a, Pe32>, pe64::load_config::LoadConfig<'a, Pe64>>> {
229		match self {
230			Wrap::T32(pe32) => pe32.load_config().map(Wrap::T32),
231			Wrap::T64(pe64) => pe64.load_config().map(Wrap::T64),
232		}
233	}
234	#[inline]
235	pub fn tls(&self) -> Result<Wrap<pe32::tls::Tls<'a, Pe32>, pe64::tls::Tls<'a, Pe64>>> {
236		match self {
237			Wrap::T32(pe32) => pe32.tls().map(Wrap::T32),
238			Wrap::T64(pe64) => pe64.tls().map(Wrap::T64),
239		}
240	}
241	#[inline]
242	pub fn security(&self) -> Result<crate::security::Security<'a>> {
243		match self {
244			Wrap::T32(pe32) => pe32.security(),
245			Wrap::T64(pe64) => pe64.security(),
246		}
247	}
248	#[inline]
249	pub fn exception(&self) -> Result<Wrap<pe32::exception::Exception<'a, Pe32>, pe64::exception::Exception<'a, Pe64>>> {
250		match self {
251			Wrap::T32(pe32) => pe32.exception().map(Wrap::T32),
252			Wrap::T64(pe64) => pe64.exception().map(Wrap::T64),
253		}
254	}
255	#[inline]
256	pub fn debug(&self) -> Result<Wrap<pe32::debug::Debug<'a, Pe32>, pe64::debug::Debug<'a, Pe64>>> {
257		match self {
258			Wrap::T32(pe32) => pe32.debug().map(Wrap::T32),
259			Wrap::T64(pe64) => pe64.debug().map(Wrap::T64),
260		}
261	}
262	#[inline]
263	#[cfg(any(feature = "std", feature = "resources_nostd"))]
264	pub fn resources(&self) -> Result<crate::resources::Resources<'a>> {
265		match self {
266			Wrap::T32(pe32) => pe32.resources(),
267			Wrap::T64(pe64) => pe64.resources(),
268		}
269	}
270	#[inline]
271	pub fn scanner(&self) -> Wrap<pe32::scanner::Scanner<Pe32>, pe64::scanner::Scanner<Pe64>> {
272		match self {
273			Wrap::T32(pe32) => Wrap::T32(pe32.scanner()),
274			Wrap::T64(pe64) => Wrap::T64(pe64.scanner()),
275		}
276	}
277}