1use crate::*;
2use super::Wrap;
3
4#[derive(Copy, Clone, Debug, Eq, PartialEq)]
8pub enum Align {
9 File,
11 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 #[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 #[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 #[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 #[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}