summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter LaFosse <peter@vector35.com>2018-01-09 16:47:47 -0500
committerPeter LaFosse <peter@vector35.com>2018-01-09 16:47:47 -0500
commit6ef9dd016c957e796f89f94f00c6d71e2f7589e8 (patch)
tree5ab4ab48cf8f47c4e5325f3b3ae4cf9e5e8d5194
parent16a4d413d58d2cb29be97781bba0b52546afa390 (diff)
parent26edabfdd7211012c7c8a03186d3025eea9aa345 (diff)
Merge branch 'dev'
-rw-r--r--architecture.cpp21
-rw-r--r--binaryninjaapi.cpp18
-rw-r--r--binaryninjaapi.h13
-rw-r--r--binaryninjacore.h10
-rw-r--r--binaryview.cpp21
-rw-r--r--docs/getting-started.md2
-rw-r--r--docs/guide/troubleshooting.md16
-rw-r--r--examples/cmdline_disasm/Makefile51
-rw-r--r--examples/cmdline_disasm/src/disasm.cpp152
m---------examples/x86_extension/src/asmx860
-rw-r--r--examples/x86_extension/src/x86_extension.cpp107
-rw-r--r--functionrecognizer.cpp18
-rw-r--r--interaction.cpp2
-rw-r--r--lowlevelilinstruction.h8
-rw-r--r--mediumlevelilinstruction.h5
-rw-r--r--python/architecture.py15
-rw-r--r--python/basicblock.py8
-rw-r--r--python/binaryview.py43
-rw-r--r--python/examples/nes.py1
-rw-r--r--python/function.py31
-rw-r--r--python/functionrecognizer.py15
-rw-r--r--python/pluginmanager.py1
-rw-r--r--python/scriptingprovider.py17
-rwxr-xr-xscripts/linux-setup.sh39
24 files changed, 554 insertions, 60 deletions
diff --git a/architecture.cpp b/architecture.cpp
index eb588394..66372bcb 100644
--- a/architecture.cpp
+++ b/architecture.cpp
@@ -30,6 +30,7 @@ using namespace std;
InstructionInfo::InstructionInfo()
{
length = 0;
+ archTransitionByTargetAddr = false;
branchCount = 0;
branchDelay = false;
}
@@ -111,6 +112,13 @@ size_t Architecture::GetDefaultIntegerSizeCallback(void* ctxt)
}
+size_t Architecture::GetInstructionAlignmentCallback(void* ctxt)
+{
+ Architecture* arch = (Architecture*)ctxt;
+ return arch->GetInstructionAlignment();
+}
+
+
size_t Architecture::GetMaxInstructionLengthCallback(void* ctxt)
{
Architecture* arch = (Architecture*)ctxt;
@@ -443,6 +451,7 @@ void Architecture::Register(Architecture* arch)
callbacks.getEndianness = GetEndiannessCallback;
callbacks.getAddressSize = GetAddressSizeCallback;
callbacks.getDefaultIntegerSize = GetDefaultIntegerSizeCallback;
+ callbacks.getInstructionAlignment = GetInstructionAlignmentCallback;
callbacks.getMaxInstructionLength = GetMaxInstructionLengthCallback;
callbacks.getOpcodeDisplayLength = GetOpcodeDisplayLengthCallback;
callbacks.getAssociatedArchitectureByAddress = GetAssociatedArchitectureByAddressCallback;
@@ -523,6 +532,12 @@ size_t Architecture::GetDefaultIntegerSize() const
}
+size_t Architecture::GetInstructionAlignment() const
+{
+ return 1;
+}
+
+
size_t Architecture::GetMaxInstructionLength() const
{
return BN_DEFAULT_NSTRUCTION_LENGTH;
@@ -905,6 +920,12 @@ size_t CoreArchitecture::GetDefaultIntegerSize() const
}
+size_t CoreArchitecture::GetInstructionAlignment() const
+{
+ return BNGetArchitectureInstructionAlignment(m_object);
+}
+
+
size_t CoreArchitecture::GetMaxInstructionLength() const
{
return BNGetArchitectureMaxInstructionLength(m_object);
diff --git a/binaryninjaapi.cpp b/binaryninjaapi.cpp
index b774cf2b..f5eede03 100644
--- a/binaryninjaapi.cpp
+++ b/binaryninjaapi.cpp
@@ -344,3 +344,21 @@ string BinaryNinja::GetUniqueIdentifierString()
BNFreeString(str);
return result;
}
+
+
+string BinaryNinja::GetLinuxCADirectory()
+{
+ char* str = BNGetLinuxCADirectory();
+ string result = str;
+ BNFreeString(str);
+ return result;
+}
+
+
+string BinaryNinja::GetLinuxCABundlePath()
+{
+ char* str = BNGetLinuxCABundlePath();
+ string result = str;
+ BNFreeString(str);
+ return result;
+}
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index a6276b00..72f74c5a 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -1027,6 +1027,7 @@ namespace BinaryNinja
uint64_t start, length;
uint64_t dataOffset, dataLength;
uint32_t flags;
+ bool autoDefined;
};
struct Section
@@ -1037,6 +1038,7 @@ namespace BinaryNinja
uint64_t infoData;
uint64_t align, entrySize;
BNSectionSemantics semantics;
+ bool autoDefined;
};
struct QualifiedNameAndType;
@@ -1088,6 +1090,7 @@ namespace BinaryNinja
virtual uint64_t PerformGetEntryPoint() const { return 0; }
virtual bool PerformIsExecutable() const { return false; }
virtual BNEndianness PerformGetDefaultEndianness() const;
+ virtual bool PerformIsRelocatable() const;
virtual size_t PerformGetAddressSize() const;
virtual bool PerformSave(FileAccessor* file);
@@ -1115,6 +1118,7 @@ namespace BinaryNinja
static uint64_t GetEntryPointCallback(void* ctxt);
static bool IsExecutableCallback(void* ctxt);
static BNEndianness GetDefaultEndiannessCallback(void* ctxt);
+ static bool IsRelocatableCallback(void* ctxt);
static size_t GetAddressSizeCallback(void* ctxt);
static bool SaveCallback(void* ctxt, BNFileAccessor* file);
@@ -1181,6 +1185,7 @@ namespace BinaryNinja
void SetDefaultPlatform(Platform* platform);
BNEndianness GetDefaultEndianness() const;
+ bool IsRelocatable() const;
size_t GetAddressSize() const;
bool IsExecutable() const;
@@ -1582,6 +1587,7 @@ namespace BinaryNinja
static BNEndianness GetEndiannessCallback(void* ctxt);
static size_t GetAddressSizeCallback(void* ctxt);
static size_t GetDefaultIntegerSizeCallback(void* ctxt);
+ static size_t GetInstructionAlignmentCallback(void* ctxt);
static size_t GetMaxInstructionLengthCallback(void* ctxt);
static size_t GetOpcodeDisplayLengthCallback(void* ctxt);
static BNArchitecture* GetAssociatedArchitectureByAddressCallback(void* ctxt, uint64_t* addr);
@@ -1637,6 +1643,7 @@ namespace BinaryNinja
virtual size_t GetAddressSize() const = 0;
virtual size_t GetDefaultIntegerSize() const;
+ virtual size_t GetInstructionAlignment() const;
virtual size_t GetMaxInstructionLength() const;
virtual size_t GetOpcodeDisplayLength() const;
@@ -1777,6 +1784,7 @@ namespace BinaryNinja
virtual BNEndianness GetEndianness() const override;
virtual size_t GetAddressSize() const override;
virtual size_t GetDefaultIntegerSize() const override;
+ virtual size_t GetInstructionAlignment() const override;
virtual size_t GetMaxInstructionLength() const override;
virtual size_t GetOpcodeDisplayLength() const override;
virtual Ref<Architecture> GetAssociatedArchitectureByAddress(uint64_t& addr) override;
@@ -2945,6 +2953,7 @@ namespace BinaryNinja
class FunctionRecognizer
{
static bool RecognizeLowLevelILCallback(void* ctxt, BNBinaryView* data, BNFunction* func, BNLowLevelILFunction* il);
+ static bool RecognizeMediumLevelILCallback(void* ctxt, BNBinaryView* data, BNFunction* func, BNMediumLevelILFunction* il);
public:
FunctionRecognizer();
@@ -2953,6 +2962,7 @@ namespace BinaryNinja
static void RegisterArchitectureFunctionRecognizer(Architecture* arch, FunctionRecognizer* recog);
virtual bool RecognizeLowLevelIL(BinaryView* data, Function* func, LowLevelILFunction* il);
+ virtual bool RecognizeMediumLevelIL(BinaryView* data, Function* func, MediumLevelILFunction* il);
};
class UpdateException: public std::exception
@@ -3575,4 +3585,7 @@ namespace BinaryNinja
bool IsArray() const;
bool IsKeyValueStore() const;
};
+
+ std::string GetLinuxCADirectory();
+ std::string GetLinuxCABundlePath();
}
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 870c2de3..245e6353 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -935,6 +935,7 @@ extern "C"
uint64_t (*getEntryPoint)(void* ctxt);
bool (*isExecutable)(void* ctxt);
BNEndianness (*getDefaultEndianness)(void* ctxt);
+ bool (*isRelocatable)(void* ctxt);
size_t (*getAddressSize)(void* ctxt);
bool (*save)(void* ctxt, BNFileAccessor* accessor);
};
@@ -972,6 +973,7 @@ extern "C"
{
size_t length;
size_t branchCount;
+ bool archTransitionByTargetAddr;
bool branchDelay;
BNBranchType branchType[BN_MAX_INSTRUCTION_BRANCHES];
uint64_t branchTarget[BN_MAX_INSTRUCTION_BRANCHES];
@@ -1002,6 +1004,7 @@ extern "C"
BNEndianness (*getEndianness)(void* ctxt);
size_t (*getAddressSize)(void* ctxt);
size_t (*getDefaultIntegerSize)(void* ctxt);
+ size_t (*getInstructionAlignment)(void* ctxt);
size_t (*getMaxInstructionLength)(void* ctxt);
size_t (*getOpcodeDisplayLength)(void* ctxt);
BNArchitecture* (*getAssociatedArchitectureByAddress)(void* ctxt, uint64_t* addr);
@@ -1189,6 +1192,7 @@ extern "C"
{
void* context;
bool (*recognizeLowLevelIL)(void* ctxt, BNBinaryView* data, BNFunction* func, BNLowLevelILFunction* il);
+ bool (*recognizeMediumLevelIL)(void* ctxt, BNBinaryView* data, BNFunction* func, BNMediumLevelILFunction* il);
};
struct BNTypeParserResult
@@ -1527,6 +1531,7 @@ extern "C"
uint64_t start, length;
uint64_t dataOffset, dataLength;
uint32_t flags;
+ bool autoDefined;
};
enum BNSectionSemantics
@@ -1547,6 +1552,7 @@ extern "C"
uint64_t infoData;
uint64_t align, entrySize;
BNSectionSemantics semantics;
+ bool autoDefined;
};
struct BNAddressRange
@@ -1777,6 +1783,7 @@ extern "C"
BINARYNINJACOREAPI BNPlatform* BNGetDefaultPlatform(BNBinaryView* view);
BINARYNINJACOREAPI void BNSetDefaultPlatform(BNBinaryView* view, BNPlatform* platform);
BINARYNINJACOREAPI BNEndianness BNGetDefaultEndianness(BNBinaryView* view);
+ BINARYNINJACOREAPI bool BNIsRelocatable(BNBinaryView* view);
BINARYNINJACOREAPI size_t BNGetViewAddressSize(BNBinaryView* view);
BINARYNINJACOREAPI bool BNIsViewModified(BNBinaryView* view);
@@ -1944,6 +1951,7 @@ extern "C"
BINARYNINJACOREAPI BNEndianness BNGetArchitectureEndianness(BNArchitecture* arch);
BINARYNINJACOREAPI size_t BNGetArchitectureAddressSize(BNArchitecture* arch);
BINARYNINJACOREAPI size_t BNGetArchitectureDefaultIntegerSize(BNArchitecture* arch);
+ BINARYNINJACOREAPI size_t BNGetArchitectureInstructionAlignment(BNArchitecture* arch);
BINARYNINJACOREAPI size_t BNGetArchitectureMaxInstructionLength(BNArchitecture* arch);
BINARYNINJACOREAPI size_t BNGetArchitectureOpcodeDisplayLength(BNArchitecture* arch);
BINARYNINJACOREAPI BNArchitecture* BNGetAssociatedArchitectureByAddress(BNArchitecture* arch, uint64_t* addr);
@@ -3181,6 +3189,8 @@ extern "C"
BINARYNINJACOREAPI BNMetadata* BNBinaryViewQueryMetadata(BNBinaryView* view, const char* key);
BINARYNINJACOREAPI void BNBinaryViewRemoveMetadata(BNBinaryView* view, const char* key);
+ BINARYNINJACOREAPI char* BNGetLinuxCADirectory();
+ BINARYNINJACOREAPI char* BNGetLinuxCABundlePath();
#ifdef __cplusplus
}
#endif
diff --git a/binaryview.cpp b/binaryview.cpp
index 213be79a..50011a0f 100644
--- a/binaryview.cpp
+++ b/binaryview.cpp
@@ -288,6 +288,7 @@ BinaryView::BinaryView(const std::string& typeName, FileMetadata* file, BinaryVi
view.getEntryPoint = GetEntryPointCallback;
view.isExecutable = IsExecutableCallback;
view.getDefaultEndianness = GetDefaultEndiannessCallback;
+ view.isRelocatable = IsRelocatableCallback;
view.getAddressSize = GetAddressSizeCallback;
view.save = SaveCallback;
@@ -431,6 +432,13 @@ BNEndianness BinaryView::GetDefaultEndiannessCallback(void* ctxt)
}
+bool BinaryView::IsRelocatableCallback(void* ctxt)
+{
+ BinaryView* view = (BinaryView*)ctxt;
+ return view->PerformIsRelocatable();
+}
+
+
size_t BinaryView::GetAddressSizeCallback(void* ctxt)
{
BinaryView* view = (BinaryView*)ctxt;
@@ -494,6 +502,11 @@ BNEndianness BinaryView::PerformGetDefaultEndianness() const
}
+bool BinaryView::PerformIsRelocatable() const
+{
+ return false;
+}
+
size_t BinaryView::PerformGetAddressSize() const
{
Ref<Architecture> arch = GetDefaultArchitecture();
@@ -836,6 +849,12 @@ BNEndianness BinaryView::GetDefaultEndianness() const
}
+bool BinaryView::IsRelocatable() const
+{
+ return BNIsRelocatable(m_object);
+}
+
+
size_t BinaryView::GetAddressSize() const
{
return BNGetViewAddressSize(m_object);
@@ -1705,6 +1724,7 @@ vector<Segment> BinaryView::GetSegments()
segment.dataOffset = segments[i].dataOffset;
segment.dataLength = segments[i].dataLength;
segment.flags = segments[i].flags;
+ segment.autoDefined = segments[i].autoDefined;
result.push_back(segment);
}
@@ -1712,7 +1732,6 @@ vector<Segment> BinaryView::GetSegments()
return result;
}
-
bool BinaryView::GetSegmentAt(uint64_t addr, Segment& result)
{
BNSegment segment;
diff --git a/docs/getting-started.md b/docs/getting-started.md
index 39809747..88945f7b 100644
--- a/docs/getting-started.md
+++ b/docs/getting-started.md
@@ -255,6 +255,8 @@ Settings are stored in the _user_ directory in the file `settings.json`. Each to
|Plugin | Setting | Type | Default | Description |
|------:|-------------------------:|-------------:|-----------------------------------------------:|:----------------------------------------------------------------------------------------------|
+| core | linux\_ca\_bundle | string | "" | Certificate authority (.pem or .crt) file to be used for secure downloads |
+| core | linux\_ca\_dir | string | "" | Certificate authority directory (for distributions without a CA bundle) |
| ui | activeContent | boolean | True | Allow Binary Ninja to connect to the web to check for updates |
| ui | colorblind | boolean | True | Choose colors that are visible to those with red/green colorblind |
| ui | debug | boolean | False | Enable developer debugging features (Additional views: Lifted IL, and SSA forms) |
diff --git a/docs/guide/troubleshooting.md b/docs/guide/troubleshooting.md
index c1b3a910..5e310dfb 100644
--- a/docs/guide/troubleshooting.md
+++ b/docs/guide/troubleshooting.md
@@ -36,6 +36,16 @@ Next, if running a python plugin, make sure the python requirements are met by y
- If experiencing problems with Windows UAC permissions during an update, the easiest fix is to completely un-install and [recover][recover] the latest installer and license. Preferences are saved outside the installation folder and are preserved, though you might want to remove your [license](/getting-started/#license).
- If you need to change the email address on your license, contact [support].
+## OS X
+
+While OS X is generally the most trouble-free environment for Binary Ninja, very old versions may have problems with the RPATH for our binaries and libraries. There are two solutions. First, run Binary Ninja with:
+
+```
+DYLD_LIBRARY_PATH="/Applications/Binary Ninja.app/Contents/MacOS" /Applications/Binary\ Ninja.app/Contents/MacOS/binaryninja
+```
+
+Or second, modify the binary itself using the [install_name_tool](https://blogs.oracle.com/dipol/dynamic-libraries,-rpath,-and-mac-os).
+
## Linux
Given the diversity of Linux distributions, some work-arounds are required to run Binary Ninja on platforms that are not [officially supported][faq].
@@ -67,9 +77,9 @@ QT_PLUGIN_PATH=./qt ./binaryninja
For Debian variants that (Kali, eg) don't match packages with Ubuntu LTS or the latest stable, the following might fix problems with libssl and libcrypto:
```
-$ cd binaryninja/plugins
-$ ln -s libssl.so libssl.so.1.0.0
-$ ln -s libcrypto.so libcrypto.so.1.0.0
+$ cd binaryninja
+$ ln -s plugins/libssl.so libssl.so.1.0.0
+$ ln -s plugins/libcrypto.so libcrypto.so.1.0.0
```
Alternatively, you might need to (as root):
diff --git a/examples/cmdline_disasm/Makefile b/examples/cmdline_disasm/Makefile
new file mode 100644
index 00000000..12931876
--- /dev/null
+++ b/examples/cmdline_disasm/Makefile
@@ -0,0 +1,51 @@
+# Path to prebuilt libbinaryninjaapi.a
+BINJA_API_A := ../../bin/libbinaryninjaapi.a
+
+# Path to binaryninjaapi.h and json
+INC := -I../../
+
+UNAME_S := $(shell uname -s)
+ifeq ($(UNAME_S),Linux)
+ # Path to binaryninja install
+ BINJAPATH := $(HOME)/binaryninja/
+ CC := gcc
+else
+ BINJAPATH := /Applications/Binary\ Ninja.app/Contents/MacOS
+ CC := clang
+endif
+
+SRCDIR := src
+BUILDDIR := build
+TARGETDIR := bin
+
+TARGETNAME := disasm
+TARGET := $(TARGETDIR)/$(TARGETNAME)
+
+SRCEXT := cpp
+SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
+OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))
+
+LIBS := -L $(BINJAPATH) -lbinaryninjacore
+CPPFLAGS := -c -O2 -Wall -W -fPIC --std=c++11 -pipe
+
+all: $(TARGET)
+
+ifeq ($(UNAME_S),Linux)
+$(TARGET): $(OBJECTS)
+ @mkdir -p $(TARGETDIR)
+ $(CC) $^ $(BINJA_API_A) $(LIBS) -Wl,-rpath=$(BINJAPATH) -ldl -o $@
+else
+$(TARGET): $(OBJECTS)
+ @mkdir -p $(TARGETDIR)
+ $(CC) $^ $(BINJA_API_A) $(LIBS) -o $@
+ install_name_tool -change @rpath/libbinaryninjacore.dylib $(BINJAPATH)/libbinaryninjacore.dylib $@
+endif
+
+$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
+ @mkdir -p $(BUILDDIR)
+ $(CC) $(CPPFLAGS) $(INC) -c -o $@ $<
+
+clean:
+ $(RM) -r $(BUILDDIR) $(TARGETDIR)
+
+.PHONY: clean
diff --git a/examples/cmdline_disasm/src/disasm.cpp b/examples/cmdline_disasm/src/disasm.cpp
new file mode 100644
index 00000000..c763fc11
--- /dev/null
+++ b/examples/cmdline_disasm/src/disasm.cpp
@@ -0,0 +1,152 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "binaryninjacore.h"
+#include "binaryninjaapi.h"
+
+using namespace BinaryNinja;
+
+/* forward declarations */
+int parse_nib(const char *str, uint8_t *val);
+int parse_uint8_hex(const char *str, uint8_t *result);
+
+/******************************************************************************
+ MAIN
+******************************************************************************/
+
+void usage(int ac, char **av)
+{
+ (void)ac;
+ printf(" syntax: %s <arch+mode> <byte0> <byte1> ...\n", av[0]);
+ printf("examples:\n");
+ printf(" %s x86 83 83 ec 0c\n", av[0]);
+ printf(" %s x86_64 48 89 e5\n", av[0]);
+ printf(" %s armv7 14 d0 4d e2\n", av[0]);
+ printf(" %s armv7eb d0 14 e2 4d\n", av[0]);
+ printf(" %s thumb2 4f f0 00 0c\n", av[0]);
+ printf(" %s thumb2eb f0 4f 0c 00\n", av[0]);
+ printf(" %s ppc 93 e1 ff fc\n", av[0]);
+ printf(" %s aarch64 ff 43 00 d1\n", av[0]);
+ printf(" %s mips32 27 bd ff f0\n", av[0]);
+ printf(" %s mipsel32 f0 ff bd 27\n", av[0]);
+}
+
+int main(int ac, char **av)
+{
+ int rc = -1;
+ unsigned int i;
+
+ char *archmode;
+ BNArchitecture *arch;
+
+ size_t nBytesDisasm;
+
+ uint8_t input[64];
+ unsigned int input_n;
+
+ BNInstructionTextToken *ttResult = NULL;
+ size_t ttCount;
+
+ char *path_bundled_plugins;
+
+ /* plugin path */
+ path_bundled_plugins = BNGetBundledPluginDirectory();
+ printf("using bundled plugin path: %s\n", path_bundled_plugins);
+ BNSetBundledPluginDirectory(path_bundled_plugins);
+ BNInitCorePlugins();
+
+ /* parse architecture argument */
+ if(ac < 2)
+ { usage(ac, av); goto cleanup; }
+ archmode = av[1];
+
+ printf("looking up architecture \"%s\"\n", archmode);
+ arch = BNGetArchitectureByName(archmode);
+ if(!arch) {
+ printf("ERROR: BNGetArchitectureByName() (is \"%s\" valid?)\n", archmode);
+ usage(ac, av);
+ goto cleanup;
+ }
+
+ /* parse bytes argument */
+ input_n = ac - 2;
+ for(i=0; i<input_n && i<sizeof(input); ++i) {
+ if(parse_uint8_hex(av[i+2], input+i)) {
+ printf("ERROR: can't parse byte: %s\n", av[i+2]);
+ goto cleanup;
+ }
+ }
+
+ printf("parsed bytes: ");
+ for(i=0; i<input_n; ++i)
+ printf("%02X ", input[i]);
+ printf("\n");
+
+ /* actually disassemble now */
+ nBytesDisasm = input_n;
+ BNGetInstructionText(arch, (const uint8_t *)input, 0, &nBytesDisasm,
+ &ttResult, &ttCount);
+
+ //printf("%zu text tokens\n", ttCount);
+
+ for(i=0; i<ttCount; ++i)
+ printf("%s", ttResult[i].text);
+ printf("\n");
+
+ /* done! */
+ cleanup:
+ if(ttResult)
+ BNFreeInstructionText(ttResult, ttCount);
+ return rc;
+}
+
+/******************************************************************************
+ PARSING
+******************************************************************************/
+
+int parse_nib(const char *str, uint8_t *val)
+{
+ int rc = -1;
+ char c = *str;
+
+ if(c>='0' && c<='9') {
+ *val = c-'0';
+ rc = 0;
+ }
+ else if(c>='a' && c<='f') {
+ *val = 10 + (c-'a');
+ rc = 0;
+ }
+ else if(c>='A' && c<='F') {
+ *val = 10 + (c-'A');
+ rc = 0;
+ }
+ else {
+ printf("ERROR: %s('%c', ...)\n", __func__, c);
+ }
+
+ return rc;
+}
+
+int parse_uint8_hex(const char *str, uint8_t *result)
+{
+ int rc=-1;
+ uint8_t v1, v2;
+
+ if(parse_nib(str, &v1))
+ goto cleanup;
+ if(parse_nib(str+1, &v2))
+ goto cleanup;
+
+ *result = (v1 << 4) | v2;
+ rc = 0;
+
+ cleanup:
+ return rc;
+}
+
diff --git a/examples/x86_extension/src/asmx86 b/examples/x86_extension/src/asmx86
-Subproject f78096d79ccfcc5169b6e2ae0fa89e3eed5b85c
+Subproject 9a1bf01f4c456779544a445db45b1496c50ff37
diff --git a/examples/x86_extension/src/x86_extension.cpp b/examples/x86_extension/src/x86_extension.cpp
index 9efcc119..a2ba4c9c 100644
--- a/examples/x86_extension/src/x86_extension.cpp
+++ b/examples/x86_extension/src/x86_extension.cpp
@@ -306,6 +306,7 @@ static void Repeat(size_t addrSize,
}
}
+
// This is a wrapper for the x86 architecture. Its useful for extending and improving
// the existing core x86 architecture.
class x86ArchitectureExtension: public Architecture
@@ -327,6 +328,11 @@ public:
return LittleEndian;
}
+ virtual size_t GetInstructionAlignment() const override
+ {
+ return 1;
+ }
+
virtual bool GetInstructionInfo(const uint8_t* data, uint64_t addr, size_t maxLen, InstructionInfo& result) override
{
return m_arch->GetInstructionInfo(data, addr, maxLen, result);
@@ -345,8 +351,11 @@ public:
il.AddInstruction(il.Undefined());
return false;
}
- if (instr.operation == CPUID)
+
+ size_t addrSize = 4;
+ switch (instr.operation)
{
+ case CPUID:
// The default implementation of CPUID doesn't set registers to constant values
// Here we'll emulate a Intel(R) Core(TM) i5-6267U CPU @ 2.90GHz with _eax set to 1
il.AddInstruction(il.Register(4, REG_EAX)); // Reference the register so we know it is read
@@ -356,8 +365,96 @@ public:
il.AddInstruction(il.SetRegister(4, REG_EDX, il.Const(4, 0xbfebfbff)));
len = instr.length;
return true;
+
+ case JMP:
+ if (instr.operands[0].operand == IMM)
+ il.AddInstruction(DirectJump(this, il, instr.operands[0].immediate, addrSize));
+ else
+ il.AddInstruction(il.Jump(ReadILOperand(il, instr, 0, addrSize, true)));
+ return false;
+
+ case JO:
+ ConditionalJump(this, il, il.FlagCondition(LLFC_O), addrSize, instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JNO:
+ ConditionalJump(this, il, il.FlagCondition(LLFC_NO), addrSize, instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JB:
+ ConditionalJump(this, il, il.FlagCondition(LLFC_ULT), addrSize, instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JAE:
+ ConditionalJump(this, il, il.FlagCondition(LLFC_UGE), addrSize, instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JE:
+ ConditionalJump(this, il, il.FlagCondition(LLFC_E), addrSize, instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JNE:
+ ConditionalJump(this, il, il.FlagCondition(LLFC_NE), addrSize, instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JBE:
+ ConditionalJump(this, il, il.FlagCondition(LLFC_ULE), addrSize, instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JA:
+ ConditionalJump(this, il, il.FlagCondition(LLFC_UGT), addrSize, instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JS:
+ ConditionalJump(this, il, il.FlagCondition(LLFC_NEG), addrSize, instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JNS:
+ ConditionalJump(this, il, il.FlagCondition(LLFC_POS), addrSize, instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JPE:
+ ConditionalJump(this, il, il.Not(0, il.Flag(IL_FLAG_P)), addrSize, instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JPO:
+ ConditionalJump(this, il, il.Flag(IL_FLAG_P), addrSize, instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JL:
+ ConditionalJump(this, il, il.FlagCondition(LLFC_SLT), addrSize, instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JGE:
+ ConditionalJump(this, il, il.FlagCondition(LLFC_SGE), addrSize, instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JLE:
+ ConditionalJump(this, il, il.FlagCondition(LLFC_SLE), addrSize, instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JG:
+ ConditionalJump(this, il, il.FlagCondition(LLFC_SGT), addrSize, instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JCXZ:
+ ConditionalJump(this, il, il.CompareEqual(2, il.Register(2, REG_CX), il.Const(2, 0)), addrSize,
+ instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JECXZ:
+ ConditionalJump(this, il, il.CompareEqual(4, il.Register(4, REG_ECX), il.Const(4, 0)), addrSize,
+ instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ case JRCXZ:
+ ConditionalJump(this, il, il.CompareEqual(8, il.Register(8, REG_RCX), il.Const(8, 0)), addrSize,
+ instr.operands[0].immediate, addr + instr.length);
+ return false;
+
+ default:
+ return m_arch->GetInstructionLowLevelIL(data, addr, len, il);
}
- return m_arch->GetInstructionLowLevelIL(data, addr, len, il);
}
virtual size_t GetFlagWriteLowLevelIL(BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,
@@ -485,6 +582,12 @@ public:
extern "C"
{
+ BINARYNINJAPLUGIN void CorePluginDependencies()
+ {
+ // Make sure we load after the original x86 plugin loads
+ SetCurrentPluginLoadOrder(LatePluginLoadOrder);
+ }
+
BINARYNINJAPLUGIN bool CorePluginInit()
{
Architecture* x86ext = new x86ArchitectureExtension();
diff --git a/functionrecognizer.cpp b/functionrecognizer.cpp
index 32c7245c..34f1db80 100644
--- a/functionrecognizer.cpp
+++ b/functionrecognizer.cpp
@@ -38,11 +38,22 @@ bool FunctionRecognizer::RecognizeLowLevelILCallback(void* ctxt, BNBinaryView* d
}
+bool FunctionRecognizer::RecognizeMediumLevelILCallback(void* ctxt, BNBinaryView* data, BNFunction* func, BNMediumLevelILFunction* il)
+{
+ FunctionRecognizer* recog = (FunctionRecognizer*)ctxt;
+ Ref<BinaryView> dataObj = new BinaryView(BNNewViewReference(data));
+ Ref<Function> funcObj = new Function(BNNewFunctionReference(func));
+ Ref<MediumLevelILFunction> ilObj = new MediumLevelILFunction(BNNewMediumLevelILFunctionReference(il));
+ return recog->RecognizeMediumLevelIL(dataObj, funcObj, ilObj);
+}
+
+
void FunctionRecognizer::RegisterGlobalRecognizer(FunctionRecognizer* recog)
{
BNFunctionRecognizer reg;
reg.context = recog;
reg.recognizeLowLevelIL = RecognizeLowLevelILCallback;
+ reg.recognizeMediumLevelIL = RecognizeMediumLevelILCallback;
BNRegisterGlobalFunctionRecognizer(&reg);
}
@@ -52,6 +63,7 @@ void FunctionRecognizer::RegisterArchitectureFunctionRecognizer(Architecture* ar
BNFunctionRecognizer reg;
reg.context = recog;
reg.recognizeLowLevelIL = RecognizeLowLevelILCallback;
+ reg.recognizeMediumLevelIL = RecognizeMediumLevelILCallback;
BNRegisterArchitectureFunctionRecognizer(arch->GetObject(), &reg);
}
@@ -60,3 +72,9 @@ bool FunctionRecognizer::RecognizeLowLevelIL(BinaryView*, Function*, LowLevelILF
{
return false;
}
+
+
+bool FunctionRecognizer::RecognizeMediumLevelIL(BinaryView*, Function*, MediumLevelILFunction*)
+{
+ return false;
+}
diff --git a/interaction.cpp b/interaction.cpp
index fb4eb6d4..2f84c4ec 100644
--- a/interaction.cpp
+++ b/interaction.cpp
@@ -119,8 +119,6 @@ void InteractionHandler::ShowHTMLReport(Ref<BinaryView> view, const string& titl
bool InteractionHandler::GetIntegerInput(int64_t& result, const string& prompt, const string& title)
{
- string input;
-
while (true)
{
string input;
diff --git a/lowlevelilinstruction.h b/lowlevelilinstruction.h
index b2849d44..169c7a60 100644
--- a/lowlevelilinstruction.h
+++ b/lowlevelilinstruction.h
@@ -158,10 +158,10 @@ namespace std
#else
typedef BinaryNinja::SSARegister argument_type;
#endif
- typedef uint64_t result_type;
+ typedef uint32_t result_type;
result_type operator()(argument_type const& value) const
{
- return ((result_type)value.reg) ^ ((result_type)value.version << 32);
+ return ((result_type)value.reg) ^ ((result_type)value.version << 16);
}
};
@@ -176,10 +176,10 @@ namespace std
#else
typedef BinaryNinja::SSAFlag argument_type;
#endif
- typedef uint64_t result_type;
+ typedef uint32_t result_type;
result_type operator()(argument_type const& value) const
{
- return ((result_type)value.flag) ^ ((result_type)value.version << 32);
+ return ((result_type)value.flag) ^ ((result_type)value.version << 16);
}
};
diff --git a/mediumlevelilinstruction.h b/mediumlevelilinstruction.h
index 9a76cb6c..8bab199f 100644
--- a/mediumlevelilinstruction.h
+++ b/mediumlevelilinstruction.h
@@ -135,10 +135,11 @@ namespace std
#else
typedef BinaryNinja::SSAVariable argument_type;
#endif
- typedef uint64_t result_type;
+ typedef uint32_t result_type;
result_type operator()(argument_type const& value) const
{
- return ((result_type)value.var.ToIdentifier()) ^ ((result_type)value.version << 40);
+ uint64_t hashTmp = ((uint64_t)value.var.ToIdentifier()) ^ ((uint64_t)value.version << 40);
+ return (uint32_t)((hashTmp >> 32) ^ (uint32_t)hashTmp);
}
};
diff --git a/python/architecture.py b/python/architecture.py
index 72403fec..a893c1d4 100644
--- a/python/architecture.py
+++ b/python/architecture.py
@@ -111,6 +111,7 @@ class Architecture(object):
endianness = Endianness.LittleEndian
address_size = 8
default_int_size = 4
+ instr_alignment = 1
max_instr_length = 16
opcode_display_length = 8
regs = {}
@@ -132,6 +133,7 @@ class Architecture(object):
self.__dict__["endianness"] = Endianness(core.BNGetArchitectureEndianness(self.handle))
self.__dict__["address_size"] = core.BNGetArchitectureAddressSize(self.handle)
self.__dict__["default_int_size"] = core.BNGetArchitectureDefaultIntegerSize(self.handle)
+ self.__dict__["instr_alignment"] = core.BNGetArchitectureInstructionAlignment(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,
@@ -228,6 +230,7 @@ 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.getInstructionAlignment = self._cb.getInstructionAlignment.__class__(self._get_instruction_alignment)
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.getAssociatedArchitectureByAddress = \
@@ -385,7 +388,8 @@ class Architecture(object):
def __setattr__(self, name, value):
if ((name == "name") or (name == "endianness") or (name == "address_size") or
- (name == "default_int_size") or (name == "regs") or (name == "get_max_instruction_length")):
+ (name == "default_int_size") or (name == "regs") or (name == "get_max_instruction_length") or
+ (name == "get_instruction_alignment")):
raise AttributeError("attribute '%s' is read only" % name)
else:
try:
@@ -420,6 +424,13 @@ class Architecture(object):
log.log_error(traceback.format_exc())
return 4
+ def _get_instruction_alignment(self, ctxt):
+ try:
+ return self.__class__.instr_alignment
+ except:
+ log.log_error(traceback.format_exc())
+ return 1
+
def _get_max_instruction_length(self, ctxt):
try:
return self.__class__.max_instr_length
@@ -451,6 +462,7 @@ class Architecture(object):
if info is None:
return False
result[0].length = info.length
+ result[0].archTransitionByTargetAddr = info.arch_transition_by_target_addr
result[0].branchDelay = info.branch_delay
result[0].branchCount = len(info.branches)
for i in xrange(0, len(info.branches)):
@@ -1152,6 +1164,7 @@ class Architecture(object):
return None
result = function.InstructionInfo()
result.length = info.length
+ result.arch_transition_by_target_addr = info.archTransitionByTargetAddr
result.branch_delay = info.branchDelay
for i in xrange(0, info.branchCount):
target = info.branchTarget[i]
diff --git a/python/basicblock.py b/python/basicblock.py
index 66d96882..8e64c1c1 100644
--- a/python/basicblock.py
+++ b/python/basicblock.py
@@ -35,6 +35,14 @@ class BasicBlockEdge(object):
self.target = target
self.back_edge = back_edge
+ def __eq__(self, value):
+ if not isinstance(value, BasicBlockEdge):
+ return False
+ return (self.type, self.source, self.target, self.back_edge) == (value.type, value.source, value.target, value.back_edge)
+
+ def __hash__(self):
+ return hash((self.type, self.source, self.target, self.back_edge))
+
def __repr__(self):
if self.type == BranchType.UnresolvedBranch:
return "<%s>" % BranchType(self.type).name
diff --git a/python/binaryview.py b/python/binaryview.py
index e6cb5b04..6eb59db1 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -416,12 +416,13 @@ class BinaryViewType(object):
class Segment(object):
- def __init__(self, start, length, data_offset, data_length, flags):
+ def __init__(self, start, length, data_offset, data_length, flags, auto_defined):
self.start = start
self.length = length
self.data_offset = data_offset
self.data_length = data_length
self.flags = flags
+ self.auto_defined = auto_defined
@property
def executable(self):
@@ -450,7 +451,7 @@ class Segment(object):
class Section(object):
- def __init__(self, name, section_type, start, length, linked_section, info_section, info_data, align, entry_size, semantics):
+ def __init__(self, name, section_type, start, length, linked_section, info_section, info_data, align, entry_size, semantics, auto_defined):
self.name = name
self.type = section_type
self.start = start
@@ -461,6 +462,7 @@ class Section(object):
self.align = align
self.entry_size = entry_size
self.semantics = SectionSemantics(semantics)
+ self.auto_defined = auto_defined
@property
def end(self):
@@ -583,6 +585,7 @@ class BinaryView(object):
self._cb.getEntryPoint = self._cb.getEntryPoint.__class__(self._get_entry_point)
self._cb.isExecutable = self._cb.isExecutable.__class__(self._is_executable)
self._cb.getDefaultEndianness = self._cb.getDefaultEndianness.__class__(self._get_default_endianness)
+ self._cb.isRelocatable = self._cb.isRelocatable.__class__(self._is_relocatable)
self._cb.getAddressSize = self._cb.getAddressSize.__class__(self._get_address_size)
self._cb.save = self._cb.save.__class__(self._save)
self.file = file_metadata
@@ -839,6 +842,11 @@ class BinaryView(object):
return Endianness(core.BNGetDefaultEndianness(self.handle))
@property
+ def relocatable(self):
+ """Boolean - is the binary relocatable (read-only)"""
+ return core.BNIsRelocatable(self.handle)
+
+ @property
def address_size(self):
"""Address size of the binary (read-only)"""
return core.BNGetViewAddressSize(self.handle)
@@ -959,7 +967,7 @@ class BinaryView(object):
result = []
for i in xrange(0, count.value):
result.append(Segment(segment_list[i].start, segment_list[i].length,
- segment_list[i].dataOffset, segment_list[i].dataLength, segment_list[i].flags))
+ segment_list[i].dataOffset, segment_list[i].dataLength, segment_list[i].flags, segment_list[i].autoDefined))
core.BNFreeSegmentList(segment_list)
return result
@@ -973,7 +981,7 @@ class BinaryView(object):
result[section_list[i].name] = Section(section_list[i].name, section_list[i].type, section_list[i].start,
section_list[i].length, section_list[i].linkedSection, section_list[i].infoSection,
section_list[i].infoData, section_list[i].align, section_list[i].entrySize,
- section_list[i].semantics)
+ section_list[i].semantics, section_list[i].autoDefined)
core.BNFreeSectionList(section_list, count.value)
return result
@@ -1202,6 +1210,13 @@ class BinaryView(object):
log.log_error(traceback.format_exc())
return Endianness.LittleEndian
+ def _is_relocatable(self, ctxt):
+ try:
+ return self.perform_is_relocatable()
+ except:
+ log.log_error(traceback.format_exc())
+ return False
+
def _get_address_size(self, ctxt):
try:
return self.perform_get_address_size()
@@ -1494,6 +1509,19 @@ class BinaryView(object):
"""
return Endianness.LittleEndian
+ def perform_is_relocatable(self):
+ """
+ ``perform_is_relocatable`` implements a check which returns true if the BinaryView is relocatable. Defaults to
+ True.
+
+ .. note:: This method **may** be implemented for custom BinaryViews that are relocatable.
+ .. warning:: This method **must not** be called directly.
+
+ :return: True if the BinaryView is relocatable, False otherwise
+ :rtype: boolean
+ """
+ return True
+
def create_database(self, filename, progress_func=None):
"""
``create_database`` writes the current database (.bndb) file out to the specified file.
@@ -3327,7 +3355,7 @@ class BinaryView(object):
if not core.BNGetSegmentAt(self.handle, addr, segment):
return None
result = Segment(segment.start, segment.length, segment.dataOffset, segment.dataLength,
- segment.flags)
+ segment.flags, segment.autoDefined)
return result
def get_address_for_data_offset(self, offset):
@@ -3360,7 +3388,7 @@ class BinaryView(object):
result.append(Section(section_list[i].name, section_list[i].type, section_list[i].start,
section_list[i].length, section_list[i].linkedSection, section_list[i].infoSection,
section_list[i].infoData, section_list[i].align, section_list[i].entrySize,
- section_list[i].semantics))
+ section_list[i].semantics, section_list[i].autoDefined))
core.BNFreeSectionList(section_list, count.value)
return result
@@ -3369,7 +3397,8 @@ class BinaryView(object):
if not core.BNGetSectionByName(self.handle, name, section):
return None
result = Section(section.name, section.type, section.start, section.length, section.linkedSection,
- section.infoSection, section.infoData, section.align, section.entrySize, section.semantics)
+ section.infoSection, section.infoData, section.align, section.entrySize, section.semantics,
+ section_list.autoDefined)
core.BNFreeSection(section)
return result
diff --git a/python/examples/nes.py b/python/examples/nes.py
index e55a90b7..39544c9f 100644
--- a/python/examples/nes.py
+++ b/python/examples/nes.py
@@ -367,6 +367,7 @@ class M6502(Architecture):
name = "6502"
address_size = 2
default_int_size = 1
+ instr_alignment = 1
max_instr_length = 3
regs = {
"a": RegisterInfo("a", 1),
diff --git a/python/function.py b/python/function.py
index f8aaae44..58bee8f4 100644
--- a/python/function.py
+++ b/python/function.py
@@ -123,6 +123,8 @@ class PossibleValueSet(object):
self.reg = arch.get_reg_name(value.value)
elif value.state == RegisterValueType.ConstantValue:
self.value = value.value
+ elif value.state == RegisterValueType.ConstantPointerValue:
+ self.value = value.value
elif value.state == RegisterValueType.StackFrameOffset:
self.offset = value.value
elif value.state == RegisterValueType.SignedRangeValue:
@@ -164,6 +166,8 @@ class PossibleValueSet(object):
return "<entry %s>" % self.reg
if self.type == RegisterValueType.ConstantValue:
return "<const %#x>" % self.value
+ if self.type == RegisterValueType.ConstantPointerValue:
+ return "<const ptr %#x>" % self.value
if self.type == RegisterValueType.StackFrameOffset:
return "<stack frame offset %#x>" % self.offset
if self.type == RegisterValueType.SignedRangeValue:
@@ -307,6 +311,8 @@ class Function(object):
self._view = view
self.handle = core.handle_of_type(handle, core.BNFunction)
self._advanced_analysis_requests = 0
+ self._arch = None
+ self._platform = None
def __del__(self):
if self._advanced_analysis_requests > 0:
@@ -358,18 +364,26 @@ class Function(object):
@property
def arch(self):
"""Function architecture (read-only)"""
- arch = core.BNGetFunctionArchitecture(self.handle)
- if arch is None:
- return None
- return architecture.Architecture(arch)
+ if self._arch:
+ return self._arch
+ else:
+ arch = core.BNGetFunctionArchitecture(self.handle)
+ if arch is None:
+ return None
+ self._arch = architecture.Architecture(arch)
+ return self._arch
@property
def platform(self):
"""Function platform (read-only)"""
- plat = core.BNGetFunctionPlatform(self.handle)
- if plat is None:
- return None
- return platform.Platform(None, handle = plat)
+ if self._platform:
+ return self._platform
+ else:
+ plat = core.BNGetFunctionPlatform(self.handle)
+ if plat is None:
+ return None
+ self._platform = platform.Platform(None, handle = plat)
+ return self._platform
@property
def start(self):
@@ -1741,6 +1755,7 @@ class InstructionBranch(object):
class InstructionInfo(object):
def __init__(self):
self.length = 0
+ self.arch_transition_by_target_addr = False
self.branch_delay = False
self.branches = []
diff --git a/python/functionrecognizer.py b/python/functionrecognizer.py
index 8514a2ee..4ac304ca 100644
--- a/python/functionrecognizer.py
+++ b/python/functionrecognizer.py
@@ -36,6 +36,7 @@ class FunctionRecognizer(object):
self._cb = core.BNFunctionRecognizer()
self._cb.context = 0
self._cb.recognizeLowLevelIL = self._cb.recognizeLowLevelIL.__class__(self._recognize_low_level_il)
+ self._cb.recognizeMediumLevelIL = self._cb.recognizeMediumLevelIL.__class__(self._recognize_medium_level_il)
@classmethod
def register_global(cls):
@@ -62,3 +63,17 @@ class FunctionRecognizer(object):
def recognize_low_level_il(self, data, func, il):
return False
+
+ def _recognize_medium_level_il(self, ctxt, data, func, il):
+ try:
+ file_metadata = filemetadata.FileMetadata(handle = core.BNGetFileForView(data))
+ view = binaryview.BinaryView(file_metadata = file_metadata, handle = core.BNNewViewReference(data))
+ func = function.Function(view, handle = core.BNNewFunctionReference(func))
+ il = mediumlevelil.MediumLevelILFunction(func.arch, handle = core.BNNewMediumLevelILFunctionReference(il))
+ return self.recognize_medium_level_il(view, func, il)
+ except:
+ log.log_error(traceback.format_exc())
+ return False
+
+ def recognize_medium_level_il(self, data, func, il):
+ return False
diff --git a/python/pluginmanager.py b/python/pluginmanager.py
index 6896d699..2f293577 100644
--- a/python/pluginmanager.py
+++ b/python/pluginmanager.py
@@ -382,7 +382,6 @@ class RepositoryManager(object):
>>> mgr = RepositoryManager()
>>> mgr.add_repository(url="https://github.com/vector35/community-plugins.git",
repopath="myrepo",
- repomanifest="plugins",
localreference="master", remotereference="origin")
True
>>>
diff --git a/python/scriptingprovider.py b/python/scriptingprovider.py
index f9758cc9..c92c249a 100644
--- a/python/scriptingprovider.py
+++ b/python/scriptingprovider.py
@@ -42,14 +42,14 @@ class _ThreadActionContext(object):
def __init__(self, func):
self.func = func
self.interpreter = None
- if "value" in dir(PythonScriptingInstance._interpreter):
+ if hasattr(PythonScriptingInstance._interpreter, "value"):
self.interpreter = PythonScriptingInstance._interpreter.value
self.__class__._actions.append(self)
self.callback = ctypes.CFUNCTYPE(None, ctypes.c_void_p)(lambda ctxt: self.execute())
def execute(self):
old_interpreter = None
- if "value" in dir(PythonScriptingInstance._interpreter):
+ if hasattr(PythonScriptingInstance._interpreter, "value"):
old_interpreter = PythonScriptingInstance._interpreter.value
PythonScriptingInstance._interpreter.value = self.interpreter
try:
@@ -380,7 +380,7 @@ class _PythonScriptingInstanceOutput(object):
def write(self, data):
interpreter = None
- if "value" in dir(PythonScriptingInstance._interpreter):
+ if hasattr(PythonScriptingInstance._interpreter, "value"):
interpreter = PythonScriptingInstance._interpreter.value
if interpreter is None:
@@ -419,7 +419,7 @@ class _PythonScriptingInstanceInput(object):
def read(self, size):
interpreter = None
- if "value" in dir(PythonScriptingInstance._interpreter):
+ if hasattr(PythonScriptingInstance._interpreter, "value"):
interpreter = PythonScriptingInstance._interpreter.value
if interpreter is None:
@@ -434,7 +434,7 @@ class _PythonScriptingInstanceInput(object):
def readline(self):
interpreter = None
- if "value" in dir(PythonScriptingInstance._interpreter):
+ if hasattr(PythonScriptingInstance._interpreter, "value"):
interpreter = PythonScriptingInstance._interpreter.value
if interpreter is None:
@@ -457,7 +457,7 @@ class PythonScriptingInstance(ScriptingInstance):
super(PythonScriptingInstance.InterpreterThread, self).__init__()
self.instance = instance
self.locals = {"__name__": "__console__", "__doc__": None, "binaryninja": sys.modules[__name__]}
- self.interpreter = code.InteractiveInterpreter(self.locals)
+ self.interpreter = code.InteractiveConsole(self.locals)
self.event = threading.Event()
self.daemon = True
@@ -484,7 +484,7 @@ class PythonScriptingInstance(ScriptingInstance):
self.code = None
self.input = ""
- self.interpreter.runsource("from binaryninja import *\n")
+ self.interpreter.push("from binaryninja import *\n")
def execute(self, code):
self.code = code
@@ -547,7 +547,8 @@ class PythonScriptingInstance(ScriptingInstance):
self.locals["current_llil"] = self.active_func.low_level_il
self.locals["current_mlil"] = self.active_func.medium_level_il
- self.interpreter.runsource(code)
+ for line in code.split("\n"):
+ self.interpreter.push(line)
if self.locals["here"] != self.active_addr:
if not self.active_view.file.navigate(self.active_view.file.view, self.locals["here"]):
diff --git a/scripts/linux-setup.sh b/scripts/linux-setup.sh
index 8bf15ddd..bb1e0f28 100755
--- a/scripts/linux-setup.sh
+++ b/scripts/linux-setup.sh
@@ -14,7 +14,7 @@ setvars()
APP="binaryninja"
FILECOMMENT="Binary Ninja Analysis Database"
APPCOMMENT="Binary Ninja: A Reverse Engineering Platform"
- BNPATH=$(dirname $(readlink -f "$0"))
+ BNPATH="$(dirname $(readlink -f "$0"))/.."
EXEC="${BNPATH}/binaryninja"
PNG="${BNPATH}/docs/images/logo.png"
EXT="bndb"
@@ -54,6 +54,10 @@ lastrun()
then
echo lastrun already exists, remove to create a new one
else
+ if [ ! -d ${HOME}/.binaryninja ]
+ then
+ mkdir ${HOME}/.binaryninja
+ fi
echo ${BNPATH} > ${HOME}/.binaryninja/lastrun
fi
}
@@ -61,7 +65,12 @@ lastrun()
pythonpath()
{
echo Configuring python path
- ${SUDO}python ${BNPATH}/scripts/install_api.py $ROOT
+ if [[ $(python -V) == "Python 3."* ]]
+ then
+ ${SUDO}python2 ${BNPATH}/scripts/install_api.py $ROOT
+ else
+ ${SUDO}python ${BNPATH}/scripts/install_api.py $ROOT
+ fi
}
createdesktopfile()
@@ -81,14 +90,9 @@ Type=Application
Categories=Utility;
Comment=${APPCOMMENT}
EOF
- if [ "${ROOT}" == "root" ]
- then
- echo ${DESKTOP} | $SUDO tee ${DESKTOPFILE} >/dev/null
- $SUDO chmod +x ${DESKTOPFILE}
- $SUDO update-desktop-database ${SHARE}/applications
- else
- echo ${DESKTOP} > ${HOME}/Desktop/${APP}.desktop
- fi
+ echo "${DESKTOP}" | $SUDO tee ${DESKTOPFILE} >/dev/null
+ $SUDO chmod +x ${DESKTOPFILE}
+ $SUDO update-desktop-database ${SHARE}/applications
}
createmime()
@@ -112,12 +116,8 @@ createmime()
#echo Copying icon
#$SUDO cp $PNG $IMAGEFILE
- if [ "${ROOT}" == "root" ]
- then
- $SUDO cp ${PNG} ${IMAGEFILE}
- $SUDO update-mime-database ${SHARE}/mime
- fi
-
+ $SUDO cp ${PNG} ${IMAGEFILE}
+ $SUDO update-mime-database ${SHARE}/mime
}
addtodesktop()
@@ -127,11 +127,8 @@ addtodesktop()
uninstall()
{
- rm -i -r $DESKTOPFILE $MIMEFILE $IMAGEFILE
- if [ "$ROOT" == "root" ]
- then
- $SUDO update-mime-database ${SHARE}/mime
- fi
+ rm -i -r $DESKTOPFILE $MIMEFILE $IMAGEFILE ${HOME}/Desktop/${APP}.desktop
+ $SUDO update-mime-database ${SHARE}/mime
exit 0
}