diff --git a/src/pe/mod.rs b/src/pe/mod.rs index 208511a19..72a5c8e53 100644 --- a/src/pe/mod.rs +++ b/src/pe/mod.rs @@ -343,13 +343,26 @@ mod tests { ]; #[test] - fn issue_309() { + fn string_table_excludes_length() { let coff = Coff::parse(&&COFF_FILE_SINGLE_STRING_IN_STRING_TABLE[..]).unwrap(); let string_table = coff.strings.to_vec().unwrap(); assert!(string_table == vec!["ExitProcess"]); } + #[test] + fn symbol_name_excludes_length() { + let coff = Coff::parse(&COFF_FILE_SINGLE_STRING_IN_STRING_TABLE).unwrap(); + let strings = coff.strings; + let symbols = coff + .symbols + .iter() + .filter(|(_, name, _)| name.is_none()) + .map(|(_, _, sym)| sym.name(&strings).unwrap().to_owned()) + .collect::>(); + assert_eq!(symbols, vec!["ExitProcess"]) + } + #[test] fn invalid_dos_header() { if let Ok(_) = PE::parse(&INVALID_DOS_SIGNATURE) { diff --git a/src/pe/symbol.rs b/src/pe/symbol.rs index a4e365142..b2ced808a 100644 --- a/src/pe/symbol.rs +++ b/src/pe/symbol.rs @@ -230,8 +230,14 @@ impl Symbol { /// /// Returns `None` if the name is inline. pub fn name_offset(&self) -> Option { + // Symbol offset starts at the strtable's length, so let's adjust it + let length_field_size = core::mem::size_of::() as u32; + if self.name[0] == 0 { - self.name.pread_with(4, scroll::LE).ok() + self.name + .pread_with(4, scroll::LE) + .ok() + .map(|offset: u32| offset - length_field_size) } else { None }