From 2c7f7b5cb0a7ab4dec9d039d57d049278b07c2ce Mon Sep 17 00:00:00 2001 From: Radmir Date: Mon, 29 Jul 2024 16:25:15 +0300 Subject: [PATCH 1/3] pe.cert_table: ignore malformed --- src/pe/mod.rs | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/pe/mod.rs b/src/pe/mod.rs index 3c8c3c3e..02d3cc44 100644 --- a/src/pe/mod.rs +++ b/src/pe/mod.rs @@ -3,12 +3,19 @@ // TODO: panics with unwrap on None for apisetschema.dll, fhuxgraphics.dll and some others -use core::cmp::max; - use alloc::borrow::Cow; use alloc::string::String; use alloc::vec::Vec; +use core::cmp::max; + +use log::debug; use log::warn; +use scroll::{ctx, Pwrite}; + +use crate::container; +use crate::error; +use crate::pe::utils::pad; +use crate::strtab; pub mod authenticode; pub mod certificate_table; @@ -29,15 +36,6 @@ pub mod symbol; pub mod tls; pub mod utils; -use crate::container; -use crate::error; -use crate::pe::utils::pad; -use crate::strtab; - -use scroll::{ctx, Pwrite}; - -use log::debug; - #[derive(Debug)] /// An analyzed PE32/PE32+ binary pub struct PE<'a> { @@ -142,7 +140,7 @@ impl<'a> PE<'a> { return Err(error::Error::Malformed(format!( "Unsupported header magic ({:#x})", magic - ))) + ))); } }; @@ -268,7 +266,11 @@ impl<'a> PE<'a> { bytes, certificate_table.virtual_address, certificate_table.size, - )?; + ) + .unwrap_or_else(|err| { + warn!("Cannot parse CertificateTable: {:?}", err); + Default::default() + }); certificate_table.size as usize } else { From b46e266a34638fdaadf3656373da579f4b6d39cc Mon Sep 17 00:00:00 2001 From: Radmir Date: Wed, 14 Aug 2024 18:24:25 +0300 Subject: [PATCH 2/3] pe.cert_table: revert formatting --- src/pe/mod.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/pe/mod.rs b/src/pe/mod.rs index 02d3cc44..fdeb7717 100644 --- a/src/pe/mod.rs +++ b/src/pe/mod.rs @@ -3,19 +3,12 @@ // TODO: panics with unwrap on None for apisetschema.dll, fhuxgraphics.dll and some others +use core::cmp::max; + use alloc::borrow::Cow; use alloc::string::String; use alloc::vec::Vec; -use core::cmp::max; - -use log::debug; use log::warn; -use scroll::{ctx, Pwrite}; - -use crate::container; -use crate::error; -use crate::pe::utils::pad; -use crate::strtab; pub mod authenticode; pub mod certificate_table; @@ -36,6 +29,15 @@ pub mod symbol; pub mod tls; pub mod utils; +use crate::container; +use crate::error; +use crate::pe::utils::pad; +use crate::strtab; + +use scroll::{ctx, Pwrite}; + +use log::debug; + #[derive(Debug)] /// An analyzed PE32/PE32+ binary pub struct PE<'a> { @@ -140,7 +142,7 @@ impl<'a> PE<'a> { return Err(error::Error::Malformed(format!( "Unsupported header magic ({:#x})", magic - ))); + ))) } }; From ac97d4c9207667dbe32092c76fcf5ea9067b0a4c Mon Sep 17 00:00:00 2001 From: Radmir Date: Sun, 8 Dec 2024 16:19:28 +0300 Subject: [PATCH 3/3] parse_options: added ParseMode --- src/pe/mod.rs | 18 ++++++++++++------ src/pe/options.rs | 11 +++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/pe/mod.rs b/src/pe/mod.rs index 5323ce05..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,15 +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, - ) - .unwrap_or_else(|err| { - warn!("Cannot parse CertificateTable: {:?}", err); - Default::default() - }); + ); + + 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 { @@ -529,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, } } }