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