(f, mod_headers, ftpr_offset, me_end)
| 136 | |
| 137 | |
| 138 | def remove_modules(f, mod_headers, ftpr_offset, me_end): |
| 139 | comp_str = ("uncomp.", "Huffman", "LZMA") |
| 140 | unremovable_huff_chunks = [] |
| 141 | chunks_offsets = [] |
| 142 | base = 0 |
| 143 | chunk_size = 0 |
| 144 | end_addr = 0 |
| 145 | |
| 146 | for mod_header in mod_headers: |
| 147 | name = mod_header[0x04:0x14].rstrip(b"\x00").decode("ascii") |
| 148 | offset = unpack("<I", mod_header[0x38:0x3C])[0] + ftpr_offset |
| 149 | size = unpack("<I", mod_header[0x40:0x44])[0] |
| 150 | flags = unpack("<I", mod_header[0x50:0x54])[0] |
| 151 | comp_type = (flags >> 4) & 7 |
| 152 | |
| 153 | print(" {:<16} ({:<7}, ".format(name, comp_str[comp_type]), end="") |
| 154 | |
| 155 | if comp_type == 0x00 or comp_type == 0x02: |
| 156 | print("0x{:06x} - 0x{:06x} ): " |
| 157 | .format(offset, offset + size), end="") |
| 158 | |
| 159 | if name in unremovable_modules: |
| 160 | end_addr = max(end_addr, offset + size) |
| 161 | print("NOT removed, essential") |
| 162 | else: |
| 163 | end = min(offset + size, me_end) |
| 164 | f.fill_range(offset, end, b"\xff") |
| 165 | print("removed") |
| 166 | |
| 167 | elif comp_type == 0x01: |
| 168 | if not chunks_offsets: |
| 169 | f.seek(offset) |
| 170 | llut = f.read(4) |
| 171 | if llut == b"LLUT": |
| 172 | llut += f.read(0x3c) |
| 173 | |
| 174 | chunk_count = unpack("<I", llut[0x4:0x8])[0] |
| 175 | base = unpack("<I", llut[0x8:0xc])[0] + 0x10000000 |
| 176 | chunk_size = unpack("<I", llut[0x30:0x34])[0] |
| 177 | |
| 178 | llut += f.read(chunk_count * 4) |
| 179 | chunks_offsets = get_chunks_offsets(llut) |
| 180 | else: |
| 181 | sys.exit("Huffman modules found, but LLUT is not present") |
| 182 | |
| 183 | module_base = unpack("<I", mod_header[0x34:0x38])[0] |
| 184 | module_size = unpack("<I", mod_header[0x3c:0x40])[0] |
| 185 | first_chunk_num = (module_base - base) // chunk_size |
| 186 | last_chunk_num = first_chunk_num + module_size // chunk_size |
| 187 | huff_size = 0 |
| 188 | |
| 189 | for chunk in chunks_offsets[first_chunk_num:last_chunk_num + 1]: |
| 190 | huff_size += chunk[1] - chunk[0] |
| 191 | |
| 192 | print("fragmented data, {:<9}): " |
| 193 | .format("~" + str(int(round(huff_size / 1024))) + " KiB"), |
| 194 | end="") |
| 195 |
no test coverage detected