Skip to content

Commit

Permalink
MCE v1.1.2 & DB r12
Browse files Browse the repository at this point in the history
v1.1.2

Fixed crash at Intel Extended Microcode Header analysis
Fixed various code issues and errors under rare cases
Improved "Skipped Microcode" text with Intel,AMD,VIA
Updated Microcode Repository Database to r12

r12

cpu000906E9_plat22_ver00000048_date15-11-2016
cpu00050671_plat78_verFFFF01A0_date12-10-2016
cpu000306F4_plat80_ver0000000E_date07-10-2016
cpu000506C9_plat01_ver00000020_date09-09-2016
cpu000906E9_plat22_ver0000002C_date16-06-2016
  • Loading branch information
platomav authored Dec 19, 2016
1 parent 032f4ed commit f1df349
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 55 deletions.
8 changes: 8 additions & 0 deletions Changelog DB.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
r12

cpu000906E9_plat22_ver00000048_date15-11-2016
cpu00050671_plat78_verFFFF01A0_date12-10-2016
cpu000306F4_plat80_ver0000000E_date07-10-2016
cpu000506C9_plat01_ver00000020_date09-09-2016
cpu000906E9_plat22_ver0000002C_date16-06-2016

r11

cpu00050671_plat78_ver000001A1_date20-10-2016
Expand Down
7 changes: 7 additions & 0 deletions Changelog MCE.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
v1.1.2

Fixed crash at Intel Extended Microcode Header analysis
Fixed various code issues and errors under rare cases
Improved "Skipped Microcode" text with Intel,AMD,VIA
Updated Microcode Repository Database to r12

v1.1.0

Major performance improvement, up to x10 times faster
Expand Down
9 changes: 7 additions & 2 deletions MCE.dat
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
*** MC Extractor Microcode Repository Database ***
*** Revision r11 (23/11/2016 , 20:53) ***
*** Revision r12 (12/12/2016 , 15:33) ***

*** INTEL (1340) ***
*** INTEL (1345) ***

CPUID + PLATFORM + VERSION + MMDDYYYY + SIZE + CHECKSUM

