From 01aec7ed694b537192093d37a7933f710bc0d70b Mon Sep 17 00:00:00 2001 From: Brian Potchik Date: Wed, 18 Oct 2017 17:03:37 -0400 Subject: UI Updates for Product and Update Status. --- binaryninjaapi.cpp | 18 ++++++++++++++++++ binaryninjaapi.h | 4 +++- binaryninjacore.h | 8 ++++++-- python/__init__.py | 7 +++++++ python/update.py | 2 +- update.cpp | 4 ++-- 6 files changed, 37 insertions(+), 6 deletions(-) diff --git a/binaryninjaapi.cpp b/binaryninjaapi.cpp index 6f488788..b774cf2b 100644 --- a/binaryninjaapi.cpp +++ b/binaryninjaapi.cpp @@ -173,6 +173,15 @@ string BinaryNinja::GetVersionString() } +string BinaryNinja::GetLicensedUserEmail() +{ + char* str = BNGetLicensedUserEmail(); + string result = str; + BNFreeString(str); + return result; +} + + string BinaryNinja::GetProduct() { char* str = BNGetProduct(); @@ -191,6 +200,15 @@ string BinaryNinja::GetProductType() } +string BinaryNinja::GetSerialNumber() +{ + char* str = BNGetSerialNumber(); + string result = str; + BNFreeString(str); + return result; +} + + int BinaryNinja::GetLicenseCount() { return BNGetLicenseCount(); diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 9d4a7257..a6276b00 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -575,8 +575,10 @@ namespace BinaryNinja std::string& output, std::string& errors, bool stdoutIsText=false, bool stderrIsText=true); std::string GetVersionString(); + std::string GetLicensedUserEmail(); std::string GetProduct(); std::string GetProductType(); + std::string GetSerialNumber(); int GetLicenseCount(); bool IsUIEnabled(); uint32_t GetBuildId(); @@ -2969,7 +2971,7 @@ namespace BinaryNinja static std::vector GetList(); - bool AreUpdatesAvailable(); + bool AreUpdatesAvailable(uint64_t* expireTime, uint64_t* serverTime); BNUpdateResult UpdateToVersion(const std::string& version); BNUpdateResult UpdateToVersion(const std::string& version, diff --git a/binaryninjacore.h b/binaryninjacore.h index 1bb4c726..870c2de3 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1203,7 +1203,8 @@ extern "C" { UpdateFailed = 0, UpdateSuccess = 1, - AlreadyUpToDate = 2 + AlreadyUpToDate = 2, + UpdateAvailable = 3 }; struct BNUpdateChannel @@ -1603,7 +1604,10 @@ extern "C" BINARYNINJACOREAPI char* BNGetVersionString(void); BINARYNINJACOREAPI uint32_t BNGetBuildId(void); + BINARYNINJACOREAPI char* BNGetSerialNumber(void); + BINARYNINJACOREAPI uint64_t BNGetLicenseExpirationTime(void); BINARYNINJACOREAPI bool BNIsLicenseValidated(void); + BINARYNINJACOREAPI char* BNGetLicensedUserEmail(void); BINARYNINJACOREAPI char* BNGetProduct(void); BINARYNINJACOREAPI char* BNGetProductType(void); BINARYNINJACOREAPI int BNGetLicenseCount(void); @@ -2769,7 +2773,7 @@ extern "C" BINARYNINJACOREAPI BNUpdateVersion* BNGetUpdateChannelVersions(const char* channel, size_t* count, char** errors); BINARYNINJACOREAPI void BNFreeUpdateChannelVersionList(BNUpdateVersion* list, size_t count); - BINARYNINJACOREAPI bool BNAreUpdatesAvailable(const char* channel, char** errors); + BINARYNINJACOREAPI bool BNAreUpdatesAvailable(const char* channel, uint64_t* expireTime, uint64_t* serverTime, char** errors); BINARYNINJACOREAPI BNUpdateResult BNUpdateToVersion(const char* channel, const char* version, char** errors, bool (*progress)(void* ctxt, uint64_t progress, uint64_t total), diff --git a/python/__init__.py b/python/__init__.py index f4a8fac8..729e4f8a 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -21,6 +21,7 @@ import atexit import sys +from time import gmtime # Binary Ninja components import _binaryninjacore as core @@ -147,6 +148,12 @@ core_version = core.BNGetVersionString() core_build_id = core.BNGetBuildId() '''Build ID''' +core_serial = core.BNGetSerialNumber() +'''Serial Number''' + +core_expires = gmtime(core.BNGetLicenseExpirationTime()) +'''License Expiration''' + core_product = core.BNGetProduct() '''Product string from the license file''' diff --git a/python/update.py b/python/update.py index be6962d7..1eb8ea61 100644 --- a/python/update.py +++ b/python/update.py @@ -154,7 +154,7 @@ class UpdateChannel(object): def updates_available(self): """Whether updates are available (read-only)""" errors = ctypes.c_char_p() - result = core.BNAreUpdatesAvailable(self.name, errors) + result = core.BNAreUpdatesAvailable(self.name, None, None, errors) if errors: error_str = errors.value core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte))) diff --git a/update.cpp b/update.cpp index 135fee5e..0ec69892 100644 --- a/update.cpp +++ b/update.cpp @@ -67,10 +67,10 @@ vector UpdateChannel::GetList() } -bool UpdateChannel::AreUpdatesAvailable() +bool UpdateChannel::AreUpdatesAvailable(uint64_t* expireTime, uint64_t* serverTime) { char* errors; - bool result = BNAreUpdatesAvailable(name.c_str(), &errors); + bool result = BNAreUpdatesAvailable(name.c_str(), expireTime, serverTime, &errors); if (errors) { -- cgit v1.3.1 From 77e09a2d02efbb2d6aa9758b503e37cbe7655f7f Mon Sep 17 00:00:00 2001 From: Jordan Wiens Date: Wed, 25 Oct 2017 11:57:40 -0400 Subject: additional debian sym link instructions --- docs/guide/troubleshooting.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/guide/troubleshooting.md b/docs/guide/troubleshooting.md index a640d47e..c1b3a910 100644 --- a/docs/guide/troubleshooting.md +++ b/docs/guide/troubleshooting.md @@ -72,6 +72,14 @@ $ ln -s libssl.so libssl.so.1.0.0 $ ln -s libcrypto.so libcrypto.so.1.0.0 ``` +Alternatively, you might need to (as root): + +``` +apt-get install libssl-dev +ln -s /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.2 /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0 +ln -s /usr/lib/x86_64-linux-gnu/libssl.so.1.0.2 /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0 +``` + ### Gentoo One Gentoo user [reported][issue672] a failed SSL certificate when trying to update. The solution was to copy over `/etc/ssl/certs/ca-certificates.crt` from another Linux distribution. -- cgit v1.3.1 From 75242aecc30c565ee56d3e74ec2e2dd502a6f073 Mon Sep 17 00:00:00 2001 From: Josh Watson Date: Sun, 29 Oct 2017 12:51:23 -0400 Subject: Fixed possible IndexError in Function.get_*_at methods (#775) `Function.get_low_level_il_at` and `Function.get_lifted_il_at` methods could raise an IndexError because proper checking was not performed on the index returned by the core method that retrieves the IL instruction index of the requested instruction. The methods now check this value to see if it is equal to the length of the IL function, and if so, returns `None` instead. The onus of checking for `None` will be on the user, but at least they shouldn't have to wrap this in a try/except block anymore. --- python/function.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/python/function.py b/python/function.py index 5daa7b2a..9aafdf52 100644 --- a/python/function.py +++ b/python/function.py @@ -727,7 +727,13 @@ class Function(object): """ if arch is None: arch = self.arch - return self.low_level_il[core.BNGetLowLevelILForInstruction(self.handle, arch.handle, addr)] + + idx = core.BNGetLowLevelILForInstruction(self.handle, arch.handle, addr) + + if idx == len(self.low_level_il): + return None + + return self.low_level_il[idx] def get_low_level_il_exits_at(self, addr, arch=None): if arch is None: @@ -878,7 +884,13 @@ class Function(object): def get_lifted_il_at(self, addr, arch=None): if arch is None: arch = self.arch - return self.lifted_il[core.BNGetLiftedILForInstruction(self.handle, arch.handle, addr)] + + idx = core.BNGetLiftedILForInstruction(self.handle, arch.handle, addr) + + if idx == len(self.lifted_il): + return None + + return self.lifted_il[idx] def get_lifted_il_flag_uses_for_definition(self, i, flag): flag = self.arch.get_flag_index(flag) -- cgit v1.3.1 From 0ca722550555a1a0fc82766686bade6d669af3dc Mon Sep 17 00:00:00 2001 From: Cory Duplantis Date: Sun, 29 Oct 2017 13:23:33 -0500 Subject: Add convenience API's for accessing blocks and instructions in Function (#792) * Update export-svg.py path splitting Changed the path splitting part to the way python's documentation recommends it. I got some errors trying to use that function on windows, because it didn't split correctly. I stumbled upon this in the python documentation: https://docs.python.org/2/library/os.html#os.sep I changed the relevant line using their recommendation. * Rename data to session_data, as this API is per-session and not stored in the db * get_basic_blocks_starting_at incorrectly in the docs * Update troubleshooting.md * Zoom * get_instruction_low_level_il tweak made api docs less ambiguous * documenting Type.int and Type.function * Update __init__.py * Add convenience API's for accessing blocks and instructions in Function --- python/function.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/python/function.py b/python/function.py index 9aafdf52..cbbdf9bd 100644 --- a/python/function.py +++ b/python/function.py @@ -666,6 +666,41 @@ class Function(object): """Sets a comment for the current function""" return core.BNSetFunctionComment(self.handle, comment) + @property + def llil_basic_blocks(self): + """A generator of all LowLevelILBasicBlock objects in the current function""" + for block in self.low_level_il: + yield block + + @property + def mlil_basic_blocks(self): + """A generator of all MediumLevelILBasicBlock objects in the current function""" + for block in self.medium_level_il: + yield block + + @property + def instructions(self): + """A generator of instruction tokens and their start addresses for the current function""" + for block in self.basic_blocks: + start = block.start + for i in block: + yield (i[0], start) + start += i[1] + + @property + def llil_instructions(self): + """A generator of llil instructions of the current function""" + for block in self.llil_basic_blocks: + for i in block: + yield i + + @property + def mlil_instructions(self): + """A generator of mlil instructions of the current function""" + for block in self.mlil_basic_blocks: + for i in block: + yield i + def __iter__(self): count = ctypes.c_ulonglong() blocks = core.BNGetFunctionBasicBlockList(self.handle, count) -- cgit v1.3.1 From c396d2cfb3682cb4c152b9dba6f866f6783e4a80 Mon Sep 17 00:00:00 2001 From: Jordan Wiens Date: Mon, 30 Oct 2017 17:46:49 -0400 Subject: __hash__ for three types of basic blocks --- python/basicblock.py | 3 +++ python/lowlevelil.py | 3 +++ python/mediumlevelil.py | 3 +++ 3 files changed, 9 insertions(+) diff --git a/python/basicblock.py b/python/basicblock.py index 26db925d..66d96882 100644 --- a/python/basicblock.py +++ b/python/basicblock.py @@ -68,6 +68,9 @@ class BasicBlock(object): """Internal method used to instantiante child instances""" return BasicBlock(view, handle) + def __hash__(self): + return hash((self.start, self.end, self.arch.name)) + @property def function(self): """Basic block function (read-only)""" diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 75a3f1ad..dfc5af5f 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -1733,6 +1733,9 @@ class LowLevelILBasicBlock(basicblock.BasicBlock): """Internal method by super to instantiante child instances""" return LowLevelILBasicBlock(view, handle, self.il_function) + def __hash__(self): + return hash((self.start, self.end, self.il_function)) + def LLIL_TEMP(n): return n | 0x80000000 diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 07759a47..9167212a 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -893,3 +893,6 @@ class MediumLevelILBasicBlock(basicblock.BasicBlock): def _create_instance(self, view, handle): """Internal method by super to instantiante child instances""" return MediumLevelILBasicBlock(view, handle, self.il_function) + + def __hash__(self): + return hash((self.start, self.end, self.il_function)) -- cgit v1.3.1 From a774e47ee36a5d4418c9aec13e5612f158a825d3 Mon Sep 17 00:00:00 2001 From: Jordan Wiens Date: Mon, 30 Oct 2017 21:21:48 -0400 Subject: add current_llil and current_mlil scripting console aliases --- docs/getting-started.md | 2 ++ python/scriptingprovider.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docs/getting-started.md b/docs/getting-started.md index 692c1e67..39809747 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -210,6 +210,8 @@ By default the interactive python prompt has a number of convenient helper funct - `bv` / `current_view` / : the current [BinaryView](https://api.binary.ninja/binaryninja.BinaryView.html) - `current_function`: the current [Function](https://api.binary.ninja/binaryninja.Function.html) - `current_basic_block`: the current [BasicBlock](https://api.binary.ninja/binaryninja.BasicBlock.html) +- `current_llil`: the current [LowLevelILBasicBlock](https://api.binary.ninja/binaryninja.lowlevelil.LowLevelILBasicBlock.html) +- `current_mlil`: the current [MediumLevelILBasicBlock](https://api.binary.ninja/binaryninja.mediumlevelil.MediumLevelILBasicBlock.html) - `current_selection`: a tuple of the start and end addresses of the current selection - `write_at_cursor(data)`: function that writes data to the start of the current selection - `get_selected_data()`: function that returns the data in the current selection diff --git a/python/scriptingprovider.py b/python/scriptingprovider.py index ed9688b9..211d2fb7 100644 --- a/python/scriptingprovider.py +++ b/python/scriptingprovider.py @@ -540,6 +540,8 @@ class PythonScriptingInstance(ScriptingInstance): self.locals["current_address"] = self.active_addr self.locals["here"] = self.active_addr self.locals["current_selection"] = (self.active_selection_begin, self.active_selection_end) + self.locals["current_llil"] = self.active_func.low_level_il + self.locals["current_mlil"] = self.active_func.medium_level_il self.interpreter.runsource(code) -- cgit v1.3.1 From de70f093cc429a125dde201cfe245b616c10ebce Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Mon, 30 Oct 2017 22:03:01 -0400 Subject: Provide a slightly different implementation for @joshwatson's AnalysisCompletionEvent PR and documentation update --- python/binaryview.py | 13 ++++++++++++- python/interaction.py | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/python/binaryview.py b/python/binaryview.py index 9304d412..e6cb5b04 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -103,6 +103,17 @@ class StringReference(object): class AnalysisCompletionEvent(object): + """ + The ``AnalysisCompletionEvent`` object provides an asynchronous mechanism for receiving + callbacks when analysis is complete. + + :Example: + >>> def on_complete(self): + ... print "Analysis Complete", self.view + ... + >>> evt = AnalysisCompletionEvent(bv, on_complete) + >>> + """ def __init__(self, view, callback): self.view = view self.callback = callback @@ -114,7 +125,7 @@ class AnalysisCompletionEvent(object): def _notify(self, ctxt): try: - self.callback() + self.callback(self) except: log.log_error(traceback.format_exc()) diff --git a/python/interaction.py b/python/interaction.py index 979549f5..96cac42d 100644 --- a/python/interaction.py +++ b/python/interaction.py @@ -520,7 +520,7 @@ def show_html_report(title, contents, plaintext=""): :param str contents: HTML contents to display :param str plaintext: Plain text version to display (used on the command line) :rtype: None - :Example" + :Example: >>> show_html_report("title", "

Contents

", "Plain text contents") Plain text contents """ -- cgit v1.3.1 From 9a70f039ffd68190a3a6efc53a4fab3cf20b7963 Mon Sep 17 00:00:00 2001 From: Jordan Wiens Date: Wed, 1 Nov 2017 00:42:32 -0400 Subject: fix new scripting provider aliases when no current context exists --- python/scriptingprovider.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/python/scriptingprovider.py b/python/scriptingprovider.py index 211d2fb7..f9758cc9 100644 --- a/python/scriptingprovider.py +++ b/python/scriptingprovider.py @@ -540,8 +540,12 @@ class PythonScriptingInstance(ScriptingInstance): self.locals["current_address"] = self.active_addr self.locals["here"] = self.active_addr self.locals["current_selection"] = (self.active_selection_begin, self.active_selection_end) - self.locals["current_llil"] = self.active_func.low_level_il - self.locals["current_mlil"] = self.active_func.medium_level_il + if self.active_func == None: + self.locals["current_llil"] = None + self.locals["current_mlil"] = None + else: + self.locals["current_llil"] = self.active_func.low_level_il + self.locals["current_mlil"] = self.active_func.medium_level_il self.interpreter.runsource(code) -- cgit v1.3.1 From 54a23d9e1ae34936427461b2807e3d5980e17486 Mon Sep 17 00:00:00 2001 From: David Barksdale Date: Thu, 2 Nov 2017 11:30:12 -0500 Subject: Make SSAVariables unique between functions (#855) This helps a ton with inter-function analysis. --- python/mediumlevelil.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 9167212a..333a6c4d 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -39,12 +39,12 @@ class SSAVariable(object): def __eq__(self, other): return ( - (self.var.identifier, self.version) == - (other.var.identifier, other.version) + (self.var.identifier, self.var.function, self.version) == + (other.var.identifier, other.var.function, other.version) ) def __hash__(self): - return hash((self.var.identifier, self.version)) + return hash((self.var.identifier, self.var.function, self.version)) class MediumLevelILLabel(object): -- cgit v1.3.1 From 704ceff1223485e9dc12947a36b0d56a3ff9d3ae Mon Sep 17 00:00:00 2001 From: David Barksdale Date: Thu, 2 Nov 2017 11:38:11 -0500 Subject: Move the function discrimination from SSAVariable to Variable (#856) --- python/function.py | 4 ++-- python/mediumlevelil.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/python/function.py b/python/function.py index cbbdf9bd..f8aaae44 100644 --- a/python/function.py +++ b/python/function.py @@ -241,10 +241,10 @@ class Variable(object): return self.name def __eq__(self, other): - return self.identifier == other.identifier + return (self.identifier, self.function) == (other.identifier, other.function) def __hash__(self): - return hash(self.identifier) + return hash((self.identifier, self.function)) class ConstantReference(object): diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 333a6c4d..6f5515bb 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -39,12 +39,12 @@ class SSAVariable(object): def __eq__(self, other): return ( - (self.var.identifier, self.var.function, self.version) == - (other.var.identifier, other.var.function, other.version) + (self.var, self.version) == + (other.var, other.version) ) def __hash__(self): - return hash((self.var.identifier, self.var.function, self.version)) + return hash((self.var, self.version)) class MediumLevelILLabel(object): -- cgit v1.3.1 From 1476607ebb677b4c7316957505c9aa95c7d08788 Mon Sep 17 00:00:00 2001 From: Jordan Wiens Date: Fri, 3 Nov 2017 15:51:47 -0400 Subject: fix docs for plugin manager example --- docs/guide/plugins.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide/plugins.md b/docs/guide/plugins.md index 9c67d44f..442d6fe4 100644 --- a/docs/guide/plugins.md +++ b/docs/guide/plugins.md @@ -36,9 +36,9 @@ Binary Ninja now offers a [PluginManager API] which can simplify the process of ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'add_repository', 'check_for_updates', 'default_repository', 'disable_plugin', 'enable_plugin', 'handle', 'install_plugin', 'plugins', 'repositories', 'uninstall_plugin', 'update_plugin'] >>> mgr.plugins {'default': [, , , , , , , , , , , ]} ->>> mgr.install_plugin(easypatch) +>>> mgr.install_plugin("easypatch") True ->>> mgr.enable(easypatch) +>>> mgr.enable_plugin("easypatch") True ``` -- cgit v1.3.1 From af062c5608b6a4abb60c3d6ebc193d3ac929165b Mon Sep 17 00:00:00 2001 From: Jordan Wiens Date: Fri, 3 Nov 2017 15:53:08 -0400 Subject: point linux setup script at the right path for api install --- scripts/linux-setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/linux-setup.sh b/scripts/linux-setup.sh index f1650b7f..8bf15ddd 100755 --- a/scripts/linux-setup.sh +++ b/scripts/linux-setup.sh @@ -61,7 +61,7 @@ lastrun() pythonpath() { echo Configuring python path - ${SUDO}python ${BNPATH}/install_api.py $ROOT + ${SUDO}python ${BNPATH}/scripts/install_api.py $ROOT } createdesktopfile() -- cgit v1.3.1 From 3d45c0be55585e0d868e1a09c86fdaf925d490a3 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Tue, 7 Nov 2017 16:47:28 -0500 Subject: Update to latest asmx86 --- examples/x86_extension/src/asmx86 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/x86_extension/src/asmx86 b/examples/x86_extension/src/asmx86 index f78096d7..9a1bf01f 160000 --- a/examples/x86_extension/src/asmx86 +++ b/examples/x86_extension/src/asmx86 @@ -1 +1 @@ -Subproject commit f78096d79ccfcc5169b6e2ae0fa89e3eed5b85cc +Subproject commit 9a1bf01f4c456779544a445db45b1496c50ff372 -- cgit v1.3.1 From c4d8b6f18c094d98df4448bdaf14faa86b33cc86 Mon Sep 17 00:00:00 2001 From: Matt Revelle Date: Wed, 8 Nov 2017 11:18:03 -0500 Subject: Cache arch and platform property values (#862) * Added __hash__ impl for BasicBlock instances. * Removed too specific __hash__ impl. * Cache arch and platform property values. --- python/function.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/python/function.py b/python/function.py index f8aaae44..bec3c2ad 100644 --- a/python/function.py +++ b/python/function.py @@ -307,6 +307,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 +360,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 = plat + return platform.Platform(None, handle = plat) @property def start(self): -- cgit v1.3.1 From 382b1353649472bc2088598b3b8b60c096c1e201 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Fri, 10 Nov 2017 17:42:28 -0500 Subject: Add 'relocatable' property to BinaryView class --- binaryninjaapi.h | 3 +++ binaryninjacore.h | 2 ++ binaryview.cpp | 19 +++++++++++++++++++ python/binaryview.py | 26 ++++++++++++++++++++++++++ 4 files changed, 50 insertions(+) diff --git a/binaryninjaapi.h b/binaryninjaapi.h index a6276b00..5f3aace7 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1088,6 +1088,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 +1116,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 +1183,7 @@ namespace BinaryNinja void SetDefaultPlatform(Platform* platform); BNEndianness GetDefaultEndianness() const; + bool IsRelocatable() const; size_t GetAddressSize() const; bool IsExecutable() const; diff --git a/binaryninjacore.h b/binaryninjacore.h index 870c2de3..45e6310c 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); }; @@ -1777,6 +1778,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); diff --git a/binaryview.cpp b/binaryview.cpp index 213be79a..0a082458 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 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); diff --git a/python/binaryview.py b/python/binaryview.py index e6cb5b04..9f149ba8 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -583,6 +583,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 @@ -838,6 +839,11 @@ class BinaryView(object): """Endianness of the binary (read-only)""" 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)""" @@ -1202,6 +1208,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 +1507,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. -- cgit v1.3.1 From 32b22a22aaf7b76d47e91ed49a3246b66b431991 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Sun, 12 Nov 2017 11:35:39 -0500 Subject: Removed unneeded shadowed variabled --- interaction.cpp | 2 -- 1 file changed, 2 deletions(-) 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 view, const string& titl bool InteractionHandler::GetIntegerInput(int64_t& result, const string& prompt, const string& title) { - string input; - while (true) { string input; -- cgit v1.3.1 From 0cff612e91e59a343fad898daa6fa51ab525a789 Mon Sep 17 00:00:00 2001 From: Brian Potchik Date: Mon, 13 Nov 2017 17:09:13 -0500 Subject: Add GetInstructionAlignment Callback to Architecture. --- architecture.cpp | 20 ++++++++++++++++++++ binaryninjaapi.h | 3 +++ binaryninjacore.h | 2 ++ examples/x86_extension/src/x86_extension.cpp | 5 +++++ python/architecture.py | 13 ++++++++++++- python/examples/nes.py | 1 + 6 files changed, 43 insertions(+), 1 deletion(-) diff --git a/architecture.cpp b/architecture.cpp index eb588394..17d02909 100644 --- a/architecture.cpp +++ b/architecture.cpp @@ -111,6 +111,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 +450,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 +531,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 +919,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.h b/binaryninjaapi.h index 5f3aace7..4f62ef5f 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1585,6 +1585,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); @@ -1640,6 +1641,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; @@ -1780,6 +1782,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 GetAssociatedArchitectureByAddress(uint64_t& addr) override; diff --git a/binaryninjacore.h b/binaryninjacore.h index 45e6310c..cb99958c 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1003,6 +1003,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); @@ -1946,6 +1947,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); diff --git a/examples/x86_extension/src/x86_extension.cpp b/examples/x86_extension/src/x86_extension.cpp index 9efcc119..076551ab 100644 --- a/examples/x86_extension/src/x86_extension.cpp +++ b/examples/x86_extension/src/x86_extension.cpp @@ -327,6 +327,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); diff --git a/python/architecture.py b/python/architecture.py index 72403fec..41a130bf 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 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), -- cgit v1.3.1 From 88af32b1b20026d3bc063be558f63aeb1ccfd579 Mon Sep 17 00:00:00 2001 From: Brian Potchik Date: Tue, 14 Nov 2017 15:33:01 -0500 Subject: Fix _get_instruction_alignment type. --- python/architecture.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/architecture.py b/python/architecture.py index 41a130bf..ed03a6e6 100644 --- a/python/architecture.py +++ b/python/architecture.py @@ -424,7 +424,7 @@ class Architecture(object): log.log_error(traceback.format_exc()) return 4 - def __get_instruction_alignment(self, ctxt): + def _get_instruction_alignment(self, ctxt): try: return self.__class__.instr_alignment except: -- cgit v1.3.1 From 661581594a014ceadc6284ef8c907162ef17380e Mon Sep 17 00:00:00 2001 From: David Barksdale Date: Tue, 14 Nov 2017 14:05:22 -0600 Subject: Cache Platform object and not handle --- python/function.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/function.py b/python/function.py index bec3c2ad..9547e34a 100644 --- a/python/function.py +++ b/python/function.py @@ -378,8 +378,8 @@ class Function(object): plat = core.BNGetFunctionPlatform(self.handle) if plat is None: return None - self._platform = plat - return platform.Platform(None, handle = plat) + self._platform = platform.Platform(None, handle = plat) + return self._platform @property def start(self): -- cgit v1.3.1 From 9c53cec0d232d36ff56b91cd90b3837a0015b615 Mon Sep 17 00:00:00 2001 From: Nick Fox Date: Sun, 19 Nov 2017 15:57:31 -0500 Subject: Add missing quotes to fix issue with broken .desktop file --- scripts/linux-setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/linux-setup.sh b/scripts/linux-setup.sh index 8bf15ddd..0b23bbb0 100755 --- a/scripts/linux-setup.sh +++ b/scripts/linux-setup.sh @@ -83,11 +83,11 @@ Comment=${APPCOMMENT} EOF if [ "${ROOT}" == "root" ] then - echo ${DESKTOP} | $SUDO tee ${DESKTOPFILE} >/dev/null + echo "${DESKTOP}" | $SUDO tee ${DESKTOPFILE} >/dev/null $SUDO chmod +x ${DESKTOPFILE} $SUDO update-desktop-database ${SHARE}/applications else - echo ${DESKTOP} > ${HOME}/Desktop/${APP}.desktop + echo "${DESKTOP}" > ${HOME}/Desktop/${APP}.desktop fi } -- cgit v1.3.1 From 5d502ffe11df31f9671c43df293db9fa390026f6 Mon Sep 17 00:00:00 2001 From: Nick Fox Date: Sun, 19 Nov 2017 16:17:09 -0500 Subject: Fix incorrect BNPATH: previously pointed to /scripts --- scripts/linux-setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/linux-setup.sh b/scripts/linux-setup.sh index 0b23bbb0..02af9623 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" -- cgit v1.3.1 From d9e2d2ff81ac214ed8296507b5564a6b76f90596 Mon Sep 17 00:00:00 2001 From: Nick Fox Date: Sun, 19 Nov 2017 16:29:26 -0500 Subject: Fix bugs in setup script by removing unneeded sudo conditionals --- scripts/linux-setup.sh | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/scripts/linux-setup.sh b/scripts/linux-setup.sh index 02af9623..e18082e1 100755 --- a/scripts/linux-setup.sh +++ b/scripts/linux-setup.sh @@ -81,14 +81,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() @@ -108,16 +103,12 @@ createmime() -"| $SUDO tee ${MIMEFILE} >/dev/null +"| $SUDO tee ${MIMEFILEbinary} >/dev/null #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 +118,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 } -- cgit v1.3.1 From b86e60ffa3e95f0470a8f10828b38006b20b33cd Mon Sep 17 00:00:00 2001 From: Nick Fox Date: Sun, 19 Nov 2017 19:31:31 -0500 Subject: Fix typo in MIME filename introduced in last commit --- scripts/linux-setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/linux-setup.sh b/scripts/linux-setup.sh index e18082e1..3409d094 100755 --- a/scripts/linux-setup.sh +++ b/scripts/linux-setup.sh @@ -103,7 +103,7 @@ createmime() -"| $SUDO tee ${MIMEFILEbinary} >/dev/null +"| $SUDO tee ${MIMEFILE} >/dev/null #echo Copying icon #$SUDO cp $PNG $IMAGEFILE -- cgit v1.3.1 From 9850719b95278ff9890fff3551623635404b4f0c Mon Sep 17 00:00:00 2001 From: Nick Fox Date: Sun, 19 Nov 2017 20:18:36 -0500 Subject: Remove unnecessary trailing slash in BNPATH --- scripts/linux-setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/linux-setup.sh b/scripts/linux-setup.sh index 3409d094..c0e3697f 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" -- cgit v1.3.1 From adfddcf0ce0875df4512cd05a58cd1d5bc7e49d5 Mon Sep 17 00:00:00 2001 From: Nick Fox Date: Sun, 19 Nov 2017 22:06:36 -0500 Subject: Check python version and use python2 if python3 is default --- scripts/linux-setup.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/linux-setup.sh b/scripts/linux-setup.sh index c0e3697f..c6e376ce 100755 --- a/scripts/linux-setup.sh +++ b/scripts/linux-setup.sh @@ -61,7 +61,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() -- cgit v1.3.1 From 8db4153af8182f9a3ef8b124a34860e5e4d16bcc Mon Sep 17 00:00:00 2001 From: Brian Potchik Date: Mon, 20 Nov 2017 11:50:34 -0500 Subject: Update Python API to display PossibleValues that are of type ConstantPointerValue. --- python/function.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/function.py b/python/function.py index 9547e34a..e9e5dcc9 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 "" % self.reg if self.type == RegisterValueType.ConstantValue: return "" % self.value + if self.type == RegisterValueType.ConstantPointerValue: + return "" % self.value if self.type == RegisterValueType.StackFrameOffset: return "" % self.offset if self.type == RegisterValueType.SignedRangeValue: -- cgit v1.3.1 From 3764c6efde43547a112e637c1bb80ec5dbf1919c Mon Sep 17 00:00:00 2001 From: Jordan Wiens Date: Tue, 21 Nov 2017 14:30:40 -0500 Subject: @GeneralBisons suggested fix until libcurl/libssl are included --- docs/guide/troubleshooting.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/guide/troubleshooting.md b/docs/guide/troubleshooting.md index c1b3a910..593e50b4 100644 --- a/docs/guide/troubleshooting.md +++ b/docs/guide/troubleshooting.md @@ -67,9 +67,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): -- cgit v1.3.1 From db7fbfe8029ecf9126a2cb0e7b0d2c372fe47daa Mon Sep 17 00:00:00 2001 From: Andrew Lamoureux Date: Tue, 21 Nov 2017 16:33:51 -0500 Subject: example: use arch plugins for cmdline disassembler --- examples/cmdline_disasm/Makefile | 51 +++++++++++ examples/cmdline_disasm/src/disasm.cpp | 152 +++++++++++++++++++++++++++++++++ 2 files changed, 203 insertions(+) create mode 100644 examples/cmdline_disasm/Makefile create mode 100644 examples/cmdline_disasm/src/disasm.cpp 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 +#include +#include +#include + +#include +#include + +#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 ...\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='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; +} + -- cgit v1.3.1 From eb862da7472ed36e584a59329dbc56a4de7be017 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Fri, 24 Nov 2017 10:29:18 -0500 Subject: Adding API's to get Linux CA bundle info --- binaryninjaapi.cpp | 18 ++++++++++++++++++ binaryninjaapi.h | 3 +++ binaryninjacore.h | 2 ++ 3 files changed, 23 insertions(+) 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 4f62ef5f..e4ef4c43 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -3581,4 +3581,7 @@ namespace BinaryNinja bool IsArray() const; bool IsKeyValueStore() const; }; + + std::string GetLinuxCADirectory(); + std::string GetLinuxCABundlePath(); } diff --git a/binaryninjacore.h b/binaryninjacore.h index cb99958c..82198efd 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -3185,6 +3185,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 -- cgit v1.3.1 From 7dee9c4f68147bd88d1c60577912c3a91c510331 Mon Sep 17 00:00:00 2001 From: Jordan Wiens Date: Wed, 29 Nov 2017 10:55:05 -0500 Subject: update OS X troubleshooting docs for old unsupported versions --- docs/guide/troubleshooting.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/guide/troubleshooting.md b/docs/guide/troubleshooting.md index 593e50b4..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]. -- cgit v1.3.1 From 448ffe2842b2b1e0d21f905403489d3f865672d8 Mon Sep 17 00:00:00 2001 From: Brian Potchik Date: Mon, 4 Dec 2017 13:12:06 -0500 Subject: Add MediumLevelIL Function Recognizer. --- binaryninjaapi.h | 2 ++ binaryninjacore.h | 1 + functionrecognizer.cpp | 18 ++++++++++++++++++ python/functionrecognizer.py | 15 +++++++++++++++ 4 files changed, 36 insertions(+) diff --git a/binaryninjaapi.h b/binaryninjaapi.h index e4ef4c43..baeb5de6 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2951,6 +2951,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(); @@ -2959,6 +2960,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 diff --git a/binaryninjacore.h b/binaryninjacore.h index 82198efd..7a0e585e 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1191,6 +1191,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 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 dataObj = new BinaryView(BNNewViewReference(data)); + Ref funcObj = new Function(BNNewFunctionReference(func)); + Ref 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(®); } @@ -52,6 +63,7 @@ void FunctionRecognizer::RegisterArchitectureFunctionRecognizer(Architecture* ar BNFunctionRecognizer reg; reg.context = recog; reg.recognizeLowLevelIL = RecognizeLowLevelILCallback; + reg.recognizeMediumLevelIL = RecognizeMediumLevelILCallback; BNRegisterArchitectureFunctionRecognizer(arch->GetObject(), ®); } @@ -60,3 +72,9 @@ bool FunctionRecognizer::RecognizeLowLevelIL(BinaryView*, Function*, LowLevelILF { return false; } + + +bool FunctionRecognizer::RecognizeMediumLevelIL(BinaryView*, Function*, MediumLevelILFunction*) +{ + return false; +} 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 -- cgit v1.3.1 From 10cf74045e1e2495813597a499dee4fb4baf601f Mon Sep 17 00:00:00 2001 From: Brian Potchik Date: Mon, 4 Dec 2017 13:23:26 -0500 Subject: Better Architecture Transition Support. --- architecture.cpp | 1 + binaryninjacore.h | 1 + python/architecture.py | 2 ++ python/function.py | 1 + 4 files changed, 5 insertions(+) diff --git a/architecture.cpp b/architecture.cpp index 17d02909..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; } diff --git a/binaryninjacore.h b/binaryninjacore.h index 7a0e585e..1bb0c70a 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -973,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]; diff --git a/python/architecture.py b/python/architecture.py index ed03a6e6..a893c1d4 100644 --- a/python/architecture.py +++ b/python/architecture.py @@ -462,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)): @@ -1163,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/function.py b/python/function.py index e9e5dcc9..58bee8f4 100644 --- a/python/function.py +++ b/python/function.py @@ -1755,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 = [] -- cgit v1.3.1 From 78a9a6fd52cb36e1e2fddfb0cbaf4f56a6b8016e Mon Sep 17 00:00:00 2001 From: David Barksdale Date: Tue, 5 Dec 2017 11:34:32 -0600 Subject: Add __eq__ and __hash__ to BasicBlockEdge --- python/basicblock.py | 8 ++++++++ 1 file changed, 8 insertions(+) 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 -- cgit v1.3.1 From 859b86c233a8783f134c498b9c32ea1826ed4503 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Tue, 12 Dec 2017 11:02:19 -0500 Subject: Add fixes for x86_extension wrapper --- examples/x86_extension/src/x86_extension.cpp | 102 ++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 2 deletions(-) diff --git a/examples/x86_extension/src/x86_extension.cpp b/examples/x86_extension/src/x86_extension.cpp index 076551ab..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 @@ -350,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 @@ -361,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, @@ -490,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(); -- cgit v1.3.1 From fc96aa9e5058a0b064bbdeb20e85e951eb2b7703 Mon Sep 17 00:00:00 2001 From: Brian Potchik Date: Tue, 12 Dec 2017 17:09:40 -0500 Subject: Modify Hash Functions. --- lowlevelilinstruction.h | 8 ++++---- mediumlevelilinstruction.h | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) 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); } }; -- cgit v1.3.1 From 565dd968745465d3ab939303056431bf9fa2f924 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Thu, 14 Dec 2017 15:13:54 -0500 Subject: Fix multi-line execution in python console --- python/scriptingprovider.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/scriptingprovider.py b/python/scriptingprovider.py index f9758cc9..8645c96c 100644 --- a/python/scriptingprovider.py +++ b/python/scriptingprovider.py @@ -547,7 +547,7 @@ 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) + self.interpreter.runcode(code) if self.locals["here"] != self.active_addr: if not self.active_view.file.navigate(self.active_view.file.view, self.locals["here"]): -- cgit v1.3.1 From ae5ce4da4c1f6ea3a071a4eec1a5da3e6e2a3305 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Thu, 14 Dec 2017 18:38:57 -0500 Subject: Fix multi-line insertion and single expression evalutation --- python/scriptingprovider.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/python/scriptingprovider.py b/python/scriptingprovider.py index 8645c96c..761b359c 100644 --- a/python/scriptingprovider.py +++ b/python/scriptingprovider.py @@ -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.runcode(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"]): -- cgit v1.3.1 From b207c76729df133c7b6fc4bc9f1abb6948ae6438 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Thu, 14 Dec 2017 18:46:10 -0500 Subject: Add autoDefined attribute to Sections and Segments --- binaryninjaapi.h | 2 ++ binaryninjacore.h | 2 ++ binaryview.cpp | 2 +- python/binaryview.py | 17 ++++++++++------- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/binaryninjaapi.h b/binaryninjaapi.h index baeb5de6..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; diff --git a/binaryninjacore.h b/binaryninjacore.h index 1bb0c70a..245e6353 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1531,6 +1531,7 @@ extern "C" uint64_t start, length; uint64_t dataOffset, dataLength; uint32_t flags; + bool autoDefined; }; enum BNSectionSemantics @@ -1551,6 +1552,7 @@ extern "C" uint64_t infoData; uint64_t align, entrySize; BNSectionSemantics semantics; + bool autoDefined; }; struct BNAddressRange diff --git a/binaryview.cpp b/binaryview.cpp index 0a082458..50011a0f 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -1724,6 +1724,7 @@ vector 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); } @@ -1731,7 +1732,6 @@ vector BinaryView::GetSegments() return result; } - bool BinaryView::GetSegmentAt(uint64_t addr, Segment& result) { BNSegment segment; diff --git a/python/binaryview.py b/python/binaryview.py index 9f149ba8..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): @@ -965,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 @@ -979,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 @@ -3353,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): @@ -3386,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 @@ -3395,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 -- cgit v1.3.1 From b64d65be48ba44d9c2b564d88aec15430fd289df Mon Sep 17 00:00:00 2001 From: toolCHAINZ Date: Thu, 14 Dec 2017 19:07:25 -0500 Subject: Fix PluginManager Doc Example (#885) Fix doc string example for add_repository --- python/pluginmanager.py | 1 - 1 file changed, 1 deletion(-) 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 >>> -- cgit v1.3.1 From 4862340bc92c7bcde9d377cbf7cff1417a39509e Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Fri, 15 Dec 2017 09:56:59 -0500 Subject: Make multi-line python input more robust --- python/scriptingprovider.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/python/scriptingprovider.py b/python/scriptingprovider.py index 761b359c..6b03d49e 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: @@ -548,7 +548,7 @@ class PythonScriptingInstance(ScriptingInstance): self.locals["current_mlil"] = self.active_func.medium_level_il for line in code.split("\n"): - self.interpreter.push(line) + self.interpreter.push(line + "\n") if self.locals["here"] != self.active_addr: if not self.active_view.file.navigate(self.active_view.file.view, self.locals["here"]): -- cgit v1.3.1 From 89a1e8d47efbf85055b5053823d77d67c54e074e Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Fri, 15 Dec 2017 16:12:34 -0500 Subject: Adding documentation for linux CA path settings --- docs/getting-started.md | 2 ++ 1 file changed, 2 insertions(+) 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) | -- cgit v1.3.1 From 0963fc9e3623f9758afb63b4b089a0fa7873c395 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Mon, 18 Dec 2017 11:43:43 -0500 Subject: Remove newline from split lines as it breaks more than it fixes --- python/scriptingprovider.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/scriptingprovider.py b/python/scriptingprovider.py index 6b03d49e..c92c249a 100644 --- a/python/scriptingprovider.py +++ b/python/scriptingprovider.py @@ -548,7 +548,7 @@ class PythonScriptingInstance(ScriptingInstance): self.locals["current_mlil"] = self.active_func.medium_level_il for line in code.split("\n"): - self.interpreter.push(line + "\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"]): -- cgit v1.3.1 From 26edabfdd7211012c7c8a03186d3025eea9aa345 Mon Sep 17 00:00:00 2001 From: Jordan Wiens Date: Wed, 20 Dec 2017 16:12:15 -0500 Subject: fixes broken lastrun creation --- scripts/linux-setup.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/linux-setup.sh b/scripts/linux-setup.sh index c6e376ce..bb1e0f28 100755 --- a/scripts/linux-setup.sh +++ b/scripts/linux-setup.sh @@ -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 } -- cgit v1.3.1