summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2017-02-22 00:24:14 -0500
committerRusty Wagner <rusty@vector35.com>2017-02-22 00:24:14 -0500
commitc687ea8692ee553476280ee5b621e861b627fa80 (patch)
tree2cff5bca0fcead176ec23a1667366788de36ff81
parent33ae06ad9a4dfe1e78467ebf7f82a4c95f8945eb (diff)
Add SSA form APIs
-rw-r--r--binaryninjaapi.h1
-rw-r--r--binaryninjacore.h49
-rw-r--r--function.cpp6
-rw-r--r--python/function.py5
-rw-r--r--python/lowlevelil.py54
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