diff options
| author | Rusty Wagner <rusty@vector35.com> | 2016-05-08 23:46:20 -0400 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2016-05-08 23:48:17 -0400 |
| commit | 3ab807811a7efdcfeff4be101822be9d383c15e1 (patch) | |
| tree | 52115a5182525d8ad557af54b6135800f9b9a9a5 | |
| parent | ecaf78b419d323f6b589aac4b9ff5ff24b314bc6 (diff) | |
Add additional IL stage for flags resolution
| -rw-r--r-- | architecture.cpp | 26 | ||||
| -rw-r--r-- | binaryninjaapi.h | 28 | ||||
| -rw-r--r-- | binaryninjacore.h | 38 | ||||
| -rw-r--r-- | function.cpp | 42 | ||||
| -rw-r--r-- | lowlevelil.cpp | 16 | ||||
| -rw-r--r-- | python/__init__.py | 64 | ||||
| -rw-r--r-- | python/examples/nes.py | 8 |
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"], |
