diff options
| -rw-r--r-- | architecture.cpp | 267 | ||||
| -rw-r--r-- | binaryninjaapi.h | 48 | ||||
| -rw-r--r-- | binaryninjacore.h | 50 | ||||
| -rw-r--r-- | lowlevelilinstruction.cpp | 59 | ||||
| -rw-r--r-- | lowlevelilinstruction.h | 16 | ||||
| -rw-r--r-- | mediumlevelilinstruction.cpp | 8 | ||||
| -rw-r--r-- | python/architecture.py | 382 | ||||
| -rw-r--r-- | python/lowlevelil.py | 58 | ||||
| -rw-r--r-- | python/mediumlevelil.py | 1 |
9 files changed, 832 insertions, 57 deletions
diff --git a/architecture.cpp b/architecture.cpp index 3ca41741..571794c6 100644 --- a/architecture.cpp +++ b/architecture.cpp @@ -224,6 +224,22 @@ char* Architecture::GetFlagWriteTypeNameCallback(void* ctxt, uint32_t flags) } +char* Architecture::GetSemanticFlagClassNameCallback(void* ctxt, uint32_t semClass) +{ + Architecture* arch = (Architecture*)ctxt; + string result = arch->GetSemanticFlagClassName(semClass); + return BNAllocString(result.c_str()); +} + + +char* Architecture::GetSemanticFlagGroupNameCallback(void* ctxt, uint32_t semGroup) +{ + Architecture* arch = (Architecture*)ctxt; + string result = arch->GetSemanticFlagGroupName(semGroup); + return BNAllocString(result.c_str()); +} + + uint32_t* Architecture::GetFullWidthRegistersCallback(void* ctxt, size_t* count) { Architecture* arch = (Architecture*)ctxt; @@ -276,6 +292,32 @@ uint32_t* Architecture::GetAllFlagWriteTypesCallback(void* ctxt, size_t* count) } +uint32_t* Architecture::GetAllSemanticFlagClassesCallback(void* ctxt, size_t* count) +{ + Architecture* arch = (Architecture*)ctxt; + vector<uint32_t> regs = arch->GetAllSemanticFlagClasses(); + *count = regs.size(); + + uint32_t* result = new uint32_t[regs.size()]; + for (size_t i = 0; i < regs.size(); i++) + result[i] = regs[i]; + return result; +} + + +uint32_t* Architecture::GetAllSemanticFlagGroupsCallback(void* ctxt, size_t* count) +{ + Architecture* arch = (Architecture*)ctxt; + vector<uint32_t> regs = arch->GetAllSemanticFlagGroups(); + *count = regs.size(); + + uint32_t* result = new uint32_t[regs.size()]; + for (size_t i = 0; i < regs.size(); i++) + result[i] = regs[i]; + return result; +} + + BNFlagRole Architecture::GetFlagRoleCallback(void* ctxt, uint32_t flag) { Architecture* arch = (Architecture*)ctxt; @@ -283,10 +325,24 @@ BNFlagRole Architecture::GetFlagRoleCallback(void* ctxt, uint32_t flag) } -uint32_t* Architecture::GetFlagsRequiredForFlagConditionCallback(void* ctxt, BNLowLevelILFlagCondition cond, size_t* count) +uint32_t* Architecture::GetFlagsRequiredForFlagConditionCallback(void* ctxt, BNLowLevelILFlagCondition cond, + uint32_t semClass, size_t* count) +{ + Architecture* arch = (Architecture*)ctxt; + vector<uint32_t> flags = arch->GetFlagsRequiredForFlagCondition(cond, semClass); + *count = flags.size(); + + uint32_t* result = new uint32_t[flags.size()]; + for (size_t i = 0; i < flags.size(); i++) + result[i] = flags[i]; + return result; +} + + +uint32_t* Architecture::GetFlagsRequiredForSemanticFlagGroupCallback(void* ctxt, uint32_t semGroup, size_t* count) { Architecture* arch = (Architecture*)ctxt; - vector<uint32_t> flags = arch->GetFlagsRequiredForFlagCondition(cond); + vector<uint32_t> flags = arch->GetFlagsRequiredForSemanticFlagGroup(semGroup); *count = flags.size(); uint32_t* result = new uint32_t[flags.size()]; @@ -296,6 +352,31 @@ uint32_t* Architecture::GetFlagsRequiredForFlagConditionCallback(void* ctxt, BNL } +BNFlagConditionForSemanticClass* Architecture::GetFlagConditionsForSemanticFlagGroupCallback(void* ctxt, + uint32_t semGroup, size_t* count) +{ + Architecture* arch = (Architecture*)ctxt; + map<uint32_t, BNLowLevelILFlagCondition> conditions = arch->GetFlagConditionsForSemanticFlagGroup(semGroup); + *count = conditions.size(); + + BNFlagConditionForSemanticClass* result = new BNFlagConditionForSemanticClass[conditions.size()]; + size_t i = 0; + for (auto& j : conditions) + { + result[i].semanticClass = j.first; + result[i].condition = j.second; + i++; + } + return result; +} + + +void Architecture::FreeFlagConditionsForSemanticFlagGroupCallback(void*, BNFlagConditionForSemanticClass* conditions) +{ + delete[] conditions; +} + + uint32_t* Architecture::GetFlagsWrittenByFlagWriteTypeCallback(void* ctxt, uint32_t writeType, size_t* count) { Architecture* arch = (Architecture*)ctxt; @@ -309,6 +390,13 @@ uint32_t* Architecture::GetFlagsWrittenByFlagWriteTypeCallback(void* ctxt, uint3 } +uint32_t Architecture::GetSemanticClassForFlagWriteTypeCallback(void* ctxt, uint32_t writeType) +{ + Architecture* arch = (Architecture*)ctxt; + return arch->GetSemanticClassForFlagWriteType(writeType); +} + + size_t Architecture::GetFlagWriteLowLevelILCallback(void* ctxt, BNLowLevelILOperation op, size_t size, uint32_t flagWriteType, uint32_t flag, BNRegisterOrConstant* operands, size_t operandCount, BNLowLevelILFunction* il) { @@ -318,12 +406,20 @@ size_t Architecture::GetFlagWriteLowLevelILCallback(void* ctxt, BNLowLevelILOper } -size_t Architecture::GetFlagConditionLowLevelILCallback(void* ctxt, BNLowLevelILFlagCondition cond, +size_t Architecture::GetFlagConditionLowLevelILCallback(void* ctxt, BNLowLevelILFlagCondition cond, uint32_t semClass, BNLowLevelILFunction* il) { Architecture* arch = (Architecture*)ctxt; LowLevelILFunction func(il); - return arch->GetFlagConditionLowLevelIL(cond, func); + return arch->GetFlagConditionLowLevelIL(cond, semClass, func); +} + + +size_t Architecture::GetSemanticFlagGroupLowLevelILCallback(void* ctxt, uint32_t semGroup, BNLowLevelILFunction* il) +{ + Architecture* arch = (Architecture*)ctxt; + LowLevelILFunction func(il); + return arch->GetSemanticFlagGroupLowLevelIL(semGroup, func); } @@ -490,15 +586,24 @@ void Architecture::Register(Architecture* arch) callbacks.getRegisterName = GetRegisterNameCallback; callbacks.getFlagName = GetFlagNameCallback; callbacks.getFlagWriteTypeName = GetFlagWriteTypeNameCallback; + callbacks.getSemanticFlagClassName = GetSemanticFlagClassNameCallback; + callbacks.getSemanticFlagGroupName = GetSemanticFlagGroupNameCallback; callbacks.getFullWidthRegisters = GetFullWidthRegistersCallback; callbacks.getAllRegisters = GetAllRegistersCallback; callbacks.getAllFlags = GetAllFlagsCallback; callbacks.getAllFlagWriteTypes = GetAllFlagWriteTypesCallback; + callbacks.getAllSemanticFlagClasses = GetAllSemanticFlagClassesCallback; + callbacks.getAllSemanticFlagGroups = GetAllSemanticFlagGroupsCallback; callbacks.getFlagRole = GetFlagRoleCallback; callbacks.getFlagsRequiredForFlagCondition = GetFlagsRequiredForFlagConditionCallback; + callbacks.getFlagsRequiredForSemanticFlagGroup = GetFlagsRequiredForSemanticFlagGroupCallback; + callbacks.getFlagConditionsForSemanticFlagGroup = GetFlagConditionsForSemanticFlagGroupCallback; + callbacks.freeFlagConditionsForSemanticFlagGroup = FreeFlagConditionsForSemanticFlagGroupCallback; callbacks.getFlagsWrittenByFlagWriteType = GetFlagsWrittenByFlagWriteTypeCallback; + callbacks.getSemanticClassForFlagWriteType = GetSemanticClassForFlagWriteTypeCallback; callbacks.getFlagWriteLowLevelIL = GetFlagWriteLowLevelILCallback; callbacks.getFlagConditionLowLevelIL = GetFlagConditionLowLevelILCallback; + callbacks.getSemanticFlagGroupLowLevelIL = GetSemanticFlagGroupLowLevelILCallback; callbacks.freeRegisterList = FreeRegisterListCallback; callbacks.getRegisterInfo = GetRegisterInfoCallback; callbacks.getStackPointerRegister = GetStackPointerRegisterCallback; @@ -621,6 +726,24 @@ string Architecture::GetFlagWriteTypeName(uint32_t flags) } +string Architecture::GetSemanticFlagClassName(uint32_t semClass) +{ + if (semClass == 0) + return ""; + char flagStr[32]; + sprintf(flagStr, "semantic%" PRIu32, semClass); + return flagStr; +} + + +string Architecture::GetSemanticFlagGroupName(uint32_t semGroup) +{ + char flagStr[32]; + sprintf(flagStr, "group%" PRIu32, semGroup); + return flagStr; +} + + vector<uint32_t> Architecture::GetFullWidthRegisters() { return vector<uint32_t>(); @@ -645,24 +768,54 @@ vector<uint32_t> Architecture::GetAllFlagWriteTypes() } +vector<uint32_t> Architecture::GetAllSemanticFlagClasses() +{ + return vector<uint32_t>(); +} + + +vector<uint32_t> Architecture::GetAllSemanticFlagGroups() +{ + return vector<uint32_t>(); +} + + BNFlagRole Architecture::GetFlagRole(uint32_t) { return SpecialFlagRole; } -vector<uint32_t> Architecture::GetFlagsRequiredForFlagCondition(BNLowLevelILFlagCondition) +vector<uint32_t> Architecture::GetFlagsRequiredForFlagCondition(BNLowLevelILFlagCondition, uint32_t) { return vector<uint32_t>(); } +vector<uint32_t> Architecture::GetFlagsRequiredForSemanticFlagGroup(uint32_t) +{ + return vector<uint32_t>(); +} + + +map<uint32_t, BNLowLevelILFlagCondition> Architecture::GetFlagConditionsForSemanticFlagGroup(uint32_t) +{ + return map<uint32_t, BNLowLevelILFlagCondition>(); +} + + vector<uint32_t> Architecture::GetFlagsWrittenByFlagWriteType(uint32_t) { return vector<uint32_t>(); } +uint32_t Architecture::GetSemanticClassForFlagWriteType(uint32_t) +{ + return 0; +} + + size_t Architecture::GetFlagWriteLowLevelIL(BNLowLevelILOperation op, size_t size, uint32_t flagWriteType, uint32_t flag, BNRegisterOrConstant* operands, size_t operandCount,LowLevelILFunction& il) { @@ -681,7 +834,7 @@ size_t Architecture::GetDefaultFlagWriteLowLevelIL(BNLowLevelILOperation op, siz } -ExprId Architecture::GetFlagConditionLowLevelIL(BNLowLevelILFlagCondition cond, LowLevelILFunction& il) +ExprId Architecture::GetFlagConditionLowLevelIL(BNLowLevelILFlagCondition cond, uint32_t, LowLevelILFunction& il) { return BNGetDefaultArchitectureFlagConditionLowLevelIL(m_object, cond, il.GetObject()); } @@ -693,6 +846,12 @@ ExprId Architecture::GetDefaultFlagConditionLowLevelIL(BNLowLevelILFlagCondition } +ExprId Architecture::GetSemanticFlagGroupLowLevelIL(uint32_t, LowLevelILFunction& il) +{ + return il.Unimplemented(); +} + + BNRegisterInfo Architecture::GetRegisterInfo(uint32_t) { BNRegisterInfo result; @@ -1064,6 +1223,24 @@ string CoreArchitecture::GetFlagWriteTypeName(uint32_t flags) } +string CoreArchitecture::GetSemanticFlagClassName(uint32_t semClass) +{ + char* name = BNGetArchitectureSemanticFlagClassName(m_object, semClass); + string result = name; + BNFreeString(name); + return result; +} + + +string CoreArchitecture::GetSemanticFlagGroupName(uint32_t semGroup) +{ + char* name = BNGetArchitectureSemanticFlagGroupName(m_object, semGroup); + string result = name; + BNFreeString(name); + return result; +} + + vector<uint32_t> CoreArchitecture::GetFullWidthRegisters() { size_t count; @@ -1120,16 +1297,58 @@ vector<uint32_t> CoreArchitecture::GetAllFlagWriteTypes() } +vector<uint32_t> CoreArchitecture::GetAllSemanticFlagClasses() +{ + size_t count; + uint32_t* regs = BNGetAllArchitectureSemanticFlagClasses(m_object, &count); + + vector<uint32_t> result; + for (size_t i = 0; i < count; i++) + result.push_back(regs[i]); + + BNFreeRegisterList(regs); + return result; +} + + +vector<uint32_t> CoreArchitecture::GetAllSemanticFlagGroups() +{ + size_t count; + uint32_t* regs = BNGetAllArchitectureSemanticFlagGroups(m_object, &count); + + vector<uint32_t> result; + for (size_t i = 0; i < count; i++) + result.push_back(regs[i]); + + BNFreeRegisterList(regs); + return result; +} + + BNFlagRole CoreArchitecture::GetFlagRole(uint32_t flag) { return BNGetArchitectureFlagRole(m_object, flag); } -vector<uint32_t> CoreArchitecture::GetFlagsRequiredForFlagCondition(BNLowLevelILFlagCondition cond) +vector<uint32_t> CoreArchitecture::GetFlagsRequiredForFlagCondition(BNLowLevelILFlagCondition cond, uint32_t semClass) +{ + size_t count; + uint32_t* flags = BNGetArchitectureFlagsRequiredForFlagCondition(m_object, cond, semClass, &count); + + vector<uint32_t> result; + for (size_t i = 0; i < count; i++) + result.push_back(flags[i]); + + BNFreeRegisterList(flags); + return result; +} + + +vector<uint32_t> CoreArchitecture::GetFlagsRequiredForSemanticFlagGroup(uint32_t semGroup) { size_t count; - uint32_t* flags = BNGetArchitectureFlagsRequiredForFlagCondition(m_object, cond, &count); + uint32_t* flags = BNGetArchitectureFlagsRequiredForSemanticFlagGroup(m_object, semGroup, &count); vector<uint32_t> result; for (size_t i = 0; i < count; i++) @@ -1140,6 +1359,21 @@ vector<uint32_t> CoreArchitecture::GetFlagsRequiredForFlagCondition(BNLowLevelIL } +map<uint32_t, BNLowLevelILFlagCondition> CoreArchitecture::GetFlagConditionsForSemanticFlagGroup(uint32_t semGroup) +{ + size_t count; + BNFlagConditionForSemanticClass* conditions = BNGetArchitectureFlagConditionsForSemanticFlagGroup(m_object, + semGroup, &count); + + map<uint32_t, BNLowLevelILFlagCondition> result; + for (size_t i = 0; i < count; i++) + result[conditions[i].semanticClass] = conditions[i].condition; + + BNFreeFlagConditionsForSemanticFlagGroup(conditions); + return result; +} + + vector<uint32_t> CoreArchitecture::GetFlagsWrittenByFlagWriteType(uint32_t writeType) { size_t count; @@ -1154,6 +1388,12 @@ vector<uint32_t> CoreArchitecture::GetFlagsWrittenByFlagWriteType(uint32_t write } +uint32_t CoreArchitecture::GetSemanticClassForFlagWriteType(uint32_t writeType) +{ + return BNGetArchitectureSemanticClassForFlagWriteType(m_object, writeType); +} + + size_t CoreArchitecture::GetFlagWriteLowLevelIL(BNLowLevelILOperation op, size_t size, uint32_t flagWriteType, uint32_t flag, BNRegisterOrConstant* operands, size_t operandCount, LowLevelILFunction& il) { @@ -1162,9 +1402,16 @@ size_t CoreArchitecture::GetFlagWriteLowLevelIL(BNLowLevelILOperation op, size_t } -ExprId CoreArchitecture::GetFlagConditionLowLevelIL(BNLowLevelILFlagCondition cond, LowLevelILFunction& il) +ExprId CoreArchitecture::GetFlagConditionLowLevelIL(BNLowLevelILFlagCondition cond, + uint32_t semClass, LowLevelILFunction& il) +{ + return (ExprId)BNGetArchitectureFlagConditionLowLevelIL(m_object, cond, semClass, il.GetObject()); +} + + +ExprId CoreArchitecture::GetSemanticFlagGroupLowLevelIL(uint32_t semGroup, LowLevelILFunction& il) { - return (ExprId)BNGetArchitectureFlagConditionLowLevelIL(m_object, cond, il.GetObject()); + return (ExprId)BNGetArchitectureSemanticFlagGroupLowLevelIL(m_object, semGroup, il.GetObject()); } diff --git a/binaryninjaapi.h b/binaryninjaapi.h index b90f72a2..cbd51d05 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1601,17 +1601,28 @@ namespace BinaryNinja static char* GetRegisterNameCallback(void* ctxt, uint32_t reg); static char* GetFlagNameCallback(void* ctxt, uint32_t flag); static char* GetFlagWriteTypeNameCallback(void* ctxt, uint32_t flags); + static char* GetSemanticFlagClassNameCallback(void* ctxt, uint32_t semClass); + static char* GetSemanticFlagGroupNameCallback(void* ctxt, uint32_t semGroup); static uint32_t* GetFullWidthRegistersCallback(void* ctxt, size_t* count); static uint32_t* GetAllRegistersCallback(void* ctxt, size_t* count); static uint32_t* GetAllFlagsCallback(void* ctxt, size_t* count); static uint32_t* GetAllFlagWriteTypesCallback(void* ctxt, size_t* count); + static uint32_t* GetAllSemanticFlagClassesCallback(void* ctxt, size_t* count); + static uint32_t* GetAllSemanticFlagGroupsCallback(void* ctxt, size_t* count); static BNFlagRole GetFlagRoleCallback(void* ctxt, uint32_t flag); - static uint32_t* GetFlagsRequiredForFlagConditionCallback(void* ctxt, BNLowLevelILFlagCondition cond, size_t* count); + static uint32_t* GetFlagsRequiredForFlagConditionCallback(void* ctxt, BNLowLevelILFlagCondition cond, + uint32_t semClass, size_t* count); + static uint32_t* GetFlagsRequiredForSemanticFlagGroupCallback(void* ctxt, uint32_t semGroup, size_t* count); + static BNFlagConditionForSemanticClass* GetFlagConditionsForSemanticFlagGroupCallback(void* ctxt, + uint32_t semGroup, size_t* count); + static void FreeFlagConditionsForSemanticFlagGroupCallback(void* ctxt, BNFlagConditionForSemanticClass* conditions); static uint32_t* GetFlagsWrittenByFlagWriteTypeCallback(void* ctxt, uint32_t writeType, size_t* count); + static uint32_t GetSemanticClassForFlagWriteTypeCallback(void* ctxt, uint32_t writeType); 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); + uint32_t semClass, BNLowLevelILFunction* il); + static size_t GetSemanticFlagGroupLowLevelILCallback(void* ctxt, uint32_t semGroup, BNLowLevelILFunction* il); static void FreeRegisterListCallback(void* ctxt, uint32_t* regs); static void GetRegisterInfoCallback(void* ctxt, uint32_t reg, BNRegisterInfo* result); static uint32_t GetStackPointerRegisterCallback(void* ctxt); @@ -1668,19 +1679,28 @@ namespace BinaryNinja virtual std::string GetRegisterName(uint32_t reg); virtual std::string GetFlagName(uint32_t flag); virtual std::string GetFlagWriteTypeName(uint32_t flags); + virtual std::string GetSemanticFlagClassName(uint32_t semClass); + virtual std::string GetSemanticFlagGroupName(uint32_t semGroup); virtual std::vector<uint32_t> GetFullWidthRegisters(); virtual std::vector<uint32_t> GetAllRegisters(); virtual std::vector<uint32_t> GetAllFlags(); virtual std::vector<uint32_t> GetAllFlagWriteTypes(); + virtual std::vector<uint32_t> GetAllSemanticFlagClasses(); + virtual std::vector<uint32_t> GetAllSemanticFlagGroups(); virtual BNFlagRole GetFlagRole(uint32_t flag); - virtual std::vector<uint32_t> GetFlagsRequiredForFlagCondition(BNLowLevelILFlagCondition cond); + virtual std::vector<uint32_t> GetFlagsRequiredForFlagCondition(BNLowLevelILFlagCondition cond, + uint32_t semClass = 0); + virtual std::vector<uint32_t> GetFlagsRequiredForSemanticFlagGroup(uint32_t semGroup); + virtual std::map<uint32_t, BNLowLevelILFlagCondition> GetFlagConditionsForSemanticFlagGroup(uint32_t semGroup); virtual std::vector<uint32_t> GetFlagsWrittenByFlagWriteType(uint32_t writeType); + virtual uint32_t GetSemanticClassForFlagWriteType(uint32_t writeType); 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, BNFlagRole role, BNRegisterOrConstant* operands, size_t operandCount, LowLevelILFunction& il); - virtual ExprId GetFlagConditionLowLevelIL(BNLowLevelILFlagCondition cond, LowLevelILFunction& il); + virtual ExprId GetFlagConditionLowLevelIL(BNLowLevelILFlagCondition cond, uint32_t semClass, LowLevelILFunction& il); ExprId GetDefaultFlagConditionLowLevelIL(BNLowLevelILFlagCondition cond, LowLevelILFunction& il); + virtual ExprId GetSemanticFlagGroupLowLevelIL(uint32_t semGroup, LowLevelILFunction& il); virtual BNRegisterInfo GetRegisterInfo(uint32_t reg); virtual uint32_t GetStackPointerRegister(); virtual uint32_t GetLinkRegister(); @@ -1804,16 +1824,26 @@ namespace BinaryNinja virtual std::string GetRegisterName(uint32_t reg) override; virtual std::string GetFlagName(uint32_t flag) override; virtual std::string GetFlagWriteTypeName(uint32_t flags) override; + virtual std::string GetSemanticFlagClassName(uint32_t semClass) override; + virtual std::string GetSemanticFlagGroupName(uint32_t semGroup) override; virtual std::vector<uint32_t> GetFullWidthRegisters() override; virtual std::vector<uint32_t> GetAllRegisters() override; virtual std::vector<uint32_t> GetAllFlags() override; virtual std::vector<uint32_t> GetAllFlagWriteTypes() override; + virtual std::vector<uint32_t> GetAllSemanticFlagClasses() override; + virtual std::vector<uint32_t> GetAllSemanticFlagGroups() override; virtual BNFlagRole GetFlagRole(uint32_t flag) override; - virtual std::vector<uint32_t> GetFlagsRequiredForFlagCondition(BNLowLevelILFlagCondition cond) override; + virtual std::vector<uint32_t> GetFlagsRequiredForFlagCondition(BNLowLevelILFlagCondition cond, + uint32_t semClass = 0) override; + virtual std::vector<uint32_t> GetFlagsRequiredForSemanticFlagGroup(uint32_t semGroup) override; + virtual std::map<uint32_t, BNLowLevelILFlagCondition> GetFlagConditionsForSemanticFlagGroup(uint32_t semGroup) override; virtual std::vector<uint32_t> GetFlagsWrittenByFlagWriteType(uint32_t writeType) override; + virtual uint32_t GetSemanticClassForFlagWriteType(uint32_t writeType) 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 ExprId GetFlagConditionLowLevelIL(BNLowLevelILFlagCondition cond, + uint32_t semClass, LowLevelILFunction& il) override; + virtual ExprId GetSemanticFlagGroupLowLevelIL(uint32_t semGroup, LowLevelILFunction& il) override; virtual BNRegisterInfo GetRegisterInfo(uint32_t reg) override; virtual uint32_t GetStackPointerRegister() override; virtual uint32_t GetLinkRegister() override; @@ -2584,7 +2614,9 @@ namespace BinaryNinja const ILSourceLocation& loc = ILSourceLocation()); ExprId Return(size_t dest, const ILSourceLocation& loc = ILSourceLocation()); ExprId NoReturn(const ILSourceLocation& loc = ILSourceLocation()); - ExprId FlagCondition(BNLowLevelILFlagCondition cond, const ILSourceLocation& loc = ILSourceLocation()); + ExprId FlagCondition(BNLowLevelILFlagCondition cond, uint32_t semClass = 0, + const ILSourceLocation& loc = ILSourceLocation()); + ExprId FlagGroup(uint32_t semGroup, const ILSourceLocation& loc = ILSourceLocation()); ExprId CompareEqual(size_t size, ExprId a, ExprId b, const ILSourceLocation& loc = ILSourceLocation()); ExprId CompareNotEqual(size_t size, ExprId a, ExprId b, @@ -2641,6 +2673,7 @@ namespace BinaryNinja ExprId FloatCompareLessEqual(size_t size, ExprId a, ExprId b, const ILSourceLocation& loc = ILSourceLocation()); ExprId FloatCompareGreaterEqual(size_t size, ExprId a, ExprId b, const ILSourceLocation& loc = ILSourceLocation()); ExprId FloatCompareGreaterThan(size_t size, ExprId a, ExprId b, const ILSourceLocation& loc = ILSourceLocation()); + ExprId FloatCompareOrdered(size_t size, ExprId a, ExprId b, const ILSourceLocation& loc = ILSourceLocation()); ExprId FloatCompareUnordered(size_t size, ExprId a, ExprId b, const ILSourceLocation& loc = ILSourceLocation()); ExprId Goto(BNLowLevelILLabel& label, const ILSourceLocation& loc = ILSourceLocation()); @@ -2944,6 +2977,7 @@ namespace BinaryNinja ExprId FloatCompareLessEqual(size_t size, ExprId a, ExprId b, const ILSourceLocation& loc = ILSourceLocation()); ExprId FloatCompareGreaterEqual(size_t size, ExprId a, ExprId b, const ILSourceLocation& loc = ILSourceLocation()); ExprId FloatCompareGreaterThan(size_t size, ExprId a, ExprId b, const ILSourceLocation& loc = ILSourceLocation()); + ExprId FloatCompareOrdered(size_t size, ExprId a, ExprId b, const ILSourceLocation& loc = ILSourceLocation()); ExprId FloatCompareUnordered(size_t size, ExprId a, ExprId b, const ILSourceLocation& loc = ILSourceLocation()); ExprId Goto(BNMediumLevelILLabel& label, const ILSourceLocation& loc = ILSourceLocation()); diff --git a/binaryninjacore.h b/binaryninjacore.h index baca94be..388d3643 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -335,6 +335,7 @@ extern "C" LLIL_IF, LLIL_GOTO, LLIL_FLAG_COND, // Valid only in Lifted IL + LLIL_FLAG_GROUP, // Valid only in Lifted IL LLIL_CMP_E, LLIL_CMP_NE, LLIL_CMP_SLT, @@ -372,6 +373,7 @@ extern "C" LLIL_FCMP_LE, LLIL_FCMP_GE, LLIL_FCMP_GT, + LLIL_FCMP_O, LLIL_FCMP_UO, // The following instructions are only used in SSA form @@ -418,7 +420,15 @@ extern "C" LLFC_NEG, LLFC_POS, LLFC_O, - LLFC_NO + LLFC_NO, + LLFC_FE, + LLFC_FNE, + LLFC_FLT, + LLFC_FLE, + LLFC_FGE, + LLFC_FGT, + LLFC_FO, + LLFC_FUO }; enum BNFlagRole @@ -869,6 +879,7 @@ extern "C" MLIL_FCMP_LE, MLIL_FCMP_GE, MLIL_FCMP_GT, + MLIL_FCMP_O, MLIL_FCMP_UO, // The following instructions are only used in SSA form @@ -1058,6 +1069,12 @@ extern "C" size_t count; }; + struct BNFlagConditionForSemanticClass + { + uint32_t semanticClass; + BNLowLevelILFlagCondition condition; + }; + struct BNCustomArchitecture { void* context; @@ -1077,16 +1094,27 @@ extern "C" char* (*getRegisterName)(void* ctxt, uint32_t reg); char* (*getFlagName)(void* ctxt, uint32_t flag); char* (*getFlagWriteTypeName)(void* ctxt, uint32_t flags); + char* (*getSemanticFlagClassName)(void* ctxt, uint32_t semClass); + char* (*getSemanticFlagGroupName)(void* ctxt, uint32_t semGroup); uint32_t* (*getFullWidthRegisters)(void* ctxt, size_t* count); uint32_t* (*getAllRegisters)(void* ctxt, size_t* count); uint32_t* (*getAllFlags)(void* ctxt, size_t* count); uint32_t* (*getAllFlagWriteTypes)(void* ctxt, size_t* count); + uint32_t* (*getAllSemanticFlagClasses)(void* ctxt, size_t* count); + uint32_t* (*getAllSemanticFlagGroups)(void* ctxt, size_t* count); BNFlagRole (*getFlagRole)(void* ctxt, uint32_t flag); - uint32_t* (*getFlagsRequiredForFlagCondition)(void* ctxt, BNLowLevelILFlagCondition cond, size_t* count); + uint32_t* (*getFlagsRequiredForFlagCondition)(void* ctxt, BNLowLevelILFlagCondition cond, + uint32_t semClass, size_t* count); + uint32_t* (*getFlagsRequiredForSemanticFlagGroup)(void* ctxt, uint32_t semGroup, size_t* count); + BNFlagConditionForSemanticClass* (*getFlagConditionsForSemanticFlagGroup)(void* ctxt, uint32_t semGroup, size_t* count); + void (*freeFlagConditionsForSemanticFlagGroup)(void* ctxt, BNFlagConditionForSemanticClass* conditions); uint32_t* (*getFlagsWrittenByFlagWriteType)(void* ctxt, uint32_t writeType, size_t* count); + uint32_t (*getSemanticClassForFlagWriteType)(void* ctxt, uint32_t writeType); 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); + size_t (*getFlagConditionLowLevelIL)(void* ctxt, BNLowLevelILFlagCondition cond, + uint32_t semClass, BNLowLevelILFunction* il); + size_t (*getSemanticFlagGroupLowLevelIL)(void* ctxt, uint32_t semGroup, BNLowLevelILFunction* il); void (*freeRegisterList)(void* ctxt, uint32_t* regs); void (*getRegisterInfo)(void* ctxt, uint32_t reg, BNRegisterInfo* result); uint32_t (*getStackPointerRegister)(void* ctxt); @@ -2042,24 +2070,36 @@ extern "C" BINARYNINJACOREAPI char* BNGetArchitectureRegisterName(BNArchitecture* arch, uint32_t reg); BINARYNINJACOREAPI char* BNGetArchitectureFlagName(BNArchitecture* arch, uint32_t flag); BINARYNINJACOREAPI char* BNGetArchitectureFlagWriteTypeName(BNArchitecture* arch, uint32_t flags); + BINARYNINJACOREAPI char* BNGetArchitectureSemanticFlagClassName(BNArchitecture* arch, uint32_t semClass); + BINARYNINJACOREAPI char* BNGetArchitectureSemanticFlagGroupName(BNArchitecture* arch, uint32_t semGroup); BINARYNINJACOREAPI uint32_t* BNGetFullWidthArchitectureRegisters(BNArchitecture* arch, size_t* count); BINARYNINJACOREAPI uint32_t* BNGetAllArchitectureRegisters(BNArchitecture* arch, size_t* count); BINARYNINJACOREAPI uint32_t* BNGetAllArchitectureFlags(BNArchitecture* arch, size_t* count); BINARYNINJACOREAPI uint32_t* BNGetAllArchitectureFlagWriteTypes(BNArchitecture* arch, size_t* count); + BINARYNINJACOREAPI uint32_t* BNGetAllArchitectureSemanticFlagClasses(BNArchitecture* arch, size_t* count); + BINARYNINJACOREAPI uint32_t* BNGetAllArchitectureSemanticFlagGroups(BNArchitecture* arch, size_t* count); BINARYNINJACOREAPI BNFlagRole BNGetArchitectureFlagRole(BNArchitecture* arch, uint32_t flag); BINARYNINJACOREAPI uint32_t* BNGetArchitectureFlagsRequiredForFlagCondition(BNArchitecture* arch, BNLowLevelILFlagCondition cond, - size_t* count); + uint32_t semClass, size_t* count); + BINARYNINJACOREAPI uint32_t* BNGetArchitectureFlagsRequiredForSemanticFlagGroup(BNArchitecture* arch, + uint32_t semGroup, size_t* count); + BINARYNINJACOREAPI BNFlagConditionForSemanticClass* BNGetArchitectureFlagConditionsForSemanticFlagGroup(BNArchitecture* arch, + uint32_t semGroup, size_t* count); + BINARYNINJACOREAPI void BNFreeFlagConditionsForSemanticFlagGroup(BNFlagConditionForSemanticClass* conditions); BINARYNINJACOREAPI uint32_t* BNGetArchitectureFlagsWrittenByFlagWriteType(BNArchitecture* arch, uint32_t writeType, size_t* count); + BINARYNINJACOREAPI uint32_t BNGetArchitectureSemanticClassForFlagWriteType(BNArchitecture* arch, uint32_t writeType); 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, BNFlagRole role, BNRegisterOrConstant* operands, size_t operandCount, BNLowLevelILFunction* il); BINARYNINJACOREAPI size_t BNGetArchitectureFlagConditionLowLevelIL(BNArchitecture* arch, BNLowLevelILFlagCondition cond, - BNLowLevelILFunction* il); + uint32_t semClass, BNLowLevelILFunction* il); BINARYNINJACOREAPI size_t BNGetDefaultArchitectureFlagConditionLowLevelIL(BNArchitecture* arch, BNLowLevelILFlagCondition cond, BNLowLevelILFunction* il); + BINARYNINJACOREAPI size_t BNGetArchitectureSemanticFlagGroupLowLevelIL(BNArchitecture* arch, + uint32_t semGroup, BNLowLevelILFunction* il); BINARYNINJACOREAPI uint32_t* BNGetModifiedArchitectureRegistersOnWrite(BNArchitecture* arch, uint32_t reg, size_t* count); BINARYNINJACOREAPI void BNFreeRegisterList(uint32_t* regs); BINARYNINJACOREAPI BNRegisterInfo BNGetArchitectureRegisterInfo(BNArchitecture* arch, uint32_t reg); diff --git a/lowlevelilinstruction.cpp b/lowlevelilinstruction.cpp index 6b67ef72..4b1acff3 100644 --- a/lowlevelilinstruction.cpp +++ b/lowlevelilinstruction.cpp @@ -49,6 +49,8 @@ unordered_map<LowLevelILOperandUsage, LowLevelILOperandType> {DestSSARegisterLowLevelOperandUsage, SSARegisterLowLevelOperand}, {DestSSARegisterStackLowLevelOperandUsage, SSARegisterStackLowLevelOperand}, {DestSSAFlagLowLevelOperandUsage, SSAFlagLowLevelOperand}, + {SemanticFlagClassLowLevelOperandUsage, SemanticFlagClassLowLevelOperand}, + {SemanticFlagGroupLowLevelOperandUsage, SemanticFlagGroupLowLevelOperand}, {PartialRegisterLowLevelOperandUsage, RegisterLowLevelOperand}, {PartialSSARegisterStackSourceLowLevelOperandUsage, SSARegisterStackLowLevelOperand}, {StackSSARegisterLowLevelOperandUsage, SSARegisterLowLevelOperand}, @@ -140,7 +142,8 @@ unordered_map<BNLowLevelILOperation, vector<LowLevelILOperandUsage>> {LLIL_IF, {ConditionExprLowLevelOperandUsage, TrueTargetLowLevelOperandUsage, FalseTargetLowLevelOperandUsage}}, {LLIL_GOTO, {TargetLowLevelOperandUsage}}, - {LLIL_FLAG_COND, {FlagConditionLowLevelOperandUsage}}, + {LLIL_FLAG_COND, {FlagConditionLowLevelOperandUsage, SemanticFlagClassLowLevelOperandUsage}}, + {LLIL_FLAG_GROUP, {SemanticFlagGroupLowLevelOperandUsage}}, {LLIL_TRAP, {VectorLowLevelOperandUsage}}, {LLIL_CALL_SSA, {OutputSSARegistersLowLevelOperandUsage, OutputMemoryVersionLowLevelOperandUsage, DestExprLowLevelOperandUsage, StackSSARegisterLowLevelOperandUsage, @@ -886,6 +889,22 @@ BNLowLevelILFlagCondition LowLevelILOperand::GetFlagCondition() const } +uint32_t LowLevelILOperand::GetSemanticFlagClass() const +{ + if (m_type != SemanticFlagClassLowLevelOperand) + throw LowLevelILInstructionAccessException(); + return m_instr.GetRawOperandAsRegister(m_operandIndex); +} + + +uint32_t LowLevelILOperand::GetSemanticFlagGroup() const +{ + if (m_type != SemanticFlagGroupLowLevelOperand) + throw LowLevelILInstructionAccessException(); + return m_instr.GetRawOperandAsRegister(m_operandIndex); +} + + SSARegister LowLevelILOperand::GetSSARegister() const { if (m_type != SSARegisterLowLevelOperand) @@ -1710,7 +1729,9 @@ ExprId LowLevelILInstruction::CopyTo(LowLevelILFunction* dest, return dest->Undefined(*this); return dest->If(subExprHandler(GetConditionExpr<LLIL_IF>()), *labelA, *labelB, *this); case LLIL_FLAG_COND: - return dest->FlagCondition(GetFlagCondition<LLIL_FLAG_COND>(), *this); + return dest->FlagCondition(GetFlagCondition<LLIL_FLAG_COND>(), GetSemanticFlagClass<LLIL_FLAG_COND>(), *this); + case LLIL_FLAG_GROUP: + return dest->FlagGroup(GetSemanticFlagGroup<LLIL_FLAG_GROUP>(), *this); case LLIL_TRAP: return dest->Trap(GetVector<LLIL_TRAP>(), *this); case LLIL_CALL_SSA: @@ -1964,6 +1985,24 @@ SSAFlag LowLevelILInstruction::GetDestSSAFlag() const } +uint32_t LowLevelILInstruction::GetSemanticFlagClass() const +{ + size_t operandIndex; + if (GetOperandIndexForUsage(SemanticFlagClassLowLevelOperandUsage, operandIndex)) + return GetRawOperandAsRegister(operandIndex); + throw LowLevelILInstructionAccessException(); +} + + +uint32_t LowLevelILInstruction::GetSemanticFlagGroup() const +{ + size_t operandIndex; + if (GetOperandIndexForUsage(SemanticFlagGroupLowLevelOperandUsage, operandIndex)) + return GetRawOperandAsRegister(operandIndex); + throw LowLevelILInstructionAccessException(); +} + + uint32_t LowLevelILInstruction::GetPartialRegister() const { size_t operandIndex; @@ -2748,9 +2787,15 @@ ExprId LowLevelILFunction::NoReturn(const ILSourceLocation& loc) } -ExprId LowLevelILFunction::FlagCondition(BNLowLevelILFlagCondition cond, const ILSourceLocation& loc) +ExprId LowLevelILFunction::FlagCondition(BNLowLevelILFlagCondition cond, uint32_t semClass, const ILSourceLocation& loc) { - return AddExprWithLocation(LLIL_FLAG_COND, loc, 0, 0, (ExprId)cond); + return AddExprWithLocation(LLIL_FLAG_COND, loc, 0, 0, (ExprId)cond, semClass); +} + + +ExprId LowLevelILFunction::FlagGroup(uint32_t semGroup, const ILSourceLocation& loc) +{ + return AddExprWithLocation(LLIL_FLAG_GROUP, loc, 0, 0, semGroup); } @@ -2988,6 +3033,12 @@ ExprId LowLevelILFunction::FloatCompareGreaterThan(size_t size, ExprId a, ExprId } +ExprId LowLevelILFunction::FloatCompareOrdered(size_t size, ExprId a, ExprId b, const ILSourceLocation& loc) +{ + return AddExprWithLocation(LLIL_FCMP_O, loc, size, 0, a, b); +} + + ExprId LowLevelILFunction::FloatCompareUnordered(size_t size, ExprId a, ExprId b, const ILSourceLocation& loc) { return AddExprWithLocation(LLIL_FCMP_UO, loc, size, 0, a, b); diff --git a/lowlevelilinstruction.h b/lowlevelilinstruction.h index a0a867af..bb5041a6 100644 --- a/lowlevelilinstruction.h +++ b/lowlevelilinstruction.h @@ -108,6 +108,8 @@ namespace BinaryNinja RegisterStackLowLevelOperand, FlagLowLevelOperand, FlagConditionLowLevelOperand, + SemanticFlagClassLowLevelOperand, + SemanticFlagGroupLowLevelOperand, SSARegisterLowLevelOperand, SSARegisterStackLowLevelOperand, SSAFlagLowLevelOperand, @@ -135,6 +137,8 @@ namespace BinaryNinja DestSSARegisterLowLevelOperandUsage, DestSSARegisterStackLowLevelOperandUsage, DestSSAFlagLowLevelOperandUsage, + SemanticFlagClassLowLevelOperandUsage, + SemanticFlagGroupLowLevelOperandUsage, PartialRegisterLowLevelOperandUsage, PartialSSARegisterStackSourceLowLevelOperandUsage, StackSSARegisterLowLevelOperandUsage, @@ -587,6 +591,8 @@ namespace BinaryNinja template <BNLowLevelILOperation N> SSARegister GetDestSSARegister() const { return As<N>().GetDestSSARegister(); } template <BNLowLevelILOperation N> SSARegisterStack GetDestSSARegisterStack() const { return As<N>().GetDestSSARegisterStack(); } template <BNLowLevelILOperation N> SSAFlag GetDestSSAFlag() const { return As<N>().GetDestSSAFlag(); } + template <BNLowLevelILOperation N> uint32_t GetSemanticFlagClass() const { return As<N>().GetSemanticFlagClass(); } + template <BNLowLevelILOperation N> uint32_t GetSemanticFlagGroup() const { return As<N>().GetSemanticFlagGroup(); } template <BNLowLevelILOperation N> uint32_t GetPartialRegister() const { return As<N>().GetPartialRegister(); } template <BNLowLevelILOperation N> SSARegister GetStackSSARegister() const { return As<N>().GetStackSSARegister(); } template <BNLowLevelILOperation N> SSARegister GetTopSSARegister() const { return As<N>().GetTopSSARegister(); } @@ -645,6 +651,8 @@ namespace BinaryNinja SSARegister GetDestSSARegister() const; SSARegisterStack GetDestSSARegisterStack() const; SSAFlag GetDestSSAFlag() const; + uint32_t GetSemanticFlagClass() const; + uint32_t GetSemanticFlagGroup() const; uint32_t GetPartialRegister() const; SSARegister GetStackSSARegister() const; SSARegister GetTopSSARegister() const; @@ -696,6 +704,8 @@ namespace BinaryNinja uint32_t GetRegister() const; uint32_t GetRegisterStack() const; uint32_t GetFlag() const; + uint32_t GetSemanticFlagClass() const; + uint32_t GetSemanticFlagGroup() const; BNLowLevelILFlagCondition GetFlagCondition() const; SSARegister GetSSARegister() const; SSARegisterStack GetSSARegisterStack() const; @@ -974,6 +984,11 @@ namespace BinaryNinja template <> struct LowLevelILInstructionAccessor<LLIL_FLAG_COND>: public LowLevelILInstructionBase { BNLowLevelILFlagCondition GetFlagCondition() const { return GetRawOperandAsFlagCondition(0); } + uint32_t GetSemanticFlagClass() const { return GetRawOperandAsRegister(1); } + }; + template <> struct LowLevelILInstructionAccessor<LLIL_FLAG_GROUP>: public LowLevelILInstructionBase + { + uint32_t GetSemanticFlagGroup() const { return GetRawOperandAsRegister(0); } }; template <> struct LowLevelILInstructionAccessor<LLIL_TRAP>: public LowLevelILInstructionBase @@ -1083,6 +1098,7 @@ namespace BinaryNinja template <> struct LowLevelILInstructionAccessor<LLIL_FCMP_LE>: public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor<LLIL_FCMP_GE>: public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor<LLIL_FCMP_GT>: public LowLevelILTwoOperandInstruction {}; + template <> struct LowLevelILInstructionAccessor<LLIL_FCMP_O>: public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor<LLIL_FCMP_UO>: public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor<LLIL_ADC>: public LowLevelILTwoOperandWithCarryInstruction {}; diff --git a/mediumlevelilinstruction.cpp b/mediumlevelilinstruction.cpp index c3b4014f..e911c298 100644 --- a/mediumlevelilinstruction.cpp +++ b/mediumlevelilinstruction.cpp @@ -1331,6 +1331,7 @@ void MediumLevelILInstruction::VisitExprs(const std::function<bool(const MediumL case MLIL_FCMP_LE: case MLIL_FCMP_GE: case MLIL_FCMP_GT: + case MLIL_FCMP_O: case MLIL_FCMP_UO: AsTwoOperand().GetLeftExpr().VisitExprs(func); AsTwoOperand().GetRightExpr().VisitExprs(func); @@ -1561,6 +1562,7 @@ ExprId MediumLevelILInstruction::CopyTo(MediumLevelILFunction* dest, case MLIL_FCMP_LE: case MLIL_FCMP_GE: case MLIL_FCMP_GT: + case MLIL_FCMP_O: case MLIL_FCMP_UO: return dest->AddExprWithLocation(operation, *this, size, subExprHandler(AsTwoOperand().GetLeftExpr()), subExprHandler(AsTwoOperand().GetRightExpr())); @@ -2706,6 +2708,12 @@ ExprId MediumLevelILFunction::FloatCompareGreaterThan(size_t size, ExprId a, Exp } +ExprId MediumLevelILFunction::FloatCompareOrdered(size_t size, ExprId a, ExprId b, const ILSourceLocation& loc) +{ + return AddExprWithLocation(MLIL_FCMP_O, loc, size, a, b); +} + + ExprId MediumLevelILFunction::FloatCompareUnordered(size_t size, ExprId a, ExprId b, const ILSourceLocation& loc) { return AddExprWithLocation(MLIL_FCMP_UO, loc, size, a, b); diff --git a/python/architecture.py b/python/architecture.py index 08049d46..d2ab586e 100644 --- a/python/architecture.py +++ b/python/architecture.py @@ -33,7 +33,6 @@ import callingconvention import platform import log import databuffer -import types class _ArchitectureMetaClass(type): @@ -120,9 +119,14 @@ class Architecture(object): global_regs = [] flags = [] flag_write_types = [] + semantic_flag_classes = [] + semantic_flag_groups = [] flag_roles = {} flags_required_for_flag_condition = {} + flags_required_for_semantic_flag_group = {} + flag_conditions_for_semantic_flag_group = {} flags_written_by_flag_write_type = {} + semantic_class_for_flag_write_type = {} reg_stacks = {} __metaclass__ = _ArchitectureMetaClass next_address = 0 @@ -166,16 +170,40 @@ class Architecture(object): core.BNFreeRegisterList(flags) count = ctypes.c_ulonglong() - types = core.BNGetAllArchitectureFlagWriteTypes(self.handle, count) + write_types = core.BNGetAllArchitectureFlagWriteTypes(self.handle, count) self._flag_write_types = {} self._flag_write_types_by_index = {} self.__dict__["flag_write_types"] = [] for i in xrange(0, count.value): - name = core.BNGetArchitectureFlagWriteTypeName(self.handle, types[i]) - self._flag_write_types[name] = types[i] - self._flag_write_types_by_index[types[i]] = name + name = core.BNGetArchitectureFlagWriteTypeName(self.handle, write_types[i]) + self._flag_write_types[name] = write_types[i] + self._flag_write_types_by_index[write_types[i]] = name self.flag_write_types.append(name) - core.BNFreeRegisterList(types) + core.BNFreeRegisterList(write_types) + + count = ctypes.c_ulonglong() + sem_classes = core.BNGetAllArchitectureSemanticFlagClasses(self.handle, count) + self._semantic_flag_classes = {} + self._semantic_flag_classes_by_index = {} + self.__dict__["semantic_flag_classes"] = [] + for i in xrange(0, count.value): + name = core.BNGetArchitectureSemanticFlagClassName(self.handle, sem_classes[i]) + self._semantic_flag_classes[name] = sem_classes[i] + self._semantic_flag_classes_by_index[sem_classes[i]] = name + self.semantic_flag_classes.append(name) + core.BNFreeRegisterList(sem_classes) + + count = ctypes.c_ulonglong() + sem_groups = core.BNGetAllArchitectureSemanticFlagGroups(self.handle, count) + self._semantic_flag_groups = {} + self._semantic_flag_groups_by_index = {} + self.__dict__["semantic_flag_groups"] = [] + for i in xrange(0, count.value): + name = core.BNGetArchitectureSemanticFlagGroupName(self.handle, sem_groups[i]) + self._semantic_flag_groups[name] = sem_groups[i] + self._semantic_flag_groups_by_index[sem_groups[i]] = name + self.semantic_flag_groups.append(name) + core.BNFreeRegisterList(sem_groups) self._flag_roles = {} self.__dict__["flag_roles"] = {} @@ -184,19 +212,48 @@ class Architecture(object): self.__dict__["flag_roles"][flag] = role self._flag_roles[self._flags[flag]] = role - self._flags_required_for_flag_condition = {} self.__dict__["flags_required_for_flag_condition"] = {} for cond in LowLevelILFlagCondition: count = ctypes.c_ulonglong() - flags = core.BNGetArchitectureFlagsRequiredForFlagCondition(self.handle, cond, count) + flags = core.BNGetArchitectureFlagsRequiredForFlagCondition(self.handle, cond, 0, count) + flag_names = [] + for i in xrange(0, count.value): + flag_names.append(self._flags_by_index[flags[i]]) + core.BNFreeRegisterList(flags) + self.__dict__["flags_required_for_flag_condition"][cond] = flag_names + + self._flags_required_by_semantic_flag_group = {} + self.__dict__["flags_required_for_semantic_flag_group"] = {} + for group in self.semantic_flag_groups: + count = ctypes.c_ulonglong() + flags = core.BNGetArchitectureFlagsRequiredForSemanticFlagGroup(self.handle, + self._semantic_flag_groups[group], count) flag_indexes = [] flag_names = [] for i in xrange(0, count.value): flag_indexes.append(flags[i]) flag_names.append(self._flags_by_index[flags[i]]) core.BNFreeRegisterList(flags) - self._flags_required_for_flag_condition[cond] = flag_indexes - self.__dict__["flags_required_for_flag_condition"][cond] = flag_names + self._flags_required_by_semantic_flag_group[self._semantic_flag_groups[group]] = flag_indexes + self.__dict__["flags_required_for_semantic_flag_group"][cond] = flag_names + + self._flag_conditions_for_semantic_flag_group = {} + self.__dict__["flag_conditions_for_semantic_flag_group"] = {} + for group in self.semantic_flag_groups: + count = ctypes.c_ulonglong() + conditions = core.BNGetArchitectureFlagConditionsForSemanticFlagGroup(self.handle, + self._semantic_flag_groups[group], count) + class_index_cond = {} + class_cond = {} + for i in xrange(0, count.value): + class_index_cond[conditions[i].semanticClass] = conditions[i].condition + if conditions[i].semanticClass == 0: + class_cond[None] = conditions[i].condition + elif conditions[i].semanticClass in self._semantic_flag_classes_by_index: + class_cond[self._semantic_flag_classes_by_index[conditions[i].semanticClass]] = conditions[i].condition + core.BNFreeFlagConditionsForSemanticFlagGroup(conditions) + self._flag_conditions_for_semantic_flag_group[self._semantic_flag_groups[group]] = class_index_cond + self.__dict__["flag_conditions_for_semantic_flag_group"][group] = class_cond self._flags_written_by_flag_write_type = {} self.__dict__["flags_written_by_flag_write_type"] = {} @@ -213,6 +270,18 @@ class Architecture(object): self._flags_written_by_flag_write_type[self._flag_write_types[write_type]] = flag_indexes self.__dict__["flags_written_by_flag_write_type"][write_type] = flag_names + self._semantic_class_for_flag_write_type = {} + self.__dict__["semantic_class_for_flag_write_type"] = {} + for write_type in self.flag_write_types: + sem_class = core.BNGetArchitectureSemanticClassForFlagWriteType(self.handle, + self._flag_write_types[write_type]) + if sem_class == 0: + sem_class_name = None + else: + sem_class_name = self._semantic_flag_classes_by_index[sem_class] + self._semantic_class_for_flag_write_type[self._flag_write_types[write_type]] = sem_class + self.__dict__["semantic_class_for_flag_write_type"][write_type] = sem_class_name + count = ctypes.c_ulonglong() regs = core.BNGetArchitectureGlobalRegisters(self.handle, count) self.__dict__["global_regs"] = [] @@ -260,19 +329,33 @@ class Architecture(object): self._cb.getRegisterName = self._cb.getRegisterName.__class__(self._get_register_name) self._cb.getFlagName = self._cb.getFlagName.__class__(self._get_flag_name) self._cb.getFlagWriteTypeName = self._cb.getFlagWriteTypeName.__class__(self._get_flag_write_type_name) + self._cb.getFlagSemanticClassName = self._cb.getFlagSemanticClassName.__class__(self._get_semantic_flag_class_name) + self._cb.getFlagSemanticGroupName = self._cb.getFlagSemanticGroupName.__class__(self._get_semantic_flag_group_name) self._cb.getFullWidthRegisters = self._cb.getFullWidthRegisters.__class__(self._get_full_width_registers) self._cb.getAllRegisters = self._cb.getAllRegisters.__class__(self._get_all_registers) self._cb.getAllFlags = self._cb.getAllRegisters.__class__(self._get_all_flags) self._cb.getAllFlagWriteTypes = self._cb.getAllRegisters.__class__(self._get_all_flag_write_types) + self._cb.getAllFlagSemanticClasses = self._cb.getAllFlagSemanticClasses.__class__(self._get_all_semantic_flag_classes) + self._cb.getAllFlagSemanticGroups = self._cb.getAllFlagSemanticGroups.__class__(self._get_all_semantic_flag_groups) self._cb.getFlagRole = self._cb.getFlagRole.__class__(self._get_flag_role) self._cb.getFlagsRequiredForFlagCondition = self._cb.getFlagsRequiredForFlagCondition.__class__( self._get_flags_required_for_flag_condition) + self._cb.getFlagsRequiredForSemanticFlagGroup = self._cb.getFlagsRequiredForSemanticFlagGroup.__class__( + self._get_flags_required_for_semantic_flag_group) + self._cb.getFlagConditionsForSemanticFlagGroup = self._cb.getFlagConditionsForSemanticFlagGroup.__class__( + self._get_flag_conditions_for_semantic_flag_group) + self._cb.freeFlagConditionsForSemanticFlagGroup = self._cb.freeFlagConditionsForSemanticFlagGroup.__class__( + self._free_flag_conditions_for_semantic_flag_group) self._cb.getFlagsWrittenByFlagWriteType = self._cb.getFlagsWrittenByFlagWriteType.__class__( self._get_flags_written_by_flag_write_type) + self._cb.getSemanticClassForFlagWriteType = self._cb.getSemanticClassForFlagWriteType.__class__( + self._get_semantic_class_for_flag_write_type) self._cb.getFlagWriteLowLevelIL = self._cb.getFlagWriteLowLevelIL.__class__( self._get_flag_write_low_level_il) self._cb.getFlagConditionLowLevelIL = self._cb.getFlagConditionLowLevelIL.__class__( self._get_flag_condition_low_level_il) + self._cb.getSemanticFlagGroupLowLevelIL = self._cb.getSemanticFlagGroupLowLevelIL.__class__( + self._get_semantic_flag_group_low_level_il) self._cb.freeRegisterList = self._cb.freeRegisterList.__class__(self._free_register_list) self._cb.getRegisterInfo = self._cb.getRegisterInfo.__class__(self._get_register_info) self._cb.getStackPointerRegister = self._cb.getStackPointerRegister.__class__( @@ -362,6 +445,26 @@ class Architecture(object): self._flag_write_types_by_index[write_type_index] = write_type write_type_index += 1 + self._semantic_flag_classes = {} + self._semantic_flag_classes_by_index = {} + self.__dict__["semantic_flag_classes"] = self.__class__.semantic_flag_classes + semantic_class_index = 1 + for sem_class in self.__class__.semantic_flag_classes: + if sem_class not in self._semantic_flag_classes: + self._semantic_flag_classes[sem_class] = semantic_class_index + self._semantic_flag_classes_by_index[semantic_class_index] = sem_class + semantic_class_index += 1 + + self._semantic_flag_groups = {} + self._semantic_flag_groups_by_index = {} + self.__dict__["semantic_flag_groups"] = self.__class__.semantic_flag_groups + semantic_group_index = 0 + for sem_group in self.__class__.semantic_flag_groups: + if sem_group not in self._semantic_flag_groups: + self._semantic_flag_groups[sem_group] = semantic_group_index + self._semantic_flag_groups_by_index[semantic_group_index] = sem_group + semantic_group_index += 1 + self._flag_roles = {} self.__dict__["flag_roles"] = self.__class__.flag_roles for flag in self.__class__.flag_roles: @@ -370,13 +473,26 @@ class Architecture(object): role = FlagRole[role] self._flag_roles[self._flags[flag]] = role - self._flags_required_for_flag_condition = {} self.__dict__["flags_required_for_flag_condition"] = self.__class__.flags_required_for_flag_condition - for cond in self.__class__.flags_required_for_flag_condition: + + self._flags_required_by_semantic_flag_group = {} + self.__dict__["flags_required_for_semantic_flag_group"] = self.__class__.flags_required_for_semantic_flag_group + for group in self.__class__.flags_required_for_semantic_flag_group: flags = [] - for flag in self.__class__.flags_required_for_flag_condition[cond]: + for flag in self.__class__.flags_required_for_semantic_flag_group[group]: flags.append(self._flags[flag]) - self._flags_required_for_flag_condition[cond] = flags + self._flags_required_by_semantic_flag_group[self._semantic_flag_groups[group]] = flags + + self._flag_conditions_for_semantic_flag_group = {} + self.__dict__["flag_conditions_for_semantic_flag_group"] = self.__class__.flag_conditions_for_semantic_flag_group + for group in self.__class__.flag_conditions_for_semantic_flag_group: + class_cond = {} + for sem_class in self.__class__.flag_conditions_for_semantic_flag_group[group]: + if sem_class is None: + class_cond[0] = self.__class__.flag_conditions_for_semantic_flag_group[group][sem_class] + else: + class_cond[self._semantic_flag_classes[sem_class]] = self.__class__.flag_conditions_for_semantic_flag_group[group][sem_class] + self._flag_conditions_for_semantic_flag_group[self._semantic_flag_groups[group]] = class_cond self._flags_written_by_flag_write_type = {} self.__dict__["flags_written_by_flag_write_type"] = self.__class__.flags_written_by_flag_write_type @@ -386,10 +502,21 @@ class Architecture(object): flags.append(self._flags[flag]) self._flags_written_by_flag_write_type[self._flag_write_types[write_type]] = flags + self._semantic_class_for_flag_write_type = {} + self.__dict__["semantic_class_for_flag_write_type"] = self.__class__.semantic_class_for_flag_write_type + for write_type in self.__class__.semantic_class_for_flag_write_type: + sem_class = self.__class__.semantic_class_for_flag_write_type[write_type] + if sem_class in self._semantic_flag_classes: + sem_class_index = self._semantic_flag_classes[sem_class] + else: + sem_class_index = 0 + self._semantic_class_for_flag_write_type[self._flag_write_types[write_type]] = sem_class_index + self.__dict__["global_regs"] = self.__class__.global_regs self._pending_reg_lists = {} self._pending_token_lists = {} + self._pending_condition_lists = {} def __eq__(self, value): if not isinstance(value, Architecture): @@ -605,6 +732,24 @@ class Architecture(object): log.log_error(traceback.format_exc()) return core.BNAllocString("") + def _get_semantic_flag_class_name(self, ctxt, sem_class): + try: + if sem_class in self._semantic_flag_class_by_index: + return core.BNAllocString(self._semantic_flag_class_by_index[sem_class]) + return core.BNAllocString("") + except (KeyError, OSError): + log.log_error(traceback.format_exc()) + return core.BNAllocString("") + + def _get_semantic_flag_group_name(self, ctxt, sem_group): + try: + if sem_group in self._semantic_flag_group_by_index: + return core.BNAllocString(self._semantic_flag_group_by_index[sem_group]) + return core.BNAllocString("") + except (KeyError, OSError): + log.log_error(traceback.format_exc()) + return core.BNAllocString("") + def _get_full_width_registers(self, ctxt, count): try: regs = self._full_width_regs.values() @@ -652,11 +797,11 @@ class Architecture(object): def _get_all_flag_write_types(self, ctxt, count): try: - types = self._flag_write_types_by_index.keys() - count[0] = len(types) - type_buf = (ctypes.c_uint * len(types))() - for i in xrange(0, len(types)): - type_buf[i] = types[i] + write_types = self._flag_write_types_by_index.keys() + count[0] = len(write_types) + type_buf = (ctypes.c_uint * len(write_types))() + for i in xrange(0, len(write_types)): + type_buf[i] = write_types[i] result = ctypes.cast(type_buf, ctypes.c_void_p) self._pending_reg_lists[result.value] = (result, type_buf) return result.value @@ -665,6 +810,36 @@ class Architecture(object): count[0] = 0 return None + def _get_all_semantic_flag_classes(self, ctxt, count): + try: + sem_classes = self._semantic_flag_classes_by_index.keys() + count[0] = len(sem_classes) + class_buf = (ctypes.c_uint * len(sem_classes))() + for i in xrange(0, len(sem_classes)): + class_buf[i] = sem_classes[i] + result = ctypes.cast(class_buf, ctypes.c_void_p) + self._pending_reg_lists[result.value] = (result, class_buf) + return result.value + except KeyError: + log.log_error(traceback.format_exc()) + count[0] = 0 + return None + + def _get_all_semantic_flag_groups(self, ctxt, count): + try: + sem_groups = self._semantic_flag_groups_by_index.keys() + count[0] = len(sem_groups) + group_buf = (ctypes.c_uint * len(sem_groups))() + for i in xrange(0, len(sem_groups)): + group_buf[i] = sem_groups[i] + result = ctypes.cast(group_buf, ctypes.c_void_p) + self._pending_reg_lists[result.value] = (result, group_buf) + return result.value + except KeyError: + log.log_error(traceback.format_exc()) + count[0] = 0 + return None + def _get_flag_role(self, ctxt, flag): try: if flag in self._flag_roles: @@ -674,12 +849,16 @@ class Architecture(object): log.log_error(traceback.format_exc()) return None - def _get_flags_required_for_flag_condition(self, ctxt, cond, count): + def _get_flags_required_for_flag_condition(self, ctxt, cond, sem_class, count): try: - if cond in self._flags_required_for_flag_condition: - flags = self._flags_required_for_flag_condition[cond] + if sem_class in self._semantic_flag_classes_by_index: + sem_class = self._semantic_flag_classes_by_index[sem_class] else: - flags = [] + sem_class = 0 + flag_names = self.perform_get_flags_required_for_flag_condition(cond, sem_class) + flags = [] + for name in flag_names: + flags.append(self._flags[name]) count[0] = len(flags) flag_buf = (ctypes.c_uint * len(flags))() for i in xrange(0, len(flags)): @@ -692,6 +871,59 @@ class Architecture(object): count[0] = 0 return None + def perform_get_flags_required_for_flag_condition(self, cond, sem_class): + if cond in self.flags_required_for_flag_condition: + return self.flags_required_for_flag_condition[cond] + return [] + + def _get_flags_required_for_semantic_flag_group(self, ctxt, sem_group, count): + try: + if sem_group in self._flags_required_by_semantic_flag_group: + flags = self._flags_required_by_semantic_flag_group[sem_group] + else: + flags = [] + count[0] = len(flags) + flag_buf = (ctypes.c_uint * len(flags))() + for i in xrange(0, len(flags)): + flag_buf[i] = flags[i] + result = ctypes.cast(flag_buf, ctypes.c_void_p) + self._pending_reg_lists[result.value] = (result, flag_buf) + return result.value + except (KeyError, OSError): + log.log_error(traceback.format_exc()) + count[0] = 0 + return None + + def _get_flag_conditions_for_semantic_flag_group(self, ctxt, sem_group, count): + try: + if sem_group in self._flag_conditions_by_semantic_flag_group: + class_cond = self._flag_conditions_by_semantic_flag_group[sem_group] + else: + class_cond = {} + count[0] = len(class_cond) + cond_buf = (core.BNFlagConditionForSemanticClass * len(class_cond))() + i = 0 + for class_index in class_cond.keys(): + cond_buf[i].semanticClass = class_index + cond_buf[i].condition = class_cond[class_index] + i += 1 + result = ctypes.cast(cond_buf, ctypes.c_void_p) + self._pending_conditions[result.value] = (result, cond_buf) + return result.value + except (KeyError, OSError): + log.log_error(traceback.format_exc()) + count[0] = 0 + return None + + def _free_flag_conditions_for_semantic_flag_group(self, ctxt, conditions): + try: + buf = ctypes.cast(conditions, ctypes.c_void_p) + if buf.value not in self._pending_conditions: + raise ValueError("freeing condition list that wasn't allocated") + del self._pending_conditions[buf.value] + except (ValueError, KeyError): + log.log_error(traceback.format_exc()) + def _get_flags_written_by_flag_write_type(self, ctxt, write_type, count): try: if write_type in self._flags_written_by_flag_write_type: @@ -710,6 +942,16 @@ class Architecture(object): count[0] = 0 return None + def _get_semantic_class_for_flag_write_type(self, ctxt, write_type): + try: + if write_type in self._semantic_class_for_flag_write_type: + return self._semantic_class_for_flag_write_type[write_type] + else: + return 0 + except (KeyError, OSError): + log.log_error(traceback.format_exc()) + return 0 + def _get_flag_write_low_level_il(self, ctxt, op, size, write_type, flag, operands, operand_count, il): try: write_type_name = None @@ -730,9 +972,25 @@ class Architecture(object): log.log_error(traceback.format_exc()) return False - def _get_flag_condition_low_level_il(self, ctxt, cond, il): + def _get_flag_condition_low_level_il(self, ctxt, cond, sem_class, il): + try: + if sem_class in self._semantic_flag_classes_by_index: + sem_class_name = self._semantic_flag_classes_by_index[sem_class] + else: + sem_class_name = None + return self.perform_get_flag_condition_low_level_il(cond, sem_class_name, + lowlevelil.LowLevelILFunction(self, core.BNNewLowLevelILFunctionReference(il))).index + except OSError: + log.log_error(traceback.format_exc()) + return 0 + + def _get_semantic_flag_group_low_level_il(self, ctxt, sem_group, il): try: - return self.perform_get_flag_condition_low_level_il(cond, + if sem_group in self._semantic_flag_groups_by_index: + sem_group_name = self._semantic_flag_groups_by_index[sem_group] + else: + sem_group_name = None + return self.perform_get_semantic_flag_group_low_level_il(sem_group_name, lowlevelil.LowLevelILFunction(self, core.BNNewLowLevelILFunctionReference(il))).index except OSError: log.log_error(traceback.format_exc()) @@ -1054,18 +1312,31 @@ class Architecture(object): return self.get_default_flag_write_low_level_il(op, size, self._flag_roles[flag], operands, il) @abc.abstractmethod - def perform_get_flag_condition_low_level_il(self, cond, il): + def perform_get_flag_condition_low_level_il(self, cond, sem_class, il): """ .. note:: Architecture subclasses should implement this method. .. warning:: This method should never be called directly. - :param LowLevelILFlagCondition cond: - :param LowLevelILFunction il: + :param LowLevelILFlagCondition cond: Flag condition to be computed + :param str sem_class: Semantic class to be used (None for default semantics) + :param LowLevelILFunction il: LowLevelILFunction object to append LowLevelILExpr objects to :rtype: LowLevelILExpr """ return self.get_default_flag_condition_low_level_il(cond, il) @abc.abstractmethod + def perform_get_semantic_flag_group_low_level_il(self, sem_group, il): + """ + .. note:: Architecture subclasses should implement this method. + .. warning:: This method should never be called directly. + + :param str sem_group: Semantic group to be computed + :param LowLevelILFunction il: LowLevelILFunction object to append LowLevelILExpr objects to + :rtype: LowLevelILExpr + """ + return il.unimplemented() + + @abc.abstractmethod def perform_assemble(self, code, addr): """ ``perform_assemble`` implements a method to convert the string of assembly instructions ``code`` loaded at @@ -1407,6 +1678,22 @@ class Architecture(object): return flag.index return flag + def get_semantic_flag_class_index(self, sem_class): + if sem_class is None: + return 0 + elif isinstance(sem_class, str): + return self._semantic_flag_classes[sem_class] + elif isinstance(sem_class, lowlevelil.ILSemanticFlagClass): + return sem_class.index + return sem_class + + def get_semantic_flag_group_index(self, sem_group): + if isinstance(sem_group, str): + return self._semantic_flag_groups[sem_group] + elif isinstance(sem_group, lowlevelil.ILSemanticFlagGroup): + return sem_group.index + return sem_group + def get_flag_write_type_name(self, write_type): """ ``get_flag_write_type_name`` gets the flag write type name for the given flag. @@ -1437,6 +1724,26 @@ class Architecture(object): """ return self._flag_write_types[write_type] + def get_semantic_flag_class_by_name(self, sem_class): + """ + ``get_semantic_flag_class_by_name`` gets the semantic flag class index by name. + + :param int sem_class: semantic flag class + :return: semantic flag class index + :rtype: str + """ + return self._semantic_flag_classes[sem_class] + + def get_semantic_flag_group_by_name(self, sem_group): + """ + ``get_semantic_flag_group_by_name`` gets the semantic flag group index by name. + + :param int sem_group: semantic flag group + :return: semantic flag group index + :rtype: str + """ + return self._semantic_flag_groups[sem_group] + def get_flag_write_low_level_il(self, op, size, write_type, flag, operands, il): """ :param LowLevelILOperation op: @@ -1502,6 +1809,25 @@ class Architecture(object): """ return lowlevelil.LowLevelILExpr(core.BNGetDefaultArchitectureFlagConditionLowLevelIL(self.handle, cond, il.handle)) + def get_semantic_flag_group_low_level_il(self, sem_group, il): + """ + :param str sem_group: + :param LowLevelILFunction il: + :rtype: LowLevelILExpr + """ + group_index = self.get_semantic_flag_group_index(sem_group) + return lowlevelil.LowLevelILExpr(core.BNGetArchitectureSemanticFlagGroupLowLevelIL(self.handle, group_index, il.handle)) + + def get_flags_required_for_flag_condition(self, cond, sem_class = None): + sem_class = self.get_semantic_flag_class_index(sem_class) + count = ctypes.c_ulonglong() + flags = core.BNGetArchitectureFlagsRequiredForFlagCondition(self.handle, cond, sem_class, count) + flag_names = [] + for i in xrange(0, count.value): + flag_names.append(self._flags_by_index[flags[i]]) + core.BNFreeRegisterList(flags) + return flag_names + def get_modified_regs_on_write(self, reg): """ ``get_modified_regs_on_write`` returns a list of register names that are modified when ``reg`` is written. diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 42c34ee0..a2d77c9f 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -99,6 +99,38 @@ class ILFlag(object): return self.name +class ILSemanticFlagClass(object): + def __init__(self, arch, sem_class): + self.arch = arch + self.index = sem_class + self.name = self.arch.get_semantic_flag_class_name(self.index) + + def __str__(self): + return self.name + + def __repr__(self): + return self.name + + def __eq__(self, other): + return self.index == other.index + + +class ILSemanticFlagGroup(object): + def __init__(self, arch, sem_group): + self.arch = arch + self.index = sem_group + self.name = self.arch.get_semantic_flag_group_name(self.index) + + def __str__(self): + return self.name + + def __repr__(self): + return self.name + + def __eq__(self, other): + return self.index == other.index + + class SSARegister(object): def __init__(self, reg, version): self.reg = reg @@ -202,7 +234,8 @@ class LowLevelILInstruction(object): LowLevelILOperation.LLIL_NORET: [], LowLevelILOperation.LLIL_IF: [("condition", "expr"), ("true", "int"), ("false", "int")], LowLevelILOperation.LLIL_GOTO: [("dest", "int")], - LowLevelILOperation.LLIL_FLAG_COND: [("condition", "cond")], + LowLevelILOperation.LLIL_FLAG_COND: [("condition", "cond", "semantic_class", "sem_class")], + LowLevelILOperation.LLIL_FLAG_GROUP: [("semantic_group", "sem_group")], LowLevelILOperation.LLIL_CMP_E: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_CMP_NE: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_CMP_SLT: [("left", "expr"), ("right", "expr")], @@ -238,6 +271,7 @@ class LowLevelILInstruction(object): LowLevelILOperation.LLIL_FCMP_LE: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_FCMP_GE: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_FCMP_GT: [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FCMP_O: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_FCMP_UO: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_SET_REG_SSA: [("dest", "reg_ssa"), ("src", "expr")], LowLevelILOperation.LLIL_SET_REG_SSA_PARTIAL: [("full_reg", "reg_ssa"), ("dest", "reg"), ("src", "expr")], @@ -324,6 +358,10 @@ class LowLevelILInstruction(object): flag = ILFlag(func.arch, instr.operands[i]) i += 1 value = SSAFlag(flag, instr.operands[i]) + elif operand_type == "sem_class": + value = ILSemanticFlagClass(func.arch, instr.operands[i]) + elif operand_type == "sem_group": + value = ILSemanticFlagGroup(func.arch, instr.operands[i]) elif operand_type == "cond": value = LowLevelILFlagCondition(instr.operands[i]) elif operand_type == "int_list": @@ -1507,11 +1545,12 @@ class LowLevelILFunction(object): """ return self.expr(LowLevelILOperation.LLIL_NORET) - def flag_condition(self, cond): + def flag_condition(self, cond, sem_class = None): """ ``flag_condition`` returns a flag_condition expression for the given LowLevelILFlagCondition :param LowLevelILFlagCondition cond: Flag condition expression to retrieve + :param str sem_class: Optional semantic flag class :return: A flag_condition expression :rtype: LowLevelILExpr """ @@ -1519,7 +1558,19 @@ class LowLevelILFunction(object): cond = LowLevelILFlagCondition[cond] elif isinstance(cond, LowLevelILFlagCondition): cond = cond.value - return self.expr(LowLevelILOperation.LLIL_FLAG_COND, cond) + class_index = self.arch.get_semantic_flag_class_index(sem_class) + return self.expr(LowLevelILOperation.LLIL_FLAG_COND, cond, class_index) + + def flag_group(self, sem_group): + """ + ``flag_group`` returns a flag_group expression for the given semantic flag group + + :param str sem_group: Semantic flag group to access + :return: A flag_group expression + :rtype: LowLevelILExpr + """ + group = self.arch.get_semantic_flag_group_index(sem_group) + return self.expr(LowLevelILOperation.LLIL_FLAG_GROUP, group) def compare_equal(self, size, a, b): """ @@ -2174,6 +2225,7 @@ class LowLevelILBasicBlock(basicblock.BasicBlock): def __hash__(self): return hash((self.start, self.end, self.il_function)) + def LLIL_TEMP(n): return n | 0x80000000 diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 85feba0a..8594ea36 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -169,6 +169,7 @@ class MediumLevelILInstruction(object): MediumLevelILOperation.MLIL_FCMP_LE: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FCMP_GE: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FCMP_GT: [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_FCMP_O: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FCMP_UO: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_SET_VAR_SSA: [("dest", "var_ssa"), ("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_SSA_FIELD: [("prev", "var_ssa_dest_and_src"), ("offset", "int"), ("src", "expr")], |
