From 460656be13999759eb1eeb5bd9a868b34c0aea22 Mon Sep 17 00:00:00 2001 From: Glenn Smith Date: Wed, 31 Aug 2022 23:01:49 -0400 Subject: Expose CallingConvention::GetVariablesForParameters --- binaryninjacore.h | 16 +++++++++++ rust/src/callingconvention.rs | 62 +++++++++++++++++++++++++++++++++++++++++++ rust/src/symbol.rs | 2 +- rust/src/types.rs | 2 +- 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/binaryninjacore.h b/binaryninjacore.h index f2211a45..daffe5bf 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -5631,6 +5631,22 @@ extern "C" BNCallingConvention* cc, uint32_t reg, BNFunction* func); BINARYNINJACOREAPI BNRegisterValue BNGetIncomingFlagValue(BNCallingConvention* cc, uint32_t reg, BNFunction* func); + BINARYNINJACOREAPI BNVariable* BNGetVariablesForParametersDefaultIntArgs( + BNCallingConvention* cc, const BNFunctionParameter* params, size_t paramCount, size_t* count); + BINARYNINJACOREAPI BNVariable* BNGetVariablesForParameters( + BNCallingConvention* cc, const BNFunctionParameter* params, size_t paramCount, + const uint32_t* intArgs, size_t intArgCount, size_t* count); + BINARYNINJACOREAPI BNVariable* BNGetParameterOrderingForVariables( + BNCallingConvention* cc, const BNVariable* paramVars, const BNType** paramTypes, + size_t paramCount, size_t* count); + BINARYNINJACOREAPI int64_t BNGetStackAdjustmentForVariables( + BNCallingConvention* cc, const BNVariable* paramVars, const BNType** paramTypes, + size_t paramCount); + BINARYNINJACOREAPI size_t BNGetRegisterStackAdjustments( + BNCallingConvention* cc, const uint32_t* returnRegs, size_t returnRegCount, BNType* returnType, + const BNVariable* params, size_t paramCount, const BNType** types, size_t typeCount, + uint32_t** resultRegisters, uint32_t** resultAdjustments); + BINARYNINJACOREAPI BNVariable BNGetIncomingVariableForParameterVariable( BNCallingConvention* cc, const BNVariable* var, BNFunction* func); BINARYNINJACOREAPI BNVariable BNGetParameterVariableForIncomingVariable( diff --git a/rust/src/callingconvention.rs b/rust/src/callingconvention.rs index 79fe7201..a8deadef 100644 --- a/rust/src/callingconvention.rs +++ b/rust/src/callingconvention.rs @@ -445,6 +445,66 @@ impl CallingConvention { pub fn name(&self) -> BnString { unsafe { BnString::from_raw(BNGetCallingConventionName(self.handle)) } } + + pub fn variables_for_parameters( + &self, + params: &Vec>, + int_arg_registers: Option>, + ) -> Vec { + let mut bn_params: Vec = vec![]; + + for parameter in params.iter() { + let raw_name = parameter.name.clone().into_bytes_with_nul(); + let location = match ¶meter.location { + Some(location) => location.into_raw(), + None => unsafe { mem::zeroed() }, + }; + bn_params.push(BNFunctionParameter { + name: raw_name.as_ref().as_ptr() as *mut _, + type_: parameter.t.contents.handle, + typeConfidence: parameter.t.confidence, + defaultLocation: parameter.location.is_none(), + location, + }); + } + + let mut count: usize = 0; + let vars: *mut BNVariable = if let Some(int_args) = int_arg_registers { + let mut int_regs = vec![]; + for r in int_args { + int_regs.push(r.id()); + } + + unsafe { + BNGetVariablesForParameters( + self.handle, + bn_params.as_ptr(), + bn_params.len(), + int_regs.as_ptr(), + int_regs.len(), + &mut count, + ) + } + } else { + unsafe { + BNGetVariablesForParametersDefaultIntArgs( + self.handle, + bn_params.as_ptr(), + bn_params.len(), + &mut count, + ) + } + }; + + let vars_slice = unsafe { slice::from_raw_parts(vars, count) }; + let mut result = vec![]; + for var in vars_slice { + result.push(unsafe { Variable::from_raw(*var) }); + } + + unsafe { BNFreeVariableList(vars) }; + result + } } impl Eq for CallingConvention {} @@ -454,7 +514,9 @@ impl PartialEq for CallingConvention { } } +use crate::types::{FunctionParameter, Variable}; use std::hash::{Hash, Hasher}; + impl Hash for CallingConvention { fn hash(&self, state: &mut H) { self.handle.hash(state); diff --git a/rust/src/symbol.rs b/rust/src/symbol.rs index 2d5df068..2578bee2 100644 --- a/rust/src/symbol.rs +++ b/rust/src/symbol.rs @@ -280,7 +280,7 @@ unsafe impl<'a> CoreArrayWrapper<'a> for Symbol { impl PartialEq for Symbol { fn eq(&self, other: &Self) -> bool { - *self == *other + self.handle == other.handle } } diff --git a/rust/src/types.rs b/rust/src/types.rs index 790faca5..4f9d8bff 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -1315,7 +1315,7 @@ impl FunctionParameter { ////////////// // Variable -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] pub struct Variable { pub t: BNVariableSourceType, pub index: u32, -- cgit v1.3.1