This repository has been archived by the owner on Feb 21, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 250
/
init.py
executable file
·295 lines (251 loc) · 10.1 KB
/
init.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# -------------------------------------------------------------------------
#
# Copyright (C) 2017 Cisco Talos Security Intelligence and Research Group
#
# PyREBox: Python scriptable Reverse Engineering Sandbox
# Author: Xabier Ugarte-Pedrero
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
# -------------------------------------------------------------------------
import os.path
import os
from prettytable import PrettyTable
import sys
import ConfigParser
import traceback
from utils import ConfigurationManager as conf_m
from utils import pp_print
from utils import pp_debug
from utils import pp_warning
from utils import pp_error
import functools
# Python module initialization routine
# ====================================
# Module handle incremental counter, start at 0x1
MODULE_COUNTER = 0x0
modules = {}
class Module:
def __init__(self, _id, module_name):
self.__module_name = module_name
self.__module = None
self.__loaded = False
self.__id = _id
def get_module_name(self):
return self.__module_name
def is_loaded(self):
return (self.__loaded)
def load(self):
import api_internal
from ipython_shell import add_command
pp_print("[*] Loading python module %s\n" % self.__module_name)
self.__module = __import__(self.__module_name, fromlist=[''])
# Import other modules or plugins required by the module
if hasattr(self.__module, "requirements"):
for el in self.__module.requirements:
import_module(el)
self.__loaded = True
self.__module.initialize_callbacks(self.__id,
functools.partial(api_internal.print_internal, self.__module_name))
# Add commands declared by the module
for element in dir(self.__module):
if element.startswith("do_"):
add_command(element[3:], getattr(self.__module, element))
def reload(self):
import api_internal
from ipython_shell import add_command
if self.__module is not None:
pp_print("[*] Reloading python module %s\n" % self.__module_name)
if self.__loaded is True:
self.unload()
reload(self.__module)
# Add again commands and call initialize_callbacks:
self.__module.initialize_callbacks(self.__id,
functools.partial(api_internal.print_internal, self.__module_name))
# Add commands declared by the module
for element in dir(self.__module):
if element.startswith("do_"):
add_command(element[3:], getattr(self.__module, element))
self.__loaded = True
else:
pp_warning("[!] The module was not correctly imported!\n")
def unload(self):
from ipython_shell import remove_command
if self.__loaded is True:
pp_print("[*] Unloading %s\n" % self.__module_name)
# Add commands declared by the module
for element in dir(self.__module):
if element.startswith("do_"):
remove_command(element[3:])
self.__module.clean()
self.__loaded = False
else:
pp_warning("[*] Module %d is not loaded!\n" % self.__id)
def import_module(module_name):
global MODULE_COUNTER
try:
already_imported = False
for mod in modules:
if modules[mod].get_module_name() == module_name:
already_imported = True
break
if not already_imported:
MODULE_COUNTER += 1
modules[MODULE_COUNTER] = Module(MODULE_COUNTER, module_name)
modules[MODULE_COUNTER].load()
else:
pp_warning("[*] Module %s already imported, did you want to reload it instead?\n" % module_name)
except Exception as e:
pp_error("[!] Could not initialize python module due to exception\n")
pp_error(" %s\n" % str(e))
return
def reload_module(_id):
try:
if _id in modules:
modules[_id].reload()
else:
pp_warning("[*] The module number specified (%d) has not been imported\n" % _id)
except Exception as e:
pp_error("[!] Could not reload python module due to exception\n")
pp_error(" %s\n" % str(e))
return
def unload_module(_id):
try:
if _id in modules:
modules[_id].unload()
else:
pp_warning("[*] The module number specified (%d) has not been imported\n" % _id)
pp_warning("[*] Possible ids:")
for i in modules:
pp_warning(" %s - %s" % (str(i),str(type(i))))
except Exception as e:
pp_error("[!] Could not unload python module due to exception\n")
pp_error(" %s\n" % str(e))
return
def list_modules():
t = PrettyTable(["Hdl", "Module name", "Loaded"])
for mod in modules:
t.add_row([mod, modules[mod].get_module_name(), "Yes" if modules[mod].is_loaded() else "No"])
pp_print(str(t) + "\n")
def get_loaded_modules():
mods = []
for mod in modules:
mods.append({"module_handle": mod, "module_name": modules[mod].get_module_name(), "is_loaded": modules[mod].is_loaded()})
return mods
def pyrebox_shell():
finished = False
while not finished:
try:
from ipython_shell import start_shell
start_shell()
finished = True
except Exception as e:
pp_error(str(e) + "\n")
traceback.print_exc(file=sys.stdout)
def pyrebox_ipython_shell():
finished = False
while not finished:
try:
from ipython_shell import start_shell
start_shell()
finished = True
except Exception as e:
pp_error(str(e) + "\n")
traceback.print_exc(file=sys.stdout)
def init_volatility():
import volatility.conf as volconf
import volatility.registry as registry
import volatility.commands as commands
import volatility.addrspace as addrspace
if hasattr(volconf, "PyREBoxVolatility"):
registry.PluginImporter()
vol_config = volconf.ConfObject()
registry.register_global_options(vol_config, commands.Command)
registry.register_global_options(vol_config, addrspace.BaseAddressSpace)
vol_config.PROFILE = conf_m.vol_profile
# Set global volatility configuration
conf_m.vol_conf = vol_config
return True
else:
pp_error("""The imported volatility version is not appropriate for PyREBox:
* Your local volatility installation may be in conflict with PyREBox's volatility installation...
... set up a virtual env to avoid the conflict (see installation instructions).
* You have a virtual env for PyREBox's python dependencies, and you forgot to activate it!
... you know what to do!\n""")
return False
def init(platform, root_path, volatility_path, conf_name):
try:
# Just configure basic logging
import logging
logging.basicConfig()
# Initialize stuff
pp_debug("[*] Platform: %s\n" % platform)
pp_debug("[*] Starting python module initialization\n")
pp_debug("[*] Reading configuration from '%s'\n" % (conf_name))
sys.settrace
config = ConfigParser.RawConfigParser()
# Store configuration information in raw,
# for plugins to be able to fetch it
conf_m.config = config
if not os.path.isfile(conf_name):
pp_error("[!] Could not initialize pyrebox, conf file '%s' missing!\n" % (conf_name))
return None
config.read(conf_name)
vol_profile = config.get('VOL', 'profile')
# Set global configuration
conf_m.volatility_path = volatility_path
conf_m.vol_profile = vol_profile
conf_m.platform = platform
conf_m.pyre_root = root_path
if platform == "x86_64-softmmu":
conf_m.bitness = 64
conf_m.endianess = "l"
elif platform == "i386-softmmu":
conf_m.bitness = 32
conf_m.endianess = "l"
sys.path.append(volatility_path)
sys.path.append(root_path)
sys.path.append(os.getcwd())
if not init_volatility():
return None
# Initialize the shell now
from ipython_shell import initialize_shell
initialize_shell()
# Initialize the symbol cache from the file
if config.has_option('SYMBOL_CACHE', 'path'):
from vmi import load_symbols_from_cache_file
from vmi import set_symbol_cache_path
set_symbol_cache_path(config.get('SYMBOL_CACHE', 'path'))
load_symbols_from_cache_file()
return vol_profile
except Exception as e:
# Do this to make sure we print the stack trace to help trouble-shooting
traceback.print_exc()
raise e
def init_plugins():
try:
pp_debug("[*] Initializing scripts...\n")
# Locate python modules that should be loaded by default
for (module, enable) in conf_m.config.items("MODULES"):
if enable.strip().lower() == "true" or enable.strip().lower() == "yes":
import_module(module)
pp_debug("[*] Finished python module initialization\n")
return True
except Exception as e:
# Do this to make sure we print the stack trace to help trouble-shooting
traceback.print_exc()
raise e
if __name__ == "__main__":
pp_debug("\n[*] Loading python component initialization script\n")