5 use core
::convert
::TryInto
;
7 use crate::read
::coff
::{CoffCommon, CoffSymbol, CoffSymbolIterator, CoffSymbolTable, SymbolTable}
;
9 self, Architecture
, ComdatKind
, Error
, Export
, FileFlags
, Import
, NoDynamicRelocationIterator
,
10 Object
, ObjectComdat
, ReadError
, ReadRef
, Result
, SectionIndex
, SymbolIndex
,
13 pe
, ByteString
, Bytes
, CodeView
, LittleEndian
as LE
, Pod
, U16Bytes
, U32Bytes
, U32
, U64
,
16 use super::{PeSection, PeSectionIterator, PeSegment, PeSegmentIterator, SectionTable}
;
18 /// A PE32 (32-bit) image file.
19 pub type PeFile32
<'data
, R
= &'data
[u8]> = PeFile
<'data
, pe
::ImageNtHeaders32
, R
>;
20 /// A PE32+ (64-bit) image file.
21 pub type PeFile64
<'data
, R
= &'data
[u8]> = PeFile
<'data
, pe
::ImageNtHeaders64
, R
>;
25 pub struct PeFile
<'data
, Pe
, R
= &'data
[u8]>
30 pub(super) dos_header
: &'data pe
::ImageDosHeader
,
31 pub(super) nt_headers
: &'data Pe
,
32 pub(super) data_directories
: &'data
[pe
::ImageDataDirectory
],
33 pub(super) common
: CoffCommon
<'data
, R
>,
37 impl<'data
, Pe
, R
> PeFile
<'data
, Pe
, R
>
42 /// Parse the raw PE file data.
43 pub fn parse(data
: R
) -> Result
<Self> {
44 let dos_header
= pe
::ImageDosHeader
::parse(data
)?
;
45 let mut offset
= dos_header
.nt_headers_offset().into();
46 let (nt_headers
, data_directories
) = Pe
::parse(data
, &mut offset
)?
;
47 let sections
= nt_headers
.sections(data
, offset
)?
;
48 let symbols
= nt_headers
.symbols(data
)?
;
49 let image_base
= nt_headers
.optional_header().image_base();
64 pub(super) fn section_alignment(&self) -> u64 {
65 u64::from(self.nt_headers
.optional_header().section_alignment())
68 /// Return the DOS header of this file
69 pub fn dos_header(&self) -> &'data pe
::ImageDosHeader
{
73 /// Return the NT Headers of this file
74 pub fn nt_headers(&self) -> &'data Pe
{
78 /// Returns the section table of this binary.
79 pub fn section_table(&self) -> SectionTable
<'data
> {
83 /// Returns the data directory at the given index.
84 pub fn data_directory(&self, id
: usize) -> Option
<&'data pe
::ImageDataDirectory
> {
87 .filter(|d
| d
.size
.get(LE
) != 0)
90 fn data_at(&self, va
: u32) -> Option
<Bytes
<'data
>> {
91 self.common
.sections
.pe_data_at(self.data
, va
).map(Bytes
)
94 /// Returns this binary data.
95 pub fn data(&self) -> R
{
100 impl<'data
, Pe
, R
> read
::private
::Sealed
for PeFile
<'data
, Pe
, R
>
107 impl<'data
, 'file
, Pe
, R
> Object
<'data
, 'file
> for PeFile
<'data
, Pe
, R
>
111 R
: 'file
+ ReadRef
<'data
>,
113 type Segment
= PeSegment
<'data
, 'file
, Pe
, R
>;
114 type SegmentIterator
= PeSegmentIterator
<'data
, 'file
, Pe
, R
>;
115 type Section
= PeSection
<'data
, 'file
, Pe
, R
>;
116 type SectionIterator
= PeSectionIterator
<'data
, 'file
, Pe
, R
>;
117 type Comdat
= PeComdat
<'data
, 'file
, Pe
, R
>;
118 type ComdatIterator
= PeComdatIterator
<'data
, 'file
, Pe
, R
>;
119 type Symbol
= CoffSymbol
<'data
, 'file
, R
>;
120 type SymbolIterator
= CoffSymbolIterator
<'data
, 'file
, R
>;
121 type SymbolTable
= CoffSymbolTable
<'data
, 'file
, R
>;
122 type DynamicRelocationIterator
= NoDynamicRelocationIterator
;
124 fn architecture(&self) -> Architecture
{
125 match self.nt_headers
.file_header().machine
.get(LE
) {
126 pe
::IMAGE_FILE_MACHINE_ARMNT
=> Architecture
::Arm
,
127 pe
::IMAGE_FILE_MACHINE_ARM64
=> Architecture
::Aarch64
,
128 pe
::IMAGE_FILE_MACHINE_I386
=> Architecture
::I386
,
129 pe
::IMAGE_FILE_MACHINE_AMD64
=> Architecture
::X86_64
,
130 _
=> Architecture
::Unknown
,
135 fn is_little_endian(&self) -> bool
{
136 // Only little endian is supported.
141 fn is_64(&self) -> bool
{
142 self.nt_headers
.is_type_64()
145 fn segments(&'file
self) -> PeSegmentIterator
<'data
, 'file
, Pe
, R
> {
148 iter
: self.common
.sections
.iter(),
152 fn section_by_name(&'file
self, section_name
: &str) -> Option
<PeSection
<'data
, 'file
, Pe
, R
>> {
155 .section_by_name(self.common
.symbols
.strings(), section_name
.as_bytes())
156 .map(|(index
, section
)| PeSection
{
158 index
: SectionIndex(index
),
166 ) -> Result
<PeSection
<'data
, 'file
, Pe
, R
>> {
167 let section
= self.common
.sections
.section(index
.0)?
;
175 fn sections(&'file
self) -> PeSectionIterator
<'data
, 'file
, Pe
, R
> {
178 iter
: self.common
.sections
.iter().enumerate(),
182 fn comdats(&'file
self) -> PeComdatIterator
<'data
, 'file
, Pe
, R
> {
183 PeComdatIterator { file: self }
186 fn symbol_by_index(&'file
self, index
: SymbolIndex
) -> Result
<CoffSymbol
<'data
, 'file
, R
>> {
187 let symbol
= self.common
.symbols
.symbol(index
.0)?
;
195 fn symbols(&'file
self) -> CoffSymbolIterator
<'data
, 'file
, R
> {
202 fn symbol_table(&'file
self) -> Option
<CoffSymbolTable
<'data
, 'file
, R
>> {
203 Some(CoffSymbolTable { file: &self.common }
)
206 fn dynamic_symbols(&'file
self) -> CoffSymbolIterator
<'data
, 'file
, R
> {
209 // Hack: don't return any.
210 index
: self.common
.symbols
.len(),
214 fn dynamic_symbol_table(&'file
self) -> Option
<CoffSymbolTable
<'data
, 'file
, R
>> {
218 fn dynamic_relocations(&'file
self) -> Option
<NoDynamicRelocationIterator
> {
222 fn imports(&self) -> Result
<Vec
<Import
<'data
>>> {
223 let data_dir
= match self.data_directory(pe
::IMAGE_DIRECTORY_ENTRY_IMPORT
) {
224 Some(data_dir
) => data_dir
,
225 None
=> return Ok(Vec
::new()),
227 let mut import_descriptors
= data_dir
.data(self.data
, &self.common
.sections
).map(Bytes
)?
;
228 let mut imports
= Vec
::new();
230 let import_desc
= import_descriptors
231 .read
::<pe
::ImageImportDescriptor
>()
232 .read_error("Missing PE null import descriptor")?
;
233 if import_desc
.original_first_thunk
.get(LE
) == 0 {
238 .data_at(import_desc
.name
.get(LE
))
239 .read_error("Invalid PE import descriptor name")?
241 .read_error("Invalid PE import descriptor name")?
;
243 let thunk_va
= import_desc
.original_first_thunk
.get(LE
);
244 let mut thunk_data
= self
246 .read_error("Invalid PE import thunk address")?
;
248 let hint_name
= if self.is_64() {
249 let thunk
= thunk_data
251 .read_error("Missing PE null import thunk")?
256 if thunk
& pe
::IMAGE_ORDINAL_FLAG64
!= 0 {
257 // TODO: handle import by ordinal
262 let thunk
= thunk_data
264 .read_error("Missing PE null import thunk")?
269 if thunk
& pe
::IMAGE_ORDINAL_FLAG32
!= 0 {
270 // TODO: handle import by ordinal
277 .read_error("Invalid PE import thunk name")?
279 .read_error("Invalid PE import thunk name")?
;
281 imports
.push(Import
{
282 name
: ByteString(name
),
283 library
: ByteString(library
),
290 fn exports(&self) -> Result
<Vec
<Export
<'data
>>> {
291 let data_dir
= match self.data_directory(pe
::IMAGE_DIRECTORY_ENTRY_EXPORT
) {
292 Some(data_dir
) => data_dir
,
293 None
=> return Ok(Vec
::new()),
295 let export_va
= data_dir
.virtual_address
.get(LE
);
296 let export_size
= data_dir
.size
.get(LE
);
297 let export_data
= data_dir
.data(self.data
, &self.common
.sections
).map(Bytes
)?
;
298 let export_dir
= export_data
299 .read_at
::<pe
::ImageExportDirectory
>(0)
300 .read_error("Invalid PE export dir size")?
;
301 let addresses
= export_data
302 .read_slice_at
::<U32Bytes
<_
>>(
304 .address_of_functions
306 .wrapping_sub(export_va
) as usize,
307 export_dir
.number_of_functions
.get(LE
) as usize,
309 .read_error("Invalid PE export address table")?
;
310 let number
= export_dir
.number_of_names
.get(LE
) as usize;
311 let names
= export_data
312 .read_slice_at
::<U32Bytes
<_
>>(
313 export_dir
.address_of_names
.get(LE
).wrapping_sub(export_va
) as usize,
316 .read_error("Invalid PE export name table")?
;
317 let ordinals
= export_data
318 .read_slice_at
::<U16Bytes
<_
>>(
320 .address_of_name_ordinals
322 .wrapping_sub(export_va
) as usize,
325 .read_error("Invalid PE export ordinal table")?
;
327 let mut exports
= Vec
::new();
328 for (name
, ordinal
) in names
.iter().zip(ordinals
.iter()) {
329 let name
= export_data
330 .read_string_at(name
.get(LE
).wrapping_sub(export_va
) as usize)
331 .read_error("Invalid PE export name entry")?
;
332 let address
= addresses
333 .get(ordinal
.get(LE
) as usize)
334 .read_error("Invalid PE export ordinal entry")?
336 // Check for export address (vs forwarder address).
337 if address
< export_va
|| (address
- export_va
) >= export_size
{
338 exports
.push(Export
{
339 name
: ByteString(name
),
340 address
: self.common
.image_base
.wrapping_add(address
.into()),
347 fn pdb_info(&self) -> Result
<Option
<CodeView
>> {
348 let data_dir
= match self.data_directory(pe
::IMAGE_DIRECTORY_ENTRY_DEBUG
) {
349 Some(data_dir
) => data_dir
,
350 None
=> return Ok(None
),
352 let debug_data
= data_dir
.data(self.data
, &self.common
.sections
).map(Bytes
)?
;
353 let debug_dir
= debug_data
354 .read_at
::<pe
::ImageDebugDirectory
>(0)
355 .read_error("Invalid PE debug dir size")?
;
357 if debug_dir
.typ
.get(LE
) != pe
::IMAGE_DEBUG_TYPE_CODEVIEW
{
363 .read_slice_at
::<u8>(
364 debug_dir
.pointer_to_raw_data
.get(LE
) as u64,
365 debug_dir
.size_of_data
.get(LE
) as usize,
367 .read_error("Invalid CodeView Info address")?
;
369 let mut info
= Bytes(info
);
373 .read_error("Invalid CodeView signature")?
;
374 if sig
.0 != b
"RSDS" {
378 let guid
: [u8; 16] = info
380 .read_error("Invalid CodeView GUID")?
385 let age
= info
.read
::<U32
<LE
>>().read_error("Invalid CodeView Age")?
;
389 .read_error("Invalid CodeView file path")?
;
392 path
: ByteString(path
),
398 fn has_debug_symbols(&self) -> bool
{
399 self.section_by_name(".debug_info").is_some()
402 fn relative_address_base(&self) -> u64 {
403 self.common
.image_base
406 fn entry(&self) -> u64 {
407 u64::from(self.nt_headers
.optional_header().address_of_entry_point())
408 .wrapping_add(self.common
.image_base
)
411 fn flags(&self) -> FileFlags
{
413 characteristics
: self.nt_headers
.file_header().characteristics
.get(LE
),
418 /// An iterator over the COMDAT section groups of a `PeFile32`.
419 pub type PeComdatIterator32
<'data
, 'file
, R
= &'data
[u8]> =
420 PeComdatIterator
<'data
, 'file
, pe
::ImageNtHeaders32
, R
>;
421 /// An iterator over the COMDAT section groups of a `PeFile64`.
422 pub type PeComdatIterator64
<'data
, 'file
, R
= &'data
[u8]> =
423 PeComdatIterator
<'data
, 'file
, pe
::ImageNtHeaders64
, R
>;
425 /// An iterator over the COMDAT section groups of a `PeFile`.
427 pub struct PeComdatIterator
<'data
, 'file
, Pe
, R
= &'data
[u8]>
432 file
: &'file PeFile
<'data
, Pe
, R
>,
435 impl<'data
, 'file
, Pe
, R
> Iterator
for PeComdatIterator
<'data
, 'file
, Pe
, R
>
440 type Item
= PeComdat
<'data
, 'file
, Pe
, R
>;
443 fn next(&mut self) -> Option
<Self::Item
> {
448 /// A COMDAT section group of a `PeFile32`.
449 pub type PeComdat32
<'data
, 'file
, R
= &'data
[u8]> =
450 PeComdat
<'data
, 'file
, pe
::ImageNtHeaders32
, R
>;
451 /// A COMDAT section group of a `PeFile64`.
452 pub type PeComdat64
<'data
, 'file
, R
= &'data
[u8]> =
453 PeComdat
<'data
, 'file
, pe
::ImageNtHeaders64
, R
>;
455 /// A COMDAT section group of a `PeFile`.
457 pub struct PeComdat
<'data
, 'file
, Pe
, R
= &'data
[u8]>
462 file
: &'file PeFile
<'data
, Pe
, R
>,
465 impl<'data
, 'file
, Pe
, R
> read
::private
::Sealed
for PeComdat
<'data
, 'file
, Pe
, R
>
472 impl<'data
, 'file
, Pe
, R
> ObjectComdat
<'data
> for PeComdat
<'data
, 'file
, Pe
, R
>
477 type SectionIterator
= PeComdatSectionIterator
<'data
, 'file
, Pe
, R
>;
480 fn kind(&self) -> ComdatKind
{
485 fn symbol(&self) -> SymbolIndex
{
490 fn name(&self) -> Result
<&str> {
495 fn sections(&self) -> Self::SectionIterator
{
500 /// An iterator over the sections in a COMDAT section group of a `PeFile32`.
501 pub type PeComdatSectionIterator32
<'data
, 'file
, R
= &'data
[u8]> =
502 PeComdatSectionIterator
<'data
, 'file
, pe
::ImageNtHeaders32
, R
>;
503 /// An iterator over the sections in a COMDAT section group of a `PeFile64`.
504 pub type PeComdatSectionIterator64
<'data
, 'file
, R
= &'data
[u8]> =
505 PeComdatSectionIterator
<'data
, 'file
, pe
::ImageNtHeaders64
, R
>;
507 /// An iterator over the sections in a COMDAT section group of a `PeFile`.
509 pub struct PeComdatSectionIterator
<'data
, 'file
, Pe
, R
= &'data
[u8]>
514 file
: &'file PeFile
<'data
, Pe
, R
>,
517 impl<'data
, 'file
, Pe
, R
> Iterator
for PeComdatSectionIterator
<'data
, 'file
, Pe
, R
>
522 type Item
= SectionIndex
;
524 fn next(&mut self) -> Option
<Self::Item
> {
529 impl pe
::ImageDosHeader
{
530 /// Read the DOS header.
532 /// Also checks that the `e_magic` field in the header is valid.
533 pub fn parse
<'data
, R
: ReadRef
<'data
>>(data
: R
) -> read
::Result
<&'data
Self> {
534 // DOS header comes first.
535 let dos_header
= data
536 .read_at
::<pe
::ImageDosHeader
>(0)
537 .read_error("Invalid DOS header size or alignment")?
;
538 if dos_header
.e_magic
.get(LE
) != pe
::IMAGE_DOS_SIGNATURE
{
539 return Err(Error("Invalid DOS magic"));
544 /// Return the file offset of the nt_headers.
546 pub fn nt_headers_offset(&self) -> u32 {
547 self.e_lfanew
.get(LE
)
551 /// Find the optional header and read the `optional_header.magic`.
553 /// It can be useful to know this magic value before trying to
554 /// fully parse the NT headers.
555 pub fn optional_header_magic
<'data
, R
: ReadRef
<'data
>>(data
: R
) -> Result
<u16> {
556 let dos_header
= pe
::ImageDosHeader
::parse(data
)?
;
557 // NT headers are at an offset specified in the DOS header.
558 let offset
= dos_header
.nt_headers_offset().into();
559 // It doesn't matter which NT header type is used for the purpose
560 // of reading the optional header magic.
561 let nt_headers
= data
562 .read_at
::<pe
::ImageNtHeaders32
>(offset
)
563 .read_error("Invalid NT headers offset, size, or alignment")?
;
564 if nt_headers
.signature() != pe
::IMAGE_NT_SIGNATURE
{
565 return Err(Error("Invalid PE magic"));
567 Ok(nt_headers
.optional_header().magic())
570 /// A trait for generic access to `ImageNtHeaders32` and `ImageNtHeaders64`.
571 #[allow(missing_docs)]
572 pub trait ImageNtHeaders
: Debug
+ Pod
{
573 type ImageOptionalHeader
: ImageOptionalHeader
;
575 /// Return true if this type is a 64-bit header.
577 /// This is a property of the type, not a value in the header data.
578 fn is_type_64(&self) -> bool
;
580 /// Return true if the magic field in the optional header is valid.
581 fn is_valid_optional_magic(&self) -> bool
;
583 /// Return the signature
584 fn signature(&self) -> u32;
586 /// Return the file header.
587 fn file_header(&self) -> &pe
::ImageFileHeader
;
589 /// Return the optional header.
590 fn optional_header(&self) -> &Self::ImageOptionalHeader
;
594 /// Read the NT headers, including the data directories.
596 /// `data` must be for the entire file.
598 /// `offset` must be headers offset, which can be obtained from `ImageDosHeader::nt_headers_offset`.
599 /// It is updated to point after the optional header, which is where the section headers are located.
601 /// Also checks that the `signature` and `magic` fields in the headers are valid.
602 fn parse
<'data
, R
: ReadRef
<'data
>>(
605 ) -> read
::Result
<(&'data
Self, &'data
[pe
::ImageDataDirectory
])> {
606 // Note that this does not include the data directories in the optional header.
607 let nt_headers
= data
608 .read
::<Self>(offset
)
609 .read_error("Invalid PE headers offset or size")?
;
610 if nt_headers
.signature() != pe
::IMAGE_NT_SIGNATURE
{
611 return Err(Error("Invalid PE magic"));
613 if !nt_headers
.is_valid_optional_magic() {
614 return Err(Error("Invalid PE optional header magic"));
617 // Read the rest of the optional header, and then read the data directories from that.
618 let optional_data_size
=
619 u64::from(nt_headers
.file_header().size_of_optional_header
.get(LE
))
620 .checked_sub(mem
::size_of
::<Self::ImageOptionalHeader
>() as u64)
621 .read_error("PE optional header size is too small")?
;
622 let mut optional_data
= data
623 .read_bytes(offset
, optional_data_size
)
624 .read_error("Invalid PE optional header size")
626 let data_directories
= optional_data
627 .read_slice(nt_headers
.optional_header().number_of_rva_and_sizes() as usize)
628 .read_error("Invalid PE number of RVA and sizes")?
;
630 Ok((nt_headers
, data_directories
))
633 /// Read the section table.
635 /// `data` must be for the entire file.
636 /// `offset` must be after the optional file header.
638 fn sections
<'data
, R
: ReadRef
<'data
>>(
642 ) -> read
::Result
<SectionTable
<'data
>> {
643 SectionTable
::parse(self.file_header(), data
, offset
)
646 /// Read the symbol table and string table.
648 /// `data` must be the entire file data.
650 fn symbols
<'data
, R
: ReadRef
<'data
>>(&self, data
: R
) -> read
::Result
<SymbolTable
<'data
, R
>> {
651 SymbolTable
::parse(self.file_header(), data
)
655 /// A trait for generic access to `ImageOptionalHeader32` and `ImageOptionalHeader64`.
656 #[allow(missing_docs)]
657 pub trait ImageOptionalHeader
: Debug
+ Pod
{
659 fn magic(&self) -> u16;
660 fn major_linker_version(&self) -> u8;
661 fn minor_linker_version(&self) -> u8;
662 fn size_of_code(&self) -> u32;
663 fn size_of_initialized_data(&self) -> u32;
664 fn size_of_uninitialized_data(&self) -> u32;
665 fn address_of_entry_point(&self) -> u32;
666 fn base_of_code(&self) -> u32;
668 // NT additional fields.
669 fn image_base(&self) -> u64;
670 fn section_alignment(&self) -> u32;
671 fn file_alignment(&self) -> u32;
672 fn major_operating_system_version(&self) -> u16;
673 fn minor_operating_system_version(&self) -> u16;
674 fn major_image_version(&self) -> u16;
675 fn minor_image_version(&self) -> u16;
676 fn major_subsystem_version(&self) -> u16;
677 fn minor_subsystem_version(&self) -> u16;
678 fn win32_version_value(&self) -> u32;
679 fn size_of_image(&self) -> u32;
680 fn size_of_headers(&self) -> u32;
681 fn check_sum(&self) -> u32;
682 fn subsystem(&self) -> u16;
683 fn dll_characteristics(&self) -> u16;
684 fn size_of_stack_reserve(&self) -> u64;
685 fn size_of_stack_commit(&self) -> u64;
686 fn size_of_heap_reserve(&self) -> u64;
687 fn size_of_heap_commit(&self) -> u64;
688 fn loader_flags(&self) -> u32;
689 fn number_of_rva_and_sizes(&self) -> u32;
692 impl ImageNtHeaders
for pe
::ImageNtHeaders32
{
693 type ImageOptionalHeader
= pe
::ImageOptionalHeader32
;
696 fn is_type_64(&self) -> bool
{
701 fn is_valid_optional_magic(&self) -> bool
{
702 self.optional_header
.magic
.get(LE
) == pe
::IMAGE_NT_OPTIONAL_HDR32_MAGIC
706 fn signature(&self) -> u32 {
707 self.signature
.get(LE
)
711 fn file_header(&self) -> &pe
::ImageFileHeader
{
716 fn optional_header(&self) -> &Self::ImageOptionalHeader
{
717 &self.optional_header
721 impl ImageOptionalHeader
for pe
::ImageOptionalHeader32
{
723 fn magic(&self) -> u16 {
728 fn major_linker_version(&self) -> u8 {
729 self.major_linker_version
733 fn minor_linker_version(&self) -> u8 {
734 self.minor_linker_version
738 fn size_of_code(&self) -> u32 {
739 self.size_of_code
.get(LE
)
743 fn size_of_initialized_data(&self) -> u32 {
744 self.size_of_initialized_data
.get(LE
)
748 fn size_of_uninitialized_data(&self) -> u32 {
749 self.size_of_uninitialized_data
.get(LE
)
753 fn address_of_entry_point(&self) -> u32 {
754 self.address_of_entry_point
.get(LE
)
758 fn base_of_code(&self) -> u32 {
759 self.base_of_code
.get(LE
)
763 fn image_base(&self) -> u64 {
764 self.image_base
.get(LE
).into()
768 fn section_alignment(&self) -> u32 {
769 self.section_alignment
.get(LE
)
773 fn file_alignment(&self) -> u32 {
774 self.file_alignment
.get(LE
)
778 fn major_operating_system_version(&self) -> u16 {
779 self.major_operating_system_version
.get(LE
)
783 fn minor_operating_system_version(&self) -> u16 {
784 self.minor_operating_system_version
.get(LE
)
788 fn major_image_version(&self) -> u16 {
789 self.major_image_version
.get(LE
)
793 fn minor_image_version(&self) -> u16 {
794 self.minor_image_version
.get(LE
)
798 fn major_subsystem_version(&self) -> u16 {
799 self.major_subsystem_version
.get(LE
)
803 fn minor_subsystem_version(&self) -> u16 {
804 self.minor_subsystem_version
.get(LE
)
808 fn win32_version_value(&self) -> u32 {
809 self.win32_version_value
.get(LE
)
813 fn size_of_image(&self) -> u32 {
814 self.size_of_image
.get(LE
)
818 fn size_of_headers(&self) -> u32 {
819 self.size_of_headers
.get(LE
)
823 fn check_sum(&self) -> u32 {
824 self.check_sum
.get(LE
)
828 fn subsystem(&self) -> u16 {
829 self.subsystem
.get(LE
)
833 fn dll_characteristics(&self) -> u16 {
834 self.dll_characteristics
.get(LE
)
838 fn size_of_stack_reserve(&self) -> u64 {
839 self.size_of_stack_reserve
.get(LE
).into()
843 fn size_of_stack_commit(&self) -> u64 {
844 self.size_of_stack_commit
.get(LE
).into()
848 fn size_of_heap_reserve(&self) -> u64 {
849 self.size_of_heap_reserve
.get(LE
).into()
853 fn size_of_heap_commit(&self) -> u64 {
854 self.size_of_heap_commit
.get(LE
).into()
858 fn loader_flags(&self) -> u32 {
859 self.loader_flags
.get(LE
)
863 fn number_of_rva_and_sizes(&self) -> u32 {
864 self.number_of_rva_and_sizes
.get(LE
)
868 impl ImageNtHeaders
for pe
::ImageNtHeaders64
{
869 type ImageOptionalHeader
= pe
::ImageOptionalHeader64
;
872 fn is_type_64(&self) -> bool
{
877 fn is_valid_optional_magic(&self) -> bool
{
878 self.optional_header
.magic
.get(LE
) == pe
::IMAGE_NT_OPTIONAL_HDR64_MAGIC
882 fn signature(&self) -> u32 {
883 self.signature
.get(LE
)
887 fn file_header(&self) -> &pe
::ImageFileHeader
{
892 fn optional_header(&self) -> &Self::ImageOptionalHeader
{
893 &self.optional_header
897 impl ImageOptionalHeader
for pe
::ImageOptionalHeader64
{
899 fn magic(&self) -> u16 {
904 fn major_linker_version(&self) -> u8 {
905 self.major_linker_version
909 fn minor_linker_version(&self) -> u8 {
910 self.minor_linker_version
914 fn size_of_code(&self) -> u32 {
915 self.size_of_code
.get(LE
)
919 fn size_of_initialized_data(&self) -> u32 {
920 self.size_of_initialized_data
.get(LE
)
924 fn size_of_uninitialized_data(&self) -> u32 {
925 self.size_of_uninitialized_data
.get(LE
)
929 fn address_of_entry_point(&self) -> u32 {
930 self.address_of_entry_point
.get(LE
)
934 fn base_of_code(&self) -> u32 {
935 self.base_of_code
.get(LE
)
939 fn image_base(&self) -> u64 {
940 self.image_base
.get(LE
)
944 fn section_alignment(&self) -> u32 {
945 self.section_alignment
.get(LE
)
949 fn file_alignment(&self) -> u32 {
950 self.file_alignment
.get(LE
)
954 fn major_operating_system_version(&self) -> u16 {
955 self.major_operating_system_version
.get(LE
)
959 fn minor_operating_system_version(&self) -> u16 {
960 self.minor_operating_system_version
.get(LE
)
964 fn major_image_version(&self) -> u16 {
965 self.major_image_version
.get(LE
)
969 fn minor_image_version(&self) -> u16 {
970 self.minor_image_version
.get(LE
)
974 fn major_subsystem_version(&self) -> u16 {
975 self.major_subsystem_version
.get(LE
)
979 fn minor_subsystem_version(&self) -> u16 {
980 self.minor_subsystem_version
.get(LE
)
984 fn win32_version_value(&self) -> u32 {
985 self.win32_version_value
.get(LE
)
989 fn size_of_image(&self) -> u32 {
990 self.size_of_image
.get(LE
)
994 fn size_of_headers(&self) -> u32 {
995 self.size_of_headers
.get(LE
)
999 fn check_sum(&self) -> u32 {
1000 self.check_sum
.get(LE
)
1004 fn subsystem(&self) -> u16 {
1005 self.subsystem
.get(LE
)
1009 fn dll_characteristics(&self) -> u16 {
1010 self.dll_characteristics
.get(LE
)
1014 fn size_of_stack_reserve(&self) -> u64 {
1015 self.size_of_stack_reserve
.get(LE
)
1019 fn size_of_stack_commit(&self) -> u64 {
1020 self.size_of_stack_commit
.get(LE
)
1024 fn size_of_heap_reserve(&self) -> u64 {
1025 self.size_of_heap_reserve
.get(LE
)
1029 fn size_of_heap_commit(&self) -> u64 {
1030 self.size_of_heap_commit
.get(LE
)
1034 fn loader_flags(&self) -> u32 {
1035 self.loader_flags
.get(LE
)
1039 fn number_of_rva_and_sizes(&self) -> u32 {
1040 self.number_of_rva_and_sizes
.get(LE
)
1044 impl pe
::ImageDataDirectory
{
1045 /// Get the data referenced by this directory entry.
1046 pub fn data
<'data
, R
: ReadRef
<'data
>>(
1049 sections
: &SectionTable
<'data
>,
1050 ) -> Result
<&'data
[u8]> {
1052 .pe_data_at(data
, self.virtual_address
.get(LE
))
1053 .read_error("Invalid data dir virtual address or size")?
1054 .get(..self.size
.get(LE
) as usize)
1055 .read_error("Invalid data dir size")