def do_ioctl_init(arch_name): ''' One-time init for arch-specific bit-packed ioctl cmd struct. ''' # Default config (x86, x86-64, ARM, AArch 64) with options for PPC global ioctl_initialized if ioctl_initialized: return ioctl_initialized = True TYPE_BITS = 8 CMD_BITS = 8 SIZE_BITS = 14 if arch_name != "ppc" else 13 DIR_BITS = 2 if arch_name != "ppc" else 3 ffi.cdef(""" struct IoctlCmdBits { uint8_t type_num:%d; uint8_t cmd_num:%d; uint16_t arg_size:%d; uint8_t direction:%d; }; union IoctlCmdUnion { struct IoctlCmdBits bits; uint32_t asUnsigned32; }; enum ioctl_direction { IO = 0, IOW = 1, IOR = 2, IOWR = 3 }; """ % (TYPE_BITS, CMD_BITS, SIZE_BITS, DIR_BITS), packed=True)
arch = "x86_64" if len(argv) <= 1 else argv[1] extra = "-nographic" #qcow = "/home/luke/workspace/qcows/instance-1.qcow2" #panda = Panda(arch=arch, qcow=qcow, extra_args=extra, mem="1G") panda = Panda(generic=arch) interesting_file_name = b"panda.panda2" panda.set_os_name("linux-64-ubuntu") panda.load_plugin("callstack_instr", args={"stack_type": "asid"}) panda.require("syscalls2") cb_name = "on_sys_read_return" cb_args = "CPUState *, target_ulong, uint32_t, uint64_t, uint32_t" ffi.cdef(f"void ppp_add_cb_{cb_name}(void (*)({cb_args}));") file_info = None @ffi.callback(f"void({cb_args})") def on_sys_read_return(cpustate, pc, fd, buf, count): global file_info if file_info: cr3, fd1 = file_info if cr3 == cpustate.env_ptr.cr[3] and fd == fd1: returned = panda.arch.get_reg(cpustate, "RAX") if returned >= 0: a_buf = (10 * b"a") + b"\x00" panda.virtual_memory_write(cpustate, buf, a_buf) file_info = None