diff options
| author | Rusty Wagner <rusty@vector35.com> | 2017-02-22 00:24:14 -0500 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2017-02-22 00:24:14 -0500 |
| commit | c687ea8692ee553476280ee5b621e861b627fa80 (patch) | |
| tree | 2cff5bca0fcead176ec23a1667366788de36ff81 | |
| parent | 33ae06ad9a4dfe1e78467ebf7f82a4c95f8945eb (diff) | |
Add SSA form APIs
| -rw-r--r-- | binaryninjaapi.h | 1 | ||||
| -rw-r--r-- | binaryninjacore.h | 49 | ||||
| -rw-r--r-- | function.cpp | 6 | ||||
| -rw-r--r-- | python/function.py | 5 | ||||
| -rw-r--r-- | python/lowlevelil.py | 54 |
5 files changed, 97 insertions, 18 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 6b69c95f..188471b3 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1887,6 +1887,7 @@ namespace BinaryNinja void SetCommentForAddress(uint64_t addr, const std::string& comment); Ref<LowLevelILFunction> GetLowLevelIL() const; + Ref<LowLevelILFunction> GetLowLevelILSSAForm() const; size_t GetLowLevelILForInstruction(Architecture* arch, uint64_t addr); std::vector<size_t> GetLowLevelILExitsForInstruction(Architecture* arch, uint64_t addr); RegisterValue GetRegisterValueAtInstruction(Architecture* arch, uint64_t addr, uint32_t reg); diff --git a/binaryninjacore.h b/binaryninjacore.h index d1c7f4d2..c1e7d6f9 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -238,17 +238,17 @@ extern "C" enum BNLowLevelILOperation { LLIL_NOP, - LLIL_SET_REG, - LLIL_SET_REG_SPLIT, - LLIL_SET_FLAG, - LLIL_LOAD, - LLIL_STORE, - LLIL_PUSH, - LLIL_POP, - LLIL_REG, + LLIL_SET_REG, // Not valid in SSA form (see LLIL_SET_REG_SSA) + LLIL_SET_REG_SPLIT, // Not valid in SSA form (see LLIL_SET_REG_SPLIT_SSA) + LLIL_SET_FLAG, // Not valid in SSA form (see LLIL_SET_FLAG_SSA) + LLIL_LOAD, // Not valid in SSA form (see LLIL_LOAD_SSA) + LLIL_STORE, // Not valid in SSA form (see LLIL_STORE_SSA) + LLIL_PUSH, // Not valid in SSA form (expanded) + LLIL_POP, // Not valid in SSA form (expanded) + LLIL_REG, // Not valid in SSA form (see LLIL_REG_SSA) LLIL_CONST, - LLIL_FLAG, - LLIL_FLAG_BIT, + LLIL_FLAG, // Not valid in SSA form (see LLIL_FLAG_SSA) + LLIL_FLAG_BIT, // Not valid in SSA form (see LLIL_FLAG_BIT_SSA) LLIL_ADD, LLIL_ADC, LLIL_SUB, @@ -285,7 +285,7 @@ extern "C" LLIL_NORET, LLIL_IF, LLIL_GOTO, - LLIL_FLAG_COND, + LLIL_FLAG_COND, // Valid only in Lifted IL LLIL_CMP_E, LLIL_CMP_NE, LLIL_CMP_SLT, @@ -303,7 +303,28 @@ extern "C" LLIL_TRAP, LLIL_UNDEF, LLIL_UNIMPL, - LLIL_UNIMPL_MEM + LLIL_UNIMPL_MEM, + + // The following instructions are only used in SSA form + LLIL_SET_REG_SSA, + LLIL_SET_REG_SSA_PARTIAL, + LLIL_SET_REG_SPLIT_SSA, + LLIL_REG_SPLIT_DEST_SSA, // Only valid within an LLIL_SET_REG_SPLIT_SSA instruction + LLIL_REG_SSA, + LLIL_REG_SSA_PARTIAL, + LLIL_SET_FLAG_SSA, + LLIL_FLAG_SSA, + LLIL_FLAG_BIT_SSA, + LLIL_CALL_SSA, + LLIL_SYSCALL_SSA, + LLIL_CALL_PARAM_SSA, // Only valid within the LLIL_CALL_SSA or LLIL_SYSCALL_SSA instructions + LLIL_CALL_STACK_SSA, // Only valid within the LLIL_CALL_SSA or LLIL_SYSCALL_SSA instructions + LLIL_CALL_OUTPUT_SSA, // Only valid within the LLIL_CALL_SSA or LLIL_SYSCALL_SSA instructions + LLIL_LOAD_SSA, + LLIL_STORE_SSA, + LLIL_REG_PHI, + LLIL_FLAG_PHI, + LLIL_MEM_PHI }; enum BNLowLevelILFlagCondition @@ -341,7 +362,8 @@ extern "C" { NormalFunctionGraph = 0, LowLevelILFunctionGraph = 1, - LiftedILFunctionGraph = 2 + LiftedILFunctionGraph = 2, + LowLevelILSSAFormFunctionGraph = 3 }; enum BNDisassemblyOption @@ -1672,6 +1694,7 @@ extern "C" BINARYNINJACOREAPI BNBasicBlock** BNGetBasicBlocksStartingAtAddress(BNBinaryView* view, uint64_t addr, size_t* count); BINARYNINJACOREAPI BNLowLevelILFunction* BNGetFunctionLowLevelIL(BNFunction* func); + BINARYNINJACOREAPI BNLowLevelILFunction* BNGetFunctionLowLevelILSSAForm(BNFunction* func); BINARYNINJACOREAPI size_t BNGetLowLevelILForInstruction(BNFunction* func, BNArchitecture* arch, uint64_t addr); BINARYNINJACOREAPI size_t* BNGetLowLevelILExitsForInstruction(BNFunction* func, BNArchitecture* arch, uint64_t addr, size_t* count); diff --git a/function.cpp b/function.cpp index b1d008ee..d8a5a4a7 100644 --- a/function.cpp +++ b/function.cpp @@ -147,6 +147,12 @@ Ref<LowLevelILFunction> Function::GetLowLevelIL() const } +Ref<LowLevelILFunction> Function::GetLowLevelILSSAForm() const +{ + return new LowLevelILFunction(BNGetFunctionLowLevelILSSAForm(m_object)); +} + + size_t Function::GetLowLevelILForInstruction(Architecture* arch, uint64_t addr) { return BNGetLowLevelILForInstruction(m_object, arch->GetObject(), addr); diff --git a/python/function.py b/python/function.py index 86c93bf7..47099395 100644 --- a/python/function.py +++ b/python/function.py @@ -293,6 +293,11 @@ class Function(object): return lowlevelil.LowLevelILFunction(self.arch, core.BNGetFunctionLowLevelIL(self.handle), self) @property + def low_level_il_ssa_form(self): + """Function low level IL in SSA form (read-only)""" + return lowlevelil.LowLevelILFunction(self.arch, core.BNGetFunctionLowLevelILSSAForm(self.handle), self) + + @property def lifted_il(self): """Function lifted IL (read-only)""" return lowlevelil.LowLevelILFunction(self.arch, core.BNGetFunctionLiftedIL(self.handle), self) diff --git a/python/lowlevelil.py b/python/lowlevelil.py index c80fcd0d..3ce55793 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -110,7 +110,26 @@ class LowLevelILInstruction(object): LowLevelILOperation.LLIL_TRAP: [("value", "int")], LowLevelILOperation.LLIL_UNDEF: [], LowLevelILOperation.LLIL_UNIMPL: [], - LowLevelILOperation.LLIL_UNIMPL_MEM: [("src", "expr")] + LowLevelILOperation.LLIL_UNIMPL_MEM: [("src", "expr")], + LowLevelILOperation.LLIL_SET_REG_SSA: [("dest", "reg"), ("index", "int"), ("src", "expr")], + LowLevelILOperation.LLIL_SET_REG_SSA_PARTIAL: [("full_reg", "reg"), ("index", "int"), ("dest", "reg"), ("src", "expr")], + LowLevelILOperation.LLIL_SET_REG_SPLIT_SSA: [("hi", "expr"), ("lo", "expr"), ("src", "expr")], + LowLevelILOperation.LLIL_REG_SPLIT_DEST_SSA: [("dest", "reg", "index", "int")], + LowLevelILOperation.LLIL_REG_SSA: [("src", "reg"), ("index", "int")], + LowLevelILOperation.LLIL_REG_SSA_PARTIAL: [("full_reg", "reg"), ("index", "int"), ("src", "reg")], + LowLevelILOperation.LLIL_SET_FLAG_SSA: [("dest", "flag"), ("index", "int"), ("src", "expr")], + LowLevelILOperation.LLIL_FLAG_SSA: [("src", "flag"), ("index", "int")], + LowLevelILOperation.LLIL_FLAG_BIT_SSA: [("src", "flag"), ("index", "int"), ("bit", "int")], + LowLevelILOperation.LLIL_CALL_SSA: [("output", "expr"), ("dest", "expr"), ("stack", "expr"), ("param", "expr")], + LowLevelILOperation.LLIL_SYSCALL_SSA: [("output", "expr"), ("stack", "expr"), ("param", "expr")], + LowLevelILOperation.LLIL_CALL_OUTPUT_SSA: [("dest_memory", "int"), ("dest", "reg_ssa_list")], + LowLevelILOperation.LLIL_CALL_STACK_SSA: [("src", "reg"), ("index", "int"), ("src_memory", "int")], + LowLevelILOperation.LLIL_CALL_PARAM_SSA: [("dest", "reg_ssa_list")], + LowLevelILOperation.LLIL_LOAD_SSA: [("src", "expr"), ("src_memory", "int")], + LowLevelILOperation.LLIL_STORE_SSA: [("dest", "expr"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")], + LowLevelILOperation.LLIL_REG_PHI: [("dest", "reg"), ("index", "int"), ("src", "reg_ssa_list")], + LowLevelILOperation.LLIL_FLAG_PHI: [("dest", "reg"), ("index", "int"), ("src", "flag_ssa_list")], + LowLevelILOperation.LLIL_MEM_PHI: [("dest_memory", "int"), ("src_memory", "int_list")] } def __init__(self, func, expr_index, instr_index=None): @@ -142,16 +161,41 @@ class LowLevelILInstruction(object): else: value = func.arch.get_reg_name(instr.operands[i]) elif operand_type == "flag": - value = func.arch.get_flag_name(instr.operands[i]) + if (instr.operands[i] & 0x80000000) != 0: + value = instr.operands[i] + else: + value = func.arch.get_flag_name(instr.operands[i]) elif operand_type == "cond": value = LowLevelILFlagCondition(instr.operands[i]) elif operand_type == "int_list": count = ctypes.c_ulonglong() - operands = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count) + operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count) value = [] for i in xrange(count.value): - value.append(operands[i]) - core.BNLowLevelILFreeOperandList(operands) + value.append(operand_list[i]) + core.BNLowLevelILFreeOperandList(operand_list) + elif operand_type == "reg_ssa_list": + count = ctypes.c_ulonglong() + operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count) + value = [] + for i in xrange(count.value / 2): + reg = operand_list[i * 2] + reg_index = operand_list[(i * 2) + 1] + if (reg & 0x80000000) == 0: + reg = func.arch.get_reg_name(reg) + value.append((reg, reg_index)) + core.BNLowLevelILFreeOperandList(operand_list) + elif operand_type == "flag_ssa_list": + count = ctypes.c_ulonglong() + operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count) + value = [] + for i in xrange(count.value / 2): + flag = operand_list[i * 2] + flag_index = operand_list[(i * 2) + 1] + if (flag & 0x80000000) == 0: + flag = func.arch.get_flag_name(flag) + value.append((flag, flag_index)) + core.BNLowLevelILFreeOperandList(operand_list) self.operands.append(value) self.__dict__[name] = value |
