Line data Source code
1 : //! PE Data Directory module
2 :
3 : use std::marker::PhantomData;
4 :
5 : use crate::common::into_optional;
6 : use crate::common::FromFFI;
7 : use crate::declare_iterator;
8 : use crate::pe::Section;
9 : use lief_ffi as ffi;
10 :
11 : pub struct DataDirectory<'a> {
12 : ptr: cxx::UniquePtr<ffi::PE_DataDirectory>,
13 : _owner: PhantomData<&'a ffi::PE_Binary>,
14 : }
15 :
16 : #[allow(non_camel_case_types)]
17 2500 : #[derive(Debug, Copy, Clone)]
18 : pub enum Type {
19 : EXPORT_TABLE,
20 : IMPORT_TABLE,
21 : RESOURCE_TABLE,
22 : EXCEPTION_TABLE,
23 : CERTIFICATE_TABLE,
24 : BASE_RELOCATION_TABLE,
25 : DEBUG_DIR,
26 : ARCHITECTURE,
27 : GLOBAL_PTR,
28 : TLS_TABLE,
29 : LOAD_CONFIG_TABLE,
30 : BOUND_IMPORT,
31 : IAT,
32 : DELAY_IMPORT_DESCRIPTOR,
33 : CLR_RUNTIME_HEADER,
34 : RESERVED,
35 : UNKNOWN(u32),
36 : }
37 :
38 :
39 : /// Data directory's types
40 : impl From<u32> for Type {
41 2500 : fn from(value: u32) -> Self {
42 2500 : match value {
43 80 : 0x00000000 => Type::EXPORT_TABLE,
44 690 : 0x00000001 => Type::IMPORT_TABLE,
45 80 : 0x00000002 => Type::RESOURCE_TABLE,
46 80 : 0x00000003 => Type::EXCEPTION_TABLE,
47 80 : 0x00000004 => Type::CERTIFICATE_TABLE,
48 80 : 0x00000005 => Type::BASE_RELOCATION_TABLE,
49 80 : 0x00000006 => Type::DEBUG_DIR,
50 80 : 0x00000007 => Type::ARCHITECTURE,
51 80 : 0x00000008 => Type::GLOBAL_PTR,
52 80 : 0x00000009 => Type::TLS_TABLE,
53 80 : 0x0000000a => Type::LOAD_CONFIG_TABLE,
54 80 : 0x0000000b => Type::BOUND_IMPORT,
55 690 : 0x0000000c => Type::IAT,
56 80 : 0x0000000d => Type::DELAY_IMPORT_DESCRIPTOR,
57 80 : 0x0000000e => Type::CLR_RUNTIME_HEADER,
58 80 : 0x0000000f => Type::RESERVED,
59 0 : _ => Type::UNKNOWN(value),
60 :
61 : }
62 2500 : }
63 : }
64 : impl Into<u32> for Type {
65 10 : fn into(self) -> u32 {
66 10 : match self {
67 0 : Type::EXPORT_TABLE => 0x00000000,
68 10 : Type::IMPORT_TABLE => 0x00000001,
69 0 : Type::RESOURCE_TABLE => 0x00000002,
70 0 : Type::EXCEPTION_TABLE => 0x00000003,
71 0 : Type::CERTIFICATE_TABLE => 0x00000004,
72 0 : Type::BASE_RELOCATION_TABLE => 0x00000005,
73 0 : Type::DEBUG_DIR => 0x00000006,
74 0 : Type::ARCHITECTURE => 0x00000007,
75 0 : Type::GLOBAL_PTR => 0x00000008,
76 0 : Type::TLS_TABLE => 0x00000009,
77 0 : Type::LOAD_CONFIG_TABLE => 0x0000000a,
78 0 : Type::BOUND_IMPORT => 0x0000000b,
79 0 : Type::IAT => 0x0000000c,
80 0 : Type::DELAY_IMPORT_DESCRIPTOR => 0x0000000d,
81 0 : Type::CLR_RUNTIME_HEADER => 0x0000000e,
82 0 : Type::RESERVED => 0x0000000f,
83 0 : Type::UNKNOWN(_) => 0x0000000f, // RESERVED
84 :
85 : }
86 10 : }
87 : }
88 :
89 : impl std::fmt::Debug for DataDirectory<'_> {
90 2500 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91 2500 : f.debug_struct("DataDirectory")
92 2500 : .field("type", &self.get_type())
93 2500 : .field("rva", &self.rva())
94 2500 : .field("size", &self.size())
95 2500 : .field("section", &self.section())
96 2500 : .finish()
97 2500 : }
98 : }
99 :
100 : impl<'a> FromFFI<ffi::PE_DataDirectory> for DataDirectory<'a> {
101 2510 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DataDirectory>) -> Self {
102 2510 : DataDirectory {
103 2510 : ptr,
104 2510 : _owner: PhantomData,
105 2510 : }
106 2510 : }
107 : }
108 :
109 : impl DataDirectory<'_> {
110 : /// The **relative** virtual address where the data referenced by this data directory are
111 : /// located.
112 2500 : pub fn rva(&self) -> u32 {
113 2500 : self.ptr.RVA()
114 2500 : }
115 : /// The size of the data referenced by this data directory
116 2500 : pub fn size(&self) -> u32 {
117 2500 : self.ptr.size()
118 2500 : }
119 : /// The type of the data directory which is defined by its index.
120 2500 : pub fn get_type(&self) -> Type {
121 2500 : Type::from(self.ptr.get_type())
122 2500 : }
123 : /// The (optional) section in which the data associated with the data directory
124 : /// are located.
125 2500 : pub fn section(&self) -> Option<Section> {
126 2500 : into_optional(self.ptr.section())
127 2500 : }
128 : }
129 :
130 1280 : declare_iterator!(
131 1280 : DataDirectories,
132 1280 : DataDirectory<'a>,
133 1280 : ffi::PE_DataDirectory,
134 1280 : ffi::PE_Binary,
135 1280 : ffi::PE_Binary_it_data_directories
136 1280 : );
|