RWE helper added. SMRR support check added where required. HyperV workaround for SMRR msrs.

This commit is contained in:
Andrew Furtak
2017-02-22 13:07:36 -08:00
parent f12b035458
commit 14904f35e6
6 changed files with 1015 additions and 10 deletions
+27 -1
View File
@@ -43,6 +43,12 @@ from collections import namedtuple
from chipsec.hal import acpi, hal_base
from chipsec.logger import logger
VMM_NONE = 0
VMM_XEN = 0x1
VMM_HYPER_V = 0x2
VMM_VMWARE = 0x3
VMM_KVM = 0x4
class CPURuntimeError (RuntimeError):
pass
@@ -74,6 +80,22 @@ class CPU(hal_base.HALBase):
if logger().VERBOSE: logger().log( "[cpu] CPUID out: EAX=0x%08X, EBX=0x%08X, ECX=0x%08X, EDX=0x%08X" % (eax, ebx, ecx, edx) )
return (eax, ebx, ecx, edx)
# Using cpuid check if running under vmm control
def check_vmm(self):
# check Hypervisor Present
(eax, ebx, ecx, edx) = self.cpuid( 0x01, 0 )
if (ecx & 0x80000000):
(eax, ebx, ecx, edx) = self.cpuid( 0x40000000, 0 )
is_xen = ((ebx == 0x566e6558) and (ecx == 0x65584d4d) and (edx == 0x4d4d566e))
if is_xen: return VMM_XEN
is_hyperv = ((ebx == 0x7263694D) and (ecx == 0x666F736F) and (edx == 0x76482074))
if is_hyperv: return VMM_HYPER_V
is_vmware = ((ebx == 0x61774d56) and (ecx == 0x4d566572) and (edx == 0x65726177))
if is_vmware: return VMM_VMWARE
is_kvm = ((ebx == 0x4b4d564b) and (ecx == 0x564b4d56) and (edx == 0x0000004d))
if is_kvm: return VMM_KVM
return VMM_NONE
# Using CPUID we can determine if Hyper-Threading is enabled in the CPU
def is_HT_active(self):
logical_processor_per_core=self.get_number_logical_processor_per_core()
@@ -157,7 +179,8 @@ class CPU(hal_base.HALBase):
smram_limit = None
smram_size = 0
try:
(smram_base, smram_limit, smram_size) = self.get_SMRR_SMRAM()
if (self.check_SMRR_supported()):
(smram_base, smram_limit, smram_size) = self.get_SMRR_SMRAM()
except:
pass
@@ -172,6 +195,9 @@ class CPU(hal_base.HALBase):
# Check that SMRR is supported by CPU in IA32_MTRRCAP_MSR[SMRR]
#
def check_SMRR_supported( self ):
# MS HyperV workaround. HyperV reports SMRR support but throws and exception on access to SMRR msrs.
# Not a problem for chipsec driver but crashes RwDrv.
if self.check_vmm() == VMM_HYPER_V: return False
mtrrcap_msr_reg = self.cs.read_register( 'MTRRCAP' )
if logger().VERBOSE: self.cs.print_register( 'MTRRCAP', mtrrcap_msr_reg )
smrr = self.cs.get_register_field( 'MTRRCAP', mtrrcap_msr_reg, 'SMRR' )
+1
View File
@@ -22,5 +22,6 @@
from chipsec.helper.efi import *
from chipsec.helper.linux import *
from chipsec.helper.osx import *
#from chipsec.helper.rwe import *
from chipsec.helper.win import *
+26
View File
@@ -0,0 +1,26 @@
#!/usr/bin/python
#CHIPSEC: Platform Security Assessment Framework
#Copyright (c) 2010-2017, 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 platform, os
if "windows" == platform.system().lower() and os.environ.has_key("USERWE"):
__all__ = [ "rwehelper" ]
else:
__all__ = [ ]
+948
View File
@@ -0,0 +1,948 @@
#CHIPSEC: Platform Security Assessment Framework
#Copyright (c) 2010-2017, 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
#
# -------------------------------------------------------------------------------
#
# CHIPSEC: Platform Hardware Security Assessment Framework
# (c) 2010-2012 Intel Corporation
#
# -------------------------------------------------------------------------------
"""
Management and communication with Windows kernel mode driver which provides access to hardware resources
.. note::
On Windows you need to install pywin32 Python extension corresponding to your Python version:
http://sourceforge.net/projects/pywin32/
"""
__version__ = '1.0'
import os.path
import struct
import sys
import platform
import re
import errno
import traceback
import time
from threading import Lock
from collections import namedtuple
from ctypes import *
import pywintypes
import win32service #win32serviceutil, win32api, win32con
import winerror
from win32file import FILE_SHARE_READ, FILE_SHARE_WRITE, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, FILE_FLAG_OVERLAPPED, INVALID_HANDLE_VALUE
import win32api, win32process, win32security, win32file, win32serviceutil
from chipsec.helper.oshelper import Helper, OsHelperError, HWAccessViolationError, UnimplementedAPIError, UnimplementedNativeAPIError, get_tools_path
from chipsec.logger import logger, print_buffer
import chipsec.file
import chipsec.defines
class PCI_BDF(Structure):
_fields_ = [("BUS", c_ushort, 16), # Bus
("DEV", c_ushort, 16), # Device
("FUNC", c_ushort, 16), # Function
("OFF", c_ushort, 16)] # Offset
def cfg_address(self):
addr = (self.BUS << 16) | (self.DEV << 11) | (self.FUNC << 8) | (self.OFF & 0xFC) | 0x80000000
return addr
kernel32 = windll.kernel32
drv_hndl_error_msg = "Cannot open rwe driver handle. Make sure rwe driver is installed and started if you are using option -e (see README)"
DRIVER_FILE_NAME = "RwDrv.sys"
DEVICE_FILE = "\\\\.\\RwDrv"
SERVICE_NAME = "RwDrv"
DISPLAY_NAME = "RwDrv"
CHIPSEC_INSTALL_PATH = os.path.join(sys.prefix, "Lib\site-packages\chipsec")
# Status Codes
STATUS_PRIVILEGED_INSTRUCTION = 0xC0000096
# Defines for Win32 API Calls
GENERIC_READ = 0x80000000
GENERIC_WRITE = 0x40000000
OPEN_EXISTING = 0x3
FILE_DEVICE_UNKNOWN = 0x00000022
METHOD_BUFFERED = 0
METHOD_IN_DIRECT = 1
METHOD_OUT_DIRECT = 2
METHOD_NEITHER = 3
FILE_ANY_ACCESS = 0
FILE_SPECIAL_ACCESS = (FILE_ANY_ACCESS)
FILE_READ_ACCESS = ( 0x0001 )
FILE_WRITE_ACCESS = ( 0x0002 )
def CTL_CODE( DeviceType, Function, Method, Access ):
return ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)
#
# chipsec driver IOCTL codes
#
CHIPSEC_CTL_ACCESS = (FILE_ANY_ACCESS)
#CLOSE_DRIVER = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
READ_PCI_CFG_REGISTER = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
WRITE_PCI_CFG_REGISTER = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
IOCTL_READ_PHYSMEM = CTL_CODE(FILE_DEVICE_UNKNOWN, 0xa02, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
IOCTL_WRITE_PHYSMEM = CTL_CODE(FILE_DEVICE_UNKNOWN, 0xa03, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
#IOCTL_LOAD_UCODE_PATCH = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80b, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
IOCTL_WRMSR = CTL_CODE(FILE_DEVICE_UNKNOWN, 0xa13, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
IOCTL_RDMSR = CTL_CODE(FILE_DEVICE_UNKNOWN, 0xa12, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
IOCTL_READ_IO_PORT_BYTE = CTL_CODE(FILE_DEVICE_UNKNOWN, 0xa04, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
IOCTL_READ_IO_PORT_WORD = CTL_CODE(FILE_DEVICE_UNKNOWN, 0xa06, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
IOCTL_READ_IO_PORT_DWORD = CTL_CODE(FILE_DEVICE_UNKNOWN, 0xa08, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
IOCTL_WRITE_IO_PORT_BYTE = CTL_CODE(FILE_DEVICE_UNKNOWN, 0xa05, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
IOCTL_WRITE_IO_PORT_WORD = CTL_CODE(FILE_DEVICE_UNKNOWN, 0xa07, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
IOCTL_WRITE_IO_PORT_DWORD = CTL_CODE(FILE_DEVICE_UNKNOWN, 0xa09, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
#IOCTL_GET_CPU_DESCRIPTOR_TABLE = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x810, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
#IOCTL_SWSMI = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x811, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
IOCTL_ALLOC_PHYSMEM = CTL_CODE(FILE_DEVICE_UNKNOWN, 0xa20, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
IOCTL_FREE_PHYSMEM = CTL_CODE(FILE_DEVICE_UNKNOWN, 0xa21, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
IOCTL_RDCR = CTL_CODE(FILE_DEVICE_UNKNOWN, 0xa1b, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
IOCTL_WRCR = CTL_CODE(FILE_DEVICE_UNKNOWN, 0xa1c, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
IOCTL_CPUID = CTL_CODE(FILE_DEVICE_UNKNOWN, 0xa14, METHOD_BUFFERED, CHIPSEC_CTL_ACCESS)
#
# NT Errors
#
# Defined in WinDDK\7600.16385.1\inc\api\ntstatus.h
#
#
# UEFI constants
#
# Default buffer size for EFI variables
#EFI_VAR_MAX_BUFFER_SIZE = 128*1024
EFI_VAR_MAX_BUFFER_SIZE = 1024*1024
attributes = {
"EFI_VARIABLE_NON_VOLATILE" : 0x00000001,
"EFI_VARIABLE_BOOTSERVICE_ACCESS" : 0x00000002,
"EFI_VARIABLE_RUNTIME_ACCESS" : 0x00000004,
"EFI_VARIABLE_HARDWARE_ERROR_RECORD" : 0x00000008,
"EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS" : 0x00000010,
"EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS" : 0x00000020,
"EFI_VARIABLE_APPEND_WRITE" : 0x00000040
}
PyLong_AsByteArray = pythonapi._PyLong_AsByteArray
PyLong_AsByteArray.argtypes = [py_object,
c_char_p,
c_size_t,
c_int,
c_int]
def packl_ctypes( lnum, bitlength ):
length = (bitlength + 7)/8
a = create_string_buffer( length )
PyLong_AsByteArray(lnum, a, len(a), 1, 1) # 4th param is for endianness 0 - big, non 0 - little
return a.raw
#
# Firmware Table Provider Signatures
#
FirmwareTableProviderSignature_ACPI = 0x41435049 # 'ACPI' - The ACPI firmware table provider
FirmwareTableProviderSignature_FIRM = 0x4649524D # 'FIRM' - The raw firmware table provider
FirmwareTableProviderSignature_RSMB = 0x52534D42 # 'RSMB' - The raw SMBIOS firmware table provider
FirmwareTableID_RSDT = 0x54445352
FirmwareTableID_XSDT = 0x54445358
#
# Windows 8 NtEnumerateSystemEnvironmentValuesEx (infcls = 2)
#
def guid_str(guid0, guid1, guid2, guid3):
return ( "%08X-%04X-%04X-%04s-%06s" % (guid0, guid1, guid2, guid3[:2].encode('hex').upper(), guid3[-6::].encode('hex').upper()) )
class EFI_HDR_WIN( namedtuple('EFI_HDR_WIN', 'Size DataOffset DataSize Attributes guid0 guid1 guid2 guid3') ):
__slots__ = ()
def __str__(self):
return """
Header (Windows)
----------------
VendorGuid= {%08X-%04X-%04X-%04s-%06s}
Size = 0x%08X
DataOffset= 0x%08X
DataSize = 0x%08X
Attributes= 0x%08X
""" % ( self.guid0, self.guid1, self.guid2, self.guid3[:2].encode('hex').upper(), self.guid3[-6::].encode('hex').upper(), self.Size, self.DataOffset, self.DataSize, self.Attributes )
def getEFIvariables_NtEnumerateSystemEnvironmentValuesEx2( nvram_buf ):
start = 0
buffer = nvram_buf
bsize = len(buffer)
header_fmt = "<IIIIIHH8s"
header_size = struct.calcsize( header_fmt )
variables = dict()
off = 0
while (off + header_size) < bsize:
efi_var_hdr = EFI_HDR_WIN( *struct.unpack_from( header_fmt, buffer[ off : off + header_size ] ) )
next_var_offset = off + efi_var_hdr.Size
efi_var_buf = buffer[ off : next_var_offset ]
efi_var_data = buffer[ off + efi_var_hdr.DataOffset : off + efi_var_hdr.DataOffset + efi_var_hdr.DataSize ]
#efi_var_name = "".join( buffer[ start + header_size : start + efi_var_hdr.DataOffset ] ).decode('utf-16-le')
str_fmt = "%ds" % (efi_var_hdr.DataOffset - header_size)
s, = struct.unpack( str_fmt, buffer[ off + header_size : off + efi_var_hdr.DataOffset ] )
efi_var_name = unicode(s, "utf-16-le", errors="replace").split(u'\u0000')[0]
if efi_var_name not in variables.keys():
variables[efi_var_name] = []
# off, buf, hdr, data, guid, attrs
variables[efi_var_name].append( (off, efi_var_buf, efi_var_hdr, efi_var_data, guid_str(efi_var_hdr.guid0, efi_var_hdr.guid1, efi_var_hdr.guid2, efi_var_hdr.guid3), efi_var_hdr.Attributes) )
if 0 == efi_var_hdr.Size: break
off = next_var_offset
return variables
# return ( start, next_var_offset, efi_var_buf, efi_var_hdr, efi_var_name, efi_var_data, guid_str(efi_var_hdr.guid0, efi_var_hdr.guid1, efi_var_hdr.guid2, efi_var_hdr.guid3), efi_var_hdr.Attributes )
def _handle_winerror(fn, msg, hr):
_handle_error( ("%s failed: %s (%d)" % (fn, msg, hr)), hr )
def _handle_error( err, hr=0 ):
logger().error( err )
raise OsHelperError( err, hr )
_tools = {
chipsec.defines.ToolType.TIANO_COMPRESS: 'TianoCompress.exe',
chipsec.defines.ToolType.LZMA_COMPRESS : 'LzmaCompress.exe'
}
class RweHelper(Helper):
def __init__(self):
super(RweHelper, self).__init__()
import platform
self.os_system = platform.system()
self.os_release = platform.release()
self.os_version = platform.version()
self.os_machine = platform.machine()
self.os_uname = platform.uname()
if "windows" == self.os_system.lower():
win_ver = "win7_" + self.os_machine.lower()
if ("5" == self.os_release): win_ver = "winxp"
if logger().HAL: logger().log( "[helper] OS: %s %s %s" % (self.os_system, self.os_release, self.os_version) )
if logger().HAL: logger().log( "[helper] Using 'helper/win/%s' path for driver" % win_ver )
self.use_existing_service = False
self.driver_path = None
self.win_ver = win_ver
self.driver_handle = None
self.device_file = pywintypes.Unicode(DEVICE_FILE)
c_int_p = POINTER(c_int)
# enable required SeSystemEnvironmentPrivilege privilege
privilege = win32security.LookupPrivilegeValue( None, 'SeSystemEnvironmentPrivilege' )
token = win32security.OpenProcessToken( win32process.GetCurrentProcess(), win32security.TOKEN_READ|win32security.TOKEN_ADJUST_PRIVILEGES )
win32security.AdjustTokenPrivileges( token, False, [(privilege, win32security.SE_PRIVILEGE_ENABLED)] )
win32api.CloseHandle( token )
# import firmware variable API
try:
self.GetFirmwareEnvironmentVariable = kernel32.GetFirmwareEnvironmentVariableW
self.GetFirmwareEnvironmentVariable.restype = c_int
self.GetFirmwareEnvironmentVariable.argtypes = [c_wchar_p, c_wchar_p, c_void_p, c_int]
self.SetFirmwareEnvironmentVariable = kernel32.SetFirmwareEnvironmentVariableW
self.SetFirmwareEnvironmentVariable.restype = c_int
self.SetFirmwareEnvironmentVariable.argtypes = [c_wchar_p, c_wchar_p, c_void_p, c_int]
except AttributeError, msg:
logger().warn( "G[S]etFirmwareEnvironmentVariableW function doesn't seem to exist" )
pass
try:
self.NtEnumerateSystemEnvironmentValuesEx = windll.ntdll.NtEnumerateSystemEnvironmentValuesEx
self.NtEnumerateSystemEnvironmentValuesEx.restype = c_int
self.NtEnumerateSystemEnvironmentValuesEx.argtypes = [c_int, c_void_p, c_void_p]
except AttributeError, msg:
logger().warn( "NtEnumerateSystemEnvironmentValuesEx function doesn't seem to exist" )
pass
try:
self.GetFirmwareEnvironmentVariableEx = kernel32.GetFirmwareEnvironmentVariableExW
self.GetFirmwareEnvironmentVariableEx.restype = c_int
self.GetFirmwareEnvironmentVariableEx.argtypes = [c_wchar_p, c_wchar_p, c_void_p, c_int, c_int_p]
self.SetFirmwareEnvironmentVariableEx = kernel32.SetFirmwareEnvironmentVariableExW
self.SetFirmwareEnvironmentVariableEx.restype = c_int
self.SetFirmwareEnvironmentVariableEx.argtypes = [c_wchar_p, c_wchar_p, c_void_p, c_int, c_int]
except AttributeError, msg:
if logger().VERBOSE: logger().warn( "G[S]etFirmwareEnvironmentVariableExW function doesn't seem to exist" )
pass
try:
self.GetSystemFirmwareTbl = kernel32.GetSystemFirmwareTable
self.GetSystemFirmwareTbl.restype = c_int
self.GetSystemFirmwareTbl.argtypes = [c_int, c_int, c_void_p, c_int]
except AttributeError, msg:
logger().warn( "GetSystemFirmwareTable function doesn't seem to exist" )
pass
try:
self.EnumSystemFirmwareTbls = kernel32.EnumSystemFirmwareTables
self.EnumSystemFirmwareTbls.restype = c_int
self.EnumSystemFirmwareTbls.argtypes = [c_int, c_void_p, c_int]
except AttributeError, msg:
logger().warn( "GetSystemFirmwareTable function doesn't seem to exist" )
def __del__(self):
if self.driver_handle:
win32api.CloseHandle( self.driver_handle )
self.driver_handle = None
###############################################################################################
# Driver/service management functions
###############################################################################################
def show_warning(self):
logger().log( "" )
logger().warn( "*******************************************************************" )
logger().warn( "Chipsec should only be used on test systems!" )
logger().warn( "It should not be installed/deployed on production end-user systems." )
logger().warn( "See WARNING.txt" )
logger().warn( "*******************************************************************" )
logger().log( "" )
#
# Create (register/install) chipsec service
#
def create(self, start_driver):
if not start_driver: return True
self.show_warning()
try:
hscm = win32service.OpenSCManager( None, None, win32service.SC_MANAGER_ALL_ACCESS ) # SC_MANAGER_CREATE_SERVICE
except win32service.error, (hr, fn, msg):
handle_winerror(fn, msg, hr)
if logger().VERBOSE: logger().log( "[helper] service control manager opened (handle = 0x%08x)" % hscm )
driver_path = os.path.join( chipsec.file.get_main_dir(), "chipsec", "helper", "rwe", self.win_ver, DRIVER_FILE_NAME )
if os.path.isfile( driver_path ):
self.driver_path = driver_path
if logger().VERBOSE: logger().log( "[helper] driver path: '%s'" % os.path.abspath(self.driver_path) )
else:
logger().error( "could not locate driver file '%.256s'" % driver_path )
return False
try:
hs = win32service.CreateService(
hscm,
SERVICE_NAME,
DISPLAY_NAME,
(win32service.SERVICE_QUERY_STATUS|win32service.SERVICE_START|win32service.SERVICE_STOP),
win32service.SERVICE_KERNEL_DRIVER,
win32service.SERVICE_DEMAND_START,
win32service.SERVICE_ERROR_NORMAL,
os.path.abspath(driver_path),
None, 0, u"", None, None )
if hs:
if logger().VERBOSE: logger().log( "[helper] service '%s' created (handle = 0x%08x)" % (SERVICE_NAME,hs) )
except win32service.error, (hr, fn, msg):
if (winerror.ERROR_SERVICE_EXISTS == hr):
if logger().VERBOSE: logger().log( "[helper] service '%s' already exists: %s (%d)" % (SERVICE_NAME, msg, hr) )
try:
hs = win32service.OpenService( hscm, SERVICE_NAME, (win32service.SERVICE_QUERY_STATUS|win32service.SERVICE_START|win32service.SERVICE_STOP) ) # SERVICE_ALL_ACCESS
except win32service.error, (hr, fn, msg):
handle_winerror(fn, msg, hr)
else:
handle_winerror(fn, msg, hr)
finally:
win32service.CloseServiceHandle( hs )
win32service.CloseServiceHandle( hscm )
return True
#
# Remove (detele/unregister/uninstall) chipsec service
#
def delete( self, start_driver ):
if not start_driver: return True
if self.use_existing_service: return True
if win32serviceutil.QueryServiceStatus( SERVICE_NAME )[1] != win32service.SERVICE_STOPPED:
logger().warn( "cannot delete service '%s' (not stopped)" % SERVICE_NAME )
return False
if logger().VERBOSE: logger().log( "[helper] deleting service '%s'..." % SERVICE_NAME )
try:
win32serviceutil.RemoveService( SERVICE_NAME )
if logger().VERBOSE: logger().log( "[helper] service '%s' deleted" % SERVICE_NAME )
except win32service.error, (hr, fn, msg):
logger().warn( "RemoveService failed: %s (%d)" % (msg, hr) )
return False
return True
#
# Start chipsec service
#
def start(self, start_driver, driver_exists=False):
# we are in native API mode so not starting the service/driver
if not start_driver: return True
self.use_existing_service = (win32serviceutil.QueryServiceStatus( SERVICE_NAME )[1] == win32service.SERVICE_RUNNING)
if self.use_existing_service:
self.driver_loaded = True
if logger().VERBOSE: logger().log( "[helper] service '%s' already running" % SERVICE_NAME )
if logger().VERBOSE: logger().log( "[helper] trying to connect to existing '%s' service..." % SERVICE_NAME )
else:
#if self.use_existing_service:
# _handle_error( "connecting to existing '%s' service failed (service is not running)" % SERVICE_NAME )
try:
win32serviceutil.StartService( SERVICE_NAME )
win32serviceutil.WaitForServiceStatus( SERVICE_NAME, win32service.SERVICE_RUNNING, 1 )
self.driver_loaded = True
if logger().VERBOSE: logger().log( "[helper] service '%s' started" % SERVICE_NAME )
except pywintypes.error, (hr, fn, msg):
_handle_error( "service '%s' didn't start: %s (%d)" % (SERVICE_NAME, msg, hr), hr )
return True
#
# Stop chipsec service
#
def stop( self, start_driver ):
if not start_driver: return True
if self.use_existing_service: return True
if logger().VERBOSE: logger().log( "[helper] stopping service '%s'.." % SERVICE_NAME )
try:
win32api.CloseHandle( self.driver_handle )
self.driver_handle = None
win32serviceutil.StopService( SERVICE_NAME )
except pywintypes.error, (hr, fn, msg):
logger().error( "StopService failed: %s (%d)" % (msg, hr) )
return False
finally:
self.driver_loaded = False
try:
win32serviceutil.WaitForServiceStatus( SERVICE_NAME, win32service.SERVICE_STOPPED, 1 )
if logger().VERBOSE: logger().log( "[helper] service '%s' stopped" % SERVICE_NAME )
except pywintypes.error, (hr, fn, msg):
logger().warn( "service '%s' didn't stop: %s (%d)" % (SERVICE_NAME, msg, hr) )
return False
return True
def get_driver_handle( self ):
# This is bad but DeviceIoControl fails ocasionally if new device handle is not opened every time ;(
if (self.driver_handle is not None) and (INVALID_HANDLE_VALUE != self.driver_handle):
return self.driver_handle
self.driver_handle = win32file.CreateFile( self.device_file, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, None, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, None )
if (self.driver_handle is None) or (INVALID_HANDLE_VALUE == self.driver_handle):
_handle_error( drv_hndl_error_msg, errno.ENXIO )
else:
if logger().VERBOSE: logger().log( "[helper] opened device '%.64s' (handle: %08x)" % (DEVICE_FILE, self.driver_handle) )
return self.driver_handle
def check_driver_handle( self ):
if (0x6 == kernel32.GetLastError()):
#kernel32.CloseHandle( self.driver_handle )
win32api.CloseHandle( self.driver_handle )
self.driver_handle = None
self.get_driver_handle()
logger().warn( "Invalid handle (wtf?): re-opened device '%.64s' (new handle: %08x)" % (self.device_file, self.driver_handle) )
return False
return True
#
# Auxiliary functions
#
def get_threads_count ( self ):
sum = 0
proc_group_count = (kernel32.GetActiveProcessorGroupCount() & 0xFFFF)
for grp in range(proc_group_count):
procs = kernel32.GetActiveProcessorCount( grp )
sum = sum + procs
return sum
def getcwd( self ):
return ("\\\\?\\" + os.getcwd())
#
# Generic IOCTL call function
#
def _ioctl( self, ioctl_code, in_buf, out_length ):
if not self.driver_loaded:
_handle_error("chipsec kernel driver is not loaded (in native API mode?)")
out_buf = (c_char * out_length)()
self.get_driver_handle()
if logger().VERBOSE: print_buffer( in_buf )
try:
out_buf = win32file.DeviceIoControl( self.driver_handle, ioctl_code, in_buf, out_length, None )
except pywintypes.error, _err:
err_status = _err[0] + 0x100000000
if STATUS_PRIVILEGED_INSTRUCTION == err_status:
err_msg = "HW Access Violation: DeviceIoControl returned STATUS_PRIVILEGED_INSTRUCTION (0x%X)" % err_status
logger().error( err_msg )
raise HWAccessViolationError( err_msg, err_status )
else:
_handle_error( "HW Access Error: DeviceIoControl returned status 0x%X (%s)" % (err_status,_err[2]), err_status )
return out_buf
###############################################################################################
# Actual driver IOCTL functions to access HW resources
###############################################################################################
def read_phys_mem( self, phys_address_hi, phys_address_lo, length ):
out_length = length
out_buf = (c_char * out_length)()
in_buf = struct.pack( '<4IQ', phys_address_lo, phys_address_hi, length, 0, addressof(out_buf) )
self._ioctl( IOCTL_READ_PHYSMEM, in_buf, len(in_buf) )
return out_buf.raw
def native_read_phys_mem( self, phys_address_hi, phys_address_lo, length ):
raise UnimplementedNativeAPIError( "native_read_phys_mem" )
def write_phys_mem( self, phys_address_hi, phys_address_lo, length, buf ):
write_buf = (c_char * len(buf))()
write_buf.raw = buf
#print " *** write_phys_mem *** "
#print_buffer( buf )
#print " *** write_phys_mem *** "
in_buf = struct.pack( '<4IQ', phys_address_lo, phys_address_hi, len(buf), 0, addressof(write_buf) )
self._ioctl( IOCTL_WRITE_PHYSMEM, in_buf, len(in_buf) )
return None
def native_write_phys_mem( self, phys_address_hi, phys_address_lo, length, buf ):
raise UnimplementedNativeAPIError( "native_write_phys_mem" )
# @TODO: Temporarily the same as read_phys_mem for compatibility
def read_mmio_reg( self, phys_address, size ):
#raise UnimplementedNativeAPIError( "read_mmio_reg" )
out_buf = self.read_phys_mem( (phys_address>>32)&0xFFFFFFFF, phys_address&0xFFFFFFFF, size )
if size == 8:
value = struct.unpack( '=Q', out_buf )[0]
elif size == 4:
value = struct.unpack( '=I', out_buf )[0]
elif size == 2:
value = struct.unpack( '=H', out_buf )[0]
elif size == 1:
value = struct.unpack( '=B', out_buf )[0]
else: value = 0
return value
def write_mmio_reg( self, phys_address, size, value ):
#raise UnimplementedNativeAPIError( "write_mmio_reg" )
if size == 8: buf = struct.pack( '=Q', value )
elif size == 4: buf = struct.pack( '=I', value&0xFFFFFFFF )
elif size == 2: buf = struct.pack( '=H', value&0xFFFF )
elif size == 1: buf = struct.pack( '=B', value&0xFF )
else: return False
return self.write_phys_mem( ((phys_address>>32)&0xFFFFFFFF), (phys_address&0xFFFFFFFF), size, buf )
def alloc_phys_mem( self, length, max_pa ):
#raise UnimplementedNativeAPIError( "alloc_phys_mem" )
(va, pa) = (0,0)
out_length = 16
out_buf = (c_char * out_length)()
in_buf = struct.pack( '<I', length )
out_buf = self._ioctl( IOCTL_ALLOC_PHYSMEM, in_buf, out_length )
(size, pa, va) = struct.unpack( '<IIQ', out_buf )
print hex(va), hex(pa)
return (va, pa)
def va2pa( self, va ):
raise UnimplementedNativeAPIError( "va2pa" )
error_code = 0
in_length = 8
out_length = 8
out_buf = (c_char * out_length)()
in_buf = struct.pack( 'Q', va )
out_buf = self._ioctl( IOCTL_GET_PHYSADDR, in_buf, out_length )
pa = struct.unpack( 'Q', out_buf )[0]
return (pa,error_code)
#
# HYPERCALL
#
def hypercall( self, rcx, rdx, r8, r9, r10, r11, rax, rbx, rdi, rsi, xmm_buffer ):
raise UnimplementedNativeAPIError( "hypercall" )
if self.os_machine == 'AMD64':
arg_type = 'Q'
out_length = 8
else:
arg_type = 'I'
out_length = 4
out_buf = (c_char * out_length)()
in_buf = struct.pack( '<11' + arg_type, rcx, rdx, r8, r9, r10, r11, rax, rbx, rdi, rsi, xmm_buffer )
out_buf = self._ioctl( IOCTL_HYPERCALL, in_buf, out_length )
return struct.unpack( '<' + arg_type, out_buf )[0]
#
# MAP_IO_SPACE
#
def map_io_space( self, physical_address, length, cache_type ):
raise UnimplementedNativeAPIError( "map_io_space" )
out_length = 8
out_buf = (c_char * out_length)()
in_buf = struct.pack( '<3Q', physical_address, length, cache_type )
out_buf = self._ioctl( IOCTL_MAP_IO_SPACE, in_buf, out_length )
virtual_address = struct.unpack( '<Q', out_buf )[0]
return virtual_address
#
# FREE_PHYS_MEM
#
def free_phys_mem( self, physical_address ):
raise UnimplementedNativeAPIError( "free_phys_mem" )
out_length = 8
out_buf = (c_char * out_length)()
in_buf = struct.pack( '<QQ', 0, physical_address )
out_buf = self._ioctl( IOCTL_FREE_PHYSMEM, in_buf, out_length )
return
def read_msr( self, cpu_thread_id, msr_addr ):
(eax,ebx,ecx,edx) = (0,0,0,0)
out_length = 16
out_buf = (c_char * out_length)()
out_size = c_ulong(out_length)
in_buf = struct.pack( '<4I', 0, 0, msr_addr, 0 )
out_buf = self._ioctl( IOCTL_RDMSR, in_buf, out_length )
try:
(eax,ebx,ecx,edx) = struct.unpack( '<4I', out_buf )
except:
logger().error( 'DeviceIoControl did not return 4 DWORD values' )
return (eax, edx)
def write_msr( self, cpu_thread_id, msr_addr, eax, edx ):
out_length = 0
out_buf = (c_char * out_length)()
out_size = c_ulong(out_length)
in_buf = struct.pack( '<4I', eax, 0, msr_addr, edx )
out_buf = self._ioctl( IOCTL_WRMSR, in_buf, out_length )
return
def read_pci_reg( self, bus, device, function, address, size ):
#raise UnimplementedNativeAPIError( "read_pci_reg" )
if not self.driver_loaded:
return 0xFFFF
value = 0xFFFFFFFF
bdf = PCI_BDF( bus&0xFFFF, device&0xFFFF, function&0xFFFF, address&0xFFFF )
cfg_addr = bdf.cfg_address()
self.write_io_port( 0xCF8, cfg_addr, 4 )
value = self.read_io_port( 0xCFC, size )
return value
def write_pci_reg( self, bus, device, function, address, value, size ):
#raise UnimplementedNativeAPIError( "write_pci_reg" )
bdf = PCI_BDF( bus&0xFFFF, device&0xFFFF, function&0xFFFF, address&0xFFFF )
cfg_addr = bdf.cfg_address()
self.write_io_port( 0xCF8, cfg_addr, 4 )
self.write_io_port( 0xCFC, value, size )
return True
def load_ucode_update( self, cpu_thread_id, ucode_update_buf ):
raise UnimplementedNativeAPIError( "load_ucode_update" )
in_length = len(ucode_update_buf) + 3
out_length = 0
out_buf = (c_char * out_length)()
in_buf = struct.pack( '=BH', cpu_thread_id, len(ucode_update_buf) ) + ucode_update_buf
out_buf = self._ioctl( IOCTL_LOAD_UCODE_PATCH, in_buf, out_length )
return True
def read_io_port( self, io_port, size ):
in_buf = struct.pack( '<II', io_port, 0 )
mask = 0
#print "[read_io_port] ", hex(io_port), size
try:
if 1 == size:
out_buf = self._ioctl( IOCTL_READ_IO_PORT_BYTE, in_buf, 8 )
mask = 0xff
elif 2 == size:
out_buf = self._ioctl( IOCTL_READ_IO_PORT_WORD, in_buf, 8 )
mask = 0xffff
else:
out_buf = self._ioctl( IOCTL_READ_IO_PORT_DWORD, in_buf, 8 )
mask = 0xffffffff
except:
logger().error( "DeviceIoControl did not return value of proper size %x (value = '%s')" % (size, out_buf) )
#print len(out_buf), ":", out_buf.encode('hex')
value = struct.unpack("<II", out_buf)[1] & mask
return value
def write_io_port( self, io_port, value, size ):
#print "[write_io_port] ", hex(io_port), hex(value), size
in_buf = struct.pack( '<II', io_port, value )
out = ""
if 1 == size:
out = self._ioctl( IOCTL_WRITE_IO_PORT_BYTE, in_buf, 8 )
elif 2 == size:
out = self._ioctl( IOCTL_WRITE_IO_PORT_WORD, in_buf, 8 )
elif 4 == size:
out = self._ioctl( IOCTL_WRITE_IO_PORT_DWORD, in_buf, 8 )
else:
return -1
#print len(out), ":", out.encode('hex')
return 0
def read_cr(self, cpu_thread_id, cr_number):
#raise UnimplementedNativeAPIError( "read_cr" )
# TODO: set affinity to the required thread
value = 0
in_buf = struct.pack( '<QQ', cr_number, 0 )
out_buf = self._ioctl( IOCTL_RDCR, in_buf, 16)
print len(out_buf), out_buf.encode('hex')
code, value = struct.unpack( '<QQ', out_buf )
return value
def write_cr(self, cpu_thread_id, cr_number, value):
#raise UnimplementedNativeAPIError( "write_cr" )
in_buf = struct.pack( '<QQ', cr_number, value )
out_buf = self._ioctl( IOCTL_WRCR, in_buf, 0 )
return True
#
# IDTR/GDTR/LDTR
#
def get_descriptor_table( self, cpu_thread_id, desc_table_code ):
raise UnimplementedNativeAPIError( "get_descriptor_table" )
in_buf = struct.pack( 'BB', cpu_thread_id, desc_table_code )
out_buf = self._ioctl( IOCTL_GET_CPU_DESCRIPTOR_TABLE, in_buf, 18 )
(limit,base,pa) = struct.unpack( '=HQQ', out_buf )
return (limit,base,pa)
#
# EFI Variable API
#
def EFI_supported( self):
# @TODO: use GetFirmwareType ?
return ((self.GetFirmwareEnvironmentVariable is not None) or (self.GetFirmwareEnvironmentVariableEx is not None))
def get_EFI_variable_full( self, name, guid, attrs=None ):
status = 0 # EFI_SUCCESS
efi_var = create_string_buffer( EFI_VAR_MAX_BUFFER_SIZE )
if attrs is None:
if self.GetFirmwareEnvironmentVariable is not None:
if logger().HAL: logger().log( "[helper] -> GetFirmwareEnvironmentVariable( name='%s', GUID='%s' ).." % (name, "{%s}" % guid) )
length = self.GetFirmwareEnvironmentVariable( name, "{%s}" % guid, efi_var, EFI_VAR_MAX_BUFFER_SIZE )
else:
if self.GetFirmwareEnvironmentVariableEx is not None:
pattrs = c_int(attrs)
if logger().HAL: logger().log( "[helper] -> GetFirmwareEnvironmentVariableEx( name='%s', GUID='%s', attrs = 0x%X ).." % (name, "{%s}" % guid, attrs) )
length = self.GetFirmwareEnvironmentVariableEx( name, "{%s}" % guid, efi_var, EFI_VAR_MAX_BUFFER_SIZE, pattrs )
if (0 == length) or (efi_var is None):
status = kernel32.GetLastError()
logger().error( 'GetFirmwareEnvironmentVariable[Ex] returned error: %s' % WinError() )
efi_var_data = None
#raise WinError(errno.EIO,"Unable to get EFI variable")
else:
efi_var_data = efi_var[:length]
return (status, efi_var_data, attrs)
def get_EFI_variable( self, name, guid, attrs=None ):
(status, data, attributes) = self.get_EFI_variable_full( name, guid, attrs )
return data
def set_EFI_variable( self, name, guid, data, datasize, attrs ):
var = bytes(0) if data is None else data
var_len = len(var) if datasize is None else datasize
if attrs is None:
if self.SetFirmwareEnvironmentVariable is not None:
if logger().HAL: logger().log( "[helper] -> SetFirmwareEnvironmentVariable( name='%s', GUID='%s', length=0x%X ).." % (name, "{%s}" % guid, var_len) )
ntsts = self.SetFirmwareEnvironmentVariable( name, "{%s}" % guid, var, var_len )
else:
if self.SetFirmwareEnvironmentVariableEx is not None:
if logger().HAL: logger().log( "[helper] -> SetFirmwareEnvironmentVariableEx( name='%s', GUID='%s', length=0x%X, length=0x%X ).." % (name, "{%s}" % guid, var_len, attrs) )
ntsts = self.SetFirmwareEnvironmentVariableEx( name, "{%s}" % guid, var, var_len, attrs )
if 0 != ntsts:
status = 0 # EFI_SUCCESS
else:
status = kernel32.GetLastError()
logger().error( 'SetFirmwareEnvironmentVariable[Ex] returned error: %s' % WinError() )
#raise WinError(errno.EIO, "Unable to set EFI variable")
return status
def delete_EFI_variable(self, name, guid):
return self.set_EFI_variable( name, guid, None, datasize=0, attrs=None )
def list_EFI_variables( self, infcls=2 ):
if logger().VERBOSE: logger().log( '[helper] -> NtEnumerateSystemEnvironmentValuesEx( infcls=%d )..' % infcls )
efi_vars = create_string_buffer( EFI_VAR_MAX_BUFFER_SIZE )
length = packl_ctypes( long(EFI_VAR_MAX_BUFFER_SIZE), 32 )
status = self.NtEnumerateSystemEnvironmentValuesEx( infcls, efi_vars, length )
status = ( ((1 << 32) - 1) & status)
if (0xC0000023 == status):
retlength, = struct.unpack("<I", length)
efi_vars = create_string_buffer( retlength )
status = self.NtEnumerateSystemEnvironmentValuesEx( infcls, efi_vars, length )
elif (0xC0000002 == status):
logger().warn( 'NtEnumerateSystemEnvironmentValuesEx was not found (NTSTATUS = 0xC0000002)' )
logger().log( '[*] Your Windows does not expose UEFI Runtime Variable API. It was likely installed as legacy boot.\nTo use UEFI variable functions, chipsec needs to run in OS installed with UEFI boot (enable UEFI Boot in BIOS before installing OS)' )
return None
if 0 != status:
logger().error( 'NtEnumerateSystemEnvironmentValuesEx failed (GetLastError = 0x%x)' % kernel32.GetLastError() )
logger().error( '*** NTSTATUS: %08X' % ( ((1 << 32) - 1) & status) )
raise WinError()
if logger().VERBOSE: logger().log( '[helper] len(efi_vars) = 0x%X (should be 0x20000)' % len(efi_vars) )
return getEFIvariables_NtEnumerateSystemEnvironmentValuesEx2( efi_vars )
#
# Interrupts
#
def send_sw_smi( self, cpu_thread_id, SMI_code_data, _rax, _rbx, _rcx, _rdx, _rsi, _rdi ):
raise UnimplementedNativeAPIError( "send_sw_smi" )
out_length = 0
out_buf = (c_char * out_length)()
out_size = c_ulong(out_length)
in_buf = struct.pack( '=H6Q', SMI_code_data, _rax, _rbx, _rcx, _rdx, _rsi, _rdi )
out_buf = self._ioctl( IOCTL_SWSMI, in_buf, out_length )
return
def _get_handle_for_pid( self, pid=0, ro=True ):
if pid == 0:
pHandle = win32process.GetCurrentProcess()
else:
flags = win32con.PROCESS_QUERY_INFORMATION
if not ro:
flags |= wn32con.PROCESS_SET_INFORMATION
try:
pHandle = win32api.OpenProcess(flags, 0, pid)
except pywintypes.error, e:
print "unable to open a process handle"
raise ValueError, e
return pHandle
def set_affinity( self, value ):
pHandle = self._get_handle_for_pid(0, False)
current = win32process.GetProcessAffinityMask(pHandle)[0]
try:
win32process.SetProcessAffinityMask(pHandle, current)
except win32process.error, e:
print "unable to set process affinity"
raise ValueError, e
return current
def get_affinity( self ):
pHandle = self._get_handle_for_pid()
try:
return win32process.GetProcessAffinityMask(pHandle)[0]
except win32process.error, e:
print "unable to get the running cpu"
raise ValueError, e
#
# CPUID
#
def cpuid( self, eax, ecx ):
#raise UnimplementedNativeAPIError( "cpuid" )
out_length = 16
out_buf = (c_char * out_length)()
in_buf = struct.pack( '<2I', eax, ecx )
out_buf = self._ioctl( IOCTL_CPUID, in_buf, out_length )
(eax, ebx, ecx, edx) = struct.unpack( '<4I', out_buf )
return (eax, ebx, ecx, edx)
def get_ACPI_SDT( self ):
sdt = self.native_get_ACPI_table( 'XSDT' ) # FirmwareTableID_XSDT
xsdt = sdt is not None
if not xsdt:
sdt = self.native_get_ACPI_table( 'RSDT' ) # FirmwareTableID_RSDT
return sdt, xsdt
def native_get_ACPI_table( self, table_name ):
table_size = 36
tBuffer = create_string_buffer( table_size )
tbl = struct.unpack("<I", table_name)[0]
retVal = self.GetSystemFirmwareTbl( FirmwareTableProviderSignature_ACPI, tbl, tBuffer, table_size )
if retVal == 0: return None
if retVal > table_size:
table_size = retVal
tBuffer = create_string_buffer( table_size )
retVal = self.GetSystemFirmwareTbl( FirmwareTableProviderSignature_ACPI, tbl, tBuffer, table_size )
return tBuffer[:retVal]
# ACPI access is implemented through ACPI HAL rather than through kernel module
def get_ACPI_table( self ):
raise UnimplementedAPIError( "get_ACPI_table" )
#
# IOSF Message Bus access
#
def msgbus_send_read_message( self, mcr, mcrx ):
logger().error( "[helper] Message Bus is not supported yet" )
return None
def msgbus_send_write_message( self, mcr, mcrx, mdr ):
logger().error( "[helper] Message Bus is not supported yet" )
return None
def msgbus_send_message( self, mcr, mcrx, mdr=None ):
logger().error( "[helper] Message Bus is not supported yet" )
return None
#
# File system
#
def get_tool_info( self, tool_type ):
tool_name = _tools[ tool_type ] if tool_type in _tools else None
tool_path = os.path.join( get_tools_path(), self.os_system.lower() )
return tool_name,tool_path
#
# Get instance of this OS helper
#
def get_helper():
return RweHelper( )
+6 -6
View File
@@ -42,11 +42,11 @@ class smrr(BaseModule):
#
# Check that SMRR are supported by CPU in IA32_MTRRCAP_MSR[SMRR]
#
def check_SMRR_supported(self):
mtrrcap_msr_reg = self.cs.read_register( 'MTRRCAP' )
if self.logger.VERBOSE: self.cs.print_register( 'MTRRCAP', mtrrcap_msr_reg )
smrr = self.cs.get_register_field( 'MTRRCAP', mtrrcap_msr_reg, 'SMRR' )
return (1 == smrr)
#def check_SMRR_supported(self):
#mtrrcap_msr_reg = self.cs.read_register( 'MTRRCAP' )
#if self.logger.VERBOSE: self.cs.print_register( 'MTRRCAP', mtrrcap_msr_reg )
#smrr = self.cs.get_register_field( 'MTRRCAP', mtrrcap_msr_reg, 'SMRR' )
#return (1 == smrr)
def check_SMRR(self, do_modify):
if not self.cs.is_register_defined( 'MTRRCAP' ) or \
@@ -55,7 +55,7 @@ class smrr(BaseModule):
self.logger.error( "Couldn't find definition of required configuration registers" )
return ModuleResult.ERROR
if self.check_SMRR_supported():
if self.cs.cpu.check_SMRR_supported():
self.logger.log_good( "OK. SMRR range protection is supported" )
else:
self.logger.log_important( "CPU does not support SMRR range protection of SMRAM" )
+7 -3
View File
@@ -61,15 +61,19 @@ class smm_dma(BaseModule):
def check_tseg_config(self):
res = ModuleResult.FAILED
(tseg_base, tseg_limit, tseg_size ) = self.cs.cpu.get_TSEG()
(smram_base, smram_limit, smram_size) = self.cs.cpu.get_SMRR_SMRAM()
self.logger.log("[*] TSEG : 0x%016X - 0x%016X (size = 0x%08X)" % (tseg_base, tseg_limit, tseg_size ))
self.logger.log("[*] SMRR range: 0x%016X - 0x%016X (size = 0x%08X)\n" % (smram_base, smram_limit, smram_size))
if (self.cs.cpu.check_SMRR_supported()):
(smram_base, smram_limit, smram_size) = self.cs.cpu.get_SMRR_SMRAM()
self.logger.log("[*] SMRR range: 0x%016X - 0x%016X (size = 0x%08X)\n" % (smram_base, smram_limit, smram_size))
else:
smram_base = 0
smram_limit = 0
self.logger.log("[*] SMRR is not supported\n")
self.logger.log( "[*] checking TSEG range configuration.." )
if (0 == smram_base) and (0 == smram_limit):
res = ModuleResult.WARNING
self.logger.log_warn_check( "TSEG is properly configured but can't determine if it covers entire SMRAM" )
else:
if (tseg_base <= smram_base) and (smram_limit <= tseg_limit):
#if (tseg_base == smram_base) and (tseg_size == smram_size):