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 --- python/function.py | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) (limited to 'python/function.py') diff --git a/python/function.py b/python/function.py index 8beebe66..3cd5396f 100644 --- a/python/function.py +++ b/python/function.py @@ -183,9 +183,11 @@ class Variable(object): if name is None: name = core.BNGetVariableName(func.handle, var) if var_type is None: - var_type = core.BNGetVariableType(func.handle, var) - if var_type: - var_type = types.Type(var_type) + var_type_conf = core.BNGetVariableType(func.handle, var) + if var_type_conf.type: + var_type = types.Type(var_type, confidence = var_type_conf.confidence) + else: + var_type = None self.name = name self.type = var_type @@ -390,7 +392,7 @@ class Function(object): result = [] for i in xrange(0, count.value): result.append(Variable(self, v[i].var.type, v[i].var.index, v[i].var.storage, v[i].name, - types.Type(handle = core.BNNewTypeReference(v[i].type)))) + types.Type(handle = core.BNNewTypeReference(v[i].type), confidence = v[i].typeConfidence))) result.sort(key = lambda x: x.identifier) core.BNFreeVariableList(v, count.value) return result @@ -403,7 +405,7 @@ class Function(object): result = [] for i in xrange(0, count.value): result.append(Variable(self, v[i].var.type, v[i].var.index, v[i].var.storage, v[i].name, - types.Type(handle = core.BNNewTypeReference(v[i].type)))) + types.Type(handle = core.BNNewTypeReference(v[i].type), confidence = v[i].typeConfidence))) result.sort(key = lambda x: x.identifier) core.BNFreeVariableList(v, count.value) return result @@ -616,7 +618,7 @@ class Function(object): refs = core.BNGetStackVariablesReferencedByInstruction(self.handle, arch.handle, addr, count) result = [] for i in xrange(0, count.value): - var_type = types.Type(core.BNNewTypeReference(refs[i].type)) + 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)) @@ -730,8 +732,9 @@ class Function(object): size = lines[i].tokens[j].size operand = lines[i].tokens[j].operand context = lines[i].tokens[j].context + confidence = lines[i].tokens[j].confidence address = lines[i].tokens[j].address - tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address)) + tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address, confidence)) result.append(tokens) core.BNFreeInstructionTextLines(lines, count.value) return result @@ -853,10 +856,16 @@ class Function(object): core.BNSetUserInstructionHighlight(self.handle, arch.handle, addr, color._get_core_struct()) def create_auto_stack_var(self, offset, var_type, name): - core.BNCreateAutoStackVariable(self.handle, offset, var_type.handle, name) + tc = core.BNTypeWithConfidence() + tc.type = var_type.handle + tc.confidence = var_type.confidence + core.BNCreateAutoStackVariable(self.handle, offset, tc, name) def create_user_stack_var(self, offset, var_type, name): - core.BNCreateUserStackVariable(self.handle, offset, var_type.handle, name) + tc = core.BNTypeWithConfidence() + tc.type = var_type.handle + tc.confidence = var_type.confidence + core.BNCreateUserStackVariable(self.handle, offset, tc, name) def delete_auto_stack_var(self, offset): core.BNDeleteAutoStackVariable(self.handle, offset) @@ -869,14 +878,20 @@ class Function(object): var_data.type = var.source_type var_data.index = var.index var_data.storage = var.storage - core.BNCreateAutoVariable(self.handle, var_data, var_type.handle, name, ignore_disjoint_uses) + tc = core.BNTypeWithConfidence() + tc.type = var_type.handle + tc.confidence = var_type.confidence + core.BNCreateAutoVariable(self.handle, var_data, tc, name, ignore_disjoint_uses) def create_user_var(self, var, var_type, name, ignore_disjoint_uses = False): var_data = core.BNVariable() var_data.type = var.source_type var_data.index = var.index var_data.storage = var.storage - core.BNCreateUserVariable(self.handle, var_data, var_type.handle, name, ignore_disjoint_uses) + tc = core.BNTypeWithConfidence() + tc.type = var_type.handle + tc.confidence = var_type.confidence + core.BNCreateUserVariable(self.handle, var_data, tc, name, ignore_disjoint_uses) def delete_auto_var(self, var): var_data = core.BNVariable() @@ -899,7 +914,7 @@ class Function(object): if not core.BNGetStackVariableAtFrameOffset(self.handle, arch.handle, addr, offset, found_var): return None result = Variable(self, found_var.var.type, found_var.var.index, found_var.var.storage, - found_var.name, types.Type(handle = core.BNNewTypeReference(found_var.type))) + found_var.name, types.Type(handle = core.BNNewTypeReference(found_var.type), confidence = found_var.typeConfidence)) core.BNFreeVariableNameAndType(found_var) return result @@ -1043,8 +1058,9 @@ class FunctionGraphBlock(object): size = lines[i].tokens[j].size operand = lines[i].tokens[j].operand context = lines[i].tokens[j].context + confidence = lines[i].tokens[j].confidence address = lines[i].tokens[j].address - tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address)) + tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address, confidence)) result.append(DisassemblyTextLine(addr, tokens)) core.BNFreeDisassemblyTextLines(lines, count.value) return result @@ -1101,8 +1117,9 @@ class FunctionGraphBlock(object): size = lines[i].tokens[j].size operand = lines[i].tokens[j].operand context = lines[i].tokens[j].context + confidence = lines[i].tokens[j].confidence address = lines[i].tokens[j].address - tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address)) + tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address, confidence)) yield DisassemblyTextLine(addr, tokens) finally: core.BNFreeDisassemblyTextLines(lines, count.value) @@ -1384,13 +1401,14 @@ class InstructionTextToken(object): """ def __init__(self, token_type, text, value = 0, size = 0, operand = 0xffffffff, - context = InstructionTextTokenContext.NoTokenContext, address = 0): + context = InstructionTextTokenContext.NoTokenContext, address = 0, confidence = types.Type.max_confidence): self.type = InstructionTextTokenType(token_type) self.text = text self.value = value self.size = size self.operand = operand self.context = InstructionTextTokenContext(context) + self.confidence = confidence self.address = address def __str__(self): -- 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 'python/function.py') 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 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 'python/function.py') 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