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