Skip to content

Commit

Permalink
pe: add strict option to parse config; fix fail on malformed certific…
Browse files Browse the repository at this point in the history
…ate table parsing (#417)

* pe.cert_table: ignore malformed
* parse_options: added ParseMode
* pe.options: added te(), fixes
  • Loading branch information
ideeockus authored Jan 5, 2025
1 parent 1a999cc commit 50fa096
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 8 deletions.
18 changes: 12 additions & 6 deletions src/pe/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use crate::container;
use crate::error;
use crate::pe::utils::pad;
use crate::strtab;
use options::ParseMode;

use scroll::{ctx, Pwrite};

Expand Down Expand Up @@ -264,11 +265,19 @@ impl<'a> PE<'a> {
if let Some(&certificate_table) =
optional_header.data_directories.get_certificate_table()
{
certificates = certificate_table::enumerate_certificates(
let certificates_result = certificate_table::enumerate_certificates(
bytes,
certificate_table.virtual_address,
certificate_table.size,
)?;
);

certificates = match opts.parse_mode {
ParseMode::Strict => certificates_result?,
ParseMode::Permissive => certificates_result.unwrap_or_else(|err| {
warn!("Cannot parse CertificateTable: {:?}", err);
Default::default()
}),
};

certificate_table.size as usize
} else {
Expand Down Expand Up @@ -522,10 +531,7 @@ pub struct TE<'a> {
impl<'a> TE<'a> {
/// Reads a TE binary from the underlying `bytes`
pub fn parse(bytes: &'a [u8]) -> error::Result<Self> {
let opts = &options::ParseOptions {
resolve_rva: false,
parse_attribute_certificates: false,
};
let opts = &options::ParseOptions::te();

let mut offset = 0;

Expand Down
26 changes: 24 additions & 2 deletions src/pe/options.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/// Parsing Options structure for the PE parser
#[non_exhaustive]
#[derive(Debug, Copy, Clone)]
pub struct ParseOptions {
/// Wether the parser should resolve rvas or not. Default: true
Expand All @@ -8,14 +9,35 @@ pub struct ParseOptions {
/// memory](https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#other-contents-of-the-file).
/// For on-disk representations, leave as true. Default: true
pub parse_attribute_certificates: bool,
/// Whether or not to end with an error in case of incorrect data or continue parsing if able. Default: ParseMode::Strict
pub parse_mode: ParseMode,
}

impl ParseOptions {
#[derive(Debug, Copy, Clone)]
pub enum ParseMode {
/// Always end with error on incorrect data
Strict,
/// Incorrect data will not cause to end with error if possible
Permissive,
}

impl Default for ParseOptions {
/// Returns a parse options structure with default values
pub fn default() -> Self {
fn default() -> Self {
ParseOptions {
resolve_rva: true,
parse_attribute_certificates: true,
parse_mode: ParseMode::Strict,
}
}
}

impl ParseOptions {
pub(crate) fn te() -> Self {
Self {
resolve_rva: false,
parse_attribute_certificates: false,
parse_mode: ParseMode::Strict,
}
}
}

0 comments on commit 50fa096

Please sign in to comment.