000906E9000000220000004811152016000178004761D4C9
000506C900000001000000200909201600003C00D3A8176D
0005067100000078FFFF01A010122016000058003ABD24E0
000906E9000000220000002C0616201600017400F87BFABC
000306F4000000800000000E1007201600003C006A49D5A3
0005067100000078000001A11020201600005C00C33A135A
000406E3000000C0000000A20727201600017C0085A3645E
000406C4000000010000040E1014201600010C002D30C9EB
Expand Down
110 changes: 57 additions & 53 deletions MCE.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
'''
MC Extractor v1.1.0.0
"""
MC Extractor
Intel, AMD & VIA Microcode Extractor
Copyright (C) 2016 Plato Mavropoulos
Based on UEFIStrip v7.8.2 by Lordkag
'''
"""

title = 'MC Extractor v1.1.0'
title = 'MC Extractor v1.1.2'

import sys
import re
Expand Down Expand Up @@ -33,7 +34,7 @@
uint64_t = ctypes.c_uint64

class MCE_Param :

def __init__(self,source) :

self.all = ['-?','-skip','-info','-pdb','-padd','-file','-false','-extr','-exc','-cont','-mass']
Expand Down Expand Up @@ -83,8 +84,8 @@ class Intel_MC_Header(ctypes.LittleEndianStructure) :
("Reserved2", uint32_t), # 28
("Reserved3", uint32_t), # 2C
# 30
]
]

def mc_print(self) :

full_date = "%0.2X/%0.2X/%0.4X" % (self.Day, self.Month, self.Year)
Expand Down Expand Up @@ -129,22 +130,22 @@ class Intel_MC_Header_Extra(ctypes.LittleEndianStructure) :
("RSAPublicKey", uint32_t*64), # 80
("RSAExponent", uint32_t), # 180
# 184
]
]

def mc_print_extra(self) :

full_date = "%0.2X/%0.2X/%0.4X" % (self.Day, self.Month, self.Year)

Unknown5 = " ".join("%0.8X" % val for val in self.Unknown5)
if re.match('(0{8} ){6}0{8}', Unknown5) : Unknown5 = '00 * 28'
unknown5 = " ".join("%0.8X" % val for val in self.unknown5)
if re.match('(0{8} ){6}0{8}', unknown5) : unknown5 = '00 * 28'

Unknown8 = " ".join("%0.8X" % val for val in self.Unknown8)
if re.match('(0{8} ){4}0{8}', Unknown8) : Unknown8 = '00 * 20'
unknown8 = " ".join("%0.8X" % val for val in self.unknown8)
if re.match('(0{8} ){4}0{8}', unknown8) : unknown8 = '00 * 20'

Unknown9 = " ".join("%0.8X" % val for val in self.Unknown9)
unknown9 = " ".join("%0.8X" % val for val in self.unknown9)
RSAPublicKey = " ".join("%0.8X" % val for val in self.RSAPublicKey)

UpdateSize = (self.UpdateSize)*4
UpdateSize = self.UpdateSize * 4

print("")
print("-----------------Intel Extra Header-----------------\n")
Expand All @@ -158,11 +159,11 @@ def mc_print_extra(self) :
print("Update Size: 0x%0.2X" % UpdateSize)
print("Loader Revision: %0.8X" % self.LoaderRevision)
print("Processor Signature: %0.8X" % self.ProcessorSignature)
print("Unknown 5: %s" % Unknown5)
print("Unknown 5: %s" % unknown5)
print("Unknown 6: %0.8X" % self.Unknown6)
print("Unknown 7: %0.8X" % self.Unknown7)
print("Unknown 8: %s" % Unknown8)
print("Unknown 9: %s [...]" % Unknown9[:8])
print("Unknown 8: %s" % unknown8)
print("Unknown 9: %s [...]" % unknown9[:8])
print("RSA Public Key: %s [...]" % RSAPublicKey[:8])
print("RSA Exponent: %0.8X" % self.RSAExponent)

Expand All @@ -175,8 +176,8 @@ class Intel_MC_Header_Extended(ctypes.LittleEndianStructure) :
("Reserved2", uint32_t), # 0C
("Reserved3", uint32_t), # 10
# 14
]
]

def mc_print_extended(self) :

if self.Reserved1 == self.Reserved2 == self.Reserved3 == 0 :
Expand All @@ -197,8 +198,8 @@ class Intel_MC_Header_Extended_Field(ctypes.LittleEndianStructure) :
("ProcessorFlags", uint32_t), # 04
("Checksum", uint16_t), # 08
# 0C
]
]

def mc_print_extended_field(self) :

print("")
Expand All @@ -225,8 +226,8 @@ class AMD_MC_Header(ctypes.LittleEndianStructure) :
("Reserved", uint8_t * 3), # 1D 000000 or AAAAAA (Pattern)
("MatchReg", uint32_t * 8), # 20 Not always present
# 40
]
]

def mc_print(self) :

full_date = "%0.2X/%0.2X/%0.4X" % (self.Date >> 16 & 0xFF, self.Date >> 24, self.Date & 0xFFFF)
Expand Down Expand Up @@ -270,14 +271,14 @@ class VIA_MC_Header(ctypes.LittleEndianStructure) :
("Name", char*8), # 24
("Unknown", uint32_t), # 2C
# 30
]
]

def mc_print(self) :

full_date = "%0.2d/%0.2d/%0.4d" % (self.Day, self.Month, self.Year)

print("-----------------VIA Header-----------------\n")
print("Signature: %s" % (self.Signature).decode('utf-8'))
print("Signature: %s" % self.Signature.decode('utf-8'))
print("Update Revision: %0.8X" % self.UpdateRevision)
print("Date (d/m/y): %s" % full_date)
print("Processor Signature: %0.8X" % self.ProcessorSignature)
Expand All @@ -286,7 +287,7 @@ def mc_print(self) :
print("Reserved: %0.8X" % self.Reserved)
print("Data Size: 0x%0.2X" % self.DataSize)
print("Total Size: 0x%0.2X" % self.TotalSize)
print("Name: %s" % (self.Name).decode('utf-8'))
print("Name: %s" % self.Name.decode('utf-8'))
print("Unknown: %0.8X" % self.Unknown)

def mce_help() :
Expand All @@ -307,7 +308,7 @@ def mce_help() :
mce_exit(0)

def mce_exit(code) :
if not param.mce_extr : wait_user = input("\nPress enter to exit")
if not param.mce_extr : input("\nPress enter to exit")
colorama.deinit() # Stop Colorama
sys.exit(code)

Expand All @@ -330,7 +331,7 @@ def get_script_dir(follow_symlinks=True) :
path = inspect.getabsfile(get_script_dir)
if follow_symlinks :
path = os.path.realpath(path)

return os.path.dirname(path)

# https://stackoverflow.com/a/781074
Expand All @@ -340,7 +341,7 @@ def show_exception_and_exit(exc_type, exc_value, tb) :
sys.exit(-1)

def adler32(data) :
return zlib.adler32(data) & 0xFFFFFFFF
return zlib.adler32(data) & 0xFFFFFFFF

def checksum32(data) :

Expand Down Expand Up @@ -449,27 +450,27 @@ def init_file(in_file,orig_file,temp) :
mc_file_name = ''

if not os.path.isfile(in_file) :
if any(p in in_file for p in param.all) : return ('continue','continue')
if any(p in in_file for p in param.all) : return 'continue', 'continue'

print(col_red + "\nError" + col_end + ", file %s was not found!\n" % ascii(in_file))
print(col_red + "\nError" + col_end + ", file %s was not found!\n" % force_ascii(in_file))

if not param.mass_scan : mce_exit(1)
else : return ('continue','continue')
else : return 'continue', 'continue'

with open(in_file, 'rb') as work_file : reading = work_file.read()

if not temp :
if not param.mce_extr : print("\nFile: %s\n" % ascii(os.path.basename(in_file)))
if not param.mce_extr : print("\nFile: %s\n" % force_ascii(os.path.basename(in_file)))
if param.print_file : mc_file_name = '__%s' % os.path.basename(in_file)
else :
if param.print_file : mc_file_name = '__%s' % os.path.basename(orig_file)

return (reading,mc_file_name)
return reading, mc_file_name

# Force string to be printed as ASCII, ignore errors
def ascii(string) :
def force_ascii(string) :
# Input string is bare and only for printing (no open(), no Colorama etc)
ascii_str = (str((string).encode('ascii', 'ignore'))).strip("b'")
ascii_str = (str(string.encode('ascii', 'ignore'))).strip("b'")
return ascii_str

def mass_scan(f_path) :
Expand Down Expand Up @@ -506,7 +507,7 @@ def mass_scan(f_path) :

if arg_num == 2 :
print("Press Enter to skip or input -? to list options\n")
print("\nFile: " + col_green + "%s" % ascii(os.path.basename(sys.argv[1])) + col_end)
print("\nFile: " + col_green + "%s" % force_ascii(os.path.basename(sys.argv[1])) + col_end)
elif arg_num > 2 :
print("Press Enter to skip or input -? to list options\n")
print("\nFiles: " + col_yellow + "Multiple" + col_end)
Expand All @@ -526,7 +527,7 @@ def mass_scan(f_path) :
if input_var[0] != "" :
for i in input_var:
if i not in param.all :
(sys.argv).append(i.strip('"'))
sys.argv.append(i.strip('"'))

# Re-enumerate parameter input
arg_num = len(sys.argv)
Expand Down Expand Up @@ -602,7 +603,7 @@ def mass_scan(f_path) :
wlp = int.from_bytes(binascii.unhexlify(wlp), 'little')
mc_conv_data += bytes.fromhex('%0.8X' % wlp)

if type_conv == '' : raise
if type_conv == '' : raise Exception('')

temp_file.write(mc_conv_data)

Expand All @@ -629,6 +630,7 @@ def mass_scan(f_path) :

for match_ucode in match_list_i :

# noinspection PyRedeclaration
(mc_bgn, end_mc_match) = match_ucode.span()

mc_hdr = get_struct(reading, mc_bgn, Intel_MC_Header)
Expand Down Expand Up @@ -659,21 +661,21 @@ def mass_scan(f_path) :
# Remove false results, based on date
try :
date_chk = datetime.datetime.strptime(full_date, '%d-%m-%Y')
if date_chk.year > 2016 or date_chk.year < 1993 : raise DateErr('WrongDate') # 1st MC from 1995 (P6), 1993 for safety
if date_chk.year > 2016 or date_chk.year < 1993 : raise Exception('WrongDate') # 1st MC from 1995 (P6), 1993 for safety
except :
if full_date == '07-00-1896' and patch == '000000D1' : pass # Drunk employee #1, Happy 0th month from 19th century Intel!
else :
print(col_magenta + "\nWarning: Skipped microcode at 0x%0.2X, invalid Date of %s!\n" % (mc_bgn, full_date) + col_end)
print(col_magenta + "\nWarning: Skipped Intel microcode at 0x%0.2X, invalid Date of %s!\n" % (mc_bgn, full_date) + col_end)
continue

# Remove false results, based on Reserved field
if res_field != 0 :
print(col_magenta + "\nWarning: Skipped microcode at 0x%0.2X, Reserved field not empty!\n" % (mc_bgn) + col_end)
print(col_magenta + "\nWarning: Skipped Intel microcode at 0x%0.2X, Reserved field not empty!\n" % mc_bgn + col_end)
continue

# Remove false results, based on data
if reading[mc_bgn + 0x90:mc_bgn + 0x94] == b'\x00' * 4 : # 0x90 is either encrypted data (old MC) or RSA PKEY (Extra Header)
print(col_magenta + "\nWarning: Skipped microcode at 0x%0.2X, null data at 0x90!\n" % (mc_bgn) + col_end)
print(col_magenta + "\nWarning: Skipped Intel microcode at 0x%0.2X, null data at 0x90!\n" % mc_bgn + col_end)
continue

# Print the Header(s)
Expand All @@ -689,9 +691,9 @@ def mass_scan(f_path) :
mc_hdr_extended = get_struct(reading, mc_extended_off, Intel_MC_Header_Extended)
mc_hdr_extended.mc_print_extended()

mc_extended_field_off = mc_ext_off + 0x14
mc_extended_field_off = mc_extended_off + 0x14

for idx in range(mc_hdr_ext.ExtendedSignatureCount) :
for idx in range(Intel_MC_Header_Extended.ExtendedSignatureCount) :

mc_hdr_extended_field = get_struct(reading, mc_extended_field_off, Intel_MC_Header_Extended_Field)
mc_hdr_extended_field.mc_print_extended_field()
Expand Down Expand Up @@ -759,6 +761,7 @@ def mass_scan(f_path) :

for match_ucode in match_list_a :

# noinspection PyRedeclaration
(mc_bgn, end_mc_match) = match_ucode.span()

if reading[mc_bgn:mc_bgn + 6] == b'$UCODE' : mc_bgn += 8
Expand Down Expand Up @@ -795,23 +798,23 @@ def mass_scan(f_path) :
# Remove false results, based on Date
if full_date == '09-13-2011' and patch == '03000027' : pass # Drunk employee #2, Happy 13th month from AMD!
elif month == '13' or year > '2016' :
print(col_magenta + "\nWarning: Skipped microcode at 0x%0.2X, invalid Date of %s!\n" % (mc_bgn, full_date) + col_end)
print(col_magenta + "\nWarning: Skipped AMD microcode at 0x%0.2X, invalid Date of %s!\n" % (mc_bgn, full_date) + col_end)
continue

# Remove false results, based on VEN_IDs
if (nb_id != '0'*8 and '1002' not in nb_id[4:8] and '1022' not in nb_id[4:8]) \
or (sb_id != '0'*8 and '1002' not in sb_id[4:8] and '1022' not in sb_id[4:8]) :
print(col_magenta + "\nWarning: Skipped microcode at 0x%0.2X, invalid VEN_IDs of %s,%s!\n" % (mc_bgn, nb_id[4:8], sb_id[4:8]) + col_end)
print(col_magenta + "\nWarning: Skipped AMD microcode at 0x%0.2X, invalid VEN_IDs of %s,%s!\n" % (mc_bgn, nb_id[4:8], sb_id[4:8]) + col_end)
continue

# Remove false results, based on Data Length
if data_len not in ['10','20','00'] :
print(col_magenta + "\nWarning: Skipped microcode at 0x%0.2X, Data Length not standard!\n" % (mc_bgn) + col_end)
print(col_magenta + "\nWarning: Skipped AMD microcode at 0x%0.2X, Data Length not standard!\n" % mc_bgn + col_end)
continue

# Remove false results, based on data
if reading[mc_bgn + 0x40:mc_bgn + 0x44] == b'\x00' * 4 : # 0x40 has non-null data
print(col_magenta + "\nWarning: Skipped microcode at 0x%0.2X, null data at 0x40!\n" % (mc_bgn) + col_end)
print(col_magenta + "\nWarning: Skipped AMD microcode at 0x%0.2X, null data at 0x40!\n" % mc_bgn + col_end)
continue

# Print the Header
Expand Down Expand Up @@ -924,6 +927,7 @@ def mass_scan(f_path) :

for match_ucode in match_list_v :

# noinspection PyRedeclaration
(mc_bgn, end_mc_match) = match_ucode.span()

mc_hdr = get_struct(reading, mc_bgn, VIA_MC_Header)
Expand Down Expand Up @@ -951,10 +955,10 @@ def mass_scan(f_path) :
# Remove false results, based on date
try :
date_chk = datetime.datetime.strptime(full_date, '%d-%m-%Y')
if date_chk.year > 2016 or date_chk.year < 2006 : raise DateErr('WrongDate') # 1st MC from 2008 (Nano), 2006 for safety
if date_chk.year > 2016 or date_chk.year < 2006 : raise Exception('WrongDate') # 1st MC from 2008 (Nano), 2006 for safety
except :
# VIA is sober? No drunk employee #3 ???
print(col_magenta + "\nWarning: Skipped microcode at 0x%0.2X, invalid Date of %s!\n" % (mc_bgn, full_date) + col_end)
print(col_magenta + "\nWarning: Skipped VIA microcode at 0x%0.2X, invalid Date of %s!\n" % (mc_bgn, full_date) + col_end)
continue

# Print the Header(s)
Expand Down

0 comments on commit f1df349

Please sign in to comment.