Skip to content

Commit b3a80fd

Browse files
authored
pe: TLS parser rework (#435)
* Remove generics from tls parser in favor of is_64 boolean
1 parent 9c59d67 commit b3a80fd

File tree

2 files changed

+28
-30
lines changed

2 files changed

+28
-30
lines changed

src/pe/mod.rs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -222,25 +222,15 @@ impl<'a> PE<'a> {
222222
}
223223

224224
if let Some(tls_table) = optional_header.data_directories.get_tls_table() {
225-
tls_data = if is_64 {
226-
tls::TlsData::parse_with_opts::<u64>(
227-
bytes,
228-
image_base,
229-
tls_table,
230-
&sections,
231-
file_alignment,
232-
opts,
233-
)?
234-
} else {
235-
tls::TlsData::parse_with_opts::<u32>(
236-
bytes,
237-
image_base,
238-
&tls_table,
239-
&sections,
240-
file_alignment,
241-
opts,
242-
)?
243-
};
225+
tls_data = tls::TlsData::parse_with_opts(
226+
bytes,
227+
image_base,
228+
tls_table,
229+
&sections,
230+
file_alignment,
231+
opts,
232+
is_64,
233+
)?;
244234
debug!("tls data: {:#?}", tls_data);
245235
}
246236

src/pe/tls.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,27 +94,30 @@ pub struct TlsData<'a> {
9494
}
9595

9696
impl ImageTlsDirectory {
97-
pub fn parse<T: Sized>(
97+
pub fn parse(
9898
bytes: &[u8],
9999
dd: data_directories::DataDirectory,
100100
sections: &[section_table::SectionTable],
101101
file_alignment: u32,
102+
is_64: bool,
102103
) -> error::Result<Self> {
103-
Self::parse_with_opts::<T>(
104+
Self::parse_with_opts(
104105
bytes,
105106
dd,
106107
sections,
107108
file_alignment,
108109
&options::ParseOptions::default(),
110+
is_64,
109111
)
110112
}
111113

112-
pub fn parse_with_opts<T: Sized>(
114+
pub fn parse_with_opts(
113115
bytes: &[u8],
114116
dd: data_directories::DataDirectory,
115117
sections: &[section_table::SectionTable],
116118
file_alignment: u32,
117119
opts: &options::ParseOptions,
120+
is_64: bool,
118121
) -> error::Result<Self> {
119122
let rva = dd.virtual_address as usize;
120123
let mut offset =
@@ -125,8 +128,6 @@ impl ImageTlsDirectory {
125128
))
126129
})?;
127130

128-
let is_64 = core::mem::size_of::<T>() == 8;
129-
130131
let start_address_of_raw_data = if is_64 {
131132
bytes.gread_with::<u64>(&mut offset, scroll::LE)?
132133
} else {
@@ -164,39 +165,40 @@ impl ImageTlsDirectory {
164165
}
165166

166167
impl<'a> TlsData<'a> {
167-
pub fn parse<T: Sized>(
168+
pub fn parse(
168169
bytes: &'a [u8],
169170
image_base: u64,
170171
dd: &data_directories::DataDirectory,
171172
sections: &[section_table::SectionTable],
172173
file_alignment: u32,
174+
is_64: bool,
173175
) -> error::Result<Option<Self>> {
174-
Self::parse_with_opts::<T>(
176+
Self::parse_with_opts(
175177
bytes,
176178
image_base,
177179
dd,
178180
sections,
179181
file_alignment,
180182
&options::ParseOptions::default(),
183+
is_64,
181184
)
182185
}
183186

184-
pub fn parse_with_opts<T: Sized>(
187+
pub fn parse_with_opts(
185188
bytes: &'a [u8],
186189
image_base: u64,
187190
dd: &data_directories::DataDirectory,
188191
sections: &[section_table::SectionTable],
189192
file_alignment: u32,
190193
opts: &options::ParseOptions,
194+
is_64: bool,
191195
) -> error::Result<Option<Self>> {
192196
let mut raw_data = None;
193197
let mut slot = None;
194198
let mut callbacks = Vec::new();
195199

196-
let is_64 = core::mem::size_of::<T>() == 8;
197-
198200
let itd =
199-
ImageTlsDirectory::parse_with_opts::<T>(bytes, *dd, sections, file_alignment, opts)?;
201+
ImageTlsDirectory::parse_with_opts(bytes, *dd, sections, file_alignment, opts, is_64)?;
200202

201203
// Parse the raw data if any
202204
if itd.end_address_of_raw_data != 0 && itd.start_address_of_raw_data != 0 {
@@ -225,6 +227,12 @@ impl<'a> TlsData<'a> {
225227
rva
226228
))
227229
})?;
230+
if offset + size as usize > bytes.len() {
231+
return Err(error::Error::Malformed(format!(
232+
"tls raw data offset ({:#x}) and size ({:#x}) greater than byte slice len ({:#x})",
233+
offset, size, bytes.len()
234+
)));
235+
}
228236
raw_data = Some(&bytes[offset..offset + size as usize]);
229237
}
230238

0 commit comments

Comments
 (0)