Sadly I don't have a dev device on iOS 10, but for anyone playing around with zIVA caring about the kernel task port:
Starting with iOS 10.3 (and macOS 10.12.4), Apple changed
convert_port_to_locked_task (and a few other port-to-something conversion functions) to blacklist the kernel task by means of a direct check. As a result, you can still obtain the kernel task port, but almost all APIs will simply treat it like
MACH_PORT_NULL, thus rendering it useless. The check is a simple pointer comparison though, so it can be circumvented by just remapping the task struct at an additional virtual address and creating a new port from that with a ROP equivalent of:
vm_map_remap( kernel_map, &remap_addr, sizeof(task_t), 0, VM_FLAGS_ANYWHERE | VM_FLAGS_RETURN_DATA_ADDR, zone_map, kernel_task, false, &dummy, &dummy, VM_INHERIT_NONE ); mach_vm_wire(&realhost, kernel_map, remap_addr, sizeof(task_t), VM_PROT_READ | VM_PROT_WRITE); realhost.special = ipc_port_make_send(ipc_port_alloc_special(ipc_space_kernel)); ipc_kobject_set(realhost.special, remap_addr, IKOT_TASK);
- I successfully tested this on macOS 10.12.4 and 10.12.5, so I'm not 100% sure it'll work unmodified on iOS, but it should in theory.
- I'm not sure if
mach_vm_wireis required or not, but I'm sure it works when it's there.
- I'm still not sure why
kernel_mapdoesn't work in
zone_map's place - it looks to me like
vm_map_remapshould work recursively, but I haven't had time to investigate this further.
That's all I can add for now, take it if it helps you or enlighten me if there is more to it on iOS. :)