pub trait HandleControlFlow {
type Error: Error;
type CachedKey: Clone;
// Required methods
fn at_decode_begin(&mut self) -> Result<(), Self::Error>;
fn on_new_block(
&mut self,
block_addr: u64,
transition_kind: ControlFlowTransitionKind,
cache: bool,
) -> Result<(), Self::Error>;
fn cache_prev_cached_key(
&mut self,
cached_key: Self::CachedKey,
) -> Result<(), Self::Error>;
fn take_cache(&mut self) -> Result<Option<Self::CachedKey>, Self::Error>;
fn clear_current_cache(&mut self) -> Result<(), Self::Error>;
fn on_reused_cache(
&mut self,
cached_key: &Self::CachedKey,
new_bb: u64,
) -> Result<(), Self::Error>;
}Expand description
Control flow handler used for EdgeAnalyzer
There are several implementors provided in this crate, such as
FuzzBitmapControlFlowHandler.
§Non-cache mode
For non-cache mode, the usage of this trait is very simple: there are only two methods.
at_decode_begin is invoked at decode begin, and
on_new_block is invoked every time a basic block is
encountered.
§Cache-mode
The overall workflow when using this trait is like:
- Creating a new handler.
- Clear cache by
clear_current_cache - When a new basic block is met, call
on_new_block. This function should always deal with the impact, and deal with the cache depending on thecacheparameter. - When a previous cache is met, call
on_reused_cache. This function should only deal with the impact. - Optionally merge caches by
cache_prev_cached_key. - Collect cache by
take_cache.
In the documentation of this trait, there are two terms: “impact” and “cache”. Let’s take some examples. For fuzzing, “impact” means modification of fuzzing bitmap, and “cache” means modification of internal cached information. For logging, “impact” means logging the basic block transition, and “cache” also means the modification of internal cached information.
It should be noted that, the correctness of implementation of cache-mode HandleControlFlow
will have no impact on the correctness of cache mechanism used by EdgeAnalyzer.
Instead, since on_new_block is only invoked when a non-cache
basic block is encountered, if you incorrectly implemented this trait, you may not accurately
get all basic blocks.
Required Associated Types§
Sourcetype CachedKey: Clone
Available on crate feature cache only.
type CachedKey: Clone
cache only.Cached key returned by take_cache.
This can be used by the edge analyzer to tell the control flow handler a previous TNT sequence has been met again and the cache is reused instead of re-parsing all TNT bits.
Required Methods§
Sourcefn at_decode_begin(&mut self) -> Result<(), Self::Error>
fn at_decode_begin(&mut self) -> Result<(), Self::Error>
Callback at begin of decoding.
This is useful when using the same handler to process multiple Intel PT traces
Sourcefn on_new_block(
&mut self,
block_addr: u64,
transition_kind: ControlFlowTransitionKind,
cache: bool,
) -> Result<(), Self::Error>
fn on_new_block( &mut self, block_addr: u64, transition_kind: ControlFlowTransitionKind, cache: bool, ) -> Result<(), Self::Error>
Callback when a new basic block is met.
For non-cache mode, this function is always invoked no matter whether this basic block has been encountered before (i.e., this is not a “unique” block). For cache mode, this function is only invoked when a non-cached basic block is encountered.
The new block’s address is block_addr, and the reason for getting
into this block is in transition_kind. cache is only used in cache mode,
which indicates whether this block transition should be taken into cache
by the implementor, which is used as an optimizing hint. If cache is false,
this means this transition will never be folded into cache.
No matter cache is true or false, this function should always deal with
the impact of new block.
When conducting caching, it should be extremely important, that
the cached state should always be consistent with block_addr.
Suggest marking #[inline] on the implementation
Sourcefn cache_prev_cached_key(
&mut self,
cached_key: Self::CachedKey,
) -> Result<(), Self::Error>
Available on crate feature cache only.
fn cache_prev_cached_key( &mut self, cached_key: Self::CachedKey, ) -> Result<(), Self::Error>
cache only.Merge a previous cached key into cache
When analyzing TNT packets, the cache manager maintains two kinds of cache: 8bits cache and 32bits cache. As a result, when creating 32bits caches, we need to merge four 8bits caches into one 32bits cache, and this function serves the purpose.
It should be noted that although merged, the previous cache should still be kept.
This function only deals with the caching thing. The previously cached information should
not have impact in this function. For dealing with impacts, see on_reused_cache.
Sourcefn take_cache(&mut self) -> Result<Option<Self::CachedKey>, Self::Error>
Available on crate feature cache only.
fn take_cache(&mut self) -> Result<Option<Self::CachedKey>, Self::Error>
cache only.Collect all currently cached information and generate a cached key. This could clear the cache depending on your implementing logic.
If there is no cache, this function should return Ok(None).
Sourcefn clear_current_cache(&mut self) -> Result<(), Self::Error>
Available on crate feature cache only.
fn clear_current_cache(&mut self) -> Result<(), Self::Error>
cache only.Clear the cache.
This is NOT clearing all cached information. Instead, this is to clear current temporary cache.
Sourcefn on_reused_cache(
&mut self,
cached_key: &Self::CachedKey,
new_bb: u64,
) -> Result<(), Self::Error>
Available on crate feature cache only.
fn on_reused_cache( &mut self, cached_key: &Self::CachedKey, new_bb: u64, ) -> Result<(), Self::Error>
cache only.Callback when a given cached key is being reused.
new_bb is the next basic block address after the cached key is applied.
This function only deals ith the impact of cached key, and should not add new caches.
For adding new caches, see cache_prev_cached_key.
Implementors§
Source§impl<H1, H2> HandleControlFlow for CombinedControlFlowHandler<H1, H2>where
H1: HandleControlFlow,
H2: HandleControlFlow,
impl<H1, H2> HandleControlFlow for CombinedControlFlowHandler<H1, H2>where
H1: HandleControlFlow,
H2: HandleControlFlow,
type Error = CombinedError<H1, H2>
type CachedKey = (Option<<H1 as HandleControlFlow>::CachedKey>, Option<<H2 as HandleControlFlow>::CachedKey>)
Source§impl<M: AsRef<[u8]> + AsMut<[u8]>> HandleControlFlow for FuzzBitmapControlFlowHandler<M>
Available on crate feature fuzz_bitmap only.
impl<M: AsRef<[u8]> + AsMut<[u8]>> HandleControlFlow for FuzzBitmapControlFlowHandler<M>
fuzz_bitmap only.