Our targets (on iPod 6G on 10.3.3):
From v0rtex.m lines 41~53
#define OFFSET_ZONE_MAP 0xfffffff007558478 /* "zone_init: kmem_suballoc failed" */
#define OFFSET_KERNEL_MAP 0xfffffff0075b4050
#define OFFSET_KERNEL_TASK 0xfffffff0075b4048
#define OFFSET_REALHOST 0xfffffff00753aba0 /* host_priv_self */
#define OFFSET_BZERO 0xfffffff00708df80
#define OFFSET_BCOPY 0xfffffff00708ddc0
#define OFFSET_COPYIN 0xfffffff00718d028
#define OFFSET_COPYOUT 0xfffffff00718d21c
#define OFFSET_IPC_PORT_ALLOC_SPECIAL 0xfffffff0070a60b4 /* convert_task_suspension_token_to_port */
#define OFFSET_IPC_KOBJECT_SET 0xfffffff0070b938c /* convert_task_suspension_token_to_port */
#define OFFSET_IPC_PORT_MAKE_SEND 0xfffffff0070a5bd8 /* "ipc_host_init" */
#define OFFSET_IOSURFACEROOTUSERCLIENT_VTAB 0xfffffff006ef2d78
#define OFFSET_ROP_ADD_X0_X0_0x10 0xfffffff00651a174
Use this script or follow the instructions below.
Get an ipsw of your target device and iOS version. Unzip it and copy the kernelcache.release.xxx
file to your working copy. Delete ipsw and unzipped folder if you want).
Alternatively, use partialzip
to speed things up
partialzip ipsw_url kernel_name output_name
To decompress the kernel cache, get joker run
joker -dec kernelcache.release.xxx
Will create a decompressed file at /tmp/kernel
. Move it to your working directory as kernelcache.release.xxx.dec
.
If that coesn't work, follow these instead:
- Compile lzssdec.cpp from here: http://nah6.com/~itsme/cvs-xdadevtools/iphone/tools/lzssdec.cpp
- Open the kernel cache file with a Hex editor and find the magical 0xFEEDFACE. Note the offset.
- Run:
./lzssdec -o OFFSET_YOUVE_NOTED_IN_STEP_2 < kernelcache.release.***** > kernelcache.decrypted
To extract the kext from the kernel cache:
joker -K com.apple.iokit.IOSurface kernelcache.release.xxx.dec
kext is now at /tmp/com.apple.iokit.IOSurface.kext
. Copy it to your working directory.
Finding OFFSET_BZERO
, OFFSET_BCOPY
, OFFSET_COPYIN
, OFFSET_COPYOUT
, OFFSET_KERNEL_MAP
, OFFSET_KERNEL_TASK
nm kernelcache.release.xxx.dec | grep -E " ___bzero$| _bcopy$| _copyin$| _copyout$| _kernel_map$| _kernel_task$"
Finding OFFSET_ZONE_MAP
(credit cryptic)
- Drop
kernelcache.release.xxx.dec
in Hopper - Go to the string tab and search for
zone_init: kmem_suballoc failed
- Click the result that came up. Double click on the
DATA XREF=sub_fffffff
- Double click on the DATA XREF to the very far right of the location you landed on
- The offset will be the first qword above the location you jumped to
Finding OFFSET_REALHOST
(credit cryptic)
- Drop
kernelcache.release.xxx.dec
in Hopper - Search for host_priv_self under the Labels tab
- Select the result.
- The offset is the right of the add x0, x0 line
Finding OFFSET_IPC_PORT_ALLOC_SPECIAL
, OFFSET_IPC_KOBJECT_SET
and OFFSET_IPC_PORT_MAKE_SEND
(credit siguza)
- Drop
kernelcache.release.xxx.dec
in Hopper - Search for the string "ipc_host_init", it should be referenced from one location like so:
0xfffffff0070d5198 008dab50 adr x0, str._ipc_host_init_
0xfffffff0070d519c 1f2003d5 nop
0xfffffff0070d51a0 0c86ff97 bl sym._panic
- Find a reference to that address (i.e.
0xfffffff0070d5198
), of which there should be three. Doesn't matter which one you pick, around it there should be three function calls like so:
0xfffffff0070d38f8 ef49ff97 bl sym.func.fffffff0070a60b4
0xfffffff0070d38fc f40300aa mov x20, x0
;-- hit2_0:
0xfffffff0070d3900 d4c400b4 cbz x20, 0xfffffff0070d5198
0xfffffff0070d3904 22028052 movz w2, 0x11
0xfffffff0070d3908 e00314aa mov x0, x20
0xfffffff0070d390c e10315aa mov x1, x21
0xfffffff0070d3910 9f96ff97 bl sym.func.fffffff0070b938c
0xfffffff0070d3914 e00314aa mov x0, x20
0xfffffff0070d3918 b048ff97 bl sym.func.fffffff0070a5bd8
- Those are
OFFSET_IPC_PORT_ALLOC_SPECIAL
,OFFSET_IPC_KOBJECT_SET
andOFFSET_IPC_PORT_MAKE_SEND
(0xfffffff0070a60b4
,oxfffffff0070b938c
,0xfffffff0070a5bd8
).
OFFSET_IPC_PORT_MAKE_SEND video
Finding OFFSET_IOSURFACEROOTUSERCLIENT_VTAB
(credit sticktron)
(See this gist for explanation/context)
- Run
r2 com.apple.iokit.IOSurface.kext
in terminal - Type
S
to list the sections - Copy the address to the
__DATA_CONST.__const
section (example0xfffffff006e7b818
) - Type
s 0xfffffff006e7b818
to seek to that address - The length is the value of sz=0x2330. type
pxq 0x2330
- The first red address is the start of the vtable. The offset we are looking for is circled in green. the 8th pointer is used to check the validity
- Check for validity like so
Instructions to check validity:
- Take 8th pointer (must be red!) (example
0xfffffff0064960d4
- Type
s 0xfffffff0064960d4
to seek to that address - Type
pd 3
to show 3 instructions at that address - Take note of the address on the
adrp
instruction and the offset at theadd
instruction (example0xfffffff00760d000
and0x218
) - Type
"/c pointer; offset"
to search other instances of the same pair of similar instructions (example"/c 0xfffffff00760d000; 0x218"
) - From the resulting list, try using the second to last result (example
0xfffffff00649ae20
) - Type
pd 10 @ 0xfffffff00649ae20
to show 10 instructions at that address - Take note of the address on the first
adrp
instruction and the offset at the followingadd
instruction (example0xfffffff0073000
and0x202
) - Type
ps @0xfffffff0073000 + 0x202
- If you get
IOSurfaceRootUserClient
you found a validOFFSET_IOSURFACEROOTUSERCLIENT_VTAB
(0xfffffff006e7b9c8
)!
Finding OFFSET_ROP_ADD_X0_X0_10
(credit cryptic)
- Run
r2 kernelcache.release.xxx.dec
in terminal - Type
"/c add x0, x0, 0x10; ret"
to search for the ROP gadget. You should get an output like this: - Take note of the second address (example it's
0xfffffff00651a178
) - Seek to an address 4 bytes before. We do that by subtracting
0x4
to it. Types 0xfffffff00651a178 - 0x4
(which is also0xfffffff00651a174
) - Type
pd 2
to show 2 instructions at that address - If your output looks similar to this, you found a valid
OFFSET_ROP_ADD_X0_X0_10
(0xfffffff00651a174
)!
You found everything! Yay!
Now go an try putting it into practice. Clone https://github.com/Sticktron/v0rtex-S and replace the offsets for your target device!
For my iPad Air WiFi (iPad4,1) iOS 10.3.2, there are two kernelcache.release.xxx files. which file should I use?