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