summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2016-07-15 21:15:37 -0400
committerRusty Wagner <rusty@vector35.com>2016-07-15 21:15:37 -0400
commit2c2f521aa188d4f8027c5db8dfaf88f670d8a63f (patch)
treef736704102bc0f1f779a7ab34714baf465a66042
parent8fcc840c79174728ef96afa0ff37713e74311d51 (diff)
Add API for instruction length and option for showing opcodes in disassembly
-rw-r--r--architecture.cpp43
-rw-r--r--binaryninjaapi.h7
-rw-r--r--binaryninjacore.h11
-rw-r--r--python/__init__.py20
-rw-r--r--python/examples/nes.py1
5 files changed, 81 insertions, 1 deletions
diff --git a/architecture.cpp b/architecture.cpp
index accfa69f..d068ff36 100644
--- a/architecture.cpp
+++ b/architecture.cpp
@@ -97,6 +97,20 @@ size_t Architecture::GetDefaultIntegerSizeCallback(void* ctxt)
}
+size_t Architecture::GetMaxInstructionLengthCallback(void* ctxt)
+{
+ Architecture* arch = (Architecture*)ctxt;
+ return arch->GetMaxInstructionLength();
+}
+
+
+size_t Architecture::GetOpcodeDisplayLengthCallback(void* ctxt)
+{
+ Architecture* arch = (Architecture*)ctxt;
+ return arch->GetOpcodeDisplayLength();
+}
+
+
bool Architecture::GetInstructionInfoCallback(void* ctxt, const uint8_t* data, uint64_t addr,
size_t maxLen, BNInstructionInfo* result)
{
@@ -390,6 +404,8 @@ void Architecture::Register(Architecture* arch)
callbacks.getEndianness = GetEndiannessCallback;
callbacks.getAddressSize = GetAddressSizeCallback;
callbacks.getDefaultIntegerSize = GetDefaultIntegerSizeCallback;
+ callbacks.getMaxInstructionLength = GetMaxInstructionLengthCallback;
+ callbacks.getOpcodeDisplayLength = GetOpcodeDisplayLengthCallback;
callbacks.getInstructionInfo = GetInstructionInfoCallback;
callbacks.getInstructionText = GetInstructionTextCallback;
callbacks.freeInstructionText = FreeInstructionTextCallback;
@@ -466,6 +482,21 @@ size_t Architecture::GetDefaultIntegerSize() const
}
+size_t Architecture::GetMaxInstructionLength() const
+{
+ return BN_DEFAULT_NSTRUCTION_LENGTH;
+}
+
+
+size_t Architecture::GetOpcodeDisplayLength() const
+{
+ size_t maxLen = GetMaxInstructionLength();
+ if (maxLen < BN_DEFAULT_OPCODE_DISPLAY)
+ return maxLen;
+ return BN_DEFAULT_OPCODE_DISPLAY;
+}
+
+
bool Architecture::GetInstructionLowLevelIL(const uint8_t*, uint64_t, size_t&, LowLevelILFunction& il)
{
il.AddInstruction(il.Undefined());
@@ -874,6 +905,18 @@ size_t CoreArchitecture::GetDefaultIntegerSize() const
}
+size_t CoreArchitecture::GetMaxInstructionLength() const
+{
+ return BNGetArchitectureMaxInstructionLength(m_object);
+}
+
+
+size_t CoreArchitecture::GetOpcodeDisplayLength() const
+{
+ return BNGetArchitectureOpcodeDisplayLength(m_object);
+}
+
+
bool CoreArchitecture::GetInstructionInfo(const uint8_t* data, uint64_t addr, size_t maxLen, InstructionInfo& result)
{
return BNGetInstructionInfo(m_object, data, addr, maxLen, &result);
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index fedd2bf0..18a379c3 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -1108,6 +1108,8 @@ namespace BinaryNinja
static BNEndianness GetEndiannessCallback(void* ctxt);
static size_t GetAddressSizeCallback(void* ctxt);
static size_t GetDefaultIntegerSizeCallback(void* ctxt);
+ static size_t GetMaxInstructionLengthCallback(void* ctxt);
+ static size_t GetOpcodeDisplayLengthCallback(void* ctxt);
static bool GetInstructionInfoCallback(void* ctxt, const uint8_t* data, uint64_t addr,
size_t maxLen, BNInstructionInfo* result);
static bool GetInstructionTextCallback(void* ctxt, const uint8_t* data, uint64_t addr,
@@ -1159,6 +1161,9 @@ namespace BinaryNinja
virtual size_t GetAddressSize() const = 0;
virtual size_t GetDefaultIntegerSize() const;
+ virtual size_t GetMaxInstructionLength() const;
+ virtual size_t GetOpcodeDisplayLength() const;
+
virtual bool GetInstructionInfo(const uint8_t* data, uint64_t addr, size_t maxLen, InstructionInfo& result) = 0;
virtual bool GetInstructionText(const uint8_t* data, uint64_t addr, size_t& len,
std::vector<InstructionTextToken>& result) = 0;
@@ -1300,6 +1305,8 @@ namespace BinaryNinja
virtual BNEndianness GetEndianness() const override;
virtual size_t GetAddressSize() const override;
virtual size_t GetDefaultIntegerSize() const override;
+ virtual size_t GetMaxInstructionLength() const override;
+ virtual size_t GetOpcodeDisplayLength() const override;
virtual bool GetInstructionInfo(const uint8_t* data, uint64_t addr, size_t maxLen, InstructionInfo& result) override;
virtual bool GetInstructionText(const uint8_t* data, uint64_t addr, size_t& len,
std::vector<InstructionTextToken>& result) override;
diff --git a/binaryninjacore.h b/binaryninjacore.h
index a257d0d0..ac9e9da9 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -45,7 +45,9 @@
#endif
#endif
-#define BN_MAX_INSTRUCTION_LENGTH 16
+#define BN_MAX_INSTRUCTION_LENGTH 256
+#define BN_DEFAULT_NSTRUCTION_LENGTH 16
+#define BN_DEFAULT_OPCODE_DISPLAY 8
#define BN_MAX_INSTRUCTION_BRANCHES 3
#define BN_MAX_STORED_DATA_LENGTH 0x3fffffff
@@ -168,6 +170,7 @@ extern "C"
HexDumpSkippedByteToken = 17,
HexDumpInvalidByteToken = 18,
HexDumpTextToken = 19,
+ OpcodeToken = 20,
// The following are output by the analysis system automatically, these should
// not be used directly by the architecture plugins
@@ -322,6 +325,8 @@ extern "C"
enum BNDisassemblyOption
{
ShowAddress = 0,
+ ShowOpcode = 1,
+ ExpandLongOpcode = 2,
// Linear disassembly options
GroupLinearDisassemblyFunctions = 64,
@@ -672,6 +677,8 @@ extern "C"
BNEndianness (*getEndianness)(void* ctxt);
size_t (*getAddressSize)(void* ctxt);
size_t (*getDefaultIntegerSize)(void* ctxt);
+ size_t (*getMaxInstructionLength)(void* ctxt);
+ size_t (*getOpcodeDisplayLength)(void* ctxt);
bool (*getInstructionInfo)(void* ctxt, const uint8_t* data, uint64_t addr, size_t maxLen, BNInstructionInfo* result);
bool (*getInstructionText)(void* ctxt, const uint8_t* data, uint64_t addr, size_t* len,
BNInstructionTextToken** result, size_t* count);
@@ -1202,6 +1209,8 @@ extern "C"
BINARYNINJACOREAPI BNEndianness BNGetArchitectureEndianness(BNArchitecture* arch);
BINARYNINJACOREAPI size_t BNGetArchitectureAddressSize(BNArchitecture* arch);
BINARYNINJACOREAPI size_t BNGetArchitectureDefaultIntegerSize(BNArchitecture* arch);
+ BINARYNINJACOREAPI size_t BNGetArchitectureMaxInstructionLength(BNArchitecture* arch);
+ BINARYNINJACOREAPI size_t BNGetArchitectureOpcodeDisplayLength(BNArchitecture* arch);
BINARYNINJACOREAPI bool BNGetInstructionInfo(BNArchitecture* arch, const uint8_t* data, uint64_t addr,
size_t maxLen, BNInstructionInfo* result);
BINARYNINJACOREAPI bool BNGetInstructionText(BNArchitecture* arch, const uint8_t* data, uint64_t addr,
diff --git a/python/__init__.py b/python/__init__.py
index f2be8758..fb5bfa3c 100644
--- a/python/__init__.py
+++ b/python/__init__.py
@@ -3261,6 +3261,8 @@ class Architecture(object):
endianness = core.LittleEndian
address_size = 8
default_int_size = 4
+ max_instr_length = 16
+ opcode_display_length = 8
regs = {}
stack_pointer = None
link_reg = None
@@ -3278,6 +3280,8 @@ class Architecture(object):
self.__dict__["endianness"] = core.BNEndianness_names[core.BNGetArchitectureEndianness(self.handle)]
self.__dict__["address_size"] = core.BNGetArchitectureAddressSize(self.handle)
self.__dict__["default_int_size"] = core.BNGetArchitectureDefaultIntegerSize(self.handle)
+ self.__dict__["max_instr_length"] = core.BNGetArchitectureMaxInstructionLength(self.handle)
+ self.__dict__["opcode_display_length"] = core.BNGetArchitectureOpcodeDisplayLength(self.handle)
self.__dict__["stack_pointer"] = core.BNGetArchitectureRegisterName(self.handle,
core.BNGetArchitectureStackPointerRegister(self.handle))
self.__dict__["link_reg"] = core.BNGetArchitectureRegisterName(self.handle,
@@ -3361,6 +3365,8 @@ class Architecture(object):
self._cb.getEndianness = self._cb.getEndianness.__class__(self._get_endianness)
self._cb.getAddressSize = self._cb.getAddressSize.__class__(self._get_address_size)
self._cb.getDefaultIntegerSize = self._cb.getDefaultIntegerSize.__class__(self._get_default_integer_size)
+ self._cb.getMaxInstructionLength = self._cb.getMaxInstructionLength.__class__(self._get_max_instruction_length)
+ self._cb.getOpcodeDisplayLength = self._cb.getOpcodeDisplayLength.__class__(self._get_opcode_display_length)
self._cb.getInstructionInfo = self._cb.getInstructionInfo.__class__(self._get_instruction_info)
self._cb.getInstructionText = self._cb.getInstructionText.__class__(self._get_instruction_text)
self._cb.freeInstructionText = self._cb.freeInstructionText.__class__(self._free_instruction_text)
@@ -3536,6 +3542,20 @@ class Architecture(object):
log_error(traceback.format_exc())
return 4
+ def _get_max_instruction_length(self, ctxt):
+ try:
+ return self.__class__.max_instr_length
+ except:
+ log_error(traceback.format_exc())
+ return 16
+
+ def _get_opcode_display_length(self, ctxt):
+ try:
+ return self.__class__.opcode_display_length
+ except:
+ log_error(traceback.format_exc())
+ return 8
+
def _get_instruction_info(self, ctxt, data, addr, max_len, result):
try:
buf = ctypes.create_string_buffer(max_len)
diff --git a/python/examples/nes.py b/python/examples/nes.py
index 21b02dfa..5cb6bc0d 100644
--- a/python/examples/nes.py
+++ b/python/examples/nes.py
@@ -349,6 +349,7 @@ class M6502(Architecture):
name = "6502"
address_size = 2
default_int_size = 1
+ max_instr_length = 3
regs = {
"a": RegisterInfo("a", 1),
"x": RegisterInfo("x", 1),