summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2017-02-23 22:56:47 -0500
committerRusty Wagner <rusty@vector35.com>2017-02-23 22:56:47 -0500
commitba4bb6dbee0476d5c30d942ae978621af790d518 (patch)
tree854dc124db4895ff69bde99e630667c03ea8baf1
parentdbe5606575f6b59b82eff2f9ab7b41990b57147e (diff)
Add APIs for definitions and uses of SSA variables
-rw-r--r--binaryninjaapi.h10
-rw-r--r--binaryninjacore.h12
-rw-r--r--lowlevelil.cpp81
-rw-r--r--python/lowlevelil.py59
4 files changed, 162 insertions, 0 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 9d81b198..9bdaf5f5 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -2160,6 +2160,16 @@ namespace BinaryNinja
std::vector<Ref<BasicBlock>> GetBasicBlocks() const;
Ref<LowLevelILFunction> GetSSAForm() const;
+ Ref<LowLevelILFunction> GetNonSSAForm() const;
+ size_t GetSSAInstructionIndex(size_t instr) const;
+ size_t GetNonSSAInstructionIndex(size_t instr) const;
+
+ size_t GetSSARegisterDefinition(uint32_t reg, size_t idx) const;
+ size_t GetSSAFlagDefinition(uint32_t flag, size_t idx) const;
+ size_t GetSSAMemoryDefinition(size_t idx) const;
+ std::set<size_t> GetSSARegisterUses(uint32_t reg, size_t idx) const;
+ std::set<size_t> GetSSAFlagUses(uint32_t flag, size_t idx) const;
+ std::set<size_t> GetSSAMemoryUses(size_t idx) const;
};
class FunctionRecognizer
diff --git a/binaryninjacore.h b/binaryninjacore.h
index e95f2bf3..f7fb2172 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -2018,6 +2018,18 @@ extern "C"
BINARYNINJACOREAPI BNBasicBlock** BNGetLowLevelILBasicBlockList(BNLowLevelILFunction* func, size_t* count);
BINARYNINJACOREAPI BNLowLevelILFunction* BNGetLowLevelILSSAForm(BNLowLevelILFunction* func);
+ BINARYNINJACOREAPI BNLowLevelILFunction* BNGetLowLevelILNonSSAForm(BNLowLevelILFunction* func);
+ BINARYNINJACOREAPI size_t BNGetLowLevelILSSAInstructionIndex(BNLowLevelILFunction* func, size_t instr);
+ BINARYNINJACOREAPI size_t BNGetLowLevelILNonSSAInstructionIndex(BNLowLevelILFunction* func, size_t instr);
+
+ BINARYNINJACOREAPI size_t BNGetLowLevelILSSARegisterDefinition(BNLowLevelILFunction* func, uint32_t reg, size_t idx);
+ BINARYNINJACOREAPI size_t BNGetLowLevelILSSAFlagDefinition(BNLowLevelILFunction* func, uint32_t reg, size_t idx);
+ BINARYNINJACOREAPI size_t BNGetLowLevelILSSAMemoryDefinition(BNLowLevelILFunction* func, size_t idx);
+ BINARYNINJACOREAPI size_t* BNGetLowLevelILSSARegisterUses(BNLowLevelILFunction* func, uint32_t reg, size_t idx,
+ size_t* count);
+ BINARYNINJACOREAPI size_t* BNGetLowLevelILSSAFlagUses(BNLowLevelILFunction* func, uint32_t reg, size_t idx,
+ size_t* count);
+ BINARYNINJACOREAPI size_t* BNGetLowLevelILSSAMemoryUses(BNLowLevelILFunction* func, size_t idx, size_t* count);
// Types
BINARYNINJACOREAPI BNType* BNCreateVoidType(void);
diff --git a/lowlevelil.cpp b/lowlevelil.cpp
index 1a353b51..d09db62c 100644
--- a/lowlevelil.cpp
+++ b/lowlevelil.cpp
@@ -658,3 +658,84 @@ Ref<LowLevelILFunction> LowLevelILFunction::GetSSAForm() const
return nullptr;
return new LowLevelILFunction(func);
}
+
+
+Ref<LowLevelILFunction> LowLevelILFunction::GetNonSSAForm() const
+{
+ BNLowLevelILFunction* func = BNGetLowLevelILNonSSAForm(m_object);
+ if (!func)
+ return nullptr;
+ return new LowLevelILFunction(func);
+}
+
+
+size_t LowLevelILFunction::GetSSAInstructionIndex(size_t instr) const
+{
+ return BNGetLowLevelILNonSSAInstructionIndex(m_object, instr);
+}
+
+
+size_t LowLevelILFunction::GetNonSSAInstructionIndex(size_t instr) const
+{
+ return BNGetLowLevelILNonSSAInstructionIndex(m_object, instr);
+}
+
+
+size_t LowLevelILFunction::GetSSARegisterDefinition(uint32_t reg, size_t idx) const
+{
+ return BNGetLowLevelILSSARegisterDefinition(m_object, reg, idx);
+}
+
+
+size_t LowLevelILFunction::GetSSAFlagDefinition(uint32_t flag, size_t idx) const
+{
+ return BNGetLowLevelILSSAFlagDefinition(m_object, flag, idx);
+}
+
+
+size_t LowLevelILFunction::GetSSAMemoryDefinition(size_t idx) const
+{
+ return BNGetLowLevelILSSAMemoryDefinition(m_object, idx);
+}
+
+
+set<size_t> LowLevelILFunction::GetSSARegisterUses(uint32_t reg, size_t idx) const
+{
+ size_t count;
+ size_t* instrs = BNGetLowLevelILSSARegisterUses(m_object, reg, idx, &count);
+
+ set<size_t> result;
+ for (size_t i = 0; i < count; i++)
+ result.insert(instrs[i]);
+
+ BNFreeLowLevelILInstructionList(instrs);
+ return result;
+}
+
+
+set<size_t> LowLevelILFunction::GetSSAFlagUses(uint32_t flag, size_t idx) const
+{
+ size_t count;
+ size_t* instrs = BNGetLowLevelILSSAFlagUses(m_object, flag, idx, &count);
+
+ set<size_t> result;
+ for (size_t i = 0; i < count; i++)
+ result.insert(instrs[i]);
+
+ BNFreeLowLevelILInstructionList(instrs);
+ return result;
+}
+
+
+set<size_t> LowLevelILFunction::GetSSAMemoryUses(size_t idx) const
+{
+ size_t count;
+ size_t* instrs = BNGetLowLevelILSSAMemoryUses(m_object, idx, &count);
+
+ set<size_t> result;
+ for (size_t i = 0; i < count; i++)
+ result.insert(instrs[i]);
+
+ BNFreeLowLevelILInstructionList(instrs);
+ return result;
+}
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index 390e4210..564fef34 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -353,6 +353,14 @@ class LowLevelILFunction(object):
return None
return LowLevelILFunction(self.arch, result, self.source_function)
+ @property
+ def non_ssa_form(self):
+ """Low level IL in non-SSA (default) form (read-only)"""
+ result = core.BNGetLowLevelILNonSSAForm(self.handle)
+ if not result:
+ return None
+ return LowLevelILFunction(self.arch, result, self.source_function)
+
def __setattr__(self, name, value):
try:
object.__setattr__(self, name, value)
@@ -1327,6 +1335,57 @@ class LowLevelILFunction(object):
return None
return LowLevelILLabel(label)
+ def get_ssa_instruction_index(self, instr):
+ return core.BNGetLowLevelILSSAInstructionIndex(self.handle, instr)
+
+ def get_non_ssa_instruction_index(self, instr):
+ return core.BNGetLowLevelILNonSSAInstructionIndex(self.handle, instr)
+
+ def get_ssa_reg_definition(self, reg, index):
+ result = core.BNGetLowLevelILSSARegisterDefinition(self.handle, reg, index)
+ if result >= core.BNGetLowLevelILInstructionCount(self.handle):
+ return None
+ return result
+
+ def get_ssa_flag_definition(self, flag, index):
+ result = core.BNGetLowLevelILSSAFlagDefinition(self.handle, flag, index)
+ if result >= core.BNGetLowLevelILInstructionCount(self.handle):
+ return None
+ return result
+
+ def get_ssa_memory_definition(self, index):
+ result = core.BNGetLowLevelILSSAMemoryDefinition(self.handle, index)
+ if result >= core.BNGetLowLevelILInstructionCount(self.handle):
+ return None
+ return result
+
+ def get_ssa_reg_uses(self, reg, index):
+ count = ctypes.c_ulonglong()
+ instrs = core.BNGetLowLevelILSSARegisterUses(self.handle, reg, index, count)
+ result = []
+ for i in xrange(0, count.value):
+ result.append(instrs[i])
+ core.BNFreeLowLevelILInstructionList(instrs)
+ return result
+
+ def get_ssa_flag_uses(self, flag, index):
+ count = ctypes.c_ulonglong()
+ instrs = core.BNGetLowLevelILSSAFlagUses(self.handle, flag, index, count)
+ result = []
+ for i in xrange(0, count.value):
+ result.append(instrs[i])
+ core.BNFreeLowLevelILInstructionList(instrs)
+ return result
+
+ def get_ssa_memory_uses(self, index):
+ count = ctypes.c_ulonglong()
+ instrs = core.BNGetLowLevelILSSAMemoryUses(self.handle, index, count)
+ result = []
+ for i in xrange(0, count.value):
+ result.append(instrs[i])
+ core.BNFreeLowLevelILInstructionList(instrs)
+ return result
+
class LowLevelILBasicBlock(basicblock.BasicBlock):
def __init__(self, view, handle, owner):