summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXusheng <xusheng@vector35.com>2020-09-18 18:35:27 +0800
committerXusheng <xusheng@vector35.com>2020-10-15 12:50:02 +0800
commitcbe3ded641a0ce4b50ae447a4426b71f3e0f0119 (patch)
tree339cff6f061f89a49a78f82626dd5601c448bf05
parentd77c63efc16070868bf6eb87d274bf846f4440f7 (diff)
edit current line in linear view
add CanAssemble() to architectures
-rw-r--r--architecture.cpp18
-rw-r--r--binaryninjaapi.h6
-rw-r--r--binaryninjacore.h4
-rw-r--r--binaryview.cpp5
-rw-r--r--python/architecture.py5
-rw-r--r--python/binaryview.py16
-rw-r--r--ui/linearview.h7
-rw-r--r--ui/viewframe.h2
8 files changed, 63 insertions, 0 deletions
diff --git a/architecture.cpp b/architecture.cpp
index 9415b966..d07fbcbb 100644
--- a/architecture.cpp
+++ b/architecture.cpp
@@ -643,6 +643,11 @@ void Architecture::FreeTypeListCallback(void*, BNTypeWithConfidence* types, size
delete[] types;
}
+bool Architecture::CanAssembleCallback(void* ctxt)
+{
+ Architecture* arch = (Architecture*)ctxt;
+ return arch->CanAssemble();
+}
bool Architecture::AssembleCallback(void* ctxt, const char* code, uint64_t addr, BNDataBuffer* result, char** errors)
{
@@ -779,6 +784,7 @@ void Architecture::Register(Architecture* arch)
callbacks.freeNameAndTypeList = FreeNameAndTypeListCallback;
callbacks.getIntrinsicOutputs = GetIntrinsicOutputsCallback;
callbacks.freeTypeList = FreeTypeListCallback;
+ callbacks.canAssemble = CanAssembleCallback;
callbacks.assemble = AssembleCallback;
callbacks.isNeverBranchPatchAvailable = IsNeverBranchPatchAvailableCallback;
callbacks.isAlwaysBranchPatchAvailable = IsAlwaysBranchPatchAvailableCallback;
@@ -1145,6 +1151,10 @@ uint32_t Architecture::GetRegisterByName(const string& name)
return BNGetArchitectureRegisterByName(m_object, name.c_str());
}
+bool Architecture::CanAssemble()
+{
+ return false;
+}
bool Architecture::Assemble(const std::string&, uint64_t, DataBuffer&, std::string& errors)
{
@@ -1770,6 +1780,10 @@ vector<Confidence<Ref<Type>>> CoreArchitecture::GetIntrinsicOutputs(uint32_t int
return result;
}
+bool CoreArchitecture::CanAssemble()
+{
+ return BNCanArchitectureAssemble(m_object);
+}
bool CoreArchitecture::Assemble(const string& code, uint64_t addr, DataBuffer& result, string& errors)
{
@@ -2108,6 +2122,10 @@ vector<Confidence<Ref<Type>>> ArchitectureExtension::GetIntrinsicOutputs(uint32_
return m_base->GetIntrinsicOutputs(intrinsic);
}
+bool ArchitectureExtension::CanAssemble()
+{
+ return m_base->CanAssemble();
+}
bool ArchitectureExtension::Assemble(const string& code, uint64_t addr, DataBuffer& result, string& errors)
{
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 0e281baa..930bfe4e 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -1637,6 +1637,8 @@ __attribute__ ((format (printf, 1, 2)))
Ref<Tag> CreateAutoDataTag(uint64_t addr, Ref<TagType> tagType, const std::string& data, bool unique = false);
Ref<Tag> CreateUserDataTag(uint64_t addr, Ref<TagType> tagType, const std::string& data, bool unique = false);
+ bool CanAssemble(Architecture* arch);
+
bool IsNeverBranchPatchAvailable(Architecture* arch, uint64_t addr);
bool IsAlwaysBranchPatchAvailable(Architecture* arch, uint64_t addr);
bool IsInvertBranchPatchAvailable(Architecture* arch, uint64_t addr);
@@ -2102,6 +2104,7 @@ __attribute__ ((format (printf, 1, 2)))
static BNTypeWithConfidence* GetIntrinsicOutputsCallback(void* ctxt, uint32_t intrinsic, size_t* count);
static void FreeTypeListCallback(void* ctxt, BNTypeWithConfidence* types, size_t count);
+ static bool CanAssembleCallback(void* ctxt);
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);
@@ -2192,6 +2195,7 @@ __attribute__ ((format (printf, 1, 2)))
virtual std::vector<NameAndType> GetIntrinsicInputs(uint32_t intrinsic);
virtual std::vector<Confidence<Ref<Type>>> GetIntrinsicOutputs(uint32_t intrinsic);
+ virtual bool CanAssemble();
virtual bool Assemble(const std::string& code, uint64_t addr, DataBuffer& result, std::string& errors);
/*! IsNeverBranchPatchAvailable returns true if the instruction at addr can be patched to never branch.
@@ -2342,6 +2346,7 @@ __attribute__ ((format (printf, 1, 2)))
virtual std::vector<NameAndType> GetIntrinsicInputs(uint32_t intrinsic) override;
virtual std::vector<Confidence<Ref<Type>>> GetIntrinsicOutputs(uint32_t intrinsic) override;
+ virtual bool CanAssemble() 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;
@@ -2417,6 +2422,7 @@ __attribute__ ((format (printf, 1, 2)))
virtual std::vector<NameAndType> GetIntrinsicInputs(uint32_t intrinsic) override;
virtual std::vector<Confidence<Ref<Type>>> GetIntrinsicOutputs(uint32_t intrinsic) override;
+ virtual bool CanAssemble() 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;
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 938ed0cb..dfd78fad 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -1483,6 +1483,7 @@ extern "C"
BNTypeWithConfidence* (*getIntrinsicOutputs)(void* ctxt, uint32_t intrinsic, size_t* count);
void (*freeTypeList)(void* ctxt, BNTypeWithConfidence* types, size_t count);
+ bool (*canAssemble)(void* ctxt);
bool (*assemble)(void* ctxt, const char* code, uint64_t addr, BNDataBuffer* result, char** errors);
bool (*isNeverBranchPatchAvailable)(void* ctxt, const uint8_t* data, uint64_t addr, size_t len);
@@ -2680,6 +2681,8 @@ __attribute__ ((format (printf, 1, 2)))
BINARYNINJACOREAPI void BNRegisterDataNotification(BNBinaryView* view, BNBinaryDataNotification* notify);
BINARYNINJACOREAPI void BNUnregisterDataNotification(BNBinaryView* view, BNBinaryDataNotification* notify);
+ BINARYNINJACOREAPI bool BNCanAssemble(BNBinaryView* view, BNArchitecture* arch);
+
BINARYNINJACOREAPI bool BNIsNeverBranchPatchAvailable(BNBinaryView* view, BNArchitecture* arch, uint64_t addr);
BINARYNINJACOREAPI bool BNIsAlwaysBranchPatchAvailable(BNBinaryView* view, BNArchitecture* arch, uint64_t addr);
BINARYNINJACOREAPI bool BNIsInvertBranchPatchAvailable(BNBinaryView* view, BNArchitecture* arch, uint64_t addr);
@@ -2927,6 +2930,7 @@ __attribute__ ((format (printf, 1, 2)))
size_t* count);
BINARYNINJACOREAPI void BNFreeOutputTypeList(BNTypeWithConfidence* types, size_t count);
+ BINARYNINJACOREAPI bool BNCanArchitectureAssemble(BNArchitecture* arch);
BINARYNINJACOREAPI bool BNAssemble(BNArchitecture* arch, const char* code, uint64_t addr, BNDataBuffer* result, char** errors);
BINARYNINJACOREAPI bool BNIsArchitectureNeverBranchPatchAvailable(BNArchitecture* arch, const uint8_t* data,
diff --git a/binaryview.cpp b/binaryview.cpp
index 11a6c032..8e3f115a 100644
--- a/binaryview.cpp
+++ b/binaryview.cpp
@@ -2284,6 +2284,11 @@ Ref<Tag> BinaryView::CreateUserDataTag(uint64_t addr, Ref<TagType> tagType, cons
return tag;
}
+bool BinaryView::CanAssemble(Architecture* arch)
+{
+ return BNCanAssemble(m_object, arch->GetObject());
+
+}
bool BinaryView::IsNeverBranchPatchAvailable(Architecture* arch, uint64_t addr)
{
diff --git a/python/architecture.py b/python/architecture.py
index bb1f17db..0c5f816d 100644
--- a/python/architecture.py
+++ b/python/architecture.py
@@ -453,6 +453,11 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
core.BNFreeTypeLibraryList(handles, count.value)
return result
+ @property
+ def can_assemble(self):
+ """returns if the architecture can assemble instructions (read-only)"""
+ return core.BNCanArchitectureAssemble(self.handle)
+
def _init(self, ctxt, handle):
self.handle = handle
diff --git a/python/binaryview.py b/python/binaryview.py
index 7c0ac0c2..7e893ab2 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -3853,6 +3853,22 @@ class BinaryView(object):
"""
core.BNRemoveAutoDataTag(self.handle, addr, tag.handle)
+ def can_assemble(self, arch=None):
+ """
+ ``can_assemble`` queries the architecture plugin to determine if the architecture can assemble instructions.
+
+ :return: True if the architecture can assemble, False otherwise
+ :rtype: bool
+ :Example:
+
+ >>> bv.can_assemble()
+ True
+ >>>
+ """
+ if arch is None:
+ arch = self.arch
+ return core.BNCanAssemble(self.handle, arch.handle)
+
def is_never_branch_patch_available(self, addr, arch=None):
"""
``is_never_branch_patch_available`` queries the architecture plugin to determine if the instruction at the
diff --git a/ui/linearview.h b/ui/linearview.h
index 3f152f9c..f792d921 100644
--- a/ui/linearview.h
+++ b/ui/linearview.h
@@ -9,6 +9,8 @@
#include "menus.h"
#include "statusbarwidget.h"
#include "uicontext.h"
+#include "instructionedit.h"
+#include <assembledialog.h>
#define LINEAR_VIEW_UPDATE_CHECK_INTERVAL 200
#define MAX_STRING_TYPE_LENGTH 1048576
@@ -123,6 +125,8 @@ class BINARYNINJAUIAPI LinearView: public QAbstractScrollArea, public View, publ
DisassemblySettingsRef m_options;
BNFunctionGraphType m_type;
+ InstructionEdit* m_instrEdit;
+
BinaryNinja::Ref<BinaryNinja::LinearViewCursor> m_topPosition, m_bottomPosition;
std::vector<LinearViewLine> m_lines;
size_t m_topLine;
@@ -255,6 +259,9 @@ private Q_SLOTS:
void setStackAdjustment();
void setCallTypeAdjustment();
+ void editInstruction();
+ void instrEditDoneEvent();
+
Q_SIGNALS:
void notifyResizeEvent(int width, int height);
diff --git a/ui/viewframe.h b/ui/viewframe.h
index 4d367074..b54ec8c0 100644
--- a/ui/viewframe.h
+++ b/ui/viewframe.h
@@ -258,6 +258,8 @@ public:
static void registerActions();
static ViewFrame* viewFrameForWidget(QWidget* widget);
+ static bool lineHasInstructionToken(const BinaryNinja::DisassemblyTextLine& line);
+ static QString getDisassemblyText(const std::vector<BinaryNinja::DisassemblyTextLine>& lines);
public Q_SLOTS:
virtual void assemble();