def sys_x86_64_arch_prctl(jitter, linux_env): # Parse arguments code_name = { 0x1001: "ARCH_SET_GS", 0x1002: "ARCH_SET_FS", 0x1003: "ARCH_GET_FS", 0x1004: "ARCH_GET_GS", 0x1011: "ARCH_GET_CPUID", 0x1012: "ARCH_SET_CPUID", 0x2001: "ARCH_MAP_VDSO_X32", 0x2002: "ARCH_MAP_VDSO_32", 0x2003: "ARCH_MAP_VDSO_64", 0x3001: "ARCH_CET_STATUS", 0x3002: "ARCH_CET_DISABLE", 0x3003: "ARCH_CET_LOCK", 0x3004: "ARCH_CET_EXEC", 0x3005: "ARCH_CET_ALLOC_SHSTK", 0x3006: "ARCH_CET_PUSH_SHSTK", 0x3007: "ARCH_CET_LEGACY_BITMAP", } code = jitter.cpu.RDI rcode = code_name[code] addr = jitter.cpu.RSI log.debug("sys_arch_prctl(%s, %x)", rcode, addr) if code == 0x1002: jitter.cpu.set_segm_base(jitter.cpu.FS, addr) elif code == 0x3001: # CET status (disabled) jitter.cpu.set_mem(addr, pck64(0)) else: raise RuntimeError("Not implemented") jitter.cpu.RAX = 0
def sys_x86_64_arch_prctl(jitter, linux_env): # Parse arguments code_name = { 0x1001: "ARCH_SET_GS", 0x1002: "ARCH_SET_FS", 0x1003: "ARCH_GET_FS", 0x1004: "ARCH_GET_GS", 0x1011: "ARCH_GET_CPUID", 0x1012: "ARCH_SET_CPUID", 0x2001: "ARCH_MAP_VDSO_X32", 0x2002: "ARCH_MAP_VDSO_32", 0x2003: "ARCH_MAP_VDSO_64", 0x3001: "ARCH_CET_STATUS", 0x3002: "ARCH_CET_DISABLE", 0x3003: "ARCH_CET_LOCK", 0x3004: "ARCH_CET_EXEC", 0x3005: "ARCH_CET_ALLOC_SHSTK", 0x3006: "ARCH_CET_PUSH_SHSTK", 0x3007: "ARCH_CET_LEGACY_BITMAP", } code = jitter.cpu.RDI rcode = code_name[code] addr = jitter.cpu.RSI log.debug("sys_arch_prctl(%s, %x)", rcode, addr) if code == 0x1002: jitter.cpu.set_segm_base(jitter.cpu.FS, addr) elif code == 0x3001: # CET status (disabled) jitter.vm.set_mem(addr, pck64(0)) else: raise RuntimeError("Not implemented") jitter.cpu.RAX = 0
def main(): global dse, todo, current sys.setrecursionlimit(2000) # oof # Parse arguments parser = Sandbox_Win_x86_64.parser(description="PE sandboxer") parser.add_argument("filename", help="PE Filename") options = parser.parse_args() options.dependencies = True # So we dont need to reimplement qt sb = Sandbox_Win_x86_64(LocationDB(), options.filename, options, custom_methods=qt_methods) sb.jitter.add_breakpoint(end_ptr, stop_exec) # End condition # Setup the qt string memory and a pointer to it sb.jitter.vm.add_memory_page(0x10000018, PAGE_READ | PAGE_WRITE, pck64(0x20000000)) # Hooking in here sb.jitter.vm.add_memory_page(0x20000000, PAGE_READ | PAGE_WRITE, qtstring) # The initial qstring sb.jitter.vm.add_memory_page(0x10000020, PAGE_READ | PAGE_WRITE, b'\x00') # The result sb.jitter.cpu.R15 = 0x10000000 sb.jitter.cpu.RSP = sb.jitter.stack_base + 0x8000 # Setup and attach the DSE dse = DSEPC(sb.machine, sb.loc_db, produce_solution=DSEPC.PRODUCE_SOLUTION_PATH_COV) sb.jitter.init_run(0x140004B61) dse.attach(sb.jitter) dse.update_state_from_concrete() dse.symbolize_memory(interval([(flag_ptr, flag_ptr + 0x20)])) # Printable unicode only for address in range(flag_ptr, flag_ptr + 0x20, 0x2): z3_mem = dse.z3_trans.from_expr( dse.eval_expr(ExprMem(ExprInt(address, 64), 16))) unicode_constraint = z3.And( \ z3.UGE(z3_mem, dse.z3_trans.from_expr(ExprInt(0x0020, 16))), \ z3.ULE(z3_mem, dse.z3_trans.from_expr(ExprInt(0x007E, 16))) \ ) dse.cur_solver.add(unicode_constraint) snapshot = dse.take_snapshot() # Begin run todo = [b'\x41\x00' * 0x10] while todo: dse.restore_snapshot(snapshot) current = todo.pop() sb.jitter.vm.set_mem(flag_ptr, current) # Update the password in jitter memory print('-' * 40 + f' CONCRETE: {unicode_string(current)}') sb.jitter.continue_run()
def func_prepare_stdcall(self, ret_addr, *args): for index in range(min(len(args), 4)): setattr(self.cpu, 'X%d' % index, args[index]) for index in range(4, len(args)): self.vm.set_mem(self.cpu.SP + 8 * (index - 4), pck64(args[index])) self.cpu.LR = ret_addr
def push_uint64_t(self, value): self.cpu.SP -= 8 self.vm.set_mem(self.cpu.SP, pck64(value))