1use alloc::vec::Vec;
2use core::fmt::Debug;
3use core::{mem, str};
4
5use core::convert::TryInto;
6
7use crate::endian::{LittleEndian as LE, U32};
8use crate::pe;
9use crate::pod::{self, Pod};
10use crate::read::coff::{CoffCommon, CoffSymbol, CoffSymbolIterator, CoffSymbolTable, SymbolTable};
11use crate::read::{
12 self, Architecture, ByteString, Bytes, CodeView, ComdatKind, Error, Export, FileFlags, Import,
13 NoDynamicRelocationIterator, Object, ObjectComdat, ObjectKind, ReadError, ReadRef, Result,
14 SectionIndex, SubArchitecture, SymbolIndex,
15};
16
17use super::{
18 DataDirectories, ExportTable, ImageThunkData, ImportTable, PeSection, PeSectionIterator,
19 PeSegment, PeSegmentIterator, RichHeaderInfo, SectionTable,
20};
21
22pub type PeFile32<'data, R = &'data [u8]> = PeFile<'data, pe::ImageNtHeaders32, R>;
27pub type PeFile64<'data, R = &'data [u8]> = PeFile<'data, pe::ImageNtHeaders64, R>;
32
33#[derive(Debug)]
37pub struct PeFile<'data, Pe, R = &'data [u8]>
38where
39 Pe: ImageNtHeaders,
40 R: ReadRef<'data>,
41{
42 pub(super) dos_header: &'data pe::ImageDosHeader,
43 pub(super) nt_headers: &'data Pe,
44 pub(super) data_directories: DataDirectories<'data>,
45 pub(super) common: CoffCommon<'data, R>,
46 pub(super) data: R,
47}
48
49impl<'data, Pe, R> PeFile<'data, Pe, R>
50where
51 Pe: ImageNtHeaders,
52 R: ReadRef<'data>,
53{
54 pub fn parse(data: R) -> Result<Self> {
56 let dos_header = pe::ImageDosHeader::parse(data)?;
57 let mut offset = dos_header.nt_headers_offset().into();
58 let (nt_headers, data_directories) = Pe::parse(data, &mut offset)?;
59 let sections = nt_headers.sections(data, offset)?;
60 let coff_symbols = nt_headers.symbols(data);
61 let image_base = nt_headers.optional_header().image_base();
62
63 Ok(PeFile {
64 dos_header,
65 nt_headers,
66 data_directories,
67 common: CoffCommon {
68 sections,
69 symbols: coff_symbols.unwrap_or_default(),
72 image_base,
73 },
74 data,
75 })
76 }
77
78 pub fn data(&self) -> R {
80 self.data
81 }
82
83 pub fn dos_header(&self) -> &'data pe::ImageDosHeader {
85 self.dos_header
86 }
87
88 pub fn nt_headers(&self) -> &'data Pe {
90 self.nt_headers
91 }
92
93 pub fn rich_header_info(&self) -> Option<RichHeaderInfo<'_>> {
95 RichHeaderInfo::parse(self.data, self.dos_header.nt_headers_offset().into())
96 }
97
98 pub fn section_table(&self) -> SectionTable<'data> {
100 self.common.sections
101 }
102
103 pub fn data_directories(&self) -> DataDirectories<'data> {
105 self.data_directories
106 }
107
108 pub fn data_directory(&self, id: usize) -> Option<&'data pe::ImageDataDirectory> {
110 self.data_directories.get(id)
111 }
112
113 pub fn export_table(&self) -> Result<Option<ExportTable<'data>>> {
117 self.data_directories
118 .export_table(self.data, &self.common.sections)
119 }
120
121 pub fn import_table(&self) -> Result<Option<ImportTable<'data>>> {
125 self.data_directories
126 .import_table(self.data, &self.common.sections)
127 }
128
129 pub(super) fn section_alignment(&self) -> u64 {
130 u64::from(self.nt_headers.optional_header().section_alignment())
131 }
132}
133
134impl<'data, Pe, R> read::private::Sealed for PeFile<'data, Pe, R>
135where
136 Pe: ImageNtHeaders,
137 R: ReadRef<'data>,
138{
139}
140
141impl<'data, Pe, R> Object<'data> for PeFile<'data, Pe, R>
142where
143 Pe: ImageNtHeaders,
144 R: ReadRef<'data>,
145{
146 type Segment<'file> = PeSegment<'data, 'file, Pe, R> where Self: 'file, 'data: 'file;
147 type SegmentIterator<'file> = PeSegmentIterator<'data, 'file, Pe, R> where Self: 'file, 'data: 'file;
148 type Section<'file> = PeSection<'data, 'file, Pe, R> where Self: 'file, 'data: 'file;
149 type SectionIterator<'file> = PeSectionIterator<'data, 'file, Pe, R> where Self: 'file, 'data: 'file;
150 type Comdat<'file> = PeComdat<'data, 'file, Pe, R> where Self: 'file, 'data: 'file;
151 type ComdatIterator<'file> = PeComdatIterator<'data, 'file, Pe, R> where Self: 'file, 'data: 'file;
152 type Symbol<'file> = CoffSymbol<'data, 'file, R> where Self: 'file, 'data: 'file;
153 type SymbolIterator<'file> = CoffSymbolIterator<'data, 'file, R> where Self: 'file, 'data: 'file;
154 type SymbolTable<'file> = CoffSymbolTable<'data, 'file, R> where Self: 'file, 'data: 'file;
155 type DynamicRelocationIterator<'file> = NoDynamicRelocationIterator where Self: 'file, 'data: 'file;
156
157 fn architecture(&self) -> Architecture {
158 match self.nt_headers.file_header().machine.get(LE) {
159 pe::IMAGE_FILE_MACHINE_ARMNT => Architecture::Arm,
160 pe::IMAGE_FILE_MACHINE_ARM64 | pe::IMAGE_FILE_MACHINE_ARM64EC => Architecture::Aarch64,
161 pe::IMAGE_FILE_MACHINE_I386 => Architecture::I386,
162 pe::IMAGE_FILE_MACHINE_AMD64 => Architecture::X86_64,
163 _ => Architecture::Unknown,
164 }
165 }
166
167 fn sub_architecture(&self) -> Option<SubArchitecture> {
168 match self.nt_headers.file_header().machine.get(LE) {
169 pe::IMAGE_FILE_MACHINE_ARM64EC => Some(SubArchitecture::Arm64EC),
170 _ => None,
171 }
172 }
173
174 #[inline]
175 fn is_little_endian(&self) -> bool {
176 true
178 }
179
180 #[inline]
181 fn is_64(&self) -> bool {
182 self.nt_headers.is_type_64()
183 }
184
185 fn kind(&self) -> ObjectKind {
186 let characteristics = self.nt_headers.file_header().characteristics.get(LE);
187 if characteristics & pe::IMAGE_FILE_DLL != 0 {
188 ObjectKind::Dynamic
189 } else if characteristics & pe::IMAGE_FILE_SYSTEM != 0 {
190 ObjectKind::Unknown
191 } else {
192 ObjectKind::Executable
193 }
194 }
195
196 fn segments(&self) -> PeSegmentIterator<'data, '_, Pe, R> {
197 PeSegmentIterator {
198 file: self,
199 iter: self.common.sections.iter(),
200 }
201 }
202
203 fn section_by_name_bytes<'file>(
204 &'file self,
205 section_name: &[u8],
206 ) -> Option<PeSection<'data, 'file, Pe, R>> {
207 self.common
208 .sections
209 .section_by_name(self.common.symbols.strings(), section_name)
210 .map(|(index, section)| PeSection {
211 file: self,
212 index,
213 section,
214 })
215 }
216
217 fn section_by_index(&self, index: SectionIndex) -> Result<PeSection<'data, '_, Pe, R>> {
218 let section = self.common.sections.section(index)?;
219 Ok(PeSection {
220 file: self,
221 index,
222 section,
223 })
224 }
225
226 fn sections(&self) -> PeSectionIterator<'data, '_, Pe, R> {
227 PeSectionIterator {
228 file: self,
229 iter: self.common.sections.iter().enumerate(),
230 }
231 }
232
233 fn comdats(&self) -> PeComdatIterator<'data, '_, Pe, R> {
234 PeComdatIterator { file: self }
235 }
236
237 fn symbol_by_index(&self, index: SymbolIndex) -> Result<CoffSymbol<'data, '_, R>> {
238 let symbol = self.common.symbols.symbol(index)?;
239 Ok(CoffSymbol {
240 file: &self.common,
241 index,
242 symbol,
243 })
244 }
245
246 fn symbols(&self) -> CoffSymbolIterator<'data, '_, R> {
247 CoffSymbolIterator::new(&self.common)
248 }
249
250 fn symbol_table(&self) -> Option<CoffSymbolTable<'data, '_, R>> {
251 Some(CoffSymbolTable { file: &self.common })
252 }
253
254 fn dynamic_symbols(&self) -> CoffSymbolIterator<'data, '_, R> {
255 CoffSymbolIterator::empty(&self.common)
256 }
257
258 fn dynamic_symbol_table(&self) -> Option<CoffSymbolTable<'data, '_, R>> {
259 None
260 }
261
262 fn dynamic_relocations(&self) -> Option<NoDynamicRelocationIterator> {
263 None
264 }
265
266 fn imports(&self) -> Result<Vec<Import<'data>>> {
267 let mut imports = Vec::new();
268 if let Some(import_table) = self.import_table()? {
269 let mut import_descs = import_table.descriptors()?;
270 while let Some(import_desc) = import_descs.next()? {
271 let library = import_table.name(import_desc.name.get(LE))?;
272 let mut first_thunk = import_desc.original_first_thunk.get(LE);
273 if first_thunk == 0 {
274 first_thunk = import_desc.first_thunk.get(LE);
275 }
276 let mut thunks = import_table.thunks(first_thunk)?;
277 while let Some(thunk) = thunks.next::<Pe>()? {
278 if !thunk.is_ordinal() {
279 let (_hint, name) = import_table.hint_name(thunk.address())?;
280 imports.push(Import {
281 library: ByteString(library),
282 name: ByteString(name),
283 });
284 }
285 }
286 }
287 }
288 Ok(imports)
289 }
290
291 fn exports(&self) -> Result<Vec<Export<'data>>> {
292 let mut exports = Vec::new();
293 if let Some(export_table) = self.export_table()? {
294 for (name_pointer, address_index) in export_table.name_iter() {
295 let name = export_table.name_from_pointer(name_pointer)?;
296 let address = export_table.address_by_index(address_index.into())?;
297 if !export_table.is_forward(address) {
298 exports.push(Export {
299 name: ByteString(name),
300 address: self.common.image_base.wrapping_add(address.into()),
301 })
302 }
303 }
304 }
305 Ok(exports)
306 }
307
308 fn pdb_info(&self) -> Result<Option<CodeView<'_>>> {
309 let data_dir = match self.data_directory(pe::IMAGE_DIRECTORY_ENTRY_DEBUG) {
310 Some(data_dir) => data_dir,
311 None => return Ok(None),
312 };
313 let debug_data = data_dir.data(self.data, &self.common.sections)?;
314 let debug_dirs = pod::slice_from_all_bytes::<pe::ImageDebugDirectory>(debug_data)
315 .read_error("Invalid PE debug dir size")?;
316
317 for debug_dir in debug_dirs {
318 if debug_dir.typ.get(LE) != pe::IMAGE_DEBUG_TYPE_CODEVIEW {
319 continue;
320 }
321
322 let info = self
323 .data
324 .read_slice_at::<u8>(
325 debug_dir.pointer_to_raw_data.get(LE) as u64,
326 debug_dir.size_of_data.get(LE) as usize,
327 )
328 .read_error("Invalid CodeView Info address")?;
329
330 let mut info = Bytes(info);
331
332 let sig = info
333 .read_bytes(4)
334 .read_error("Invalid CodeView signature")?;
335 if sig.0 != b"RSDS" {
336 continue;
337 }
338
339 let guid: [u8; 16] = info
340 .read_bytes(16)
341 .read_error("Invalid CodeView GUID")?
342 .0
343 .try_into()
344 .unwrap();
345
346 let age = info.read::<U32<LE>>().read_error("Invalid CodeView Age")?;
347
348 let path = info
349 .read_string()
350 .read_error("Invalid CodeView file path")?;
351
352 return Ok(Some(CodeView {
353 path: ByteString(path),
354 guid,
355 age: age.get(LE),
356 }));
357 }
358 Ok(None)
359 }
360
361 fn has_debug_symbols(&self) -> bool {
362 self.section_by_name(".debug_info").is_some()
363 }
364
365 fn relative_address_base(&self) -> u64 {
366 self.common.image_base
367 }
368
369 fn entry(&self) -> u64 {
370 u64::from(self.nt_headers.optional_header().address_of_entry_point())
371 .wrapping_add(self.common.image_base)
372 }
373
374 fn flags(&self) -> FileFlags {
375 FileFlags::Coff {
376 characteristics: self.nt_headers.file_header().characteristics.get(LE),
377 }
378 }
379}
380
381pub type PeComdatIterator32<'data, 'file, R = &'data [u8]> =
383 PeComdatIterator<'data, 'file, pe::ImageNtHeaders32, R>;
384pub type PeComdatIterator64<'data, 'file, R = &'data [u8]> =
386 PeComdatIterator<'data, 'file, pe::ImageNtHeaders64, R>;
387
388#[derive(Debug)]
392pub struct PeComdatIterator<'data, 'file, Pe, R = &'data [u8]>
393where
394 Pe: ImageNtHeaders,
395 R: ReadRef<'data>,
396{
397 #[allow(unused)]
398 file: &'file PeFile<'data, Pe, R>,
399}
400
401impl<'data, 'file, Pe, R> Iterator for PeComdatIterator<'data, 'file, Pe, R>
402where
403 Pe: ImageNtHeaders,
404 R: ReadRef<'data>,
405{
406 type Item = PeComdat<'data, 'file, Pe, R>;
407
408 #[inline]
409 fn next(&mut self) -> Option<Self::Item> {
410 None
411 }
412}
413
414pub type PeComdat32<'data, 'file, R = &'data [u8]> =
416 PeComdat<'data, 'file, pe::ImageNtHeaders32, R>;
417pub type PeComdat64<'data, 'file, R = &'data [u8]> =
419 PeComdat<'data, 'file, pe::ImageNtHeaders64, R>;
420
421#[derive(Debug)]
425pub struct PeComdat<'data, 'file, Pe, R = &'data [u8]>
426where
427 Pe: ImageNtHeaders,
428 R: ReadRef<'data>,
429{
430 #[allow(unused)]
431 file: &'file PeFile<'data, Pe, R>,
432}
433
434impl<'data, 'file, Pe, R> read::private::Sealed for PeComdat<'data, 'file, Pe, R>
435where
436 Pe: ImageNtHeaders,
437 R: ReadRef<'data>,
438{
439}
440
441impl<'data, 'file, Pe, R> ObjectComdat<'data> for PeComdat<'data, 'file, Pe, R>
442where
443 Pe: ImageNtHeaders,
444 R: ReadRef<'data>,
445{
446 type SectionIterator = PeComdatSectionIterator<'data, 'file, Pe, R>;
447
448 #[inline]
449 fn kind(&self) -> ComdatKind {
450 unreachable!();
451 }
452
453 #[inline]
454 fn symbol(&self) -> SymbolIndex {
455 unreachable!();
456 }
457
458 #[inline]
459 fn name_bytes(&self) -> Result<&'data [u8]> {
460 unreachable!();
461 }
462
463 #[inline]
464 fn name(&self) -> Result<&'data str> {
465 unreachable!();
466 }
467
468 #[inline]
469 fn sections(&self) -> Self::SectionIterator {
470 unreachable!();
471 }
472}
473
474pub type PeComdatSectionIterator32<'data, 'file, R = &'data [u8]> =
476 PeComdatSectionIterator<'data, 'file, pe::ImageNtHeaders32, R>;
477pub type PeComdatSectionIterator64<'data, 'file, R = &'data [u8]> =
479 PeComdatSectionIterator<'data, 'file, pe::ImageNtHeaders64, R>;
480
481#[derive(Debug)]
485pub struct PeComdatSectionIterator<'data, 'file, Pe, R = &'data [u8]>
486where
487 Pe: ImageNtHeaders,
488 R: ReadRef<'data>,
489{
490 #[allow(unused)]
491 file: &'file PeFile<'data, Pe, R>,
492}
493
494impl<'data, 'file, Pe, R> Iterator for PeComdatSectionIterator<'data, 'file, Pe, R>
495where
496 Pe: ImageNtHeaders,
497 R: ReadRef<'data>,
498{
499 type Item = SectionIndex;
500
501 fn next(&mut self) -> Option<Self::Item> {
502 None
503 }
504}
505
506impl pe::ImageDosHeader {
507 pub fn parse<'data, R: ReadRef<'data>>(data: R) -> read::Result<&'data Self> {
511 let dos_header = data
513 .read_at::<pe::ImageDosHeader>(0)
514 .read_error("Invalid DOS header size or alignment")?;
515 if dos_header.e_magic.get(LE) != pe::IMAGE_DOS_SIGNATURE {
516 return Err(Error("Invalid DOS magic"));
517 }
518 Ok(dos_header)
519 }
520
521 #[inline]
523 pub fn nt_headers_offset(&self) -> u32 {
524 self.e_lfanew.get(LE)
525 }
526}
527
528pub fn optional_header_magic<'data, R: ReadRef<'data>>(data: R) -> Result<u16> {
533 let dos_header = pe::ImageDosHeader::parse(data)?;
534 let offset = dos_header.nt_headers_offset().into();
536 let nt_headers = data
539 .read_at::<pe::ImageNtHeaders32>(offset)
540 .read_error("Invalid NT headers offset, size, or alignment")?;
541 if nt_headers.signature() != pe::IMAGE_NT_SIGNATURE {
542 return Err(Error("Invalid PE magic"));
543 }
544 Ok(nt_headers.optional_header().magic())
545}
546
547#[allow(missing_docs)]
549pub trait ImageNtHeaders: Debug + Pod {
550 type ImageOptionalHeader: ImageOptionalHeader;
551 type ImageThunkData: ImageThunkData;
552
553 fn is_type_64(&self) -> bool;
557
558 fn is_valid_optional_magic(&self) -> bool;
560
561 fn signature(&self) -> u32;
563
564 fn file_header(&self) -> &pe::ImageFileHeader;
566
567 fn optional_header(&self) -> &Self::ImageOptionalHeader;
569
570 fn parse<'data, R: ReadRef<'data>>(
581 data: R,
582 offset: &mut u64,
583 ) -> read::Result<(&'data Self, DataDirectories<'data>)> {
584 let nt_headers = data
586 .read::<Self>(offset)
587 .read_error("Invalid PE headers offset or size")?;
588 if nt_headers.signature() != pe::IMAGE_NT_SIGNATURE {
589 return Err(Error("Invalid PE magic"));
590 }
591 if !nt_headers.is_valid_optional_magic() {
592 return Err(Error("Invalid PE optional header magic"));
593 }
594
595 let optional_data_size =
597 u64::from(nt_headers.file_header().size_of_optional_header.get(LE))
598 .checked_sub(mem::size_of::<Self::ImageOptionalHeader>() as u64)
599 .read_error("PE optional header size is too small")?;
600 let optional_data = data
601 .read_bytes(offset, optional_data_size)
602 .read_error("Invalid PE optional header size")?;
603 let data_directories = DataDirectories::parse(
604 optional_data,
605 nt_headers.optional_header().number_of_rva_and_sizes(),
606 )?;
607
608 Ok((nt_headers, data_directories))
609 }
610
611 #[inline]
616 fn sections<'data, R: ReadRef<'data>>(
617 &self,
618 data: R,
619 offset: u64,
620 ) -> read::Result<SectionTable<'data>> {
621 SectionTable::parse(self.file_header(), data, offset)
622 }
623
624 #[inline]
628 fn symbols<'data, R: ReadRef<'data>>(&self, data: R) -> read::Result<SymbolTable<'data, R>> {
629 SymbolTable::parse(self.file_header(), data)
630 }
631}
632
633#[allow(missing_docs)]
635pub trait ImageOptionalHeader: Debug + Pod {
636 fn magic(&self) -> u16;
638 fn major_linker_version(&self) -> u8;
639 fn minor_linker_version(&self) -> u8;
640 fn size_of_code(&self) -> u32;
641 fn size_of_initialized_data(&self) -> u32;
642 fn size_of_uninitialized_data(&self) -> u32;
643 fn address_of_entry_point(&self) -> u32;
644 fn base_of_code(&self) -> u32;
645 fn base_of_data(&self) -> Option<u32>;
646
647 fn image_base(&self) -> u64;
649 fn section_alignment(&self) -> u32;
650 fn file_alignment(&self) -> u32;
651 fn major_operating_system_version(&self) -> u16;
652 fn minor_operating_system_version(&self) -> u16;
653 fn major_image_version(&self) -> u16;
654 fn minor_image_version(&self) -> u16;
655 fn major_subsystem_version(&self) -> u16;
656 fn minor_subsystem_version(&self) -> u16;
657 fn win32_version_value(&self) -> u32;
658 fn size_of_image(&self) -> u32;
659 fn size_of_headers(&self) -> u32;
660 fn check_sum(&self) -> u32;
661 fn subsystem(&self) -> u16;
662 fn dll_characteristics(&self) -> u16;
663 fn size_of_stack_reserve(&self) -> u64;
664 fn size_of_stack_commit(&self) -> u64;
665 fn size_of_heap_reserve(&self) -> u64;
666 fn size_of_heap_commit(&self) -> u64;
667 fn loader_flags(&self) -> u32;
668 fn number_of_rva_and_sizes(&self) -> u32;
669}
670
671impl ImageNtHeaders for pe::ImageNtHeaders32 {
672 type ImageOptionalHeader = pe::ImageOptionalHeader32;
673 type ImageThunkData = pe::ImageThunkData32;
674
675 #[inline]
676 fn is_type_64(&self) -> bool {
677 false
678 }
679
680 #[inline]
681 fn is_valid_optional_magic(&self) -> bool {
682 self.optional_header.magic.get(LE) == pe::IMAGE_NT_OPTIONAL_HDR32_MAGIC
683 }
684
685 #[inline]
686 fn signature(&self) -> u32 {
687 self.signature.get(LE)
688 }
689
690 #[inline]
691 fn file_header(&self) -> &pe::ImageFileHeader {
692 &self.file_header
693 }
694
695 #[inline]
696 fn optional_header(&self) -> &Self::ImageOptionalHeader {
697 &self.optional_header
698 }
699}
700
701impl ImageOptionalHeader for pe::ImageOptionalHeader32 {
702 #[inline]
703 fn magic(&self) -> u16 {
704 self.magic.get(LE)
705 }
706
707 #[inline]
708 fn major_linker_version(&self) -> u8 {
709 self.major_linker_version
710 }
711
712 #[inline]
713 fn minor_linker_version(&self) -> u8 {
714 self.minor_linker_version
715 }
716
717 #[inline]
718 fn size_of_code(&self) -> u32 {
719 self.size_of_code.get(LE)
720 }
721
722 #[inline]
723 fn size_of_initialized_data(&self) -> u32 {
724 self.size_of_initialized_data.get(LE)
725 }
726
727 #[inline]
728 fn size_of_uninitialized_data(&self) -> u32 {
729 self.size_of_uninitialized_data.get(LE)
730 }
731
732 #[inline]
733 fn address_of_entry_point(&self) -> u32 {
734 self.address_of_entry_point.get(LE)
735 }
736
737 #[inline]
738 fn base_of_code(&self) -> u32 {
739 self.base_of_code.get(LE)
740 }
741
742 #[inline]
743 fn base_of_data(&self) -> Option<u32> {
744 Some(self.base_of_data.get(LE))
745 }
746
747 #[inline]
748 fn image_base(&self) -> u64 {
749 self.image_base.get(LE).into()
750 }
751
752 #[inline]
753 fn section_alignment(&self) -> u32 {
754 self.section_alignment.get(LE)
755 }
756
757 #[inline]
758 fn file_alignment(&self) -> u32 {
759 self.file_alignment.get(LE)
760 }
761
762 #[inline]
763 fn major_operating_system_version(&self) -> u16 {
764 self.major_operating_system_version.get(LE)
765 }
766
767 #[inline]
768 fn minor_operating_system_version(&self) -> u16 {
769 self.minor_operating_system_version.get(LE)
770 }
771
772 #[inline]
773 fn major_image_version(&self) -> u16 {
774 self.major_image_version.get(LE)
775 }
776
777 #[inline]
778 fn minor_image_version(&self) -> u16 {
779 self.minor_image_version.get(LE)
780 }
781
782 #[inline]
783 fn major_subsystem_version(&self) -> u16 {
784 self.major_subsystem_version.get(LE)
785 }
786
787 #[inline]
788 fn minor_subsystem_version(&self) -> u16 {
789 self.minor_subsystem_version.get(LE)
790 }
791
792 #[inline]
793 fn win32_version_value(&self) -> u32 {
794 self.win32_version_value.get(LE)
795 }
796
797 #[inline]
798 fn size_of_image(&self) -> u32 {
799 self.size_of_image.get(LE)
800 }
801
802 #[inline]
803 fn size_of_headers(&self) -> u32 {
804 self.size_of_headers.get(LE)
805 }
806
807 #[inline]
808 fn check_sum(&self) -> u32 {
809 self.check_sum.get(LE)
810 }
811
812 #[inline]
813 fn subsystem(&self) -> u16 {
814 self.subsystem.get(LE)
815 }
816
817 #[inline]
818 fn dll_characteristics(&self) -> u16 {
819 self.dll_characteristics.get(LE)
820 }
821
822 #[inline]
823 fn size_of_stack_reserve(&self) -> u64 {
824 self.size_of_stack_reserve.get(LE).into()
825 }
826
827 #[inline]
828 fn size_of_stack_commit(&self) -> u64 {
829 self.size_of_stack_commit.get(LE).into()
830 }
831
832 #[inline]
833 fn size_of_heap_reserve(&self) -> u64 {
834 self.size_of_heap_reserve.get(LE).into()
835 }
836
837 #[inline]
838 fn size_of_heap_commit(&self) -> u64 {
839 self.size_of_heap_commit.get(LE).into()
840 }
841
842 #[inline]
843 fn loader_flags(&self) -> u32 {
844 self.loader_flags.get(LE)
845 }
846
847 #[inline]
848 fn number_of_rva_and_sizes(&self) -> u32 {
849 self.number_of_rva_and_sizes.get(LE)
850 }
851}
852
853impl ImageNtHeaders for pe::ImageNtHeaders64 {
854 type ImageOptionalHeader = pe::ImageOptionalHeader64;
855 type ImageThunkData = pe::ImageThunkData64;
856
857 #[inline]
858 fn is_type_64(&self) -> bool {
859 true
860 }
861
862 #[inline]
863 fn is_valid_optional_magic(&self) -> bool {
864 self.optional_header.magic.get(LE) == pe::IMAGE_NT_OPTIONAL_HDR64_MAGIC
865 }
866
867 #[inline]
868 fn signature(&self) -> u32 {
869 self.signature.get(LE)
870 }
871
872 #[inline]
873 fn file_header(&self) -> &pe::ImageFileHeader {
874 &self.file_header
875 }
876
877 #[inline]
878 fn optional_header(&self) -> &Self::ImageOptionalHeader {
879 &self.optional_header
880 }
881}
882
883impl ImageOptionalHeader for pe::ImageOptionalHeader64 {
884 #[inline]
885 fn magic(&self) -> u16 {
886 self.magic.get(LE)
887 }
888
889 #[inline]
890 fn major_linker_version(&self) -> u8 {
891 self.major_linker_version
892 }
893
894 #[inline]
895 fn minor_linker_version(&self) -> u8 {
896 self.minor_linker_version
897 }
898
899 #[inline]
900 fn size_of_code(&self) -> u32 {
901 self.size_of_code.get(LE)
902 }
903
904 #[inline]
905 fn size_of_initialized_data(&self) -> u32 {
906 self.size_of_initialized_data.get(LE)
907 }
908
909 #[inline]
910 fn size_of_uninitialized_data(&self) -> u32 {
911 self.size_of_uninitialized_data.get(LE)
912 }
913
914 #[inline]
915 fn address_of_entry_point(&self) -> u32 {
916 self.address_of_entry_point.get(LE)
917 }
918
919 #[inline]
920 fn base_of_code(&self) -> u32 {
921 self.base_of_code.get(LE)
922 }
923
924 #[inline]
925 fn base_of_data(&self) -> Option<u32> {
926 None
927 }
928
929 #[inline]
930 fn image_base(&self) -> u64 {
931 self.image_base.get(LE)
932 }
933
934 #[inline]
935 fn section_alignment(&self) -> u32 {
936 self.section_alignment.get(LE)
937 }
938
939 #[inline]
940 fn file_alignment(&self) -> u32 {
941 self.file_alignment.get(LE)
942 }
943
944 #[inline]
945 fn major_operating_system_version(&self) -> u16 {
946 self.major_operating_system_version.get(LE)
947 }
948
949 #[inline]
950 fn minor_operating_system_version(&self) -> u16 {
951 self.minor_operating_system_version.get(LE)
952 }
953
954 #[inline]
955 fn major_image_version(&self) -> u16 {
956 self.major_image_version.get(LE)
957 }
958
959 #[inline]
960 fn minor_image_version(&self) -> u16 {
961 self.minor_image_version.get(LE)
962 }
963
964 #[inline]
965 fn major_subsystem_version(&self) -> u16 {
966 self.major_subsystem_version.get(LE)
967 }
968
969 #[inline]
970 fn minor_subsystem_version(&self) -> u16 {
971 self.minor_subsystem_version.get(LE)
972 }
973
974 #[inline]
975 fn win32_version_value(&self) -> u32 {
976 self.win32_version_value.get(LE)
977 }
978
979 #[inline]
980 fn size_of_image(&self) -> u32 {
981 self.size_of_image.get(LE)
982 }
983
984 #[inline]
985 fn size_of_headers(&self) -> u32 {
986 self.size_of_headers.get(LE)
987 }
988
989 #[inline]
990 fn check_sum(&self) -> u32 {
991 self.check_sum.get(LE)
992 }
993
994 #[inline]
995 fn subsystem(&self) -> u16 {
996 self.subsystem.get(LE)
997 }
998
999 #[inline]
1000 fn dll_characteristics(&self) -> u16 {
1001 self.dll_characteristics.get(LE)
1002 }
1003
1004 #[inline]
1005 fn size_of_stack_reserve(&self) -> u64 {
1006 self.size_of_stack_reserve.get(LE)
1007 }
1008
1009 #[inline]
1010 fn size_of_stack_commit(&self) -> u64 {
1011 self.size_of_stack_commit.get(LE)
1012 }
1013
1014 #[inline]
1015 fn size_of_heap_reserve(&self) -> u64 {
1016 self.size_of_heap_reserve.get(LE)
1017 }
1018
1019 #[inline]
1020 fn size_of_heap_commit(&self) -> u64 {
1021 self.size_of_heap_commit.get(LE)
1022 }
1023
1024 #[inline]
1025 fn loader_flags(&self) -> u32 {
1026 self.loader_flags.get(LE)
1027 }
1028
1029 #[inline]
1030 fn number_of_rva_and_sizes(&self) -> u32 {
1031 self.number_of_rva_and_sizes.get(LE)
1032 }
1033}