summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2016-05-08 23:46:20 -0400
committerRusty Wagner <rusty@vector35.com>2016-05-08 23:48:17 -0400
commit3ab807811a7efdcfeff4be101822be9d383c15e1 (patch)
tree52115a5182525d8ad557af54b6135800f9b9a9a5
parentecaf78b419d323f6b589aac4b9ff5ff24b314bc6 (diff)
Add additional IL stage for flags resolution
-rw-r--r--architecture.cpp26
-rw-r--r--binaryninjaapi.h28
-rw-r--r--binaryninjacore.h38
-rw-r--r--function.cpp42
-rw-r--r--lowlevelil.cpp16
-rw-r--r--python/__init__.py64
-rw-r--r--python/examples/nes.py8
7 files changed, 154 insertions, 68 deletions
diff --git a/architecture.cpp b/architecture.cpp
index b1f6c416..accfa69f 100644
--- a/architecture.cpp
+++ b/architecture.cpp
@@ -261,12 +261,12 @@ uint32_t* Architecture::GetFlagsWrittenByFlagWriteTypeCallback(void* ctxt, uint3
}
-bool Architecture::GetFlagWriteLowLevelILCallback(void* ctxt, BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
- BNRegisterOrConstant* operands, size_t operandCount, BNLowLevelILFunction* il)
+size_t Architecture::GetFlagWriteLowLevelILCallback(void* ctxt, BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
+ uint32_t flag, BNRegisterOrConstant* operands, size_t operandCount, BNLowLevelILFunction* il)
{
Architecture* arch = (Architecture*)ctxt;
LowLevelILFunction func(BNNewLowLevelILFunctionReference(il));
- return arch->GetFlagWriteLowLevelIL(op, size, flagWriteType, operands, operandCount, func);
+ return arch->GetFlagWriteLowLevelIL(op, size, flagWriteType, flag, operands, operandCount, func);
}
@@ -539,10 +539,18 @@ vector<uint32_t> Architecture::GetFlagsWrittenByFlagWriteType(uint32_t)
}
-bool Architecture::GetFlagWriteLowLevelIL(BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
- BNRegisterOrConstant* operands, size_t operandCount,LowLevelILFunction& il)
+size_t Architecture::GetFlagWriteLowLevelIL(BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
+ uint32_t flag, BNRegisterOrConstant* operands, size_t operandCount,LowLevelILFunction& il)
{
- return BNGetDefaultArchitectureFlagWriteLowLevelIL(m_object, op, size, flagWriteType, operands,
+ return BNGetDefaultArchitectureFlagWriteLowLevelIL(m_object, op, size, flagWriteType, flag, operands,
+ operandCount, il.GetObject());
+}
+
+
+size_t Architecture::GetDefaultFlagWriteLowLevelIL(BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
+ uint32_t flag, BNRegisterOrConstant* operands, size_t operandCount,LowLevelILFunction& il)
+{
+ return BNGetDefaultArchitectureFlagWriteLowLevelIL(m_object, op, size, flagWriteType, flag, operands,
operandCount, il.GetObject());
}
@@ -1010,10 +1018,10 @@ vector<uint32_t> CoreArchitecture::GetFlagsWrittenByFlagWriteType(uint32_t write
}
-bool CoreArchitecture::GetFlagWriteLowLevelIL(BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
- BNRegisterOrConstant* operands, size_t operandCount, LowLevelILFunction& il)
+size_t CoreArchitecture::GetFlagWriteLowLevelIL(BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
+ uint32_t flag, BNRegisterOrConstant* operands, size_t operandCount, LowLevelILFunction& il)
{
- return BNGetArchitectureFlagWriteLowLevelIL(m_object, op, size, flagWriteType, operands,
+ return BNGetArchitectureFlagWriteLowLevelIL(m_object, op, size, flagWriteType, flag, operands,
operandCount, il.GetObject());
}
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 977727e8..97caebb6 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -1008,8 +1008,8 @@ namespace BinaryNinja
static BNFlagRole GetFlagRoleCallback(void* ctxt, uint32_t flag);
static uint32_t* GetFlagsRequiredForFlagConditionCallback(void* ctxt, BNLowLevelILFlagCondition cond, size_t* count);
static uint32_t* GetFlagsWrittenByFlagWriteTypeCallback(void* ctxt, uint32_t writeType, size_t* count);
- static bool GetFlagWriteLowLevelILCallback(void* ctxt, BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
- BNRegisterOrConstant* operands, size_t operandCount, BNLowLevelILFunction* il);
+ static size_t GetFlagWriteLowLevelILCallback(void* ctxt, BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
+ uint32_t flag, BNRegisterOrConstant* operands, size_t operandCount, BNLowLevelILFunction* il);
static size_t GetFlagConditionLowLevelILCallback(void* ctxt, BNLowLevelILFlagCondition cond,
BNLowLevelILFunction* il);
static void FreeRegisterListCallback(void* ctxt, uint32_t* regs);
@@ -1058,8 +1058,10 @@ namespace BinaryNinja
virtual BNFlagRole GetFlagRole(uint32_t flag);
virtual std::vector<uint32_t> GetFlagsRequiredForFlagCondition(BNLowLevelILFlagCondition cond);
virtual std::vector<uint32_t> GetFlagsWrittenByFlagWriteType(uint32_t writeType);
- virtual bool GetFlagWriteLowLevelIL(BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
- BNRegisterOrConstant* operands, size_t operandCount, LowLevelILFunction& il);
+ virtual ExprId GetFlagWriteLowLevelIL(BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
+ uint32_t flag, BNRegisterOrConstant* operands, size_t operandCount, LowLevelILFunction& il);
+ ExprId GetDefaultFlagWriteLowLevelIL(BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
+ uint32_t flag, BNRegisterOrConstant* operands, size_t operandCount, LowLevelILFunction& il);
virtual ExprId GetFlagConditionLowLevelIL(BNLowLevelILFlagCondition cond, LowLevelILFunction& il);
virtual BNRegisterInfo GetRegisterInfo(uint32_t reg);
virtual uint32_t GetStackPointerRegister();
@@ -1132,8 +1134,8 @@ namespace BinaryNinja
virtual BNFlagRole GetFlagRole(uint32_t flag) override;
virtual std::vector<uint32_t> GetFlagsRequiredForFlagCondition(BNLowLevelILFlagCondition cond) override;
virtual std::vector<uint32_t> GetFlagsWrittenByFlagWriteType(uint32_t writeType) override;
- virtual bool GetFlagWriteLowLevelIL(BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
- BNRegisterOrConstant* operands, size_t operandCount, LowLevelILFunction& il) override;
+ virtual ExprId GetFlagWriteLowLevelIL(BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
+ uint32_t flag, BNRegisterOrConstant* operands, size_t operandCount, LowLevelILFunction& il) override;
virtual ExprId GetFlagConditionLowLevelIL(BNLowLevelILFlagCondition cond, LowLevelILFunction& il) override;
virtual BNRegisterInfo GetRegisterInfo(uint32_t reg) override;
virtual uint32_t GetStackPointerRegister() override;
@@ -1344,10 +1346,13 @@ namespace BinaryNinja
std::vector<uint32_t> GetRegistersWrittenByInstruction(Architecture* arch, uint64_t addr);
std::vector<StackVariableReference> GetStackVariablesReferencedByInstruction(Architecture* arch, uint64_t addr);
- std::set<size_t> GetLowLevelILFlagUsesForDefinition(size_t i, uint32_t flag);
- std::set<size_t> GetLowLevelILFlagDefinitionsForUse(size_t i, uint32_t flag);
- std::set<uint32_t> GetFlagsReadByLowLevelILInstruction(size_t i);
- std::set<uint32_t> GetFlagsWrittenByLowLevelILInstruction(size_t i);
+ Ref<LowLevelILFunction> GetLiftedIL() const;
+ std::vector<Ref<BasicBlock>> GetLiftedILBasicBlocks() const;
+ size_t GetLiftedILForInstruction(Architecture* arch, uint64_t addr);
+ std::set<size_t> GetLiftedILFlagUsesForDefinition(size_t i, uint32_t flag);
+ std::set<size_t> GetLiftedILFlagDefinitionsForUse(size_t i, uint32_t flag);
+ std::set<uint32_t> GetFlagsReadByLiftedILInstruction(size_t i);
+ std::set<uint32_t> GetFlagsWrittenByLiftedILInstruction(size_t i);
Ref<Type> GetType() const;
void ApplyImportedTypes(Symbol* sym);
@@ -1545,6 +1550,9 @@ namespace BinaryNinja
bool GetExprText(Architecture* arch, ExprId expr, std::vector<InstructionTextToken>& tokens);
bool GetInstructionText(Architecture* arch, size_t i, std::vector<InstructionTextToken>& tokens);
+
+ uint32_t GetTemporaryRegisterCount();
+ uint32_t GetTemporaryFlagCount();
};
class FunctionRecognizer
diff --git a/binaryninjacore.h b/binaryninjacore.h
index d062c4d8..2a9eb187 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -287,7 +287,8 @@ extern "C"
enum BNFunctionGraphType
{
NormalFunctionGraph = 0,
- LowLevelILFunctionGraph = 1
+ LowLevelILFunctionGraph = 1,
+ LiftedILFunctionGraph = 2
};
enum BNFunctionGraphOption
@@ -370,11 +371,8 @@ extern "C"
struct BNRegisterOrConstant
{
bool constant;
- union
- {
- uint32_t reg;
- uint64_t value;
- };
+ uint32_t reg;
+ uint64_t value;
};
// Callbacks
@@ -507,8 +505,8 @@ extern "C"
BNFlagRole (*getFlagRole)(void* ctxt, uint32_t flag);
uint32_t* (*getFlagsRequiredForFlagCondition)(void* ctxt, BNLowLevelILFlagCondition cond, size_t* count);
uint32_t* (*getFlagsWrittenByFlagWriteType)(void* ctxt, uint32_t writeType, size_t* count);
- bool (*getFlagWriteLowLevelIL)(void* ctxt, BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
- BNRegisterOrConstant* operands, size_t operandCount, BNLowLevelILFunction* il);
+ size_t (*getFlagWriteLowLevelIL)(void* ctxt, BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
+ uint32_t flag, BNRegisterOrConstant* operands, size_t operandCount, BNLowLevelILFunction* il);
size_t (*getFlagConditionLowLevelIL)(void* ctxt, BNLowLevelILFlagCondition cond, BNLowLevelILFunction* il);
void (*freeRegisterList)(void* ctxt, uint32_t* regs);
void (*getRegisterInfo)(void* ctxt, uint32_t reg, BNRegisterInfo* result);
@@ -1012,10 +1010,12 @@ extern "C"
size_t* count);
BINARYNINJACOREAPI uint32_t* BNGetArchitectureFlagsWrittenByFlagWriteType(BNArchitecture* arch, uint32_t writeType,
size_t* count);
- BINARYNINJACOREAPI bool BNGetArchitectureFlagWriteLowLevelIL(BNArchitecture* arch, BNLowLevelILOperation op,
- size_t size, uint32_t flagWriteType, BNRegisterOrConstant* operands, size_t operandCount, BNLowLevelILFunction* il);
- BINARYNINJACOREAPI bool BNGetDefaultArchitectureFlagWriteLowLevelIL(BNArchitecture* arch, BNLowLevelILOperation op,
- size_t size, uint32_t flagWriteType, BNRegisterOrConstant* operands, size_t operandCount, BNLowLevelILFunction* il);
+ BINARYNINJACOREAPI size_t BNGetArchitectureFlagWriteLowLevelIL(BNArchitecture* arch, BNLowLevelILOperation op,
+ size_t size, uint32_t flagWriteType, uint32_t flag, BNRegisterOrConstant* operands, size_t operandCount,
+ BNLowLevelILFunction* il);
+ BINARYNINJACOREAPI size_t BNGetDefaultArchitectureFlagWriteLowLevelIL(BNArchitecture* arch, BNLowLevelILOperation op,
+ size_t size, uint32_t flagWriteType, uint32_t flag, BNRegisterOrConstant* operands, size_t operandCount,
+ BNLowLevelILFunction* il);
BINARYNINJACOREAPI size_t BNGetArchitectureFlagConditionLowLevelIL(BNArchitecture* arch, BNLowLevelILFlagCondition cond,
BNLowLevelILFunction* il);
BINARYNINJACOREAPI uint32_t* BNGetModifiedArchitectureRegistersOnWrite(BNArchitecture* arch, uint32_t reg, size_t* count);
@@ -1111,10 +1111,13 @@ extern "C"
uint64_t addr, size_t* count);
BINARYNINJACOREAPI void BNFreeStackVariableReferenceList(BNStackVariableReference* refs, size_t count);
- BINARYNINJACOREAPI size_t* BNGetLowLevelILFlagUsesForDefinition(BNFunction* func, size_t i, uint32_t flag, size_t* count);
- BINARYNINJACOREAPI size_t* BNGetLowLevelILFlagDefinitionsForUse(BNFunction* func, size_t i, uint32_t flag, size_t* count);
- BINARYNINJACOREAPI uint32_t* BNGetFlagsReadByLowLevelILInstruction(BNFunction* func, size_t i, size_t* count);
- BINARYNINJACOREAPI uint32_t* BNGetFlagsWrittenByLowLevelILInstruction(BNFunction* func, size_t i, size_t* count);
+ BINARYNINJACOREAPI BNLowLevelILFunction* BNGetFunctionLiftedIL(BNFunction* func);
+ BINARYNINJACOREAPI BNBasicBlock** BNGetFunctionLiftedILBasicBlockList(BNFunction* func, size_t* count);
+ BINARYNINJACOREAPI size_t BNGetLiftedILForInstruction(BNFunction* func, BNArchitecture* arch, uint64_t addr);
+ BINARYNINJACOREAPI size_t* BNGetLiftedILFlagUsesForDefinition(BNFunction* func, size_t i, uint32_t flag, size_t* count);
+ BINARYNINJACOREAPI size_t* BNGetLiftedILFlagDefinitionsForUse(BNFunction* func, size_t i, uint32_t flag, size_t* count);
+ BINARYNINJACOREAPI uint32_t* BNGetFlagsReadByLiftedILInstruction(BNFunction* func, size_t i, size_t* count);
+ BINARYNINJACOREAPI uint32_t* BNGetFlagsWrittenByLiftedILInstruction(BNFunction* func, size_t i, size_t* count);
BINARYNINJACOREAPI BNType* BNGetFunctionType(BNFunction* func);
BINARYNINJACOREAPI void BNApplyImportedTypes(BNFunction* func, BNSymbol* sym);
@@ -1279,6 +1282,9 @@ extern "C"
BINARYNINJACOREAPI bool BNGetLowLevelILInstructionText(BNLowLevelILFunction* func, BNArchitecture* arch, size_t i,
BNInstructionTextToken** tokens, size_t* count);
+ BINARYNINJACOREAPI uint32_t BNGetLowLevelILTemporaryRegisterCount(BNLowLevelILFunction* func);
+ BINARYNINJACOREAPI uint32_t BNGetLowLevelILTemporaryFlagCount(BNLowLevelILFunction* func);
+
// Types
BINARYNINJACOREAPI BNType* BNCreateVoidType(void);
BINARYNINJACOREAPI BNType* BNCreateBoolType(void);
diff --git a/function.cpp b/function.cpp
index 0fb163e0..209537b7 100644
--- a/function.cpp
+++ b/function.cpp
@@ -229,10 +229,36 @@ vector<StackVariableReference> Function::GetStackVariablesReferencedByInstructio
}
-set<size_t> Function::GetLowLevelILFlagUsesForDefinition(size_t i, uint32_t flag)
+Ref<LowLevelILFunction> Function::GetLiftedIL() const
+{
+ return new LowLevelILFunction(BNGetFunctionLiftedIL(m_object));
+}
+
+
+vector<Ref<BasicBlock>> Function::GetLiftedILBasicBlocks() const
+{
+ size_t count;
+ BNBasicBlock** blocks = BNGetFunctionLiftedILBasicBlockList(m_object, &count);
+
+ vector<Ref<BasicBlock>> result;
+ for (size_t i = 0; i < count; i++)
+ result.push_back(new BasicBlock(BNNewBasicBlockReference(blocks[i])));
+
+ BNFreeBasicBlockList(blocks, count);
+ return result;
+}
+
+
+size_t Function::GetLiftedILForInstruction(Architecture* arch, uint64_t addr)
+{
+ return BNGetLiftedILForInstruction(m_object, arch->GetObject(), addr);
+}
+
+
+set<size_t> Function::GetLiftedILFlagUsesForDefinition(size_t i, uint32_t flag)
{
size_t count;
- size_t* instrs = BNGetLowLevelILFlagUsesForDefinition(m_object, i, flag, &count);
+ size_t* instrs = BNGetLiftedILFlagUsesForDefinition(m_object, i, flag, &count);
set<size_t> result;
result.insert(&instrs[0], &instrs[count]);
@@ -241,10 +267,10 @@ set<size_t> Function::GetLowLevelILFlagUsesForDefinition(size_t i, uint32_t flag
}
-set<size_t> Function::GetLowLevelILFlagDefinitionsForUse(size_t i, uint32_t flag)
+set<size_t> Function::GetLiftedILFlagDefinitionsForUse(size_t i, uint32_t flag)
{
size_t count;
- size_t* instrs = BNGetLowLevelILFlagDefinitionsForUse(m_object, i, flag, &count);
+ size_t* instrs = BNGetLiftedILFlagDefinitionsForUse(m_object, i, flag, &count);
set<size_t> result;
result.insert(&instrs[0], &instrs[count]);
@@ -253,10 +279,10 @@ set<size_t> Function::GetLowLevelILFlagDefinitionsForUse(size_t i, uint32_t flag
}
-set<uint32_t> Function::GetFlagsReadByLowLevelILInstruction(size_t i)
+set<uint32_t> Function::GetFlagsReadByLiftedILInstruction(size_t i)
{
size_t count;
- uint32_t* flags = BNGetFlagsReadByLowLevelILInstruction(m_object, i, &count);
+ uint32_t* flags = BNGetFlagsReadByLiftedILInstruction(m_object, i, &count);
set<uint32_t> result;
result.insert(&flags[0], &flags[count]);
@@ -265,10 +291,10 @@ set<uint32_t> Function::GetFlagsReadByLowLevelILInstruction(size_t i)
}
-set<uint32_t> Function::GetFlagsWrittenByLowLevelILInstruction(size_t i)
+set<uint32_t> Function::GetFlagsWrittenByLiftedILInstruction(size_t i)
{
size_t count;
- uint32_t* flags = BNGetFlagsWrittenByLowLevelILInstruction(m_object, i, &count);
+ uint32_t* flags = BNGetFlagsWrittenByLiftedILInstruction(m_object, i, &count);
set<uint32_t> result;
result.insert(&flags[0], &flags[count]);
diff --git a/lowlevelil.cpp b/lowlevelil.cpp
index a3d591a0..81104419 100644
--- a/lowlevelil.cpp
+++ b/lowlevelil.cpp
@@ -482,10 +482,10 @@ void LowLevelILFunction::MarkLabel(BNLowLevelILLabel& label)
}
-vector<uint64_t> LowLevelILFunction::GetOperandList(ExprId i, size_t listOperand)
+vector<uint64_t> LowLevelILFunction::GetOperandList(ExprId expr, size_t listOperand)
{
size_t count;
- uint64_t* operands = BNLowLevelILGetOperandList(m_object, i, listOperand, &count);
+ uint64_t* operands = BNLowLevelILGetOperandList(m_object, expr, listOperand, &count);
vector<uint64_t> result;
for (size_t i = 0; i < count; i++)
result.push_back(operands[i]);
@@ -601,3 +601,15 @@ bool LowLevelILFunction::GetInstructionText(Architecture* arch, size_t instr, ve
BNFreeInstructionText(list, count);
return true;
}
+
+
+uint32_t LowLevelILFunction::GetTemporaryRegisterCount()
+{
+ return BNGetLowLevelILTemporaryRegisterCount(m_object);
+}
+
+
+uint32_t LowLevelILFunction::GetTemporaryFlagCount()
+{
+ return BNGetLowLevelILTemporaryFlagCount(m_object);
+}
diff --git a/python/__init__.py b/python/__init__.py
index e0de7099..088e0540 100644
--- a/python/__init__.py
+++ b/python/__init__.py
@@ -1952,6 +1952,17 @@ class Function:
result.append(BasicBlock(self._view, core.BNNewBasicBlockReference(blocks[i])))
core.BNFreeBasicBlockList(blocks, count.value)
return result
+ elif name == "lifted_il":
+ return LowLevelILFunction(self.arch, core.BNNewLowLevelILFunctionReference(
+ core.BNGetFunctionLiftedIL(self.handle)))
+ elif name == "lifted_il_basic_blocks":
+ count = ctypes.c_ulonglong()
+ blocks = core.BNGetFunctionLiftedILBasicBlockList(self.handle, count)
+ result = []
+ for i in xrange(0, count.value):
+ result.append(BasicBlock(self._view, core.BNNewBasicBlockReference(blocks[i])))
+ core.BNFreeBasicBlockList(blocks, count.value)
+ return result
elif name == "type":
return Type(core.BNGetFunctionType(self.handle))
elif name == "stack_layout":
@@ -1976,14 +1987,15 @@ class Function:
def __setattr__(self, name, value):
if ((name == "view") or (name == "arch") or (name == "start") or (name == "symbol") or (name == "auto") or
(name == "can_return") or (name == "basic_blocks") or (name == "comments") or (name == "low_level_il") or
- (name == "low_level_il_basic_blocks") or (name == "type") or (name == "explicitly_defined_type") or
- (name == "stack_layout") or (name == "indirect_branches")):
+ (name == "low_level_il_basic_blocks") or (name == "lifted_il") or (name == "lifted_il_basic_blocks") or
+ (name == "type") or (name == "explicitly_defined_type") or (name == "stack_layout") or
+ (name == "indirect_branches")):
raise AttributeError, "attribute '%s' is read only" % name
else:
self.__dict__[name] = value
def __dir__(self):
- return dir(self.__class__) + ["view", "arch", "start", "symbol", "auto", "can_return", "explicitly_defined_type", "basic_blocks", "comments", "low_level_il", "low_level_il_basic_blocks", "type", "stack_layout"]
+ return dir(self.__class__) + ["view", "arch", "start", "symbol", "auto", "can_return", "explicitly_defined_type", "basic_blocks", "comments", "low_level_il", "low_level_il_basic_blocks", "lifted_il", "lifted_il_basic_blocks", "type", "stack_layout"]
def __repr__(self):
arch = self.arch
@@ -2065,40 +2077,43 @@ class Function:
core.BNFreeStackVariableReferenceList(refs, count.value)
return result
- def get_low_level_il_flag_uses_for_definition(self, i, flag):
+ def get_lifted_il_at(self, arch, addr):
+ return core.BNGetLiftedILForInstruction(self.handle, arch.handle, addr)
+
+ def get_lifted_il_flag_uses_for_definition(self, i, flag):
if isinstance(flag, str):
flag = self.arch._flags[flag]
count = ctypes.c_ulonglong()
- instrs = core.BNGetLowLevelILFlagUsesForDefinition(self.handle, i, flag, count)
+ instrs = core.BNGetLiftedILFlagUsesForDefinition(self.handle, i, flag, count)
result = []
for i in xrange(0, count.value):
result.append(instrs[i])
core.BNFreeLowLevelILInstructionList(instrs)
return result
- def get_low_level_il_flag_definitions_for_use(self, i, flag):
+ def get_lifted_il_flag_definitions_for_use(self, i, flag):
if isinstance(flag, str):
flag = self.arch._flags[flag]
count = ctypes.c_ulonglong()
- instrs = core.BNGetLowLevelILFlagDefinitionsForUse(self.handle, i, flag, count)
+ instrs = core.BNGetLiftedILFlagDefinitionsForUse(self.handle, i, flag, count)
result = []
for i in xrange(0, count.value):
result.append(instrs[i])
core.BNFreeLowLevelILInstructionList(instrs)
return result
- def get_flags_read_by_low_level_il_instruction(self, i):
+ def get_flags_read_by_lifted_il_instruction(self, i):
count = ctypes.c_ulonglong()
- flags = core.BNGetFlagsReadByLowLevelILInstruction(self.handle, i, count)
+ flags = core.BNGetFlagsReadByLiftedILInstruction(self.handle, i, count)
result = []
for i in xrange(0, count.value):
result.append(self.arch._flags_by_index[flags[i]])
core.BNFreeRegisterList(flags)
return result
- def get_flags_written_by_low_level_il_instruction(self, i):
+ def get_flags_written_by_lifted_il_instruction(self, i):
count = ctypes.c_ulonglong()
- flags = core.BNGetFlagsWrittenByLowLevelILInstruction(self.handle, i, count)
+ flags = core.BNGetFlagsWrittenByLiftedILInstruction(self.handle, i, count)
result = []
for i in xrange(0, count.value):
result.append(self.arch._flags_by_index[flags[i]])
@@ -3009,19 +3024,22 @@ class Architecture:
count[0] = 0
return None
- def _get_flag_write_low_level_il(self, ctxt, op, size, write_type, operands, operand_count, il):
+ def _get_flag_write_low_level_il(self, ctxt, op, size, write_type, flag, operands, operand_count, il):
try:
write_type_name = None
if write_type != 0:
write_type_name = self._flag_write_types_by_index[write_type]
+ flag_name = self._flags_by_index[flag]
operand_list = []
for i in xrange(operand_count):
if operands[i].constant:
- operand_list.append(operands[i].value)
+ operand_list.append(("const", operands[i].value))
+ elif LLIL_REG_IS_TEMP(operands[i].reg):
+ operand_list.append(("reg", operands[i].reg))
else:
- operand_list.append(self._regs_by_index[operands[i].reg])
- return self.perform_get_flag_write_low_level_il(op, size, write_type_name, operand_list,
- LowLevelILFunction(self, core.BNNewLowLevelILFunctionReference(il)))
+ operand_list.append(("reg", self._regs_by_index[operands[i].reg]))
+ return self.perform_get_flag_write_low_level_il(op, size, write_type_name, flag_name, operand_list,
+ LowLevelILFunction(self, core.BNNewLowLevelILFunctionReference(il))).index
except:
log_error(traceback.format_exc())
return False
@@ -3029,7 +3047,7 @@ class Architecture:
def _get_flag_condition_low_level_il(self, ctxt, cond, il):
try:
return self.perform_get_flag_condition_low_level_il(cond,
- LowLevelILFunction(self, core.BNNewLowLevelILFunctionReference(il)))
+ LowLevelILFunction(self, core.BNNewLowLevelILFunctionReference(il))).index
except:
log_error(traceback.format_exc())
return 0
@@ -3210,8 +3228,8 @@ class Architecture:
def perform_get_instruction_low_level_il(self, data, addr, il):
return None
- def perform_get_flag_write_low_level_il(self, op, size, write_type, operands, il):
- return False
+ def perform_get_flag_write_low_level_il(self, op, size, write_type, flag, operands, il):
+ return il.unimplemented()
def perform_get_flag_condition_low_level_il(self, cond, il):
return il.unimplemented()
@@ -3669,16 +3687,22 @@ class LowLevelILFunction:
def __getattr__(self, name):
if name == "current_address":
return core.BNLowLevelILGetCurrentAddress(self.handle)
+ elif name == "temp_reg_count":
+ return core.BNGetLowLevelILTemporaryRegisterCount(self.handle)
+ elif name == "temp_flag_count":
+ return core.BNGetLowLevelILTemporaryFlagCount(self.handle)
raise AttributeError, "no attribute '%s'" % name
def __setattr__(self, name, value):
if name == "current_address":
core.BNLowLevelILSetCurrentAddress(self.handle, value)
+ elif (name == "temp_reg_count") or (name == "temp_flag_count"):
+ raise AttributeError, "attribute '%s' is read only" % name
else:
self.__dict__[name] = value
def __dir__(self):
- return dir(self.__class__) + ["current_address"]
+ return dir(self.__class__) + ["current_address", "temp_reg_count", "temp_flag_count"]
def __len__(self):
return int(core.BNGetLowLevelILInstructionCount(self.handle))
diff --git a/python/examples/nes.py b/python/examples/nes.py
index 8d3d9269..21b02dfa 100644
--- a/python/examples/nes.py
+++ b/python/examples/nes.py
@@ -291,9 +291,9 @@ InstructionIL = {
"bcs": lambda il, operand: cond_branch(il, il.flag_condition(LLFC_ULT), operand),
"beq": lambda il, operand: cond_branch(il, il.flag_condition(LLFC_E), operand),
"bit": lambda il, operand: il.and_expr(1, il.reg(1, "a"), operand, flags = "czs"),
- "bmi": lambda il, operand: cond_branch(il, il.flag("s"), operand),
+ "bmi": lambda il, operand: cond_branch(il, il.flag_condition(LLFC_NEG), operand),
"bne": lambda il, operand: cond_branch(il, il.flag_condition(LLFC_NE), operand),
- "bpl": lambda il, operand: cond_branch(il, il.not_expr(0, il.flag("s")), operand),
+ "bpl": lambda il, operand: cond_branch(il, il.flag_condition(LLFC_POS), operand),
"brk": lambda il, operand: il.system_call(),
"bvc": lambda il, operand: cond_branch(il, il.not_expr(0, il.flag("v")), operand),
"bvs": lambda il, operand: cond_branch(il, il.flag("v"), operand),
@@ -368,7 +368,9 @@ class M6502(Architecture):
LLFC_UGE: ["c"],
LLFC_ULT: ["c"],
LLFC_E: ["z"],
- LLFC_NE: ["z"]
+ LLFC_NE: ["z"],
+ LLFC_NEG: ["s"],
+ LLFC_POS: ["s"]
}
flags_written_by_flag_write_type = {
"*": ["c", "z", "v", "s"],