Skip to content

Commit

Permalink
updates to BAP 1.4 release
Browse files Browse the repository at this point in the history
In this update we are relying on the new Primus Taint Analysis
Framework to provide us data-flow information via the
`primus-propagate-taint` compatibility layer. We allow a user to
select the taint propagation engine, as well as its parameters.

This commit also moves the bap_taint module to the utilities package,
as otherwise it is loaded multiple times by each plugin separatly that
may lead to unexpected results (don't ask me what are they)

There is also a small fix that prevents the racing condition between
askXXX dialogs and IDA Python breakability facility.

The merge of this PR is blocked until
BinaryAnalysisPlatform/bap#784 is merged
  • Loading branch information
ivg committed Feb 27, 2018
1 parent dc1d0c6 commit 5d74602
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 30 deletions.
2 changes: 1 addition & 1 deletion plugins/bap/plugins/__init__.py
Original file line number Diff line number Diff line change
@@ -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')
5 changes: 4 additions & 1 deletion plugins/bap/plugins/bap_bir_attr.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion plugins/bap/plugins/bap_taint_ptr.py
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
2 changes: 1 addition & 1 deletion plugins/bap/plugins/bap_taint_reg.py
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
2 changes: 1 addition & 1 deletion plugins/bap/plugins/pseudocode_bap_taint.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion plugins/bap/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Commonly used utilities."""

__all__ = ('sexpr', 'bap_comment', 'run', 'ida', 'abstract_ida_plugins',
'config')
'config', 'bap_taint')
50 changes: 35 additions & 15 deletions plugins/bap/plugins/bap_taint.py → plugins/bap/utils/bap_taint.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand All @@ -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),
Expand All @@ -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=<stdin>:{0},<stdout>:{1}'.format(
stdin.name,
stdout.name)
]



class BapTaint(idaapi.plugin_t):
flags = 0
comment = "BAP Taint Plugin"
Expand Down Expand Up @@ -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()
17 changes: 8 additions & 9 deletions plugins/plugin_loader_bap.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Loads all possible BAP IDA Python plugins."""


import os
import bap.plugins
import bap.utils.run
import idaapi


Expand All @@ -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."""
Expand Down

0 comments on commit 5d74602

Please sign in to comment.