#!/usr/bin/python # me_cleaner - Tool for partial deblobbing of Intel ME/TXE firmware images # Copyright (C) 2016, 2017 Nicola Corna # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # import sys import itertools import binascii import hashlib from struct import pack, unpack unremovable_modules = ("BUP", "ROMP") def get_chunks_offsets(llut, me_start): chunk_count = unpack("> 4) & 7 sys.stdout.write(" {:<16} ({:<7}, ".format(name, comp_str[comp_type])) if comp_type == 0x00 or comp_type == 0x02: sys.stdout.write("0x{:06x} - 0x{:06x}): " .format(offset, offset + size)) if name in unremovable_modules: print("NOT removed, essential") else: fill_range(f, offset, offset + size, b"\xff") print("removed") elif comp_type == 0x01: sys.stdout.write("fragmented data ): ") if not chunks_offsets: f.seek(offset) llut = f.read(4) if llut == b"LLUT": llut += f.read(0x3c) chunk_count = unpack(" removable_chunk[0]: fill_range(f, removable_chunk[0], removable_chunk[1], b"\xff") def check_partition_signature(f, offset): f.seek(offset) header = f.read(0x80) modulus = int(binascii.hexlify(f.read(0x100)[::-1]), 16) public_exponent = int(binascii.hexlify(f.read(0x4)[::-1]), 16) signature = int(binascii.hexlify(f.read(0x100)[::-1]), 16) header_len = unpack("> 24 & 0x7 frba = flmap0 >> 12 & 0xff0 if nr >= 2: f.seek(frba + 0x8) flreg2 = unpack("> 4 & 0x1fff000 | 0xfff if me_start >= me_end: sys.exit("The ME/TXE region in this image has been " "disabled") f.seek(me_start + 0x10) if f.read(4) != b"$FPT": sys.exit("The ME/TXE region is corrupted or missing") print("The ME/TXE region goes from {:#x} to {:#x}" .format(me_start, me_end)) else: sys.exit("This image does not contains a ME/TXE firmware " "(NR = {})".format(nr)) else: sys.exit("Unknown image") print("Found FPT header at {:#x}".format(me_start + 0x10)) f.seek(me_start + 0x14) entries = unpack("