Nick: roxfan E-mail: none Board: unknown Contents: # extract microcode updates from binary BIOS files # v 0.1 2012/07/23 # v 0.2 2012/07/23 added VIA Nano support (relaxed some checks) import ctypes import struct import sys import array uint8_t = ctypes.c_ubyte char = ctypes.c_char uint32_t = ctypes.c_uint uint64_t = ctypes.c_uint64 uint16_t = ctypes.c_ushort def get_struct(str_, off, struct): s = struct() slen = ctypes.sizeof(s) bytes = str_[off:off+slen] fit = min(len(bytes), slen) ctypes.memmove(ctypes.addressof(s), bytes, fit) return s def DwordAt(f, off): return struct.unpack(" maxoff: return # update size must be a multiple of DWORD if (hdr.DataSize & 3) or (hdr.TotalSize & 3): return # looks okay. let's check the checksum mdata = f[off:off+check_len] # make an array of DWORDs arr = array.array("I", mdata) # sum them ck = sum(arr) & 0xFFFFFFFF if ck == 0: print "%08X: found a valid-looking update" % off print ["Date: %02X/%02X/%4X", "Date: %02d/%02d/%4d"][is_via] % ((hdr.Date >> 24)&0xFF, (hdr.Date >> 16)&0xFF, hdr.Date & 0xFFFF) print "Processor signature: %08X" % hdr.ProcessorSignature if not is_via: print "Processor flags: %08X" % hdr.ProcessorFlags print "Length: %08X" % check_len fname = "mcode_upd_%08X.bin" % off print "Extracting to %s" % fname open(fname, "wb").write(mdata) return True # nope return False def find_ucode(f, is_via): maxoff = len(f) # minimal microcode update length is 2048 bytes off = (maxoff-2048+8)&(~15) # look for BCD date ddmmyyyy # yyyy off-2 # dd off-1 # mm off print "Scanning...\n%08X" % off while off > 11: # looks like a date? m = ord(f[off]) if (1 <= m <= 0x12) and (1 <= ord(f[off-1]) <= 0x31): if check_valid_mcode(f, off-11, maxoff, is_via): maxoff = off-11 print "Scanning...\n%08X" % off off -= 1 if (off & 0xFFFFF) == 0: print "%08X" % off print "\nDone" if len(sys.argv) < 2: print "Usage: microcode_extract.py [-i|-v]" print " -i: look for Intel microcode (default)" print " -v: look for VIA Nano microcode" sys.exit(1) else: fn = None is_via = False for arg in sys.argv[1:]: if arg == "-v": is_via = True elif arg == "-i": is_via = False else: fn = arg f = open(fn, "rb").read() find_ucode(f, is_via)