This repository has been archived by the owner on Jun 7, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
/
vbin.py
140 lines (121 loc) · 4.71 KB
/
vbin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# -*- coding: utf-8 -*-
# This file is part of Viper - https://github.com/viper-framework/viper
# See the file 'LICENSE' for copying permission.
import os
from viper.common.abstracts import Module
from viper.core.session import __sessions__
try:
import idb
HAVE_PYIDB = True
except ImportError:
HAVE_PYIDB = False
class vBin(Module):
cmd = 'vbin'
description = 'Viper binary analysis (vBin) module to inspect the sample'
authors = ['emdel']
def __init__(self):
super(vBin, self).__init__()
subparsers = self.parser.add_subparsers(dest='subname')
subparsers.add_parser('functions', help='List functions in the IDB')
disass_parser = subparsers.add_parser('disass', help='Disassemble functions from the IDB')
disass_parser.add_argument('-f', '--function', help='Specify the function name')
calls_parser = subparsers.add_parser('calls', help='List calls inside a function')
calls_parser.add_argument('-f', '--function', help='Specify the function name')
def get_current_file_dir(self, filename):
return filename + ".dir"
def get_current_idb_path(self, path):
return os.path.join(path, "executable.idb")
def get_current_idb_path64(self, path):
return os.path.join(path, "executable.i64")
def get_db(self, current_idb):
h_idb = open(current_idb, "rb")
idb_data = h_idb.read()
h_idb.close()
return idb.from_buffer(idb_data)
def list_functions(self, db):
api = idb.IDAPython(db)
for ea in api.idautils.Functions():
name = api.idc.GetFunctionName(ea)
self.log('info', "%x: %s" % (ea, name))
def disass(self, db, func_name):
api = idb.IDAPython(db)
found = 0
for ea in api.idautils.Functions():
name = api.idc.GetFunctionName(ea)
if name == func_name:
found = 1
break
if found == 0:
self.log('error', "Function %s not found" % func_name)
return
fx_start = ea
fx_end = api.ida_funcs.get_func(fx_start).endEA
self.log("info", "Function start at: %x" % fx_start)
self.log("info", "Function end at: %x" % fx_end)
heads = []
heads.append(fx_start)
for addr in range(fx_start, fx_end):
a = api.idc.NextHead(addr)
heads.append(a)
for h in sorted(set(heads)):
try:
op = api.idc._disassemble(h)
code = "{0}: {1} {2}".format(hex(h), op.mnemonic, op.op_str)
print(code)
except (ValueError, RuntimeError) as error:
self.log("error", error)
continue
def show_calls(self, db, func_name):
api = idb.IDAPython(db)
found = 0
for ea in api.idautils.Functions():
name = api.idc.GetFunctionName(ea)
if name == func_name:
found = 1
break
if found == 0:
self.log('error', "Function %s not found" % func_name)
return
fx_start = ea
fx_end = api.ida_funcs.get_func(fx_start).endEA
heads = []
for addr in range(fx_start, fx_end):
a = api.idc.NextHead(addr)
heads.append(a)
for h in set(heads):
try:
op = api.idc._disassemble(h)
if op.mnemonic != "call":
continue
code = "{0}: {1} {2}".format(hex(h), op.mnemonic, op.op_str)
print(code)
except Exception:
continue
def run(self):
super(vBin, self).run()
if self.args is None:
return
if not HAVE_PYIDB:
self.log('error', "Missing dependancy, install python-idb")
return
if not __sessions__.is_set():
self.log('error', "No open session. This command expects a file to be open.")
return
current_file = __sessions__.current.file.path
current_dir = self.get_current_file_dir(current_file)
current_idb = self.get_current_idb_path(current_dir)
if not os.path.exists(current_idb):
current_idb = self.get_current_idb_path64(current_dir)
# Loading IDB
db = self.get_db(current_idb)
if self.args.subname == "functions":
self.list_functions(db)
elif self.args.subname == "disass":
func_name = self.args.function
self.disass(db, func_name)
elif self.args.subname == "calls":
func_name = self.args.function
self.show_calls(db, func_name)
else:
self.log('error', 'At least one of the parameters is required')
self.usage()