diff options
| author | Rusty Wagner <rusty@vector35.com> | 2018-02-23 14:54:44 -0500 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2018-02-23 15:00:43 -0500 |
| commit | ef91ab7f3b648051b72fd06dd05eff3c57fa7f65 (patch) | |
| tree | d8f6c12a846414e09eb8c5fcb24f45f8260fdb1f /architecture.cpp | |
| parent | 76f691d065332fabe7ee9aa6370e3fedef217f02 (diff) | |
Add APIs for subclassing or hooking an existing architecture in C/C++
Diffstat (limited to 'architecture.cpp')
| -rw-r--r-- | architecture.cpp | 378 |
1 files changed, 376 insertions, 2 deletions
diff --git a/architecture.cpp b/architecture.cpp index 90f8e622..a1aaca2d 100644 --- a/architecture.cpp +++ b/architecture.cpp @@ -640,6 +640,13 @@ bool Architecture::SkipAndReturnValueCallback(void* ctxt, uint8_t* data, uint64_ } +void Architecture::Register(BNCustomArchitecture* callbacks) +{ + AddRefForRegistration(); + BNRegisterArchitecture(m_nameForRegister.c_str(), callbacks); +} + + void Architecture::Register(Architecture* arch) { BNCustomArchitecture callbacks; @@ -701,8 +708,7 @@ void Architecture::Register(Architecture* arch) callbacks.alwaysBranch = AlwaysBranchCallback; callbacks.invertBranch = InvertBranchCallback; callbacks.skipAndReturnValue = SkipAndReturnValueCallback; - arch->AddRefForRegistration(); - BNRegisterArchitecture(arch->m_nameForRegister.c_str(), &callbacks); + arch->Register(&callbacks); } @@ -1228,6 +1234,12 @@ Ref<Platform> Architecture::GetStandalonePlatform() } +void Architecture::AddArchitectureRedirection(Architecture* from, Architecture* to) +{ + BNAddArchitectureRedirection(m_object, from->GetObject(), to->GetObject()); +} + + CoreArchitecture::CoreArchitecture(BNArchitecture* arch): Architecture(arch) { } @@ -1712,3 +1724,365 @@ bool CoreArchitecture::SkipAndReturnValue(uint8_t* data, uint64_t addr, size_t l { return BNArchitectureSkipAndReturnValue(m_object, data, addr, len, value); } + + +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); +} |
