#!/usr/bin/python # Copyright (C) 2016 Nicola Corna # # me_cleaner 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. # # me_cleaner 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. # # You should have received a copy of the GNU General Public License # along with me_cleaner. If not, see . # import sys import itertools from struct import pack, unpack unremovable_huff_modules = ("BUP", "ROMP") def get_chunks_offsets(llut, me_start): chunk_count = unpack("> 4) & 7 if comp_type == 0x01: name = mod_header[0x04:0x14].rstrip(b"\x00").decode("ascii") if name in unremovable_huff_modules: module_base = unpack(" removable_chunk[0]: fill_range(f, removable_chunk[0], removable_chunk[1], b"\xff") def module_removal_report(f, mod_headers, ftpr_offset, lzma_start, lzma_end, lzma_removed, huffman_removed): for mod_header in mod_headers: name = mod_header[0x04:0x14].rstrip(b"\x00").decode("ascii") flags = unpack("> 4) & 7 sys.stdout.write(" {:<16} ".format(name)) if comp_type == 0x00 or comp_type == 0x02: start = unpack("= lzma_start and start + size <= lzma_end: if lzma_removed: print("removed") else: print("NOT removed") else: print("outside the LZMA region ({:#x} - {:#x}), skipping" .format(lzma_start, lzma_end)) elif comp_type == 0x01: sys.stdout.write("(Huffman, fragmented data ): ") if name in unremovable_huff_modules: print("NOT removed, essential") else: if huffman_removed: print("removed") else: print("NOT removed") else: print("unknown compression, skipping") if len(sys.argv) != 2 or sys.argv[1] == "-h" or sys.argv[1] == "--help": print("Usage: \n" " me_cleaner.py me_image.bin\n" "or\n" " me_cleaner.py full_dump.bin") else: with open(sys.argv[1], "r+b") as f: f.seek(0x10, 0) magic = f.read(4) me_start = 0 me_end = 0 if magic == b"$FPT": print("ME image detected") me_start = 0 f.seek(0, 2) me_end = f.tell() elif magic == b"\x5a\xa5\xf0\x0f": print("Full image detected") f.seek(0x14, 0) flmap0 = unpack("> 24 & 0x7 frba = flmap0 >> 12 & 0xff0 if nr >= 2: f.seek(frba + 0x8, 0) flreg2 = unpack("> 4 & 0x1fff000 | 0xfff if me_start >= me_end: sys.exit("The ME region in this image has been disabled") f.seek(me_start + 0x10) if f.read(4) != b"$FPT": sys.exit("The ME region is corrupted or missing") print("The ME region goes from {:#x} to {:#x}" .format(me_start, me_end)) else: sys.exit("This image does not contains a ME 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("