From 94b38cee51eff16f1e79945806088c7ae60016d7 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Wed, 1 Mar 2017 03:45:51 -0500 Subject: Adding framework for medium level IL --- python/mediumlevelil.py | 525 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 525 insertions(+) create mode 100644 python/mediumlevelil.py (limited to 'python/mediumlevelil.py') diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py new file mode 100644 index 00000000..c4c4aa23 --- /dev/null +++ b/python/mediumlevelil.py @@ -0,0 +1,525 @@ +# Copyright (c) 2017 Vector 35 LLC +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +import ctypes + +# Binary Ninja components +import _binaryninjacore as core +from .enums import MediumLevelILOperation, InstructionTextTokenType, ILVariableSourceType +import function +import basicblock + + +class MediumLevelILLabel(object): + def __init__(self, handle = None): + if handle is None: + self.handle = (core.BNMediumLevelILLabel * 1)() + core.BNMediumLevelILInitLabel(self.handle) + else: + self.handle = handle + + +class MediumLevelILInstruction(object): + """ + ``class MediumLevelILInstruction`` Medium Level Intermediate Language Instructions are infinite length tree-based + instructions. Tree-based instructions use infix notation with the left hand operand being the destination operand. + Infix notation is thus more natural to read than other notations (e.g. x86 ``mov eax, 0`` vs. MLIL ``eax = 0``). + """ + + ILOperations = { + MediumLevelILOperation.MLIL_NOP: [], + MediumLevelILOperation.MLIL_SET_VAR: [("dest", "var"), ("src", "expr")], + MediumLevelILOperation.MLIL_SET_VAR_FIELD: [("dest", "var"), ("offset", "int"), ("src", "expr")], + MediumLevelILOperation.MLIL_LOAD: [("src", "expr")], + MediumLevelILOperation.MLIL_STORE: [("dest", "expr"), ("src", "expr")], + MediumLevelILOperation.MLIL_VAR: [("src", "var")], + MediumLevelILOperation.MLIL_VAR_FIELD: [("src", "var"), ("offset", "int")], + MediumLevelILOperation.MLIL_CONST: [("constant", "int")], + MediumLevelILOperation.MLIL_ADD: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_ADC: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_SUB: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_SBB: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_AND: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_OR: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_XOR: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_LSL: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_LSR: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_ASR: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_ROL: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_RLC: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_ROR: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_RRC: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_MUL: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_MULU_DP: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_MULS_DP: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_DIVU: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_DIVU_DP: [("hi", "expr"), ("lo", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_DIVS: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_DIVS_DP: [("hi", "expr"), ("lo", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_MODU: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_MODU_DP: [("hi", "expr"), ("lo", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_MODS: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_MODS_DP: [("hi", "expr"), ("lo", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_NEG: [("src", "expr")], + MediumLevelILOperation.MLIL_NOT: [("src", "expr")], + MediumLevelILOperation.MLIL_SX: [("src", "expr")], + MediumLevelILOperation.MLIL_ZX: [("src", "expr")], + MediumLevelILOperation.MLIL_JUMP: [("dest", "expr")], + MediumLevelILOperation.MLIL_JUMP_TO: [("dest", "expr"), ("targets", "int_list")], + MediumLevelILOperation.MLIL_CALL: [("dest", "expr")], + MediumLevelILOperation.MLIL_RET: [], + MediumLevelILOperation.MLIL_NORET: [], + MediumLevelILOperation.MLIL_IF: [("condition", "expr"), ("true", "int"), ("false", "int")], + MediumLevelILOperation.MLIL_GOTO: [("dest", "int")], + MediumLevelILOperation.MLIL_CMP_E: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_NE: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_SLT: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_ULT: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_SLE: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_ULE: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_SGE: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_UGE: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_SGT: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_CMP_UGT: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_TEST_BIT: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_BOOL_TO_INT: [("src", "expr")], + MediumLevelILOperation.MLIL_SYSCALL: [], + MediumLevelILOperation.MLIL_BP: [], + MediumLevelILOperation.MLIL_TRAP: [("vector", "int")], + MediumLevelILOperation.MLIL_UNDEF: [], + MediumLevelILOperation.MLIL_UNIMPL: [], + MediumLevelILOperation.MLIL_UNIMPL_MEM: [("src", "expr")], + MediumLevelILOperation.MLIL_SET_VAR_SSA: [("dest", "var"), ("index", "int"), ("src", "expr")], + MediumLevelILOperation.MLIL_SET_VAR_SSA_FIELD: [("dest", "var"), ("index", "int"), ("offset", "int"), ("src", "expr")], + MediumLevelILOperation.MLIL_VAR_SSA: [("src", "var"), ("index", "int")], + MediumLevelILOperation.MLIL_VAR_SSA_FIELD: [("src", "var"), ("index", "int"), ("offset", "int")], + MediumLevelILOperation.MLIL_CALL_SSA: [("output", "expr"), ("dest", "expr"), ("param", "expr")], + MediumLevelILOperation.MLIL_SYSCALL_SSA: [("output", "expr"), ("param", "expr")], + MediumLevelILOperation.MLIL_CALL_OUTPUT_SSA: [("dest_memory", "int"), ("dest", "var_ssa_list")], + MediumLevelILOperation.MLIL_CALL_PARAM_SSA: [("src", "var_ssa_list")], + MediumLevelILOperation.MLIL_LOAD_SSA: [("src", "expr"), ("src_memory", "int")], + MediumLevelILOperation.MLIL_STORE_SSA: [("dest", "expr"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")], + MediumLevelILOperation.MLIL_VAR_PHI: [("dest", "var"), ("index", "int"), ("src", "var_ssa_list")], + MediumLevelILOperation.MLIL_MEM_PHI: [("dest_memory", "int"), ("src_memory", "int_list")] + } + + def __init__(self, func, expr_index, instr_index=None): + instr = core.BNGetMediumLevelILByIndex(func.handle, expr_index) + self.function = func + self.expr_index = expr_index + self.instr_index = instr_index + self.operation = MediumLevelILOperation(instr.operation) + self.size = instr.size + self.address = instr.address + operands = MediumLevelILInstruction.ILOperations[instr.operation] + self.operands = [] + i = 0 + while i < len(operands): + name, operand_type = operands[i] + if operand_type == "int": + value = instr.operands[i] + elif operand_type == "expr": + value = MediumLevelILInstruction(func, instr.operands[i]) + elif operand_type == "var": + var_type = ILVariableSourceType(instr.operands[i] >> 32) + index = instr.operands[i] & 0xffffffff + identifier = instr.operands[i + 1] + i += 1 + value = function.ILVariable(self.function, var_type, index, identifier) + elif operand_type == "int_list": + count = ctypes.c_ulonglong() + operand_list = core.BNMediumLevelILGetOperandList(func.handle, self.expr_index, i, count) + value = [] + for i in xrange(count.value): + value.append(operand_list[i]) + core.BNMediumLevelILFreeOperandList(operand_list) + elif operand_type == "var_ssa_list": + count = ctypes.c_ulonglong() + operand_list = core.BNMediumLevelILGetOperandList(func.handle, self.expr_index, i, count) + i += 1 + value = [] + for j in xrange(count.value / 3): + var_type = ILVariableSourceType(operand_list[j * 3] >> 32) + index = operand_list[j * 3] & 0xffffffff + identifier = operand_list[(j * 3) + 1] + var_index = operand_list[(j * 3) + 2] + value.append((function.ILVariable(self.function, var_type, index, identifier), var_index)) + core.BNMediumLevelILFreeOperandList(operand_list) + self.operands.append(value) + self.__dict__[name] = value + + def __str__(self): + tokens = self.tokens + if tokens is None: + return "invalid" + result = "" + for token in tokens: + result += token.text + return result + + def __repr__(self): + return "" % str(self) + + @property + def tokens(self): + """MLIL tokens (read-only)""" + count = ctypes.c_ulonglong() + tokens = ctypes.POINTER(core.BNInstructionTextToken)() + if (self.instr_index is not None) and (self.function.source_function is not None): + if not core.BNGetMediumLevelILInstructionText(self.function.handle, self.function.source_function.handle, + self.function.arch.handle, self.instr_index, tokens, count): + return None + else: + if not core.BNGetMediumLevelILExprText(self.function.handle, self.function.arch.handle, + self.expr_index, tokens, count): + return None + result = [] + for i in xrange(0, count.value): + token_type = InstructionTextTokenType(tokens[i].type) + text = tokens[i].text + value = tokens[i].value + size = tokens[i].size + operand = tokens[i].operand + context = tokens[i].context + address = tokens[i].address + result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address)) + core.BNFreeInstructionText(tokens, count.value) + return result + + @property + def ssa_form(self): + """SSA form of expression (read-only)""" + return MediumLevelILInstruction(self.function.ssa_form, + core.BNGetMediumLevelILSSAExprIndex(self.function.handle, self.expr_index)) + + @property + def non_ssa_form(self): + """Non-SSA form of expression (read-only)""" + return MediumLevelILInstruction(self.function.non_ssa_form, + core.BNGetMediumLevelILNonSSAExprIndex(self.function.handle, self.expr_index)) + + @property + def value(self): + """Value of expression using static data flow analysis (read-only)""" + value = core.BNGetMediumLevelILExprValue(self.function.handle, self.expr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def __setattr__(self, name, value): + try: + object.__setattr__(self, name, value) + except AttributeError: + raise AttributeError("attribute '%s' is read only" % name) + + +class MediumLevelILExpr(object): + """ + ``class MediumLevelILExpr`` hold the index of IL Expressions. + + .. note:: This class shouldn't be instantiated directly. Rather the helper members of MediumLevelILFunction should be \ + used instead. + """ + def __init__(self, index): + self.index = index + + +class MediumLevelILFunction(object): + """ + ``class MediumLevelILFunction`` contains the list of MediumLevelILExpr objects that make up a function. MediumLevelILExpr + objects can be added to the MediumLevelILFunction by calling ``append`` and passing the result of the various class + methods which return MediumLevelILExpr objects. + """ + def __init__(self, arch, handle = None, source_func = None): + self.arch = arch + self.source_function = source_func + if handle is not None: + self.handle = core.handle_of_type(handle, core.BNMediumLevelILFunction) + else: + func_handle = None + if self.source_function is not None: + func_handle = self.source_function.handle + self.handle = core.BNCreateMediumLevelILFunction(arch.handle, func_handle) + + def __del__(self): + core.BNFreeMediumLevelILFunction(self.handle) + + def __eq__(self, value): + if not isinstance(value, MediumLevelILFunction): + return False + return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents) + + def __ne__(self, value): + if not isinstance(value, MediumLevelILFunction): + return True + return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents) + + @property + def current_address(self): + """Current IL Address (read/write)""" + return core.BNMediumLevelILGetCurrentAddress(self.handle) + + @current_address.setter + def current_address(self, value): + core.BNMediumLevelILSetCurrentAddress(self.handle, self.arch.handle, value) + + def set_current_address(self, value, arch = None): + if arch is None: + arch = self.arch + core.BNMediumLevelILSetCurrentAddress(self.handle, arch.handle, value) + + @property + def basic_blocks(self): + """list of MediumLevelILBasicBlock objects (read-only)""" + count = ctypes.c_ulonglong() + blocks = core.BNGetMediumLevelILBasicBlockList(self.handle, count) + result = [] + view = None + if self.source_function is not None: + view = self.source_function.view + for i in xrange(0, count.value): + result.append(MediumLevelILBasicBlock(view, core.BNNewBasicBlockReference(blocks[i]), self)) + core.BNFreeBasicBlockList(blocks, count.value) + return result + + @property + def ssa_form(self): + """Medium level IL in SSA form (read-only)""" + result = core.BNGetMediumLevelILSSAForm(self.handle) + if not result: + return None + return MediumLevelILFunction(self.arch, result, self.source_function) + + @property + def non_ssa_form(self): + """Medium level IL in non-SSA (default) form (read-only)""" + result = core.BNGetMediumLevelILNonSSAForm(self.handle) + if not result: + return None + return MediumLevelILFunction(self.arch, result, self.source_function) + + def __setattr__(self, name, value): + try: + object.__setattr__(self, name, value) + except AttributeError: + raise AttributeError("attribute '%s' is read only" % name) + + def __len__(self): + return int(core.BNGetMediumLevelILInstructionCount(self.handle)) + + def __getitem__(self, i): + if isinstance(i, slice) or isinstance(i, tuple): + raise IndexError("expected integer instruction index") + if isinstance(i, MediumLevelILExpr): + return MediumLevelILInstruction(self, i.index) + if (i < 0) or (i >= len(self)): + raise IndexError("index out of range") + return MediumLevelILInstruction(self, core.BNGetMediumLevelILIndexForInstruction(self.handle, i), i) + + def __setitem__(self, i, j): + raise IndexError("instruction modification not implemented") + + def __iter__(self): + count = ctypes.c_ulonglong() + blocks = core.BNGetMediumLevelILBasicBlockList(self.handle, count) + view = None + if self.source_function is not None: + view = self.source_function.view + try: + for i in xrange(0, count.value): + yield MediumLevelILBasicBlock(view, core.BNNewBasicBlockReference(blocks[i]), self) + finally: + core.BNFreeBasicBlockList(blocks, count.value) + + def get_instruction_start(self, addr, arch = None): + if arch is None: + arch = self.arch + result = core.BNMediumLevelILGetInstructionStart(self.handle, arch.handle, addr) + if result >= core.BNGetMediumLevelILInstructionCount(self.handle): + return None + return result + + def expr(self, operation, a = 0, b = 0, c = 0, d = 0, e = 0, size = 0): + if isinstance(operation, str): + operation = MediumLevelILOperation[operation] + elif isinstance(operation, MediumLevelILOperation): + operation = operation.value + return MediumLevelILExpr(core.BNMediumLevelILAddExpr(self.handle, operation, size, a, b, c, d, e)) + + def append(self, expr): + """ + ``append`` adds the MediumLevelILExpr ``expr`` to the current MediumLevelILFunction. + + :param MediumLevelILExpr expr: the MediumLevelILExpr to add to the current MediumLevelILFunction + :return: number of MediumLevelILExpr in the current function + :rtype: int + """ + return core.BNMediumLevelILAddInstruction(self.handle, expr.index) + + def goto(self, label): + """ + ``goto`` returns a goto expression which jumps to the provided MediumLevelILLabel. + + :param MediumLevelILLabel label: Label to jump to + :return: the MediumLevelILExpr that jumps to the provided label + :rtype: MediumLevelILExpr + """ + return MediumLevelILExpr(core.BNMediumLevelILGoto(self.handle, label.handle)) + + def if_expr(self, operand, t, f): + """ + ``if_expr`` returns the ``if`` expression which depending on condition ``operand`` jumps to the MediumLevelILLabel + ``t`` when the condition expression ``operand`` is non-zero and ``f`` when it's zero. + + :param MediumLevelILExpr operand: comparison expression to evaluate. + :param MediumLevelILLabel t: Label for the true branch + :param MediumLevelILLabel f: Label for the false branch + :return: the MediumLevelILExpr for the if expression + :rtype: MediumLevelILExpr + """ + return MediumLevelILExpr(core.BNMediumLevelILIf(self.handle, operand.index, t.handle, f.handle)) + + def mark_label(self, label): + """ + ``mark_label`` assigns a MediumLevelILLabel to the current IL address. + + :param MediumLevelILLabel label: + :rtype: None + """ + core.BNMediumLevelILMarkLabel(self.handle, label.handle) + + def add_label_list(self, labels): + """ + ``add_label_list`` returns a label list expression for the given list of MediumLevelILLabel objects. + + :param list(MediumLevelILLabel) lables: the list of MediumLevelILLabel to get a label list expression from + :return: the label list expression + :rtype: MediumLevelILExpr + """ + label_list = (ctypes.POINTER(core.BNMediumLevelILLabel) * len(labels))() + for i in xrange(len(labels)): + label_list[i] = labels[i].handle + return MediumLevelILExpr(core.BNMediumLevelILAddLabelList(self.handle, label_list, len(labels))) + + def add_operand_list(self, operands): + """ + ``add_operand_list`` returns an operand list expression for the given list of integer operands. + + :param list(int) operands: list of operand numbers + :return: an operand list expression + :rtype: MediumLevelILExpr + """ + operand_list = (ctypes.c_ulonglong * len(operands))() + for i in xrange(len(operands)): + operand_list[i] = operands[i] + return MediumLevelILExpr(core.BNMediumLevelILAddOperandList(self.handle, operand_list, len(operands))) + + def operand(self, n, expr): + """ + ``operand`` sets the operand number of the expression ``expr`` and passes back ``expr`` without modification. + + :param int n: + :param MediumLevelILExpr expr: + :return: returns the expression ``expr`` unmodified + :rtype: MediumLevelILExpr + """ + core.BNMediumLevelILSetExprSourceOperand(self.handle, expr.index, n) + return expr + + def finalize(self): + """ + ``finalize`` ends the function and computes the list of basic blocks. + + :rtype: None + """ + core.BNFinalizeMediumLevelILFunction(self.handle) + + def get_ssa_instruction_index(self, instr): + return core.BNGetMediumLevelILSSAInstructionIndex(self.handle, instr) + + def get_non_ssa_instruction_index(self, instr): + return core.BNGetMediumLevelILNonSSAInstructionIndex(self.handle, instr) + + def get_ssa_var_definition(self, var, index): + var_data = core.BNILVariable() + var_data.type = var.type + var_data.index = var.index + var_data.identifier = var.identifier + result = core.BNGetMediumLevelILSSAVarDefinition(self.handle, var_data, index) + if result >= core.BNGetMediumLevelILInstructionCount(self.handle): + return None + return result + + def get_ssa_memory_definition(self, index): + result = core.BNGetMediumLevelILSSAMemoryDefinition(self.handle, index) + if result >= core.BNGetMediumLevelILInstructionCount(self.handle): + return None + return result + + def get_ssa_var_uses(self, var, index): + count = ctypes.c_ulonglong() + var_data = core.BNILVariable() + var_data.type = var.type + var_data.index = var.index + var_data.identifier = var.identifier + instrs = core.BNGetMediumLevelILSSAVarUses(self.handle, var_data, index, count) + result = [] + for i in xrange(0, count.value): + result.append(instrs[i]) + core.BNFreeILInstructionList(instrs) + return result + + def get_ssa_memory_uses(self, index): + count = ctypes.c_ulonglong() + instrs = core.BNGetMediumLevelILSSAMemoryUses(self.handle, index, count) + result = [] + for i in xrange(0, count.value): + result.append(instrs[i]) + core.BNFreeILInstructionList(instrs) + return result + + def get_ssa_var_value(self, var, index): + var_data = core.BNILVariable() + var_data.type = var.type + var_data.index = var.index + var_data.identifier = var.identifier + value = core.BNGetMediumLevelILSSAVarValue(self.handle, var_data, index) + result = function.RegisterValue(self.arch, value) + core.BNFreeRegisterValue(value) + return result + + +class MediumLevelILBasicBlock(basicblock.BasicBlock): + def __init__(self, view, handle, owner): + super(MediumLevelILBasicBlock, self).__init__(view, handle) + self.il_function = owner + + def __iter__(self): + for idx in xrange(self.start, self.end): + yield self.il_function[idx] + + def __getitem__(self, idx): + size = self.end - self.start + if idx > size or idx < -size: + raise IndexError("list index is out of range") + if idx >= 0: + return self.il_function[idx + self.start] + else: + return self.il_function[self.end + idx] -- cgit v1.3.1 From 7aab4e4a3f8f2daadd1fbd00259da5b01090d84c Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Thu, 2 Mar 2017 00:37:46 -0500 Subject: Adding MLIL instructions, moving stack contents data flow to a later stage --- binaryninjaapi.h | 6 +++++- binaryninjacore.h | 7 +++++-- lowlevelil.cpp | 7 ------- mediumlevelil.cpp | 31 +++++++++++++++++++++++++++++++ python/lowlevelil.py | 6 ------ python/mediumlevelil.py | 5 ++++- 6 files changed, 45 insertions(+), 17 deletions(-) (limited to 'python/mediumlevelil.py') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 1367e7c1..e3ba4968 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2180,7 +2180,6 @@ namespace BinaryNinja RegisterValue GetSSARegisterValue(uint32_t reg, size_t idx); RegisterValue GetSSAFlagValue(uint32_t flag, size_t idx); - RegisterValue GetSSAStackContents(size_t memoryIndex, int64_t offset, size_t size); RegisterValue GetExprValue(size_t expr); }; @@ -2207,12 +2206,17 @@ namespace BinaryNinja ExprId SetVar(size_t size, const BNILVariable& var, ExprId src); ExprId SetVarField(size_t size, const BNILVariable& var, int64_t offset, ExprId src); + ExprId SetVarSplit(size_t size, const BNILVariable& high, const BNILVariable& low, ExprId src); ExprId SetVarSSA(size_t size, const BNILVariable& var, size_t index, ExprId src); ExprId SetVarFieldSSA(size_t size, const BNILVariable& var, int64_t offset, size_t varIndex, ExprId src); + ExprId SetVarSplitSSA(size_t size, const BNILVariable& high, size_t highIndex, + const BNILVariable& low, size_t lowIndex, ExprId src); ExprId Var(size_t size, const BNILVariable& var); ExprId VarField(size_t size, const BNILVariable& var, int64_t offset); ExprId VarSSA(size_t size, const BNILVariable& var, size_t index); ExprId VarFieldSSA(size_t size, const BNILVariable& var, int64_t offset, size_t varIndex); + ExprId AddressOf(size_t size, const BNILVariable& var); + ExprId AddressOfField(size_t size, const BNILVariable& var, int64_t offset); ExprId Goto(BNMediumLevelILLabel& label); ExprId If(ExprId operand, BNMediumLevelILLabel& t, BNMediumLevelILLabel& f); diff --git a/binaryninjacore.h b/binaryninjacore.h index aa9bb49b..d35f806c 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -645,10 +645,13 @@ extern "C" MLIL_NOP, MLIL_SET_VAR, // Not valid in SSA form (see MLIL_SET_VAR_SSA) 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_STORE, // Not valid in SSA form (see MLIL_STORE_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, + MLIL_ADDRESS_OF_FIELD, MLIL_CONST, MLIL_ADD, MLIL_ADC, @@ -708,6 +711,8 @@ extern "C" // The following instructions are only used in SSA form MLIL_SET_VAR_SSA, MLIL_SET_VAR_SSA_FIELD, + MLIL_SET_VAR_SPLIT_SSA, + MLIL_VAR_SPLIT_DEST_SSA, MLIL_VAR_SSA, MLIL_VAR_SSA_FIELD, MLIL_CALL_SSA, @@ -2151,8 +2156,6 @@ extern "C" uint32_t reg, size_t idx); BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILSSAFlagValue(BNLowLevelILFunction* func, uint32_t flag, size_t idx); - BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILSSAStackContents(BNLowLevelILFunction* func, - size_t memoryIndex, int64_t offset, size_t size); BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILExprValue(BNLowLevelILFunction* func, size_t expr); diff --git a/lowlevelil.cpp b/lowlevelil.cpp index 5a789981..342effea 100644 --- a/lowlevelil.cpp +++ b/lowlevelil.cpp @@ -767,13 +767,6 @@ RegisterValue LowLevelILFunction::GetSSAFlagValue(uint32_t flag, size_t idx) } -RegisterValue LowLevelILFunction::GetSSAStackContents(size_t memoryIndex, int64_t offset, size_t size) -{ - BNRegisterValue value = BNGetLowLevelILSSAStackContents(m_object, memoryIndex, offset, size); - return RegisterValue::FromAPIObject(value); -} - - RegisterValue LowLevelILFunction::GetExprValue(size_t expr) { BNRegisterValue value = BNGetLowLevelILExprValue(m_object, expr); diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index f6ad5bfd..8c97db61 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -86,6 +86,13 @@ ExprId MediumLevelILFunction::SetVarField(size_t size, const BNILVariable& var, } +ExprId MediumLevelILFunction::SetVarSplit(size_t size, const BNILVariable& high, const BNILVariable& low, ExprId src) +{ + return AddExpr(MLIL_SET_VAR_SPLIT, size, ((uint64_t)high.type << 32) | (uint64_t)high.index, high.identifier, + ((uint64_t)low.type << 32) | (uint64_t)low.index, low.identifier, src); +} + + ExprId MediumLevelILFunction::SetVarSSA(size_t size, const BNILVariable& var, size_t varIndex, ExprId src) { return AddExpr(MLIL_SET_VAR_SSA, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, @@ -101,6 +108,17 @@ ExprId MediumLevelILFunction::SetVarFieldSSA(size_t size, const BNILVariable& va } +ExprId MediumLevelILFunction::SetVarSplitSSA(size_t size, const BNILVariable& high, size_t highIndex, + const BNILVariable& low, size_t lowIndex, ExprId src) +{ + return AddExpr(MLIL_SET_VAR_SPLIT_SSA, size, + AddExpr(MLIL_VAR_SPLIT_DEST_SSA, size, ((uint64_t)high.type << 32) | (uint64_t)high.index, + high.identifier, highIndex), + AddExpr(MLIL_VAR_SPLIT_DEST_SSA, size, ((uint64_t)low.type << 32) | (uint64_t)low.index, + low.identifier, lowIndex), src); +} + + ExprId MediumLevelILFunction::Var(size_t size, const BNILVariable& var) { return AddExpr(MLIL_VAR, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier); @@ -127,6 +145,19 @@ ExprId MediumLevelILFunction::VarFieldSSA(size_t size, const BNILVariable& var, } +ExprId MediumLevelILFunction::AddressOf(size_t size, const BNILVariable& var) +{ + return AddExpr(MLIL_ADDRESS_OF, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier); +} + + +ExprId MediumLevelILFunction::AddressOfField(size_t size, const BNILVariable& var, int64_t offset) +{ + return AddExpr(MLIL_ADDRESS_OF_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, + var.identifier, offset); +} + + ExprId MediumLevelILFunction::Goto(BNMediumLevelILLabel& label) { return BNMediumLevelILGoto(m_object, &label); diff --git a/python/lowlevelil.py b/python/lowlevelil.py index ed1cedd4..40cb964c 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -1422,12 +1422,6 @@ class LowLevelILFunction(object): core.BNFreeRegisterValue(value) return result - def get_ssa_stack_contents(self, memory_index, offset, size): - value = core.BNGetLowLevelILSSAStackContents(self.handle, memory_index, offset, size) - result = function.RegisterValue(self.arch, value) - core.BNFreeRegisterValue(value) - return result - class LowLevelILBasicBlock(basicblock.BasicBlock): def __init__(self, view, handle, owner): diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index c4c4aa23..839c45ce 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -47,6 +47,7 @@ class MediumLevelILInstruction(object): MediumLevelILOperation.MLIL_NOP: [], MediumLevelILOperation.MLIL_SET_VAR: [("dest", "var"), ("src", "expr")], 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_STORE: [("dest", "expr"), ("src", "expr")], MediumLevelILOperation.MLIL_VAR: [("src", "var")], @@ -108,12 +109,14 @@ class MediumLevelILInstruction(object): MediumLevelILOperation.MLIL_UNIMPL_MEM: [("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_SSA: [("dest", "var"), ("index", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_SSA_FIELD: [("dest", "var"), ("index", "int"), ("offset", "int"), ("src", "expr")], + MediumLevelILOperation.MLIL_SET_VAR_SPLIT_SSA: [("high", "expr"), ("low", "expr"), ("src", "expr")], + MediumLevelILOperation.MLIL_VAR_SPLIT_DEST_SSA: [("dest", "var"), ("index", "int")], MediumLevelILOperation.MLIL_VAR_SSA: [("src", "var"), ("index", "int")], MediumLevelILOperation.MLIL_VAR_SSA_FIELD: [("src", "var"), ("index", "int"), ("offset", "int")], MediumLevelILOperation.MLIL_CALL_SSA: [("output", "expr"), ("dest", "expr"), ("param", "expr")], MediumLevelILOperation.MLIL_SYSCALL_SSA: [("output", "expr"), ("param", "expr")], MediumLevelILOperation.MLIL_CALL_OUTPUT_SSA: [("dest_memory", "int"), ("dest", "var_ssa_list")], - MediumLevelILOperation.MLIL_CALL_PARAM_SSA: [("src", "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_STORE_SSA: [("dest", "expr"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_VAR_PHI: [("dest", "var"), ("index", "int"), ("src", "var_ssa_list")], -- cgit v1.3.1 From 3a95d0ae05e21775042176b8f688bafeb3f6d80f Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Tue, 7 Mar 2017 02:38:09 -0500 Subject: Add outputs and parameters for call and return, handle aliasing --- binaryninjaapi.h | 9 +++++++-- binaryninjacore.h | 25 ++++++++++++++++++------- mediumlevelil.cpp | 39 ++++++++++++++++++++++++++++++++++----- python/mediumlevelil.py | 36 +++++++++++++++++++++++++++++------- 4 files changed, 88 insertions(+), 21 deletions(-) (limited to 'python/mediumlevelil.py') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index e3ba4968..f63deee1 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2201,20 +2201,25 @@ namespace BinaryNinja size_t GetInstructionStart(Architecture* arch, uint64_t addr); ExprId AddExpr(BNMediumLevelILOperation operation, size_t size, - ExprId a = 0, ExprId b = 0, ExprId c = 0, ExprId d = 0, ExprId e = 0); + ExprId a = 0, ExprId b = 0, ExprId c = 0, ExprId d = 0, ExprId e = 0, ExprId f = 0); ExprId AddInstruction(ExprId expr); ExprId SetVar(size_t size, const BNILVariable& var, ExprId src); ExprId SetVarField(size_t size, const BNILVariable& var, int64_t offset, ExprId src); ExprId SetVarSplit(size_t size, const BNILVariable& high, const BNILVariable& low, ExprId src); ExprId SetVarSSA(size_t size, const BNILVariable& var, size_t index, ExprId src); - ExprId SetVarFieldSSA(size_t size, const BNILVariable& var, int64_t offset, size_t varIndex, ExprId src); + ExprId SetVarFieldSSA(size_t size, const BNILVariable& var, size_t varIndex, int64_t offset, ExprId src); ExprId SetVarSplitSSA(size_t size, const BNILVariable& high, size_t highIndex, const BNILVariable& low, size_t lowIndex, ExprId src); + ExprId SetVarAliased(size_t size, const BNILVariable& var, size_t destIndex, size_t srcIndex, ExprId src); + ExprId SetVarFieldAliased(size_t size, const BNILVariable& var, size_t destIndex, size_t srcIndex, + int64_t offset, ExprId src); ExprId Var(size_t size, const BNILVariable& var); ExprId VarField(size_t size, const BNILVariable& var, int64_t offset); ExprId VarSSA(size_t size, const BNILVariable& var, size_t index); ExprId VarFieldSSA(size_t size, const BNILVariable& var, int64_t offset, size_t varIndex); + ExprId VarAliased(size_t size, const BNILVariable& var, size_t memIndex); + ExprId VarFieldAliased(size_t size, const BNILVariable& var, int64_t offset, size_t memIndex); ExprId AddressOf(size_t size, const BNILVariable& var); ExprId AddressOfField(size_t size, const BNILVariable& var, int64_t offset); diff --git a/binaryninjacore.h b/binaryninjacore.h index d35f806c..fe8382f9 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -684,8 +684,11 @@ extern "C" MLIL_ZX, MLIL_JUMP, MLIL_JUMP_TO, - MLIL_CALL, - MLIL_RET, + MLIL_CALL, // Not valid in SSA form (see MLIL_CALL_SSA) + MLIL_CALL_UNTYPED, // Not valid in SSA form (see MLIL_CALL_UNTYPED_SSA) + MLIL_CALL_OUTPUT, // Only valid within MLIL_CALL or MLIL_SYSCALL family instructions + MLIL_CALL_PARAM, // Only valid within MLIL_CALL or MLIL_SYSCALL family instructions + MLIL_RET, // Not valid in SSA form (see MLIL_RET_SSA) MLIL_NORET, MLIL_IF, MLIL_GOTO, @@ -701,7 +704,8 @@ extern "C" MLIL_CMP_UGT, MLIL_TEST_BIT, MLIL_BOOL_TO_INT, - MLIL_SYSCALL, + MLIL_SYSCALL, // Not valid in SSA form (see MLIL_SYSCALL_SSA) + MLIL_SYSCALL_UNTYPED, // Not valid in SSA form (see MLIL_SYSCALL_UNTYPED_SSA) MLIL_BP, MLIL_TRAP, MLIL_UNDEF, @@ -713,12 +717,19 @@ extern "C" MLIL_SET_VAR_SSA_FIELD, MLIL_SET_VAR_SPLIT_SSA, MLIL_VAR_SPLIT_DEST_SSA, + MLIL_SET_VAR_ALIASED, + MLIL_SET_VAR_ALIASED_FIELD, MLIL_VAR_SSA, MLIL_VAR_SSA_FIELD, + MLIL_VAR_ALIASED, + MLIL_VAR_ALIASED_FIELD, MLIL_CALL_SSA, + MLIL_CALL_UNTYPED_SSA, MLIL_SYSCALL_SSA, - MLIL_CALL_PARAM_SSA, // Only valid within the LLIL_CALL_SSA or LLIL_SYSCALL_SSA instructions - MLIL_CALL_OUTPUT_SSA, // Only valid within the LLIL_CALL_SSA or LLIL_SYSCALL_SSA instructions + MLIL_SYSCALL_UNTYPED_SSA, + MLIL_CALL_PARAM_SSA, // Only valid within the LLIL_CALL_SSA, LLIL_SYSCALL_SSA family instructions + MLIL_CALL_OUTPUT_SSA, // Only valid within the LLIL_CALL_SSA or LLIL_SYSCALL_SSA family instructions + MLIL_RET_SSA, MLIL_LOAD_SSA, MLIL_STORE_SSA, MLIL_VAR_PHI, @@ -729,7 +740,7 @@ extern "C" { BNMediumLevelILOperation operation; size_t size; - uint64_t operands[5]; + uint64_t operands[6]; uint64_t address; }; @@ -2169,7 +2180,7 @@ extern "C" BINARYNINJACOREAPI size_t BNMediumLevelILGetInstructionStart(BNMediumLevelILFunction* func, BNArchitecture* arch, uint64_t addr); BINARYNINJACOREAPI size_t BNMediumLevelILAddExpr(BNMediumLevelILFunction* func, BNMediumLevelILOperation operation, - size_t size, uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e); + size_t size, uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e, uint64_t f); BINARYNINJACOREAPI size_t BNMediumLevelILAddInstruction(BNMediumLevelILFunction* func, size_t expr); BINARYNINJACOREAPI size_t BNMediumLevelILGoto(BNMediumLevelILFunction* func, BNMediumLevelILLabel* label); BINARYNINJACOREAPI size_t BNMediumLevelILIf(BNMediumLevelILFunction* func, uint64_t op, diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index 8c97db61..f1f0bdd2 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -61,9 +61,9 @@ size_t MediumLevelILFunction::GetInstructionStart(Architecture* arch, uint64_t a ExprId MediumLevelILFunction::AddExpr(BNMediumLevelILOperation operation, size_t size, - ExprId a, ExprId b, ExprId c, ExprId d, ExprId e) + ExprId a, ExprId b, ExprId c, ExprId d, ExprId e, ExprId f) { - return BNMediumLevelILAddExpr(m_object, operation, size, a, b, c, d, e); + return BNMediumLevelILAddExpr(m_object, operation, size, a, b, c, d, e, f); } @@ -100,11 +100,11 @@ ExprId MediumLevelILFunction::SetVarSSA(size_t size, const BNILVariable& var, si } -ExprId MediumLevelILFunction::SetVarFieldSSA(size_t size, const BNILVariable& var, int64_t offset, - size_t varIndex, ExprId src) +ExprId MediumLevelILFunction::SetVarFieldSSA(size_t size, const BNILVariable& var, size_t varIndex, + int64_t offset, ExprId src) { return AddExpr(MLIL_SET_VAR_SSA_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, - offset, varIndex, src); + varIndex, offset, src); } @@ -119,6 +119,22 @@ ExprId MediumLevelILFunction::SetVarSplitSSA(size_t size, const BNILVariable& hi } +ExprId MediumLevelILFunction::SetVarAliased(size_t size, const BNILVariable& var, size_t destIndex, + size_t srcIndex, ExprId src) +{ + return AddExpr(MLIL_SET_VAR_ALIASED, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, + destIndex, srcIndex, src); +} + + +ExprId MediumLevelILFunction::SetVarFieldAliased(size_t size, const BNILVariable& var, size_t destIndex, + size_t srcIndex, int64_t offset, ExprId src) +{ + return AddExpr(MLIL_SET_VAR_ALIASED_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, + destIndex, srcIndex, offset, src); +} + + ExprId MediumLevelILFunction::Var(size_t size, const BNILVariable& var) { return AddExpr(MLIL_VAR, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier); @@ -145,6 +161,19 @@ ExprId MediumLevelILFunction::VarFieldSSA(size_t size, const BNILVariable& var, } +ExprId MediumLevelILFunction::VarAliased(size_t size, const BNILVariable& var, size_t memIndex) +{ + return AddExpr(MLIL_VAR_ALIASED, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, memIndex); +} + + +ExprId MediumLevelILFunction::VarFieldAliased(size_t size, const BNILVariable& var, int64_t offset, size_t memIndex) +{ + return AddExpr(MLIL_VAR_ALIASED_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, + offset, memIndex); +} + + ExprId MediumLevelILFunction::AddressOf(size_t size, const BNILVariable& var) { return AddExpr(MLIL_ADDRESS_OF, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier); diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 839c45ce..fa6371f8 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -84,8 +84,11 @@ class MediumLevelILInstruction(object): MediumLevelILOperation.MLIL_ZX: [("src", "expr")], MediumLevelILOperation.MLIL_JUMP: [("dest", "expr")], MediumLevelILOperation.MLIL_JUMP_TO: [("dest", "expr"), ("targets", "int_list")], - MediumLevelILOperation.MLIL_CALL: [("dest", "expr")], - MediumLevelILOperation.MLIL_RET: [], + MediumLevelILOperation.MLIL_CALL: [("output", "var_list"), ("dest", "expr"), ("params", "var_list")], + MediumLevelILOperation.MLIL_CALL_UNTYPED: [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")], + MediumLevelILOperation.MLIL_CALL_OUTPUT: [("dest", "var_list")], + MediumLevelILOperation.MLIL_CALL_PARAM: [("src", "var_list")], + MediumLevelILOperation.MLIL_RET: [("src", "var_list")], MediumLevelILOperation.MLIL_NORET: [], MediumLevelILOperation.MLIL_IF: [("condition", "expr"), ("true", "int"), ("false", "int")], MediumLevelILOperation.MLIL_GOTO: [("dest", "int")], @@ -101,7 +104,8 @@ class MediumLevelILInstruction(object): MediumLevelILOperation.MLIL_CMP_UGT: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_TEST_BIT: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_BOOL_TO_INT: [("src", "expr")], - MediumLevelILOperation.MLIL_SYSCALL: [], + MediumLevelILOperation.MLIL_SYSCALL: [("output", "var_list"), ("params", "var_list")], + MediumLevelILOperation.MLIL_SYSCALL_UNTYPED: [("output", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_BP: [], MediumLevelILOperation.MLIL_TRAP: [("vector", "int")], MediumLevelILOperation.MLIL_UNDEF: [], @@ -110,11 +114,17 @@ class MediumLevelILInstruction(object): MediumLevelILOperation.MLIL_SET_VAR_SSA: [("dest", "var"), ("index", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_SSA_FIELD: [("dest", "var"), ("index", "int"), ("offset", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_SPLIT_SSA: [("high", "expr"), ("low", "expr"), ("src", "expr")], + MediumLevelILOperation.MLIL_SET_VAR_ALIASED: [("dest", "var"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "exor")], + MediumLevelILOperation.MLIL_SET_VAR_ALIASED_FIELD: [("dest", "var"), ("dest_memory", "int"), ("src_memory", "int"), ("offset", "int"), ("src", "exor")], MediumLevelILOperation.MLIL_VAR_SPLIT_DEST_SSA: [("dest", "var"), ("index", "int")], MediumLevelILOperation.MLIL_VAR_SSA: [("src", "var"), ("index", "int")], MediumLevelILOperation.MLIL_VAR_SSA_FIELD: [("src", "var"), ("index", "int"), ("offset", "int")], + MediumLevelILOperation.MLIL_VAR_ALIASED: [("src", "var"), ("src_memory", "int")], + MediumLevelILOperation.MLIL_VAR_ALIASED_FIELD: [("src", "var"), ("src_memory", "int"), ("offset", "int")], MediumLevelILOperation.MLIL_CALL_SSA: [("output", "expr"), ("dest", "expr"), ("param", "expr")], + MediumLevelILOperation.MLIL_CALL_UNTYPED_SSA: [("output", "expr"), ("dest", "expr"), ("param", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_SYSCALL_SSA: [("output", "expr"), ("param", "expr")], + MediumLevelILOperation.MLIL_SYSCALL_UNTYPED_SSA: [("output", "expr"), ("param", "expr"), ("stack", "expr")], 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")], @@ -134,8 +144,8 @@ class MediumLevelILInstruction(object): operands = MediumLevelILInstruction.ILOperations[instr.operation] self.operands = [] i = 0 - while i < len(operands): - name, operand_type = operands[i] + for operand in operands: + name, operand_type = operand if operand_type == "int": value = instr.operands[i] elif operand_type == "expr": @@ -150,8 +160,19 @@ class MediumLevelILInstruction(object): count = ctypes.c_ulonglong() operand_list = core.BNMediumLevelILGetOperandList(func.handle, self.expr_index, i, count) value = [] - for i in xrange(count.value): - value.append(operand_list[i]) + for j in xrange(count.value): + value.append(operand_list[j]) + core.BNMediumLevelILFreeOperandList(operand_list) + elif operand_type == "var_list": + count = ctypes.c_ulonglong() + operand_list = core.BNMediumLevelILGetOperandList(func.handle, self.expr_index, i, count) + i += 1 + value = [] + for j in xrange(count.value / 2): + var_type = ILVariableSourceType(operand_list[j * 2] >> 32) + index = operand_list[j * 2] & 0xffffffff + identifier = operand_list[(j * 2) + 1] + value.append(function.ILVariable(self.function, var_type, index, identifier)) core.BNMediumLevelILFreeOperandList(operand_list) elif operand_type == "var_ssa_list": count = ctypes.c_ulonglong() @@ -167,6 +188,7 @@ class MediumLevelILInstruction(object): core.BNMediumLevelILFreeOperandList(operand_list) self.operands.append(value) self.__dict__[name] = value + i += 1 def __str__(self): tokens = self.tokens -- cgit v1.3.1 From a51f7666462341f77e3223ff2b6ab218688dfa8c Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Tue, 7 Mar 2017 17:05:42 -0500 Subject: Use expression lists in call and return --- binaryninjacore.h | 1 - python/mediumlevelil.py | 24 +++++++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) (limited to 'python/mediumlevelil.py') diff --git a/binaryninjacore.h b/binaryninjacore.h index fe8382f9..1d5e10d8 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -729,7 +729,6 @@ extern "C" MLIL_SYSCALL_UNTYPED_SSA, MLIL_CALL_PARAM_SSA, // Only valid within the LLIL_CALL_SSA, LLIL_SYSCALL_SSA family instructions MLIL_CALL_OUTPUT_SSA, // Only valid within the LLIL_CALL_SSA or LLIL_SYSCALL_SSA family instructions - MLIL_RET_SSA, MLIL_LOAD_SSA, MLIL_STORE_SSA, MLIL_VAR_PHI, diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index fa6371f8..9f25ee97 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -52,6 +52,8 @@ class MediumLevelILInstruction(object): MediumLevelILOperation.MLIL_STORE: [("dest", "expr"), ("src", "expr")], MediumLevelILOperation.MLIL_VAR: [("src", "var")], MediumLevelILOperation.MLIL_VAR_FIELD: [("src", "var"), ("offset", "int")], + MediumLevelILOperation.MLIL_ADDRESS_OF: [("src", "var")], + MediumLevelILOperation.MLIL_ADDRESS_OF_FIELD: [("src", "var"), ("offset", "int")], MediumLevelILOperation.MLIL_CONST: [("constant", "int")], MediumLevelILOperation.MLIL_ADD: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_ADC: [("left", "expr"), ("right", "expr")], @@ -84,11 +86,11 @@ class MediumLevelILInstruction(object): MediumLevelILOperation.MLIL_ZX: [("src", "expr")], MediumLevelILOperation.MLIL_JUMP: [("dest", "expr")], MediumLevelILOperation.MLIL_JUMP_TO: [("dest", "expr"), ("targets", "int_list")], - MediumLevelILOperation.MLIL_CALL: [("output", "var_list"), ("dest", "expr"), ("params", "var_list")], + MediumLevelILOperation.MLIL_CALL: [("output", "var_list"), ("dest", "expr"), ("params", "expr_list")], MediumLevelILOperation.MLIL_CALL_UNTYPED: [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_CALL_OUTPUT: [("dest", "var_list")], MediumLevelILOperation.MLIL_CALL_PARAM: [("src", "var_list")], - MediumLevelILOperation.MLIL_RET: [("src", "var_list")], + MediumLevelILOperation.MLIL_RET: [("src", "expr_list")], MediumLevelILOperation.MLIL_NORET: [], MediumLevelILOperation.MLIL_IF: [("condition", "expr"), ("true", "int"), ("false", "int")], MediumLevelILOperation.MLIL_GOTO: [("dest", "int")], @@ -104,7 +106,7 @@ class MediumLevelILInstruction(object): MediumLevelILOperation.MLIL_CMP_UGT: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_TEST_BIT: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_BOOL_TO_INT: [("src", "expr")], - MediumLevelILOperation.MLIL_SYSCALL: [("output", "var_list"), ("params", "var_list")], + MediumLevelILOperation.MLIL_SYSCALL: [("output", "var_list"), ("params", "expr_list")], MediumLevelILOperation.MLIL_SYSCALL_UNTYPED: [("output", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_BP: [], MediumLevelILOperation.MLIL_TRAP: [("vector", "int")], @@ -121,10 +123,10 @@ class MediumLevelILInstruction(object): MediumLevelILOperation.MLIL_VAR_SSA_FIELD: [("src", "var"), ("index", "int"), ("offset", "int")], MediumLevelILOperation.MLIL_VAR_ALIASED: [("src", "var"), ("src_memory", "int")], MediumLevelILOperation.MLIL_VAR_ALIASED_FIELD: [("src", "var"), ("src_memory", "int"), ("offset", "int")], - MediumLevelILOperation.MLIL_CALL_SSA: [("output", "expr"), ("dest", "expr"), ("param", "expr")], - MediumLevelILOperation.MLIL_CALL_UNTYPED_SSA: [("output", "expr"), ("dest", "expr"), ("param", "expr"), ("stack", "expr")], - MediumLevelILOperation.MLIL_SYSCALL_SSA: [("output", "expr"), ("param", "expr")], - MediumLevelILOperation.MLIL_SYSCALL_UNTYPED_SSA: [("output", "expr"), ("param", "expr"), ("stack", "expr")], + MediumLevelILOperation.MLIL_CALL_SSA: [("output", "expr"), ("dest", "expr"), ("params", "expr_list"), ("src_memory", "int")], + MediumLevelILOperation.MLIL_CALL_UNTYPED_SSA: [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")], + MediumLevelILOperation.MLIL_SYSCALL_SSA: [("output", "expr"), ("params", "expr_list"), ("src_memory", "int")], + MediumLevelILOperation.MLIL_SYSCALL_UNTYPED_SSA: [("output", "expr"), ("params", "expr"), ("stack", "expr")], 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")], @@ -186,6 +188,14 @@ class MediumLevelILInstruction(object): var_index = operand_list[(j * 3) + 2] value.append((function.ILVariable(self.function, var_type, index, identifier), var_index)) core.BNMediumLevelILFreeOperandList(operand_list) + elif operand_type == "expr_list": + count = ctypes.c_ulonglong() + operand_list = core.BNMediumLevelILGetOperandList(func.handle, self.expr_index, i, count) + i += 1 + value = [] + for j in xrange(count.value): + value.append(MediumLevelILInstruction(func, operand_list[j])) + core.BNMediumLevelILFreeOperandList(operand_list) self.operands.append(value) self.__dict__[name] = value i += 1 -- cgit v1.3.1 From 29be664b3c91d135b54ed34976357bb7d3413e94 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Fri, 10 Mar 2017 19:21:10 -0500 Subject: Mappings between low level IL and medium level IL --- binaryninjaapi.h | 14 ++++++++++++++ binaryninjacore.h | 26 ++++++++++++++++++++++--- lowlevelil.cpp | 36 ++++++++++++++++++++++++++++++++++ mediumlevelil.cpp | 39 +++++++++++++++++++++++++++++++++++++ python/lowlevelil.py | 45 +++++++++++++++++++++++++++++++++++++++++++ python/mediumlevelil.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 208 insertions(+), 3 deletions(-) (limited to 'python/mediumlevelil.py') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index f63deee1..ee342851 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2149,6 +2149,7 @@ namespace BinaryNinja BNLowLevelILInstruction operator[](size_t i) const; size_t GetIndexForInstruction(size_t i) const; size_t GetInstructionCount() const; + size_t GetExprCount() const; void AddLabelForAddress(Architecture* arch, ExprId addr); BNLowLevelILLabel* GetLabelForAddress(Architecture* arch, ExprId addr); @@ -2182,6 +2183,11 @@ namespace BinaryNinja RegisterValue GetSSAFlagValue(uint32_t flag, size_t idx); RegisterValue GetExprValue(size_t expr); + + Ref GetMediumLevelIL() const; + Ref GetMappedMediumLevelIL() const; + size_t GetMappedMediumLevelILInstructionIndex(size_t instr) const; + size_t GetMappedMediumLevelILExprIndex(size_t expr) const; }; struct MediumLevelILLabel: public BNMediumLevelILLabel @@ -2236,6 +2242,7 @@ namespace BinaryNinja BNMediumLevelILInstruction operator[](size_t i) const; size_t GetIndexForInstruction(size_t i) const; size_t GetInstructionCount() const; + size_t GetExprCount() const; void Finalize(); @@ -2259,6 +2266,13 @@ namespace BinaryNinja RegisterValue GetSSAVarValue(const BNILVariable& var, size_t idx); RegisterValue GetExprValue(size_t expr); + + size_t GetSSAVarIndexAtInstruction(const BNILVariable& var, size_t instr) const; + size_t GetSSAMemoryIndexAtInstruction(size_t instr) const; + + Ref GetLowLevelIL() const; + size_t GetLowLevelILInstructionIndex(size_t instr) const; + size_t GetLowLevelILExprIndex(size_t expr) const; }; class FunctionRecognizer diff --git a/binaryninjacore.h b/binaryninjacore.h index 1d5e10d8..66d5f010 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -60,6 +60,8 @@ #define BN_INVALID_OPERAND 0xffffffff +#define BN_INVALID_EXPR ((size_t)-1) + #define BN_DEFAULT_MIN_STRING_LENGTH 4 #define BN_MAX_STRING_LENGTH 128 @@ -366,7 +368,9 @@ extern "C" LiftedILFunctionGraph = 2, LowLevelILSSAFormFunctionGraph = 3, MediumLevelILFunctionGraph = 4, - MediumLevelILSSAFormFunctionGraph = 5 + MediumLevelILSSAFormFunctionGraph = 5, + MappedMediumLevelILFunctionGraph = 6, + MappedMediumLevelILSSAFormFunctionGraph = 7 }; enum BNDisassemblyOption @@ -727,8 +731,8 @@ extern "C" MLIL_CALL_UNTYPED_SSA, MLIL_SYSCALL_SSA, MLIL_SYSCALL_UNTYPED_SSA, - MLIL_CALL_PARAM_SSA, // Only valid within the LLIL_CALL_SSA, LLIL_SYSCALL_SSA family instructions - MLIL_CALL_OUTPUT_SSA, // Only valid within the LLIL_CALL_SSA or LLIL_SYSCALL_SSA family instructions + 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_STORE_SSA, MLIL_VAR_PHI, @@ -2131,6 +2135,7 @@ extern "C" BINARYNINJACOREAPI BNLowLevelILInstruction BNGetLowLevelILByIndex(BNLowLevelILFunction* func, size_t i); BINARYNINJACOREAPI size_t BNGetLowLevelILIndexForInstruction(BNLowLevelILFunction* func, size_t i); BINARYNINJACOREAPI size_t BNGetLowLevelILInstructionCount(BNLowLevelILFunction* func); + BINARYNINJACOREAPI size_t BNGetLowLevelILExprCount(BNLowLevelILFunction* func); BINARYNINJACOREAPI void BNAddLowLevelILLabelForAddress(BNLowLevelILFunction* func, BNArchitecture* arch, uint64_t addr); BINARYNINJACOREAPI BNLowLevelILLabel* BNGetLowLevelILLabelForAddress(BNLowLevelILFunction* func, @@ -2169,6 +2174,11 @@ extern "C" BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILExprValue(BNLowLevelILFunction* func, size_t expr); + BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetMediumLevelILForLowLevelIL(BNLowLevelILFunction* func); + BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetMappedMediumLevelIL(BNLowLevelILFunction* func); + BINARYNINJACOREAPI size_t BNGetMappedMediumLevelILInstructionIndex(BNLowLevelILFunction* func, size_t instr); + BINARYNINJACOREAPI size_t BNGetMappedMediumLevelILExprIndex(BNLowLevelILFunction* func, size_t expr); + // Medium-level IL BINARYNINJACOREAPI BNMediumLevelILFunction* BNCreateMediumLevelILFunction(BNArchitecture* arch, BNFunction* func); BINARYNINJACOREAPI BNMediumLevelILFunction* BNNewMediumLevelILFunctionReference(BNMediumLevelILFunction* func); @@ -2199,6 +2209,7 @@ extern "C" BINARYNINJACOREAPI BNMediumLevelILInstruction BNGetMediumLevelILByIndex(BNMediumLevelILFunction* func, size_t i); BINARYNINJACOREAPI size_t BNGetMediumLevelILIndexForInstruction(BNMediumLevelILFunction* func, size_t i); BINARYNINJACOREAPI size_t BNGetMediumLevelILInstructionCount(BNMediumLevelILFunction* func); + BINARYNINJACOREAPI size_t BNGetMediumLevelILExprCount(BNMediumLevelILFunction* func); BINARYNINJACOREAPI bool BNGetMediumLevelILExprText(BNMediumLevelILFunction* func, BNArchitecture* arch, size_t i, BNInstructionTextToken** tokens, size_t* count); @@ -2226,6 +2237,15 @@ extern "C" const BNILVariable* var, size_t idx); BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILExprValue(BNMediumLevelILFunction* func, size_t expr); + BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAVarIndexAtILInstruction(BNMediumLevelILFunction* func, + const BNILVariable* var, size_t instr); + BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAMemoryIndexAtILInstruction(BNMediumLevelILFunction* func, + size_t instr); + + BINARYNINJACOREAPI BNLowLevelILFunction* BNGetLowLevelILForMediumLevelIL(BNMediumLevelILFunction* func); + BINARYNINJACOREAPI size_t BNGetLowLevelILInstructionIndex(BNMediumLevelILFunction* func, size_t instr); + BINARYNINJACOREAPI size_t BNGetLowLevelILExprIndex(BNMediumLevelILFunction* func, size_t expr); + // Types BINARYNINJACOREAPI BNType* BNCreateVoidType(void); BINARYNINJACOREAPI BNType* BNCreateBoolType(void); diff --git a/lowlevelil.cpp b/lowlevelil.cpp index 342effea..bd038b6e 100644 --- a/lowlevelil.cpp +++ b/lowlevelil.cpp @@ -553,6 +553,12 @@ size_t LowLevelILFunction::GetInstructionCount() const } +size_t LowLevelILFunction::GetExprCount() const +{ + return BNGetLowLevelILExprCount(m_object); +} + + void LowLevelILFunction::AddLabelForAddress(Architecture* arch, ExprId addr) { BNAddLowLevelILLabelForAddress(m_object, arch->GetObject(), addr); @@ -772,3 +778,33 @@ RegisterValue LowLevelILFunction::GetExprValue(size_t expr) BNRegisterValue value = BNGetLowLevelILExprValue(m_object, expr); return RegisterValue::FromAPIObject(value); } + + +Ref LowLevelILFunction::GetMediumLevelIL() const +{ + BNMediumLevelILFunction* func = BNGetMediumLevelILForLowLevelIL(m_object); + if (!func) + return nullptr; + return new MediumLevelILFunction(func); +} + + +Ref LowLevelILFunction::GetMappedMediumLevelIL() const +{ + BNMediumLevelILFunction* func = BNGetMappedMediumLevelIL(m_object); + if (!func) + return nullptr; + return new MediumLevelILFunction(func); +} + + +size_t LowLevelILFunction::GetMappedMediumLevelILInstructionIndex(size_t instr) const +{ + return BNGetMappedMediumLevelILInstructionIndex(m_object, instr); +} + + +size_t LowLevelILFunction::GetMappedMediumLevelILExprIndex(size_t expr) const +{ + return BNGetMappedMediumLevelILExprIndex(m_object, expr); +} diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index f1f0bdd2..04b1cffd 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -268,6 +268,12 @@ size_t MediumLevelILFunction::GetInstructionCount() const } +size_t MediumLevelILFunction::GetExprCount() const +{ + return BNGetMediumLevelILExprCount(m_object); +} + + void MediumLevelILFunction::Finalize() { BNFinalizeMediumLevelILFunction(m_object); @@ -436,3 +442,36 @@ RegisterValue MediumLevelILFunction::GetExprValue(size_t expr) BNRegisterValue value = BNGetMediumLevelILExprValue(m_object, expr); return RegisterValue::FromAPIObject(value); } + + +size_t MediumLevelILFunction::GetSSAVarIndexAtInstruction(const BNILVariable& var, size_t instr) const +{ + return BNGetMediumLevelILSSAVarIndexAtILInstruction(m_object, &var, instr); +} + + +size_t MediumLevelILFunction::GetSSAMemoryIndexAtInstruction(size_t instr) const +{ + return BNGetMediumLevelILSSAMemoryIndexAtILInstruction(m_object, instr); +} + + +Ref MediumLevelILFunction::GetLowLevelIL() const +{ + BNLowLevelILFunction* func = BNGetLowLevelILForMediumLevelIL(m_object); + if (!func) + return nullptr; + return new LowLevelILFunction(func); +} + + +size_t MediumLevelILFunction::GetLowLevelILInstructionIndex(size_t instr) const +{ + return BNGetLowLevelILInstructionIndex(m_object, instr); +} + + +size_t MediumLevelILFunction::GetLowLevelILExprIndex(size_t expr) const +{ + return BNGetLowLevelILExprIndex(m_object, expr); +} diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 40cb964c..462d4ade 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -25,6 +25,7 @@ import _binaryninjacore as core from .enums import LowLevelILOperation, LowLevelILFlagCondition, InstructionTextTokenType import function import basicblock +import mediumlevelil class LowLevelILLabel(object): @@ -249,6 +250,14 @@ class LowLevelILInstruction(object): return LowLevelILInstruction(self.function.non_ssa_form, core.BNGetLowLevelILNonSSAExprIndex(self.function.handle, self.expr_index)) + @property + def mapped_medium_level_il(self): + """Gets the 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 + return mediumlevelil.MediumLevelILInstruction(self.function.mapped_medium_level_il, expr) + @property def value(self): """Value of expression using static data flow analysis (read-only)""" @@ -381,6 +390,24 @@ class LowLevelILFunction(object): return None return LowLevelILFunction(self.arch, result, self.source_function) + @property + def medium_level_il(self): + """Medium level IL for this low level IL.""" + result = core.BNGetMediumLevelILForLowLevelIL(self.handle) + if not result: + return None + return mediumlevelil.MediumLevelILFunction(self.arch, result, self.source_function) + + @property + def mapped_medium_level_il(self): + """Medium level IL with mappings between low level IL and medium level IL. Unused stores are not removed. + Typically, this should only be used to answer queries on assembly or low level IL where the query is + easier to perform on medium level IL.""" + result = core.BNGetMappedMediumLevelIL(self.handle) + if not result: + return None + return mediumlevelil.MediumLevelILFunction(self.arch, result, self.source_function) + def __setattr__(self, name, value): try: object.__setattr__(self, name, value) @@ -1422,6 +1449,24 @@ class LowLevelILFunction(object): core.BNFreeRegisterValue(value) return result + def get_mapped_medium_level_il_instruction_index(self, instr): + med_il = self.mapped_medium_level_il + if med_il is None: + return None + result = core.BNGetMappedMediumLevelILInstructionIndex(self.handle, instr) + if result >= core.BNGetMediumLevelILInstructionCount(med_il.handle): + return None + return result + + def get_mapped_medium_level_il_expr_index(self, expr): + med_il = self.mapped_medium_level_il + if med_il is None: + return None + result = core.BNGetMappedMediumLevelILExprIndex(self.handle, expr) + if result >= core.BNGetMediumLevelILExprCount(med_il.handle): + return None + return result + class LowLevelILBasicBlock(basicblock.BasicBlock): def __init__(self, view, handle, owner): diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 9f25ee97..00d7215f 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -25,6 +25,7 @@ import _binaryninjacore as core from .enums import MediumLevelILOperation, InstructionTextTokenType, ILVariableSourceType import function import basicblock +import lowlevelil class MediumLevelILLabel(object): @@ -258,6 +259,14 @@ class MediumLevelILInstruction(object): core.BNFreeRegisterValue(value) return result + @property + def low_level_il(self): + """Low level IL form of this expression""" + expr = self.function.get_low_level_il_expr_index(self.expr_index) + if expr is None: + return None + return lowlevelil.LowLevelILInstruction(self.function.low_level_il.ssa_form, expr) + def __setattr__(self, name, value): try: object.__setattr__(self, name, value) @@ -350,6 +359,14 @@ class MediumLevelILFunction(object): return None return MediumLevelILFunction(self.arch, result, self.source_function) + @property + def low_level_il(self): + """Low level IL for this function""" + result = core.BNGetLowLevelILForMediumLevelIL(self.handle) + if not result: + return None + return lowlevelil.LowLevelILFunction(self.arch, result, self.source_function) + def __setattr__(self, name, value): try: object.__setattr__(self, name, value) @@ -540,6 +557,40 @@ class MediumLevelILFunction(object): core.BNFreeRegisterValue(value) return result + def get_ssa_var_index_at_instruction(self, var, instr): + var_data = core.BNILVariable() + var_data.type = var.type + var_data.index = var.index + var_data.identifier = var.identifier + return core.BNGetMediumLevelILSSAVarIndexAtILInstruction(self.handle, var_data, instr) + + def get_ssa_memory_index_at_instruction(self, instr): + return core.BNGetMediumLevelILSSAMemoryIndexAtILInstruction(self.handle, instr) + + def get_low_level_il_instruction_index(self, instr): + low_il = self.low_level_il + if low_il is None: + return None + low_il = low_il.ssa_form + if low_il is None: + return None + result = core.BNGetLowLevelILInstructionIndex(self.handle, instr) + if result >= core.BNGetLowLevelILInstructionCount(low_il.handle): + return None + return result + + def get_low_level_il_expr_index(self, expr): + low_il = self.low_level_il + if low_il is None: + return None + low_il = low_il.ssa_form + if low_il is None: + return None + result = core.BNGetLowLevelILExprIndex(self.handle, expr) + if result >= core.BNGetLowLevelILExprCount(low_il.handle): + return None + return result + class MediumLevelILBasicBlock(basicblock.BasicBlock): def __init__(self, view, handle, owner): -- cgit v1.3.1 From 42cb99079d4ff0a5aa49e7730bb73500d13f35dd Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Mon, 13 Mar 2017 23:03:41 -0400 Subject: Branch dependence APIs for path sensitive analysis --- binaryninjaapi.h | 3 +++ binaryninjacore.h | 19 +++++++++++++++++++ mediumlevelil.cpp | 20 ++++++++++++++++++++ python/mediumlevelil.py | 19 ++++++++++++++++++- 4 files changed, 60 insertions(+), 1 deletion(-) (limited to 'python/mediumlevelil.py') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index ee342851..fb735a9d 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2270,6 +2270,9 @@ namespace BinaryNinja size_t GetSSAVarIndexAtInstruction(const BNILVariable& var, size_t instr) const; size_t GetSSAMemoryIndexAtInstruction(size_t instr) const; + BNILBranchDependence GetBranchDependenceAtInstruction(size_t curInstr, size_t branchInstr) const; + std::map GetAllBranchDependenceAtInstruction(size_t instr) const; + Ref GetLowLevelIL() const; size_t GetLowLevelILInstructionIndex(size_t instr) const; size_t GetLowLevelILExprIndex(size_t expr) const; diff --git a/binaryninjacore.h b/binaryninjacore.h index 66d5f010..7cc8b200 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1379,6 +1379,19 @@ extern "C" BNType* type; }; + enum BNILBranchDependence + { + NotBranchDependent, + TrueBranchDependent, + FalseBranchDependent + }; + + struct BNILBranchInstructionAndDependence + { + size_t branch; + BNILBranchDependence dependence; + }; + BINARYNINJACOREAPI char* BNAllocString(const char* contents); BINARYNINJACOREAPI void BNFreeString(char* str); BINARYNINJACOREAPI void BNFreeStringList(char** strs, size_t count); @@ -2242,6 +2255,12 @@ extern "C" BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAMemoryIndexAtILInstruction(BNMediumLevelILFunction* func, size_t instr); + BINARYNINJACOREAPI BNILBranchDependence BNGetMediumLevelILBranchDependence(BNMediumLevelILFunction* func, + size_t curInstr, size_t branchInstr); + BINARYNINJACOREAPI BNILBranchInstructionAndDependence* BNGetAllMediumLevelILBranchDependence( + BNMediumLevelILFunction* func, size_t instr, size_t* count); + BINARYNINJACOREAPI void BNFreeILBranchDependenceList(BNILBranchInstructionAndDependence* branches); + BINARYNINJACOREAPI BNLowLevelILFunction* BNGetLowLevelILForMediumLevelIL(BNMediumLevelILFunction* func); BINARYNINJACOREAPI size_t BNGetLowLevelILInstructionIndex(BNMediumLevelILFunction* func, size_t instr); BINARYNINJACOREAPI size_t BNGetLowLevelILExprIndex(BNMediumLevelILFunction* func, size_t expr); diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index 04b1cffd..dcd1fe8e 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -456,6 +456,26 @@ size_t MediumLevelILFunction::GetSSAMemoryIndexAtInstruction(size_t instr) const } +BNILBranchDependence MediumLevelILFunction::GetBranchDependenceAtInstruction(size_t curInstr, size_t branchInstr) const +{ + return BNGetMediumLevelILBranchDependence(m_object, curInstr, branchInstr); +} + + +map MediumLevelILFunction::GetAllBranchDependenceAtInstruction(size_t instr) const +{ + size_t count; + BNILBranchInstructionAndDependence* deps = BNGetAllMediumLevelILBranchDependence(m_object, instr, &count); + + map result; + for (size_t i = 0; i < count; i++) + result[deps[i].branch] = deps[i].dependence; + + BNFreeILBranchDependenceList(deps); + return result; +} + + Ref MediumLevelILFunction::GetLowLevelIL() const { BNLowLevelILFunction* func = BNGetLowLevelILForMediumLevelIL(m_object); diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 00d7215f..8830e738 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -22,7 +22,7 @@ import ctypes # Binary Ninja components import _binaryninjacore as core -from .enums import MediumLevelILOperation, InstructionTextTokenType, ILVariableSourceType +from .enums import MediumLevelILOperation, InstructionTextTokenType, ILVariableSourceType, ILBranchDependence import function import basicblock import lowlevelil @@ -259,6 +259,11 @@ class MediumLevelILInstruction(object): core.BNFreeRegisterValue(value) return result + @property + def branch_dependence(self): + """Set of branching instructions that must take the true or false path to reach this instruction""" + return self.function.get_all_branch_dependence_at_instruction(self.instr_index) + @property def low_level_il(self): """Low level IL form of this expression""" @@ -567,6 +572,18 @@ class MediumLevelILFunction(object): def get_ssa_memory_index_at_instruction(self, instr): return core.BNGetMediumLevelILSSAMemoryIndexAtILInstruction(self.handle, instr) + def get_branch_dependence_at_instruction(self, cur_instr, branch_instr): + return ILBranchDependence(core.BNGetMediumLevelILBranchDependence(self.handle, cur_instr, branch_instr)) + + def get_all_branch_dependence_at_instruction(self, instr): + count = ctypes.c_ulonglong() + deps = core.BNGetAllMediumLevelILBranchDependence(self.handle, instr, count) + result = {} + for i in xrange(0, count.value): + result[deps[i].branch] = ILBranchDependence(deps[i].dependence) + core.BNFreeILBranchDependenceList(deps) + return result + def get_low_level_il_instruction_index(self, instr): low_il = self.low_level_il if low_il is None: -- cgit v1.3.1 From da77a3011450e694a506c8d16ef084a28bc58214 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Wed, 15 Mar 2017 19:51:15 -0400 Subject: APIs for performing range analysis --- binaryninjaapi.h | 3 +++ binaryninjacore.h | 4 ++++ mediumlevelil.cpp | 20 ++++++++++++++++++++ python/mediumlevelil.py | 28 +++++++++++++++++++++++++--- 4 files changed, 52 insertions(+), 3 deletions(-) (limited to 'python/mediumlevelil.py') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index fb735a9d..3f39c827 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2241,6 +2241,7 @@ namespace BinaryNinja BNMediumLevelILInstruction operator[](size_t i) const; size_t GetIndexForInstruction(size_t i) const; + size_t GetInstructionForExpr(size_t expr) const; size_t GetInstructionCount() const; size_t GetExprCount() const; @@ -2266,6 +2267,8 @@ namespace BinaryNinja RegisterValue GetSSAVarValue(const BNILVariable& var, size_t idx); RegisterValue GetExprValue(size_t expr); + RegisterValue GetPossibleSSAVarValues(const BNILVariable& var, size_t idx, size_t instr); + RegisterValue GetPossibleExprValues(size_t expr); size_t GetSSAVarIndexAtInstruction(const BNILVariable& var, size_t instr) const; size_t GetSSAMemoryIndexAtInstruction(size_t instr) const; diff --git a/binaryninjacore.h b/binaryninjacore.h index 7cc8b200..4905a73c 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -2221,6 +2221,7 @@ extern "C" BINARYNINJACOREAPI BNMediumLevelILInstruction BNGetMediumLevelILByIndex(BNMediumLevelILFunction* func, size_t i); BINARYNINJACOREAPI size_t BNGetMediumLevelILIndexForInstruction(BNMediumLevelILFunction* func, size_t i); + BINARYNINJACOREAPI size_t BNGetMediumLevelILInstructionForExpr(BNMediumLevelILFunction* func, size_t expr); BINARYNINJACOREAPI size_t BNGetMediumLevelILInstructionCount(BNMediumLevelILFunction* func); BINARYNINJACOREAPI size_t BNGetMediumLevelILExprCount(BNMediumLevelILFunction* func); @@ -2249,6 +2250,9 @@ extern "C" BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILSSAVarValue(BNMediumLevelILFunction* func, const BNILVariable* var, size_t idx); BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILExprValue(BNMediumLevelILFunction* func, size_t expr); + BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleSSAVarValues(BNMediumLevelILFunction* func, + const BNILVariable* var, size_t idx, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleExprValues(BNMediumLevelILFunction* func, size_t expr); BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAVarIndexAtILInstruction(BNMediumLevelILFunction* func, const BNILVariable* var, size_t instr); diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index dcd1fe8e..51dd067d 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -262,6 +262,12 @@ size_t MediumLevelILFunction::GetIndexForInstruction(size_t i) const } +size_t MediumLevelILFunction::GetInstructionForExpr(size_t expr) const +{ + return BNGetMediumLevelILInstructionForExpr(m_object, expr); +} + + size_t MediumLevelILFunction::GetInstructionCount() const { return BNGetMediumLevelILInstructionCount(m_object); @@ -444,6 +450,20 @@ RegisterValue MediumLevelILFunction::GetExprValue(size_t expr) } +RegisterValue MediumLevelILFunction::GetPossibleSSAVarValues(const BNILVariable& var, size_t idx, size_t instr) +{ + BNRegisterValue value = BNGetMediumLevelILPossibleSSAVarValues(m_object, &var, idx, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue MediumLevelILFunction::GetPossibleExprValues(size_t expr) +{ + BNRegisterValue value = BNGetMediumLevelILPossibleExprValues(m_object, expr); + return RegisterValue::FromAPIObject(value); +} + + size_t MediumLevelILFunction::GetSSAVarIndexAtInstruction(const BNILVariable& var, size_t instr) const { return BNGetMediumLevelILSSAVarIndexAtILInstruction(m_object, &var, instr); diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 8830e738..a63e1b31 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -140,7 +140,10 @@ class MediumLevelILInstruction(object): instr = core.BNGetMediumLevelILByIndex(func.handle, expr_index) self.function = func self.expr_index = expr_index - self.instr_index = instr_index + if instr_index is None: + self.instr_index = core.BNGetMediumLevelILInstructionForExpr(func.handle, expr_index) + else: + self.instr_index = instr_index self.operation = MediumLevelILOperation(instr.operation) self.size = instr.size self.address = instr.address @@ -218,7 +221,8 @@ class MediumLevelILInstruction(object): """MLIL tokens (read-only)""" count = ctypes.c_ulonglong() tokens = ctypes.POINTER(core.BNInstructionTextToken)() - if (self.instr_index is not None) and (self.function.source_function is not None): + if ((self.instr_index is not None) and (self.function.source_function is not None) and + (self.expr_index == core.BNGetMediumLevelILIndexForInstruction(self.function.handle, self.instr_index))): if not core.BNGetMediumLevelILInstructionText(self.function.handle, self.function.source_function.handle, self.function.arch.handle, self.instr_index, tokens, count): return None @@ -253,12 +257,20 @@ class MediumLevelILInstruction(object): @property def value(self): - """Value of expression using static data flow analysis (read-only)""" + """Value of expression if constant or a known value (read-only)""" value = core.BNGetMediumLevelILExprValue(self.function.handle, self.expr_index) result = function.RegisterValue(self.function.arch, value) core.BNFreeRegisterValue(value) return result + @property + def possible_values(self): + """Possible values of expression using path-sensitive static data flow analysis (read-only)""" + value = core.BNGetMediumLevelILPossibleExprValues(self.function.handle, self.expr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + @property def branch_dependence(self): """Set of branching instructions that must take the true or false path to reach this instruction""" @@ -272,6 +284,16 @@ class MediumLevelILInstruction(object): return None return lowlevelil.LowLevelILInstruction(self.function.low_level_il.ssa_form, expr) + def get_ssa_var_possible_values(self, var, index): + var_data = core.BNILVariable() + var_data.type = var.type + var_data.index = var.index + var_data.identifier = var.identifier + value = core.BNGetMediumLevelILPossibleSSAVarValues(self.function.handle, var_data, index, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + def __setattr__(self, name, value): try: object.__setattr__(self, name, value) -- cgit v1.3.1 From cec08b6240f775a831226d9f36ee7f96b369f285 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Thu, 16 Mar 2017 03:41:04 -0400 Subject: Adding APIs to query register and stack contents from IL --- binaryninjaapi.h | 34 +++++++++-- binaryninjacore.h | 63 ++++++++++++++++++-- function.cpp | 28 --------- lowlevelil.cpp | 91 +++++++++++++++++++++++++++++ mediumlevelil.cpp | 102 +++++++++++++++++++++++++++++++++ python/function.py | 42 -------------- python/lowlevelil.py | 98 ++++++++++++++++++++++++++++++- python/mediumlevelil.py | 149 ++++++++++++++++++++++++++++++++++++++++-------- 8 files changed, 503 insertions(+), 104 deletions(-) (limited to 'python/mediumlevelil.py') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 3f39c827..131d6a17 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1894,12 +1894,8 @@ namespace BinaryNinja std::vector GetLowLevelILExitsForInstruction(Architecture* arch, uint64_t addr); RegisterValue GetRegisterValueAtInstruction(Architecture* arch, uint64_t addr, uint32_t reg); RegisterValue GetRegisterValueAfterInstruction(Architecture* arch, uint64_t addr, uint32_t reg); - RegisterValue GetRegisterValueAtLowLevelILInstruction(size_t i, uint32_t reg); - RegisterValue GetRegisterValueAfterLowLevelILInstruction(size_t i, uint32_t reg); RegisterValue GetStackContentsAtInstruction(Architecture* arch, uint64_t addr, int64_t offset, size_t size); RegisterValue GetStackContentsAfterInstruction(Architecture* arch, uint64_t addr, int64_t offset, size_t size); - RegisterValue GetStackContentsAtLowLevelILInstruction(size_t i, int64_t offset, size_t size); - RegisterValue GetStackContentsAfterLowLevelILInstruction(size_t i, int64_t offset, size_t size); RegisterValue GetParameterValueAtInstruction(Architecture* arch, uint64_t addr, Type* functionType, size_t i); RegisterValue GetParameterValueAtLowLevelILInstruction(size_t instr, Type* functionType, size_t i); std::vector GetRegistersReadByInstruction(Architecture* arch, uint64_t addr); @@ -2183,6 +2179,20 @@ namespace BinaryNinja RegisterValue GetSSAFlagValue(uint32_t flag, size_t idx); RegisterValue GetExprValue(size_t expr); + RegisterValue GetPossibleExprValues(size_t expr); + + RegisterValue GetRegisterValueAtInstruction(uint32_t reg, size_t instr); + RegisterValue GetRegisterValueAfterInstruction(uint32_t reg, size_t instr); + RegisterValue GetPossibleRegisterValuesAtInstruction(uint32_t reg, size_t instr); + RegisterValue GetPossibleRegisterValuesAfterInstruction(uint32_t reg, size_t instr); + RegisterValue GetFlagValueAtInstruction(uint32_t flag, size_t instr); + RegisterValue GetFlagValueAfterInstruction(uint32_t flag, size_t instr); + RegisterValue GetPossibleFlagValuesAtInstruction(uint32_t flag, size_t instr); + RegisterValue GetPossibleFlagValuesAfterInstruction(uint32_t flag, size_t instr); + RegisterValue GetStackContentsAtInstruction(int32_t offset, size_t len, size_t instr); + RegisterValue GetStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr); + RegisterValue GetPossibleStackContentsAtInstruction(int32_t offset, size_t len, size_t instr); + RegisterValue GetPossibleStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr); Ref GetMediumLevelIL() const; Ref GetMappedMediumLevelIL() const; @@ -2272,6 +2282,22 @@ namespace BinaryNinja size_t GetSSAVarIndexAtInstruction(const BNILVariable& var, size_t instr) const; size_t GetSSAMemoryIndexAtInstruction(size_t instr) const; + BNILVariable GetVariableForRegisterAtInstruction(uint32_t reg, size_t instr) const; + BNILVariable GetVariableForFlagAtInstruction(uint32_t flag, size_t instr) const; + BNILVariable GetVariableForStackLocationAtInstruction(int64_t offset, size_t instr) const; + + RegisterValue GetRegisterValueAtInstruction(uint32_t reg, size_t instr); + RegisterValue GetRegisterValueAfterInstruction(uint32_t reg, size_t instr); + RegisterValue GetPossibleRegisterValuesAtInstruction(uint32_t reg, size_t instr); + RegisterValue GetPossibleRegisterValuesAfterInstruction(uint32_t reg, size_t instr); + RegisterValue GetFlagValueAtInstruction(uint32_t flag, size_t instr); + RegisterValue GetFlagValueAfterInstruction(uint32_t flag, size_t instr); + RegisterValue GetPossibleFlagValuesAtInstruction(uint32_t flag, size_t instr); + RegisterValue GetPossibleFlagValuesAfterInstruction(uint32_t flag, size_t instr); + RegisterValue GetStackContentsAtInstruction(int32_t offset, size_t len, size_t instr); + RegisterValue GetStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr); + RegisterValue GetPossibleStackContentsAtInstruction(int32_t offset, size_t len, size_t instr); + RegisterValue GetPossibleStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr); BNILBranchDependence GetBranchDependenceAtInstruction(size_t curInstr, size_t branchInstr) const; std::map GetAllBranchDependenceAtInstruction(size_t instr) const; diff --git a/binaryninjacore.h b/binaryninjacore.h index 4905a73c..eaba1a51 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1848,16 +1848,10 @@ extern "C" uint64_t addr, uint32_t reg); BINARYNINJACOREAPI BNRegisterValue BNGetRegisterValueAfterInstruction(BNFunction* func, BNArchitecture* arch, uint64_t addr, uint32_t reg); - BINARYNINJACOREAPI BNRegisterValue BNGetRegisterValueAtLowLevelILInstruction(BNFunction* func, size_t i, uint32_t reg); - BINARYNINJACOREAPI BNRegisterValue BNGetRegisterValueAfterLowLevelILInstruction(BNFunction* func, size_t i, uint32_t reg); BINARYNINJACOREAPI BNRegisterValue BNGetStackContentsAtInstruction(BNFunction* func, BNArchitecture* arch, uint64_t addr, int64_t offset, size_t size); BINARYNINJACOREAPI BNRegisterValue BNGetStackContentsAfterInstruction(BNFunction* func, BNArchitecture* arch, uint64_t addr, int64_t offset, size_t size); - BINARYNINJACOREAPI BNRegisterValue BNGetStackContentsAtLowLevelILInstruction(BNFunction* func, size_t i, - int64_t offset, size_t size); - BINARYNINJACOREAPI BNRegisterValue BNGetStackContentsAfterLowLevelILInstruction(BNFunction* func, size_t i, - int64_t offset, size_t size); BINARYNINJACOREAPI BNRegisterValue BNGetParameterValueAtInstruction(BNFunction* func, BNArchitecture* arch, uint64_t addr, BNType* functionType, size_t i); BINARYNINJACOREAPI BNRegisterValue BNGetParameterValueAtLowLevelILInstruction(BNFunction* func, size_t instr, @@ -2186,6 +2180,32 @@ extern "C" uint32_t flag, size_t idx); BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILExprValue(BNLowLevelILFunction* func, size_t expr); + BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILPossibleExprValues(BNLowLevelILFunction* func, size_t expr); + + BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILRegisterValueAtInstruction(BNLowLevelILFunction* func, + uint32_t reg, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILRegisterValueAfterInstruction(BNLowLevelILFunction* func, + uint32_t reg, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILPossibleRegisterValuesAtInstruction(BNLowLevelILFunction* func, + uint32_t reg, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILPossibleRegisterValuesAfterInstruction(BNLowLevelILFunction* func, + uint32_t reg, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILFlagValueAtInstruction(BNLowLevelILFunction* func, + uint32_t flag, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILFlagValueAfterInstruction(BNLowLevelILFunction* func, + uint32_t flag, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILPossibleFlagValuesAtInstruction(BNLowLevelILFunction* func, + uint32_t flag, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILPossibleFlagValuesAfterInstruction(BNLowLevelILFunction* func, + uint32_t flag, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILStackContentsAtInstruction(BNLowLevelILFunction* func, + int64_t offset, size_t len, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILStackContentsAfterInstruction(BNLowLevelILFunction* func, + int64_t offset, size_t len, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILPossibleStackContentsAtInstruction(BNLowLevelILFunction* func, + int64_t offset, size_t len, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILPossibleStackContentsAfterInstruction(BNLowLevelILFunction* func, + int64_t offset, size_t len, size_t instr); BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetMediumLevelILForLowLevelIL(BNLowLevelILFunction* func); BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetMappedMediumLevelIL(BNLowLevelILFunction* func); @@ -2258,6 +2278,37 @@ extern "C" const BNILVariable* var, size_t instr); BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAMemoryIndexAtILInstruction(BNMediumLevelILFunction* func, size_t instr); + BINARYNINJACOREAPI BNILVariable BNGetMediumLevelILVariableForRegisterAtInstruction(BNMediumLevelILFunction* func, + uint32_t reg, size_t instr); + BINARYNINJACOREAPI BNILVariable BNGetMediumLevelILVariableForFlagAtInstruction(BNMediumLevelILFunction* func, + uint32_t flag, size_t instr); + BINARYNINJACOREAPI BNILVariable BNGetMediumLevelILVariableForStackLocationAtInstruction(BNMediumLevelILFunction* func, + int64_t offset, size_t instr); + + BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILRegisterValueAtInstruction(BNMediumLevelILFunction* func, + uint32_t reg, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILRegisterValueAfterInstruction(BNMediumLevelILFunction* func, + uint32_t reg, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleRegisterValuesAtInstruction(BNMediumLevelILFunction* func, + uint32_t reg, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleRegisterValuesAfterInstruction(BNMediumLevelILFunction* func, + uint32_t reg, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILFlagValueAtInstruction(BNMediumLevelILFunction* func, + uint32_t flag, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILFlagValueAfterInstruction(BNMediumLevelILFunction* func, + uint32_t flag, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleFlagValuesAtInstruction(BNMediumLevelILFunction* func, + uint32_t flag, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleFlagValuesAfterInstruction(BNMediumLevelILFunction* func, + uint32_t flag, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILStackContentsAtInstruction(BNMediumLevelILFunction* func, + int64_t offset, size_t len, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILStackContentsAfterInstruction(BNMediumLevelILFunction* func, + int64_t offset, size_t len, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleStackContentsAtInstruction(BNMediumLevelILFunction* func, + int64_t offset, size_t len, size_t instr); + BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleStackContentsAfterInstruction(BNMediumLevelILFunction* func, + int64_t offset, size_t len, size_t instr); BINARYNINJACOREAPI BNILBranchDependence BNGetMediumLevelILBranchDependence(BNMediumLevelILFunction* func, size_t curInstr, size_t branchInstr); diff --git a/function.cpp b/function.cpp index 9faf68fa..aa56f7af 100644 --- a/function.cpp +++ b/function.cpp @@ -205,20 +205,6 @@ RegisterValue Function::GetRegisterValueAfterInstruction(Architecture* arch, uin } -RegisterValue Function::GetRegisterValueAtLowLevelILInstruction(size_t i, uint32_t reg) -{ - BNRegisterValue value = BNGetRegisterValueAtLowLevelILInstruction(m_object, i, reg); - return RegisterValue::FromAPIObject(value); -} - - -RegisterValue Function::GetRegisterValueAfterLowLevelILInstruction(size_t i, uint32_t reg) -{ - BNRegisterValue value = BNGetRegisterValueAfterLowLevelILInstruction(m_object, i, reg); - return RegisterValue::FromAPIObject(value); -} - - RegisterValue Function::GetStackContentsAtInstruction(Architecture* arch, uint64_t addr, int64_t offset, size_t size) { BNRegisterValue value = BNGetStackContentsAtInstruction(m_object, arch->GetObject(), addr, offset, size); @@ -233,20 +219,6 @@ RegisterValue Function::GetStackContentsAfterInstruction(Architecture* arch, uin } -RegisterValue Function::GetStackContentsAtLowLevelILInstruction(size_t i, int64_t offset, size_t size) -{ - BNRegisterValue value = BNGetStackContentsAtLowLevelILInstruction(m_object, i, offset, size); - return RegisterValue::FromAPIObject(value); -} - - -RegisterValue Function::GetStackContentsAfterLowLevelILInstruction(size_t i, int64_t offset, size_t size) -{ - BNRegisterValue value = BNGetStackContentsAfterLowLevelILInstruction(m_object, i, offset, size); - return RegisterValue::FromAPIObject(value); -} - - RegisterValue Function::GetParameterValueAtInstruction(Architecture* arch, uint64_t addr, Type* functionType, size_t i) { BNRegisterValue value = BNGetParameterValueAtInstruction(m_object, arch->GetObject(), addr, diff --git a/lowlevelil.cpp b/lowlevelil.cpp index bd038b6e..54e26498 100644 --- a/lowlevelil.cpp +++ b/lowlevelil.cpp @@ -780,6 +780,97 @@ RegisterValue LowLevelILFunction::GetExprValue(size_t expr) } +RegisterValue LowLevelILFunction::GetPossibleExprValues(size_t expr) +{ + BNRegisterValue value = BNGetLowLevelILPossibleExprValues(m_object, expr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue LowLevelILFunction::GetRegisterValueAtInstruction(uint32_t reg, size_t instr) +{ + BNRegisterValue value = BNGetLowLevelILRegisterValueAtInstruction(m_object, reg, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue LowLevelILFunction::GetRegisterValueAfterInstruction(uint32_t reg, size_t instr) +{ + BNRegisterValue value = BNGetLowLevelILRegisterValueAfterInstruction(m_object, reg, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue LowLevelILFunction::GetPossibleRegisterValuesAtInstruction(uint32_t reg, size_t instr) +{ + BNRegisterValue value = BNGetLowLevelILPossibleRegisterValuesAtInstruction(m_object, reg, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue LowLevelILFunction::GetPossibleRegisterValuesAfterInstruction(uint32_t reg, size_t instr) +{ + BNRegisterValue value = BNGetLowLevelILPossibleRegisterValuesAfterInstruction(m_object, reg, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue LowLevelILFunction::GetFlagValueAtInstruction(uint32_t flag, size_t instr) +{ + BNRegisterValue value = BNGetLowLevelILFlagValueAtInstruction(m_object, flag, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue LowLevelILFunction::GetFlagValueAfterInstruction(uint32_t flag, size_t instr) +{ + BNRegisterValue value = BNGetLowLevelILFlagValueAfterInstruction(m_object, flag, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue LowLevelILFunction::GetPossibleFlagValuesAtInstruction(uint32_t flag, size_t instr) +{ + BNRegisterValue value = BNGetLowLevelILPossibleFlagValuesAtInstruction(m_object, flag, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue LowLevelILFunction::GetPossibleFlagValuesAfterInstruction(uint32_t flag, size_t instr) +{ + BNRegisterValue value = BNGetLowLevelILPossibleFlagValuesAfterInstruction(m_object, flag, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue LowLevelILFunction::GetStackContentsAtInstruction(int32_t offset, size_t len, size_t instr) +{ + BNRegisterValue value = BNGetLowLevelILStackContentsAtInstruction(m_object, offset, len, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue LowLevelILFunction::GetStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr) +{ + BNRegisterValue value = BNGetLowLevelILStackContentsAfterInstruction(m_object, offset, len, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue LowLevelILFunction::GetPossibleStackContentsAtInstruction(int32_t offset, size_t len, size_t instr) +{ + BNRegisterValue value = BNGetLowLevelILPossibleStackContentsAtInstruction(m_object, offset, len, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue LowLevelILFunction::GetPossibleStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr) +{ + BNRegisterValue value = BNGetLowLevelILPossibleStackContentsAfterInstruction(m_object, offset, len, instr); + return RegisterValue::FromAPIObject(value); +} + + Ref LowLevelILFunction::GetMediumLevelIL() const { BNMediumLevelILFunction* func = BNGetMediumLevelILForLowLevelIL(m_object); diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index 51dd067d..bb629e64 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -476,6 +476,108 @@ size_t MediumLevelILFunction::GetSSAMemoryIndexAtInstruction(size_t instr) const } +BNILVariable MediumLevelILFunction::GetVariableForRegisterAtInstruction(uint32_t reg, size_t instr) const +{ + return BNGetMediumLevelILVariableForRegisterAtInstruction(m_object, reg, instr); +} + + +BNILVariable MediumLevelILFunction::GetVariableForFlagAtInstruction(uint32_t flag, size_t instr) const +{ + return BNGetMediumLevelILVariableForFlagAtInstruction(m_object, flag, instr); +} + + +BNILVariable MediumLevelILFunction::GetVariableForStackLocationAtInstruction(int64_t offset, size_t instr) const +{ + return BNGetMediumLevelILVariableForStackLocationAtInstruction(m_object, offset, instr); +} + + +RegisterValue MediumLevelILFunction::GetRegisterValueAtInstruction(uint32_t reg, size_t instr) +{ + BNRegisterValue value = BNGetMediumLevelILRegisterValueAtInstruction(m_object, reg, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue MediumLevelILFunction::GetRegisterValueAfterInstruction(uint32_t reg, size_t instr) +{ + BNRegisterValue value = BNGetMediumLevelILRegisterValueAfterInstruction(m_object, reg, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue MediumLevelILFunction::GetPossibleRegisterValuesAtInstruction(uint32_t reg, size_t instr) +{ + BNRegisterValue value = BNGetMediumLevelILPossibleRegisterValuesAtInstruction(m_object, reg, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue MediumLevelILFunction::GetPossibleRegisterValuesAfterInstruction(uint32_t reg, size_t instr) +{ + BNRegisterValue value = BNGetMediumLevelILPossibleRegisterValuesAfterInstruction(m_object, reg, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue MediumLevelILFunction::GetFlagValueAtInstruction(uint32_t flag, size_t instr) +{ + BNRegisterValue value = BNGetMediumLevelILFlagValueAtInstruction(m_object, flag, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue MediumLevelILFunction::GetFlagValueAfterInstruction(uint32_t flag, size_t instr) +{ + BNRegisterValue value = BNGetMediumLevelILFlagValueAfterInstruction(m_object, flag, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue MediumLevelILFunction::GetPossibleFlagValuesAtInstruction(uint32_t flag, size_t instr) +{ + BNRegisterValue value = BNGetMediumLevelILPossibleFlagValuesAtInstruction(m_object, flag, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue MediumLevelILFunction::GetPossibleFlagValuesAfterInstruction(uint32_t flag, size_t instr) +{ + BNRegisterValue value = BNGetMediumLevelILPossibleFlagValuesAfterInstruction(m_object, flag, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue MediumLevelILFunction::GetStackContentsAtInstruction(int32_t offset, size_t len, size_t instr) +{ + BNRegisterValue value = BNGetMediumLevelILStackContentsAtInstruction(m_object, offset, len, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue MediumLevelILFunction::GetStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr) +{ + BNRegisterValue value = BNGetMediumLevelILStackContentsAfterInstruction(m_object, offset, len, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue MediumLevelILFunction::GetPossibleStackContentsAtInstruction(int32_t offset, size_t len, size_t instr) +{ + BNRegisterValue value = BNGetMediumLevelILPossibleStackContentsAtInstruction(m_object, offset, len, instr); + return RegisterValue::FromAPIObject(value); +} + + +RegisterValue MediumLevelILFunction::GetPossibleStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr) +{ + BNRegisterValue value = BNGetMediumLevelILPossibleStackContentsAfterInstruction(m_object, offset, len, instr); + return RegisterValue::FromAPIObject(value); +} + + BNILBranchDependence MediumLevelILFunction::GetBranchDependenceAtInstruction(size_t curInstr, size_t branchInstr) const { return BNGetMediumLevelILBranchDependence(m_object, curInstr, branchInstr); diff --git a/python/function.py b/python/function.py index ed2a537c..928597a7 100644 --- a/python/function.py +++ b/python/function.py @@ -459,36 +459,6 @@ class Function(object): core.BNFreeRegisterValue(value) return result - def get_reg_value_at_low_level_il_instruction(self, i, reg, arch=None): - """ - ``get_reg_value_at_low_level_il_instruction`` returns the value of the specified register ``reg`` at the il address - i - - :param int i: il address of instruction to query - :param Architecture arch: (optional) Architecture for the given function - :rtype: function.RegisterValue - :Example: - - >>> func.get_reg_value_at_low_level_il_instruction(15, 'rdi') - - """ - if arch is None: - arch = self.arch - if isinstance(reg, str): - reg = self.arch.regs[reg].index - value = core.BNGetRegisterValueAtLowLevelILInstruction(self.handle, i, reg) - result = RegisterValue(arch, value) - core.BNFreeRegisterValue(value) - return result - - def get_reg_value_after_low_level_il_instruction(self, i, reg): - if isinstance(reg, str): - reg = self.arch.regs[reg].index - value = core.BNGetRegisterValueAfterLowLevelILInstruction(self.handle, i, reg) - result = RegisterValue(self.arch, value) - core.BNFreeRegisterValue(value) - return result - def get_stack_contents_at(self, addr, offset, size, arch=None): """ ``get_stack_contents_at`` returns the RegisterValue for the item on the stack in the current function at the @@ -523,18 +493,6 @@ class Function(object): core.BNFreeRegisterValue(value) return result - def get_stack_contents_at_low_level_il_instruction(self, i, offset, size): - value = core.BNGetStackContentsAtLowLevelILInstruction(self.handle, i, offset, size) - result = RegisterValue(self.arch, value) - core.BNFreeRegisterValue(value) - return result - - def get_stack_contents_after_low_level_il_instruction(self, i, offset, size): - value = core.BNGetStackContentsAfterInstruction(self.handle, i, offset, size) - result = RegisterValue(self.arch, value) - core.BNFreeRegisterValue(value) - return result - def get_parameter_at(self, addr, func_type, i, arch=None): if arch is None: arch = self.arch diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 462d4ade..74b030d7 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -260,12 +260,108 @@ class LowLevelILInstruction(object): @property def value(self): - """Value of expression using static data flow analysis (read-only)""" + """Value of expression if constant or a known value (read-only)""" value = core.BNGetLowLevelILExprValue(self.function.handle, self.expr_index) result = function.RegisterValue(self.function.arch, value) core.BNFreeRegisterValue(value) return result + @property + def possible_values(self): + """Possible values of expression using path-sensitive static data flow analysis (read-only)""" + value = core.BNGetLowLevelILPossibleExprValues(self.function.handle, self.expr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_reg_value(self, reg): + if isinstance(reg, str): + reg = self.function.arch.regs[reg].index + value = core.BNGetLowLevelILRegisterValueAtInstruction(self.function.handle, reg, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_reg_value_after(self, reg): + if isinstance(reg, str): + reg = self.function.arch.regs[reg].index + value = core.BNGetLowLevelILRegisterValueAfterInstruction(self.function.handle, reg, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_possible_reg_values(self, reg): + if isinstance(reg, str): + reg = self.function.arch.regs[reg].index + value = core.BNGetLowLevelILPossibleRegisterValuesAtInstruction(self.function.handle, reg, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_possible_reg_values_after(self, reg): + if isinstance(reg, str): + reg = self.function.arch.regs[reg].index + value = core.BNGetLowLevelILPossibleRegisterValuesAfterInstruction(self.function.handle, reg, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_flag_value(self, flag): + if isinstance(flag, str): + flag = self.function.arch.flags[flag].index + value = core.BNGetLowLevelILFlagValueAtInstruction(self.function.handle, flag, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_flag_value_after(self, flag): + if isinstance(flag, str): + flag = self.function.arch.flags[flag].index + value = core.BNGetLowLevelILFlagValueAfterInstruction(self.function.handle, flag, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_possible_flag_values(self, flag): + if isinstance(flag, str): + flag = self.function.arch.flags[flag].index + value = core.BNGetLowLevelILPossibleFlagValuesAtInstruction(self.function.handle, flag, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_possible_flag_values_after(self, flag): + if isinstance(flag, str): + flag = self.function.arch.flags[flag].index + value = core.BNGetLowLevelILPossibleFlagValuesAfterInstruction(self.function.handle, flag, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_stack_contents(self, offset, size): + value = core.BNGetLowLevelILStackContentsAtInstruction(self.function.handle, offset, size, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_stack_contents_after(self, offset, size): + value = core.BNGetLowLevelILStackContentsAfterInstruction(self.function.handle, offset, size, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_possible_stack_contents(self, offset, size): + value = core.BNGetLowLevelILPossibleStackContentsAtInstruction(self.function.handle, offset, size, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_possible_stack_contents_after(self, offset, size): + value = core.BNGetLowLevelILPossibleStackContentsAfterInstruction(self.function.handle, offset, size, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + def __setattr__(self, name, value): try: object.__setattr__(self, name, value) diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index a63e1b31..6f482221 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -274,7 +274,13 @@ class MediumLevelILInstruction(object): @property def branch_dependence(self): """Set of branching instructions that must take the true or false path to reach this instruction""" - return self.function.get_all_branch_dependence_at_instruction(self.instr_index) + count = ctypes.c_ulonglong() + deps = core.BNGetAllMediumLevelILBranchDependence(self.function.handle, self.instr_index, count) + result = {} + for i in xrange(0, count.value): + result[deps[i].branch] = ILBranchDependence(deps[i].dependence) + core.BNFreeILBranchDependenceList(deps) + return result @property def low_level_il(self): @@ -284,6 +290,11 @@ class MediumLevelILInstruction(object): return None return lowlevelil.LowLevelILInstruction(self.function.low_level_il.ssa_form, expr) + @property + def ssa_memory_index(self): + """Index of active memory contents in SSA form for this instruction""" + return core.BNGetMediumLevelILSSAMemoryIndexAtILInstruction(self.function.handle, self.instr_index) + def get_ssa_var_possible_values(self, var, index): var_data = core.BNILVariable() var_data.type = var.type @@ -294,6 +305,120 @@ class MediumLevelILInstruction(object): core.BNFreeRegisterValue(value) return result + def get_ssa_var_index(self, var): + var_data = core.BNILVariable() + var_data.type = var.type + var_data.index = var.index + var_data.identifier = var.identifier + return core.BNGetMediumLevelILSSAVarIndexAtILInstruction(self.function.handle, var_data, self.instr_index) + + def get_var_for_reg(self, reg): + if isinstance(reg, str): + reg = self.function.arch.regs[reg].index + result = core.BNGetMediumLevelILVariableForRegisterAtInstruction(self.function.handle, reg, self.instr_index) + return function.ILVariable(self.function.source_function, result.type, result.index, result.identifier) + + def get_var_for_flag(self, flag): + if isinstance(flag, str): + flag = self.function.arch.regs[flag].index + result = core.BNGetMediumLevelILVariableForFlagAtInstruction(self.function.handle, flag, self.instr_index) + return function.ILVariable(self.function.source_function, result.type, result.index, result.identifier) + + def get_var_for_stack_location(self, offset): + result = core.BNGetMediumLevelILVariableForStackLocationAtInstruction(self.function.handle, offset, self.instr_index) + return function.ILVariable(self.function.source_function, result.type, result.index, result.identifier) + + def get_reg_value(self, reg): + if isinstance(reg, str): + reg = self.function.arch.regs[reg].index + value = core.BNGetMediumLevelILRegisterValueAtInstruction(self.function.handle, reg, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_reg_value_after(self, reg): + if isinstance(reg, str): + reg = self.function.arch.regs[reg].index + value = core.BNGetMediumLevelILRegisterValueAfterInstruction(self.function.handle, reg, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_possible_reg_values(self, reg): + if isinstance(reg, str): + reg = self.function.arch.regs[reg].index + value = core.BNGetMediumLevelILPossibleRegisterValuesAtInstruction(self.function.handle, reg, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_possible_reg_values_after(self, reg): + if isinstance(reg, str): + reg = self.function.arch.regs[reg].index + value = core.BNGetMediumLevelILPossibleRegisterValuesAfterInstruction(self.function.handle, reg, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_flag_value(self, flag): + if isinstance(flag, str): + flag = self.function.arch.flags[flag].index + value = core.BNGetMediumLevelILFlagValueAtInstruction(self.function.handle, flag, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_flag_value_after(self, flag): + if isinstance(flag, str): + flag = self.function.arch.flags[flag].index + value = core.BNGetMediumLevelILFlagValueAfterInstruction(self.function.handle, flag, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_possible_flag_values(self, flag): + if isinstance(flag, str): + flag = self.function.arch.flags[flag].index + value = core.BNGetMediumLevelILPossibleFlagValuesAtInstruction(self.function.handle, flag, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_possible_flag_values_after(self, flag): + if isinstance(flag, str): + flag = self.function.arch.flags[flag].index + value = core.BNGetMediumLevelILPossibleFlagValuesAfterInstruction(self.function.handle, flag, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_stack_contents(self, offset, size): + value = core.BNGetMediumLevelILStackContentsAtInstruction(self.function.handle, offset, size, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_stack_contents_after(self, offset, size): + value = core.BNGetMediumLevelILStackContentsAfterInstruction(self.function.handle, offset, size, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_possible_stack_contents(self, offset, size): + value = core.BNGetMediumLevelILPossibleStackContentsAtInstruction(self.function.handle, offset, size, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_possible_stack_contents_after(self, offset, size): + value = core.BNGetMediumLevelILPossibleStackContentsAfterInstruction(self.function.handle, offset, size, self.instr_index) + result = function.RegisterValue(self.function.arch, value) + core.BNFreeRegisterValue(value) + return result + + def get_branch_dependence(self, branch_instr): + return ILBranchDependence(core.BNGetMediumLevelILBranchDependence(self.function.handle, self.instr_index, branch_instr)) + def __setattr__(self, name, value): try: object.__setattr__(self, name, value) @@ -584,28 +709,6 @@ class MediumLevelILFunction(object): core.BNFreeRegisterValue(value) return result - def get_ssa_var_index_at_instruction(self, var, instr): - var_data = core.BNILVariable() - var_data.type = var.type - var_data.index = var.index - var_data.identifier = var.identifier - return core.BNGetMediumLevelILSSAVarIndexAtILInstruction(self.handle, var_data, instr) - - def get_ssa_memory_index_at_instruction(self, instr): - return core.BNGetMediumLevelILSSAMemoryIndexAtILInstruction(self.handle, instr) - - def get_branch_dependence_at_instruction(self, cur_instr, branch_instr): - return ILBranchDependence(core.BNGetMediumLevelILBranchDependence(self.handle, cur_instr, branch_instr)) - - def get_all_branch_dependence_at_instruction(self, instr): - count = ctypes.c_ulonglong() - deps = core.BNGetAllMediumLevelILBranchDependence(self.handle, instr, count) - result = {} - for i in xrange(0, count.value): - result[deps[i].branch] = ILBranchDependence(deps[i].dependence) - core.BNFreeILBranchDependenceList(deps) - return result - def get_low_level_il_instruction_index(self, instr): low_il = self.low_level_il if low_il is None: -- cgit v1.3.1 From cb244a62fea649d6840b70b8e7fe7953eb3acc5a Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Wed, 22 Mar 2017 22:43:16 -0400 Subject: Adding new value object to hold disjoint sets --- binaryninjaapi.h | 46 +++++++++++++++----------- binaryninjacore.h | 60 +++++++++++++++++++++------------- function.cpp | 27 ++++++++++++---- lowlevelil.cpp | 42 ++++++++++++------------ mediumlevelil.cpp | 48 +++++++++++++-------------- python/function.py | 86 ++++++++++++++++++++++++++++++++++++------------- python/lowlevelil.py | 37 ++++++++------------- python/mediumlevelil.py | 37 ++++++++------------- 8 files changed, 223 insertions(+), 160 deletions(-) (limited to 'python/mediumlevelil.py') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 131d6a17..af0cf5ce 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1853,14 +1853,22 @@ namespace BinaryNinja struct RegisterValue { BNRegisterValueType state; - uint32_t reg; // For EntryValue and OffsetFromEntryValue, the original input register - int64_t value; // Offset for OffsetFromEntryValue, StackFrameOffset or RangeValue, value of register for ConstantValue - uint64_t rangeStart, rangeEnd, rangeStep; // Range of register, inclusive - std::vector table; + int64_t value; static RegisterValue FromAPIObject(BNRegisterValue& value); }; + struct PossibleValueSet + { + BNRegisterValueType state; + int64_t value; + std::vector ranges; + std::set valueSet; + std::vector table; + + static PossibleValueSet FromAPIObject(BNPossibleValueSet& value); + }; + class FunctionGraph; class MediumLevelILFunction; @@ -2179,20 +2187,20 @@ namespace BinaryNinja RegisterValue GetSSAFlagValue(uint32_t flag, size_t idx); RegisterValue GetExprValue(size_t expr); - RegisterValue GetPossibleExprValues(size_t expr); + PossibleValueSet GetPossibleExprValues(size_t expr); RegisterValue GetRegisterValueAtInstruction(uint32_t reg, size_t instr); RegisterValue GetRegisterValueAfterInstruction(uint32_t reg, size_t instr); - RegisterValue GetPossibleRegisterValuesAtInstruction(uint32_t reg, size_t instr); - RegisterValue GetPossibleRegisterValuesAfterInstruction(uint32_t reg, size_t instr); + PossibleValueSet GetPossibleRegisterValuesAtInstruction(uint32_t reg, size_t instr); + PossibleValueSet GetPossibleRegisterValuesAfterInstruction(uint32_t reg, size_t instr); RegisterValue GetFlagValueAtInstruction(uint32_t flag, size_t instr); RegisterValue GetFlagValueAfterInstruction(uint32_t flag, size_t instr); - RegisterValue GetPossibleFlagValuesAtInstruction(uint32_t flag, size_t instr); - RegisterValue GetPossibleFlagValuesAfterInstruction(uint32_t flag, size_t instr); + PossibleValueSet GetPossibleFlagValuesAtInstruction(uint32_t flag, size_t instr); + PossibleValueSet GetPossibleFlagValuesAfterInstruction(uint32_t flag, size_t instr); RegisterValue GetStackContentsAtInstruction(int32_t offset, size_t len, size_t instr); RegisterValue GetStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr); - RegisterValue GetPossibleStackContentsAtInstruction(int32_t offset, size_t len, size_t instr); - RegisterValue GetPossibleStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr); + PossibleValueSet GetPossibleStackContentsAtInstruction(int32_t offset, size_t len, size_t instr); + PossibleValueSet GetPossibleStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr); Ref GetMediumLevelIL() const; Ref GetMappedMediumLevelIL() const; @@ -2277,8 +2285,8 @@ namespace BinaryNinja RegisterValue GetSSAVarValue(const BNILVariable& var, size_t idx); RegisterValue GetExprValue(size_t expr); - RegisterValue GetPossibleSSAVarValues(const BNILVariable& var, size_t idx, size_t instr); - RegisterValue GetPossibleExprValues(size_t expr); + PossibleValueSet GetPossibleSSAVarValues(const BNILVariable& var, size_t idx, size_t instr); + PossibleValueSet GetPossibleExprValues(size_t expr); size_t GetSSAVarIndexAtInstruction(const BNILVariable& var, size_t instr) const; size_t GetSSAMemoryIndexAtInstruction(size_t instr) const; @@ -2288,16 +2296,16 @@ namespace BinaryNinja RegisterValue GetRegisterValueAtInstruction(uint32_t reg, size_t instr); RegisterValue GetRegisterValueAfterInstruction(uint32_t reg, size_t instr); - RegisterValue GetPossibleRegisterValuesAtInstruction(uint32_t reg, size_t instr); - RegisterValue GetPossibleRegisterValuesAfterInstruction(uint32_t reg, size_t instr); + PossibleValueSet GetPossibleRegisterValuesAtInstruction(uint32_t reg, size_t instr); + PossibleValueSet GetPossibleRegisterValuesAfterInstruction(uint32_t reg, size_t instr); RegisterValue GetFlagValueAtInstruction(uint32_t flag, size_t instr); RegisterValue GetFlagValueAfterInstruction(uint32_t flag, size_t instr); - RegisterValue GetPossibleFlagValuesAtInstruction(uint32_t flag, size_t instr); - RegisterValue GetPossibleFlagValuesAfterInstruction(uint32_t flag, size_t instr); + PossibleValueSet GetPossibleFlagValuesAtInstruction(uint32_t flag, size_t instr); + PossibleValueSet GetPossibleFlagValuesAfterInstruction(uint32_t flag, size_t instr); RegisterValue GetStackContentsAtInstruction(int32_t offset, size_t len, size_t instr); RegisterValue GetStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr); - RegisterValue GetPossibleStackContentsAtInstruction(int32_t offset, size_t len, size_t instr); - RegisterValue GetPossibleStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr); + PossibleValueSet GetPossibleStackContentsAtInstruction(int32_t offset, size_t len, size_t instr); + PossibleValueSet GetPossibleStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr); BNILBranchDependence GetBranchDependenceAtInstruction(size_t curInstr, size_t branchInstr) const; std::map GetAllBranchDependenceAtInstruction(size_t instr) const; diff --git a/binaryninjacore.h b/binaryninjacore.h index feea147d..c43c9b21 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -600,14 +600,18 @@ extern "C" enum BNRegisterValueType { + UndeterminedValue, EntryValue, ConstantValue, StackFrameOffset, - UndeterminedValue, + ReturnAddressValue, + + // The following are only valid in BNPossibleValueSet SignedRangeValue, UnsignedRangeValue, LookupTableValue, - ReturnAddressValue + InSetOfValues, + NotInSetOfValues }; struct BNLookupTableEntry @@ -620,10 +624,22 @@ extern "C" struct BNRegisterValue { BNRegisterValueType state; - uint32_t reg; // For EntryValue and OffsetFromEntryValue, the original input register - int64_t value; // Offset for OffsetFromEntryValue, StackFrameOffset or RangeValue, value of register for ConstantValue - uint64_t rangeStart, rangeEnd, rangeStep; // Range of register, inclusive - BNLookupTableEntry* table; // Number of entries in rangeEnd + int64_t value; + }; + + struct BNValueRange + { + uint64_t start, end, step; + }; + + struct BNPossibleValueSet + { + BNRegisterValueType state; + int64_t value; + BNValueRange* ranges; + int64_t* valueSet; + BNLookupTableEntry* table; + size_t count; }; struct BNRegisterOrConstant @@ -1852,7 +1868,7 @@ extern "C" uint64_t addr, BNType* functionType, size_t i); BINARYNINJACOREAPI BNRegisterValue BNGetParameterValueAtLowLevelILInstruction(BNFunction* func, size_t instr, BNType* functionType, size_t i); - BINARYNINJACOREAPI void BNFreeRegisterValue(BNRegisterValue* value); + BINARYNINJACOREAPI void BNFreePossibleValueSet(BNPossibleValueSet* value); BINARYNINJACOREAPI uint32_t* BNGetRegistersReadByInstruction(BNFunction* func, BNArchitecture* arch, uint64_t addr, size_t* count); BINARYNINJACOREAPI uint32_t* BNGetRegistersWrittenByInstruction(BNFunction* func, BNArchitecture* arch, uint64_t addr, @@ -2176,31 +2192,31 @@ extern "C" uint32_t flag, size_t idx); BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILExprValue(BNLowLevelILFunction* func, size_t expr); - BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILPossibleExprValues(BNLowLevelILFunction* func, size_t expr); + BINARYNINJACOREAPI BNPossibleValueSet BNGetLowLevelILPossibleExprValues(BNLowLevelILFunction* func, size_t expr); BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILRegisterValueAtInstruction(BNLowLevelILFunction* func, uint32_t reg, size_t instr); BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILRegisterValueAfterInstruction(BNLowLevelILFunction* func, uint32_t reg, size_t instr); - BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILPossibleRegisterValuesAtInstruction(BNLowLevelILFunction* func, + BINARYNINJACOREAPI BNPossibleValueSet BNGetLowLevelILPossibleRegisterValuesAtInstruction(BNLowLevelILFunction* func, uint32_t reg, size_t instr); - BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILPossibleRegisterValuesAfterInstruction(BNLowLevelILFunction* func, + BINARYNINJACOREAPI BNPossibleValueSet BNGetLowLevelILPossibleRegisterValuesAfterInstruction(BNLowLevelILFunction* func, uint32_t reg, size_t instr); BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILFlagValueAtInstruction(BNLowLevelILFunction* func, uint32_t flag, size_t instr); BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILFlagValueAfterInstruction(BNLowLevelILFunction* func, uint32_t flag, size_t instr); - BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILPossibleFlagValuesAtInstruction(BNLowLevelILFunction* func, + BINARYNINJACOREAPI BNPossibleValueSet BNGetLowLevelILPossibleFlagValuesAtInstruction(BNLowLevelILFunction* func, uint32_t flag, size_t instr); - BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILPossibleFlagValuesAfterInstruction(BNLowLevelILFunction* func, + BINARYNINJACOREAPI BNPossibleValueSet BNGetLowLevelILPossibleFlagValuesAfterInstruction(BNLowLevelILFunction* func, uint32_t flag, size_t instr); BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILStackContentsAtInstruction(BNLowLevelILFunction* func, int64_t offset, size_t len, size_t instr); BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILStackContentsAfterInstruction(BNLowLevelILFunction* func, int64_t offset, size_t len, size_t instr); - BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILPossibleStackContentsAtInstruction(BNLowLevelILFunction* func, + BINARYNINJACOREAPI BNPossibleValueSet BNGetLowLevelILPossibleStackContentsAtInstruction(BNLowLevelILFunction* func, int64_t offset, size_t len, size_t instr); - BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILPossibleStackContentsAfterInstruction(BNLowLevelILFunction* func, + BINARYNINJACOREAPI BNPossibleValueSet BNGetLowLevelILPossibleStackContentsAfterInstruction(BNLowLevelILFunction* func, int64_t offset, size_t len, size_t instr); BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetMediumLevelILForLowLevelIL(BNLowLevelILFunction* func); @@ -2266,9 +2282,9 @@ extern "C" BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILSSAVarValue(BNMediumLevelILFunction* func, const BNILVariable* var, size_t idx); BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILExprValue(BNMediumLevelILFunction* func, size_t expr); - BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleSSAVarValues(BNMediumLevelILFunction* func, + BINARYNINJACOREAPI BNPossibleValueSet BNGetMediumLevelILPossibleSSAVarValues(BNMediumLevelILFunction* func, const BNILVariable* var, size_t idx, size_t instr); - BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleExprValues(BNMediumLevelILFunction* func, size_t expr); + BINARYNINJACOREAPI BNPossibleValueSet BNGetMediumLevelILPossibleExprValues(BNMediumLevelILFunction* func, size_t expr); BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAVarIndexAtILInstruction(BNMediumLevelILFunction* func, const BNILVariable* var, size_t instr); @@ -2285,25 +2301,25 @@ extern "C" uint32_t reg, size_t instr); BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILRegisterValueAfterInstruction(BNMediumLevelILFunction* func, uint32_t reg, size_t instr); - BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleRegisterValuesAtInstruction(BNMediumLevelILFunction* func, + BINARYNINJACOREAPI BNPossibleValueSet BNGetMediumLevelILPossibleRegisterValuesAtInstruction(BNMediumLevelILFunction* func, uint32_t reg, size_t instr); - BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleRegisterValuesAfterInstruction(BNMediumLevelILFunction* func, + BINARYNINJACOREAPI BNPossibleValueSet BNGetMediumLevelILPossibleRegisterValuesAfterInstruction(BNMediumLevelILFunction* func, uint32_t reg, size_t instr); BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILFlagValueAtInstruction(BNMediumLevelILFunction* func, uint32_t flag, size_t instr); BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILFlagValueAfterInstruction(BNMediumLevelILFunction* func, uint32_t flag, size_t instr); - BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleFlagValuesAtInstruction(BNMediumLevelILFunction* func, + BINARYNINJACOREAPI BNPossibleValueSet BNGetMediumLevelILPossibleFlagValuesAtInstruction(BNMediumLevelILFunction* func, uint32_t flag, size_t instr); - BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleFlagValuesAfterInstruction(BNMediumLevelILFunction* func, + BINARYNINJACOREAPI BNPossibleValueSet BNGetMediumLevelILPossibleFlagValuesAfterInstruction(BNMediumLevelILFunction* func, uint32_t flag, size_t instr); BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILStackContentsAtInstruction(BNMediumLevelILFunction* func, int64_t offset, size_t len, size_t instr); BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILStackContentsAfterInstruction(BNMediumLevelILFunction* func, int64_t offset, size_t len, size_t instr); - BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleStackContentsAtInstruction(BNMediumLevelILFunction* func, + BINARYNINJACOREAPI BNPossibleValueSet BNGetMediumLevelILPossibleStackContentsAtInstruction(BNMediumLevelILFunction* func, int64_t offset, size_t len, size_t instr); - BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleStackContentsAfterInstruction(BNMediumLevelILFunction* func, + BINARYNINJACOREAPI BNPossibleValueSet BNGetMediumLevelILPossibleStackContentsAfterInstruction(BNMediumLevelILFunction* func, int64_t offset, size_t len, size_t instr); BINARYNINJACOREAPI BNILBranchDependence BNGetMediumLevelILBranchDependence(BNMediumLevelILFunction* func, diff --git a/function.cpp b/function.cpp index aa56f7af..16ad1f1c 100644 --- a/function.cpp +++ b/function.cpp @@ -170,14 +170,19 @@ RegisterValue RegisterValue::FromAPIObject(BNRegisterValue& value) { RegisterValue result; result.state = value.state; - result.reg = value.reg; result.value = value.value; - result.rangeStart = value.rangeStart; - result.rangeEnd = value.rangeEnd; - result.rangeStep = value.rangeStep; + return result; +} + + +PossibleValueSet PossibleValueSet::FromAPIObject(BNPossibleValueSet& value) +{ + PossibleValueSet result; + result.state = value.state; + result.value = value.value; if (value.state == LookupTableValue) { - for (size_t i = 0; i < (size_t)value.rangeEnd; i++) + for (size_t i = 0; i < value.count; i++) { LookupTableEntry entry; entry.fromValues.insert(entry.fromValues.end(), &value.table[i].fromValues[0], @@ -186,7 +191,17 @@ RegisterValue RegisterValue::FromAPIObject(BNRegisterValue& value) result.table.push_back(entry); } } - BNFreeRegisterValue(&value); + else if ((value.state == SignedRangeValue) || (value.state == UnsignedRangeValue)) + { + for (size_t i = 0; i < value.count; i++) + result.ranges.push_back(value.ranges[i]); + } + else if ((value.state == InSetOfValues) || (value.state == NotInSetOfValues)) + { + for (size_t i = 0; i < value.count; i++) + result.valueSet.insert(value.valueSet[i]); + } + BNFreePossibleValueSet(&value); return result; } diff --git a/lowlevelil.cpp b/lowlevelil.cpp index 54e26498..9764445e 100644 --- a/lowlevelil.cpp +++ b/lowlevelil.cpp @@ -780,10 +780,10 @@ RegisterValue LowLevelILFunction::GetExprValue(size_t expr) } -RegisterValue LowLevelILFunction::GetPossibleExprValues(size_t expr) +PossibleValueSet LowLevelILFunction::GetPossibleExprValues(size_t expr) { - BNRegisterValue value = BNGetLowLevelILPossibleExprValues(m_object, expr); - return RegisterValue::FromAPIObject(value); + BNPossibleValueSet value = BNGetLowLevelILPossibleExprValues(m_object, expr); + return PossibleValueSet::FromAPIObject(value); } @@ -801,17 +801,17 @@ RegisterValue LowLevelILFunction::GetRegisterValueAfterInstruction(uint32_t reg, } -RegisterValue LowLevelILFunction::GetPossibleRegisterValuesAtInstruction(uint32_t reg, size_t instr) +PossibleValueSet LowLevelILFunction::GetPossibleRegisterValuesAtInstruction(uint32_t reg, size_t instr) { - BNRegisterValue value = BNGetLowLevelILPossibleRegisterValuesAtInstruction(m_object, reg, instr); - return RegisterValue::FromAPIObject(value); + BNPossibleValueSet value = BNGetLowLevelILPossibleRegisterValuesAtInstruction(m_object, reg, instr); + return PossibleValueSet::FromAPIObject(value); } -RegisterValue LowLevelILFunction::GetPossibleRegisterValuesAfterInstruction(uint32_t reg, size_t instr) +PossibleValueSet LowLevelILFunction::GetPossibleRegisterValuesAfterInstruction(uint32_t reg, size_t instr) { - BNRegisterValue value = BNGetLowLevelILPossibleRegisterValuesAfterInstruction(m_object, reg, instr); - return RegisterValue::FromAPIObject(value); + BNPossibleValueSet value = BNGetLowLevelILPossibleRegisterValuesAfterInstruction(m_object, reg, instr); + return PossibleValueSet::FromAPIObject(value); } @@ -829,17 +829,17 @@ RegisterValue LowLevelILFunction::GetFlagValueAfterInstruction(uint32_t flag, si } -RegisterValue LowLevelILFunction::GetPossibleFlagValuesAtInstruction(uint32_t flag, size_t instr) +PossibleValueSet LowLevelILFunction::GetPossibleFlagValuesAtInstruction(uint32_t flag, size_t instr) { - BNRegisterValue value = BNGetLowLevelILPossibleFlagValuesAtInstruction(m_object, flag, instr); - return RegisterValue::FromAPIObject(value); + BNPossibleValueSet value = BNGetLowLevelILPossibleFlagValuesAtInstruction(m_object, flag, instr); + return PossibleValueSet::FromAPIObject(value); } -RegisterValue LowLevelILFunction::GetPossibleFlagValuesAfterInstruction(uint32_t flag, size_t instr) +PossibleValueSet LowLevelILFunction::GetPossibleFlagValuesAfterInstruction(uint32_t flag, size_t instr) { - BNRegisterValue value = BNGetLowLevelILPossibleFlagValuesAfterInstruction(m_object, flag, instr); - return RegisterValue::FromAPIObject(value); + BNPossibleValueSet value = BNGetLowLevelILPossibleFlagValuesAfterInstruction(m_object, flag, instr); + return PossibleValueSet::FromAPIObject(value); } @@ -857,17 +857,17 @@ RegisterValue LowLevelILFunction::GetStackContentsAfterInstruction(int32_t offse } -RegisterValue LowLevelILFunction::GetPossibleStackContentsAtInstruction(int32_t offset, size_t len, size_t instr) +PossibleValueSet LowLevelILFunction::GetPossibleStackContentsAtInstruction(int32_t offset, size_t len, size_t instr) { - BNRegisterValue value = BNGetLowLevelILPossibleStackContentsAtInstruction(m_object, offset, len, instr); - return RegisterValue::FromAPIObject(value); + BNPossibleValueSet value = BNGetLowLevelILPossibleStackContentsAtInstruction(m_object, offset, len, instr); + return PossibleValueSet::FromAPIObject(value); } -RegisterValue LowLevelILFunction::GetPossibleStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr) +PossibleValueSet LowLevelILFunction::GetPossibleStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr) { - BNRegisterValue value = BNGetLowLevelILPossibleStackContentsAfterInstruction(m_object, offset, len, instr); - return RegisterValue::FromAPIObject(value); + BNPossibleValueSet value = BNGetLowLevelILPossibleStackContentsAfterInstruction(m_object, offset, len, instr); + return PossibleValueSet::FromAPIObject(value); } diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index bb629e64..b0eb83a1 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -450,17 +450,17 @@ RegisterValue MediumLevelILFunction::GetExprValue(size_t expr) } -RegisterValue MediumLevelILFunction::GetPossibleSSAVarValues(const BNILVariable& var, size_t idx, size_t instr) +PossibleValueSet MediumLevelILFunction::GetPossibleSSAVarValues(const BNILVariable& var, size_t idx, size_t instr) { - BNRegisterValue value = BNGetMediumLevelILPossibleSSAVarValues(m_object, &var, idx, instr); - return RegisterValue::FromAPIObject(value); + BNPossibleValueSet value = BNGetMediumLevelILPossibleSSAVarValues(m_object, &var, idx, instr); + return PossibleValueSet::FromAPIObject(value); } -RegisterValue MediumLevelILFunction::GetPossibleExprValues(size_t expr) +PossibleValueSet MediumLevelILFunction::GetPossibleExprValues(size_t expr) { - BNRegisterValue value = BNGetMediumLevelILPossibleExprValues(m_object, expr); - return RegisterValue::FromAPIObject(value); + BNPossibleValueSet value = BNGetMediumLevelILPossibleExprValues(m_object, expr); + return PossibleValueSet::FromAPIObject(value); } @@ -508,17 +508,17 @@ RegisterValue MediumLevelILFunction::GetRegisterValueAfterInstruction(uint32_t r } -RegisterValue MediumLevelILFunction::GetPossibleRegisterValuesAtInstruction(uint32_t reg, size_t instr) +PossibleValueSet MediumLevelILFunction::GetPossibleRegisterValuesAtInstruction(uint32_t reg, size_t instr) { - BNRegisterValue value = BNGetMediumLevelILPossibleRegisterValuesAtInstruction(m_object, reg, instr); - return RegisterValue::FromAPIObject(value); + BNPossibleValueSet value = BNGetMediumLevelILPossibleRegisterValuesAtInstruction(m_object, reg, instr); + return PossibleValueSet::FromAPIObject(value); } -RegisterValue MediumLevelILFunction::GetPossibleRegisterValuesAfterInstruction(uint32_t reg, size_t instr) +PossibleValueSet MediumLevelILFunction::GetPossibleRegisterValuesAfterInstruction(uint32_t reg, size_t instr) { - BNRegisterValue value = BNGetMediumLevelILPossibleRegisterValuesAfterInstruction(m_object, reg, instr); - return RegisterValue::FromAPIObject(value); + BNPossibleValueSet value = BNGetMediumLevelILPossibleRegisterValuesAfterInstruction(m_object, reg, instr); + return PossibleValueSet::FromAPIObject(value); } @@ -536,17 +536,17 @@ RegisterValue MediumLevelILFunction::GetFlagValueAfterInstruction(uint32_t flag, } -RegisterValue MediumLevelILFunction::GetPossibleFlagValuesAtInstruction(uint32_t flag, size_t instr) +PossibleValueSet MediumLevelILFunction::GetPossibleFlagValuesAtInstruction(uint32_t flag, size_t instr) { - BNRegisterValue value = BNGetMediumLevelILPossibleFlagValuesAtInstruction(m_object, flag, instr); - return RegisterValue::FromAPIObject(value); + BNPossibleValueSet value = BNGetMediumLevelILPossibleFlagValuesAtInstruction(m_object, flag, instr); + return PossibleValueSet::FromAPIObject(value); } -RegisterValue MediumLevelILFunction::GetPossibleFlagValuesAfterInstruction(uint32_t flag, size_t instr) +PossibleValueSet MediumLevelILFunction::GetPossibleFlagValuesAfterInstruction(uint32_t flag, size_t instr) { - BNRegisterValue value = BNGetMediumLevelILPossibleFlagValuesAfterInstruction(m_object, flag, instr); - return RegisterValue::FromAPIObject(value); + BNPossibleValueSet value = BNGetMediumLevelILPossibleFlagValuesAfterInstruction(m_object, flag, instr); + return PossibleValueSet::FromAPIObject(value); } @@ -564,17 +564,17 @@ RegisterValue MediumLevelILFunction::GetStackContentsAfterInstruction(int32_t of } -RegisterValue MediumLevelILFunction::GetPossibleStackContentsAtInstruction(int32_t offset, size_t len, size_t instr) +PossibleValueSet MediumLevelILFunction::GetPossibleStackContentsAtInstruction(int32_t offset, size_t len, size_t instr) { - BNRegisterValue value = BNGetMediumLevelILPossibleStackContentsAtInstruction(m_object, offset, len, instr); - return RegisterValue::FromAPIObject(value); + BNPossibleValueSet value = BNGetMediumLevelILPossibleStackContentsAtInstruction(m_object, offset, len, instr); + return PossibleValueSet::FromAPIObject(value); } -RegisterValue MediumLevelILFunction::GetPossibleStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr) +PossibleValueSet MediumLevelILFunction::GetPossibleStackContentsAfterInstruction(int32_t offset, size_t len, size_t instr) { - BNRegisterValue value = BNGetMediumLevelILPossibleStackContentsAfterInstruction(m_object, offset, len, instr); - return RegisterValue::FromAPIObject(value); + BNPossibleValueSet value = BNGetMediumLevelILPossibleStackContentsAfterInstruction(m_object, offset, len, instr); + return PossibleValueSet::FromAPIObject(value); } diff --git a/python/function.py b/python/function.py index a507534c..51d61792 100644 --- a/python/function.py +++ b/python/function.py @@ -51,34 +51,78 @@ class RegisterValue(object): def __init__(self, arch, value): self.type = RegisterValueType(value.state) if value.state == RegisterValueType.EntryValue: - self.reg = arch.get_reg_name(value.reg) + self.reg = arch.get_reg_name(value.value) + elif value.state == RegisterValueType.ConstantValue: + self.value = value.value + elif value.state == RegisterValueType.StackFrameOffset: + self.offset = value.value + + def __repr__(self): + if self.type == RegisterValueType.EntryValue: + return "" % self.reg + if self.type == RegisterValueType.ConstantValue: + return "" % self.value + if self.type == RegisterValueType.StackFrameOffset: + return "" % self.offset + if self.type == RegisterValueType.ReturnAddressValue: + return "" + return "" + + +class ValueRange(object): + def __init__(self, start, end, step): + self.start = start + self.end = end + self.step = step + + def __repr__(self): + if self.step == 1: + return "" % (self.start, self.end) + return "" % (self.start, self.end, self.step) + + +class PossibleValueSet(object): + def __init__(self, arch, value): + self.type = RegisterValueType(value.state) + if value.state == RegisterValueType.EntryValue: + self.reg = arch.get_reg_name(value.value) elif value.state == RegisterValueType.ConstantValue: self.value = value.value elif value.state == RegisterValueType.StackFrameOffset: self.offset = value.value elif value.state == RegisterValueType.SignedRangeValue: self.offset = value.value - self.start = value.rangeStart - self.end = value.rangeEnd - self.step = value.rangeStep - if self.start & (1 << 63): - self.start |= ~((1 << 63) - 1) - if self.end & (1 << 63): - self.end |= ~((1 << 63) - 1) + self.ranges = [] + for i in xrange(0, value.count): + start = value.ranges[i].start + end = value.ranges[i].end + step = value.ranges[i].step + if start & (1 << 63): + start |= ~((1 << 63) - 1) + if end & (1 << 63): + end |= ~((1 << 63) - 1) + self.ranges.append(ValueRange(start, end, step)) elif value.state == RegisterValueType.UnsignedRangeValue: self.offset = value.value - self.start = value.rangeStart - self.end = value.rangeEnd - self.step = value.rangeStep + self.ranges = [] + for i in xrange(0, value.count): + start = value.ranges[i].start + end = value.ranges[i].end + step = value.ranges[i].step + self.ranges.append(ValueRange(start, end, step)) elif value.state == RegisterValueType.LookupTableValue: self.table = [] self.mapping = {} - for i in xrange(0, value.rangeEnd): + for i in xrange(0, value.count): from_list = [] for j in xrange(0, value.table[i].fromCount): from_list.append(value.table[i].fromValues[j]) self.mapping[value.table[i].fromValues[j]] = value.table[i].toValue self.table.append(LookupTableEntry(from_list, value.table[i].toValue)) + elif (value.state == RegisterValueType.InSetOfValues) or (value.state == RegisterValueType.NotInSetOfValues): + self.values = set() + for i in xrange(0, value.count): + self.values.add(value.valueSet[i]) def __repr__(self): if self.type == RegisterValueType.EntryValue: @@ -87,12 +131,16 @@ class RegisterValue(object): return "" % self.value if self.type == RegisterValueType.StackFrameOffset: return "" % self.offset - if (self.type == RegisterValueType.SignedRangeValue) or (self.type == RegisterValueType.UnsignedRangeValue): - if self.step == 1: - return "" % (self.start, self.end) - return "" % (self.start, self.end, self.step) + if self.type == RegisterValueType.SignedRangeValue: + return "" % repr(self.ranges) + if self.type == RegisterValueType.UnsignedRangeValue: + return "" % repr(self.ranges) if self.type == RegisterValueType.LookupTableValue: return "" % ', '.join([repr(i) for i in self.table]) + if self.type == RegisterValueType.InSetOfValues: + return "" % repr(self.values) + if self.type == RegisterValueType.NotInSetOfValues: + return "" % repr(self.values) if self.type == RegisterValueType.ReturnAddressValue: return "" return "" @@ -425,7 +473,6 @@ class Function(object): reg = arch.regs[reg].index value = core.BNGetRegisterValueAtInstruction(self.handle, arch.handle, addr, reg) result = RegisterValue(arch, value) - core.BNFreeRegisterValue(value) return result def get_reg_value_after(self, addr, reg, arch=None): @@ -447,7 +494,6 @@ class Function(object): reg = arch.regs[reg].index value = core.BNGetRegisterValueAfterInstruction(self.handle, arch.handle, addr, reg) result = RegisterValue(arch, value) - core.BNFreeRegisterValue(value) return result def get_stack_contents_at(self, addr, offset, size, arch=None): @@ -473,7 +519,6 @@ class Function(object): arch = self.arch value = core.BNGetStackContentsAtInstruction(self.handle, arch.handle, addr, offset, size) result = RegisterValue(arch, value) - core.BNFreeRegisterValue(value) return result def get_stack_contents_after(self, addr, offset, size, arch=None): @@ -481,7 +526,6 @@ class Function(object): arch = self.arch value = core.BNGetStackContentsAfterInstruction(self.handle, arch.handle, addr, offset, size) result = RegisterValue(arch, value) - core.BNFreeRegisterValue(value) return result def get_parameter_at(self, addr, func_type, i, arch=None): @@ -491,7 +535,6 @@ class Function(object): func_type = func_type.handle value = core.BNGetParameterValueAtInstruction(self.handle, arch.handle, addr, func_type, i) result = RegisterValue(arch, value) - core.BNFreeRegisterValue(value) return result def get_parameter_at_low_level_il_instruction(self, instr, func_type, i): @@ -499,7 +542,6 @@ class Function(object): func_type = func_type.handle value = core.BNGetParameterValueAtLowLevelILInstruction(self.handle, instr, func_type, i) result = RegisterValue(self.arch, value) - core.BNFreeRegisterValue(value) return result def get_regs_read_by(self, addr, arch=None): diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 74b030d7..a737d95e 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -263,15 +263,14 @@ class LowLevelILInstruction(object): """Value of expression if constant or a known value (read-only)""" value = core.BNGetLowLevelILExprValue(self.function.handle, self.expr_index) result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) return result @property def possible_values(self): """Possible values of expression using path-sensitive static data flow analysis (read-only)""" value = core.BNGetLowLevelILPossibleExprValues(self.function.handle, self.expr_index) - result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) + result = function.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) return result def get_reg_value(self, reg): @@ -279,7 +278,6 @@ class LowLevelILInstruction(object): reg = self.function.arch.regs[reg].index value = core.BNGetLowLevelILRegisterValueAtInstruction(self.function.handle, reg, self.instr_index) result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) return result def get_reg_value_after(self, reg): @@ -287,23 +285,22 @@ class LowLevelILInstruction(object): reg = self.function.arch.regs[reg].index value = core.BNGetLowLevelILRegisterValueAfterInstruction(self.function.handle, reg, self.instr_index) result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) return result def get_possible_reg_values(self, reg): if isinstance(reg, str): reg = self.function.arch.regs[reg].index value = core.BNGetLowLevelILPossibleRegisterValuesAtInstruction(self.function.handle, reg, self.instr_index) - result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) + result = function.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) return result def get_possible_reg_values_after(self, reg): if isinstance(reg, str): reg = self.function.arch.regs[reg].index value = core.BNGetLowLevelILPossibleRegisterValuesAfterInstruction(self.function.handle, reg, self.instr_index) - result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) + result = function.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) return result def get_flag_value(self, flag): @@ -311,7 +308,6 @@ class LowLevelILInstruction(object): flag = self.function.arch.flags[flag].index value = core.BNGetLowLevelILFlagValueAtInstruction(self.function.handle, flag, self.instr_index) result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) return result def get_flag_value_after(self, flag): @@ -319,47 +315,44 @@ class LowLevelILInstruction(object): flag = self.function.arch.flags[flag].index value = core.BNGetLowLevelILFlagValueAfterInstruction(self.function.handle, flag, self.instr_index) result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) return result def get_possible_flag_values(self, flag): if isinstance(flag, str): flag = self.function.arch.flags[flag].index value = core.BNGetLowLevelILPossibleFlagValuesAtInstruction(self.function.handle, flag, self.instr_index) - result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) + result = function.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) return result def get_possible_flag_values_after(self, flag): if isinstance(flag, str): flag = self.function.arch.flags[flag].index value = core.BNGetLowLevelILPossibleFlagValuesAfterInstruction(self.function.handle, flag, self.instr_index) - result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) + result = function.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) return result def get_stack_contents(self, offset, size): value = core.BNGetLowLevelILStackContentsAtInstruction(self.function.handle, offset, size, self.instr_index) result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) return result def get_stack_contents_after(self, offset, size): value = core.BNGetLowLevelILStackContentsAfterInstruction(self.function.handle, offset, size, self.instr_index) result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) return result def get_possible_stack_contents(self, offset, size): value = core.BNGetLowLevelILPossibleStackContentsAtInstruction(self.function.handle, offset, size, self.instr_index) - result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) + result = function.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) return result def get_possible_stack_contents_after(self, offset, size): value = core.BNGetLowLevelILPossibleStackContentsAfterInstruction(self.function.handle, offset, size, self.instr_index) - result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) + result = function.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) return result def __setattr__(self, name, value): @@ -1534,7 +1527,6 @@ class LowLevelILFunction(object): reg = self.arch.regs[reg].index value = core.BNGetLowLevelILSSARegisterValue(self.handle, reg, index) result = function.RegisterValue(self.arch, value) - core.BNFreeRegisterValue(value) return result def get_ssa_flag_value(self, flag, index): @@ -1542,7 +1534,6 @@ class LowLevelILFunction(object): flag = self.arch.get_flag_by_name(flag) value = core.BNGetLowLevelILSSAFlagValue(self.handle, flag, index) result = function.RegisterValue(self.arch, value) - core.BNFreeRegisterValue(value) return result def get_mapped_medium_level_il_instruction_index(self, instr): diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 6f482221..951ad591 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -260,15 +260,14 @@ class MediumLevelILInstruction(object): """Value of expression if constant or a known value (read-only)""" value = core.BNGetMediumLevelILExprValue(self.function.handle, self.expr_index) result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) return result @property def possible_values(self): """Possible values of expression using path-sensitive static data flow analysis (read-only)""" value = core.BNGetMediumLevelILPossibleExprValues(self.function.handle, self.expr_index) - result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) + result = function.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) return result @property @@ -302,7 +301,6 @@ class MediumLevelILInstruction(object): var_data.identifier = var.identifier value = core.BNGetMediumLevelILPossibleSSAVarValues(self.function.handle, var_data, index, self.instr_index) result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) return result def get_ssa_var_index(self, var): @@ -333,7 +331,6 @@ class MediumLevelILInstruction(object): reg = self.function.arch.regs[reg].index value = core.BNGetMediumLevelILRegisterValueAtInstruction(self.function.handle, reg, self.instr_index) result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) return result def get_reg_value_after(self, reg): @@ -341,23 +338,22 @@ class MediumLevelILInstruction(object): reg = self.function.arch.regs[reg].index value = core.BNGetMediumLevelILRegisterValueAfterInstruction(self.function.handle, reg, self.instr_index) result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) return result def get_possible_reg_values(self, reg): if isinstance(reg, str): reg = self.function.arch.regs[reg].index value = core.BNGetMediumLevelILPossibleRegisterValuesAtInstruction(self.function.handle, reg, self.instr_index) - result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) + result = function.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) return result def get_possible_reg_values_after(self, reg): if isinstance(reg, str): reg = self.function.arch.regs[reg].index value = core.BNGetMediumLevelILPossibleRegisterValuesAfterInstruction(self.function.handle, reg, self.instr_index) - result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) + result = function.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) return result def get_flag_value(self, flag): @@ -365,7 +361,6 @@ class MediumLevelILInstruction(object): flag = self.function.arch.flags[flag].index value = core.BNGetMediumLevelILFlagValueAtInstruction(self.function.handle, flag, self.instr_index) result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) return result def get_flag_value_after(self, flag): @@ -373,47 +368,44 @@ class MediumLevelILInstruction(object): flag = self.function.arch.flags[flag].index value = core.BNGetMediumLevelILFlagValueAfterInstruction(self.function.handle, flag, self.instr_index) result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) return result def get_possible_flag_values(self, flag): if isinstance(flag, str): flag = self.function.arch.flags[flag].index value = core.BNGetMediumLevelILPossibleFlagValuesAtInstruction(self.function.handle, flag, self.instr_index) - result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) + result = function.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) return result def get_possible_flag_values_after(self, flag): if isinstance(flag, str): flag = self.function.arch.flags[flag].index value = core.BNGetMediumLevelILPossibleFlagValuesAfterInstruction(self.function.handle, flag, self.instr_index) - result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) + result = function.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) return result def get_stack_contents(self, offset, size): value = core.BNGetMediumLevelILStackContentsAtInstruction(self.function.handle, offset, size, self.instr_index) result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) return result def get_stack_contents_after(self, offset, size): value = core.BNGetMediumLevelILStackContentsAfterInstruction(self.function.handle, offset, size, self.instr_index) result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) return result def get_possible_stack_contents(self, offset, size): value = core.BNGetMediumLevelILPossibleStackContentsAtInstruction(self.function.handle, offset, size, self.instr_index) - result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) + result = function.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) return result def get_possible_stack_contents_after(self, offset, size): value = core.BNGetMediumLevelILPossibleStackContentsAfterInstruction(self.function.handle, offset, size, self.instr_index) - result = function.RegisterValue(self.function.arch, value) - core.BNFreeRegisterValue(value) + result = function.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) return result def get_branch_dependence(self, branch_instr): @@ -706,7 +698,6 @@ class MediumLevelILFunction(object): var_data.identifier = var.identifier value = core.BNGetMediumLevelILSSAVarValue(self.handle, var_data, index) result = function.RegisterValue(self.arch, value) - core.BNFreeRegisterValue(value) return result def get_low_level_il_instruction_index(self, instr): -- cgit v1.3.1 From bf57618db521f8677fd57cd9baa5d77acf025845 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Sat, 25 Mar 2017 21:50:59 -0400 Subject: Fixing partial variable write instruction --- python/mediumlevelil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'python/mediumlevelil.py') diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 951ad591..dff79fbd 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -115,7 +115,7 @@ class MediumLevelILInstruction(object): MediumLevelILOperation.MLIL_UNIMPL: [], MediumLevelILOperation.MLIL_UNIMPL_MEM: [("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_SSA: [("dest", "var"), ("index", "int"), ("src", "expr")], - MediumLevelILOperation.MLIL_SET_VAR_SSA_FIELD: [("dest", "var"), ("index", "int"), ("offset", "int"), ("src", "expr")], + MediumLevelILOperation.MLIL_SET_VAR_SSA_FIELD: [("dest", "var"), ("dest_index", "int"), ("src_index", "int"), ("offset", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_SPLIT_SSA: [("high", "expr"), ("low", "expr"), ("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_ALIASED: [("dest", "var"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "exor")], MediumLevelILOperation.MLIL_SET_VAR_ALIASED_FIELD: [("dest", "var"), ("dest_memory", "int"), ("src_memory", "int"), ("offset", "int"), ("src", "exor")], -- cgit v1.3.1 From 0ed147b61a1418915c1e243e05aa05e736b6a73f Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Mon, 17 Apr 2017 19:38:12 -0400 Subject: Use new variable system in functions --- binaryninjaapi.h | 81 ++++++++++++++++---------- binaryninjacore.h | 45 +++++++++------ function.cpp | 151 ++++++++++++++++++++++++++++++++++++++++++++---- mediumlevelil.cpp | 56 +++++++++--------- python/function.py | 39 +++++++++---- python/mediumlevelil.py | 30 +++++----- 6 files changed, 290 insertions(+), 112 deletions(-) (limited to 'python/mediumlevelil.py') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index af0cf5ce..c6ac8aa3 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1809,11 +1809,24 @@ namespace BinaryNinja static bool IsBackEdge(BasicBlock* source, BasicBlock* target); }; - struct StackVariable + struct Variable: public BNVariable { + Variable(); + Variable(BNVariableSourceType type, uint32_t index, uint64_t identifier); + Variable(const BNVariable& var); + + Variable& operator=(const Variable& var); + + bool operator==(const Variable& var) const; + bool operator!=(const Variable& var) const; + bool operator<(const Variable& var) const; + }; + + struct VariableNameAndType + { + Variable var; Ref type; std::string name; - int64_t offset; bool autoDefined; }; @@ -1928,12 +1941,20 @@ namespace BinaryNinja Ref CreateFunctionGraph(); - std::map GetStackLayout(); + std::map> GetStackLayout(); void CreateAutoStackVariable(int64_t offset, Ref type, const std::string& name); void CreateUserStackVariable(int64_t offset, Ref type, const std::string& name); void DeleteAutoStackVariable(int64_t offset); void DeleteUserStackVariable(int64_t offset); - bool GetStackVariableAtFrameOffset(int64_t offset, StackVariable& var); + bool GetStackVariableAtFrameOffset(Architecture* arch, uint64_t addr, int64_t offset, VariableNameAndType& var); + + std::map GetVariables(); + void CreateAutoVariable(const Variable& var, Ref type, const std::string& name, bool singleOnly = false); + void CreateUserVariable(const Variable& var, Ref type, const std::string& name, bool singleOnly = false); + void DeleteAutoVariable(const Variable& var); + void DeleteUserVariable(const Variable& var); + Ref GetVariableType(const Variable& var); + std::string GetVariableName(const Variable& var); void SetAutoIndirectBranches(Architecture* sourceArch, uint64_t source, const std::vector& branches); void SetUserIndirectBranches(Architecture* sourceArch, uint64_t source, const std::vector& branches); @@ -2228,24 +2249,24 @@ namespace BinaryNinja ExprId a = 0, ExprId b = 0, ExprId c = 0, ExprId d = 0, ExprId e = 0, ExprId f = 0); ExprId AddInstruction(ExprId expr); - ExprId SetVar(size_t size, const BNILVariable& var, ExprId src); - ExprId SetVarField(size_t size, const BNILVariable& var, int64_t offset, ExprId src); - ExprId SetVarSplit(size_t size, const BNILVariable& high, const BNILVariable& low, ExprId src); - ExprId SetVarSSA(size_t size, const BNILVariable& var, size_t index, ExprId src); - ExprId SetVarFieldSSA(size_t size, const BNILVariable& var, size_t varIndex, int64_t offset, ExprId src); - ExprId SetVarSplitSSA(size_t size, const BNILVariable& high, size_t highIndex, - const BNILVariable& low, size_t lowIndex, ExprId src); - ExprId SetVarAliased(size_t size, const BNILVariable& var, size_t destIndex, size_t srcIndex, ExprId src); - ExprId SetVarFieldAliased(size_t size, const BNILVariable& var, size_t destIndex, size_t srcIndex, + ExprId SetVar(size_t size, const Variable& var, ExprId src); + ExprId SetVarField(size_t size, const Variable& var, int64_t offset, ExprId src); + ExprId SetVarSplit(size_t size, const Variable& high, const Variable& low, ExprId src); + ExprId SetVarSSA(size_t size, const Variable& var, size_t index, ExprId src); + ExprId SetVarFieldSSA(size_t size, const Variable& var, size_t varIndex, int64_t offset, ExprId src); + ExprId SetVarSplitSSA(size_t size, const Variable& high, size_t highIndex, + const Variable& low, size_t lowIndex, ExprId src); + ExprId SetVarAliased(size_t size, const Variable& var, size_t destIndex, size_t srcIndex, ExprId src); + ExprId SetVarFieldAliased(size_t size, const Variable& var, size_t destIndex, size_t srcIndex, int64_t offset, ExprId src); - ExprId Var(size_t size, const BNILVariable& var); - ExprId VarField(size_t size, const BNILVariable& var, int64_t offset); - ExprId VarSSA(size_t size, const BNILVariable& var, size_t index); - ExprId VarFieldSSA(size_t size, const BNILVariable& var, int64_t offset, size_t varIndex); - ExprId VarAliased(size_t size, const BNILVariable& var, size_t memIndex); - ExprId VarFieldAliased(size_t size, const BNILVariable& var, int64_t offset, size_t memIndex); - ExprId AddressOf(size_t size, const BNILVariable& var); - ExprId AddressOfField(size_t size, const BNILVariable& var, int64_t offset); + ExprId Var(size_t size, const Variable& var); + ExprId VarField(size_t size, const Variable& var, int64_t offset); + ExprId VarSSA(size_t size, const Variable& var, size_t index); + ExprId VarFieldSSA(size_t size, const Variable& var, int64_t offset, size_t varIndex); + ExprId VarAliased(size_t size, const Variable& var, size_t memIndex); + ExprId VarFieldAliased(size_t size, const Variable& var, int64_t offset, size_t memIndex); + ExprId AddressOf(size_t size, const Variable& var); + ExprId AddressOfField(size_t size, const Variable& var, int64_t offset); ExprId Goto(BNMediumLevelILLabel& label); ExprId If(ExprId operand, BNMediumLevelILLabel& t, BNMediumLevelILLabel& f); @@ -2255,7 +2276,7 @@ namespace BinaryNinja ExprId AddLabelList(const std::vector& labels); ExprId AddOperandList(const std::vector operands); - BNILVariable GetVariable(ExprId i, size_t varOperand); + Variable GetVariable(ExprId i, size_t varOperand); BNMediumLevelILInstruction operator[](size_t i) const; size_t GetIndexForInstruction(size_t i) const; @@ -2278,21 +2299,21 @@ namespace BinaryNinja size_t GetSSAExprIndex(size_t instr) const; size_t GetNonSSAExprIndex(size_t instr) const; - size_t GetSSAVarDefinition(const BNILVariable& var, size_t idx) const; + size_t GetSSAVarDefinition(const Variable& var, size_t idx) const; size_t GetSSAMemoryDefinition(size_t idx) const; - std::set GetSSAVarUses(const BNILVariable& var, size_t idx) const; + std::set GetSSAVarUses(const Variable& var, size_t idx) const; std::set GetSSAMemoryUses(size_t idx) const; - RegisterValue GetSSAVarValue(const BNILVariable& var, size_t idx); + RegisterValue GetSSAVarValue(const Variable& var, size_t idx); RegisterValue GetExprValue(size_t expr); - PossibleValueSet GetPossibleSSAVarValues(const BNILVariable& var, size_t idx, size_t instr); + PossibleValueSet GetPossibleSSAVarValues(const Variable& var, size_t idx, size_t instr); PossibleValueSet GetPossibleExprValues(size_t expr); - size_t GetSSAVarIndexAtInstruction(const BNILVariable& var, size_t instr) const; + size_t GetSSAVarIndexAtInstruction(const Variable& var, size_t instr) const; size_t GetSSAMemoryIndexAtInstruction(size_t instr) const; - BNILVariable GetVariableForRegisterAtInstruction(uint32_t reg, size_t instr) const; - BNILVariable GetVariableForFlagAtInstruction(uint32_t flag, size_t instr) const; - BNILVariable GetVariableForStackLocationAtInstruction(int64_t offset, size_t instr) const; + Variable GetVariableForRegisterAtInstruction(uint32_t reg, size_t instr) const; + Variable GetVariableForFlagAtInstruction(uint32_t flag, size_t instr) const; + Variable GetVariableForStackLocationAtInstruction(int64_t offset, size_t instr) const; RegisterValue GetRegisterValueAtInstruction(uint32_t reg, size_t instr); RegisterValue GetRegisterValueAfterInstruction(uint32_t reg, size_t instr); diff --git a/binaryninjacore.h b/binaryninjacore.h index c43c9b21..68ea4069 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -766,16 +766,16 @@ extern "C" size_t operand; }; - enum BNILVariableSourceType + enum BNVariableSourceType { RegisterVariableSourceType, FlagVariableSourceType, StackVariableSourceType }; - struct BNILVariable + struct BNVariable { - BNILVariableSourceType type; + BNVariableSourceType type; uint32_t index; int64_t identifier; }; @@ -1129,11 +1129,11 @@ extern "C" uint32_t (*getFloatReturnValueRegister)(void* ctxt); }; - struct BNStackVariable + struct BNVariableNameAndType { + BNVariable var; BNType* type; char* name; - int64_t offset; bool autoDefined; }; @@ -1929,14 +1929,25 @@ extern "C" uint64_t len, size_t* count); BINARYNINJACOREAPI void BNFreeStringReferenceList(BNStringReference* strings); - BINARYNINJACOREAPI BNStackVariable* BNGetStackLayout(BNFunction* func, size_t* count); - BINARYNINJACOREAPI void BNFreeStackLayout(BNStackVariable* vars, size_t count); + 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 BNDeleteAutoStackVariable(BNFunction* func, int64_t offset); BINARYNINJACOREAPI void BNDeleteUserStackVariable(BNFunction* func, int64_t offset); - BINARYNINJACOREAPI bool BNGetStackVariableAtFrameOffset(BNFunction* func, int64_t offset, BNStackVariable* var); - BINARYNINJACOREAPI void BNFreeStackVariable(BNStackVariable* var); + BINARYNINJACOREAPI bool BNGetStackVariableAtFrameOffset(BNFunction* func, BNArchitecture* arch, uint64_t addr, + int64_t offset, BNVariableNameAndType* var); + BINARYNINJACOREAPI void BNFreeVariableNameAndType(BNVariableNameAndType* var); + + BINARYNINJACOREAPI BNVariableNameAndType* BNGetFunctionVariables(BNFunction* func, size_t* count); + BINARYNINJACOREAPI void BNCreateAutoVariable(BNFunction* func, const BNVariable* var, BNType* type, + const char* name, bool singleOnly); + BINARYNINJACOREAPI void BNCreateUserVariable(BNFunction* func, const BNVariable* var, BNType* type, + const char* name, bool singleOnly); + 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 char* BNGetVariableName(BNFunction* func, const BNVariable* var); BINARYNINJACOREAPI void BNSetAutoIndirectBranches(BNFunction* func, BNArchitecture* sourceArch, uint64_t source, BNArchitectureAndAddress* branches, size_t count); @@ -2272,29 +2283,29 @@ extern "C" BINARYNINJACOREAPI size_t BNGetMediumLevelILNonSSAExprIndex(BNMediumLevelILFunction* func, size_t expr); BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAVarDefinition(BNMediumLevelILFunction* func, - const BNILVariable* var, size_t idx); + const BNVariable* var, size_t idx); BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAMemoryDefinition(BNMediumLevelILFunction* func, size_t idx); - BINARYNINJACOREAPI size_t* BNGetMediumLevelILSSAVarUses(BNMediumLevelILFunction* func, const BNILVariable* var, + BINARYNINJACOREAPI size_t* BNGetMediumLevelILSSAVarUses(BNMediumLevelILFunction* func, const BNVariable* var, size_t idx, size_t* count); BINARYNINJACOREAPI size_t* BNGetMediumLevelILSSAMemoryUses(BNMediumLevelILFunction* func, size_t idx, size_t* count); BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILSSAVarValue(BNMediumLevelILFunction* func, - const BNILVariable* var, size_t idx); + const BNVariable* var, size_t idx); BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILExprValue(BNMediumLevelILFunction* func, size_t expr); BINARYNINJACOREAPI BNPossibleValueSet BNGetMediumLevelILPossibleSSAVarValues(BNMediumLevelILFunction* func, - const BNILVariable* var, size_t idx, size_t instr); + const BNVariable* var, size_t idx, size_t instr); BINARYNINJACOREAPI BNPossibleValueSet BNGetMediumLevelILPossibleExprValues(BNMediumLevelILFunction* func, size_t expr); BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAVarIndexAtILInstruction(BNMediumLevelILFunction* func, - const BNILVariable* var, size_t instr); + const BNVariable* var, size_t instr); BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAMemoryIndexAtILInstruction(BNMediumLevelILFunction* func, size_t instr); - BINARYNINJACOREAPI BNILVariable BNGetMediumLevelILVariableForRegisterAtInstruction(BNMediumLevelILFunction* func, + BINARYNINJACOREAPI BNVariable BNGetMediumLevelILVariableForRegisterAtInstruction(BNMediumLevelILFunction* func, uint32_t reg, size_t instr); - BINARYNINJACOREAPI BNILVariable BNGetMediumLevelILVariableForFlagAtInstruction(BNMediumLevelILFunction* func, + BINARYNINJACOREAPI BNVariable BNGetMediumLevelILVariableForFlagAtInstruction(BNMediumLevelILFunction* func, uint32_t flag, size_t instr); - BINARYNINJACOREAPI BNILVariable BNGetMediumLevelILVariableForStackLocationAtInstruction(BNMediumLevelILFunction* func, + BINARYNINJACOREAPI BNVariable BNGetMediumLevelILVariableForStackLocationAtInstruction(BNMediumLevelILFunction* func, int64_t offset, size_t instr); BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILRegisterValueAtInstruction(BNMediumLevelILFunction* func, diff --git a/function.cpp b/function.cpp index 16ad1f1c..c3402eea 100644 --- a/function.cpp +++ b/function.cpp @@ -24,6 +24,69 @@ using namespace BinaryNinja; using namespace std; +Variable::Variable() +{ + type = RegisterVariableSourceType; + index = 0; + identifier = 0; +} + + +Variable::Variable(BNVariableSourceType t, uint32_t i, uint64_t id) +{ + type = t; + index = i; + identifier = id; +} + + +Variable::Variable(const BNVariable& var) +{ + type = var.type; + index = var.index; + identifier = var.identifier; +} + + +Variable& Variable::operator=(const Variable& var) +{ + type = var.type; + index = var.index; + identifier = var.identifier; + return *this; +} + + +bool Variable::operator==(const Variable& var) const +{ + if (type != var.type) + return false; + if (index != var.index) + return false; + return identifier == var.identifier; +} + + +bool Variable::operator!=(const Variable& var) const +{ + return !((*this) == var); +} + + +bool Variable::operator<(const Variable& var) const +{ + if (type < var.type) + return true; + if (type > var.type) + return false; + if (index < var.index) + return true; + if (index > var.index) + return false; + return identifier < var.identifier; +} + + Function::Function(BNFunction* func) { m_object = func; @@ -414,23 +477,23 @@ Ref Function::CreateFunctionGraph() } -map Function::GetStackLayout() +map> Function::GetStackLayout() { size_t count; - BNStackVariable* vars = BNGetStackLayout(m_object, &count); + BNVariableNameAndType* vars = BNGetStackLayout(m_object, &count); - map result; + map> result; for (size_t i = 0; i < count; i++) { - StackVariable var; + VariableNameAndType var; var.name = vars[i].name; var.type = new Type(BNNewTypeReference(vars[i].type)); - var.offset = vars[i].offset; + var.var = vars[i].var; var.autoDefined = vars[i].autoDefined; - result[vars[i].offset] = var; + result[vars[i].var.identifier].push_back(var); } - BNFreeStackLayout(vars, count); + BNFreeVariableList(vars, count); return result; } @@ -459,22 +522,86 @@ void Function::DeleteUserStackVariable(int64_t offset) } -bool Function::GetStackVariableAtFrameOffset(int64_t offset, StackVariable& result) +bool Function::GetStackVariableAtFrameOffset(Architecture* arch, uint64_t addr, + int64_t offset, VariableNameAndType& result) { - BNStackVariable var; - if (!BNGetStackVariableAtFrameOffset(m_object, offset, &var)) + BNVariableNameAndType var; + if (!BNGetStackVariableAtFrameOffset(m_object, arch->GetObject(), addr, offset, &var)) return false; result.type = new Type(BNNewTypeReference(var.type)); result.name = var.name; - result.offset = var.offset; + result.var = var.var; result.autoDefined = var.autoDefined; - BNFreeStackVariable(&var); + BNFreeVariableNameAndType(&var); return true; } +map Function::GetVariables() +{ + size_t count; + BNVariableNameAndType* vars = BNGetFunctionVariables(m_object, &count); + + map result; + for (size_t i = 0; i < count; i++) + { + VariableNameAndType var; + var.name = vars[i].name; + var.type = new Type(BNNewTypeReference(vars[i].type)); + var.var = vars[i].var; + var.autoDefined = vars[i].autoDefined; + result[vars[i].var] = var; + } + + BNFreeVariableList(vars, count); + return result; +} + + +void Function::CreateAutoVariable(const Variable& var, Ref type, const string& name, bool singleOnly) +{ + BNCreateAutoVariable(m_object, &var, type->GetObject(), name.c_str(), singleOnly); +} + + +void Function::CreateUserVariable(const Variable& var, Ref type, const string& name, bool singleOnly) +{ + BNCreateUserVariable(m_object, &var, type->GetObject(), name.c_str(), singleOnly); +} + + +void Function::DeleteAutoVariable(const Variable& var) +{ + BNDeleteAutoVariable(m_object, &var); +} + + +void Function::DeleteUserVariable(const Variable& var) +{ + BNDeleteAutoVariable(m_object, &var); +} + + +Ref Function::GetVariableType(const Variable& var) +{ + BNType* type = BNGetVariableType(m_object, &var); + if (!type) + return nullptr; + return new Type(type); +} + + +string Function::GetVariableName(const Variable& var) +{ + char* name = BNGetVariableName(m_object, &var); + string result = name; + BNFreeString(name); + return result; +} + + void Function::SetAutoIndirectBranches(Architecture* sourceArch, uint64_t source, const std::vector& branches) { BNArchitectureAndAddress* branchList = new BNArchitectureAndAddress[branches.size()]; diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index b0eb83a1..4ec5d69e 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -73,34 +73,34 @@ ExprId MediumLevelILFunction::AddInstruction(size_t expr) } -ExprId MediumLevelILFunction::SetVar(size_t size, const BNILVariable& var, ExprId src) +ExprId MediumLevelILFunction::SetVar(size_t size, const Variable& var, ExprId src) { return AddExpr(MLIL_SET_VAR, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, src); } -ExprId MediumLevelILFunction::SetVarField(size_t size, const BNILVariable& var, int64_t offset, ExprId src) +ExprId MediumLevelILFunction::SetVarField(size_t size, const Variable& var, int64_t offset, ExprId src) { return AddExpr(MLIL_SET_VAR_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, offset, src); } -ExprId MediumLevelILFunction::SetVarSplit(size_t size, const BNILVariable& high, const BNILVariable& low, ExprId src) +ExprId MediumLevelILFunction::SetVarSplit(size_t size, const Variable& high, const Variable& low, ExprId src) { return AddExpr(MLIL_SET_VAR_SPLIT, size, ((uint64_t)high.type << 32) | (uint64_t)high.index, high.identifier, ((uint64_t)low.type << 32) | (uint64_t)low.index, low.identifier, src); } -ExprId MediumLevelILFunction::SetVarSSA(size_t size, const BNILVariable& var, size_t varIndex, ExprId src) +ExprId MediumLevelILFunction::SetVarSSA(size_t size, const Variable& var, size_t varIndex, ExprId src) { return AddExpr(MLIL_SET_VAR_SSA, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, varIndex, src); } -ExprId MediumLevelILFunction::SetVarFieldSSA(size_t size, const BNILVariable& var, size_t varIndex, +ExprId MediumLevelILFunction::SetVarFieldSSA(size_t size, const Variable& var, size_t varIndex, int64_t offset, ExprId src) { return AddExpr(MLIL_SET_VAR_SSA_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, @@ -108,8 +108,8 @@ ExprId MediumLevelILFunction::SetVarFieldSSA(size_t size, const BNILVariable& va } -ExprId MediumLevelILFunction::SetVarSplitSSA(size_t size, const BNILVariable& high, size_t highIndex, - const BNILVariable& low, size_t lowIndex, ExprId src) +ExprId MediumLevelILFunction::SetVarSplitSSA(size_t size, const Variable& high, size_t highIndex, + const Variable& low, size_t lowIndex, ExprId src) { return AddExpr(MLIL_SET_VAR_SPLIT_SSA, size, AddExpr(MLIL_VAR_SPLIT_DEST_SSA, size, ((uint64_t)high.type << 32) | (uint64_t)high.index, @@ -119,7 +119,7 @@ ExprId MediumLevelILFunction::SetVarSplitSSA(size_t size, const BNILVariable& hi } -ExprId MediumLevelILFunction::SetVarAliased(size_t size, const BNILVariable& var, size_t destIndex, +ExprId MediumLevelILFunction::SetVarAliased(size_t size, const Variable& var, size_t destIndex, size_t srcIndex, ExprId src) { return AddExpr(MLIL_SET_VAR_ALIASED, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, @@ -127,7 +127,7 @@ ExprId MediumLevelILFunction::SetVarAliased(size_t size, const BNILVariable& var } -ExprId MediumLevelILFunction::SetVarFieldAliased(size_t size, const BNILVariable& var, size_t destIndex, +ExprId MediumLevelILFunction::SetVarFieldAliased(size_t size, const Variable& var, size_t destIndex, size_t srcIndex, int64_t offset, ExprId src) { return AddExpr(MLIL_SET_VAR_ALIASED_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, @@ -135,25 +135,25 @@ ExprId MediumLevelILFunction::SetVarFieldAliased(size_t size, const BNILVariable } -ExprId MediumLevelILFunction::Var(size_t size, const BNILVariable& var) +ExprId MediumLevelILFunction::Var(size_t size, const Variable& var) { return AddExpr(MLIL_VAR, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier); } -ExprId MediumLevelILFunction::VarField(size_t size, const BNILVariable& var, int64_t offset) +ExprId MediumLevelILFunction::VarField(size_t size, const Variable& var, int64_t offset) { return AddExpr(MLIL_VAR_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, offset); } -ExprId MediumLevelILFunction::VarSSA(size_t size, const BNILVariable& var, size_t varIndex) +ExprId MediumLevelILFunction::VarSSA(size_t size, const Variable& var, size_t varIndex) { return AddExpr(MLIL_VAR_SSA, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, varIndex); } -ExprId MediumLevelILFunction::VarFieldSSA(size_t size, const BNILVariable& var, int64_t offset, +ExprId MediumLevelILFunction::VarFieldSSA(size_t size, const Variable& var, int64_t offset, size_t varIndex) { return AddExpr(MLIL_VAR_SSA_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, @@ -161,26 +161,26 @@ ExprId MediumLevelILFunction::VarFieldSSA(size_t size, const BNILVariable& var, } -ExprId MediumLevelILFunction::VarAliased(size_t size, const BNILVariable& var, size_t memIndex) +ExprId MediumLevelILFunction::VarAliased(size_t size, const Variable& var, size_t memIndex) { return AddExpr(MLIL_VAR_ALIASED, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, memIndex); } -ExprId MediumLevelILFunction::VarFieldAliased(size_t size, const BNILVariable& var, int64_t offset, size_t memIndex) +ExprId MediumLevelILFunction::VarFieldAliased(size_t size, const Variable& var, int64_t offset, size_t memIndex) { return AddExpr(MLIL_VAR_ALIASED_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, offset, memIndex); } -ExprId MediumLevelILFunction::AddressOf(size_t size, const BNILVariable& var) +ExprId MediumLevelILFunction::AddressOf(size_t size, const Variable& var) { return AddExpr(MLIL_ADDRESS_OF, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier); } -ExprId MediumLevelILFunction::AddressOfField(size_t size, const BNILVariable& var, int64_t offset) +ExprId MediumLevelILFunction::AddressOfField(size_t size, const Variable& var, int64_t offset) { return AddExpr(MLIL_ADDRESS_OF_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, offset); @@ -239,11 +239,11 @@ ExprId MediumLevelILFunction::AddOperandList(const vector operands) } -BNILVariable MediumLevelILFunction::GetVariable(ExprId i, size_t varOperand) +Variable MediumLevelILFunction::GetVariable(ExprId i, size_t varOperand) { BNMediumLevelILInstruction instr = (*this)[i]; - BNILVariable result; - result.type = (BNILVariableSourceType)(instr.operands[varOperand] >> 32); + Variable result; + result.type = (BNVariableSourceType)(instr.operands[varOperand] >> 32); result.index = (uint32_t)instr.operands[varOperand]; result.identifier = instr.operands[varOperand + 1]; return result; @@ -396,7 +396,7 @@ size_t MediumLevelILFunction::GetNonSSAExprIndex(size_t expr) const } -size_t MediumLevelILFunction::GetSSAVarDefinition(const BNILVariable& var, size_t idx) const +size_t MediumLevelILFunction::GetSSAVarDefinition(const Variable& var, size_t idx) const { return BNGetMediumLevelILSSAVarDefinition(m_object, &var, idx); } @@ -408,7 +408,7 @@ size_t MediumLevelILFunction::GetSSAMemoryDefinition(size_t idx) const } -set MediumLevelILFunction::GetSSAVarUses(const BNILVariable& var, size_t idx) const +set MediumLevelILFunction::GetSSAVarUses(const Variable& var, size_t idx) const { size_t count; size_t* instrs = BNGetMediumLevelILSSAVarUses(m_object, &var, idx, &count); @@ -436,7 +436,7 @@ set MediumLevelILFunction::GetSSAMemoryUses(size_t idx) const } -RegisterValue MediumLevelILFunction::GetSSAVarValue(const BNILVariable& var, size_t idx) +RegisterValue MediumLevelILFunction::GetSSAVarValue(const Variable& var, size_t idx) { BNRegisterValue value = BNGetMediumLevelILSSAVarValue(m_object, &var, idx); return RegisterValue::FromAPIObject(value); @@ -450,7 +450,7 @@ RegisterValue MediumLevelILFunction::GetExprValue(size_t expr) } -PossibleValueSet MediumLevelILFunction::GetPossibleSSAVarValues(const BNILVariable& var, size_t idx, size_t instr) +PossibleValueSet MediumLevelILFunction::GetPossibleSSAVarValues(const Variable& var, size_t idx, size_t instr) { BNPossibleValueSet value = BNGetMediumLevelILPossibleSSAVarValues(m_object, &var, idx, instr); return PossibleValueSet::FromAPIObject(value); @@ -464,7 +464,7 @@ PossibleValueSet MediumLevelILFunction::GetPossibleExprValues(size_t expr) } -size_t MediumLevelILFunction::GetSSAVarIndexAtInstruction(const BNILVariable& var, size_t instr) const +size_t MediumLevelILFunction::GetSSAVarIndexAtInstruction(const Variable& var, size_t instr) const { return BNGetMediumLevelILSSAVarIndexAtILInstruction(m_object, &var, instr); } @@ -476,19 +476,19 @@ size_t MediumLevelILFunction::GetSSAMemoryIndexAtInstruction(size_t instr) const } -BNILVariable MediumLevelILFunction::GetVariableForRegisterAtInstruction(uint32_t reg, size_t instr) const +Variable MediumLevelILFunction::GetVariableForRegisterAtInstruction(uint32_t reg, size_t instr) const { return BNGetMediumLevelILVariableForRegisterAtInstruction(m_object, reg, instr); } -BNILVariable MediumLevelILFunction::GetVariableForFlagAtInstruction(uint32_t flag, size_t instr) const +Variable MediumLevelILFunction::GetVariableForFlagAtInstruction(uint32_t flag, size_t instr) const { return BNGetMediumLevelILVariableForFlagAtInstruction(m_object, flag, instr); } -BNILVariable MediumLevelILFunction::GetVariableForStackLocationAtInstruction(int64_t offset, size_t instr) const +Variable MediumLevelILFunction::GetVariableForStackLocationAtInstruction(int64_t offset, size_t instr) const { return BNGetMediumLevelILVariableForStackLocationAtInstruction(m_object, offset, instr); } diff --git a/python/function.py b/python/function.py index 51d61792..74f4b0f8 100644 --- a/python/function.py +++ b/python/function.py @@ -26,7 +26,7 @@ import ctypes import _binaryninjacore as core from enums import (FunctionGraphType, BranchType, SymbolType, InstructionTextTokenType, HighlightStandardColor, HighlightColorStyle, RegisterValueType, ImplicitRegisterExtend, - DisassemblyOption, IntegerDisplayType, InstructionTextTokenContext) + DisassemblyOption, IntegerDisplayType, InstructionTextTokenContext, VariableSourceType) import architecture import highlight import associateddatastore @@ -146,14 +146,20 @@ class PossibleValueSet(object): return "" -class StackVariable(object): - def __init__(self, ofs, name, t): - self.offset = ofs +class VariableNameAndType(object): + def __init__(self, var, name, t): + self.var = var self.name = name self.type = t def __repr__(self): - return "" % (self.offset, self.type, self.name) + if self.var.type == VariableSourceType.StackVariableSourceType: + return "" % (self.var.identifier, self.type, self.name) + elif self.var.type == VariableSourceType.RegisterVariableSourceType: + return "" % (self.var.function.arch.get_reg_name(self.var.identifier), self.type, self.name) + elif self.var.type == VariableSourceType.FlagVariableSourceType: + return "" % (self.var.function.arch.get_flag_name(self.var.identifier), self.type, self.name) + return "" % (self.var, self.type, self.name) def __str__(self): return self.name @@ -179,7 +185,7 @@ class StackVariableReference(object): return "" % (self.source_operand, self.name) -class ILVariable(object): +class Variable(object): def __init__(self, func, var_type, index, identifier): self.function = func self.type = var_type @@ -363,14 +369,27 @@ class Function(object): @property def stack_layout(self): - """List of function stack (read-only)""" + """List of function stack variables (read-only)""" count = ctypes.c_ulonglong() v = core.BNGetStackLayout(self.handle, count) result = [] for i in xrange(0, count.value): - result.append(StackVariable(v[i].offset, v[i].name, types.Type(handle = core.BNNewTypeReference(v[i].type)))) - result.sort(key = lambda x: x.offset) - core.BNFreeStackLayout(v, count.value) + var = Variable(self, v[i].var.type, v[i].var.index, v[i].var.identifier) + result.append(VariableNameAndType(var, v[i].name, types.Type(handle = core.BNNewTypeReference(v[i].type)))) + result.sort(key = lambda x: x.var.identifier) + core.BNFreeVariableList(v, count.value) + return result + + @property + def vars(self): + """List of function variables (read-only)""" + count = ctypes.c_ulonglong() + v = core.BNGetFunctionVariables(self.handle, count) + result = [] + for i in xrange(0, count.value): + var = Variable(self, v[i].var.type, v[i].var.index, v[i].var.identifier) + result.append(VariableNameAndType(var, v[i].name, types.Type(handle = core.BNNewTypeReference(v[i].type)))) + core.BNFreeVariableList(v, count.value) return result @property diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index dff79fbd..f827819f 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -22,7 +22,7 @@ import ctypes # Binary Ninja components import _binaryninjacore as core -from .enums import MediumLevelILOperation, InstructionTextTokenType, ILVariableSourceType, ILBranchDependence +from .enums import MediumLevelILOperation, InstructionTextTokenType, VariableSourceType, ILBranchDependence import function import basicblock import lowlevelil @@ -157,11 +157,11 @@ class MediumLevelILInstruction(object): elif operand_type == "expr": value = MediumLevelILInstruction(func, instr.operands[i]) elif operand_type == "var": - var_type = ILVariableSourceType(instr.operands[i] >> 32) + var_type = VariableSourceType(instr.operands[i] >> 32) index = instr.operands[i] & 0xffffffff identifier = instr.operands[i + 1] i += 1 - value = function.ILVariable(self.function, var_type, index, identifier) + value = function.Variable(self.function, var_type, index, identifier) elif operand_type == "int_list": count = ctypes.c_ulonglong() operand_list = core.BNMediumLevelILGetOperandList(func.handle, self.expr_index, i, count) @@ -175,10 +175,10 @@ class MediumLevelILInstruction(object): i += 1 value = [] for j in xrange(count.value / 2): - var_type = ILVariableSourceType(operand_list[j * 2] >> 32) + var_type = VariableSourceType(operand_list[j * 2] >> 32) index = operand_list[j * 2] & 0xffffffff identifier = operand_list[(j * 2) + 1] - value.append(function.ILVariable(self.function, var_type, index, identifier)) + value.append(function.Variable(self.function, var_type, index, identifier)) core.BNMediumLevelILFreeOperandList(operand_list) elif operand_type == "var_ssa_list": count = ctypes.c_ulonglong() @@ -186,11 +186,11 @@ class MediumLevelILInstruction(object): i += 1 value = [] for j in xrange(count.value / 3): - var_type = ILVariableSourceType(operand_list[j * 3] >> 32) + var_type = VariableSourceType(operand_list[j * 3] >> 32) index = operand_list[j * 3] & 0xffffffff identifier = operand_list[(j * 3) + 1] var_index = operand_list[(j * 3) + 2] - value.append((function.ILVariable(self.function, var_type, index, identifier), var_index)) + value.append((function.Variable(self.function, var_type, index, identifier), var_index)) core.BNMediumLevelILFreeOperandList(operand_list) elif operand_type == "expr_list": count = ctypes.c_ulonglong() @@ -295,7 +295,7 @@ class MediumLevelILInstruction(object): return core.BNGetMediumLevelILSSAMemoryIndexAtILInstruction(self.function.handle, self.instr_index) def get_ssa_var_possible_values(self, var, index): - var_data = core.BNILVariable() + var_data = core.BNVariable() var_data.type = var.type var_data.index = var.index var_data.identifier = var.identifier @@ -304,7 +304,7 @@ class MediumLevelILInstruction(object): return result def get_ssa_var_index(self, var): - var_data = core.BNILVariable() + var_data = core.BNVariable() var_data.type = var.type var_data.index = var.index var_data.identifier = var.identifier @@ -314,17 +314,17 @@ class MediumLevelILInstruction(object): if isinstance(reg, str): reg = self.function.arch.regs[reg].index result = core.BNGetMediumLevelILVariableForRegisterAtInstruction(self.function.handle, reg, self.instr_index) - return function.ILVariable(self.function.source_function, result.type, result.index, result.identifier) + return function.Variable(self.function.source_function, result.type, result.index, result.identifier) def get_var_for_flag(self, flag): if isinstance(flag, str): flag = self.function.arch.regs[flag].index result = core.BNGetMediumLevelILVariableForFlagAtInstruction(self.function.handle, flag, self.instr_index) - return function.ILVariable(self.function.source_function, result.type, result.index, result.identifier) + return function.Variable(self.function.source_function, result.type, result.index, result.identifier) def get_var_for_stack_location(self, offset): result = core.BNGetMediumLevelILVariableForStackLocationAtInstruction(self.function.handle, offset, self.instr_index) - return function.ILVariable(self.function.source_function, result.type, result.index, result.identifier) + return function.Variable(self.function.source_function, result.type, result.index, result.identifier) def get_reg_value(self, reg): if isinstance(reg, str): @@ -654,7 +654,7 @@ class MediumLevelILFunction(object): return core.BNGetMediumLevelILNonSSAInstructionIndex(self.handle, instr) def get_ssa_var_definition(self, var, index): - var_data = core.BNILVariable() + var_data = core.BNVariable() var_data.type = var.type var_data.index = var.index var_data.identifier = var.identifier @@ -671,7 +671,7 @@ class MediumLevelILFunction(object): def get_ssa_var_uses(self, var, index): count = ctypes.c_ulonglong() - var_data = core.BNILVariable() + var_data = core.BNVariable() var_data.type = var.type var_data.index = var.index var_data.identifier = var.identifier @@ -692,7 +692,7 @@ class MediumLevelILFunction(object): return result def get_ssa_var_value(self, var, index): - var_data = core.BNILVariable() + var_data = core.BNVariable() var_data.type = var.type var_data.index = var.index var_data.identifier = var.identifier -- cgit v1.3.1 From d50d190f297afcb9621b39eb1d351e9eae96271b Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Thu, 20 Apr 2017 23:25:31 -0400 Subject: Renaming and adding variable identifiers --- binaryninjaapi.h | 11 ++++++--- binaryninjacore.h | 15 ++++++++---- function.cpp | 44 ++++++++++++++++++--------------- mediumlevelil.cpp | 38 ++++++++++++++--------------- python/function.py | 65 +++++++++++++++++++++++++++++-------------------- python/mediumlevelil.py | 38 ++++++++++++++--------------- 6 files changed, 118 insertions(+), 93 deletions(-) (limited to 'python/mediumlevelil.py') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index c6ac8aa3..0371c4ff 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1812,7 +1812,7 @@ namespace BinaryNinja struct Variable: public BNVariable { Variable(); - Variable(BNVariableSourceType type, uint32_t index, uint64_t identifier); + Variable(BNVariableSourceType type, uint32_t index, uint64_t storage); Variable(const BNVariable& var); Variable& operator=(const Variable& var); @@ -1820,6 +1820,9 @@ namespace BinaryNinja bool operator==(const Variable& var) const; bool operator!=(const Variable& var) const; bool operator<(const Variable& var) const; + + uint64_t ToIdentifier() const; + static Variable FromIdentifier(uint64_t id); }; struct VariableNameAndType @@ -1949,8 +1952,10 @@ namespace BinaryNinja bool GetStackVariableAtFrameOffset(Architecture* arch, uint64_t addr, int64_t offset, VariableNameAndType& var); std::map GetVariables(); - void CreateAutoVariable(const Variable& var, Ref type, const std::string& name, bool singleOnly = false); - void CreateUserVariable(const Variable& var, Ref type, const std::string& name, bool singleOnly = false); + void CreateAutoVariable(const Variable& var, Ref type, const std::string& name, + bool ignoreDisjointUses = false); + void CreateUserVariable(const Variable& var, Ref type, const std::string& name, + bool ignoreDisjointUses = false); void DeleteAutoVariable(const Variable& var); void DeleteUserVariable(const Variable& var); Ref GetVariableType(const Variable& var); diff --git a/binaryninjacore.h b/binaryninjacore.h index 68ea4069..1bd97cde 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -65,6 +65,9 @@ #define BN_DEFAULT_MIN_STRING_LENGTH 4 #define BN_MAX_STRING_LENGTH 128 +#define BN_MAX_VARIABLE_OFFSET 0x7fffffffffLL +#define BN_MAX_VARIABLE_INDEX 0xfffff + #ifdef __cplusplus extern "C" { @@ -768,16 +771,16 @@ extern "C" enum BNVariableSourceType { + StackVariableSourceType, RegisterVariableSourceType, - FlagVariableSourceType, - StackVariableSourceType + FlagVariableSourceType }; struct BNVariable { BNVariableSourceType type; uint32_t index; - int64_t identifier; + int64_t storage; }; // Callbacks @@ -1941,13 +1944,15 @@ extern "C" BINARYNINJACOREAPI BNVariableNameAndType* BNGetFunctionVariables(BNFunction* func, size_t* count); BINARYNINJACOREAPI void BNCreateAutoVariable(BNFunction* func, const BNVariable* var, BNType* type, - const char* name, bool singleOnly); + const char* name, bool ignoreDisjointUses); BINARYNINJACOREAPI void BNCreateUserVariable(BNFunction* func, const BNVariable* var, BNType* type, - const char* name, bool singleOnly); + 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 char* BNGetVariableName(BNFunction* func, const BNVariable* var); + BINARYNINJACOREAPI uint64_t BNToVariableIdentifier(const BNVariable* var); + BINARYNINJACOREAPI BNVariable BNFromVariableIdentifier(uint64_t id); BINARYNINJACOREAPI void BNSetAutoIndirectBranches(BNFunction* func, BNArchitecture* sourceArch, uint64_t source, BNArchitectureAndAddress* branches, size_t count); diff --git a/function.cpp b/function.cpp index c3402eea..b22f91dc 100644 --- a/function.cpp +++ b/function.cpp @@ -28,15 +28,15 @@ Variable::Variable() { type = RegisterVariableSourceType; index = 0; - identifier = 0; + storage = 0; } -Variable::Variable(BNVariableSourceType t, uint32_t i, uint64_t id) +Variable::Variable(BNVariableSourceType t, uint32_t i, uint64_t s) { type = t; index = i; - identifier = id; + storage = s; } @@ -44,7 +44,7 @@ Variable::Variable(const BNVariable& var) { type = var.type; index = var.index; - identifier = var.identifier; + storage = var.storage; } @@ -52,7 +52,7 @@ Variable& Variable::operator=(const Variable& var) { type = var.type; index = var.index; - identifier = var.identifier; + storage = var.storage; return *this; } @@ -63,7 +63,7 @@ bool Variable::operator==(const Variable& var) const return false; if (index != var.index) return false; - return identifier == var.identifier; + return storage == var.storage; } @@ -75,15 +75,19 @@ bool Variable::operator!=(const Variable& var) const bool Variable::operator<(const Variable& var) const { - if (type < var.type) - return true; - if (type > var.type) - return false; - if (index < var.index) - return true; - if (index > var.index) - return false; - return identifier < var.identifier; + return ToIdentifier() < var.ToIdentifier(); +} + + +uint64_t Variable::ToIdentifier() const +{ + return BNToVariableIdentifier(this); +} + + +Variable Variable::FromIdentifier(uint64_t id) +{ + return BNFromVariableIdentifier(id); } @@ -490,7 +494,7 @@ map> Function::GetStackLayout() var.type = new Type(BNNewTypeReference(vars[i].type)); var.var = vars[i].var; var.autoDefined = vars[i].autoDefined; - result[vars[i].var.identifier].push_back(var); + result[vars[i].var.storage].push_back(var); } BNFreeVariableList(vars, count); @@ -560,15 +564,15 @@ map Function::GetVariables() } -void Function::CreateAutoVariable(const Variable& var, Ref type, const string& name, bool singleOnly) +void Function::CreateAutoVariable(const Variable& var, Ref type, const string& name, bool ignoreDisjointUses) { - BNCreateAutoVariable(m_object, &var, type->GetObject(), name.c_str(), singleOnly); + BNCreateAutoVariable(m_object, &var, type->GetObject(), name.c_str(), ignoreDisjointUses); } -void Function::CreateUserVariable(const Variable& var, Ref type, const string& name, bool singleOnly) +void Function::CreateUserVariable(const Variable& var, Ref type, const string& name, bool ignoreDisjointUses) { - BNCreateUserVariable(m_object, &var, type->GetObject(), name.c_str(), singleOnly); + BNCreateUserVariable(m_object, &var, type->GetObject(), name.c_str(), ignoreDisjointUses); } diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index 4ec5d69e..0b420a82 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -75,27 +75,27 @@ ExprId MediumLevelILFunction::AddInstruction(size_t expr) ExprId MediumLevelILFunction::SetVar(size_t size, const Variable& var, ExprId src) { - return AddExpr(MLIL_SET_VAR, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, src); + return AddExpr(MLIL_SET_VAR, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, src); } ExprId MediumLevelILFunction::SetVarField(size_t size, const Variable& var, int64_t offset, ExprId src) { - return AddExpr(MLIL_SET_VAR_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, + return AddExpr(MLIL_SET_VAR_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, offset, src); } ExprId MediumLevelILFunction::SetVarSplit(size_t size, const Variable& high, const Variable& low, ExprId src) { - return AddExpr(MLIL_SET_VAR_SPLIT, size, ((uint64_t)high.type << 32) | (uint64_t)high.index, high.identifier, - ((uint64_t)low.type << 32) | (uint64_t)low.index, low.identifier, src); + return AddExpr(MLIL_SET_VAR_SPLIT, size, ((uint64_t)high.type << 32) | (uint64_t)high.index, high.storage, + ((uint64_t)low.type << 32) | (uint64_t)low.index, low.storage, src); } ExprId MediumLevelILFunction::SetVarSSA(size_t size, const Variable& var, size_t varIndex, ExprId src) { - return AddExpr(MLIL_SET_VAR_SSA, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, + return AddExpr(MLIL_SET_VAR_SSA, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, varIndex, src); } @@ -103,7 +103,7 @@ ExprId MediumLevelILFunction::SetVarSSA(size_t size, const Variable& var, size_t ExprId MediumLevelILFunction::SetVarFieldSSA(size_t size, const Variable& var, size_t varIndex, int64_t offset, ExprId src) { - return AddExpr(MLIL_SET_VAR_SSA_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, + return AddExpr(MLIL_SET_VAR_SSA_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, varIndex, offset, src); } @@ -113,16 +113,16 @@ ExprId MediumLevelILFunction::SetVarSplitSSA(size_t size, const Variable& high, { return AddExpr(MLIL_SET_VAR_SPLIT_SSA, size, AddExpr(MLIL_VAR_SPLIT_DEST_SSA, size, ((uint64_t)high.type << 32) | (uint64_t)high.index, - high.identifier, highIndex), + high.storage, highIndex), AddExpr(MLIL_VAR_SPLIT_DEST_SSA, size, ((uint64_t)low.type << 32) | (uint64_t)low.index, - low.identifier, lowIndex), src); + low.storage, lowIndex), src); } ExprId MediumLevelILFunction::SetVarAliased(size_t size, const Variable& var, size_t destIndex, size_t srcIndex, ExprId src) { - return AddExpr(MLIL_SET_VAR_ALIASED, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, + return AddExpr(MLIL_SET_VAR_ALIASED, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, destIndex, srcIndex, src); } @@ -130,60 +130,60 @@ ExprId MediumLevelILFunction::SetVarAliased(size_t size, const Variable& var, si ExprId MediumLevelILFunction::SetVarFieldAliased(size_t size, const Variable& var, size_t destIndex, size_t srcIndex, int64_t offset, ExprId src) { - return AddExpr(MLIL_SET_VAR_ALIASED_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, + return AddExpr(MLIL_SET_VAR_ALIASED_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, destIndex, srcIndex, offset, src); } ExprId MediumLevelILFunction::Var(size_t size, const Variable& var) { - return AddExpr(MLIL_VAR, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier); + return AddExpr(MLIL_VAR, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage); } ExprId MediumLevelILFunction::VarField(size_t size, const Variable& var, int64_t offset) { - return AddExpr(MLIL_VAR_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, offset); + return AddExpr(MLIL_VAR_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, offset); } ExprId MediumLevelILFunction::VarSSA(size_t size, const Variable& var, size_t varIndex) { - return AddExpr(MLIL_VAR_SSA, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, varIndex); + return AddExpr(MLIL_VAR_SSA, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, varIndex); } ExprId MediumLevelILFunction::VarFieldSSA(size_t size, const Variable& var, int64_t offset, size_t varIndex) { - return AddExpr(MLIL_VAR_SSA_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, + return AddExpr(MLIL_VAR_SSA_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, offset, varIndex); } ExprId MediumLevelILFunction::VarAliased(size_t size, const Variable& var, size_t memIndex) { - return AddExpr(MLIL_VAR_ALIASED, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, memIndex); + return AddExpr(MLIL_VAR_ALIASED, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, memIndex); } ExprId MediumLevelILFunction::VarFieldAliased(size_t size, const Variable& var, int64_t offset, size_t memIndex) { - return AddExpr(MLIL_VAR_ALIASED_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, + return AddExpr(MLIL_VAR_ALIASED_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, offset, memIndex); } ExprId MediumLevelILFunction::AddressOf(size_t size, const Variable& var) { - return AddExpr(MLIL_ADDRESS_OF, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier); + return AddExpr(MLIL_ADDRESS_OF, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage); } ExprId MediumLevelILFunction::AddressOfField(size_t size, const Variable& var, int64_t offset) { return AddExpr(MLIL_ADDRESS_OF_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, - var.identifier, offset); + var.storage, offset); } @@ -245,7 +245,7 @@ Variable MediumLevelILFunction::GetVariable(ExprId i, size_t varOperand) Variable result; result.type = (BNVariableSourceType)(instr.operands[varOperand] >> 32); result.index = (uint32_t)instr.operands[varOperand]; - result.identifier = instr.operands[varOperand + 1]; + result.storage = instr.operands[varOperand + 1]; return result; } diff --git a/python/function.py b/python/function.py index 74f4b0f8..bca67a44 100644 --- a/python/function.py +++ b/python/function.py @@ -146,25 +146,6 @@ class PossibleValueSet(object): return "" -class VariableNameAndType(object): - def __init__(self, var, name, t): - self.var = var - self.name = name - self.type = t - - def __repr__(self): - if self.var.type == VariableSourceType.StackVariableSourceType: - return "" % (self.var.identifier, self.type, self.name) - elif self.var.type == VariableSourceType.RegisterVariableSourceType: - return "" % (self.var.function.arch.get_reg_name(self.var.identifier), self.type, self.name) - elif self.var.type == VariableSourceType.FlagVariableSourceType: - return "" % (self.var.function.arch.get_flag_name(self.var.identifier), self.type, self.name) - return "" % (self.var, self.type, self.name) - - def __str__(self): - return self.name - - class StackVariableReference(object): def __init__(self, src_operand, t, name, start_ofs, ref_ofs): self.source_operand = src_operand @@ -186,11 +167,40 @@ class StackVariableReference(object): class Variable(object): - def __init__(self, func, var_type, index, identifier): + def __init__(self, func, source_type, index, storage, name = None, var_type = None): self.function = func - self.type = var_type + self.source_type = source_type self.index = index - self.identifier = identifier + self.storage = storage + + var = core.BNVariable() + var.type = source_type + var.index = index + var.storage = storage + self.identifier = core.BNToVariableIdentifier(var) + + 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) + + self.name = name + self.type = var_type + + @classmethod + def from_identifier(self, func, identifier): + var = core.BNFromVariableIdentifier(identifier) + return Variable(func, VariableSourceType(var.type), var.index, var.storage) + + def __repr__(self): + if self.type is None: + return "" % self.name + return "" % (self.type.get_string_before_name(), self.name, self.type.get_string_after_name()) + + def __str__(self): + return self.name class ConstantReference(object): @@ -374,9 +384,9 @@ class Function(object): v = core.BNGetStackLayout(self.handle, count) result = [] for i in xrange(0, count.value): - var = Variable(self, v[i].var.type, v[i].var.index, v[i].var.identifier) - result.append(VariableNameAndType(var, v[i].name, types.Type(handle = core.BNNewTypeReference(v[i].type)))) - result.sort(key = lambda x: x.var.identifier) + 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)))) + result.sort(key = lambda x: x.identifier) core.BNFreeVariableList(v, count.value) return result @@ -387,8 +397,9 @@ class Function(object): v = core.BNGetFunctionVariables(self.handle, count) result = [] for i in xrange(0, count.value): - var = Variable(self, v[i].var.type, v[i].var.index, v[i].var.identifier) - result.append(VariableNameAndType(var, v[i].name, types.Type(handle = core.BNNewTypeReference(v[i].type)))) + 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)))) + result.sort(key = lambda x: x.identifier) core.BNFreeVariableList(v, count.value) return result diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index f827819f..e959e480 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -159,9 +159,9 @@ class MediumLevelILInstruction(object): elif operand_type == "var": var_type = VariableSourceType(instr.operands[i] >> 32) index = instr.operands[i] & 0xffffffff - identifier = instr.operands[i + 1] + storage = instr.operands[i + 1] i += 1 - value = function.Variable(self.function, var_type, index, identifier) + value = function.Variable(self.function.source_function, var_type, index, storage) elif operand_type == "int_list": count = ctypes.c_ulonglong() operand_list = core.BNMediumLevelILGetOperandList(func.handle, self.expr_index, i, count) @@ -177,8 +177,8 @@ class MediumLevelILInstruction(object): for j in xrange(count.value / 2): var_type = VariableSourceType(operand_list[j * 2] >> 32) index = operand_list[j * 2] & 0xffffffff - identifier = operand_list[(j * 2) + 1] - value.append(function.Variable(self.function, var_type, index, identifier)) + storage = operand_list[(j * 2) + 1] + value.append(function.Variable(self.function.source_function, var_type, index, storage)) core.BNMediumLevelILFreeOperandList(operand_list) elif operand_type == "var_ssa_list": count = ctypes.c_ulonglong() @@ -188,9 +188,9 @@ class MediumLevelILInstruction(object): for j in xrange(count.value / 3): var_type = VariableSourceType(operand_list[j * 3] >> 32) index = operand_list[j * 3] & 0xffffffff - identifier = operand_list[(j * 3) + 1] + storage = operand_list[(j * 3) + 1] var_index = operand_list[(j * 3) + 2] - value.append((function.Variable(self.function, var_type, index, identifier), var_index)) + value.append((function.Variable(self.function.source_function, var_type, index, storage), var_index)) core.BNMediumLevelILFreeOperandList(operand_list) elif operand_type == "expr_list": count = ctypes.c_ulonglong() @@ -296,35 +296,35 @@ class MediumLevelILInstruction(object): def get_ssa_var_possible_values(self, var, index): var_data = core.BNVariable() - var_data.type = var.type + var_data.type = var.source_type var_data.index = var.index - var_data.identifier = var.identifier + var_data.storage = var.storage value = core.BNGetMediumLevelILPossibleSSAVarValues(self.function.handle, var_data, index, self.instr_index) result = function.RegisterValue(self.function.arch, value) return result def get_ssa_var_index(self, var): var_data = core.BNVariable() - var_data.type = var.type + var_data.type = var.source_type var_data.index = var.index - var_data.identifier = var.identifier + var_data.storage = var.storage return core.BNGetMediumLevelILSSAVarIndexAtILInstruction(self.function.handle, var_data, self.instr_index) def get_var_for_reg(self, reg): if isinstance(reg, str): reg = self.function.arch.regs[reg].index result = core.BNGetMediumLevelILVariableForRegisterAtInstruction(self.function.handle, reg, self.instr_index) - return function.Variable(self.function.source_function, result.type, result.index, result.identifier) + return function.Variable(self.function.source_function, result.type, result.index, result.storage) def get_var_for_flag(self, flag): if isinstance(flag, str): flag = self.function.arch.regs[flag].index result = core.BNGetMediumLevelILVariableForFlagAtInstruction(self.function.handle, flag, self.instr_index) - return function.Variable(self.function.source_function, result.type, result.index, result.identifier) + return function.Variable(self.function.source_function, result.type, result.index, result.storage) def get_var_for_stack_location(self, offset): result = core.BNGetMediumLevelILVariableForStackLocationAtInstruction(self.function.handle, offset, self.instr_index) - return function.Variable(self.function.source_function, result.type, result.index, result.identifier) + return function.Variable(self.function.source_function, result.type, result.index, result.storage) def get_reg_value(self, reg): if isinstance(reg, str): @@ -655,9 +655,9 @@ class MediumLevelILFunction(object): def get_ssa_var_definition(self, var, index): var_data = core.BNVariable() - var_data.type = var.type + var_data.type = var.source_type var_data.index = var.index - var_data.identifier = var.identifier + var_data.storage = var.storage result = core.BNGetMediumLevelILSSAVarDefinition(self.handle, var_data, index) if result >= core.BNGetMediumLevelILInstructionCount(self.handle): return None @@ -672,9 +672,9 @@ class MediumLevelILFunction(object): def get_ssa_var_uses(self, var, index): count = ctypes.c_ulonglong() var_data = core.BNVariable() - var_data.type = var.type + var_data.type = var.source_type var_data.index = var.index - var_data.identifier = var.identifier + var_data.storage = var.storage instrs = core.BNGetMediumLevelILSSAVarUses(self.handle, var_data, index, count) result = [] for i in xrange(0, count.value): @@ -693,9 +693,9 @@ class MediumLevelILFunction(object): def get_ssa_var_value(self, var, index): var_data = core.BNVariable() - var_data.type = var.type + var_data.type = var.source_type var_data.index = var.index - var_data.identifier = var.identifier + var_data.storage = var.storage value = core.BNGetMediumLevelILSSAVarValue(self.handle, var_data, index) result = function.RegisterValue(self.arch, value) return result -- cgit v1.3.1 From e673afe4b958b5f8f808ff8457d0664ccecce93a Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Fri, 21 Apr 2017 01:41:34 -0400 Subject: Using variable identifiers in MLIL --- binaryninjaapi.h | 23 +-------- binaryninjacore.h | 5 +- mediumlevelil.cpp | 129 +----------------------------------------------- python/mediumlevelil.py | 27 ++++------ 4 files changed, 14 insertions(+), 170 deletions(-) (limited to 'python/mediumlevelil.py') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 0371c4ff..072bfb5a 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2251,28 +2251,9 @@ namespace BinaryNinja size_t GetInstructionStart(Architecture* arch, uint64_t addr); ExprId AddExpr(BNMediumLevelILOperation operation, size_t size, - ExprId a = 0, ExprId b = 0, ExprId c = 0, ExprId d = 0, ExprId e = 0, ExprId f = 0); + ExprId a = 0, ExprId b = 0, ExprId c = 0, ExprId d = 0, ExprId e = 0); ExprId AddInstruction(ExprId expr); - ExprId SetVar(size_t size, const Variable& var, ExprId src); - ExprId SetVarField(size_t size, const Variable& var, int64_t offset, ExprId src); - ExprId SetVarSplit(size_t size, const Variable& high, const Variable& low, ExprId src); - ExprId SetVarSSA(size_t size, const Variable& var, size_t index, ExprId src); - ExprId SetVarFieldSSA(size_t size, const Variable& var, size_t varIndex, int64_t offset, ExprId src); - ExprId SetVarSplitSSA(size_t size, const Variable& high, size_t highIndex, - const Variable& low, size_t lowIndex, ExprId src); - ExprId SetVarAliased(size_t size, const Variable& var, size_t destIndex, size_t srcIndex, ExprId src); - ExprId SetVarFieldAliased(size_t size, const Variable& var, size_t destIndex, size_t srcIndex, - int64_t offset, ExprId src); - ExprId Var(size_t size, const Variable& var); - ExprId VarField(size_t size, const Variable& var, int64_t offset); - ExprId VarSSA(size_t size, const Variable& var, size_t index); - ExprId VarFieldSSA(size_t size, const Variable& var, int64_t offset, size_t varIndex); - ExprId VarAliased(size_t size, const Variable& var, size_t memIndex); - ExprId VarFieldAliased(size_t size, const Variable& var, int64_t offset, size_t memIndex); - ExprId AddressOf(size_t size, const Variable& var); - ExprId AddressOfField(size_t size, const Variable& var, int64_t offset); - ExprId Goto(BNMediumLevelILLabel& label); ExprId If(ExprId operand, BNMediumLevelILLabel& t, BNMediumLevelILLabel& f); void MarkLabel(BNMediumLevelILLabel& label); @@ -2281,8 +2262,6 @@ namespace BinaryNinja ExprId AddLabelList(const std::vector& labels); ExprId AddOperandList(const std::vector operands); - Variable GetVariable(ExprId i, size_t varOperand); - BNMediumLevelILInstruction operator[](size_t i) const; size_t GetIndexForInstruction(size_t i) const; size_t GetInstructionForExpr(size_t expr) const; diff --git a/binaryninjacore.h b/binaryninjacore.h index 1bd97cde..21592772 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -735,7 +735,6 @@ extern "C" MLIL_SET_VAR_SSA, MLIL_SET_VAR_SSA_FIELD, MLIL_SET_VAR_SPLIT_SSA, - MLIL_VAR_SPLIT_DEST_SSA, MLIL_SET_VAR_ALIASED, MLIL_SET_VAR_ALIASED_FIELD, MLIL_VAR_SSA, @@ -758,7 +757,7 @@ extern "C" { BNMediumLevelILOperation operation; size_t size; - uint64_t operands[6]; + uint64_t operands[5]; uint64_t address; }; @@ -2250,7 +2249,7 @@ extern "C" BINARYNINJACOREAPI size_t BNMediumLevelILGetInstructionStart(BNMediumLevelILFunction* func, BNArchitecture* arch, uint64_t addr); BINARYNINJACOREAPI size_t BNMediumLevelILAddExpr(BNMediumLevelILFunction* func, BNMediumLevelILOperation operation, - size_t size, uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e, uint64_t f); + size_t size, uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e); BINARYNINJACOREAPI size_t BNMediumLevelILAddInstruction(BNMediumLevelILFunction* func, size_t expr); BINARYNINJACOREAPI size_t BNMediumLevelILGoto(BNMediumLevelILFunction* func, BNMediumLevelILLabel* label); BINARYNINJACOREAPI size_t BNMediumLevelILIf(BNMediumLevelILFunction* func, uint64_t op, diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index 0b420a82..868f3f75 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -61,9 +61,9 @@ size_t MediumLevelILFunction::GetInstructionStart(Architecture* arch, uint64_t a ExprId MediumLevelILFunction::AddExpr(BNMediumLevelILOperation operation, size_t size, - ExprId a, ExprId b, ExprId c, ExprId d, ExprId e, ExprId f) + ExprId a, ExprId b, ExprId c, ExprId d, ExprId e) { - return BNMediumLevelILAddExpr(m_object, operation, size, a, b, c, d, e, f); + return BNMediumLevelILAddExpr(m_object, operation, size, a, b, c, d, e); } @@ -73,120 +73,6 @@ ExprId MediumLevelILFunction::AddInstruction(size_t expr) } -ExprId MediumLevelILFunction::SetVar(size_t size, const Variable& var, ExprId src) -{ - return AddExpr(MLIL_SET_VAR, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, src); -} - - -ExprId MediumLevelILFunction::SetVarField(size_t size, const Variable& var, int64_t offset, ExprId src) -{ - return AddExpr(MLIL_SET_VAR_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, - offset, src); -} - - -ExprId MediumLevelILFunction::SetVarSplit(size_t size, const Variable& high, const Variable& low, ExprId src) -{ - return AddExpr(MLIL_SET_VAR_SPLIT, size, ((uint64_t)high.type << 32) | (uint64_t)high.index, high.storage, - ((uint64_t)low.type << 32) | (uint64_t)low.index, low.storage, src); -} - - -ExprId MediumLevelILFunction::SetVarSSA(size_t size, const Variable& var, size_t varIndex, ExprId src) -{ - return AddExpr(MLIL_SET_VAR_SSA, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, - varIndex, src); -} - - -ExprId MediumLevelILFunction::SetVarFieldSSA(size_t size, const Variable& var, size_t varIndex, - int64_t offset, ExprId src) -{ - return AddExpr(MLIL_SET_VAR_SSA_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, - varIndex, offset, src); -} - - -ExprId MediumLevelILFunction::SetVarSplitSSA(size_t size, const Variable& high, size_t highIndex, - const Variable& low, size_t lowIndex, ExprId src) -{ - return AddExpr(MLIL_SET_VAR_SPLIT_SSA, size, - AddExpr(MLIL_VAR_SPLIT_DEST_SSA, size, ((uint64_t)high.type << 32) | (uint64_t)high.index, - high.storage, highIndex), - AddExpr(MLIL_VAR_SPLIT_DEST_SSA, size, ((uint64_t)low.type << 32) | (uint64_t)low.index, - low.storage, lowIndex), src); -} - - -ExprId MediumLevelILFunction::SetVarAliased(size_t size, const Variable& var, size_t destIndex, - size_t srcIndex, ExprId src) -{ - return AddExpr(MLIL_SET_VAR_ALIASED, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, - destIndex, srcIndex, src); -} - - -ExprId MediumLevelILFunction::SetVarFieldAliased(size_t size, const Variable& var, size_t destIndex, - size_t srcIndex, int64_t offset, ExprId src) -{ - return AddExpr(MLIL_SET_VAR_ALIASED_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, - destIndex, srcIndex, offset, src); -} - - -ExprId MediumLevelILFunction::Var(size_t size, const Variable& var) -{ - return AddExpr(MLIL_VAR, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage); -} - - -ExprId MediumLevelILFunction::VarField(size_t size, const Variable& var, int64_t offset) -{ - return AddExpr(MLIL_VAR_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, offset); -} - - -ExprId MediumLevelILFunction::VarSSA(size_t size, const Variable& var, size_t varIndex) -{ - return AddExpr(MLIL_VAR_SSA, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, varIndex); -} - - -ExprId MediumLevelILFunction::VarFieldSSA(size_t size, const Variable& var, int64_t offset, - size_t varIndex) -{ - return AddExpr(MLIL_VAR_SSA_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, - offset, varIndex); -} - - -ExprId MediumLevelILFunction::VarAliased(size_t size, const Variable& var, size_t memIndex) -{ - return AddExpr(MLIL_VAR_ALIASED, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, memIndex); -} - - -ExprId MediumLevelILFunction::VarFieldAliased(size_t size, const Variable& var, int64_t offset, size_t memIndex) -{ - return AddExpr(MLIL_VAR_ALIASED_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, - offset, memIndex); -} - - -ExprId MediumLevelILFunction::AddressOf(size_t size, const Variable& var) -{ - return AddExpr(MLIL_ADDRESS_OF, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage); -} - - -ExprId MediumLevelILFunction::AddressOfField(size_t size, const Variable& var, int64_t offset) -{ - return AddExpr(MLIL_ADDRESS_OF_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, - var.storage, offset); -} - - ExprId MediumLevelILFunction::Goto(BNMediumLevelILLabel& label) { return BNMediumLevelILGoto(m_object, &label); @@ -239,17 +125,6 @@ ExprId MediumLevelILFunction::AddOperandList(const vector operands) } -Variable MediumLevelILFunction::GetVariable(ExprId i, size_t varOperand) -{ - BNMediumLevelILInstruction instr = (*this)[i]; - Variable result; - result.type = (BNVariableSourceType)(instr.operands[varOperand] >> 32); - result.index = (uint32_t)instr.operands[varOperand]; - result.storage = instr.operands[varOperand + 1]; - return result; -} - - BNMediumLevelILInstruction MediumLevelILFunction::operator[](size_t i) const { return BNGetMediumLevelILByIndex(m_object, i); diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index e959e480..316e45b7 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -22,7 +22,7 @@ import ctypes # Binary Ninja components import _binaryninjacore as core -from .enums import MediumLevelILOperation, InstructionTextTokenType, VariableSourceType, ILBranchDependence +from .enums import MediumLevelILOperation, InstructionTextTokenType, ILBranchDependence import function import basicblock import lowlevelil @@ -119,7 +119,6 @@ class MediumLevelILInstruction(object): MediumLevelILOperation.MLIL_SET_VAR_SPLIT_SSA: [("high", "expr"), ("low", "expr"), ("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_ALIASED: [("dest", "var"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "exor")], MediumLevelILOperation.MLIL_SET_VAR_ALIASED_FIELD: [("dest", "var"), ("dest_memory", "int"), ("src_memory", "int"), ("offset", "int"), ("src", "exor")], - MediumLevelILOperation.MLIL_VAR_SPLIT_DEST_SSA: [("dest", "var"), ("index", "int")], MediumLevelILOperation.MLIL_VAR_SSA: [("src", "var"), ("index", "int")], MediumLevelILOperation.MLIL_VAR_SSA_FIELD: [("src", "var"), ("index", "int"), ("offset", "int")], MediumLevelILOperation.MLIL_VAR_ALIASED: [("src", "var"), ("src_memory", "int")], @@ -157,11 +156,7 @@ class MediumLevelILInstruction(object): elif operand_type == "expr": value = MediumLevelILInstruction(func, instr.operands[i]) elif operand_type == "var": - var_type = VariableSourceType(instr.operands[i] >> 32) - index = instr.operands[i] & 0xffffffff - storage = instr.operands[i + 1] - i += 1 - value = function.Variable(self.function.source_function, var_type, index, storage) + value = function.Variable.from_identifier(self.function.source_function, instr.operands[i]) elif operand_type == "int_list": count = ctypes.c_ulonglong() operand_list = core.BNMediumLevelILGetOperandList(func.handle, self.expr_index, i, count) @@ -174,23 +169,19 @@ class MediumLevelILInstruction(object): operand_list = core.BNMediumLevelILGetOperandList(func.handle, self.expr_index, i, count) i += 1 value = [] - for j in xrange(count.value / 2): - var_type = VariableSourceType(operand_list[j * 2] >> 32) - index = operand_list[j * 2] & 0xffffffff - storage = operand_list[(j * 2) + 1] - value.append(function.Variable(self.function.source_function, var_type, index, storage)) + for j in operand_list: + value.append(function.Variable.from_identifier(self.function.source_function, j)) core.BNMediumLevelILFreeOperandList(operand_list) elif operand_type == "var_ssa_list": count = ctypes.c_ulonglong() operand_list = core.BNMediumLevelILGetOperandList(func.handle, self.expr_index, i, count) i += 1 value = [] - for j in xrange(count.value / 3): - var_type = VariableSourceType(operand_list[j * 3] >> 32) - index = operand_list[j * 3] & 0xffffffff - storage = operand_list[(j * 3) + 1] - var_index = operand_list[(j * 3) + 2] - value.append((function.Variable(self.function.source_function, var_type, index, storage), var_index)) + for j in xrange(count.value / 2): + var_id = operand_list[j * 2] + var_index = operand_list[(j * 2) + 2] + value.append((function.Variable.from_identifier(self.function.source_function, + var_id), var_index)) core.BNMediumLevelILFreeOperandList(operand_list) elif operand_type == "expr_list": count = ctypes.c_ulonglong() -- cgit v1.3.1 From 095d7a42a0d2858b4240fbd041d8c22a01c7e571 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Fri, 21 Apr 2017 22:08:06 -0400 Subject: Allowing rename of all types of variables --- binaryninjaapi.h | 2 +- binaryninjacore.h | 10 +++++----- function.cpp | 4 ++-- python/function.py | 24 +++++++++++++----------- python/mediumlevelil.py | 4 ++-- 5 files changed, 23 insertions(+), 21 deletions(-) (limited to 'python/mediumlevelil.py') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 072bfb5a..8df46775 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1838,7 +1838,7 @@ namespace BinaryNinja uint32_t sourceOperand; Ref type; std::string name; - int64_t startingOffset; + Variable var; int64_t referencedOffset; }; diff --git a/binaryninjacore.h b/binaryninjacore.h index 21592772..69b45c28 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -188,7 +188,7 @@ extern "C" // not be used directly by the architecture plugins CodeSymbolToken = 64, DataSymbolToken = 65, - StackVariableToken = 66, + LocalVariableToken = 66, ImportToken = 67, AddressDisplayToken = 68 }; @@ -196,7 +196,7 @@ extern "C" enum BNInstructionTextTokenContext { NoTokenContext = 0, - StackVariableTokenContext = 1, + LocalVariableTokenContext = 1, DataVariableTokenContext = 2, FunctionReturnTokenContext = 3, ArgumentTokenContext = 4 @@ -212,8 +212,8 @@ extern "C" FunctionHeaderStartLineType, FunctionHeaderEndLineType, FunctionContinuationLineType, - StackVariableLineType, - StackVariableListEndLineType, + LocalVariableLineType, + LocalVariableListEndLineType, FunctionEndLineType, NoteStartLineType, NoteLineType, @@ -1144,7 +1144,7 @@ extern "C" uint32_t sourceOperand; BNType* type; char* name; - int64_t startingOffset; + uint64_t varIdentifier; int64_t referencedOffset; }; diff --git a/function.cpp b/function.cpp index b22f91dc..d4f91db1 100644 --- a/function.cpp +++ b/function.cpp @@ -355,7 +355,7 @@ vector Function::GetStackVariablesReferencedByInstructio ref.sourceOperand = refs[i].sourceOperand; ref.type = refs[i].type ? new Type(BNNewTypeReference(refs[i].type)) : nullptr; ref.name = refs[i].name; - ref.startingOffset = refs[i].startingOffset; + ref.var = Variable::FromIdentifier(refs[i].varIdentifier); ref.referencedOffset = refs[i].referencedOffset; result.push_back(ref); } @@ -584,7 +584,7 @@ void Function::DeleteAutoVariable(const Variable& var) void Function::DeleteUserVariable(const Variable& var) { - BNDeleteAutoVariable(m_object, &var); + BNDeleteUserVariable(m_object, &var); } diff --git a/python/function.py b/python/function.py index bca67a44..04187cbe 100644 --- a/python/function.py +++ b/python/function.py @@ -147,29 +147,29 @@ class PossibleValueSet(object): class StackVariableReference(object): - def __init__(self, src_operand, t, name, start_ofs, ref_ofs): + def __init__(self, src_operand, t, name, var, ref_ofs): self.source_operand = src_operand self.type = t self.name = name - self.starting_offset = start_ofs + self.var = var self.referenced_offset = ref_ofs if self.source_operand == 0xffffffff: self.source_operand = None def __repr__(self): if self.source_operand is None: - if self.referenced_offset != self.starting_offset: - return "" % (self.name, self.referenced_offset - self.starting_offset) + if self.referenced_offset != self.var.storage: + return "" % (self.name, self.referenced_offset - self.var.storage) return "" % self.name - if self.referenced_offset != self.starting_offset: - return "" % (self.source_operand, self.name, self.referenced_offset) + if self.referenced_offset != self.var.storage: + return "" % (self.source_operand, self.name, self.var.storage) return "" % (self.source_operand, self.name) class Variable(object): def __init__(self, func, source_type, index, storage, name = None, var_type = None): self.function = func - self.source_type = source_type + self.source_type = VariableSourceType(source_type) self.index = index self.storage = storage @@ -190,9 +190,9 @@ class Variable(object): self.type = var_type @classmethod - def from_identifier(self, func, identifier): + def from_identifier(self, func, identifier, name = None, var_type = None): var = core.BNFromVariableIdentifier(identifier) - return Variable(func, VariableSourceType(var.type), var.index, var.storage) + return Variable(func, VariableSourceType(var.type), var.index, var.storage, name, var_type) def __repr__(self): if self.type is None: @@ -603,8 +603,10 @@ class Function(object): refs = core.BNGetStackVariablesReferencedByInstruction(self.handle, arch.handle, addr, count) result = [] for i in xrange(0, count.value): - result.append(StackVariableReference(refs[i].sourceOperand, types.Type(core.BNNewTypeReference(refs[i].type)), - refs[i].name, refs[i].startingOffset, refs[i].referencedOffset)) + var_type = types.Type(core.BNNewTypeReference(refs[i].type)) + 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)) core.BNFreeStackVariableReferenceList(refs, count.value) return result diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 316e45b7..bc7a5c89 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -169,8 +169,8 @@ class MediumLevelILInstruction(object): operand_list = core.BNMediumLevelILGetOperandList(func.handle, self.expr_index, i, count) i += 1 value = [] - for j in operand_list: - value.append(function.Variable.from_identifier(self.function.source_function, j)) + for j in xrange(count.value): + value.append(function.Variable.from_identifier(self.function.source_function, operand_list[j])) core.BNMediumLevelILFreeOperandList(operand_list) elif operand_type == "var_ssa_list": count = ctypes.c_ulonglong() -- cgit v1.3.1