diff --git a/src/pe/mod.rs b/src/pe/mod.rs index e921f2e2..de46b1b9 100644 --- a/src/pe/mod.rs +++ b/src/pe/mod.rs @@ -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}; @@ -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 { @@ -525,6 +534,7 @@ impl<'a> TE<'a> { let opts = &options::ParseOptions { resolve_rva: false, parse_attribute_certificates: false, + parse_mode: ParseMode::Strict, }; let mut offset = 0; diff --git a/src/pe/options.rs b/src/pe/options.rs index 4461a4c7..d846eed5 100644 --- a/src/pe/options.rs +++ b/src/pe/options.rs @@ -8,6 +8,16 @@ 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, +} + +#[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 ParseOptions { @@ -16,6 +26,7 @@ impl ParseOptions { ParseOptions { resolve_rva: true, parse_attribute_certificates: true, + parse_mode: ParseMode::Strict, } } }