diff --git a/plugins/bap/plugins/__init__.py b/plugins/bap/plugins/__init__.py index f827183..78b4514 100644 --- a/plugins/bap/plugins/__init__.py +++ b/plugins/bap/plugins/__init__.py @@ -1,4 +1,4 @@ """This module contains all the plugins that will be loaded by BAP-Loader.""" -__all__ = ('bap_bir_attr', 'bap_taint', 'bap_view', 'pseudocode_bap_comment', +__all__ = ('bap_bir_attr', 'bap_taint_ptr', 'bap_taint_reg' 'bap_view', 'pseudocode_bap_comment', 'pseudocode_bap_taint') diff --git a/plugins/bap/plugins/bap_bir_attr.py b/plugins/bap/plugins/bap_bir_attr.py index bef2bc7..5aa1112 100644 --- a/plugins/bap/plugins/bap_bir_attr.py +++ b/plugins/bap/plugins/bap_bir_attr.py @@ -73,7 +73,10 @@ def run(self, arg): """ args_msg = "Arguments that will be passed to `bap'" - + # If a user is not fast enough in providing the answer + # IDA Python will popup a modal window that will block + # a user from providing the answer. + idaapi.disable_script_timeout() args = idaapi.askstr(ARGS_HISTORY, '--passes=', args_msg) if args is None: return diff --git a/plugins/bap/plugins/bap_taint_ptr.py b/plugins/bap/plugins/bap_taint_ptr.py index 02b852e..0edb3fd 100644 --- a/plugins/bap/plugins/bap_taint_ptr.py +++ b/plugins/bap/plugins/bap_taint_ptr.py @@ -1,4 +1,4 @@ -from bap.plugins.bap_taint import BapTaint +from bap.utils.bap_taint import BapTaint class BapTaintPtr(BapTaint): wanted_hotkey = "Ctrl-Shift-A" diff --git a/plugins/bap/plugins/bap_taint_reg.py b/plugins/bap/plugins/bap_taint_reg.py index 85d796f..557693c 100644 --- a/plugins/bap/plugins/bap_taint_reg.py +++ b/plugins/bap/plugins/bap_taint_reg.py @@ -1,4 +1,4 @@ -from bap.plugins.bap_taint import BapTaint +from bap.utils.bap_taint import BapTaint class BapTaintReg(BapTaint): wanted_hotkey = "Shift-A" diff --git a/plugins/bap/plugins/pseudocode_bap_taint.py b/plugins/bap/plugins/pseudocode_bap_taint.py index 8cc63c3..b6b6b42 100644 --- a/plugins/bap/plugins/pseudocode_bap_taint.py +++ b/plugins/bap/plugins/pseudocode_bap_taint.py @@ -8,7 +8,7 @@ import idaapi from bap.utils import hexrays -from bap.plugins.bap_taint import BapTaint +from bap.utils.bap_taint import BapTaint colors = { 'black': 0x000000, diff --git a/plugins/bap/utils/__init__.py b/plugins/bap/utils/__init__.py index 42ba074..87da377 100644 --- a/plugins/bap/utils/__init__.py +++ b/plugins/bap/utils/__init__.py @@ -1,4 +1,4 @@ """Commonly used utilities.""" __all__ = ('sexpr', 'bap_comment', 'run', 'ida', 'abstract_ida_plugins', - 'config') + 'config', 'bap_taint') diff --git a/plugins/bap/plugins/bap_taint.py b/plugins/bap/utils/bap_taint.py similarity index 72% rename from plugins/bap/plugins/bap_taint.py rename to plugins/bap/utils/bap_taint.py index a2be4b0..0187422 100644 --- a/plugins/bap/plugins/bap_taint.py +++ b/plugins/bap/utils/bap_taint.py @@ -18,7 +18,6 @@ import idaapi import idc from bap.utils.run import BapIda -from bap.utils.abstract_ida_plugins import DoNothing patterns = [ ('true', 'gray'), @@ -27,23 +26,45 @@ ('taints', 'yellow') ] +ENGINE_HISTORY=117342 + +ask_engine='What engine would you like, primus or legacy?' +ask_depth='For how many RTL instructions to propagate?' + class PropagateTaint(BapIda): ENGINE='primus' + DEPTH=4096 + LOOP_DEPTH=64 "Propagate taint information using BAP" def __init__(self, addr, kind): super(PropagateTaint,self).__init__() + # If a user is not fast enough in providing the answer + # IDA Python will popup a modal window that will block + # a user from providing the answer. + idaapi.disable_script_timeout() + + engine = idaapi.askstr(ENGINE_HISTORY, self.ENGINE, ask_engine) \ + or self.ENGINE + depth = idaapi.asklong(self.DEPTH, ask_depth) \ + or self.DEPTH + + # don't ask for the loop depth as a user is already annoyed. + loop_depth = self.LOOP_DEPTH - self.action = 'taint propagating from {:s}0x{:X}'.format( + self.action = 'propagating taint from {:s}0x{:X}'.format( '*' if kind == 'ptr' else '', addr) - propagate = 'run' if self.ENGINE == 'primus' else 'propagate-taint' + propagate = 'run' if engine == 'primus' else 'propagate-taint' self.passes = ['taint', propagate, 'map-terms','emit-ida-script'] self.script = self.tmpfile('py') scheme = self.tmpfile('scm') + stdin=self.tmpfile('stdin') + stdout=self.tmpfile('stdout') for (pat,color) in patterns: scheme.write('(({0}) (color {1}))\n'.format(pat,color)) scheme.close() + name = idc.GetFunctionName(addr) self.args += [ '--taint-'+kind, '0x{:X}'.format(addr), @@ -53,16 +74,22 @@ def __init__(self, addr, kind): '--emit-ida-script-file', self.script.name ] - if self.ENGINE == 'primus': + if engine == 'primus': self.args += [ - '--run-entry-points=all-subroutines', - '--primus-limit-max-length=100', - '--primus-propagate-taint-run', + '--run-entry-points={}'.format(name), + '--primus-limit-max-length={}'.format(depth), + '--primus-limit-max-visited={}'.format(loop_depth), '--primus-promiscuous-mode', - '--primus-greedy-scheduler' + '--primus-greedy-scheduler', + '--primus-propagate-taint-from-attributes', + '--primus-propagate-taint-to-attributes', + '--primus-lisp-channel-redirect=:{0},:{1}'.format( + stdin.name, + stdout.name) ] + class BapTaint(idaapi.plugin_t): flags = 0 comment = "BAP Taint Plugin" @@ -139,10 +166,3 @@ def install_callback(cls, callback_fn, ptr_or_reg=None): else: idc.Fatal("Invalid ptr_or_reg value passed {}". format(repr(ptr_or_reg))) - -class BapTaintStub(DoNothing): - pass - - -def PLUGIN_ENTRY(): - return BapTaintStub() diff --git a/plugins/plugin_loader_bap.py b/plugins/plugin_loader_bap.py index 33b1397..da94ed6 100644 --- a/plugins/plugin_loader_bap.py +++ b/plugins/plugin_loader_bap.py @@ -1,6 +1,7 @@ """Loads all possible BAP IDA Python plugins.""" - - +import os +import bap.plugins +import bap.utils.run import idaapi @@ -15,24 +16,22 @@ class bap_loader(idaapi.plugin_t): def init(self): """Read directory and load as many plugins as possible.""" - import os - import bap.plugins - import bap.utils.run - import idaapi + self.plugins = [] idaapi.msg("BAP Loader activated\n") bap.utils.run.check_and_configure_bap() plugin_path = os.path.dirname(bap.plugins.__file__) - idaapi.msg("Loading plugins from {}\n".format(plugin_path)) + idaapi.msg("BAP> Loading plugins from {}\n".format(plugin_path)) for plugin in sorted(os.listdir(plugin_path)): path = os.path.join(plugin_path, plugin) if not plugin.endswith('.py') or plugin.startswith('__'): continue # Skip non-plugins - idaapi.load_plugin(path) - return idaapi.PLUGIN_SKIP # The loader will be called whenever needed + idc.Message('BAP> Loading {}\n'.format(plugin)) + self.plugins.append(idaapi.load_plugin(path)) + return idaapi.PLUGIN_KEEP def term(self): """Ignored."""