Report abuse

fvdump.py (python)

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
#!/usr/bin/python
import sys, struct

class FV(object):
	def __init__(self, data):
		hdr = data[:0x38]
		self.rsvd, self.guid, self.size, self.magic, self.attributes, self.hdrlen, self.checksum, self.rsvd2, self.revision = struct.unpack("<16s16sQ4sIHH3sB", hdr)
		if self.magic != '_FVH':
			raise ValueError("bad magic %s"%repr(self.magic))
		data = data[:self.size]
		self.data = data[self.hdrlen:]
		self.blocks = []
		bdata = data[0x38:self.hdrlen]
		while len(bdata):
			bl = bdata[:8]
			numb, blen = struct.unpack("<II",bl)
			if (numb, blen) == (0,0):
				break
			self.blocks.append((numb, blen))
			bdata = bdata[8:]
	def showinfo(self, ts=''):
		print ts+"Reserved boot zone:", ' '.join('%02x'%ord(c) for c in self.rsvd)
		print ts+"GUID:", ' '.join('%02x'%ord(c) for c in self.guid)
		print ts+"Size: 0x%x (data 0x%x)"%(self.size,len(self.data))
		print ts+"Attributes: 0x%08x"%self.attributes
		print ts+"Revision: %d"%self.revision
		print ts+"Blocks:"
		for numb, blen in self.blocks:
			print ts+" %d: len 0x%x"%(numb,blen)

f = open(sys.argv[1],"rb")

d = f.read()

for start in range(32,len(d),16):
	if d[start+8:start+12] == '_FVH':
		start -= 32
		print "Firmware Volume at %08x"%start
		fv = FV(d[start:])
		fv.showinfo(' ')
		fn = "fv-%08x.bin"%start
		print "Dumping to %s"%fn
		fout = open(fn,"wb")
		fout.write(fv.data)
		fout.close()

vardump.py (python)

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
#!/usr/bin/python
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()