summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--architecture.cpp267
-rw-r--r--binaryninjaapi.h48
-rw-r--r--binaryninjacore.h50
-rw-r--r--lowlevelilinstruction.cpp59
-rw-r--r--lowlevelilinstruction.h16
-rw-r--r--mediumlevelilinstruction.cpp8
-rw-r--r--python/architecture.py382
-rw-r--r--python/lowlevelil.py58
-rw-r--r--python/mediumlevelil.py1
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")],