Skip to content

Commit 5d74602

Browse files
committed
updates to BAP 1.4 release
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
1 parent dc1d0c6 commit 5d74602

8 files changed

+52
-30
lines changed

plugins/bap/plugins/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
"""This module contains all the plugins that will be loaded by BAP-Loader."""
22

3-
__all__ = ('bap_bir_attr', 'bap_taint', 'bap_view', 'pseudocode_bap_comment',
3+
__all__ = ('bap_bir_attr', 'bap_taint_ptr', 'bap_taint_reg' 'bap_view', 'pseudocode_bap_comment',
44
'pseudocode_bap_taint')

plugins/bap/plugins/bap_bir_attr.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,10 @@ def run(self, arg):
7373
"""
7474

7575
args_msg = "Arguments that will be passed to `bap'"
76-
76+
# If a user is not fast enough in providing the answer
77+
# IDA Python will popup a modal window that will block
78+
# a user from providing the answer.
79+
idaapi.disable_script_timeout()
7780
args = idaapi.askstr(ARGS_HISTORY, '--passes=', args_msg)
7881
if args is None:
7982
return

plugins/bap/plugins/bap_taint_ptr.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from bap.plugins.bap_taint import BapTaint
1+
from bap.utils.bap_taint import BapTaint
22

33
class BapTaintPtr(BapTaint):
44
wanted_hotkey = "Ctrl-Shift-A"

plugins/bap/plugins/bap_taint_reg.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from bap.plugins.bap_taint import BapTaint
1+
from bap.utils.bap_taint import BapTaint
22

33
class BapTaintReg(BapTaint):
44
wanted_hotkey = "Shift-A"

plugins/bap/plugins/pseudocode_bap_taint.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import idaapi
99

1010
from bap.utils import hexrays
11-
from bap.plugins.bap_taint import BapTaint
11+
from bap.utils.bap_taint import BapTaint
1212

1313
colors = {
1414
'black': 0x000000,

plugins/bap/utils/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
"""Commonly used utilities."""
22

33
__all__ = ('sexpr', 'bap_comment', 'run', 'ida', 'abstract_ida_plugins',
4-
'config')
4+
'config', 'bap_taint')

plugins/bap/plugins/bap_taint.py renamed to plugins/bap/utils/bap_taint.py

+35-15
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import idaapi
1919
import idc
2020
from bap.utils.run import BapIda
21-
from bap.utils.abstract_ida_plugins import DoNothing
2221

2322
patterns = [
2423
('true', 'gray'),
@@ -27,23 +26,45 @@
2726
('taints', 'yellow')
2827
]
2928

29+
ENGINE_HISTORY=117342
30+
31+
ask_engine='What engine would you like, primus or legacy?'
32+
ask_depth='For how many RTL instructions to propagate?'
33+
3034
class PropagateTaint(BapIda):
3135
ENGINE='primus'
36+
DEPTH=4096
37+
LOOP_DEPTH=64
3238

3339
"Propagate taint information using BAP"
3440
def __init__(self, addr, kind):
3541
super(PropagateTaint,self).__init__()
42+
# If a user is not fast enough in providing the answer
43+
# IDA Python will popup a modal window that will block
44+
# a user from providing the answer.
45+
idaapi.disable_script_timeout()
46+
47+
engine = idaapi.askstr(ENGINE_HISTORY, self.ENGINE, ask_engine) \
48+
or self.ENGINE
49+
depth = idaapi.asklong(self.DEPTH, ask_depth) \
50+
or self.DEPTH
51+
52+
# don't ask for the loop depth as a user is already annoyed.
53+
loop_depth = self.LOOP_DEPTH
3654

37-
self.action = 'taint propagating from {:s}0x{:X}'.format(
55+
self.action = 'propagating taint from {:s}0x{:X}'.format(
3856
'*' if kind == 'ptr' else '',
3957
addr)
40-
propagate = 'run' if self.ENGINE == 'primus' else 'propagate-taint'
58+
propagate = 'run' if engine == 'primus' else 'propagate-taint'
4159
self.passes = ['taint', propagate, 'map-terms','emit-ida-script']
4260
self.script = self.tmpfile('py')
4361
scheme = self.tmpfile('scm')
62+
stdin=self.tmpfile('stdin')
63+
stdout=self.tmpfile('stdout')
4464
for (pat,color) in patterns:
4565
scheme.write('(({0}) (color {1}))\n'.format(pat,color))
4666
scheme.close()
67+
name = idc.GetFunctionName(addr)
4768

4869
self.args += [
4970
'--taint-'+kind, '0x{:X}'.format(addr),
@@ -53,16 +74,22 @@ def __init__(self, addr, kind):
5374
'--emit-ida-script-file', self.script.name
5475
]
5576

56-
if self.ENGINE == 'primus':
77+
if engine == 'primus':
5778
self.args += [
58-
'--run-entry-points=all-subroutines',
59-
'--primus-limit-max-length=100',
60-
'--primus-propagate-taint-run',
79+
'--run-entry-points={}'.format(name),
80+
'--primus-limit-max-length={}'.format(depth),
81+
'--primus-limit-max-visited={}'.format(loop_depth),
6182
'--primus-promiscuous-mode',
62-
'--primus-greedy-scheduler'
83+
'--primus-greedy-scheduler',
84+
'--primus-propagate-taint-from-attributes',
85+
'--primus-propagate-taint-to-attributes',
86+
'--primus-lisp-channel-redirect=<stdin>:{0},<stdout>:{1}'.format(
87+
stdin.name,
88+
stdout.name)
6389
]
6490

6591

92+
6693
class BapTaint(idaapi.plugin_t):
6794
flags = 0
6895
comment = "BAP Taint Plugin"
@@ -139,10 +166,3 @@ def install_callback(cls, callback_fn, ptr_or_reg=None):
139166
else:
140167
idc.Fatal("Invalid ptr_or_reg value passed {}".
141168
format(repr(ptr_or_reg)))
142-
143-
class BapTaintStub(DoNothing):
144-
pass
145-
146-
147-
def PLUGIN_ENTRY():
148-
return BapTaintStub()

plugins/plugin_loader_bap.py

+8-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Loads all possible BAP IDA Python plugins."""
2-
3-
2+
import os
3+
import bap.plugins
4+
import bap.utils.run
45
import idaapi
56

67

@@ -15,24 +16,22 @@ class bap_loader(idaapi.plugin_t):
1516

1617
def init(self):
1718
"""Read directory and load as many plugins as possible."""
18-
import os
19-
import bap.plugins
20-
import bap.utils.run
21-
import idaapi
19+
self.plugins = []
2220

2321
idaapi.msg("BAP Loader activated\n")
2422

2523
bap.utils.run.check_and_configure_bap()
2624

2725
plugin_path = os.path.dirname(bap.plugins.__file__)
28-
idaapi.msg("Loading plugins from {}\n".format(plugin_path))
26+
idaapi.msg("BAP> Loading plugins from {}\n".format(plugin_path))
2927

3028
for plugin in sorted(os.listdir(plugin_path)):
3129
path = os.path.join(plugin_path, plugin)
3230
if not plugin.endswith('.py') or plugin.startswith('__'):
3331
continue # Skip non-plugins
34-
idaapi.load_plugin(path)
35-
return idaapi.PLUGIN_SKIP # The loader will be called whenever needed
32+
idc.Message('BAP> Loading {}\n'.format(plugin))
33+
self.plugins.append(idaapi.load_plugin(path))
34+
return idaapi.PLUGIN_KEEP
3635

3736
def term(self):
3837
"""Ignored."""

0 commit comments

Comments
 (0)