vector-uefi/fd/tool/chipsec/hal/uefi_platform.py
#!/usr/local/bin/python
#CHIPSEC: Platform Security Assessment Framework
#Copyright (c) 2010-2014, 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
#
# -------------------------------------------------------------------------------
## \addtogroup hal
# chipsec/hal/uefi_platform.py
# ==================================
# Platform specific UEFI functionality (parsing platform specific EFI NVRAM, capsules, etc.)
#
#
__version__ = '1.0'
import struct
from collections import namedtuple
from chipsec.hal.uefi_common import *
#################################################################################################3
# List of supported types of EFI NVRAM format (platform/vendor specific)
#################################################################################################3
class FWType:
EFI_FW_TYPE_UEFI = 'uefi'
# EFI_FW_TYPE_WIN = 'win' # Windows 8 GetFirmwareEnvironmentVariable format
EFI_FW_TYPE_VSS = 'vss' # NVRAM using format with '$VSS' signature
EFI_FW_TYPE_VSS_NEW = 'vss_new' # NVRAM using format with '$VSS' signature (Newer one?)
EFI_FW_TYPE_NVAR = 'nvar' # 'NVAR' NVRAM format
EFI_FW_TYPE_EVSA = 'evsa' # 'EVSA' NVRAM format
fw_types = []
for i in [t for t in dir(FWType) if not callable(getattr(FWType, t))]:
if not i.startswith('__'):
fw_types.append( getattr(FWType, i) )
NVRAM_ATTR_RT = 1
NVRAM_ATTR_DESC_ASCII = 2
NVRAM_ATTR_GUID = 4
NVRAM_ATTR_DATA = 8
NVRAM_ATTR_EXTHDR = 0x10
NVRAM_ATTR_AUTHWR = 0x40
NVRAM_ATTR_HER = 0x20
NVRAM_ATTR_VLD = 0x80
#################################################################################################3
# This Variable header is defined by UEFI
#################################################################################################3
#
# Variable Store Status
#
#typedef enum {
# EfiRaw,
# EfiValid,
# EfiInvalid,
# EfiUnknown
# } VARIABLE_STORE_STATUS;
VARIABLE_STORE_STATUS_RAW = 0
VARIABLE_STORE_STATUS_VALID = 1
VARIABLE_STORE_STATUS_INVALID = 2
VARIABLE_STORE_STATUS_UNKNOWN = 3
#
# Variable State flags
#
VAR_IN_DELETED_TRANSITION = 0xfe # Variable is in obsolete transistion
VAR_DELETED = 0xfd # Variable is obsolete
VAR_ADDED = 0x7f # Variable has been completely added
#IS_VARIABLE_STATE(_c, _Mask) (BOOLEAN) (((~_c) & (~_Mask)) != 0)
def IS_VARIABLE_STATE(_c, _Mask):
return ( ( ((~_c)&0xFF) & ((~_Mask)&0xFF) ) != 0 )
#
#typedef struct {
# UINT16 StartId;
# UINT8 State;
# UINT8 Reserved;
# UINT32 Attributes;
# UINT32 NameSize;
# UINT32 DataSize;
# EFI_GUID VendorGuid;
#} VARIABLE_HEADER;
#
#typedef struct {
# UINT32 Data1;
# UINT16 Data2;
# UINT16 Data3;
# UINT8 Data4[8];
#} EFI_GUID;
#
UEFI_VARIABLE_HEADER_SIZE = 28
class UEFI_VARIABLE_HEADER( namedtuple('UEFI_VARIABLE_HEADER', 'StartId State Reserved Attributes NameSize DataSize VendorGuid0 VendorGuid1 VendorGuid2 VendorGuid3') ):
__slots__ = ()
def __str__(self):
return """
Header (UEFI)
-------------
StartId : 0x%04X
State : 0x%02X
Reserved : 0x%02X
Attributes : 0x%08X
NameSize : 0x%08X
DataSize : 0x%08X
VendorGuid : {0x%08X-0x%04X-0x%04X-0x%08X}
""" % ( self.StartId, self.State, self.Reserved, self.Attributes, self.NameSize, self.DataSize, self.VendorGuid0, self.VendorGuid1, self.VendorGuid2, self.VendorGuid3 )
def getEFIvariables_UEFI( nvram_buf ):
logger().error( 'Well, implement getEFIvariables_UEFI finally, would you??' )
return 0
##################################################################################################
#
# Platform/Vendor Specific EFI NVRAM Parsing Functions
#
# For each platform, EFI NVRAM parsing functionality includes:
# 1. Function to parse EFI variable within NVRAM binary (func_getefivariables)
# May define/use platform specific EFI Variable Header
# Function arguments:
# In : binary buffer (as a string)
# Out:
# start - offset in the buffer to the current EFI variable
# next_var_offset - offset in the buffer to the next EFI variable
# efi_var_buf - full EFI variable buffer
# efi_var_hdr - EFI variable header object
# efi_var_name - EFI variable name
# efi_var_data - EFI variable data contents
# efi_var_guid - EFI variable GUID
# efi_var_attr - EFI variable attributes
# 2. [Optional] Function to find EFI NVRAM within arbitrary binary (func_getnvstore)
# If this function is not defined, 'chipsec_util uefi' searches EFI variables from the beginning of the binary
# Function arguments:
# In : NVRAM binary buffer (as a string)
# Out:
# start - offset of NVRAM (-1 means NVRAM not found)
# size - size of NVRAM (-1 means NVRAM is entire binary)
# nvram_header - NVRAM header object
#
##################################################################################################
##################################################################################################
# NVAR format of NVRAM
#
from chipsec.logger import *
class EFI_HDR_NVAR1( namedtuple('EFI_HDR_NVAR1', 'StartId TotalSize Reserved1 Reserved2 Reserved3 Attributes State') ):
__slots__ = ()
def __str__(self):
return """
Header (NVAR)
------------
StartId : 0x%04X
TotalSize : 0x%04X
Reserved1 : 0x%02X
Reserved2 : 0x%02X
Reserved3 : 0x%02X
Attributes : 0x%02X
State : 0x%02X
""" % ( self.StartId, self.TotalSize, self.Reserved1, self.Reserved2, self.Reserved3, self.Attributes, self.State )
NVAR_EFIvar_signature = 'NVAR'
NVAR_NVRAM_FS_FILE = "CEF5B9A3-476D-497F-9FDC-E98143E0422C"
def getNVstore_NVAR( nvram_buf ):
l = (-1, -1, None)
FvOffset, FsGuid, FvLength, FvAttributes, FvHeaderLength, FvChecksum, ExtHeaderOffset, FvImage, CalcSum = NextFwVolume(nvram_buf)
while FvOffset != None:
polarity = bit_set(FvAttributes, EFI_FVB2_ERASE_POLARITY)
cur_offset, next_offset, Name, Type, Attributes, State, Checksum, Size, FileImage, HeaderSize, UD, fCalcSum = NextFwFile(FvImage, FvLength, FvHeaderLength, polarity)
while next_offset != None:
if (Type == EFI_FV_FILETYPE_RAW) and (Name == NVAR_NVRAM_FS_FILE):
l = ((FvOffset + cur_offset + HeaderSize), Size - HeaderSize, None)
if (not UD): break
cur_offset, next_offset, Name, Type, Attributes, State, Checksum, Size, FileImage, HeaderSize, UD, fCalcSum = NextFwFile(FvImage, FvLength, next_offset, polarity)
FvOffset, FsGuid, FvLength, Attributes, HeaderLength, Checksum, ExtHeaderOffset, FvImage, CalcSum = NextFwVolume(nvram_buf, FvOffset+FvLength)
return l
def getEFIvariables_NVAR( nvram_buf ):
start = nvram_buf.find( NVAR_EFIvar_signature )
nvram_size = len(nvram_buf)
EFI_HDR_NVAR = "<4sH3sB"
nvar_size = struct.calcsize(EFI_HDR_NVAR)
variables = dict()
nof = 0 #start
# EMPTY = 0
EMPTY = 0xffffffff
while (nof+nvar_size) < nvram_size:
start_id, size, next, attributes = struct.unpack(EFI_HDR_NVAR, nvram_buf[nof:nof+nvar_size])
next = get_3b_size(next)
valid = (bit_set(attributes, NVRAM_ATTR_VLD) and (not bit_set(attributes, NVRAM_ATTR_DATA)))
if not valid:
nof = nof + size
continue
isvar = (start_id == NVAR_EFIvar_signature)
if (not isvar) or (size == (EMPTY & 0xffff)): break
var_name_off = 1
if bit_set(attributes, NVRAM_ATTR_GUID):
guid0, guid1, guid2, guid3 = struct.unpack(GUID, nvram_buf[nof+nvar_size:nof+nvar_size+guid_size])
guid = guid_str(guid0, guid1, guid2, guid3)
var_name_off = guid_size
else:
guid_idx = ord(nvram_buf[nof+nvar_size])
guid0, guid1, guid2, guid3 = struct.unpack(GUID, nvram_buf[nvram_size - guid_size - guid_idx:nvram_size - guid_idx])
guid = guid_str(guid0, guid1, guid2, guid3)
name_size = 0
name_offset = nof+nvar_size+var_name_off
if not bit_set(attributes, NVRAM_ATTR_DATA):
name, name_size = get_nvar_name(nvram_buf, name_offset, bit_set(attributes, NVRAM_ATTR_DESC_ASCII))
esize = 0
eattrs = 0
if bit_set(attributes, NVRAM_ATTR_EXTHDR):
esize, = struct.unpack("<H", nvram_buf[nof+size-2:nof+size])
eattrs = ord(nvram_buf[nof+size-esize])
attribs = EFI_VARIABLE_BOOTSERVICE_ACCESS
attribs = attribs | EFI_VARIABLE_NON_VOLATILE
if bit_set(attributes, NVRAM_ATTR_RT): attribs = attribs | EFI_VARIABLE_RUNTIME_ACCESS
if bit_set(attributes, NVRAM_ATTR_HER): attribs = attribs | EFI_VARIABLE_HARDWARE_ERROR_RECORD
if bit_set(attributes, NVRAM_ATTR_AUTHWR):
if bit_set(eattrs, EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS):
attribs = attribs | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
if bit_set(eattrs, EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS):
attribs = attribs | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
# Get variable data
lof = nof
lnext = next
lattributes = attributes
lsize = size
lesize = esize
while lnext != (0xFFFFFF & EMPTY):
lof = lof + lnext
lstart_id, lsize, lnext, lattributes = struct.unpack(EFI_HDR_NVAR, nvram_buf[lof:lof+nvar_size])
lnext = get_3b_size(lnext)
dataof = lof + nvar_size
if not bit_set(lattributes, NVRAM_ATTR_DATA):
lnameof = 1
if bit_set(lattributes, NVRAM_ATTR_GUID): lnameof = guid_size
name_offset = lof+nvar_size+lnameof
name, name_size = get_nvar_name(nvram_buf, name_offset, bit_set(attributes, NVRAM_ATTR_DESC_ASCII))
dataof = name_offset + name_size
if bit_set(lattributes, NVRAM_ATTR_EXTHDR):
lesize, = struct.unpack("<H", nvram_buf[lof+lsize-2:lof+lsize])
data = nvram_buf[dataof:lof+lsize-lesize]
if name not in variables.keys():
variables[name] = []
# off, buf, hdr, data, guid, attrs
variables[name].append((nof, None, None, data, guid, attribs))
nof = nof + size
return variables
NVAR_HDR_FMT = '=IHBBBBB'
NVAR_HDR_SIZE = struct.calcsize( NVAR_HDR_FMT )
#
# Linear/simple NVAR format parsing
#
def getNVstore_NVAR_simple( nvram_buf ):
return (nvram_buf.find( NVAR_EFIvar_signature ), -1, None)
def getEFIvariables_NVAR_simple( nvram_buf ):
nvsize = len(nvram_buf)
hdr_fmt = NVAR_HDR_FMT
hdr_size = struct.calcsize( hdr_fmt )
variables = dict()
start = nvram_buf.find( NVAR_EFIvar_signature )
if -1 == start: return variables
while (start + hdr_size) < nvsize:
efi_var_hdr = EFI_HDR_NVAR1( *struct.unpack_from( hdr_fmt, nvram_buf[start:] ) )
name_size = 0
efi_var_name = "NA"
if not IS_VARIABLE_ATTRIBUTE( efi_var_hdr.Attributes, EFI_VARIABLE_HARDWARE_ERROR_RECORD ):
name_size = nvram_buf[ start + hdr_size : ].find( '\0' )
efi_var_name = "".join( nvram_buf[ start + hdr_size : start + hdr_size + name_size ] )
next_var_offset = start + efi_var_hdr.TotalSize
data_size = efi_var_hdr.TotalSize - name_size - hdr_size
efi_var_buf = nvram_buf[ start : next_var_offset ]
efi_var_data = nvram_buf[ start + hdr_size + name_size : next_var_offset ]
if efi_var_name not in variables.keys(): variables[efi_var_name] = []
# off, buf, hdr, data, guid, attrs
variables[efi_var_name].append((start, efi_var_buf, efi_var_hdr, efi_var_data, '', efi_var_hdr.Attributes))
if start >= next_var_offset: break
start = next_var_offset
return variables
#######################################################################
#
# VSS NVRAM (signature = '$VSS')
#
#
#define VARIABLE_STORE_SIGNATURE EFI_SIGNATURE_32 ('$', 'V', 'S', 'S')
VARIABLE_STORE_SIGNATURE_VSS = '$VSS'
VARIABLE_STORE_HEADER_FMT_VSS = '=IIBBHI' # Signature is '$VSS'
class VARIABLE_STORE_HEADER_VSS( namedtuple('VARIABLE_STORE_HEADER_VSS', 'Signature Size Format State Reserved Reserved1') ):
__slots__ = ()
def __str__(self):
return """
EFI Variable Store
-----------------------------
Signature : %s (0x%08X)
Size : 0x%08X bytes
Format : 0x%02X
State : 0x%02X
Reserved : 0x%04X
Reserved1 : 0x%08X
""" % ( struct.pack('=I',self.Signature), self.Signature, self.Size, self.Format, self.State, self.Reserved, self.Reserved1 )
HDR_FMT_VSS = '<HBBIIIIHH8s'
#HDR_SIZE_VSS = struct.calcsize( HDR_FMT_VSS )
#NAME_OFFSET_IN_VAR_VSS = HDR_SIZE_VSS
class EFI_HDR_VSS( namedtuple('EFI_HDR_VSS', 'StartId State Reserved Attributes NameSize DataSize guid0 guid1 guid2 guid3') ):
__slots__ = ()
def __str__(self):
return """
Header (VSS)
------------
VendorGuid : {%08X-%04X-%04X-%04s-%06s}
StartId : 0x%04X
State : 0x%02X
Reserved : 0x%02X
Attributes : 0x%08X
NameSize : 0x%08X
DataSize : 0x%08X
""" % ( self.guid0, self.guid1, self.guid2, self.guid3[:2].encode('hex').upper(), self.guid3[-6::].encode('hex').upper(), self.StartId, self.DataOffset, self.DataSize, self.Attributes )
HDR_FMT_VSS_NEW = '<HBBIQQQIIIIHH8s'
class EFI_HDR_VSS_NEW( namedtuple('EFI_HDR_VSS_NEW', 'StartId State Reserved Attributes wtf1 wtf2 wtf3 wtf4 NameSize DataSize guid0 guid1 guid2 guid3') ):
__slots__ = ()
# if you don't re-define __str__ method, initialize is to None
#__str__ = None
def __str__(self):
return """
Header (VSS_NEW)
----------------
VendorGuid : {%08X-%04X-%04X-%08X}
StartId : 0x%04X
State : 0x%02X
Reserved : 0x%02X
Attributes : 0x%08X
wtf1 : 0x%016X
wtf2 : 0x%016X
wtf3 : 0x%016X
wtf4 : 0x%08X
NameSize : 0x%08X
DataSize : 0x%08X
""" % ( self.guid0, self.guid1, self.guid2, self.guid3[:2].encode('hex').upper(), self.guid3[-6::].encode('hex').upper(), self.StartId, self.State, self.Reserved, self.Attributes, self.wtf1, self.wtf2, self.wtf3, self.wtf4, self.NameSize, self.DataSize )
def getNVstore_VSS( nvram_buf ):
nvram_start = nvram_buf.find( VARIABLE_STORE_SIGNATURE_VSS )
if -1 == nvram_start:
return (-1, 0, None)
nvram_hdr = VARIABLE_STORE_HEADER_VSS( *struct.unpack_from( VARIABLE_STORE_HEADER_FMT_VSS, nvram_buf[nvram_start:] ) )
return (nvram_start, nvram_hdr.Size, nvram_hdr)
def _getEFIvariables_VSS( nvram_buf, _fwtype ):
nvsize = len(nvram_buf)
if (FWType.EFI_FW_TYPE_VSS == _fwtype):
hdr_fmt = HDR_FMT_VSS
elif (FWType.EFI_FW_TYPE_VSS_NEW == _fwtype):
hdr_fmt = HDR_FMT_VSS_NEW
hdr_size = struct.calcsize( hdr_fmt )
variables = dict()
start = nvram_buf.find( VARIABLE_SIGNATURE_VSS )
if -1 == start:
return variables
while (start + hdr_size) < nvsize:
if (FWType.EFI_FW_TYPE_VSS == _fwtype):
efi_var_hdr = EFI_HDR_VSS( *struct.unpack_from( hdr_fmt, nvram_buf[start:] ) )
elif (FWType.EFI_FW_TYPE_VSS_NEW == _fwtype):
efi_var_hdr = EFI_HDR_VSS_NEW( *struct.unpack_from( hdr_fmt, nvram_buf[start:] ) )
if (efi_var_hdr.StartId != 0x55AA): break
name_size = efi_var_hdr.NameSize
data_size = efi_var_hdr.DataSize
efi_var_name = "<not defined>"
next_var_offset = start + hdr_size + name_size + data_size
efi_var_buf = nvram_buf[ start : next_var_offset ]
name_offset = hdr_size
#if not IS_VARIABLE_ATTRIBUTE( efi_var_hdr.Attributes, EFI_VARIABLE_HARDWARE_ERROR_RECORD ):
#efi_var_name = "".join( efi_var_buf[ NAME_OFFSET_IN_VAR_VSS : NAME_OFFSET_IN_VAR_VSS + name_size ] )
str_fmt = "%ds" % name_size
s, = struct.unpack( str_fmt, efi_var_buf[ name_offset : name_offset + name_size ] )
efi_var_name = unicode(s, "utf-16-le", errors="replace").split(u'\u0000')[0]
efi_var_data = efi_var_buf[ name_offset + name_size : next_var_offset ]
guid = guid_str(efi_var_hdr.guid0, efi_var_hdr.guid1, efi_var_hdr.guid2, efi_var_hdr.guid3)
if efi_var_name not in variables.keys():
variables[efi_var_name] = []
# off, buf, hdr, data, guid, attrs
variables[efi_var_name].append( (start, efi_var_buf, efi_var_hdr, efi_var_data, guid, efi_var_hdr.Attributes) )
if start >= next_var_offset: break
start = next_var_offset
return variables
def getEFIvariables_VSS( nvram_buf ):
return _getEFIvariables_VSS( nvram_buf, FWType.EFI_FW_TYPE_VSS )
def getEFIvariables_VSS_NEW( nvram_buf ):
return _getEFIvariables_VSS( nvram_buf, FWType.EFI_FW_TYPE_VSS_NEW )
#######################################################################
#
# EVSA NVRAM (signature = 'EVSA')
#
#
VARIABLE_STORE_SIGNATURE_EVSA = 'EVSA'
VARIABLE_STORE_FV_GUID = 'FFF12B8D-7696-4C8B-A985-2747075B4F50'
ADDITIONAL_NV_STORE_GUID = '00504624-8A59-4EEB-BD0F-6B36E96128E0'
TLV_HEADER = "<BBH"
tlv_h_size = struct.calcsize(TLV_HEADER)
def getNVstore_EVSA( nvram_buf ):
l = (-1, -1, None)
FvOffset, FsGuid, FvLength, FvAttributes, FvHeaderLength, FvChecksum, ExtHeaderOffset, FvImage, CalcSum = NextFwVolume(nvram_buf)
while FvOffset != None:
if (FsGuid == VARIABLE_STORE_FV_GUID):
nvram_start = FvImage.find( VARIABLE_STORE_SIGNATURE_EVSA )
if (nvram_start != -1) and (nvram_start >= tlv_h_size):
nvram_start = nvram_start - tlv_h_size
l = (FvOffset + nvram_start, FvLength - nvram_start, None)
break
if (FsGuid == ADDITIONAL_NV_STORE_GUID):
nvram_start = FvImage.find( VARIABLE_STORE_SIGNATURE_EVSA )
if (nvram_start != -1) and (nvram_start >= tlv_h_size):
nvram_start = nvram_start - tlv_h_size
l = (FvOffset + nvram_start, FvLength - nvram_start, None)
FvOffset, FsGuid, FvLength, Attributes, HeaderLength, Checksum, ExtHeaderOffset, FvImage, CalcSum = NextFwVolume(nvram_buf, FvOffset+FvLength)
return l
def EFIvar_EVSA(nvram_buf):
image_size = len(nvram_buf)
sn = 0
EVSA_RECORD = "<IIII"
evsa_rec_size = struct.calcsize(EVSA_RECORD)
GUID_RECORD = "<HIHH8s"
guid_rc_size = struct.calcsize(GUID_RECORD)
fof = 0
variables = dict()
while fof < image_size:
fof = nvram_buf.find("EVSA", fof)
if fof == -1: break
if fof < tlv_h_size:
fof = fof + 1
continue
start = fof - tlv_h_size
Tag0, Tag1, Size = struct.unpack(TLV_HEADER, nvram_buf[start: start + tlv_h_size])
if Tag0 != 0xEC: # Wrong EVSA block
fof = fof + 1
continue
value = nvram_buf[start + tlv_h_size:start + Size]
Signature, Unkwn0, Length, Unkwn1 = struct.unpack(EVSA_RECORD, value)
if start + Length > image_size: # Wrong EVSA record
fof = fof + 1
continue
# NV storage EVSA found
bof = 0
guid_map = dict()
var_list = list()
value_list = dict()
while (bof + tlv_h_size) < Length:
Tag0, Tag1, Size = struct.unpack(TLV_HEADER, nvram_buf[start + bof: start + bof + tlv_h_size])
value = nvram_buf[start + bof + tlv_h_size:start + bof + Size]
bof = bof + Size
if (Tag0 == 0xED) or (Tag0 == 0xE1): # guid
GuidId, guid0, guid1, guid2, guid3 = struct.unpack(GUID_RECORD, value)
g = guid_str(guid0, guid1, guid2, guid3)
guid_map[GuidId] = g
elif (Tag0 == 0xEE) or (Tag0 == 0xE2): # var name
VAR_NAME_RECORD = "<H%ds" % (Size - tlv_h_size - 2)
VarId, Name = struct.unpack(VAR_NAME_RECORD, value)
Name = unicode(Name, "utf-16-le")[:-1]
var_list.append((Name, VarId, Tag0, Tag1))
elif (Tag0 == 0xEF) or (Tag0 == 0xE3) or (Tag0 == 0x83): # values
VAR_VALUE_RECORD = "<HHI%ds" % (Size - tlv_h_size - 8)
GuidId, VarId, Attributes, Data = struct.unpack(VAR_VALUE_RECORD, value)
value_list[VarId] = (GuidId, Attributes, Data, Tag0, Tag1)
elif not ((Tag0 == 0xff) and (Tag1 == 0xff) and (Size == 0xffff)):
pass
var_count = len(var_list)
var_list.sort()
var1 = {}
for i in var_list:
name = i[0]
VarId = i[1]
#NameTag0 = i[2]
#NameTag1 = i[3]
if VarId in value_list:
var_value = value_list[VarId]
else:
# Value not found for VarId
continue
GuidId = var_value[0]
guid = "NONE"
if GuidId not in guid_map:
# Guid not found for GuidId
pass
else:
guid = guid_map[GuidId]
if name not in variables.keys():
variables[name] = []
# off, buf, hdr, data, guid, attrs
variables[name].append((start, None, None, var_value[2], guid, var_value[1]))
fof = fof + Length
return variables
#
# Uncomment if you want to parse output buffer returned by NtEnumerateSystemEnvironmentValuesEx
# using 'chipsec_util uefi nvram' command
#
#
# 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 )
"""
#################################################################################################3
# EFI Variable Header Dictionary
#################################################################################################3
#
# Add your EFI variable details to the dictionary
#
# Fields:
# name func_getefivariables func_getnvstore
#
EFI_VAR_DICT = {
# UEFI
FWType.EFI_FW_TYPE_UEFI : {'name' : 'UEFI', 'func_getefivariables' : getEFIvariables_UEFI },
# Windows 8 NtEnumerateSystemEnvironmentValuesEx (infcls = 2)
#FWType.EFI_FW_TYPE_WIN : {'name' : 'WIN', 'func_getefivariables' : getEFIvariables_NtEnumerateSystemEnvironmentValuesEx2, 'func_getnvstore' : None },
# NVAR format
FWType.EFI_FW_TYPE_NVAR : {'name' : 'NVAR', 'func_getefivariables' : getEFIvariables_NVAR, 'func_getnvstore' : getNVstore_NVAR },
# $VSS NVRAM format
FWType.EFI_FW_TYPE_VSS : {'name' : 'VSS', 'func_getefivariables' : getEFIvariables_VSS, 'func_getnvstore' : getNVstore_VSS },
# $VSS New NVRAM format
FWType.EFI_FW_TYPE_VSS_NEW : {'name' : 'VSS_NEW', 'func_getefivariables' : getEFIvariables_VSS_NEW, 'func_getnvstore' : getNVstore_VSS },
# EVSA
FWType.EFI_FW_TYPE_EVSA : {'name' : 'EVSA', 'func_getefivariables' : EFIvar_EVSA, 'func_getnvstore' : getNVstore_EVSA },
}