From 3d403cfae9d5a366f112c8a5936a371a01cfd230 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Mon, 10 Jul 2017 21:40:51 -0400 Subject: Add confidence levels to type objects --- binaryninjacore.h | 105 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 74 insertions(+), 31 deletions(-) (limited to 'binaryninjacore.h') diff --git a/binaryninjacore.h b/binaryninjacore.h index eb9927ab..f5b89437 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -92,6 +92,8 @@ #define BN_MAX_VARIABLE_OFFSET 0x7fffffffffLL #define BN_MAX_VARIABLE_INDEX 0xfffff +#define BN_FULL_CONFIDENCE 255 + #ifdef __cplusplus extern "C" { @@ -714,6 +716,7 @@ extern "C" uint64_t address; BNType* type; bool autoDiscovered; + uint8_t typeConfidence; }; enum BNMediumLevelILOperation @@ -962,6 +965,7 @@ extern "C" uint64_t value; size_t size, operand; BNInstructionTextTokenContext context; + uint8_t confidence; uint64_t address; }; @@ -1080,10 +1084,41 @@ extern "C" char* (*serialize)(void* ctxt); }; + struct BNTypeWithConfidence + { + BNType* type; + uint8_t confidence; + }; + + struct BNCallingConventionWithConfidence + { + BNCallingConvention* convention; + uint8_t confidence; + }; + + struct BNBoolWithConfidence + { + bool value; + uint8_t confidence; + }; + + struct BNMemberScopeWithConfidence + { + BNMemberScope value; + uint8_t confidence; + }; + + struct BNMemberAccessWithConfidence + { + BNMemberAccess value; + uint8_t confidence; + }; + struct BNNameAndType { char* name; BNType* type; + uint8_t typeConfidence; }; struct BNQualifiedNameAndType @@ -1097,6 +1132,7 @@ extern "C" BNType* type; char* name; uint64_t offset; + uint8_t typeConfidence; }; struct BNEnumerationMember @@ -1199,11 +1235,13 @@ extern "C" BNType* type; char* name; bool autoDefined; + uint8_t typeConfidence; }; struct BNStackVariableReference { uint32_t sourceOperand; + uint8_t typeConfidence; BNType* type; char* name; uint64_t varIdentifier; @@ -2027,8 +2065,10 @@ extern "C" BINARYNINJACOREAPI BNVariableNameAndType* BNGetStackLayout(BNFunction* func, size_t* count); BINARYNINJACOREAPI void BNFreeVariableList(BNVariableNameAndType* vars, size_t count); - BINARYNINJACOREAPI void BNCreateAutoStackVariable(BNFunction* func, int64_t offset, BNType* type, const char* name); - BINARYNINJACOREAPI void BNCreateUserStackVariable(BNFunction* func, int64_t offset, BNType* type, const char* name); + BINARYNINJACOREAPI void BNCreateAutoStackVariable(BNFunction* func, int64_t offset, + BNTypeWithConfidence* type, const char* name); + BINARYNINJACOREAPI void BNCreateUserStackVariable(BNFunction* func, int64_t offset, + BNTypeWithConfidence* type, const char* name); BINARYNINJACOREAPI void BNDeleteAutoStackVariable(BNFunction* func, int64_t offset); BINARYNINJACOREAPI void BNDeleteUserStackVariable(BNFunction* func, int64_t offset); BINARYNINJACOREAPI bool BNGetStackVariableAtFrameOffset(BNFunction* func, BNArchitecture* arch, uint64_t addr, @@ -2036,13 +2076,13 @@ extern "C" BINARYNINJACOREAPI void BNFreeVariableNameAndType(BNVariableNameAndType* var); BINARYNINJACOREAPI BNVariableNameAndType* BNGetFunctionVariables(BNFunction* func, size_t* count); - BINARYNINJACOREAPI void BNCreateAutoVariable(BNFunction* func, const BNVariable* var, BNType* type, + BINARYNINJACOREAPI void BNCreateAutoVariable(BNFunction* func, const BNVariable* var, BNTypeWithConfidence* type, const char* name, bool ignoreDisjointUses); - BINARYNINJACOREAPI void BNCreateUserVariable(BNFunction* func, const BNVariable* var, BNType* type, + BINARYNINJACOREAPI void BNCreateUserVariable(BNFunction* func, const BNVariable* var, BNTypeWithConfidence* type, const char* name, bool ignoreDisjointUses); BINARYNINJACOREAPI void BNDeleteAutoVariable(BNFunction* func, const BNVariable* var); BINARYNINJACOREAPI void BNDeleteUserVariable(BNFunction* func, const BNVariable* var); - BINARYNINJACOREAPI BNType* BNGetVariableType(BNFunction* func, const BNVariable* var); + BINARYNINJACOREAPI BNTypeWithConfidence BNGetVariableType(BNFunction* func, const BNVariable* var); BINARYNINJACOREAPI char* BNGetVariableName(BNFunction* func, const BNVariable* var); BINARYNINJACOREAPI uint64_t BNToVariableIdentifier(const BNVariable* var); BINARYNINJACOREAPI BNVariable BNFromVariableIdentifier(uint64_t id); @@ -2093,8 +2133,8 @@ extern "C" BNLinearDisassemblyPosition* pos, BNDisassemblySettings* settings, size_t* count); BINARYNINJACOREAPI void BNFreeLinearDisassemblyLines(BNLinearDisassemblyLine* lines, size_t count); - BINARYNINJACOREAPI void BNDefineDataVariable(BNBinaryView* view, uint64_t addr, BNType* type); - BINARYNINJACOREAPI void BNDefineUserDataVariable(BNBinaryView* view, uint64_t addr, BNType* type); + BINARYNINJACOREAPI void BNDefineDataVariable(BNBinaryView* view, uint64_t addr, BNTypeWithConfidence* type); + BINARYNINJACOREAPI void BNDefineUserDataVariable(BNBinaryView* view, uint64_t addr, BNTypeWithConfidence* type); BINARYNINJACOREAPI void BNUndefineDataVariable(BNBinaryView* view, uint64_t addr); BINARYNINJACOREAPI void BNUndefineUserDataVariable(BNBinaryView* view, uint64_t addr); BINARYNINJACOREAPI BNDataVariable* BNGetDataVariables(BNBinaryView* view, size_t* count); @@ -2451,17 +2491,18 @@ extern "C" // Types BINARYNINJACOREAPI BNType* BNCreateVoidType(void); BINARYNINJACOREAPI BNType* BNCreateBoolType(void); - BINARYNINJACOREAPI BNType* BNCreateIntegerType(size_t width, bool sign, const char* altName); + BINARYNINJACOREAPI BNType* BNCreateIntegerType(size_t width, BNBoolWithConfidence* sign, const char* altName); BINARYNINJACOREAPI BNType* BNCreateFloatType(size_t width, const char* altName); BINARYNINJACOREAPI BNType* BNCreateStructureType(BNStructure* s); BINARYNINJACOREAPI BNType* BNCreateEnumerationType(BNArchitecture* arch, BNEnumeration* e, size_t width, bool isSigned); - BINARYNINJACOREAPI BNType* BNCreatePointerType(BNArchitecture* arch, BNType* type, bool cnst, bool vltl, - BNReferenceType refType); - BINARYNINJACOREAPI BNType* BNCreatePointerTypeOfWidth(size_t width, BNType* type, bool cnst, bool vltl, - BNReferenceType refType); - BINARYNINJACOREAPI BNType* BNCreateArrayType(BNType* type, uint64_t elem); - BINARYNINJACOREAPI BNType* BNCreateFunctionType(BNType* returnValue, BNCallingConvention* callingConvention, - BNNameAndType* params, size_t paramCount, bool varArg); + BINARYNINJACOREAPI BNType* BNCreatePointerType(BNArchitecture* arch, BNTypeWithConfidence* type, + BNBoolWithConfidence* cnst, BNBoolWithConfidence* vltl, BNReferenceType refType); + BINARYNINJACOREAPI BNType* BNCreatePointerTypeOfWidth(size_t width, BNTypeWithConfidence* type, + BNBoolWithConfidence* cnst, BNBoolWithConfidence* vltl, BNReferenceType refType); + BINARYNINJACOREAPI BNType* BNCreateArrayType(BNTypeWithConfidence* type, uint64_t elem); + BINARYNINJACOREAPI BNType* BNCreateFunctionType(BNTypeWithConfidence* returnValue, + BNCallingConventionWithConfidence* callingConvention, BNNameAndType* params, + size_t paramCount, bool varArg); BINARYNINJACOREAPI BNType* BNNewTypeReference(BNType* type); BINARYNINJACOREAPI BNType* BNDuplicateType(BNType* type); BINARYNINJACOREAPI char* BNGetTypeAndName(BNType* type, BNQualifiedName* name); @@ -2472,27 +2513,27 @@ extern "C" BINARYNINJACOREAPI BNTypeClass BNGetTypeClass(BNType* type); BINARYNINJACOREAPI uint64_t BNGetTypeWidth(BNType* type); BINARYNINJACOREAPI size_t BNGetTypeAlignment(BNType* type); - BINARYNINJACOREAPI bool BNIsTypeSigned(BNType* type); - BINARYNINJACOREAPI bool BNIsTypeConst(BNType* type); - BINARYNINJACOREAPI bool BNIsTypeVolatile(BNType* type); + BINARYNINJACOREAPI BNBoolWithConfidence BNIsTypeSigned(BNType* type); + BINARYNINJACOREAPI BNBoolWithConfidence BNIsTypeConst(BNType* type); + BINARYNINJACOREAPI BNBoolWithConfidence BNIsTypeVolatile(BNType* type); BINARYNINJACOREAPI bool BNIsTypeFloatingPoint(BNType* type); - BINARYNINJACOREAPI BNType* BNGetChildType(BNType* type); - BINARYNINJACOREAPI BNCallingConvention* BNGetTypeCallingConvention(BNType* type); + BINARYNINJACOREAPI BNTypeWithConfidence BNGetChildType(BNType* type); + BINARYNINJACOREAPI BNCallingConventionWithConfidence BNGetTypeCallingConvention(BNType* type); BINARYNINJACOREAPI BNNameAndType* BNGetTypeParameters(BNType* type, size_t* count); BINARYNINJACOREAPI void BNFreeTypeParameterList(BNNameAndType* types, size_t count); BINARYNINJACOREAPI bool BNTypeHasVariableArguments(BNType* type); - BINARYNINJACOREAPI bool BNFunctionTypeCanReturn(BNType* type); + BINARYNINJACOREAPI BNBoolWithConfidence BNFunctionTypeCanReturn(BNType* type); BINARYNINJACOREAPI BNStructure* BNGetTypeStructure(BNType* type); BINARYNINJACOREAPI BNEnumeration* BNGetTypeEnumeration(BNType* type); BINARYNINJACOREAPI BNNamedTypeReference* BNGetTypeNamedTypeReference(BNType* type); BINARYNINJACOREAPI uint64_t BNGetTypeElementCount(BNType* type); - BINARYNINJACOREAPI void BNSetFunctionCanReturn(BNType* type, bool canReturn); - BINARYNINJACOREAPI BNMemberScope BNTypeGetMemberScope(BNType* type); - BINARYNINJACOREAPI void BNTypeSetMemberScope(BNType* type, BNMemberScope scope); - BINARYNINJACOREAPI BNMemberAccess BNTypeGetMemberAccess(BNType* type); - BINARYNINJACOREAPI void BNTypeSetMemberAccess(BNType* type, BNMemberAccess access); - BINARYNINJACOREAPI void BNTypeSetConst(BNType* type, bool cnst); - BINARYNINJACOREAPI void BNTypeSetVolatile(BNType* type, bool vltl); + BINARYNINJACOREAPI void BNSetFunctionCanReturn(BNType* type, BNBoolWithConfidence* canReturn); + BINARYNINJACOREAPI BNMemberScopeWithConfidence BNTypeGetMemberScope(BNType* type); + BINARYNINJACOREAPI void BNTypeSetMemberScope(BNType* type, BNMemberScopeWithConfidence* scope); + BINARYNINJACOREAPI BNMemberAccessWithConfidence BNTypeGetMemberAccess(BNType* type); + BINARYNINJACOREAPI void BNTypeSetMemberAccess(BNType* type, BNMemberAccessWithConfidence* access); + BINARYNINJACOREAPI void BNTypeSetConst(BNType* type, BNBoolWithConfidence* cnst); + BINARYNINJACOREAPI void BNTypeSetVolatile(BNType* type, BNBoolWithConfidence* vltl); BINARYNINJACOREAPI char* BNGetTypeString(BNType* type); BINARYNINJACOREAPI char* BNGetTypeStringBeforeName(BNType* type); @@ -2533,10 +2574,12 @@ extern "C" BINARYNINJACOREAPI void BNSetStructureType(BNStructure* s, BNStructureType type); BINARYNINJACOREAPI BNStructureType BNGetStructureType(BNStructure* s); - BINARYNINJACOREAPI void BNAddStructureMember(BNStructure* s, BNType* type, const char* name); - BINARYNINJACOREAPI void BNAddStructureMemberAtOffset(BNStructure* s, BNType* type, const char* name, uint64_t offset); + BINARYNINJACOREAPI void BNAddStructureMember(BNStructure* s, BNTypeWithConfidence* type, const char* name); + BINARYNINJACOREAPI void BNAddStructureMemberAtOffset(BNStructure* s, BNTypeWithConfidence* type, + const char* name, uint64_t offset); BINARYNINJACOREAPI void BNRemoveStructureMember(BNStructure* s, size_t idx); - BINARYNINJACOREAPI void BNReplaceStructureMember(BNStructure* s, size_t idx, BNType* type, const char* name); + BINARYNINJACOREAPI void BNReplaceStructureMember(BNStructure* s, size_t idx, BNTypeWithConfidence* type, + const char* name); BINARYNINJACOREAPI BNEnumeration* BNCreateEnumeration(void); BINARYNINJACOREAPI BNEnumeration* BNNewEnumerationReference(BNEnumeration* e); -- cgit v1.3.1 From 35c65d909d1ec36a4a1bad7404c9f986e259f662 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Fri, 14 Jul 2017 01:05:18 -0400 Subject: Adding API to get type of MLIL expression --- binaryninjaapi.h | 2 ++ binaryninjacore.h | 2 ++ mediumlevelil.cpp | 9 +++++++++ python/callingconvention.py | 2 +- python/function.py | 4 ++-- python/mediumlevelil.py | 9 +++++++++ python/types.py | 12 ++++++------ 7 files changed, 31 insertions(+), 9 deletions(-) (limited to 'binaryninjacore.h') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 2341e39f..f079e7c0 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2550,6 +2550,8 @@ namespace BinaryNinja Ref GetLowLevelIL() const; size_t GetLowLevelILInstructionIndex(size_t instr) const; size_t GetLowLevelILExprIndex(size_t expr) const; + + Confidence> GetExprType(size_t expr); }; class FunctionRecognizer diff --git a/binaryninjacore.h b/binaryninjacore.h index f5b89437..0414b512 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -2488,6 +2488,8 @@ extern "C" BINARYNINJACOREAPI size_t BNGetLowLevelILInstructionIndex(BNMediumLevelILFunction* func, size_t instr); BINARYNINJACOREAPI size_t BNGetLowLevelILExprIndex(BNMediumLevelILFunction* func, size_t expr); + BINARYNINJACOREAPI BNTypeWithConfidence BNGetMediumLevelILExprType(BNMediumLevelILFunction* func, size_t expr); + // Types BINARYNINJACOREAPI BNType* BNCreateVoidType(void); BINARYNINJACOREAPI BNType* BNCreateBoolType(void); diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index 8bbb2746..df78de2d 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -494,3 +494,12 @@ size_t MediumLevelILFunction::GetLowLevelILExprIndex(size_t expr) const { return BNGetLowLevelILExprIndex(m_object, expr); } + + +Confidence> MediumLevelILFunction::GetExprType(size_t expr) +{ + BNTypeWithConfidence result = BNGetMediumLevelILExprType(m_object, expr); + if (!result.type) + return nullptr; + return Confidence>(new Type(result.type), result.confidence); +} diff --git a/python/callingconvention.py b/python/callingconvention.py index e6aa323c..db473c53 100644 --- a/python/callingconvention.py +++ b/python/callingconvention.py @@ -41,7 +41,7 @@ class CallingConvention(object): _registered_calling_conventions = [] - def __init__(self, arch, handle = None, confidence = types.Type.max_confidence): + def __init__(self, arch, handle = None, confidence = types.max_confidence): if handle is None: self.arch = arch self._pending_reg_lists = {} diff --git a/python/function.py b/python/function.py index 3cd5396f..aa0d05eb 100644 --- a/python/function.py +++ b/python/function.py @@ -185,7 +185,7 @@ class Variable(object): if var_type is None: var_type_conf = core.BNGetVariableType(func.handle, var) if var_type_conf.type: - var_type = types.Type(var_type, confidence = var_type_conf.confidence) + var_type = types.Type(var_type_conf.type, confidence = var_type_conf.confidence) else: var_type = None @@ -1401,7 +1401,7 @@ class InstructionTextToken(object): """ def __init__(self, token_type, text, value = 0, size = 0, operand = 0xffffffff, - context = InstructionTextTokenContext.NoTokenContext, address = 0, confidence = types.Type.max_confidence): + context = InstructionTextTokenContext.NoTokenContext, address = 0, confidence = types.max_confidence): self.type = InstructionTextTokenType(token_type) self.text = text self.value = value diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 275746cc..76a85a86 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -26,6 +26,7 @@ from .enums import MediumLevelILOperation, InstructionTextTokenType, ILBranchDep import function import basicblock import lowlevelil +import types class SSAVariable(object): @@ -397,6 +398,14 @@ class MediumLevelILInstruction(object): result += operand.vars_read return result + @property + def expr_type(self): + """Type of expression""" + result = core.BNGetMediumLevelILExprType(self.function.handle, self.expr_index) + if result.type: + return types.Type(result.type, confidence = result.confidence) + return None + def get_ssa_var_possible_values(self, ssa_var): var_data = core.BNVariable() var_data.type = ssa_var.var.source_type diff --git a/python/types.py b/python/types.py index c3d7156e..5933661a 100644 --- a/python/types.py +++ b/python/types.py @@ -18,6 +18,8 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. +max_confidence = 255 + import ctypes # Binary Ninja components @@ -198,8 +200,6 @@ class Symbol(object): class Type(object): - max_confidence = 255 - def __init__(self, handle, confidence = max_confidence): self.handle = handle self.confidence = confidence @@ -336,8 +336,8 @@ class Type(object): return core.BNGetTypeString(self.handle) def __repr__(self): - if self.confidence < Type.max_confidence: - return "" % (str(self), (self.confidence * 100) / Type.max_confidence) + if self.confidence < max_confidence: + return "" % (str(self), (self.confidence * 100) / max_confidence) return "" % str(self) def get_string_before_name(self): @@ -560,7 +560,7 @@ class Type(object): class BoolWithConfidence(object): - def __init__(self, value, confidence = Type.max_confidence): + def __init__(self, value, confidence = max_confidence): self.value = value self.confidence = confidence @@ -578,7 +578,7 @@ class BoolWithConfidence(object): class ReferenceTypeWithConfidence(object): - def __init__(self, value, confidence = Type.max_confidence): + def __init__(self, value, confidence = max_confidence): self.value = value self.confidence = confidence -- cgit v1.3.1 From 18083837fe452a91e457f02ed8be2abf5fc66877 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Fri, 14 Jul 2017 18:49:26 -0400 Subject: Add API to get list of all definitions or uses of a variable --- binaryninjaapi.h | 3 +++ binaryninjacore.h | 5 +++++ mediumlevelil.cpp | 28 ++++++++++++++++++++++++++++ python/mediumlevelil.py | 26 ++++++++++++++++++++++++++ 4 files changed, 62 insertions(+) (limited to 'binaryninjacore.h') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index f079e7c0..20752370 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2520,6 +2520,9 @@ namespace BinaryNinja std::set GetSSAVarUses(const Variable& var, size_t version) const; std::set GetSSAMemoryUses(size_t version) const; + std::set GetVariableDefinitions(const Variable& var) const; + std::set GetVariableUses(const Variable& var) const; + RegisterValue GetSSAVarValue(const Variable& var, size_t version); RegisterValue GetExprValue(size_t expr); PossibleValueSet GetPossibleSSAVarValues(const Variable& var, size_t version, size_t instr); diff --git a/binaryninjacore.h b/binaryninjacore.h index 0414b512..e601cd1c 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -2435,6 +2435,11 @@ extern "C" BINARYNINJACOREAPI size_t* BNGetMediumLevelILSSAMemoryUses(BNMediumLevelILFunction* func, size_t version, size_t* count); + BINARYNINJACOREAPI size_t* BNGetMediumLevelILVariableDefinitions(BNMediumLevelILFunction* func, + const BNVariable* var, size_t* count); + BINARYNINJACOREAPI size_t* BNGetMediumLevelILVariableUses(BNMediumLevelILFunction* func, + const BNVariable* var, size_t* count); + BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILSSAVarValue(BNMediumLevelILFunction* func, const BNVariable* var, size_t version); BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILExprValue(BNMediumLevelILFunction* func, size_t expr); diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index df78de2d..b4abaa72 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -313,6 +313,34 @@ set MediumLevelILFunction::GetSSAMemoryUses(size_t version) const } +set MediumLevelILFunction::GetVariableDefinitions(const Variable& var) const +{ + size_t count; + size_t* instrs = BNGetMediumLevelILVariableDefinitions(m_object, &var, &count); + + set result; + for (size_t i = 0; i < count; i++) + result.insert(instrs[i]); + + BNFreeILInstructionList(instrs); + return result; +} + + +set MediumLevelILFunction::GetVariableUses(const Variable& var) const +{ + size_t count; + size_t* instrs = BNGetMediumLevelILVariableUses(m_object, &var, &count); + + set result; + for (size_t i = 0; i < count; i++) + result.insert(instrs[i]); + + BNFreeILInstructionList(instrs); + return result; +} + + RegisterValue MediumLevelILFunction::GetSSAVarValue(const Variable& var, size_t version) { BNRegisterValue value = BNGetMediumLevelILSSAVarValue(m_object, &var, version); diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 76a85a86..8a8d8d0b 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -793,6 +793,32 @@ class MediumLevelILFunction(object): core.BNFreeILInstructionList(instrs) return result + def get_var_definitions(self, var): + count = ctypes.c_ulonglong() + var_data = core.BNVariable() + var_data.type = var.source_type + var_data.index = var.index + var_data.storage = var.storage + instrs = core.BNGetMediumLevelILVariableDefinitions(self.handle, var_data, count) + result = [] + for i in xrange(0, count.value): + result.append(instrs[i]) + core.BNFreeILInstructionList(instrs) + return result + + def get_var_uses(self, var): + count = ctypes.c_ulonglong() + var_data = core.BNVariable() + var_data.type = var.source_type + var_data.index = var.index + var_data.storage = var.storage + instrs = core.BNGetMediumLevelILVariableUses(self.handle, var_data, count) + result = [] + for i in xrange(0, count.value): + result.append(instrs[i]) + core.BNFreeILInstructionList(instrs) + return result + def get_ssa_var_value(self, ssa_var): var_data = core.BNVariable() var_data.type = ssa_var.var.source_type -- cgit v1.3.1 From bf9d72bbae638a42f0b93a9053dffcb1f5e79ff3 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Tue, 18 Jul 2017 00:20:01 -0400 Subject: Add instruction for indirect structure access --- binaryninjaapi.h | 1 + binaryninjacore.h | 5 +++++ python/mediumlevelil.py | 4 ++++ python/types.py | 5 +++++ type.cpp | 6 ++++++ 5 files changed, 21 insertions(+) (limited to 'binaryninjacore.h') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 20752370..4f46cd44 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1842,6 +1842,7 @@ namespace BinaryNinja void SetTypeName(const QualifiedName& name); uint64_t GetElementCount() const; + uint64_t GetOffset() const; void SetFunctionCanReturn(const Confidence& canReturn); diff --git a/binaryninjacore.h b/binaryninjacore.h index e601cd1c..2b758a94 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -726,7 +726,9 @@ extern "C" MLIL_SET_VAR_FIELD, // Not valid in SSA form (see MLIL_SET_VAR_FIELD) MLIL_SET_VAR_SPLIT, // Not valid in SSA form (see MLIL_SET_VAR_SPLIT_SSA) MLIL_LOAD, // Not valid in SSA form (see MLIL_LOAD_SSA) + MLIL_LOAD_STRUCT, // Not valid in SSA form (see MLIL_LOAD_STRUCT_SSA) MLIL_STORE, // Not valid in SSA form (see MLIL_STORE_SSA) + MLIL_STORE_STRUCT, // Not valid in SSA form (see MLIL_STORE_STRUCT_SSA) MLIL_VAR, // Not valid in SSA form (see MLIL_VAR_SSA) MLIL_VAR_FIELD, // Not valid in SSA form (see MLIL_VAR_SSA_FIELD) MLIL_ADDRESS_OF, @@ -811,7 +813,9 @@ extern "C" MLIL_CALL_PARAM_SSA, // Only valid within the MLIL_CALL_SSA, MLIL_SYSCALL_SSA family instructions MLIL_CALL_OUTPUT_SSA, // Only valid within the MLIL_CALL_SSA or MLIL_SYSCALL_SSA family instructions MLIL_LOAD_SSA, + MLIL_LOAD_STRUCT_SSA, MLIL_STORE_SSA, + MLIL_STORE_STRUCT_SSA, MLIL_VAR_PHI, MLIL_MEM_PHI }; @@ -2534,6 +2538,7 @@ extern "C" BINARYNINJACOREAPI BNEnumeration* BNGetTypeEnumeration(BNType* type); BINARYNINJACOREAPI BNNamedTypeReference* BNGetTypeNamedTypeReference(BNType* type); BINARYNINJACOREAPI uint64_t BNGetTypeElementCount(BNType* type); + BINARYNINJACOREAPI uint64_t BNGetTypeOffset(BNType* type); BINARYNINJACOREAPI void BNSetFunctionCanReturn(BNType* type, BNBoolWithConfidence* canReturn); BINARYNINJACOREAPI BNMemberScopeWithConfidence BNTypeGetMemberScope(BNType* type); BINARYNINJACOREAPI void BNTypeSetMemberScope(BNType* type, BNMemberScopeWithConfidence* scope); diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 8a8d8d0b..ba83f7aa 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -71,7 +71,9 @@ class MediumLevelILInstruction(object): MediumLevelILOperation.MLIL_SET_VAR_FIELD: [("dest", "var"), ("offset", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_SPLIT: [("high", "var"), ("low", "var"), ("src", "expr")], MediumLevelILOperation.MLIL_LOAD: [("src", "expr")], + MediumLevelILOperation.MLIL_LOAD_STRUCT: [("src", "expr"), ("offset", "int")], MediumLevelILOperation.MLIL_STORE: [("dest", "expr"), ("src", "expr")], + MediumLevelILOperation.MLIL_STORE_STRUCT: [("dest", "expr"), ("offset", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_VAR: [("src", "var")], MediumLevelILOperation.MLIL_VAR_FIELD: [("src", "var"), ("offset", "int")], MediumLevelILOperation.MLIL_ADDRESS_OF: [("src", "var")], @@ -154,7 +156,9 @@ class MediumLevelILInstruction(object): MediumLevelILOperation.MLIL_CALL_OUTPUT_SSA: [("dest_memory", "int"), ("dest", "var_ssa_list")], MediumLevelILOperation.MLIL_CALL_PARAM_SSA: [("src_memory", "int"), ("src", "var_ssa_list")], MediumLevelILOperation.MLIL_LOAD_SSA: [("src", "expr"), ("src_memory", "int")], + MediumLevelILOperation.MLIL_LOAD_STRUCT_SSA: [("src", "expr"), ("offset", "int"), ("src_memory", "int")], MediumLevelILOperation.MLIL_STORE_SSA: [("dest", "expr"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")], + MediumLevelILOperation.MLIL_STORE_STRUCT_SSA: [("dest", "expr"), ("offset", "int"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_VAR_PHI: [("dest", "var_ssa"), ("src", "var_ssa_list")], MediumLevelILOperation.MLIL_MEM_PHI: [("dest_memory", "int"), ("src_memory", "int_list")] } diff --git a/python/types.py b/python/types.py index 5933661a..ab3fb337 100644 --- a/python/types.py +++ b/python/types.py @@ -332,6 +332,11 @@ class Type(object): """Type count (read-only)""" return core.BNGetTypeElementCount(self.handle) + @property + def offset(self): + """Offset into structure (read-only)""" + return core.BNGetTypeOffset(self.handle) + def __str__(self): return core.BNGetTypeString(self.handle) diff --git a/type.cpp b/type.cpp index 837b212d..19624cdd 100644 --- a/type.cpp +++ b/type.cpp @@ -414,6 +414,12 @@ uint64_t Type::GetElementCount() const } +uint64_t Type::GetOffset() const +{ + return BNGetTypeOffset(m_object); +} + + string Type::GetString() const { char* str = BNGetTypeString(m_object); -- cgit v1.3.1 From 23091d4734fede77b4da90bc14d5ba2e49b33fc2 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Fri, 21 Jul 2017 16:26:38 -0400 Subject: Provide options for controlling the display of variable types --- binaryninjacore.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'binaryninjacore.h') diff --git a/binaryninjacore.h b/binaryninjacore.h index 2b758a94..9bca447d 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -416,6 +416,9 @@ extern "C" ShowAddress = 0, ShowOpcode = 1, ExpandLongOpcode = 2, + ShowVariablesAtTopOfGraph = 3, + ShowVariableTypesWhenAssigned = 4, + ShowDefaultRegisterTypes = 5, // Linear disassembly options GroupLinearDisassemblyFunctions = 64, -- cgit v1.3.1 From 111add984b0a517966f133ae69c51d2084dee985 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Mon, 24 Jul 2017 20:10:18 -0400 Subject: Adding size of stack var refs, source operand in MLIL --- binaryninjaapi.h | 1 + binaryninjacore.h | 2 ++ function.cpp | 1 + python/function.py | 5 +++-- python/mediumlevelil.py | 1 + 5 files changed, 8 insertions(+), 2 deletions(-) (limited to 'binaryninjacore.h') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 4f46cd44..83d12d21 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2062,6 +2062,7 @@ namespace BinaryNinja std::string name; Variable var; int64_t referencedOffset; + size_t size; }; struct IndirectBranchInfo diff --git a/binaryninjacore.h b/binaryninjacore.h index 9bca447d..01c78ff4 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -826,6 +826,7 @@ extern "C" struct BNMediumLevelILInstruction { BNMediumLevelILOperation operation; + uint32_t sourceOperand; size_t size; uint64_t operands[5]; uint64_t address; @@ -1253,6 +1254,7 @@ extern "C" char* name; uint64_t varIdentifier; int64_t referencedOffset; + size_t size; }; struct BNIndirectBranchInfo diff --git a/function.cpp b/function.cpp index 0e1fa5cf..66b2aade 100644 --- a/function.cpp +++ b/function.cpp @@ -358,6 +358,7 @@ vector Function::GetStackVariablesReferencedByInstructio ref.name = refs[i].name; ref.var = Variable::FromIdentifier(refs[i].varIdentifier); ref.referencedOffset = refs[i].referencedOffset; + ref.size = refs[i].size; result.push_back(ref); } diff --git a/python/function.py b/python/function.py index aa0d05eb..c3310b6c 100644 --- a/python/function.py +++ b/python/function.py @@ -148,12 +148,13 @@ class PossibleValueSet(object): class StackVariableReference(object): - def __init__(self, src_operand, t, name, var, ref_ofs): + def __init__(self, src_operand, t, name, var, ref_ofs, size): self.source_operand = src_operand self.type = t self.name = name self.var = var self.referenced_offset = ref_ofs + self.size = size if self.source_operand == 0xffffffff: self.source_operand = None @@ -621,7 +622,7 @@ class Function(object): var_type = types.Type(core.BNNewTypeReference(refs[i].type), confidence = refs[i].typeConfidence) result.append(StackVariableReference(refs[i].sourceOperand, var_type, refs[i].name, Variable.from_identifier(self, refs[i].varIdentifier, refs[i].name, var_type), - refs[i].referencedOffset)) + refs[i].referencedOffset, refs[i].size)) core.BNFreeStackVariableReferenceList(refs, count.value) return result diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index ba83f7aa..3377ab6a 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -174,6 +174,7 @@ class MediumLevelILInstruction(object): self.operation = MediumLevelILOperation(instr.operation) self.size = instr.size self.address = instr.address + self.source_operand = instr.sourceOperand operands = MediumLevelILInstruction.ILOperations[instr.operation] self.operands = [] i = 0 -- cgit v1.3.1 From 24b090492a216278fbc0e43e8f01cec13fa59696 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Tue, 25 Jul 2017 20:20:24 -0400 Subject: Add mappings from LLIL to normal MLIL --- binaryninjaapi.h | 2 ++ binaryninjacore.h | 2 ++ lowlevelil.cpp | 12 ++++++++++++ python/lowlevelil.py | 28 +++++++++++++++++++++++++++- 4 files changed, 43 insertions(+), 1 deletion(-) (limited to 'binaryninjacore.h') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 83d12d21..d69fec0d 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2464,6 +2464,8 @@ namespace BinaryNinja Ref GetMediumLevelIL() const; Ref GetMappedMediumLevelIL() const; + size_t GetMediumLevelILInstructionIndex(size_t instr) const; + size_t GetMediumLevelILExprIndex(size_t expr) const; size_t GetMappedMediumLevelILInstructionIndex(size_t instr) const; size_t GetMappedMediumLevelILExprIndex(size_t expr) const; }; diff --git a/binaryninjacore.h b/binaryninjacore.h index 01c78ff4..bcd5fbbf 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -2386,6 +2386,8 @@ extern "C" BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetMediumLevelILForLowLevelIL(BNLowLevelILFunction* func); BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetMappedMediumLevelIL(BNLowLevelILFunction* func); + BINARYNINJACOREAPI size_t BNGetMediumLevelILInstructionIndex(BNLowLevelILFunction* func, size_t instr); + BINARYNINJACOREAPI size_t BNGetMediumLevelILExprIndex(BNLowLevelILFunction* func, size_t expr); BINARYNINJACOREAPI size_t BNGetMappedMediumLevelILInstructionIndex(BNLowLevelILFunction* func, size_t instr); BINARYNINJACOREAPI size_t BNGetMappedMediumLevelILExprIndex(BNLowLevelILFunction* func, size_t expr); diff --git a/lowlevelil.cpp b/lowlevelil.cpp index 4ff16a05..0cb733ac 100644 --- a/lowlevelil.cpp +++ b/lowlevelil.cpp @@ -955,6 +955,18 @@ Ref LowLevelILFunction::GetMappedMediumLevelIL() const } +size_t LowLevelILFunction::GetMediumLevelILInstructionIndex(size_t instr) const +{ + return BNGetMediumLevelILInstructionIndex(m_object, instr); +} + + +size_t LowLevelILFunction::GetMediumLevelILExprIndex(size_t expr) const +{ + return BNGetMediumLevelILExprIndex(m_object, expr); +} + + size_t LowLevelILFunction::GetMappedMediumLevelILInstructionIndex(size_t instr) const { return BNGetMappedMediumLevelILInstructionIndex(m_object, instr); diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 62e33a75..08ca04e6 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -327,9 +327,17 @@ class LowLevelILInstruction(object): return LowLevelILInstruction(self.function.non_ssa_form, core.BNGetLowLevelILNonSSAExprIndex(self.function.handle, self.expr_index)) + @property + def medium_level_il(self): + """Gets the medium level IL expression corresponding to this expression (may be None for eliminated instructions)""" + expr = self.function.get_medium_level_il_expr_index(self.expr_index) + if expr is None: + return None + return mediumlevelil.MediumLevelILInstruction(self.function.medium_level_il, expr) + @property def mapped_medium_level_il(self): - """Gets the medium level IL expression corresponding to this expression""" + """Gets the mapped medium level IL expression corresponding to this expression""" expr = self.function.get_mapped_medium_level_il_expr_index(self.expr_index) if expr is None: return None @@ -1652,6 +1660,24 @@ class LowLevelILFunction(object): result = function.RegisterValue(self.arch, value) return result + def get_medium_level_il_instruction_index(self, instr): + med_il = self.medium_level_il + if med_il is None: + return None + result = core.BNGetMediumLevelILInstructionIndex(self.handle, instr) + if result >= core.BNGetMediumLevelILInstructionCount(med_il.handle): + return None + return result + + def get_medium_level_il_expr_index(self, expr): + med_il = self.medium_level_il + if med_il is None: + return None + result = core.BNGetMediumLevelILExprIndex(self.handle, expr) + if result >= core.BNGetMediumLevelILExprCount(med_il.handle): + return None + return result + def get_mapped_medium_level_il_instruction_index(self, instr): med_il = self.mapped_medium_level_il if med_il is None: -- cgit v1.3.1