SHARE
TWEET

MaxL

a guest Aug 1st, 2009 4,658 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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"
RAW Paste Data
Top