1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
use std::{fmt, mem, ops, slice};
use crate::image::*;
use crate::Pod;
#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct SectionHeader(IMAGE_SECTION_HEADER);
impl SectionHeader {
#[inline]
pub fn name_bytes(&self) -> &[u8] {
crate::util::trimn(&self.0.Name)
}
pub fn name(&self) -> Result<&str, &[u8]> {
crate::util::parsen(&self.0.Name)
}
#[inline]
pub fn virtual_range(&self) -> std::ops::Range<u32> {
let start = self.0.VirtualAddress;
let end = u32::wrapping_add(self.0.VirtualAddress, self.0.VirtualSize);
start..end
}
#[inline]
pub fn file_range(&self) -> std::ops::Range<u32> {
let start = self.0.PointerToRawData;
let end = u32::wrapping_add(self.0.PointerToRawData, self.0.SizeOfRawData);
start..end
}
}
unsafe impl Pod for SectionHeader {}
impl ops::Deref for SectionHeader {
type Target = IMAGE_SECTION_HEADER;
#[inline]
fn deref(&self) -> &IMAGE_SECTION_HEADER {
&self.0
}
}
impl fmt::Debug for SectionHeader {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let name = self.name();
let name = match &name {
Ok(name) => name as &dyn fmt::Debug,
Err(name) => name as &dyn fmt::Debug,
};
f.debug_struct("SectionHeader")
.field("Name", name)
.field("VirtualAddress", &format_args!("{:#x}", self.0.VirtualAddress))
.field("VirtualSize", &format_args!("{:#x}", self.0.VirtualSize))
.field("PointerToRawData", &format_args!("{:#x}", self.0.PointerToRawData))
.field("SizeOfRawData", &format_args!("{:#x}", self.0.SizeOfRawData))
.field("Characteristics", &format_args!("{:#x}", self.0.Characteristics))
.finish()
}
}
#[repr(transparent)]
pub struct SectionHeaders([IMAGE_SECTION_HEADER]);
impl SectionHeaders {
pub(crate) fn new(image: &[IMAGE_SECTION_HEADER]) -> &SectionHeaders {
unsafe { mem::transmute(image) }
}
#[inline]
pub fn image(&self) -> &[IMAGE_SECTION_HEADER] {
&self.0
}
#[inline]
pub fn as_slice(&self) -> &[SectionHeader] {
unsafe { mem::transmute(self) }
}
#[inline]
pub fn iter(&self) -> slice::Iter<'_, SectionHeader> {
self.as_slice().iter()
}
#[inline]
pub fn by_name<S: ?Sized + AsRef<[u8]>>(&self, name: &S) -> Option<&SectionHeader> {
let name = name.as_ref();
if name.len() > IMAGE_SIZEOF_SHORT_NAME {
return None;
}
let mut name_buf = [0u8; IMAGE_SIZEOF_SHORT_NAME];
for i in 0..name.len() {
name_buf[i] = name[i];
}
for sect in self.iter() {
if sect.0.Name == name_buf {
return Some(sect);
}
}
None
}
#[inline]
pub fn by_rva(&self, rva: u32) -> Option<&SectionHeader> {
for sect in self.iter() {
if rva >= sect.VirtualAddress && rva < u32::wrapping_add(sect.VirtualAddress, sect.VirtualSize) {
return Some(sect);
}
}
None
}
}
unsafe impl Pod for SectionHeaders {}
impl<'a> IntoIterator for &'a SectionHeaders {
type Item = &'a SectionHeader;
type IntoIter = slice::Iter<'a, SectionHeader>;
fn into_iter(self) -> Self::IntoIter {
self.as_slice().into_iter()
}
}
impl fmt::Debug for SectionHeaders {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_slice().fmt(f)
}
}
#[cfg(feature = "serde")]
pub(crate) fn serialize_name<S: ::serde::ser::Serializer>(name: &[u8; IMAGE_SIZEOF_SHORT_NAME], serializer: S) -> Result<S::Ok, S::Error> {
match crate::util::parsen(name) {
Ok(name) => serializer.serialize_str(name),
Err(name) => serializer.serialize_bytes(name),
}
}
#[cfg(feature = "serde")]
mod serde {
use crate::util::serde_helper::*;
use super::{SectionHeader, SectionHeaders};
impl serde::Serialize for SectionHeaders {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.collect_seq(self.iter())
}
}
impl serde::Serialize for SectionHeader {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.0.serialize(serializer)
}
}
}