diff options
| author | Rusty Wagner <rusty@vector35.com> | 2015-05-19 03:24:43 -0400 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2015-05-19 03:24:43 -0400 |
| commit | 8a1b1bb5e3bd19dd50787bdb9616de56fea8ce00 (patch) | |
| tree | dea0b13e0c05a31198edc757d0bcbde85d6238ff | |
| parent | a4461126be25670aa4339e269270f5107b99439a (diff) | |
Quick patches in right click menu
| -rw-r--r-- | architecture.cpp | 187 | ||||
| -rw-r--r-- | binaryninjaapi.h | 46 | ||||
| -rw-r--r-- | binaryview.cpp | 54 |
3 files changed, 286 insertions, 1 deletions
diff --git a/architecture.cpp b/architecture.cpp index 268fcece..da18e9c1 100644 --- a/architecture.cpp +++ b/architecture.cpp @@ -115,6 +115,69 @@ bool Architecture::AssembleCallback(void* ctxt, const char* code, uint64_t addr, } +bool Architecture::IsNeverBranchPatchAvailableCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t len) +{ + Architecture* arch = (Architecture*)ctxt; + return arch->IsNeverBranchPatchAvailable(data, addr, len); +} + + +bool Architecture::IsAlwaysBranchPatchAvailableCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t len) +{ + Architecture* arch = (Architecture*)ctxt; + return arch->IsAlwaysBranchPatchAvailable(data, addr, len); +} + + +bool Architecture::IsInvertBranchPatchAvailableCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t len) +{ + Architecture* arch = (Architecture*)ctxt; + return arch->IsInvertBranchPatchAvailable(data, addr, len); +} + + +bool Architecture::IsSkipAndReturnZeroPatchAvailableCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t len) +{ + Architecture* arch = (Architecture*)ctxt; + return arch->IsSkipAndReturnZeroPatchAvailable(data, addr, len); +} + + +bool Architecture::IsSkipAndReturnValuePatchAvailableCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t len) +{ + Architecture* arch = (Architecture*)ctxt; + return arch->IsSkipAndReturnValuePatchAvailable(data, addr, len); +} + + +bool Architecture::ConvertToNopCallback(void* ctxt, uint8_t* data, uint64_t addr, size_t len) +{ + Architecture* arch = (Architecture*)ctxt; + return arch->ConvertToNop(data, addr, len); +} + + +bool Architecture::AlwaysBranchCallback(void* ctxt, uint8_t* data, uint64_t addr, size_t len) +{ + Architecture* arch = (Architecture*)ctxt; + return arch->AlwaysBranch(data, addr, len); +} + + +bool Architecture::InvertBranchCallback(void* ctxt, uint8_t* data, uint64_t addr, size_t len) +{ + Architecture* arch = (Architecture*)ctxt; + return arch->InvertBranch(data, addr, len); +} + + +bool Architecture::SkipAndReturnValueCallback(void* ctxt, uint8_t* data, uint64_t addr, size_t len, uint64_t value) +{ + Architecture* arch = (Architecture*)ctxt; + return arch->SkipAndReturnValue(data, addr, len, value); +} + + void Architecture::Register(Architecture* arch) { BNCustomArchitecture callbacks; @@ -125,6 +188,15 @@ void Architecture::Register(Architecture* arch) callbacks.getInstructionText = GetInstructionTextCallback; callbacks.freeInstructionText = FreeInstructionTextCallback; callbacks.assemble = AssembleCallback; + callbacks.isNeverBranchPatchAvailable = IsNeverBranchPatchAvailableCallback; + callbacks.isAlwaysBranchPatchAvailable = IsAlwaysBranchPatchAvailableCallback; + callbacks.isInvertBranchPatchAvailable = IsInvertBranchPatchAvailableCallback; + callbacks.isSkipAndReturnZeroPatchAvailable = IsSkipAndReturnZeroPatchAvailableCallback; + callbacks.isSkipAndReturnValuePatchAvailable = IsSkipAndReturnValuePatchAvailableCallback; + callbacks.convertToNop = ConvertToNopCallback; + callbacks.alwaysBranch = AlwaysBranchCallback; + callbacks.invertBranch = InvertBranchCallback; + callbacks.skipAndReturnValue = SkipAndReturnValueCallback; arch->m_arch = BNRegisterArchitecture(arch->m_nameForRegister.c_str(), &callbacks); } @@ -162,6 +234,67 @@ string Architecture::GetName() const } +bool Architecture::Assemble(const std::string&, uint64_t, DataBuffer&, std::string& errors) +{ + errors = "Architecture does not implement an assembler.\n"; + return false; +} + + +bool Architecture::IsNeverBranchPatchAvailable(const uint8_t*, uint64_t, size_t) +{ + return false; +} + + +bool Architecture::IsAlwaysBranchPatchAvailable(const uint8_t*, uint64_t, size_t) +{ + return false; +} + + +bool Architecture::IsInvertBranchPatchAvailable(const uint8_t*, uint64_t, size_t) +{ + return false; +} + + +bool Architecture::IsSkipAndReturnZeroPatchAvailable(const uint8_t*, uint64_t, size_t) +{ + return false; +} + + +bool Architecture::IsSkipAndReturnValuePatchAvailable(const uint8_t*, uint64_t, size_t) +{ + return false; +} + + +bool Architecture::ConvertToNop(uint8_t*, uint64_t, size_t) +{ + return false; +} + + +bool Architecture::AlwaysBranch(uint8_t*, uint64_t, size_t) +{ + return false; +} + + +bool Architecture::InvertBranch(uint8_t*, uint64_t, size_t) +{ + return false; +} + + +bool Architecture::SkipAndReturnValue(uint8_t*, uint64_t, size_t, uint64_t) +{ + return false; +} + + CoreArchitecture::CoreArchitecture(BNArchitecture* arch): Architecture(arch) { } @@ -211,3 +344,57 @@ bool CoreArchitecture::Assemble(const string& code, uint64_t addr, DataBuffer& r } return ok; } + + +bool CoreArchitecture::IsNeverBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len) +{ + return BNIsArchitectureNeverBranchPatchAvailable(m_arch, data, addr, len); +} + + +bool CoreArchitecture::IsAlwaysBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len) +{ + return BNIsArchitectureAlwaysBranchPatchAvailable(m_arch, data, addr, len); +} + + +bool CoreArchitecture::IsInvertBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len) +{ + return BNIsArchitectureInvertBranchPatchAvailable(m_arch, data, addr, len); +} + + +bool CoreArchitecture::IsSkipAndReturnZeroPatchAvailable(const uint8_t* data, uint64_t addr, size_t len) +{ + return BNIsArchitectureSkipAndReturnZeroPatchAvailable(m_arch, data, addr, len); +} + + +bool CoreArchitecture::IsSkipAndReturnValuePatchAvailable(const uint8_t* data, uint64_t addr, size_t len) +{ + return BNIsArchitectureSkipAndReturnValuePatchAvailable(m_arch, data, addr, len); +} + + +bool CoreArchitecture::ConvertToNop(uint8_t* data, uint64_t addr, size_t len) +{ + return BNArchitectureConvertToNop(m_arch, data, addr, len); +} + + +bool CoreArchitecture::AlwaysBranch(uint8_t* data, uint64_t addr, size_t len) +{ + return BNArchitectureAlwaysBranch(m_arch, data, addr, len); +} + + +bool CoreArchitecture::InvertBranch(uint8_t* data, uint64_t addr, size_t len) +{ + return BNArchitectureInvertBranch(m_arch, data, addr, len); +} + + +bool CoreArchitecture::SkipAndReturnValue(uint8_t* data, uint64_t addr, size_t len, uint64_t value) +{ + return BNArchitectureSkipAndReturnValue(m_arch, data, addr, len, value); +} diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 10ceda55..edf4cbb7 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -544,6 +544,17 @@ namespace BinaryNinja void DefineSymbol(Symbol* sym); void UndefineSymbol(Symbol* sym); + + bool IsNeverBranchPatchAvailable(Architecture* arch, uint64_t addr); + bool IsAlwaysBranchPatchAvailable(Architecture* arch, uint64_t addr); + bool IsInvertBranchPatchAvailable(Architecture* arch, uint64_t addr); + bool IsSkipAndReturnZeroPatchAvailable(Architecture* arch, uint64_t addr); + bool IsSkipAndReturnValuePatchAvailable(Architecture* arch, uint64_t addr); + + bool ConvertToNop(Architecture* arch, uint64_t addr); + bool AlwaysBranch(Architecture* arch, uint64_t addr); + bool InvertBranch(Architecture* arch, uint64_t addr); + bool SkipAndReturnValue(Architecture* arch, uint64_t addr, uint64_t value); }; class BinaryData: public BinaryView @@ -790,6 +801,17 @@ namespace BinaryNinja static void FreeInstructionTextCallback(BNInstructionTextToken* tokens, size_t count); static bool AssembleCallback(void* ctxt, const char* code, uint64_t addr, BNDataBuffer* result, char** errors); + static bool IsNeverBranchPatchAvailableCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t len); + static bool IsAlwaysBranchPatchAvailableCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t len); + static bool IsInvertBranchPatchAvailableCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t len); + static bool IsSkipAndReturnZeroPatchAvailableCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t len); + static bool IsSkipAndReturnValuePatchAvailableCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t len); + + static bool ConvertToNopCallback(void* ctxt, uint8_t* data, uint64_t addr, size_t len); + static bool AlwaysBranchCallback(void* ctxt, uint8_t* data, uint64_t addr, size_t len); + static bool InvertBranchCallback(void* ctxt, uint8_t* data, uint64_t addr, size_t len); + static bool SkipAndReturnValueCallback(void* ctxt, uint8_t* data, uint64_t addr, size_t len, uint64_t value); + public: Architecture(const std::string& name); @@ -808,7 +830,18 @@ namespace BinaryNinja virtual bool GetInstructionText(const uint8_t* data, uint64_t addr, size_t& len, std::vector<InstructionTextToken>& result) = 0; - virtual bool Assemble(const std::string& code, uint64_t addr, DataBuffer& result, std::string& errors) = 0; + virtual bool Assemble(const std::string& code, uint64_t addr, DataBuffer& result, std::string& errors); + + virtual bool IsNeverBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len); + virtual bool IsAlwaysBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len); + virtual bool IsInvertBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len); + virtual bool IsSkipAndReturnZeroPatchAvailable(const uint8_t* data, uint64_t addr, size_t len); + virtual bool IsSkipAndReturnValuePatchAvailable(const uint8_t* data, uint64_t addr, size_t len); + + virtual bool ConvertToNop(uint8_t* data, uint64_t addr, size_t len); + virtual bool AlwaysBranch(uint8_t* data, uint64_t addr, size_t len); + virtual bool InvertBranch(uint8_t* data, uint64_t addr, size_t len); + virtual bool SkipAndReturnValue(uint8_t* data, uint64_t addr, size_t len, uint64_t value); }; class CoreArchitecture: public Architecture @@ -821,6 +854,17 @@ namespace BinaryNinja virtual bool GetInstructionText(const uint8_t* data, uint64_t addr, size_t& len, std::vector<InstructionTextToken>& result) override; virtual bool Assemble(const std::string& code, uint64_t addr, DataBuffer& result, std::string& errors) override; + + virtual bool IsNeverBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len) override; + virtual bool IsAlwaysBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len) override; + virtual bool IsInvertBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len) override; + virtual bool IsSkipAndReturnZeroPatchAvailable(const uint8_t* data, uint64_t addr, size_t len) override; + virtual bool IsSkipAndReturnValuePatchAvailable(const uint8_t* data, uint64_t addr, size_t len) override; + + virtual bool ConvertToNop(uint8_t* data, uint64_t addr, size_t len) override; + virtual bool AlwaysBranch(uint8_t* data, uint64_t addr, size_t len) override; + virtual bool InvertBranch(uint8_t* data, uint64_t addr, size_t len) override; + virtual bool SkipAndReturnValue(uint8_t* data, uint64_t addr, size_t len, uint64_t value) override; }; class Function; diff --git a/binaryview.cpp b/binaryview.cpp index 173e3e06..d0274f95 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -750,6 +750,60 @@ void BinaryView::UndefineSymbol(Symbol* sym) } +bool BinaryView::IsNeverBranchPatchAvailable(Architecture* arch, uint64_t addr) +{ + return BNIsNeverBranchPatchAvailable(m_view, arch->GetArchitectureObject(), addr); +} + + +bool BinaryView::IsAlwaysBranchPatchAvailable(Architecture* arch, uint64_t addr) +{ + return BNIsAlwaysBranchPatchAvailable(m_view, arch->GetArchitectureObject(), addr); +} + + +bool BinaryView::IsInvertBranchPatchAvailable(Architecture* arch, uint64_t addr) +{ + return BNIsInvertBranchPatchAvailable(m_view, arch->GetArchitectureObject(), addr); +} + + +bool BinaryView::IsSkipAndReturnZeroPatchAvailable(Architecture* arch, uint64_t addr) +{ + return BNIsSkipAndReturnZeroPatchAvailable(m_view, arch->GetArchitectureObject(), addr); +} + + +bool BinaryView::IsSkipAndReturnValuePatchAvailable(Architecture* arch, uint64_t addr) +{ + return BNIsSkipAndReturnValuePatchAvailable(m_view, arch->GetArchitectureObject(), addr); +} + + +bool BinaryView::ConvertToNop(Architecture* arch, uint64_t addr) +{ + return BNConvertToNop(m_view, arch->GetArchitectureObject(), addr); +} + + +bool BinaryView::AlwaysBranch(Architecture* arch, uint64_t addr) +{ + return BNAlwaysBranch(m_view, arch->GetArchitectureObject(), addr); +} + + +bool BinaryView::InvertBranch(Architecture* arch, uint64_t addr) +{ + return BNInvertBranch(m_view, arch->GetArchitectureObject(), addr); +} + + +bool BinaryView::SkipAndReturnValue(Architecture* arch, uint64_t addr, uint64_t value) +{ + return BNSkipAndReturnValue(m_view, arch->GetArchitectureObject(), addr, value); +} + + BinaryData::BinaryData(FileMetadata* file): BinaryView(BNCreateBinaryDataView(file->GetFileObject())) { } |
