View difference between Paste ID: f604e244a and
SHOW:
|
|
- or go back to the newest paste.
1 | - | |
1 | + | #!/usr/bin/python |
2 | ||
3 | import sys, struct | |
4 | ||
5 | #VSS_OFFSET = 0x00180048 | |
6 | #VSS_SIZE = 0x4000 - 0x48 | |
7 | VSS_OFFSET = 0x000c0048 | |
8 | VSS_SIZE = 0x3f58 | |
9 | ||
10 | #PATCH_OFFSET = 0x1af | |
11 | PATCH_OFFSET = 0xae | |
12 | PATCH_VALUE = 0x01 | |
13 | PATCH_VARIABLE = u"Setup" | |
14 | ||
15 | def hexdump(s,sep=" "): | |
16 | return sep.join(map(lambda x: "%02x"%ord(x),s)) | |
17 | ||
18 | def ascii(s): | |
19 | s2 = "" | |
20 | for c in s: | |
21 | if ord(c)<0x20 or ord(c)>0x7e: | |
22 | s2 += "." | |
23 | else: | |
24 | s2 += c | |
25 | return s2 | |
26 | ||
27 | def pad(s,c,l): | |
28 | if len(s)<l: | |
29 | s += c * (l-len(s)) | |
30 | return s | |
31 | ||
32 | def chexdump(s,ts=""): | |
33 | for i in range(0,len(s),16): | |
34 | 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)) | |
35 | ||
36 | def addup(s): | |
37 | if len(s) & 1: | |
38 | s = s + "\x00" | |
39 | sum = 0 | |
40 | while len(s): | |
41 | sum += struct.unpack("<H",s[:2])[0] | |
42 | s = s[2:] | |
43 | return sum &0xFFFF | |
44 | ||
45 | class VAR(object): | |
46 | GLOBAL_VARIABLE = "\x61\xdf\xe4\x8b\xca\x93\xd2\x11\xaa\x0d\x00\xe0\x98\x03\x2b\x8c" | |
47 | def __init__(self, data): | |
48 | hdr = data[:0x20] | |
49 | self.magic, self.status, self.attributes, self.nsize, self.dsize, self.guid = struct.unpack("<HHIII16s", hdr) | |
50 | if self.magic != 0x55aa: | |
51 | raise ValueError("bad magic 0x%x"%self.magic) | |
52 | self.bname = data[0x20:0x20+self.nsize] | |
53 | self.name = ''.join(data[0x20:0x20+self.nsize:2]) | |
54 | self.name = self.name.split("\x00")[0] | |
55 | self.value = data[0x20+self.nsize:0x20+self.nsize+self.dsize] | |
56 | self.data = data[:0x20+self.nsize+self.dsize] | |
57 | cdata = data[:0x20] + "\x00\x00" + data[0x20:] | |
58 | fdata = "\xaa\x55\x7f\x00" + cdata[4:0x20+self.nsize+self.dsize] | |
59 | def update(self): | |
60 | self.nsize = len(self.name) * 2 + 2 | |
61 | self.dsize = len(self.value) | |
62 | self.data = struct.pack("<HHIII16s", self.magic, self.status, self.attributes, self.nsize, self.dsize, self.guid) | |
63 | self.data += self.name.encode('utf-16le') + "\x00\x00" | |
64 | self.data += self.value | |
65 | fdata = "\xaa\x55\x7f\x00" + self.data[4:0x20+self.nsize+self.dsize] | |
66 | self.data = self.data[:0x20] + self.data[0x20:] | |
67 | def showinfo(self, ts=''): | |
68 | print ts+"Variable %s"%repr(self.name) | |
69 | print ts+" Attributes: 0x%08x"%self.attributes | |
70 | print ts+" Status: 0x%02x"%self.status | |
71 | if self.guid == self.GLOBAL_VARIABLE: | |
72 | print ts+" VendorGUID: EFI_GLOBAL_VARIABLE (%s)"%' '.join('%02x'%ord(c) for c in self.guid) | |
73 | else: | |
74 | print ts+" VendorGUID: %s"%' '.join('%02x'%ord(c) for c in self.guid) | |
75 | print ts+" Value (0x%x bytes):"%(len(self.value)) | |
76 | chexdump(self.value, ts+" ") | |
77 | ||
78 | print "Loading BIOS..." | |
79 | bin = open(sys.argv[1], "rb").read() | |
80 | ||
81 | print "Loading VSS..." | |
82 | vss = bin[VSS_OFFSET:VSS_OFFSET+VSS_SIZE] | |
83 | ||
84 | if vss[:4] != "$VSS": | |
85 | raise ValueError("Invalid VSS signature") | |
86 | ||
87 | off = 0x10 | |
88 | ||
89 | found = False | |
90 | ||
91 | while not found and vss[off:off+2] == "\xaa\x55": | |
92 | var = VAR(vss[off:]) | |
93 | if var.name == PATCH_VARIABLE and var.status == 0x7f: | |
94 | found = True | |
95 | else: | |
96 | off += len(var.data) | |
97 | ||
98 | if not found: | |
99 | #print "Variable not found!" | |
100 | raise ValueError("Variable not found!") | |
101 | ||
102 | print "Old state:" | |
103 | var.showinfo() | |
104 | ||
105 | var.value = var.value[:PATCH_OFFSET] + chr(PATCH_VALUE) + var.value[PATCH_OFFSET+1:] | |
106 | var.update() | |
107 | print "Patched state:" | |
108 | var = VAR(var.data) | |
109 | var.showinfo() | |
110 | ||
111 | print "Updating VSS..." | |
112 | vss = vss[:off] + var.data + vss[off+len(var.data):] | |
113 | ||
114 | print "Updating BIOS..." | |
115 | bin = bin[:VSS_OFFSET] + vss + bin[VSS_OFFSET+VSS_SIZE:] | |
116 | ||
117 | print "Writing output..." | |
118 | ofd = open(sys.argv[2], "wb") | |
119 | ofd.write(bin) | |
120 | ofd.close() | |
121 | ||
122 | print "Done" |