@@ -3,7 +3,7 @@ use crate::convert::{bn_comment_to_comment, bn_var_to_location, from_bn_symbol,
33use binaryninja:: architecture:: {
44 Architecture , ImplicitRegisterExtend , Register as BNRegister , RegisterInfo ,
55} ;
6- use binaryninja:: basic_block:: BasicBlock as BNBasicBlock ;
6+ use binaryninja:: basic_block:: { BasicBlock as BNBasicBlock } ;
77use binaryninja:: binary_view:: { BinaryView , BinaryViewExt } ;
88use binaryninja:: confidence:: MAX_CONFIDENCE ;
99use binaryninja:: function:: { Function as BNFunction , NativeBlock } ;
@@ -186,7 +186,7 @@ pub fn basic_block_guid<M: FunctionMutability>(
186186 instr_bytes. truncate ( instr_info. length ) ;
187187
188188 // Find variant and blacklisted instructions using lifted il.
189- for lifted_il_instr in lifted_il . instructions_at ( instr_addr) {
189+ for lifted_il_instr in filtered_instructions_at ( lifted_il , instr_addr) {
190190 // If instruction is blacklisted, don't include the bytes.
191191 if is_blacklisted_instruction ( & lifted_il_instr) {
192192 continue ;
@@ -209,7 +209,7 @@ pub fn basic_block_guid<M: FunctionMutability>(
209209 // TODO: A "mapped llil" or having some simple data flow, the simple data flow is the most attractive
210210 // TODO: "solution", but it would require
211211 if let Ok ( llil) = & low_level_il {
212- for low_level_instr in llil . instructions_at ( instr_addr) {
212+ for low_level_instr in filtered_instructions_at ( llil , instr_addr) {
213213 if is_computed_variant_instruction ( relocatable_regions, & low_level_instr) {
214214 // Found a computed variant instruction, mask off the entire instruction.
215215 instr_bytes. fill ( 0 ) ;
@@ -226,6 +226,25 @@ pub fn basic_block_guid<M: FunctionMutability>(
226226 BasicBlockGUID :: from ( basic_block_bytes. as_slice ( ) )
227227}
228228
229+ pub fn filtered_instructions_at < M : FunctionMutability > (
230+ il : & LowLevelILFunction < M , NonSSA > ,
231+ addr : u64 ,
232+ ) -> Vec < LowLevelILInstruction < M , NonSSA > > {
233+ il. instructions_at ( addr)
234+ . into_iter ( )
235+ . enumerate ( )
236+ . take_while ( |( i, instr) | match instr. kind ( ) {
237+ // Stop collecting instructions after we see a LLIL_RET, LLIL_NO_RET.
238+ LowLevelILInstructionKind :: NoRet ( _) | LowLevelILInstructionKind :: Ret ( _) => false ,
239+ // Stop collecting instruction if we are probably the end function jump in lifted IL. This
240+ // is emitted at the end of the function and will mess with our GUID.
241+ LowLevelILInstructionKind :: Jump ( _) => * i != 0 ,
242+ _ => true ,
243+ } )
244+ . map ( |( _, instr) | instr)
245+ . collect ( )
246+ }
247+
229248/// Is the instruction not included in the masked byte sequence?
230249///
231250/// Blacklisted instructions will make an otherwise identical function GUID fail to match.
@@ -301,7 +320,7 @@ pub fn is_computed_variant_instruction<M: FunctionMutability>(
301320 instr : & LowLevelILInstruction < M , NonSSA > ,
302321) -> bool {
303322 let is_expr_constant = |expr : & LowLevelILExpression < M , NonSSA , ValueExpr > | match expr. kind ( ) {
304- LowLevelILExpressionKind :: Const ( _) => true ,
323+ LowLevelILExpressionKind :: Const ( _) | LowLevelILExpressionKind :: ConstPtr ( _ ) => true ,
305324 _ => false ,
306325 } ;
307326
0 commit comments