Skip to content

Commit 63bec4d

Browse files
vojoneplusvic
andauthored
fix: limit function and DLL names for exports in PE module (#443)
The PE parser now protects agains huge DLL and function names in PE exports. --------- Co-authored-by: Victor M. Alvarez <[email protected]>
1 parent 27b8899 commit 63bec4d

File tree

1 file changed

+9
-6
lines changed

1 file changed

+9
-6
lines changed

lib/src/modules/pe/parser.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,7 @@ impl<'a> PE<'a> {
540540
const MAX_PE_RESOURCES: usize = 65536;
541541
const MAX_DIR_ENTRIES: usize = 16;
542542
const MAX_FUNC_NAME_LENGTH: usize = 1024;
543+
const MAX_DLL_NAME_LENGTH: usize = 512;
543544

544545
fn parse_dos_header(input: &[u8]) -> IResult<&[u8], DOSHeader> {
545546
map(
@@ -2136,7 +2137,8 @@ impl<'a> PE<'a> {
21362137
})
21372138
{
21382139
if let Some(name_rva) = names.get(idx) {
2139-
f.name = self.str_at_rva(*name_rva);
2140+
f.name =
2141+
self.str_at_rva(*name_rva, Self::MAX_FUNC_NAME_LENGTH);
21402142
}
21412143
}
21422144

@@ -2146,7 +2148,8 @@ impl<'a> PE<'a> {
21462148
// really pointing to the function, but to a ASCII string that
21472149
// contains the DLL and function to which this export is forwarded.
21482150
if exports_section.contains(&f.rva) {
2149-
f.forward_name = self.str_at_rva(f.rva);
2151+
f.forward_name =
2152+
self.str_at_rva(f.rva, Self::MAX_FUNC_NAME_LENGTH);
21502153
} else {
21512154
f.offset = self.rva_to_offset(f.rva);
21522155
}
@@ -2215,17 +2218,17 @@ impl<'a> PE<'a> {
22152218
parser.parse(data).map(|(_, result)| result).ok()
22162219
}
22172220

2218-
fn str_at_rva(&self, rva: u32) -> Option<&'a str> {
2219-
let dll_name = self.parse_at_rva(rva, take_till(|c| c == 0))?;
2220-
from_utf8(dll_name).ok()
2221+
fn str_at_rva(&self, rva: u32, max_len: usize) -> Option<&'a str> {
2222+
self.parse_at_rva(rva, take_while_m_n(0, max_len, |c| c != 0))
2223+
.map(|s| from_utf8(s).ok())?
22212224
}
22222225

22232226
fn dll_name_at_rva(&self, rva: u32) -> Option<&'a str> {
22242227
// TODO: this enforces the DLL name to be valid UTF-8. Is this too
22252228
// restrictive? YARA is using a more relaxed approach and accepts
22262229
// every byte except the ones listed below. YARA imposes a length
22272230
// limit of 256 bytes, though.
2228-
let dll_name = self.str_at_rva(rva)?;
2231+
let dll_name = self.str_at_rva(rva, Self::MAX_DLL_NAME_LENGTH)?;
22292232

22302233
for c in dll_name.chars() {
22312234
if c.is_ascii_control() {

0 commit comments

Comments
 (0)