Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- import sys, struct, codecs
- sys.stdout = codecs.getwriter('utf-8')(sys.stdout)
- #STRING_TABLE = 0x10b60
- STRING_TABLE = 0x6F80
- #STRING_TABLE=0x10DD0
- storage_map = {}
- FORMS = [
- # ('Exit', 0xcac0),
- # ('Boot', 0xcb70),
- # ('Power', 0xcca0),
- # ('Security',0xd590),
- # ('Advanced',0xd7e0),
- # ('Main', 0x10950),
- # ('OEM', 0x10cc0)
- ('Setup Engine', 0x18b98)
- ]
- def fguid(s):
- a, b, c, d = struct.unpack("<IHH8s", s)
- ds = ''.join('%02x'%ord(c) for c in d)
- return "%08x-%04x-%04x-%s-%s"%(a,b,c,ds[:4], ds[4:])
- def hexdump(s):
- return ' '.join('%02x'%ord(c) for c in s)
- class HiiPack(object):
- def __init__(self, data, offset):
- hdr = data[offset:offset+6]
- self.length, self.type = struct.unpack("<IH", hdr)
- self.data = data[offset+6:offset+self.length]
- class StringTable(HiiPack):
- def __init__(self, data, offset):
- HiiPack.__init__(self, data, offset)
- self.strings = []
- hdr = self.data[:16]
- lnoff, plnoff, count, attributes = struct.unpack("<IIII", hdr)
- print "lnoff: %x, plnoff: %x, attr: %x, count: %x"%(lnoff, plnoff, attributes, count)
- offsets = struct.unpack("<%dI"%count, self.data[16:16+count*4])
- self.name = self._getstring(lnoff)
- self.printablename = self._getstring(plnoff)
- for i in range(count):
- self.strings.append(self._getstring(offsets[i]))
- def _getstring(self, off):
- return self.data[off-6:].decode('utf-16le').split('\0')[0]
- def __getitem__(self, a):
- return self.strings.__getitem__(a)
- def showinfo(self, ts=''):
- print ts+"String table:"
- print ts+" Language: %s (%s)"%(self.name, self.printablename)
- print ts+" String count: %d"%len(self.strings)
- for i in range(0, len(self.strings)-1):
- print ts+"[0x%04x] %s"%(i, self.strings[i])
- class FormOp(object):
- EFI_IFR_FORM_OP = 0x01
- EFI_IFR_SUBTITLE_OP = 0x02
- EFI_IFR_TEXT_OP = 0x03
- EFI_IFR_GRAPHIC_OP = 0x04
- EFI_IFR_ONE_OF_OP = 0x05
- EFI_IFR_CHECKBOX_OP = 0x06
- EFI_IFR_NUMERIC_OP = 0x07
- EFI_IFR_PASSWORD_OP = 0x08
- EFI_IFR_ONE_OF_OPTION_OP = 0x09 # ONEOF OPTION field
- EFI_IFR_SUPPRESS_IF_OP = 0x0A
- EFI_IFR_END_FORM_OP = 0x0B
- EFI_IFR_HIDDEN_OP = 0x0C
- EFI_IFR_END_FORM_SET_OP = 0x0D
- EFI_IFR_FORM_SET_OP = 0x0E
- EFI_IFR_REF_OP = 0x0F
- EFI_IFR_END_ONE_OF_OP = 0x10
- EFI_IFR_END_OP = EFI_IFR_END_ONE_OF_OP
- EFI_IFR_INCONSISTENT_IF_OP = 0x11
- EFI_IFR_EQ_ID_VAL_OP = 0x12
- EFI_IFR_EQ_ID_ID_OP = 0x13
- EFI_IFR_EQ_ID_LIST_OP = 0x14
- EFI_IFR_AND_OP = 0x15
- EFI_IFR_OR_OP = 0x16
- EFI_IFR_NOT_OP = 0x17
- EFI_IFR_END_IF_OP = 0x18 # for endif of
- # inconsistentif,
- # suppressif, grayoutif
- EFI_IFR_GRAYOUT_IF_OP = 0x19
- EFI_IFR_DATE_OP = 0x1A
- EFI_IFR_TIME_OP = 0x1B
- EFI_IFR_STRING_OP = 0x1C
- EFI_IFR_LABEL_OP = 0x1D
- EFI_IFR_SAVE_DEFAULTS_OP = 0x1E
- EFI_IFR_RESTORE_DEFAULTS_OP= 0x1F
- EFI_IFR_BANNER_OP = 0x20
- EFI_IFR_INVENTORY_OP = 0x21
- EFI_IFR_EQ_VAR_VAL_OP = 0x22
- EFI_IFR_ORDERED_LIST_OP = 0x23
- EFI_IFR_VARSTORE_OP = 0x24
- EFI_IFR_VARSTORE_SELECT_OP = 0x25
- EFI_IFR_VARSTORE_SELECT_PAIR_OP = 0x26
- EFI_IFR_VARSTORE_DEVICE_OP = 0x27
- EFI_IFR_LAST_OPCODE = EFI_IFR_VARSTORE_SELECT_PAIR_OP
- EFI_IFR_OEM_OP = 0xFE
- EFI_IFR_NV_ACCESS_COMMAND = 0xFF
- INDENTS = {
- EFI_IFR_FORM_OP : 1,
- EFI_IFR_SUBTITLE_OP : 0,
- EFI_IFR_TEXT_OP : 0,
- EFI_IFR_GRAPHIC_OP : 0,
- EFI_IFR_ONE_OF_OP : 1,
- EFI_IFR_CHECKBOX_OP : 0,
- EFI_IFR_NUMERIC_OP : 0,
- EFI_IFR_PASSWORD_OP : 0,
- EFI_IFR_ONE_OF_OPTION_OP : 0,
- EFI_IFR_SUPPRESS_IF_OP : 1,
- EFI_IFR_END_FORM_OP : -1,
- EFI_IFR_HIDDEN_OP : 0,
- EFI_IFR_END_FORM_SET_OP : -1,
- EFI_IFR_FORM_SET_OP : 1,
- EFI_IFR_REF_OP : 0,
- EFI_IFR_END_OP : -1,
- EFI_IFR_INCONSISTENT_IF_OP : 0,
- EFI_IFR_EQ_ID_VAL_OP : 0,
- EFI_IFR_EQ_ID_ID_OP : 0,
- EFI_IFR_EQ_ID_LIST_OP : 0,
- EFI_IFR_AND_OP : 0,
- EFI_IFR_OR_OP : 0,
- EFI_IFR_NOT_OP : 0,
- EFI_IFR_END_IF_OP : -1,
- EFI_IFR_GRAYOUT_IF_OP : 1,
- EFI_IFR_DATE_OP : 0,
- EFI_IFR_TIME_OP : 0,
- EFI_IFR_STRING_OP : 0,
- EFI_IFR_LABEL_OP : 0,
- EFI_IFR_SAVE_DEFAULTS_OP : 0,
- EFI_IFR_RESTORE_DEFAULTS_OP: 0,
- EFI_IFR_BANNER_OP : 0,
- EFI_IFR_INVENTORY_OP : 0,
- EFI_IFR_EQ_VAR_VAL_OP : 0,
- EFI_IFR_ORDERED_LIST_OP : 0,
- EFI_IFR_VARSTORE_OP : 0,
- EFI_IFR_VARSTORE_SELECT_OP : 0,
- EFI_IFR_VARSTORE_SELECT_PAIR_OP : 0,
- EFI_IFR_VARSTORE_DEVICE_OP : 0,
- EFI_IFR_LAST_OPCODE : 0,
- EFI_IFR_OEM_OP : 0,
- EFI_IFR_NV_ACCESS_COMMAND : 0,
- }
- def __init__(self, data):
- self.opcode, self.length = struct.unpack("<BB", data[:2])
- self.payload = data[2:self.length]
- self.indent = self.INDENTS[self.opcode]
- def showinfo(self, s, ts=''):
- if self.opcode == self.EFI_IFR_FORM_OP:
- id, title = struct.unpack("<HH", self.payload)
- print ts+"Form ID:0x%04x Name:'%s' (0x%04x)"%(id, s[title], title)
- elif self.opcode == self.EFI_IFR_SUBTITLE_OP:
- print ts+"Subtitle: '%s'"%s[struct.unpack("<H", self.payload)[0]]
- elif self.opcode == self.EFI_IFR_TEXT_OP:
- if len(self.payload) != 9:
- print ts+"BROKEN TEXT OP %r"%self.payload
- else:
- hid, tid, t2id, flags, key=struct.unpack("<HHHBH", self.payload)
- print ts+"Text: '%s','%s' Flags:0x%x Key:0x%x"%(s[tid],s[t2id],flags,key)
- if s[hid] and s[hid] != ' ':
- print ts+"\Help text: '%s'"%s[hid]
- elif self.opcode == self.EFI_IFR_FORM_SET_OP:
- guid, fsid, hid, cb, cls, subcls, nvsize = struct.unpack("<16sHHQHHH", self.payload)
- print ts+"Form Set '%s' Class %d-%d NvSize 0x%x Callback 0x%x"%(s[fsid],cls, subcls, nvsize, cb)
- print ts+"\GUID: %s"%fguid(guid)
- if s[hid] and s[hid] != ' ':
- print ts+"\Help text: '%s'"%s[hid]
- elif self.opcode == self.EFI_IFR_END_FORM_SET_OP:
- print ts+"End Form Set"
- elif self.opcode == self.EFI_IFR_END_FORM_OP:
- print ts+"End Form"
- elif self.opcode == self.EFI_IFR_GRAYOUT_IF_OP:
- print ts+"Grayout If"
- elif self.opcode == self.EFI_IFR_SUPPRESS_IF_OP:
- print ts+"Suppress If"
- elif self.opcode == self.EFI_IFR_END_IF_OP:
- print ts+"End If",hexdump(self.payload)
- elif self.opcode == self.EFI_IFR_EQ_ID_VAL_OP:
- qid, width, val = struct.unpack("<HBH", self.payload)
- print ts+"EQ [0x%x<%d>] == 0x%x"%(qid, width, val)
- elif self.opcode == self.EFI_IFR_EQ_ID_ID_OP:
- qid, width, qid2, width2, val = struct.unpack("<HBHB", self.payload)
- print ts+"EQ [0x%x<%d>] == [0x%x.%d]"%(qid, width, qid2, width2, val)
- elif self.opcode == self.EFI_IFR_EQ_ID_LIST_OP:
- qid, width, length = struct.unpack("<HBH", self.payload[:5])
- l = struct.unpack("<%dH"%length, self.payload[5:])
- print ts+"LIST [0x%x<%d>] in (%s)"%(qid, width, ','.join(["0x%x"%i for i in l]))
- elif self.opcode == self.EFI_IFR_AND_OP:
- print ts+"AND"
- elif self.opcode == self.EFI_IFR_OR_OP:
- print ts+"OR"
- elif self.opcode == self.EFI_IFR_NOT_OP:
- print ts+"NOT"
- elif self.opcode == self.EFI_IFR_ONE_OF_OP:
- qid, width, pid, hid = struct.unpack("<HBHH", self.payload)
- storage_map[qid] = s[pid]
- print ts+"One Of [0x%x<%d>] '%s'"%(qid, width, s[pid])
- if s[hid] and s[hid] != ' ':
- print ts+"\Help text: '%s'"%s[hid]
- elif self.opcode == self.EFI_IFR_ONE_OF_OPTION_OP:
- oid, value, flags, key = struct.unpack("<HHBH", self.payload)
- print ts+"Option '%s' = 0x%x Flags 0x%x Key 0x%x"%(s[oid], value, flags, key)
- elif self.opcode == self.EFI_IFR_END_ONE_OF_OP:
- print ts+"End One Of"
- elif self.opcode == self.EFI_IFR_LABEL_OP:
- lid = struct.unpack("<H", self.payload)[0]
- print ts+"Label ID: 0x%x"%lid
- elif self.opcode == self.EFI_IFR_REF_OP:
- fid, pid, hid, flags, key = struct.unpack("<HHHBH", self.payload)
- print ts+"Reference: '%s' Form ID 0x%x Flags 0x%x Key 0x%x"%(s[pid], fid, flags, key)
- if s[hid] and s[hid] != ' ':
- print ts+"\Help text: '%s'"%s[hid]
- elif self.opcode in (self.EFI_IFR_TIME_OP, self.EFI_IFR_DATE_OP, self.EFI_IFR_NUMERIC_OP):
- qid, width, pid, hid, flags, key, min, max, step, default = struct.unpack("<HBHHBHHHHH", self.payload)
- t = {self.EFI_IFR_TIME_OP:'Time', self.EFI_IFR_DATE_OP:'Date', self.EFI_IFR_NUMERIC_OP:'Numeric'}[self.opcode]
- 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)
- if s[hid] and s[hid] != ' ':
- print ts+"\Help text: '%s'"%s[hid]
- elif self.opcode == self.EFI_IFR_PASSWORD_OP:
- qid, width, pid, hid, flags, key, mins, maxs, encoding = struct.unpack("<HBHHBHBBH", self.payload)
- storage_map[qid] = s[pid]
- 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)
- if s[hid] and s[hid] != ' ':
- print ts+"\Help text: '%s'"%s[hid]
- else:
- print ts+"Opcode 0x%x (%d)"%(self.opcode, self.length),hexdump(self.payload)
- class Form(HiiPack):
- def __init__(self, data, offset):
- HiiPack.__init__(self, data, offset)
- data = self.data
- self.opcodes = []
- while len(data):
- op = FormOp(data)
- data = data[op.length:]
- self.opcodes.append(op)
- print len(self.opcodes)
- def showinfo(self, stringtable, ts=''):
- ind = 0
- in_if = False
- fstk = []
- for op in self.opcodes:
- if op.opcode == op.EFI_IFR_FORM_OP:
- fstk.append(ind)
- if op.indent < 0:
- ind += op.indent
- ots = ts+' '*ind
- if in_if and op.opcode in (op.EFI_IFR_SUPPRESS_IF_OP, op.EFI_IFR_GRAYOUT_IF_OP):
- ots = ts+' '*(ind-1)+'+'
- try:
- op.showinfo(stringtable, ots)
- except:
- print ts+"ERROR DECODING OPCODE 0x%x LEN 0x%x"%(op.opcode, op.length)
- finally:
- pass
- 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:
- ind += op.indent
- if op.opcode in (op.EFI_IFR_SUPPRESS_IF_OP, op.EFI_IFR_GRAYOUT_IF_OP):
- in_if = True
- elif op.opcode == op.EFI_IFR_END_IF_OP:
- in_if = False
- if op.opcode == op.EFI_IFR_END_FORM_OP:
- xind = fstk.pop()
- if xind != ind:
- print "WARNING: Indentation mismatch"
- ind = xind
- pe = open(sys.argv[1], "rb").read()
- strings = StringTable(pe, STRING_TABLE)
- strings.showinfo()
- for fn, off in FORMS:
- print
- print "Reading form '%s'"%fn
- f = Form(pe, off)
- f.showinfo(strings, ' ')
- print "Storage map:"
- for k in sorted(storage_map.keys()):
- print " 0x%x: %s"%(k,storage_map[k])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement