import sys, struct
def hexdump(s,sep=" "):
return sep.join(map(lambda x: "%02x"%ord(x),s))
def ascii(s):
s2 = ""
for c in s:
if ord(c)<0x20 or ord(c)>0x7e:
s2 += "."
else:
s2 += c
return s2
def pad(s,c,l):
if len(s)<l:
s += c * (l-len(s))
return s
def chexdump(s,ts=""):
for i in range(0,len(s),16):
print ts+"%08x %s %s |%s|"%(i,pad(hexdump(s[i:i+8],' ')," ",23),pad(hexdump(s[i+8:i+16],' ')," ",23),pad(ascii(s[i:i+16])," ",16))
class VAR(object):
GLOBAL_VARIABLE = "\x61\xdf\xe4\x8b\xca\x93\xd2\x11\xaa\x0d\x00\xe0\x98\x03\x2b\x8c"
def __init__(self, data):
hdr = data[:0x22]
self.magic, self.iter, self.attributes, self.nsize, self.dsize, self.guid, self.checksum = struct.unpack("<HHIII16sH", hdr)
if self.magic != 0x55aa:
raise ValueError("bad magic 0x%x"%self.magic)
self.name = ''.join(data[0x22:0x22+self.nsize:2])
self.name = self.name.split("\x00")[0]
self.value = data[0x22+self.nsize:0x22+self.nsize+self.dsize]
self.rest = data[0x22+self.nsize+self.dsize:]
def showinfo(self, ts=''):
print ts+"Variable %s"%repr(self.name)
print ts+" Attributes: 0x%08x"%self.attributes
print ts+" Iteration: 0x%02x"%self.iter
if self.guid == self.GLOBAL_VARIABLE:
print ts+" VendorGUID: EFI_GLOBAL_VARIABLE (%s)"%' '.join('%02x'%ord(c) for c in self.guid)
else:
print ts+" VendorGUID: %s"%' '.join('%02x'%ord(c) for c in self.guid)
print ts+" Checksum: 0x%02x"%self.checksum
print ts+" Value (0x%x bytes):"%(len(self.value))
chexdump(self.value, ts+" ")
f = open(sys.argv[1],"rb")
d = f.read()
hdr = d[:16]
if hdr[:4] != '$VSS':
raise ValueError("Bad header")
size, unk = struct.unpack("II",hdr[4:12])
vdb = d[16:size]
vdbt = {}
while vdb[:2] == "\xaa\x55":
v = VAR(vdb)
vdb = v.rest
if v.name not in vdbt or vdbt[v.name].iter <= v.iter:
vdbt[v.name] = v
for k in sorted(vdbt):
vdbt[k].showinfo()