Skip to content

Commit

Permalink
read/pe: search all ImageDebugDirectory entries for CodeView records (#…
Browse files Browse the repository at this point in the history
…451)

There can be more than one ImageDebugDirectory entries, and any of those
can be the CodeView record we are looking for.
  • Loading branch information
Swatinem authored Aug 1, 2022
1 parent 0f4e357 commit 40d77b2
Showing 1 changed file with 47 additions and 36 deletions.
83 changes: 47 additions & 36 deletions src/read/pe/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,49 +304,60 @@ where
None => return Ok(None),
};
let debug_data = data_dir.data(self.data, &self.common.sections).map(Bytes)?;
let debug_dir = debug_data
.read_at::<pe::ImageDebugDirectory>(0)
.read_error("Invalid PE debug dir size")?;
let debug_data_size = data_dir.size.get(LE) as usize;

if debug_dir.typ.get(LE) != pe::IMAGE_DEBUG_TYPE_CODEVIEW {
return Ok(None);
let count = debug_data_size / mem::size_of::<pe::ImageDebugDirectory>();
let rem = debug_data_size % mem::size_of::<pe::ImageDebugDirectory>();
if rem != 0 || count < 1 {
return Err(Error("Invalid PE debug dir size"));
}

let info = self
.data
.read_slice_at::<u8>(
debug_dir.pointer_to_raw_data.get(LE) as u64,
debug_dir.size_of_data.get(LE) as usize,
)
.read_error("Invalid CodeView Info address")?;

let mut info = Bytes(info);

let sig = info
.read_bytes(4)
.read_error("Invalid CodeView signature")?;
if sig.0 != b"RSDS" {
return Ok(None);
}
let debug_dirs = debug_data
.read_slice_at::<pe::ImageDebugDirectory>(0, count)
.read_error("Invalid PE debug dir size")?;

for debug_dir in debug_dirs {
if debug_dir.typ.get(LE) != pe::IMAGE_DEBUG_TYPE_CODEVIEW {
continue;
}

let info = self
.data
.read_slice_at::<u8>(
debug_dir.pointer_to_raw_data.get(LE) as u64,
debug_dir.size_of_data.get(LE) as usize,
)
.read_error("Invalid CodeView Info address")?;

let mut info = Bytes(info);

let sig = info
.read_bytes(4)
.read_error("Invalid CodeView signature")?;
if sig.0 != b"RSDS" {
continue;
}

let guid: [u8; 16] = info
.read_bytes(16)
.read_error("Invalid CodeView GUID")?
.0
.try_into()
.unwrap();
let guid: [u8; 16] = info
.read_bytes(16)
.read_error("Invalid CodeView GUID")?
.0
.try_into()
.unwrap();

let age = info.read::<U32<LE>>().read_error("Invalid CodeView Age")?;
let age = info.read::<U32<LE>>().read_error("Invalid CodeView Age")?;

let path = info
.read_string()
.read_error("Invalid CodeView file path")?;
let path = info
.read_string()
.read_error("Invalid CodeView file path")?;

Ok(Some(CodeView {
path: ByteString(path),
guid,
age: age.get(LE),
}))
return Ok(Some(CodeView {
path: ByteString(path),
guid,
age: age.get(LE),
}));
}
Ok(None)
}

fn has_debug_symbols(&self) -> bool {
Expand Down

0 comments on commit 40d77b2

Please sign in to comment.