Guest User

MaxL

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

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×