Files
chipsec-chipsec/chipsec/module.py
T
2024-04-22 16:36:02 -07:00

160 lines
5.5 KiB
Python

# CHIPSEC: Platform Security Assessment Framework
# Copyright (c) 2010-2021, Intel Corporation
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; Version 2.
#
# 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.
#
# Contact information:
# chipsec@intel.com
#
import re
import os
import traceback
import pickle
import chipsec.library.logger
from chipsec.library.returncode import ModuleResult, generate_hash_id
_importlib = True
try:
import importlib
except ImportError:
_importlib = False
MODPATH_RE = re.compile(r"^\w+(\.\w+)*$")
class Module:
def __init__(self, name):
self.logger = chipsec.library.logger.logger()
self.name = name
self.module = None
self.mod_obj = None
self.module_ids = self.get_module_ids_dictionary()
def __lt__(self, other):
return self.name < other.name
def __le__(self, other):
return self.name <= other.name
def __gt__(self, other):
return self.name > other.name
def __ge__(self, other):
return self.name >= other.name
def get_name(self):
return self.name
def do_import(self):
loaded = False
if not MODPATH_RE.match(self.get_name()):
self.logger.log_error(f'Invalid module path: {self.name}')
else:
try:
if _importlib:
self.module = importlib.import_module(self.name)
loaded = True
if self.logger.DEBUG:
self.logger.log_good(f'imported: {self.name}')
except BaseException as msg:
self.logger.log_error(f"Exception occurred during import of {self.name}: '{str(msg)}'")
if self.logger.DEBUG:
self.logger.log_bad(traceback.format_exc())
raise msg
return loaded
def get_module_ids_dictionary(self):
with open(os.path.join(os.getcwd(), 'chipsec', 'library', 'module_ids.pkl'), 'rb') as module_ids_file:
module_ids = pickle.load(module_ids_file)
return module_ids
def update_module_ids_file(self):
with open(os.path.join(os.getcwd(), 'chipsec', 'library', 'module_ids.pkl'), 'wb') as module_ids_file:
pickle.dump(self.module_ids, module_ids_file)
def get_module_id(self, module_name):
if module_name in self.module_ids:
module_id = self.module_ids[module_name]
else:
module_id = generate_hash_id(module_name)
self.module_ids[module_name] = module_id
self.update_module_ids_file()
return module_id
def run(self, module_argv):
self.get_module_object()
if module_argv:
self.logger.log(f'[*] Module arguments ({len(module_argv):d}):')
self.logger.log(module_argv)
else:
module_argv = []
if isinstance(self.mod_obj, chipsec.module_common.BaseModule):
self.mod_obj.result.id = self.get_module_id(self.name)
if self.mod_obj.is_supported():
result = self.mod_obj.run(module_argv)
else:
self.mod_obj.result.setStatusBit(self.mod_obj.result.status.NOT_APPLICABLE)
result = self.mod_obj.result.getReturnCode(ModuleResult.NOTAPPLICABLE)
self.logger.log(f'Skipping module {self.name} since it is not applicable in this environment and/or platform')
return result
def get_module_object(self):
if self.mod_obj is None:
try:
if _importlib:
pkg = getattr(self.module, "__package__")
class_name = getattr(self.module, "__name__")
if pkg:
class_name = class_name.replace(pkg, '')
if class_name.startswith('.'):
class_name = class_name.replace('.', '')
for iname, iref in self.module.__dict__.items():
if isinstance(iref, type):
if issubclass(iref, chipsec.module_common.BaseModule):
if iname.lower() == class_name.lower():
self.mod_obj = iref()
if self.mod_obj is None:
raise ModuleNotFoundError(self.module)
except (AttributeError, TypeError, ModuleNotFoundError):
self.logger.chipsecLogger.exception('Error getting module object')
def get_location(self):
myfile = ''
try:
if _importlib:
myfile = getattr(self.module, "__file__")
except:
pass
return myfile
def get_tags(self):
module_tags = []
metadata_tags = []
try:
if _importlib:
module_tags = getattr(self.module, 'TAGS')
metadata_tags = getattr(self.module, 'MD_TAGS')
except:
pass
return module_tags, metadata_tags
def __str__(self):
return self.get_name()