Advertisement
Guest User

MaxL

a guest
Aug 1st, 2009
1,847
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.39 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. import sys, struct, codecs
  4.  
  5. sys.stdout = codecs.getwriter('utf-8')(sys.stdout)
  6.  
  7. #STRING_TABLE = 0x10b60
  8. STRING_TABLE = 0x6F80
  9. storage_map = {}
  10.  
  11. FORMS = [
  12. #   ('Exit',    0xc640),
  13. #   ('Boot',    0xc6f0),
  14. #   ('Power',   0xc810),
  15. #   ('Security',0xd140),
  16. #   ('Advanced',0xd390),
  17. #   ('Main',    0x106b0),
  18. #   ('OEM',     0x10a20)
  19.     ('Setup Engine', 0x18b98)
  20. ]
  21.  
  22. def fguid(s):
  23.     a, b, c, d = struct.unpack("<IHH8s", s)
  24.     ds = ''.join('%02x'%ord(c) for c in d)
  25.     return "%08x-%04x-%04x-%s-%s"%(a,b,c,ds[:4], ds[4:])
  26.  
  27. def hexdump(s):
  28.     return ' '.join('%02x'%ord(c) for c in s)
  29.  
  30. class HiiPack(object):
  31.     def __init__(self, data, offset):
  32.         hdr = data[offset:offset+6]
  33.         self.length, self.type = struct.unpack("<IH", hdr)
  34.         self.data = data[offset+6:offset+self.length]
  35.  
  36. class StringTable(HiiPack):
  37.     def __init__(self, data, offset):
  38.         HiiPack.__init__(self, data, offset)
  39.         self.strings = []
  40.         hdr = self.data[:16]
  41.         lnoff, plnoff, count, attributes = struct.unpack("<IIII", hdr)
  42.         offsets = struct.unpack("<%dI"%count, self.data[16:16+count*4])
  43.         self.name = self._getstring(lnoff)
  44.         self.printablename = self._getstring(plnoff)
  45.         for i in range(count):
  46.             self.strings.append(self._getstring(offsets[i]))
  47.     def _getstring(self, off):
  48.         return self.data[off-6:].decode('utf-16le').split('\0')[0]
  49.     def __getitem__(self, a):
  50.         return self.strings.__getitem__(a)
  51.     def showinfo(self, ts=''):
  52.         print ts+"String table:"
  53.         print ts+" Language: %s (%s)"%(self.name, self.printablename)
  54.         print ts+" String count: %d"%len(self.strings)
  55.  
  56. class FormOp(object):
  57.     EFI_IFR_FORM_OP            = 0x01
  58.     EFI_IFR_SUBTITLE_OP        = 0x02
  59.     EFI_IFR_TEXT_OP            = 0x03
  60.     EFI_IFR_GRAPHIC_OP         = 0x04
  61.     EFI_IFR_ONE_OF_OP          = 0x05
  62.     EFI_IFR_CHECKBOX_OP        = 0x06
  63.     EFI_IFR_NUMERIC_OP         = 0x07
  64.     EFI_IFR_PASSWORD_OP        = 0x08
  65.     EFI_IFR_ONE_OF_OPTION_OP   = 0x09 # ONEOF OPTION field
  66.     EFI_IFR_SUPPRESS_IF_OP     = 0x0A
  67.     EFI_IFR_END_FORM_OP        = 0x0B
  68.     EFI_IFR_HIDDEN_OP          = 0x0C
  69.     EFI_IFR_END_FORM_SET_OP    = 0x0D
  70.     EFI_IFR_FORM_SET_OP        = 0x0E
  71.     EFI_IFR_REF_OP             = 0x0F
  72.     EFI_IFR_END_ONE_OF_OP      = 0x10
  73.     EFI_IFR_END_OP             = EFI_IFR_END_ONE_OF_OP
  74.     EFI_IFR_INCONSISTENT_IF_OP = 0x11
  75.     EFI_IFR_EQ_ID_VAL_OP       = 0x12
  76.     EFI_IFR_EQ_ID_ID_OP        = 0x13
  77.     EFI_IFR_EQ_ID_LIST_OP      = 0x14
  78.     EFI_IFR_AND_OP             = 0x15
  79.     EFI_IFR_OR_OP              = 0x16
  80.     EFI_IFR_NOT_OP             = 0x17
  81.     EFI_IFR_END_IF_OP          = 0x18 # for endif of
  82.                                     # inconsistentif,
  83.                                     # suppressif, grayoutif
  84.     EFI_IFR_GRAYOUT_IF_OP      = 0x19
  85.     EFI_IFR_DATE_OP            = 0x1A
  86.     EFI_IFR_TIME_OP            = 0x1B
  87.     EFI_IFR_STRING_OP          = 0x1C
  88.     EFI_IFR_LABEL_OP           = 0x1D
  89.     EFI_IFR_SAVE_DEFAULTS_OP   = 0x1E
  90.     EFI_IFR_RESTORE_DEFAULTS_OP= 0x1F
  91.     EFI_IFR_BANNER_OP          = 0x20
  92.     EFI_IFR_INVENTORY_OP       = 0x21
  93.     EFI_IFR_EQ_VAR_VAL_OP      = 0x22
  94.     EFI_IFR_ORDERED_LIST_OP    = 0x23
  95.     EFI_IFR_VARSTORE_OP        = 0x24
  96.     EFI_IFR_VARSTORE_SELECT_OP = 0x25
  97.     EFI_IFR_VARSTORE_SELECT_PAIR_OP  = 0x26
  98.     EFI_IFR_VARSTORE_DEVICE_OP = 0x27
  99.     EFI_IFR_LAST_OPCODE        = EFI_IFR_VARSTORE_SELECT_PAIR_OP
  100.     EFI_IFR_OEM_OP             = 0xFE
  101.     EFI_IFR_NV_ACCESS_COMMAND  = 0xFF
  102.    
  103.     INDENTS = {
  104.         EFI_IFR_FORM_OP            : 1,
  105.         EFI_IFR_SUBTITLE_OP        : 0,
  106.         EFI_IFR_TEXT_OP            : 0,
  107.         EFI_IFR_GRAPHIC_OP         : 0,
  108.         EFI_IFR_ONE_OF_OP          : 1,
  109.         EFI_IFR_CHECKBOX_OP        : 0,
  110.         EFI_IFR_NUMERIC_OP         : 0,
  111.         EFI_IFR_PASSWORD_OP        : 0,
  112.         EFI_IFR_ONE_OF_OPTION_OP   : 0,
  113.         EFI_IFR_SUPPRESS_IF_OP     : 1,
  114.         EFI_IFR_END_FORM_OP        : -1,
  115.         EFI_IFR_HIDDEN_OP          : 0,
  116.         EFI_IFR_END_FORM_SET_OP    : -1,
  117.         EFI_IFR_FORM_SET_OP        : 1,
  118.         EFI_IFR_REF_OP             : 0,
  119.         EFI_IFR_END_OP             : -1,
  120.         EFI_IFR_INCONSISTENT_IF_OP : 0,
  121.         EFI_IFR_EQ_ID_VAL_OP       : 0,
  122.         EFI_IFR_EQ_ID_ID_OP        : 0,
  123.         EFI_IFR_EQ_ID_LIST_OP      : 0,
  124.         EFI_IFR_AND_OP             : 0,
  125.         EFI_IFR_OR_OP              : 0,
  126.         EFI_IFR_NOT_OP             : 0,
  127.         EFI_IFR_END_IF_OP          : -1,
  128.         EFI_IFR_GRAYOUT_IF_OP      : 1,
  129.         EFI_IFR_DATE_OP            : 0,
  130.         EFI_IFR_TIME_OP            : 0,
  131.         EFI_IFR_STRING_OP          : 0,
  132.         EFI_IFR_LABEL_OP           : 0,
  133.         EFI_IFR_SAVE_DEFAULTS_OP   : 0,
  134.         EFI_IFR_RESTORE_DEFAULTS_OP: 0,
  135.         EFI_IFR_BANNER_OP          : 0,
  136.         EFI_IFR_INVENTORY_OP       : 0,
  137.         EFI_IFR_EQ_VAR_VAL_OP      : 0,
  138.         EFI_IFR_ORDERED_LIST_OP    : 0,
  139.         EFI_IFR_VARSTORE_OP        : 0,
  140.         EFI_IFR_VARSTORE_SELECT_OP : 0,
  141.         EFI_IFR_VARSTORE_SELECT_PAIR_OP : 0,
  142.         EFI_IFR_VARSTORE_DEVICE_OP : 0,
  143.         EFI_IFR_LAST_OPCODE        : 0,
  144.         EFI_IFR_OEM_OP             : 0,
  145.         EFI_IFR_NV_ACCESS_COMMAND  : 0,
  146.     }
  147.    
  148.     def __init__(self, data):
  149.         self.opcode, self.length = struct.unpack("<BB", data[:2])
  150.         self.payload = data[2:self.length]
  151.         self.indent = self.INDENTS[self.opcode]
  152.        
  153.     def showinfo(self, s, ts=''):
  154.         if self.opcode == self.EFI_IFR_FORM_OP:
  155.             id, title = struct.unpack("<HH", self.payload)
  156.             print ts+"Form ID:0x%04x Name:'%s'"%(id, s[title])
  157.         elif self.opcode == self.EFI_IFR_SUBTITLE_OP:
  158.             print ts+"Subtitle: '%s'"%s[struct.unpack("<H", self.payload)[0]]
  159.         elif self.opcode == self.EFI_IFR_TEXT_OP:
  160.             if len(self.payload) != 9:
  161.                 print ts+"BROKEN TEXT OP %r"%self.payload
  162.             else:
  163.                 hid, tid, t2id, flags, key=struct.unpack("<HHHBH", self.payload)
  164.                 print ts+"Text: '%s','%s' Flags:0x%x Key:0x%x"%(s[tid],s[t2id],flags,key)
  165.                 if s[hid] and s[hid] != ' ':
  166.                     print ts+"\Help text: '%s'"%s[hid]
  167.         elif self.opcode == self.EFI_IFR_FORM_SET_OP:
  168.             guid, fsid, hid, cb, cls, subcls, nvsize = struct.unpack("<16sHHQHHH", self.payload)
  169.             print ts+"Form Set '%s' Class %d-%d NvSize 0x%x Callback 0x%x"%(s[fsid],cls, subcls, nvsize, cb)
  170.             print ts+"\GUID: %s"%fguid(guid)
  171.             if s[hid] and s[hid] != ' ':
  172.                 print ts+"\Help text: '%s'"%s[hid]
  173.         elif self.opcode == self.EFI_IFR_END_FORM_SET_OP:
  174.             print ts+"End Form Set"
  175.         elif self.opcode == self.EFI_IFR_END_FORM_OP:
  176.             print ts+"End Form"
  177.         elif self.opcode == self.EFI_IFR_GRAYOUT_IF_OP:
  178.             print ts+"Grayout If"
  179.         elif self.opcode == self.EFI_IFR_SUPPRESS_IF_OP:
  180.             print ts+"Suppress If"
  181.         elif self.opcode == self.EFI_IFR_END_IF_OP:
  182.             print ts+"End If",hexdump(self.payload)
  183.         elif self.opcode == self.EFI_IFR_EQ_ID_VAL_OP:
  184.             qid, width, val = struct.unpack("<HBH", self.payload)
  185.             print ts+"EQ [0x%x<%d>] == 0x%x"%(qid, width, val)
  186.         elif self.opcode == self.EFI_IFR_EQ_ID_ID_OP:
  187.             qid, width, qid2, width2, val = struct.unpack("<HBHB", self.payload)
  188.             print ts+"EQ [0x%x<%d>] == [0x%x.%d]"%(qid, width, qid2, width2, val)
  189.         elif self.opcode == self.EFI_IFR_EQ_ID_LIST_OP:
  190.             qid, width, length = struct.unpack("<HBH", self.payload[:5])
  191.             l = struct.unpack("<%dH"%length, self.payload[5:])
  192.             print ts+"LIST [0x%x<%d>] in (%s)"%(qid, width, ','.join(["0x%x"%i for i in l]))
  193.         elif self.opcode == self.EFI_IFR_AND_OP:
  194.             print ts+"AND"
  195.         elif self.opcode == self.EFI_IFR_OR_OP:
  196.             print ts+"OR"
  197.         elif self.opcode == self.EFI_IFR_NOT_OP:
  198.             print ts+"NOT"
  199.         elif self.opcode == self.EFI_IFR_ONE_OF_OP:
  200.             qid, width, pid, hid = struct.unpack("<HBHH", self.payload)
  201.             storage_map[qid] = s[pid]
  202.             print ts+"One Of [0x%x<%d>] '%s'"%(qid, width, s[pid])
  203.             if s[hid] and s[hid] != ' ':
  204.                 print ts+"\Help text: '%s'"%s[hid]
  205.         elif self.opcode == self.EFI_IFR_ONE_OF_OPTION_OP:
  206.             oid, value, flags, key = struct.unpack("<HHBH", self.payload)
  207.             print ts+"Option '%s' = 0x%x Flags 0x%x Key 0x%x"%(s[oid], value, flags, key)
  208.         elif self.opcode == self.EFI_IFR_END_ONE_OF_OP:
  209.             print ts+"End One Of"
  210.         elif self.opcode == self.EFI_IFR_LABEL_OP:
  211.             lid = struct.unpack("<H", self.payload)[0]
  212.             print ts+"Label ID: 0x%x"%lid
  213.         elif self.opcode == self.EFI_IFR_REF_OP:
  214.             fid, pid, hid, flags, key = struct.unpack("<HHHBH", self.payload)
  215.             print ts+"Reference: '%s' Form ID 0x%x Flags 0x%x Key 0x%x"%(s[pid], fid, flags, key)
  216.             if s[hid] and s[hid] != ' ':
  217.                 print ts+"\Help text: '%s'"%s[hid]
  218.         elif self.opcode in (self.EFI_IFR_TIME_OP, self.EFI_IFR_DATE_OP, self.EFI_IFR_NUMERIC_OP):
  219.             qid, width, pid, hid, flags, key, min, max, step, default = struct.unpack("<HBHHBHHHHH", self.payload)
  220.             t = {self.EFI_IFR_TIME_OP:'Time', self.EFI_IFR_DATE_OP:'Date', self.EFI_IFR_NUMERIC_OP:'Numeric'}[self.opcode]
  221.             print ts+"%s: '%s' [0x%x<%d>] %d-%d Step %d Default %d Flags 0x%x"%(t, s[pid], qid, width, min, max, step, default, flags)
  222.             if s[hid] and s[hid] != ' ':
  223.                 print ts+"\Help text: '%s'"%s[hid]
  224.         elif self.opcode == self.EFI_IFR_PASSWORD_OP:
  225.             qid, width, pid, hid, flags, key, mins, maxs, encoding = struct.unpack("<HBHHBHBBH", self.payload)
  226.             storage_map[qid] = s[pid]
  227.             print ts+"Password: '%s' [0x%x<%d>] Flags 0x%x Key 0x%x Size %d-%d Encoding %d"%(s[pid], qid, width, flags, key, mins, maxs, encoding)
  228.             if s[hid] and s[hid] != ' ':
  229.                 print ts+"\Help text: '%s'"%s[hid]
  230.         else:
  231.             print ts+"Opcode 0x%x (%d)"%(self.opcode, self.length),hexdump(self.payload)
  232.  
  233. class Form(HiiPack):
  234.     def __init__(self, data, offset):
  235.         HiiPack.__init__(self, data, offset)
  236.         data = self.data
  237.         self.opcodes = []
  238.         while len(data):
  239.             op = FormOp(data)
  240.             data = data[op.length:]
  241.             self.opcodes.append(op)
  242.            
  243.     def showinfo(self, stringtable, ts=''):
  244.         ind = 0
  245.         in_if = False
  246.         fstk = []
  247.         for op in self.opcodes:
  248.             if op.opcode == op.EFI_IFR_FORM_OP:
  249.                 fstk.append(ind)
  250.             if op.indent < 0:
  251.                 ind += op.indent
  252.             ots = ts+' '*ind
  253.             if in_if and op.opcode in (op.EFI_IFR_SUPPRESS_IF_OP, op.EFI_IFR_GRAYOUT_IF_OP):
  254.                 ots = ts+' '*(ind-1)+'+'
  255.             try:
  256.                 op.showinfo(stringtable, ots)
  257.             #except:
  258.             #   print ts+"ERROR DECODING OPCODE 0x%x LEN 0x%x"%(op.opcode, op.length)
  259.             finally:
  260.                 pass
  261.             if (not in_if or op.opcode not in (op.EFI_IFR_SUPPRESS_IF_OP, op.EFI_IFR_GRAYOUT_IF_OP) ) and op.indent > 0:
  262.                 ind += op.indent
  263.             if op.opcode in (op.EFI_IFR_SUPPRESS_IF_OP, op.EFI_IFR_GRAYOUT_IF_OP):
  264.                 in_if = True
  265.             elif op.opcode == op.EFI_IFR_END_IF_OP:
  266.                 in_if = False
  267.             if op.opcode == op.EFI_IFR_END_FORM_OP:
  268.                 xind = fstk.pop()
  269.                 if xind != ind:
  270.                     print "WARNING: Indentation mismatch"
  271.                     ind = xind
  272.  
  273. pe = open(sys.argv[1], "rb").read()
  274.  
  275. strings = StringTable(pe, STRING_TABLE)
  276. strings.showinfo()
  277.  
  278. for fn, off in FORMS:
  279.     print
  280.     print "Reading form '%s'"%fn
  281.     f = Form(pe, off)
  282.     f.showinfo(strings, ' ')
  283.    
  284. print "Storage map:"
  285. for k in sorted(storage_map.keys()):
  286.     print " 0x%x: %s"%(k,storage_map[k])
  287.  
  288.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement