summaryrefslogtreecommitdiff
path: root/architecture.cpp
diff options
context:
space:
mode:
authorPeter LaFosse <peter@vector35.com>2018-04-04 14:11:55 -0400
committerPeter LaFosse <peter@vector35.com>2018-04-04 14:11:55 -0400
commitd990d5ebf56eb0f1a7d96e98577cb9ace9dac19d (patch)
tree752649d87db23f95a59384f5325b94b734e1c27b /architecture.cpp
parent1eb3683b3a1ee0d263267b1e84957fadea7fadaa (diff)
parentfa716fe2da53a4f136380b1f60197bd197b2793a (diff)
Merging with dev
Diffstat (limited to 'architecture.cpp')
-rw-r--r--architecture.cpp930
1 files changed, 906 insertions, 24 deletions
diff --git a/architecture.cpp b/architecture.cpp
index 78c41dd3..ea27d805 100644
--- a/architecture.cpp
+++ b/architecture.cpp
@@ -237,6 +237,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;
@@ -289,17 +305,44 @@ uint32_t* Architecture::GetAllFlagWriteTypesCallback(void* ctxt, size_t* count)
}
-BNFlagRole Architecture::GetFlagRoleCallback(void* ctxt, uint32_t flag)
+uint32_t* Architecture::GetAllSemanticFlagClassesCallback(void* ctxt, size_t* count)
{
Architecture* arch = (Architecture*)ctxt;
- return arch->GetFlagRole(flag);
+ 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::GetFlagsRequiredForFlagConditionCallback(void* ctxt, BNLowLevelILFlagCondition cond, size_t* count)
+uint32_t* Architecture::GetAllSemanticFlagGroupsCallback(void* ctxt, size_t* count)
{
Architecture* arch = (Architecture*)ctxt;
- vector<uint32_t> flags = arch->GetFlagsRequiredForFlagCondition(cond);
+ 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, uint32_t semClass)
+{
+ Architecture* arch = (Architecture*)ctxt;
+ return arch->GetFlagRole(flag, semClass);
+}
+
+
+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()];
@@ -309,6 +352,44 @@ uint32_t* Architecture::GetFlagsRequiredForFlagConditionCallback(void* ctxt, BNL
}
+uint32_t* Architecture::GetFlagsRequiredForSemanticFlagGroupCallback(void* ctxt, uint32_t semGroup, size_t* count)
+{
+ Architecture* arch = (Architecture*)ctxt;
+ vector<uint32_t> flags = arch->GetFlagsRequiredForSemanticFlagGroup(semGroup);
+ *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;
+}
+
+
+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;
@@ -322,6 +403,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)
{
@@ -331,12 +419,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);
}
@@ -380,6 +476,107 @@ uint32_t* Architecture::GetGlobalRegistersCallback(void* ctxt, size_t* count)
}
+char* Architecture::GetRegisterStackNameCallback(void* ctxt, uint32_t regStack)
+{
+ Architecture* arch = (Architecture*)ctxt;
+ string result = arch->GetRegisterStackName(regStack);
+ return BNAllocString(result.c_str());
+}
+
+
+uint32_t* Architecture::GetAllRegisterStacksCallback(void* ctxt, size_t* count)
+{
+ Architecture* arch = (Architecture*)ctxt;
+ vector<uint32_t> regs = arch->GetAllRegisterStacks();
+ *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;
+}
+
+
+void Architecture::GetRegisterStackInfoCallback(void* ctxt, uint32_t regStack, BNRegisterStackInfo* result)
+{
+ Architecture* arch = (Architecture*)ctxt;
+ *result = arch->GetRegisterStackInfo(regStack);
+}
+
+
+char* Architecture::GetIntrinsicNameCallback(void* ctxt, uint32_t intrinsic)
+{
+ Architecture* arch = (Architecture*)ctxt;
+ string result = arch->GetIntrinsicName(intrinsic);
+ return BNAllocString(result.c_str());
+}
+
+
+uint32_t* Architecture::GetAllIntrinsicsCallback(void* ctxt, size_t* count)
+{
+ Architecture* arch = (Architecture*)ctxt;
+ vector<uint32_t> regs = arch->GetAllIntrinsics();
+ *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;
+}
+
+
+BNNameAndType* Architecture::GetIntrinsicInputsCallback(void* ctxt, uint32_t intrinsic, size_t* count)
+{
+ Architecture* arch = (Architecture*)ctxt;
+ vector<NameAndType> inputs = arch->GetIntrinsicInputs(intrinsic);
+ *count = inputs.size();
+
+ BNNameAndType* result = new BNNameAndType[inputs.size()];
+ for (size_t i = 0; i < inputs.size(); i++)
+ {
+ result[i].name = BNAllocString(inputs[i].name.c_str());
+ result[i].type = BNNewTypeReference(inputs[i].type.GetValue()->GetObject());
+ result[i].typeConfidence = inputs[i].type.GetConfidence();
+ }
+ return result;
+}
+
+
+void Architecture::FreeNameAndTypeListCallback(void*, BNNameAndType* nt, size_t count)
+{
+ for (size_t i = 0; i < count; i++)
+ {
+ BNFreeString(nt[i].name);
+ BNFreeType(nt[i].type);
+ }
+ delete[] nt;
+}
+
+
+BNTypeWithConfidence* Architecture::GetIntrinsicOutputsCallback(void* ctxt, uint32_t intrinsic, size_t* count)
+{
+ Architecture* arch = (Architecture*)ctxt;
+ vector<Confidence<Ref<Type>>> outputs = arch->GetIntrinsicOutputs(intrinsic);
+ *count = outputs.size();
+
+ BNTypeWithConfidence* result = new BNTypeWithConfidence[outputs.size()];
+ for (size_t i = 0; i < outputs.size(); i++)
+ {
+ result[i].type = BNNewTypeReference(outputs[i].GetValue()->GetObject());
+ result[i].confidence = outputs[i].GetConfidence();
+ }
+ return result;
+}
+
+
+void Architecture::FreeTypeListCallback(void*, BNTypeWithConfidence* types, size_t count)
+{
+ for (size_t i = 0; i < count; i++)
+ BNFreeType(types[i].type);
+ delete[] types;
+}
+
+
bool Architecture::AssembleCallback(void* ctxt, const char* code, uint64_t addr, BNDataBuffer* result, char** errors)
{
Architecture* arch = (Architecture*)ctxt;
@@ -483,6 +680,13 @@ bool Architecture::ApplyELFRelocationCallback(void* ctxt, BNBinaryView* view, BN
// }
+void Architecture::Register(BNCustomArchitecture* callbacks)
+{
+ AddRefForRegistration();
+ BNRegisterArchitecture(m_nameForRegister.c_str(), callbacks);
+}
+
+
void Architecture::Register(Architecture* arch)
{
BNCustomArchitecture callbacks;
@@ -502,20 +706,38 @@ 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;
callbacks.getLinkRegister = GetLinkRegisterCallback;
callbacks.getGlobalRegisters = GetGlobalRegistersCallback;
+ callbacks.getRegisterStackName = GetRegisterStackNameCallback;
+ callbacks.getAllRegisterStacks = GetAllRegisterStacksCallback;
+ callbacks.getRegisterStackInfo = GetRegisterStackInfoCallback;
+ callbacks.getIntrinsicName = GetIntrinsicNameCallback;
+ callbacks.getAllIntrinsics = GetAllIntrinsicsCallback;
+ callbacks.getIntrinsicInputs = GetIntrinsicInputsCallback;
+ callbacks.freeNameAndTypeList = FreeNameAndTypeListCallback;
+ callbacks.getIntrinsicOutputs = GetIntrinsicOutputsCallback;
+ callbacks.freeTypeList = FreeTypeListCallback;
callbacks.assemble = AssembleCallback;
callbacks.isNeverBranchPatchAvailable = IsNeverBranchPatchAvailableCallback;
callbacks.isAlwaysBranchPatchAvailable = IsAlwaysBranchPatchAvailableCallback;
@@ -530,9 +752,7 @@ void Architecture::Register(Architecture* arch)
callbacks.applyELFRelocation = ApplyELFRelocationCallback;
// callbacks.applyMachoRelocation = ApplyMachoRelocationCallback;
callbacks.getRelocationInfo = GetRelocationInfoCallback;
-
- arch->AddRefForRegistration();
- BNRegisterArchitecture(arch->m_nameForRegister.c_str(), &callbacks);
+ arch->Register(&callbacks);
}
@@ -552,6 +772,7 @@ vector<Ref<Architecture>> Architecture::GetList()
archs = BNGetArchitectureList(&count);
vector<Ref<Architecture>> result;
+ result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new CoreArchitecture(archs[i]));
@@ -635,6 +856,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>();
@@ -659,29 +898,58 @@ vector<uint32_t> Architecture::GetAllFlagWriteTypes()
}
-BNFlagRole Architecture::GetFlagRole(uint32_t)
+vector<uint32_t> Architecture::GetAllSemanticFlagClasses()
+{
+ return vector<uint32_t>();
+}
+
+
+vector<uint32_t> Architecture::GetAllSemanticFlagGroups()
+{
+ return vector<uint32_t>();
+}
+
+
+BNFlagRole Architecture::GetFlagRole(uint32_t, 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)
{
- (void)flagWriteType;
- BNFlagRole role = GetFlagRole(flag);
+ BNFlagRole role = GetFlagRole(flag, GetSemanticClassForFlagWriteType(flagWriteType));
return BNGetDefaultArchitectureFlagWriteLowLevelIL(m_object, op, size, role, operands,
operandCount, il.GetObject());
}
@@ -695,15 +963,23 @@ size_t Architecture::GetDefaultFlagWriteLowLevelIL(BNLowLevelILOperation op, siz
}
-ExprId Architecture::GetFlagConditionLowLevelIL(BNLowLevelILFlagCondition cond, LowLevelILFunction& il)
+ExprId Architecture::GetFlagConditionLowLevelIL(BNLowLevelILFlagCondition cond,
+ uint32_t semClass, LowLevelILFunction& il)
+{
+ return BNGetDefaultArchitectureFlagConditionLowLevelIL(m_object, cond, semClass, il.GetObject());
+}
+
+
+ExprId Architecture::GetDefaultFlagConditionLowLevelIL(BNLowLevelILFlagCondition cond,
+ uint32_t semClass, LowLevelILFunction& il)
{
- return BNGetDefaultArchitectureFlagConditionLowLevelIL(m_object, cond, il.GetObject());
+ return BNGetDefaultArchitectureFlagConditionLowLevelIL(m_object, cond, semClass, il.GetObject());
}
-ExprId Architecture::GetDefaultFlagConditionLowLevelIL(BNLowLevelILFlagCondition cond, LowLevelILFunction& il)
+ExprId Architecture::GetSemanticFlagGroupLowLevelIL(uint32_t, LowLevelILFunction& il)
{
- return BNGetDefaultArchitectureFlagConditionLowLevelIL(m_object, cond, il.GetObject());
+ return il.Unimplemented();
}
@@ -742,12 +1018,71 @@ bool Architecture::IsGlobalRegister(uint32_t reg)
}
+string Architecture::GetRegisterStackName(uint32_t regStack)
+{
+ char regStr[32];
+ sprintf(regStr, "reg_stack_%" PRIu32, regStack);
+ return regStr;
+}
+
+
+vector<uint32_t> Architecture::GetAllRegisterStacks()
+{
+ return vector<uint32_t>();
+}
+
+
+BNRegisterStackInfo Architecture::GetRegisterStackInfo(uint32_t)
+{
+ BNRegisterStackInfo result;
+ result.firstStorageReg = BN_INVALID_REGISTER;
+ result.topRelativeCount = BN_INVALID_REGISTER;
+ result.storageCount = 0;
+ result.topRelativeCount = 0;
+ result.stackTopReg = BN_INVALID_REGISTER;
+ return result;
+}
+
+
+uint32_t Architecture::GetRegisterStackForRegister(uint32_t reg)
+{
+ return BNGetArchitectureRegisterStackForRegister(m_object, reg);
+}
+
+
+string Architecture::GetIntrinsicName(uint32_t intrinsic)
+{
+ char intrinsicStr[32];
+ sprintf(intrinsicStr, "intrinsic_%" PRIu32, intrinsic);
+ return intrinsicStr;
+}
+
+
+vector<uint32_t> Architecture::GetAllIntrinsics()
+{
+ return vector<uint32_t>();
+}
+
+
+vector<NameAndType> Architecture::GetIntrinsicInputs(uint32_t)
+{
+ return vector<NameAndType>();
+}
+
+
+vector<Confidence<Ref<Type>>> Architecture::GetIntrinsicOutputs(uint32_t)
+{
+ return vector<Confidence<Ref<Type>>>();
+}
+
+
vector<uint32_t> Architecture::GetModifiedRegistersOnWrite(uint32_t reg)
{
size_t count;
uint32_t* regs = BNGetModifiedArchitectureRegistersOnWrite(m_object, reg, &count);
vector<uint32_t> result;
+ result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(regs[i]);
@@ -859,6 +1194,7 @@ vector<Ref<CallingConvention>> Architecture::GetCallingConventions()
BNCallingConvention** list = BNGetArchitectureCallingConventions(m_object, &count);
vector<Ref<CallingConvention>> result;
+ result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new CoreCallingConvention(BNNewCallingConventionReference(list[i])));
@@ -973,6 +1309,12 @@ bool Architecture::ApplyELFRelocation(BinaryView* view, BNRelocationInfo& rel, u
// }
+void Architecture::AddArchitectureRedirection(Architecture* from, Architecture* to)
+{
+ BNAddArchitectureRedirection(m_object, from->GetObject(), to->GetObject());
+}
+
+
CoreArchitecture::CoreArchitecture(BNArchitecture* arch): Architecture(arch)
{
}
@@ -1033,6 +1375,7 @@ bool CoreArchitecture::GetInstructionText(const uint8_t* data, uint64_t addr, si
if (!BNGetInstructionText(m_object, data, addr, &len, &tokens, &count))
return false;
+ result.reserve(count);
for (size_t i = 0; i < count; i++)
{
result.emplace_back(tokens[i].type, tokens[i].context, tokens[i].text, tokens[i].address,
@@ -1077,12 +1420,31 @@ 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;
uint32_t* regs = BNGetFullWidthArchitectureRegisters(m_object, &count);
vector<uint32_t> result;
+ result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(regs[i]);
@@ -1097,6 +1459,7 @@ vector<uint32_t> CoreArchitecture::GetAllRegisters()
uint32_t* regs = BNGetAllArchitectureRegisters(m_object, &count);
vector<uint32_t> result;
+ result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(regs[i]);
@@ -1111,6 +1474,7 @@ vector<uint32_t> CoreArchitecture::GetAllFlags()
uint32_t* regs = BNGetAllArchitectureFlags(m_object, &count);
vector<uint32_t> result;
+ result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(regs[i]);
@@ -1125,6 +1489,35 @@ vector<uint32_t> CoreArchitecture::GetAllFlagWriteTypes()
uint32_t* regs = BNGetAllArchitectureFlagWriteTypes(m_object, &count);
vector<uint32_t> result;
+ result.reserve(count);
+ for (size_t i = 0; i < count; i++)
+ result.push_back(regs[i]);
+
+ BNFreeRegisterList(regs);
+ return result;
+}
+
+
+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]);
@@ -1133,18 +1526,33 @@ vector<uint32_t> CoreArchitecture::GetAllFlagWriteTypes()
}
-BNFlagRole CoreArchitecture::GetFlagRole(uint32_t flag)
+BNFlagRole CoreArchitecture::GetFlagRole(uint32_t flag, uint32_t semClass)
{
- return BNGetArchitectureFlagRole(m_object, flag);
+ return BNGetArchitectureFlagRole(m_object, flag, semClass);
+}
+
+
+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::GetFlagsRequiredForFlagCondition(BNLowLevelILFlagCondition cond)
+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;
+ result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(flags[i]);
@@ -1153,12 +1561,28 @@ 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;
uint32_t* flags = BNGetArchitectureFlagsWrittenByFlagWriteType(m_object, writeType, &count);
vector<uint32_t> result;
+ result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(flags[i]);
@@ -1167,6 +1591,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)
{
@@ -1175,9 +1605,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, il.GetObject());
+ return (ExprId)BNGetArchitectureFlagConditionLowLevelIL(m_object, cond, semClass, il.GetObject());
+}
+
+
+ExprId CoreArchitecture::GetSemanticFlagGroupLowLevelIL(uint32_t semGroup, LowLevelILFunction& il)
+{
+ return (ExprId)BNGetArchitectureSemanticFlagGroupLowLevelIL(m_object, semGroup, il.GetObject());
}
@@ -1205,6 +1642,59 @@ vector<uint32_t> CoreArchitecture::GetGlobalRegisters()
uint32_t* regs = BNGetArchitectureGlobalRegisters(m_object, &count);
vector<uint32_t> result;
+ result.reserve(count);
+ for (size_t i = 0; i < count; i++)
+ result.push_back(regs[i]);
+
+ BNFreeRegisterList(regs);
+ return result;
+}
+
+
+string CoreArchitecture::GetRegisterStackName(uint32_t regStack)
+{
+ char* name = BNGetArchitectureRegisterStackName(m_object, regStack);
+ string result = name;
+ BNFreeString(name);
+ return result;
+}
+
+
+vector<uint32_t> CoreArchitecture::GetAllRegisterStacks()
+{
+ size_t count;
+ uint32_t* regs = BNGetAllArchitectureRegisterStacks(m_object, &count);
+
+ vector<uint32_t> result;
+ for (size_t i = 0; i < count; i++)
+ result.push_back(regs[i]);
+
+ BNFreeRegisterList(regs);
+ return result;
+}
+
+
+BNRegisterStackInfo CoreArchitecture::GetRegisterStackInfo(uint32_t regStack)
+{
+ return BNGetArchitectureRegisterStackInfo(m_object, regStack);
+}
+
+
+string CoreArchitecture::GetIntrinsicName(uint32_t intrinsic)
+{
+ char* name = BNGetArchitectureIntrinsicName(m_object, intrinsic);
+ string result = name;
+ BNFreeString(name);
+ return result;
+}
+
+
+vector<uint32_t> CoreArchitecture::GetAllIntrinsics()
+{
+ size_t count;
+ uint32_t* regs = BNGetAllArchitectureIntrinsics(m_object, &count);
+
+ vector<uint32_t> result;
for (size_t i = 0; i < count; i++)
result.push_back(regs[i]);
@@ -1213,6 +1703,37 @@ vector<uint32_t> CoreArchitecture::GetGlobalRegisters()
}
+vector<NameAndType> CoreArchitecture::GetIntrinsicInputs(uint32_t intrinsic)
+{
+ size_t count;
+ BNNameAndType* inputs = BNGetArchitectureIntrinsicInputs(m_object, intrinsic, &count);
+
+ vector<NameAndType> result;
+ for (size_t i = 0; i < count; i++)
+ {
+ result.push_back(NameAndType(inputs[i].name, Confidence<Ref<Type>>(
+ new Type(BNNewTypeReference(inputs[i].type)), inputs[i].typeConfidence)));
+ }
+
+ BNFreeNameAndTypeList(inputs, count);
+ return result;
+}
+
+
+vector<Confidence<Ref<Type>>> CoreArchitecture::GetIntrinsicOutputs(uint32_t intrinsic)
+{
+ size_t count;
+ BNTypeWithConfidence* outputs = BNGetArchitectureIntrinsicOutputs(m_object, intrinsic, &count);
+
+ vector<Confidence<Ref<Type>>> result;
+ for (size_t i = 0; i < count; i++)
+ result.push_back(Confidence<Ref<Type>>(new Type(BNNewTypeReference(outputs[i].type)), outputs[i].confidence));
+
+ BNFreeOutputTypeList(outputs, count);
+ return result;
+}
+
+
bool CoreArchitecture::Assemble(const string& code, uint64_t addr, DataBuffer& result, string& errors)
{
char* errorStr = nullptr;
@@ -1301,4 +1822,365 @@ bool CoreArchitecture::ApplyELFRelocation(BinaryView* view, BNRelocationInfo& re
bool CoreArchitecture::GetRelocationInfo(BinaryView* view, uint64_t relocType, BNRelocationInfo& reloc)
{
return BNGetRelocationInfo(m_object, view->GetObject(), relocType, &reloc);
-} \ No newline at end of file
+}
+
+ArchitectureExtension::ArchitectureExtension(const string& name, Architecture* base): Architecture(name), m_base(base)
+{
+}
+
+
+void ArchitectureExtension::Register(BNCustomArchitecture* callbacks)
+{
+ AddRefForRegistration();
+ BNRegisterArchitectureExtension(m_nameForRegister.c_str(), m_base->GetObject(), callbacks);
+}
+
+
+BNEndianness ArchitectureExtension::GetEndianness() const
+{
+ return m_base->GetEndianness();
+}
+
+
+size_t ArchitectureExtension::GetAddressSize() const
+{
+ return m_base->GetAddressSize();
+}
+
+
+size_t ArchitectureExtension::GetDefaultIntegerSize() const
+{
+ return m_base->GetDefaultIntegerSize();
+}
+
+
+size_t ArchitectureExtension::GetInstructionAlignment() const
+{
+ return m_base->GetInstructionAlignment();
+}
+
+
+size_t ArchitectureExtension::GetMaxInstructionLength() const
+{
+ return m_base->GetMaxInstructionLength();
+}
+
+
+size_t ArchitectureExtension::GetOpcodeDisplayLength() const
+{
+ return m_base->GetOpcodeDisplayLength();
+}
+
+
+Ref<Architecture> ArchitectureExtension::GetAssociatedArchitectureByAddress(uint64_t& addr)
+{
+ Ref<Architecture> result = m_base->GetAssociatedArchitectureByAddress(addr);
+ if (result == m_base)
+ return this;
+ return result;
+}
+
+
+bool ArchitectureExtension::GetInstructionInfo(const uint8_t* data, uint64_t addr, size_t maxLen, InstructionInfo& result)
+{
+ return m_base->GetInstructionInfo(data, addr, maxLen, result);
+}
+
+
+bool ArchitectureExtension::GetInstructionText(const uint8_t* data, uint64_t addr, size_t& len,
+ vector<InstructionTextToken>& result)
+{
+ return m_base->GetInstructionText(data, addr, len, result);
+}
+
+
+bool ArchitectureExtension::GetInstructionLowLevelIL(const uint8_t* data, uint64_t addr, size_t& len, LowLevelILFunction& il)
+{
+ return m_base->GetInstructionLowLevelIL(data, addr, len, il);
+}
+
+
+string ArchitectureExtension::GetRegisterName(uint32_t reg)
+{
+ return m_base->GetRegisterName(reg);
+}
+
+
+string ArchitectureExtension::GetFlagName(uint32_t flag)
+{
+ return m_base->GetFlagName(flag);
+}
+
+
+string ArchitectureExtension::GetFlagWriteTypeName(uint32_t flags)
+{
+ return m_base->GetFlagWriteTypeName(flags);
+}
+
+
+string ArchitectureExtension::GetSemanticFlagClassName(uint32_t semClass)
+{
+ return m_base->GetSemanticFlagClassName(semClass);
+}
+
+
+string ArchitectureExtension::GetSemanticFlagGroupName(uint32_t semGroup)
+{
+ return m_base->GetSemanticFlagGroupName(semGroup);
+}
+
+
+vector<uint32_t> ArchitectureExtension::GetFullWidthRegisters()
+{
+ return m_base->GetFullWidthRegisters();
+}
+
+
+vector<uint32_t> ArchitectureExtension::GetAllRegisters()
+{
+ return m_base->GetAllRegisters();
+}
+
+
+vector<uint32_t> ArchitectureExtension::GetAllFlags()
+{
+ return m_base->GetAllFlags();
+}
+
+
+vector<uint32_t> ArchitectureExtension::GetAllFlagWriteTypes()
+{
+ return m_base->GetAllFlagWriteTypes();
+}
+
+
+vector<uint32_t> ArchitectureExtension::GetAllSemanticFlagClasses()
+{
+ return m_base->GetAllSemanticFlagClasses();
+}
+
+
+vector<uint32_t> ArchitectureExtension::GetAllSemanticFlagGroups()
+{
+ return m_base->GetAllSemanticFlagGroups();
+}
+
+
+BNFlagRole ArchitectureExtension::GetFlagRole(uint32_t flag, uint32_t semClass)
+{
+ return m_base->GetFlagRole(flag, semClass);
+}
+
+
+vector<uint32_t> ArchitectureExtension::GetFlagsRequiredForFlagCondition(BNLowLevelILFlagCondition cond,
+ uint32_t semClass)
+{
+ return m_base->GetFlagsRequiredForFlagCondition(cond, semClass);
+}
+
+
+vector<uint32_t> ArchitectureExtension::GetFlagsRequiredForSemanticFlagGroup(uint32_t semGroup)
+{
+ return m_base->GetFlagsRequiredForSemanticFlagGroup(semGroup);
+}
+
+
+map<uint32_t, BNLowLevelILFlagCondition> ArchitectureExtension::GetFlagConditionsForSemanticFlagGroup(uint32_t semGroup)
+{
+ return m_base->GetFlagConditionsForSemanticFlagGroup(semGroup);
+}
+
+
+vector<uint32_t> ArchitectureExtension::GetFlagsWrittenByFlagWriteType(uint32_t writeType)
+{
+ return m_base->GetFlagsWrittenByFlagWriteType(writeType);
+}
+
+
+uint32_t ArchitectureExtension::GetSemanticClassForFlagWriteType(uint32_t writeType)
+{
+ return m_base->GetSemanticClassForFlagWriteType(writeType);
+}
+
+
+ExprId ArchitectureExtension::GetFlagWriteLowLevelIL(BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
+ uint32_t flag, BNRegisterOrConstant* operands, size_t operandCount, LowLevelILFunction& il)
+{
+ return m_base->GetFlagWriteLowLevelIL(op, size, flagWriteType, flag, operands, operandCount, il);
+}
+
+
+ExprId ArchitectureExtension::GetFlagConditionLowLevelIL(BNLowLevelILFlagCondition cond,
+ uint32_t semClass, LowLevelILFunction& il)
+{
+ return m_base->GetFlagConditionLowLevelIL(cond, semClass, il);
+}
+
+
+ExprId ArchitectureExtension::GetSemanticFlagGroupLowLevelIL(uint32_t semGroup, LowLevelILFunction& il)
+{
+ return m_base->GetSemanticFlagGroupLowLevelIL(semGroup, il);
+}
+
+
+BNRegisterInfo ArchitectureExtension::GetRegisterInfo(uint32_t reg)
+{
+ return m_base->GetRegisterInfo(reg);
+}
+
+
+uint32_t ArchitectureExtension::GetStackPointerRegister()
+{
+ return m_base->GetStackPointerRegister();
+}
+
+
+uint32_t ArchitectureExtension::GetLinkRegister()
+{
+ return m_base->GetLinkRegister();
+}
+
+
+vector<uint32_t> ArchitectureExtension::GetGlobalRegisters()
+{
+ return m_base->GetGlobalRegisters();
+}
+
+
+string ArchitectureExtension::GetRegisterStackName(uint32_t regStack)
+{
+ return m_base->GetRegisterStackName(regStack);
+}
+
+
+vector<uint32_t> ArchitectureExtension::GetAllRegisterStacks()
+{
+ return m_base->GetAllRegisterStacks();
+}
+
+
+BNRegisterStackInfo ArchitectureExtension::GetRegisterStackInfo(uint32_t regStack)
+{
+ return m_base->GetRegisterStackInfo(regStack);
+}
+
+
+string ArchitectureExtension::GetIntrinsicName(uint32_t intrinsic)
+{
+ return m_base->GetIntrinsicName(intrinsic);
+}
+
+
+vector<uint32_t> ArchitectureExtension::GetAllIntrinsics()
+{
+ return m_base->GetAllIntrinsics();
+}
+
+
+vector<NameAndType> ArchitectureExtension::GetIntrinsicInputs(uint32_t intrinsic)
+{
+ return m_base->GetIntrinsicInputs(intrinsic);
+}
+
+
+vector<Confidence<Ref<Type>>> ArchitectureExtension::GetIntrinsicOutputs(uint32_t intrinsic)
+{
+ return m_base->GetIntrinsicOutputs(intrinsic);
+}
+
+
+bool ArchitectureExtension::Assemble(const string& code, uint64_t addr, DataBuffer& result, string& errors)
+{
+ return m_base->Assemble(code, addr, result, errors);
+}
+
+
+bool ArchitectureExtension::IsNeverBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len)
+{
+ return m_base->IsNeverBranchPatchAvailable(data, addr, len);
+}
+
+
+bool ArchitectureExtension::IsAlwaysBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len)
+{
+ return m_base->IsAlwaysBranchPatchAvailable(data, addr, len);
+}
+
+
+bool ArchitectureExtension::IsInvertBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len)
+{
+ return m_base->IsInvertBranchPatchAvailable(data, addr, len);
+}
+
+
+bool ArchitectureExtension::IsSkipAndReturnZeroPatchAvailable(const uint8_t* data, uint64_t addr, size_t len)
+{
+ return m_base->IsSkipAndReturnValuePatchAvailable(data, addr, len);
+}
+
+
+bool ArchitectureExtension::IsSkipAndReturnValuePatchAvailable(const uint8_t* data, uint64_t addr, size_t len)
+{
+ return m_base->IsSkipAndReturnValuePatchAvailable(data, addr, len);
+}
+
+
+bool ArchitectureExtension::ConvertToNop(uint8_t* data, uint64_t addr, size_t len)
+{
+ return m_base->ConvertToNop(data, addr, len);
+}
+
+
+bool ArchitectureExtension::AlwaysBranch(uint8_t* data, uint64_t addr, size_t len)
+{
+ return m_base->AlwaysBranch(data, addr, len);
+}
+
+
+bool ArchitectureExtension::InvertBranch(uint8_t* data, uint64_t addr, size_t len)
+{
+ return m_base->InvertBranch(data, addr, len);
+}
+
+
+bool ArchitectureExtension::SkipAndReturnValue(uint8_t* data, uint64_t addr, size_t len, uint64_t value)
+{
+ return m_base->SkipAndReturnValue(data, addr, len, value);
+}
+
+
+ArchitectureHook::ArchitectureHook(Architecture* base): CoreArchitecture(nullptr), m_base(base)
+{
+ // Architecture hooks allow existing architecture implementations to be extended without creating
+ // a new Architecture object for the changes. By deriving from the ArchitectureHook class and passing
+ // the original Architecture object of the architecture to be extended, any reimplemented functions
+ // will be called first before the original architecture's implementation. You MUST call the base
+ // class method to call the original implementation's version of the function, as calling the
+ // same function on the original Architecture object will call your implementation again.
+
+ // Example of a hook to modify the lifting process:
+
+ // class ArchitectureHookExample: public ArchitectureHook
+ // {
+ // public:
+ // ArchitectureHookExample(Architecture* existingArch) : ArchitectureHook(existingArch)
+ // {
+ // }
+ //
+ // virtual bool GetInstructionLowLevelIL(const uint8_t* data, uint64_t addr, size_t& len,
+ // LowLevelILFunction& il) override
+ // {
+ // // Perform extra lifting here
+ // // ...
+ // // For unhandled cases, call the original architecture's implementation
+ // return ArchitectureHook::GetInstructionLowLevelIL(data, addr, len, il);
+ // }
+ // };
+}
+
+
+void ArchitectureHook::Register(BNCustomArchitecture* callbacks)
+{
+ AddRefForRegistration();
+ m_object = BNRegisterArchitectureHook(m_base->GetObject(), callbacks);
+}