summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2015-05-19 03:24:43 -0400
committerRusty Wagner <rusty@vector35.com>2015-05-19 03:24:43 -0400
commit8a1b1bb5e3bd19dd50787bdb9616de56fea8ce00 (patch)
treedea0b13e0c05a31198edc757d0bcbde85d6238ff
parenta4461126be25670aa4339e269270f5107b99439a (diff)
Quick patches in right click menu
-rw-r--r--architecture.cpp187
-rw-r--r--binaryninjaapi.h46
-rw-r--r--binaryview.cpp54
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()))
{
}