Skip to content

Commit 289fd86

Browse files
committed
fixes and enhances function recover plugin
The function recovery plugin was broken for some amount of time, as we passed symbol file to bap, effectively disabling BAP own function finding capabilities, so bap always returned the same amount of function starts. This commit also enhances the recovery plugin, by lowering the recovery threshold. Although it will lead to more false positives it is acceptable since IDA will ignore function starts that occur in a body of an discovered function, that was already discovered and disassembled. Since most of the functions have their bodies after starts, we added sorting of the addresses, so that function starts are added to the system in the ascending order. This commit also adds two new attributes to the BapIda class. The first one is called [args] and is a list of default arguments, shared by all instances. It is useful to adapt the behavior of the plugins to your needs, and to perform fast prototyping and debugging. The second attribute is called [plugins] and it contains a list of available BAP plugins. This is useful, when an IDA plugin needs to adapt its behavior based on the presence of particular BAP plugins. For example, the function start identification plugin, is allowed to tackle with the byteweight parameters only if it is installed.
1 parent d0d7bf8 commit 289fd86

File tree

2 files changed

+32
-11
lines changed

2 files changed

+32
-11
lines changed

plugins/bap/plugins/bap_functions.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,32 @@
1010
import idaapi
1111
import idc
1212

13+
from heapq import heappush, heappop
1314
from bap.utils.run import BapIda
1415

1516

1617
class FunctionFinder(BapIda):
1718
def __init__(self):
18-
super(FunctionFinder, self).__init__()
19+
super(FunctionFinder, self).__init__(symbols=False)
1920
self.action = 'looking for function starts'
2021
self.syms = self.tmpfile('syms', mode='r')
2122
self.args += [
2223
'--print-symbol-format', 'addr',
2324
'--dump', 'symbols:{0}'.format(self.syms.name)
2425
]
2526

27+
# we can be a little bit more promiscuous since IDA will ignore
28+
# function starts that occur in the middle of a function
29+
if 'byteweight' in self.plugins and not \
30+
'--no-byteweight' in self.args:
31+
self.args += [
32+
'--byteweight-threshold', '0.5',
33+
'--byteweight-length', '4',
34+
]
35+
2636

2737
class BAP_Functions(idaapi.plugin_t):
28-
"""Plugin to get functions from BAP and mark them in IDA."""
38+
"""Uses BAP to find missed functions"""
2939

3040
flags = idaapi.PLUGIN_FIX
3141
comment = "BAP Functions Plugin"
@@ -40,15 +50,13 @@ def mark_functions(self):
4050
analysis.run()
4151

4252
def add_starts(self, bap):
43-
idaapi.refresh_idaview_anyway()
53+
syms = []
4454
for line in bap.syms:
45-
line = line.strip()
46-
if len(line) == 0:
47-
continue
48-
addr = int(line, 16)
49-
end_addr = idaapi.BADADDR
50-
idaapi.add_func(addr, end_addr)
55+
heappush(syms, int(line, 16))
56+
for i in range(len(syms)):
57+
idaapi.add_func(heappop(syms), idaapi.BADADDR)
5158
idc.Refresh()
59+
idaapi.refresh_idaview_anyway()
5260

5361
def init(self):
5462
"""Initialize Plugin."""

plugins/bap/utils/run.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,24 @@ class Bap(object):
2323
2424
We will try to keep it clean from IDA
2525
specifics, so that later we can lift it to the bap-python library
26+
27+
Attributes:
28+
29+
DEBUG print executed commands and keep temporary files
30+
args default arguments, inserted after `bap <input>`
31+
plugins a list of available plugins
2632
"""
2733

2834
DEBUG = False
2935

36+
args = []
37+
38+
plugins = []
39+
3040
def __init__(self, bap, input_file):
3141
"""Sandbox for the BAP process.
3242
33-
Each process is sandboxed, so that all intermediated data is
43+
Each process is sandboxed, so that all intermediate data are
3444
stored in a temporary directory.
3545
3646
instance variables:
@@ -50,7 +60,7 @@ def __init__(self, bap, input_file):
5060
5161
"""
5262
self.tmpdir = tempfile.mkdtemp(prefix="bap")
53-
self.args = [bap, input_file]
63+
self.args = [bap, input_file] + self.args
5464
self.proc = None
5565
self.fds = []
5666
self.out = self.tmpfile("out")
@@ -59,6 +69,9 @@ def __init__(self, bap, input_file):
5969
self.env = {'BAP_LOG_DIR': self.tmpdir}
6070
if self.DEBUG:
6171
self.env['BAP_DEBUG'] = 'yes'
72+
if not Bap.plugins:
73+
with os.popen(bap + ' --list-plugins') as out:
74+
Bap.plugins = [e.split()[1] for e in out]
6275

6376
def run(self):
6477
"starts BAP process"

0 commit comments

Comments
 (0)