1use object::ReadRef as _;
9pub use object::{
10 pe::{
11 IMAGE_DIRECTORY_ENTRY_ARCHITECTURE, IMAGE_DIRECTORY_ENTRY_BASERELOC,
12 IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT, IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR,
13 IMAGE_DIRECTORY_ENTRY_DEBUG, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT,
14 IMAGE_DIRECTORY_ENTRY_EXCEPTION, IMAGE_DIRECTORY_ENTRY_EXPORT,
15 IMAGE_DIRECTORY_ENTRY_GLOBALPTR, IMAGE_DIRECTORY_ENTRY_IAT, IMAGE_DIRECTORY_ENTRY_IMPORT,
16 IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, IMAGE_DIRECTORY_ENTRY_RESOURCE,
17 IMAGE_DIRECTORY_ENTRY_SECURITY, IMAGE_DIRECTORY_ENTRY_TLS, IMAGE_DOS_SIGNATURE,
18 IMAGE_NT_OPTIONAL_HDR32_MAGIC, IMAGE_NT_OPTIONAL_HDR64_MAGIC, IMAGE_NT_SIGNATURE,
19 IMAGE_NUMBEROF_DIRECTORY_ENTRIES, IMAGE_SIZEOF_SHORT_NAME,
20 },
21 read::pe::{Export, ExportTable, ExportTarget},
23};
24
25pub const IMAGE_DEBUG_TYPE_CODEVIEW: u32 = ::object::pe::IMAGE_DEBUG_TYPE_CODEVIEW.0;
27
28use super::error::PeError;
29
30trait ToEndian<E>
37where
38 E: ::object::Endian,
39{
40 type Output;
42
43 fn to_endian(&self, endian: E) -> Self::Output;
45}
46
47impl<E, T> ToEndian<E> for ::object::U16<E, T>
48where
49 E: ::object::Endian,
50 T: ::object::Wrap<Inner = u16> + Copy,
51{
52 type Output = u16;
53
54 fn to_endian(&self, endian: E) -> Self::Output {
55 (*self).get(endian).into_inner()
56 }
57}
58
59impl<E, T> ToEndian<E> for ::object::U32<E, T>
60where
61 E: ::object::Endian,
62 T: ::object::Wrap<Inner = u32> + Copy,
63{
64 type Output = u32;
65
66 fn to_endian(&self, endian: E) -> Self::Output {
67 (*self).get(endian).into_inner()
68 }
69}
70
71impl<E, T> ToEndian<E> for ::object::U64<E, T>
72where
73 E: ::object::Endian,
74 T: ::object::Wrap<Inner = u64> + Copy,
75{
76 type Output = u64;
77
78 fn to_endian(&self, endian: E) -> Self::Output {
79 (*self).get(endian).into_inner()
80 }
81}
82
83impl<E: ::object::Endian> ToEndian<E> for u8 {
84 type Output = u8;
85
86 fn to_endian(&self, _endian: E) -> Self::Output {
87 *self
88 }
89}
90
91impl<E: ::object::Endian, const N: usize> ToEndian<E> for [u8; N] {
92 type Output = [u8; N];
93
94 fn to_endian(&self, _endian: E) -> Self::Output {
95 *self
96 }
97}
98
99impl<E: ::object::Endian, const N: usize> ToEndian<E> for [::object::U16<E>; N] {
100 type Output = [u16; N];
101
102 fn to_endian(&self, endian: E) -> Self::Output {
103 std::array::from_fn(|i| self[i].get(endian))
104 }
105}
106
107macro_rules! impl_struct {
137 (@parse
148 from = []
149 doc = [$($doc:tt)*]
150 derive = [$($derive:tt)*]
151 attrs = [$($attrs:tt)*]
152 rest = [#[from($from:ty)] $($rest:tt)*]
153 ) => {
154 impl_struct!(@parse
155 from = [$from]
156 doc = [$($doc)*]
157 derive = [$($derive)*]
158 attrs = [$($attrs)*]
159 rest = [$($rest)*]
160 );
161 };
162
163 (@parse
165 from = [$_first:ty]
166 doc = [$($doc:tt)*]
167 derive = [$($derive:tt)*]
168 attrs = [$($attrs:tt)*]
169 rest = [#[from($_dup:ty)] $($rest:tt)*]
170 ) => {
171 compile_error!("impl_struct!: duplicate `#[from(...)]` attribute");
172 };
173
174 (@parse
176 from = [$($from:tt)*]
177 doc = [$($doc:tt)*]
178 derive = [$($derive:tt)*]
179 attrs = [$($attrs:tt)*]
180 rest = [#[doc = $d:literal] $($rest:tt)*]
181 ) => {
182 impl_struct!(@parse
183 from = [$($from)*]
184 doc = [$($doc)* #[doc = $d]]
185 derive = [$($derive)*]
186 attrs = [$($attrs)*]
187 rest = [$($rest)*]
188 );
189 };
190
191 (@parse
193 from = [$($from:tt)*]
194 doc = [$($doc:tt)*]
195 derive = [$($derive:tt)*]
196 attrs = [$($attrs:tt)*]
197 rest = [#[derive($($d:path),* $(,)?)] $($rest:tt)*]
198 ) => {
199 impl_struct!(@parse
200 from = [$($from)*]
201 doc = [$($doc)*]
202 derive = [$($derive)* $($d,)*]
203 attrs = [$($attrs)*]
204 rest = [$($rest)*]
205 );
206 };
207
208 (@parse
210 from = [$($from:tt)*]
211 doc = [$($doc:tt)*]
212 derive = [$($derive:tt)*]
213 attrs = [$($attrs:tt)*]
214 rest = [#[$attr:meta] $($rest:tt)*]
215 ) => {
216 impl_struct!(@parse
217 from = [$($from)*]
218 doc = [$($doc)*]
219 derive = [$($derive)*]
220 attrs = [$($attrs)* #[$attr]]
221 rest = [$($rest)*]
222 );
223 };
224
225 (@parse
234 from = [$from_ty:ty]
235 doc = [$($doc:tt)*]
236 derive = [$($derive:tt)*]
237 attrs = [$($attrs:tt)*]
238 rest = [
239 $vis:vis struct $name:ident {
240 $(
241 $(#[$field_attr:meta])*
242 $field_vis:vis $field:ident : $field_ty:ty
243 ),* $(,)?
244 }
245 ]
246 ) => {
247 $($doc)*
248 #[derive(
249 $($derive)*
250 ::zerocopy::FromBytes,
251 ::zerocopy::IntoBytes,
252 ::zerocopy::Immutable,
253 ::zerocopy::KnownLayout,
254 )]
255 #[repr(C, packed)]
256 $($attrs)*
257 $vis struct $name {
258 $(
259 $(#[$field_attr])*
260 $field_vis $field: $field_ty,
261 )*
262 }
263
264 impl ::core::convert::From<$from_ty> for $name {
265 fn from(value: $from_ty) -> Self {
266 Self {
267 $(
268 $field: value.$field.to_endian(::object::LittleEndian),
269 )*
270 }
271 }
272 }
273
274 const _: () = {
275 use ::core::mem::{align_of, size_of};
276
277 assert!(
278 size_of::<$name>() == size_of::<$from_ty>(),
279 concat!(stringify!($name), " size mismatch"),
280 );
281
282 assert!(
283 align_of::<$name>() == align_of::<$from_ty>(),
284 concat!(stringify!($name), " alignment mismatch"),
285 );
286 };
287
288 $(
289 const _: () = {
290 use ::core::mem::offset_of;
291
292 assert!(
293 offset_of!($name, $field) == offset_of!($from_ty, $field),
294 concat!(stringify!($name), " field offset mismatch: ", stringify!($field)),
295 );
296 };
297 )*
298 };
299
300 (@parse
301 from = []
302 doc = [$($doc:tt)*]
303 derive = [$($derive:tt)*]
304 attrs = [$($attrs:tt)*]
305 rest = [$vis:vis struct $name:ident { $($body:tt)* }]
306 ) => {
307 compile_error!(concat!(
308 "impl_struct!: missing `#[from(SourceType)]` attribute on `",
309 stringify!($name),
310 "`",
311 ));
312 };
313
314 ($($input:tt)*) => {
324 impl_struct!(@parse
325 from = []
326 doc = []
327 derive = []
328 attrs = []
329 rest = [$($input)*]
330 );
331 };
332}
333
334impl_struct! {
335 #[derive(Debug, Clone, Copy)]
345 #[from(::object::pe::ImageDosHeader)]
346 pub struct ImageDosHeader {
347 pub e_magic: u16,
349
350 pub e_cblp: u16,
352
353 pub e_cp: u16,
355
356 pub e_crlc: u16,
358
359 pub e_cparhdr: u16,
361
362 pub e_minalloc: u16,
364
365 pub e_maxalloc: u16,
367
368 pub e_ss: u16,
370
371 pub e_sp: u16,
373
374 pub e_csum: u16,
376
377 pub e_ip: u16,
379
380 pub e_cs: u16,
382
383 pub e_lfarlc: u16,
385
386 pub e_ovno: u16,
388
389 pub e_res: [u16; 4],
391
392 pub e_oemid: u16,
394
395 pub e_oeminfo: u16,
397
398 pub e_res2: [u16; 10],
400
401 pub e_lfanew: u32,
403 }
404}
405
406impl ImageDosHeader {
407 pub fn parse(data: &[u8], offset: &mut u64) -> Result<Self, PeError> {
409 let dos_header = data
410 .read_at::<::object::pe::ImageDosHeader>(0)
411 .copied()
412 .map_err(|_| PeError::InvalidDosHeader)?;
413
414 if dos_header.e_magic.get(::object::LittleEndian) != IMAGE_DOS_SIGNATURE {
415 return Err(PeError::InvalidDosMagic);
416 }
417
418 *offset = dos_header.nt_headers_offset() as u64;
419
420 Ok(dos_header.into())
421 }
422
423 pub fn nt_headers_offset(&self) -> u32 {
425 self.e_lfanew
426 }
427}
428
429#[derive(Debug, Clone, Copy)]
438pub struct ImageNtHeaders {
439 pub signature: u32,
441
442 pub file_header: ImageFileHeader,
444
445 pub optional_header: ImageOptionalHeader,
447}
448
449impl ImageNtHeaders {
450 pub fn parse(data: &[u8], offset: &mut u64) -> Result<Self, PeError> {
452 let magic =
453 ::object::read::pe::optional_header_magic(data).map_err(|_| PeError::InvalidPeMagic)?;
454
455 match magic {
456 IMAGE_NT_OPTIONAL_HDR32_MAGIC => {
457 Self::parse_inner::<::object::pe::ImageNtHeaders32>(data, offset)
458 }
459 IMAGE_NT_OPTIONAL_HDR64_MAGIC => {
460 Self::parse_inner::<::object::pe::ImageNtHeaders64>(data, offset)
461 }
462 _ => Err(PeError::InvalidPeMagic),
463 }
464 }
465
466 fn parse_inner<Pe>(data: &[u8], offset: &mut u64) -> Result<Self, PeError>
467 where
468 Self: From<Pe>,
469 Pe: ::object::read::pe::ImageNtHeaders,
470 {
471 let nt_headers = data
472 .read::<Pe>(offset)
473 .copied()
474 .map_err(|_| PeError::InvalidNtHeaders)?;
475
476 if nt_headers.signature() != IMAGE_NT_SIGNATURE {
477 return Err(PeError::InvalidPeMagic);
478 }
479
480 if !nt_headers.is_valid_optional_magic() {
481 return Err(PeError::InvalidOptionalHeaderMagic);
482 }
483
484 Ok(nt_headers.into())
485 }
486}
487
488impl From<::object::pe::ImageNtHeaders32> for ImageNtHeaders {
489 fn from(value: ::object::pe::ImageNtHeaders32) -> Self {
490 Self {
491 signature: value.signature.get(::object::LittleEndian),
492 file_header: value.file_header.into(),
493 optional_header: value.optional_header.into(),
494 }
495 }
496}
497
498impl From<::object::pe::ImageNtHeaders64> for ImageNtHeaders {
499 fn from(value: ::object::pe::ImageNtHeaders64) -> Self {
500 Self {
501 signature: value.signature.get(::object::LittleEndian),
502 file_header: value.file_header.into(),
503 optional_header: value.optional_header.into(),
504 }
505 }
506}
507
508impl_struct! {
509 #[derive(Debug, Clone, Copy)]
515 #[from(::object::pe::ImageFileHeader)]
516 pub struct ImageFileHeader {
517 pub machine: u16,
519
520 pub number_of_sections: u16,
522
523 pub time_date_stamp: u32,
525
526 pub pointer_to_symbol_table: u32,
528
529 pub number_of_symbols: u32,
531
532 pub size_of_optional_header: u16,
534
535 pub characteristics: u16,
537 }
538}
539
540impl_struct! {
541 #[derive(Debug, Clone, Copy)]
551 #[from(::object::pe::ImageOptionalHeader32)]
552 pub struct ImageOptionalHeader32 {
553 pub magic: u16,
555
556 pub major_linker_version: u8,
558
559 pub minor_linker_version: u8,
561
562 pub size_of_code: u32,
564
565 pub size_of_initialized_data: u32,
567
568 pub size_of_uninitialized_data: u32,
570
571 pub address_of_entry_point: u32,
573
574 pub base_of_code: u32,
576
577 pub base_of_data: u32,
579
580 pub image_base: u32,
582
583 pub section_alignment: u32,
585
586 pub file_alignment: u32,
588
589 pub major_operating_system_version: u16,
591
592 pub minor_operating_system_version: u16,
594
595 pub major_image_version: u16,
597
598 pub minor_image_version: u16,
600
601 pub major_subsystem_version: u16,
603
604 pub minor_subsystem_version: u16,
606
607 pub win32_version_value: u32,
609
610 pub size_of_image: u32,
612
613 pub size_of_headers: u32,
615
616 pub check_sum: u32,
618
619 pub subsystem: u16,
621
622 pub dll_characteristics: u16,
624
625 pub size_of_stack_reserve: u32,
627
628 pub size_of_stack_commit: u32,
630
631 pub size_of_heap_reserve: u32,
633
634 pub size_of_heap_commit: u32,
636
637 pub loader_flags: u32,
639
640 pub number_of_rva_and_sizes: u32,
642 }
643}
644
645impl_struct! {
646 #[derive(Debug, Clone, Copy)]
656 #[from(::object::pe::ImageOptionalHeader64)]
657 pub struct ImageOptionalHeader64 {
658 pub magic: u16,
660
661 pub major_linker_version: u8,
663
664 pub minor_linker_version: u8,
666
667 pub size_of_code: u32,
669
670 pub size_of_initialized_data: u32,
672
673 pub size_of_uninitialized_data: u32,
675
676 pub address_of_entry_point: u32,
678
679 pub base_of_code: u32,
681
682 pub image_base: u64,
684
685 pub section_alignment: u32,
687
688 pub file_alignment: u32,
690
691 pub major_operating_system_version: u16,
693
694 pub minor_operating_system_version: u16,
696
697 pub major_image_version: u16,
699
700 pub minor_image_version: u16,
702
703 pub major_subsystem_version: u16,
705
706 pub minor_subsystem_version: u16,
708
709 pub win32_version_value: u32,
711
712 pub size_of_image: u32,
714
715 pub size_of_headers: u32,
717
718 pub check_sum: u32,
720
721 pub subsystem: u16,
723
724 pub dll_characteristics: u16,
726
727 pub size_of_stack_reserve: u64,
729
730 pub size_of_stack_commit: u64,
732
733 pub size_of_heap_reserve: u64,
735
736 pub size_of_heap_commit: u64,
738
739 pub loader_flags: u32,
741
742 pub number_of_rva_and_sizes: u32,
744 }
745}
746
747#[derive(Debug, Clone, Copy)]
755pub enum ImageOptionalHeader {
756 ImageOptionalHeader32(ImageOptionalHeader32),
758
759 ImageOptionalHeader64(ImageOptionalHeader64),
761}
762
763impl From<::object::pe::ImageOptionalHeader32> for ImageOptionalHeader {
764 fn from(value: ::object::pe::ImageOptionalHeader32) -> Self {
765 Self::ImageOptionalHeader32(value.into())
766 }
767}
768
769impl From<::object::pe::ImageOptionalHeader64> for ImageOptionalHeader {
770 fn from(value: ::object::pe::ImageOptionalHeader64) -> Self {
771 Self::ImageOptionalHeader64(value.into())
772 }
773}
774
775impl ImageOptionalHeader {
776 pub fn magic(&self) -> u16 {
778 match self {
779 Self::ImageOptionalHeader32(hdr32) => hdr32.magic,
780 Self::ImageOptionalHeader64(hdr64) => hdr64.magic,
781 }
782 }
783
784 pub fn major_linker_version(&self) -> u8 {
786 match self {
787 Self::ImageOptionalHeader32(hdr32) => hdr32.major_linker_version,
788 Self::ImageOptionalHeader64(hdr64) => hdr64.major_linker_version,
789 }
790 }
791
792 pub fn minor_linker_version(&self) -> u8 {
794 match self {
795 Self::ImageOptionalHeader32(hdr32) => hdr32.minor_linker_version,
796 Self::ImageOptionalHeader64(hdr64) => hdr64.minor_linker_version,
797 }
798 }
799
800 pub fn size_of_code(&self) -> u32 {
802 match self {
803 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_code,
804 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_code,
805 }
806 }
807
808 pub fn size_of_initialized_data(&self) -> u32 {
810 match self {
811 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_initialized_data,
812 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_initialized_data,
813 }
814 }
815
816 pub fn size_of_uninitialized_data(&self) -> u32 {
818 match self {
819 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_uninitialized_data,
820 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_uninitialized_data,
821 }
822 }
823
824 pub fn address_of_entry_point(&self) -> u32 {
828 match self {
829 Self::ImageOptionalHeader32(hdr32) => hdr32.address_of_entry_point,
830 Self::ImageOptionalHeader64(hdr64) => hdr64.address_of_entry_point,
831 }
832 }
833
834 pub fn base_of_code(&self) -> u32 {
836 match self {
837 Self::ImageOptionalHeader32(hdr32) => hdr32.base_of_code,
838 Self::ImageOptionalHeader64(hdr64) => hdr64.base_of_code,
839 }
840 }
841
842 pub fn base_of_data(&self) -> Option<u32> {
844 match self {
845 Self::ImageOptionalHeader32(hdr32) => Some(hdr32.base_of_data),
846 Self::ImageOptionalHeader64(_) => None,
847 }
848 }
849
850 pub fn image_base(&self) -> u64 {
854 match self {
855 Self::ImageOptionalHeader32(hdr32) => hdr32.image_base.into(),
856 Self::ImageOptionalHeader64(hdr64) => hdr64.image_base,
857 }
858 }
859
860 pub fn section_alignment(&self) -> u32 {
864 match self {
865 Self::ImageOptionalHeader32(hdr32) => hdr32.section_alignment,
866 Self::ImageOptionalHeader64(hdr64) => hdr64.section_alignment,
867 }
868 }
869
870 pub fn file_alignment(&self) -> u32 {
872 match self {
873 Self::ImageOptionalHeader32(hdr32) => hdr32.file_alignment,
874 Self::ImageOptionalHeader64(hdr64) => hdr64.file_alignment,
875 }
876 }
877
878 pub fn major_operating_system_version(&self) -> u16 {
880 match self {
881 Self::ImageOptionalHeader32(hdr32) => hdr32.major_operating_system_version,
882 Self::ImageOptionalHeader64(hdr64) => hdr64.major_operating_system_version,
883 }
884 }
885
886 pub fn minor_operating_system_version(&self) -> u16 {
888 match self {
889 Self::ImageOptionalHeader32(hdr32) => hdr32.minor_operating_system_version,
890 Self::ImageOptionalHeader64(hdr64) => hdr64.minor_operating_system_version,
891 }
892 }
893
894 pub fn major_image_version(&self) -> u16 {
896 match self {
897 Self::ImageOptionalHeader32(hdr32) => hdr32.major_image_version,
898 Self::ImageOptionalHeader64(hdr64) => hdr64.major_image_version,
899 }
900 }
901
902 pub fn minor_image_version(&self) -> u16 {
904 match self {
905 Self::ImageOptionalHeader32(hdr32) => hdr32.minor_image_version,
906 Self::ImageOptionalHeader64(hdr64) => hdr64.minor_image_version,
907 }
908 }
909
910 pub fn major_subsystem_version(&self) -> u16 {
912 match self {
913 Self::ImageOptionalHeader32(hdr32) => hdr32.major_subsystem_version,
914 Self::ImageOptionalHeader64(hdr64) => hdr64.major_subsystem_version,
915 }
916 }
917
918 pub fn minor_subsystem_version(&self) -> u16 {
920 match self {
921 Self::ImageOptionalHeader32(hdr32) => hdr32.minor_subsystem_version,
922 Self::ImageOptionalHeader64(hdr64) => hdr64.minor_subsystem_version,
923 }
924 }
925
926 pub fn win32_version_value(&self) -> u32 {
928 match self {
929 Self::ImageOptionalHeader32(hdr32) => hdr32.win32_version_value,
930 Self::ImageOptionalHeader64(hdr64) => hdr64.win32_version_value,
931 }
932 }
933
934 pub fn size_of_image(&self) -> u32 {
936 match self {
937 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_image,
938 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_image,
939 }
940 }
941
942 pub fn size_of_headers(&self) -> u32 {
944 match self {
945 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_headers,
946 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_headers,
947 }
948 }
949
950 pub fn check_sum(&self) -> u32 {
952 match self {
953 Self::ImageOptionalHeader32(hdr32) => hdr32.check_sum,
954 Self::ImageOptionalHeader64(hdr64) => hdr64.check_sum,
955 }
956 }
957
958 pub fn subsystem(&self) -> u16 {
960 match self {
961 Self::ImageOptionalHeader32(hdr32) => hdr32.subsystem,
962 Self::ImageOptionalHeader64(hdr64) => hdr64.subsystem,
963 }
964 }
965
966 pub fn dll_characteristics(&self) -> u16 {
968 match self {
969 Self::ImageOptionalHeader32(hdr32) => hdr32.dll_characteristics,
970 Self::ImageOptionalHeader64(hdr64) => hdr64.dll_characteristics,
971 }
972 }
973
974 pub fn size_of_stack_reserve(&self) -> u64 {
976 match self {
977 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_stack_reserve.into(),
978 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_stack_reserve,
979 }
980 }
981
982 pub fn size_of_stack_commit(&self) -> u64 {
984 match self {
985 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_stack_commit.into(),
986 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_stack_commit,
987 }
988 }
989
990 pub fn size_of_heap_reserve(&self) -> u64 {
992 match self {
993 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_heap_reserve.into(),
994 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_heap_reserve,
995 }
996 }
997
998 pub fn size_of_heap_commit(&self) -> u64 {
1000 match self {
1001 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_heap_commit.into(),
1002 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_heap_commit,
1003 }
1004 }
1005
1006 pub fn loader_flags(&self) -> u32 {
1008 match self {
1009 Self::ImageOptionalHeader32(hdr32) => hdr32.loader_flags,
1010 Self::ImageOptionalHeader64(hdr64) => hdr64.loader_flags,
1011 }
1012 }
1013
1014 pub fn number_of_rva_and_sizes(&self) -> u32 {
1016 match self {
1017 Self::ImageOptionalHeader32(hdr32) => hdr32.number_of_rva_and_sizes,
1018 Self::ImageOptionalHeader64(hdr64) => hdr64.number_of_rva_and_sizes,
1019 }
1020 }
1021
1022 pub fn size(&self) -> usize {
1024 match self {
1025 Self::ImageOptionalHeader32(_) => size_of::<ImageOptionalHeader32>(),
1026 Self::ImageOptionalHeader64(_) => size_of::<ImageOptionalHeader64>(),
1027 }
1028 }
1029}
1030
1031impl_struct! {
1032 #[derive(Debug, Clone, Copy)]
1038 #[from(::object::pe::ImageSectionHeader)]
1039 pub struct ImageSectionHeader {
1040 pub name: [u8; IMAGE_SIZEOF_SHORT_NAME],
1042
1043 pub virtual_size: u32,
1045
1046 pub virtual_address: u32,
1048
1049 pub size_of_raw_data: u32,
1051
1052 pub pointer_to_raw_data: u32,
1054
1055 pub pointer_to_relocations: u32,
1057
1058 pub pointer_to_linenumbers: u32,
1060
1061 pub number_of_relocations: u16,
1063
1064 pub number_of_linenumbers: u16,
1066
1067 pub characteristics: u32,
1069 }
1070}
1071
1072impl ImageSectionHeader {
1080 pub fn pe_file_range(&self) -> (u32, u32) {
1085 let offset = self.pointer_to_raw_data;
1088 let size = std::cmp::min(self.virtual_size, self.size_of_raw_data);
1089 (offset, size)
1090 }
1091
1092 pub fn pe_file_range_at(&self, va: u32) -> Option<(u32, u32)> {
1097 let section_va = self.virtual_address;
1098 let offset = va.checked_sub(section_va)?;
1099 let (section_offset, section_size) = self.pe_file_range();
1100
1101 if offset < section_size {
1103 Some((section_offset.checked_add(offset)?, section_size - offset))
1104 }
1105 else {
1106 None
1107 }
1108 }
1109
1110 pub fn pe_data<'data>(&self, data: &'data [u8]) -> Option<&'data [u8]> {
1114 let (offset, size) = self.pe_file_range();
1115 data.read_bytes_at(offset.into(), size.into()).ok()
1116 }
1117
1118 pub fn pe_data_at<'data>(&self, data: &'data [u8], va: u32) -> Option<&'data [u8]> {
1125 let (offset, size) = self.pe_file_range_at(va)?;
1126 data.read_bytes_at(offset.into(), size.into()).ok()
1127 }
1128}
1129
1130impl_struct! {
1131 #[derive(Debug, Clone, Copy)]
1140 #[from(::object::pe::ImageDataDirectory)]
1141 pub struct ImageDataDirectory {
1142 pub virtual_address: u32,
1144
1145 pub size: u32,
1147 }
1148}
1149
1150impl_struct! {
1151 #[derive(Debug, Clone, Copy)]
1157 #[from(::object::pe::ImageDebugDirectory)]
1158 pub struct ImageDebugDirectory {
1159 pub characteristics: u32,
1161
1162 pub time_date_stamp: u32,
1164
1165 pub major_version: u16,
1167
1168 pub minor_version: u16,
1170
1171 pub typ: u32,
1173
1174 pub size_of_data: u32,
1176
1177 pub address_of_raw_data: u32,
1179
1180 pub pointer_to_raw_data: u32,
1182 }
1183}
1184
1185impl_struct! {
1186 #[derive(Debug, Clone, Copy)]
1194 #[from(::object::pe::ImageRuntimeFunctionEntry)]
1195 pub struct ImageRuntimeFunctionEntry {
1196 pub begin_address: u32,
1198
1199 pub end_address: u32,
1201
1202 pub unwind_info_address_or_data: u32,
1204 }
1205}