1use object::ReadRef as _;
9pub use object::{
10 pe::{
11 IMAGE_DEBUG_TYPE_CODEVIEW, IMAGE_DIRECTORY_ENTRY_ARCHITECTURE,
12 IMAGE_DIRECTORY_ENTRY_BASERELOC, IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
13 IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR, IMAGE_DIRECTORY_ENTRY_DEBUG,
14 IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT, IMAGE_DIRECTORY_ENTRY_EXCEPTION,
15 IMAGE_DIRECTORY_ENTRY_EXPORT, IMAGE_DIRECTORY_ENTRY_GLOBALPTR, IMAGE_DIRECTORY_ENTRY_IAT,
16 IMAGE_DIRECTORY_ENTRY_IMPORT, IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
17 IMAGE_DIRECTORY_ENTRY_RESOURCE, IMAGE_DIRECTORY_ENTRY_SECURITY, IMAGE_DIRECTORY_ENTRY_TLS,
18 IMAGE_DOS_SIGNATURE, IMAGE_NT_OPTIONAL_HDR32_MAGIC, IMAGE_NT_OPTIONAL_HDR64_MAGIC,
19 IMAGE_NT_SIGNATURE, IMAGE_NUMBEROF_DIRECTORY_ENTRIES, IMAGE_SIZEOF_SHORT_NAME,
20 },
21 read::pe::{Export, ExportTable, ExportTarget},
23};
24
25use super::error::PeError;
26
27trait ToEndian<E: ::object::Endian> {
34 type Output;
36
37 fn to_endian(&self, endian: E) -> Self::Output;
39}
40
41impl<E: ::object::Endian> ToEndian<E> for ::object::U16<E> {
42 type Output = u16;
43
44 fn to_endian(&self, endian: E) -> Self::Output {
45 self.get(endian)
46 }
47}
48
49impl<E: ::object::Endian> ToEndian<E> for ::object::U32<E> {
50 type Output = u32;
51
52 fn to_endian(&self, endian: E) -> Self::Output {
53 self.get(endian)
54 }
55}
56
57impl<E: ::object::Endian> ToEndian<E> for ::object::U64<E> {
58 type Output = u64;
59
60 fn to_endian(&self, endian: E) -> Self::Output {
61 self.get(endian)
62 }
63}
64
65impl<E: ::object::Endian> ToEndian<E> for u8 {
66 type Output = u8;
67
68 fn to_endian(&self, _endian: E) -> Self::Output {
69 *self
70 }
71}
72
73impl<E: ::object::Endian, const N: usize> ToEndian<E> for [u8; N] {
74 type Output = [u8; N];
75
76 fn to_endian(&self, _endian: E) -> Self::Output {
77 *self
78 }
79}
80
81impl<E: ::object::Endian, const N: usize> ToEndian<E> for [::object::U16<E>; N] {
82 type Output = [u16; N];
83
84 fn to_endian(&self, endian: E) -> Self::Output {
85 std::array::from_fn(|i| self[i].get(endian))
86 }
87}
88
89macro_rules! impl_struct {
119 (@parse
130 from = []
131 doc = [$($doc:tt)*]
132 derive = [$($derive:tt)*]
133 attrs = [$($attrs:tt)*]
134 rest = [#[from($from:ty)] $($rest:tt)*]
135 ) => {
136 impl_struct!(@parse
137 from = [$from]
138 doc = [$($doc)*]
139 derive = [$($derive)*]
140 attrs = [$($attrs)*]
141 rest = [$($rest)*]
142 );
143 };
144
145 (@parse
147 from = [$_first:ty]
148 doc = [$($doc:tt)*]
149 derive = [$($derive:tt)*]
150 attrs = [$($attrs:tt)*]
151 rest = [#[from($_dup:ty)] $($rest:tt)*]
152 ) => {
153 compile_error!("impl_struct!: duplicate `#[from(...)]` attribute");
154 };
155
156 (@parse
158 from = [$($from:tt)*]
159 doc = [$($doc:tt)*]
160 derive = [$($derive:tt)*]
161 attrs = [$($attrs:tt)*]
162 rest = [#[doc = $d:literal] $($rest:tt)*]
163 ) => {
164 impl_struct!(@parse
165 from = [$($from)*]
166 doc = [$($doc)* #[doc = $d]]
167 derive = [$($derive)*]
168 attrs = [$($attrs)*]
169 rest = [$($rest)*]
170 );
171 };
172
173 (@parse
175 from = [$($from:tt)*]
176 doc = [$($doc:tt)*]
177 derive = [$($derive:tt)*]
178 attrs = [$($attrs:tt)*]
179 rest = [#[derive($($d:path),* $(,)?)] $($rest:tt)*]
180 ) => {
181 impl_struct!(@parse
182 from = [$($from)*]
183 doc = [$($doc)*]
184 derive = [$($derive)* $($d,)*]
185 attrs = [$($attrs)*]
186 rest = [$($rest)*]
187 );
188 };
189
190 (@parse
192 from = [$($from:tt)*]
193 doc = [$($doc:tt)*]
194 derive = [$($derive:tt)*]
195 attrs = [$($attrs:tt)*]
196 rest = [#[$attr:meta] $($rest:tt)*]
197 ) => {
198 impl_struct!(@parse
199 from = [$($from)*]
200 doc = [$($doc)*]
201 derive = [$($derive)*]
202 attrs = [$($attrs)* #[$attr]]
203 rest = [$($rest)*]
204 );
205 };
206
207 (@parse
216 from = [$from_ty:ty]
217 doc = [$($doc:tt)*]
218 derive = [$($derive:tt)*]
219 attrs = [$($attrs:tt)*]
220 rest = [
221 $vis:vis struct $name:ident {
222 $(
223 $(#[$field_attr:meta])*
224 $field_vis:vis $field:ident : $field_ty:ty
225 ),* $(,)?
226 }
227 ]
228 ) => {
229 $($doc)*
230 #[derive(
231 $($derive)*
232 ::zerocopy::FromBytes,
233 ::zerocopy::IntoBytes,
234 ::zerocopy::Immutable,
235 ::zerocopy::KnownLayout,
236 )]
237 #[repr(C, packed)]
238 $($attrs)*
239 $vis struct $name {
240 $(
241 $(#[$field_attr])*
242 $field_vis $field: $field_ty,
243 )*
244 }
245
246 impl ::core::convert::From<$from_ty> for $name {
247 fn from(value: $from_ty) -> Self {
248 Self {
249 $(
250 $field: value.$field.to_endian(::object::LittleEndian),
251 )*
252 }
253 }
254 }
255
256 const _: () = {
257 use ::core::mem::{align_of, size_of};
258
259 assert!(
260 size_of::<$name>() == size_of::<$from_ty>(),
261 concat!(stringify!($name), " size mismatch"),
262 );
263
264 assert!(
265 align_of::<$name>() == align_of::<$from_ty>(),
266 concat!(stringify!($name), " alignment mismatch"),
267 );
268 };
269
270 $(
271 const _: () = {
272 use ::core::mem::offset_of;
273
274 assert!(
275 offset_of!($name, $field) == offset_of!($from_ty, $field),
276 concat!(stringify!($name), " field offset mismatch: ", stringify!($field)),
277 );
278 };
279 )*
280 };
281
282 (@parse
283 from = []
284 doc = [$($doc:tt)*]
285 derive = [$($derive:tt)*]
286 attrs = [$($attrs:tt)*]
287 rest = [$vis:vis struct $name:ident { $($body:tt)* }]
288 ) => {
289 compile_error!(concat!(
290 "impl_struct!: missing `#[from(SourceType)]` attribute on `",
291 stringify!($name),
292 "`",
293 ));
294 };
295
296 ($($input:tt)*) => {
306 impl_struct!(@parse
307 from = []
308 doc = []
309 derive = []
310 attrs = []
311 rest = [$($input)*]
312 );
313 };
314}
315
316impl_struct! {
317 #[derive(Debug, Clone, Copy)]
327 #[from(::object::pe::ImageDosHeader)]
328 pub struct ImageDosHeader {
329 pub e_magic: u16,
331
332 pub e_cblp: u16,
334
335 pub e_cp: u16,
337
338 pub e_crlc: u16,
340
341 pub e_cparhdr: u16,
343
344 pub e_minalloc: u16,
346
347 pub e_maxalloc: u16,
349
350 pub e_ss: u16,
352
353 pub e_sp: u16,
355
356 pub e_csum: u16,
358
359 pub e_ip: u16,
361
362 pub e_cs: u16,
364
365 pub e_lfarlc: u16,
367
368 pub e_ovno: u16,
370
371 pub e_res: [u16; 4],
373
374 pub e_oemid: u16,
376
377 pub e_oeminfo: u16,
379
380 pub e_res2: [u16; 10],
382
383 pub e_lfanew: u32,
385 }
386}
387
388impl ImageDosHeader {
389 pub fn parse(data: &[u8], offset: &mut u64) -> Result<Self, PeError> {
391 let dos_header = data
392 .read_at::<::object::pe::ImageDosHeader>(0)
393 .copied()
394 .map_err(|_| PeError::InvalidDosHeader)?;
395
396 if dos_header.e_magic.get(::object::LittleEndian) != IMAGE_DOS_SIGNATURE {
397 return Err(PeError::InvalidDosMagic);
398 }
399
400 *offset = dos_header.nt_headers_offset() as u64;
401
402 Ok(dos_header.into())
403 }
404
405 pub fn nt_headers_offset(&self) -> u32 {
407 self.e_lfanew
408 }
409}
410
411#[derive(Debug, Clone, Copy)]
420pub struct ImageNtHeaders {
421 pub signature: u32,
423
424 pub file_header: ImageFileHeader,
426
427 pub optional_header: ImageOptionalHeader,
429}
430
431impl ImageNtHeaders {
432 pub fn parse(data: &[u8], offset: &mut u64) -> Result<Self, PeError> {
434 let magic =
435 ::object::read::pe::optional_header_magic(data).map_err(|_| PeError::InvalidPeMagic)?;
436
437 match magic {
438 IMAGE_NT_OPTIONAL_HDR32_MAGIC => {
439 Self::parse_inner::<::object::pe::ImageNtHeaders32>(data, offset)
440 }
441 IMAGE_NT_OPTIONAL_HDR64_MAGIC => {
442 Self::parse_inner::<::object::pe::ImageNtHeaders64>(data, offset)
443 }
444 _ => Err(PeError::InvalidPeMagic),
445 }
446 }
447
448 fn parse_inner<Pe>(data: &[u8], offset: &mut u64) -> Result<Self, PeError>
449 where
450 Self: From<Pe>,
451 Pe: ::object::read::pe::ImageNtHeaders,
452 {
453 let nt_headers = data
454 .read::<Pe>(offset)
455 .copied()
456 .map_err(|_| PeError::InvalidNtHeaders)?;
457
458 if nt_headers.signature() != IMAGE_NT_SIGNATURE {
459 return Err(PeError::InvalidPeMagic);
460 }
461
462 if !nt_headers.is_valid_optional_magic() {
463 return Err(PeError::InvalidOptionalHeaderMagic);
464 }
465
466 Ok(nt_headers.into())
467 }
468}
469
470impl From<::object::pe::ImageNtHeaders32> for ImageNtHeaders {
471 fn from(value: ::object::pe::ImageNtHeaders32) -> Self {
472 Self {
473 signature: value.signature.get(::object::LittleEndian),
474 file_header: value.file_header.into(),
475 optional_header: value.optional_header.into(),
476 }
477 }
478}
479
480impl From<::object::pe::ImageNtHeaders64> for ImageNtHeaders {
481 fn from(value: ::object::pe::ImageNtHeaders64) -> Self {
482 Self {
483 signature: value.signature.get(::object::LittleEndian),
484 file_header: value.file_header.into(),
485 optional_header: value.optional_header.into(),
486 }
487 }
488}
489
490impl_struct! {
491 #[derive(Debug, Clone, Copy)]
497 #[from(::object::pe::ImageFileHeader)]
498 pub struct ImageFileHeader {
499 pub machine: u16,
501
502 pub number_of_sections: u16,
504
505 pub time_date_stamp: u32,
507
508 pub pointer_to_symbol_table: u32,
510
511 pub number_of_symbols: u32,
513
514 pub size_of_optional_header: u16,
516
517 pub characteristics: u16,
519 }
520}
521
522impl_struct! {
523 #[derive(Debug, Clone, Copy)]
533 #[from(::object::pe::ImageOptionalHeader32)]
534 pub struct ImageOptionalHeader32 {
535 pub magic: u16,
537
538 pub major_linker_version: u8,
540
541 pub minor_linker_version: u8,
543
544 pub size_of_code: u32,
546
547 pub size_of_initialized_data: u32,
549
550 pub size_of_uninitialized_data: u32,
552
553 pub address_of_entry_point: u32,
555
556 pub base_of_code: u32,
558
559 pub base_of_data: u32,
561
562 pub image_base: u32,
564
565 pub section_alignment: u32,
567
568 pub file_alignment: u32,
570
571 pub major_operating_system_version: u16,
573
574 pub minor_operating_system_version: u16,
576
577 pub major_image_version: u16,
579
580 pub minor_image_version: u16,
582
583 pub major_subsystem_version: u16,
585
586 pub minor_subsystem_version: u16,
588
589 pub win32_version_value: u32,
591
592 pub size_of_image: u32,
594
595 pub size_of_headers: u32,
597
598 pub check_sum: u32,
600
601 pub subsystem: u16,
603
604 pub dll_characteristics: u16,
606
607 pub size_of_stack_reserve: u32,
609
610 pub size_of_stack_commit: u32,
612
613 pub size_of_heap_reserve: u32,
615
616 pub size_of_heap_commit: u32,
618
619 pub loader_flags: u32,
621
622 pub number_of_rva_and_sizes: u32,
624 }
625}
626
627impl_struct! {
628 #[derive(Debug, Clone, Copy)]
638 #[from(::object::pe::ImageOptionalHeader64)]
639 pub struct ImageOptionalHeader64 {
640 pub magic: u16,
642
643 pub major_linker_version: u8,
645
646 pub minor_linker_version: u8,
648
649 pub size_of_code: u32,
651
652 pub size_of_initialized_data: u32,
654
655 pub size_of_uninitialized_data: u32,
657
658 pub address_of_entry_point: u32,
660
661 pub base_of_code: u32,
663
664 pub image_base: u64,
666
667 pub section_alignment: u32,
669
670 pub file_alignment: u32,
672
673 pub major_operating_system_version: u16,
675
676 pub minor_operating_system_version: u16,
678
679 pub major_image_version: u16,
681
682 pub minor_image_version: u16,
684
685 pub major_subsystem_version: u16,
687
688 pub minor_subsystem_version: u16,
690
691 pub win32_version_value: u32,
693
694 pub size_of_image: u32,
696
697 pub size_of_headers: u32,
699
700 pub check_sum: u32,
702
703 pub subsystem: u16,
705
706 pub dll_characteristics: u16,
708
709 pub size_of_stack_reserve: u64,
711
712 pub size_of_stack_commit: u64,
714
715 pub size_of_heap_reserve: u64,
717
718 pub size_of_heap_commit: u64,
720
721 pub loader_flags: u32,
723
724 pub number_of_rva_and_sizes: u32,
726 }
727}
728
729#[derive(Debug, Clone, Copy)]
737pub enum ImageOptionalHeader {
738 ImageOptionalHeader32(ImageOptionalHeader32),
740
741 ImageOptionalHeader64(ImageOptionalHeader64),
743}
744
745impl From<::object::pe::ImageOptionalHeader32> for ImageOptionalHeader {
746 fn from(value: ::object::pe::ImageOptionalHeader32) -> Self {
747 Self::ImageOptionalHeader32(value.into())
748 }
749}
750
751impl From<::object::pe::ImageOptionalHeader64> for ImageOptionalHeader {
752 fn from(value: ::object::pe::ImageOptionalHeader64) -> Self {
753 Self::ImageOptionalHeader64(value.into())
754 }
755}
756
757impl ImageOptionalHeader {
758 pub fn magic(&self) -> u16 {
760 match self {
761 Self::ImageOptionalHeader32(hdr32) => hdr32.magic,
762 Self::ImageOptionalHeader64(hdr64) => hdr64.magic,
763 }
764 }
765
766 pub fn major_linker_version(&self) -> u8 {
768 match self {
769 Self::ImageOptionalHeader32(hdr32) => hdr32.major_linker_version,
770 Self::ImageOptionalHeader64(hdr64) => hdr64.major_linker_version,
771 }
772 }
773
774 pub fn minor_linker_version(&self) -> u8 {
776 match self {
777 Self::ImageOptionalHeader32(hdr32) => hdr32.minor_linker_version,
778 Self::ImageOptionalHeader64(hdr64) => hdr64.minor_linker_version,
779 }
780 }
781
782 pub fn size_of_code(&self) -> u32 {
784 match self {
785 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_code,
786 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_code,
787 }
788 }
789
790 pub fn size_of_initialized_data(&self) -> u32 {
792 match self {
793 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_initialized_data,
794 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_initialized_data,
795 }
796 }
797
798 pub fn size_of_uninitialized_data(&self) -> u32 {
800 match self {
801 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_uninitialized_data,
802 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_uninitialized_data,
803 }
804 }
805
806 pub fn address_of_entry_point(&self) -> u32 {
810 match self {
811 Self::ImageOptionalHeader32(hdr32) => hdr32.address_of_entry_point,
812 Self::ImageOptionalHeader64(hdr64) => hdr64.address_of_entry_point,
813 }
814 }
815
816 pub fn base_of_code(&self) -> u32 {
818 match self {
819 Self::ImageOptionalHeader32(hdr32) => hdr32.base_of_code,
820 Self::ImageOptionalHeader64(hdr64) => hdr64.base_of_code,
821 }
822 }
823
824 pub fn base_of_data(&self) -> Option<u32> {
826 match self {
827 Self::ImageOptionalHeader32(hdr32) => Some(hdr32.base_of_data),
828 Self::ImageOptionalHeader64(_) => None,
829 }
830 }
831
832 pub fn image_base(&self) -> u64 {
836 match self {
837 Self::ImageOptionalHeader32(hdr32) => hdr32.image_base.into(),
838 Self::ImageOptionalHeader64(hdr64) => hdr64.image_base,
839 }
840 }
841
842 pub fn section_alignment(&self) -> u32 {
846 match self {
847 Self::ImageOptionalHeader32(hdr32) => hdr32.section_alignment,
848 Self::ImageOptionalHeader64(hdr64) => hdr64.section_alignment,
849 }
850 }
851
852 pub fn file_alignment(&self) -> u32 {
854 match self {
855 Self::ImageOptionalHeader32(hdr32) => hdr32.file_alignment,
856 Self::ImageOptionalHeader64(hdr64) => hdr64.file_alignment,
857 }
858 }
859
860 pub fn major_operating_system_version(&self) -> u16 {
862 match self {
863 Self::ImageOptionalHeader32(hdr32) => hdr32.major_operating_system_version,
864 Self::ImageOptionalHeader64(hdr64) => hdr64.major_operating_system_version,
865 }
866 }
867
868 pub fn minor_operating_system_version(&self) -> u16 {
870 match self {
871 Self::ImageOptionalHeader32(hdr32) => hdr32.minor_operating_system_version,
872 Self::ImageOptionalHeader64(hdr64) => hdr64.minor_operating_system_version,
873 }
874 }
875
876 pub fn major_image_version(&self) -> u16 {
878 match self {
879 Self::ImageOptionalHeader32(hdr32) => hdr32.major_image_version,
880 Self::ImageOptionalHeader64(hdr64) => hdr64.major_image_version,
881 }
882 }
883
884 pub fn minor_image_version(&self) -> u16 {
886 match self {
887 Self::ImageOptionalHeader32(hdr32) => hdr32.minor_image_version,
888 Self::ImageOptionalHeader64(hdr64) => hdr64.minor_image_version,
889 }
890 }
891
892 pub fn major_subsystem_version(&self) -> u16 {
894 match self {
895 Self::ImageOptionalHeader32(hdr32) => hdr32.major_subsystem_version,
896 Self::ImageOptionalHeader64(hdr64) => hdr64.major_subsystem_version,
897 }
898 }
899
900 pub fn minor_subsystem_version(&self) -> u16 {
902 match self {
903 Self::ImageOptionalHeader32(hdr32) => hdr32.minor_subsystem_version,
904 Self::ImageOptionalHeader64(hdr64) => hdr64.minor_subsystem_version,
905 }
906 }
907
908 pub fn win32_version_value(&self) -> u32 {
910 match self {
911 Self::ImageOptionalHeader32(hdr32) => hdr32.win32_version_value,
912 Self::ImageOptionalHeader64(hdr64) => hdr64.win32_version_value,
913 }
914 }
915
916 pub fn size_of_image(&self) -> u32 {
918 match self {
919 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_image,
920 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_image,
921 }
922 }
923
924 pub fn size_of_headers(&self) -> u32 {
926 match self {
927 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_headers,
928 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_headers,
929 }
930 }
931
932 pub fn check_sum(&self) -> u32 {
934 match self {
935 Self::ImageOptionalHeader32(hdr32) => hdr32.check_sum,
936 Self::ImageOptionalHeader64(hdr64) => hdr64.check_sum,
937 }
938 }
939
940 pub fn subsystem(&self) -> u16 {
942 match self {
943 Self::ImageOptionalHeader32(hdr32) => hdr32.subsystem,
944 Self::ImageOptionalHeader64(hdr64) => hdr64.subsystem,
945 }
946 }
947
948 pub fn dll_characteristics(&self) -> u16 {
950 match self {
951 Self::ImageOptionalHeader32(hdr32) => hdr32.dll_characteristics,
952 Self::ImageOptionalHeader64(hdr64) => hdr64.dll_characteristics,
953 }
954 }
955
956 pub fn size_of_stack_reserve(&self) -> u64 {
958 match self {
959 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_stack_reserve.into(),
960 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_stack_reserve,
961 }
962 }
963
964 pub fn size_of_stack_commit(&self) -> u64 {
966 match self {
967 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_stack_commit.into(),
968 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_stack_commit,
969 }
970 }
971
972 pub fn size_of_heap_reserve(&self) -> u64 {
974 match self {
975 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_heap_reserve.into(),
976 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_heap_reserve,
977 }
978 }
979
980 pub fn size_of_heap_commit(&self) -> u64 {
982 match self {
983 Self::ImageOptionalHeader32(hdr32) => hdr32.size_of_heap_commit.into(),
984 Self::ImageOptionalHeader64(hdr64) => hdr64.size_of_heap_commit,
985 }
986 }
987
988 pub fn loader_flags(&self) -> u32 {
990 match self {
991 Self::ImageOptionalHeader32(hdr32) => hdr32.loader_flags,
992 Self::ImageOptionalHeader64(hdr64) => hdr64.loader_flags,
993 }
994 }
995
996 pub fn number_of_rva_and_sizes(&self) -> u32 {
998 match self {
999 Self::ImageOptionalHeader32(hdr32) => hdr32.number_of_rva_and_sizes,
1000 Self::ImageOptionalHeader64(hdr64) => hdr64.number_of_rva_and_sizes,
1001 }
1002 }
1003
1004 pub fn size(&self) -> usize {
1006 match self {
1007 Self::ImageOptionalHeader32(_) => size_of::<ImageOptionalHeader32>(),
1008 Self::ImageOptionalHeader64(_) => size_of::<ImageOptionalHeader64>(),
1009 }
1010 }
1011}
1012
1013impl_struct! {
1014 #[derive(Debug, Clone, Copy)]
1020 #[from(::object::pe::ImageSectionHeader)]
1021 pub struct ImageSectionHeader {
1022 pub name: [u8; IMAGE_SIZEOF_SHORT_NAME],
1024
1025 pub virtual_size: u32,
1027
1028 pub virtual_address: u32,
1030
1031 pub size_of_raw_data: u32,
1033
1034 pub pointer_to_raw_data: u32,
1036
1037 pub pointer_to_relocations: u32,
1039
1040 pub pointer_to_linenumbers: u32,
1042
1043 pub number_of_relocations: u16,
1045
1046 pub number_of_linenumbers: u16,
1048
1049 pub characteristics: u32,
1051 }
1052}
1053
1054impl ImageSectionHeader {
1062 pub fn pe_file_range(&self) -> (u32, u32) {
1067 let offset = self.pointer_to_raw_data;
1070 let size = std::cmp::min(self.virtual_size, self.size_of_raw_data);
1071 (offset, size)
1072 }
1073
1074 pub fn pe_file_range_at(&self, va: u32) -> Option<(u32, u32)> {
1079 let section_va = self.virtual_address;
1080 let offset = va.checked_sub(section_va)?;
1081 let (section_offset, section_size) = self.pe_file_range();
1082
1083 if offset < section_size {
1085 Some((section_offset.checked_add(offset)?, section_size - offset))
1086 }
1087 else {
1088 None
1089 }
1090 }
1091
1092 pub fn pe_data<'data>(&self, data: &'data [u8]) -> Option<&'data [u8]> {
1096 let (offset, size) = self.pe_file_range();
1097 data.read_bytes_at(offset.into(), size.into()).ok()
1098 }
1099
1100 pub fn pe_data_at<'data>(&self, data: &'data [u8], va: u32) -> Option<&'data [u8]> {
1107 let (offset, size) = self.pe_file_range_at(va)?;
1108 data.read_bytes_at(offset.into(), size.into()).ok()
1109 }
1110}
1111
1112impl_struct! {
1113 #[derive(Debug, Clone, Copy)]
1122 #[from(::object::pe::ImageDataDirectory)]
1123 pub struct ImageDataDirectory {
1124 pub virtual_address: u32,
1126
1127 pub size: u32,
1129 }
1130}
1131
1132impl_struct! {
1133 #[derive(Debug, Clone, Copy)]
1139 #[from(::object::pe::ImageDebugDirectory)]
1140 pub struct ImageDebugDirectory {
1141 pub characteristics: u32,
1143
1144 pub time_date_stamp: u32,
1146
1147 pub major_version: u16,
1149
1150 pub minor_version: u16,
1152
1153 pub typ: u32,
1155
1156 pub size_of_data: u32,
1158
1159 pub address_of_raw_data: u32,
1161
1162 pub pointer_to_raw_data: u32,
1164 }
1165}
1166
1167impl_struct! {
1168 #[derive(Debug, Clone, Copy)]
1176 #[from(::object::pe::ImageRuntimeFunctionEntry)]
1177 pub struct ImageRuntimeFunctionEntry {
1178 pub begin_address: u32,
1180
1181 pub end_address: u32,
1183
1184 pub unwind_info_address_or_data: u32,
1186 }
1187}