Skip to content

Instantly share code, notes, and snippets.

@uroboro
Last active March 10, 2024 03:30
Show Gist options
  • Save uroboro/84309e91c1f92e873c943e94a00f3de1 to your computer and use it in GitHub Desktop.
Save uroboro/84309e91c1f92e873c943e94a00f3de1 to your computer and use it in GitHub Desktop.
v0rtex offset finder script
#!//bin/sh
export PATH=bin:$PATH
self=$0
function print_help() {
echo "$self [IPSW path]"
echo "$self [device model] [ios build]"
echo
echo "Examples:"
echo "\t $self iPodtouch_10.3.3_14G60_Restore.ipsw"
echo "\t $self iPod7,1 14G60"
}
function install_radare2() {
brew ls --versions radare2 > /dev/null
if [ ! $? -eq 0 ]; then
brew update &> /dev/null
brew install radare2 &> /dev/null
fi
}
function install_partialzip() {
if [[ ! -f bin/partialzip ]]; then
echo "[#] Cloning partial-zip repo..."
git clone https://github.com/uroboro/partial-zip &> /dev/null
pushd partial-zip &> /dev/null
echo "[#] Building..."
cmake . &> /dev/null
make &> /dev/null
popd &> /dev/null
mkdir -p bin
cp partial-zip/partialzip bin/
rm -rf partial-zip
echo "[#] Done!"
fi
}
function install_joker() {
if [[ ! -f bin/joker ]]; then
echo "[#] Downloading joker..."
curl -s http://newosxbook.com/tools/joker.tar -o /tmp/joker.tar
echo "[#] Extracting..."
tar -xf /tmp/joker.tar joker.universal
mkdir -p bin
mv joker.universal bin/joker
rm /tmp/joker.tar
echo "[#] Done!"
fi
}
function extract_from_ipsw() {
file="$1"
kernel_name=$(unzip -l $file | grep -m 1 kernelcache | awk '{ print $NF }')
unzip -p $file $kernel_name > kernelcache.comp
}
function extract_from_url() {
file="$1"
kernel_name=$(partialzip -l $file | grep -m 1 kernelcache | awk '{ print $NF }')
partialzip $file $kernel_name
cp $kernel_name kernelcache.comp
}
skip_decompression=0
if [ $# -eq 2 ]; then
if [[ "$1" == "-k" ]]; then
cp $2 kernelcache.comp
elif [[ "$1" == "-d" ]]; then
skip_decompression=1
cp $2 kernelcache
else
install_partialzip
file=$(curl -s https://api.ipsw.me/v2.1/$1/$2/url)
extract_from_url $file
fi
elif [ $# -eq 1 ]; then
file=$1
extract_from_ipsw $file
else
print_help
exit 0
fi
# Decompress kernelcache
if [ "$skip_decompression" -eq "0" ]; then
if [ ! -f kernelcache.comp ]; then
echo "[#] No kernel cache to work with. Bailing."
exit 1
fi
install_joker
joker -dec kernelcache.comp &> /dev/null
if [ ! -f /tmp/kernel ]; then
echo "[#] No compressed kernel cache to work with. Bailing."
exit 1
fi
mv /tmp/kernel ./kernelcache
else
echo "[#] Skipping decompression"
fi
# Extract IOSurface kext
install_joker
joker -K com.apple.iokit.IOSurface kernelcache &> /dev/null
if [ ! -f /tmp/com.apple.iokit.IOSurface.kext ]; then
echo "[#] No usable kernel cache to work with. Bailing."
exit 1
fi
mv /tmp/com.apple.iokit.IOSurface.kext ./
strings kernelcache | grep 'Darwin K'
echo
function address_kernel_map() {
nm kernelcache | grep ' _kernel_map$' | awk '{ print "0x" $1 }'
}
function address_kernel_task() {
nm kernelcache | grep ' _kernel_task$' | awk '{ print "0x" $1 }'
}
function address_bzero() {
nm kernelcache | grep ' ___bzero$' | awk '{ print "0x" $1 }'
}
function address_bcopy() {
nm kernelcache | grep ' _bcopy$' | awk '{ print "0x" $1 }'
}
function address_copyin() {
nm kernelcache | grep ' _copyin$' | awk '{ print "0x" $1 }'
}
function address_copyout() {
nm kernelcache | grep ' _copyout$' | awk '{ print "0x" $1 }'
}
function address_rootvnode() {
nm kernelcache | grep ' _rootvnode$' | awk '{ print "0x" $1 }'
}
function address_kauth_cred_ref() {
nm kernelcache | grep ' _kauth_cred_ref$' | awk '{ print "0x" $1 }'
}
function address_osserializer_serialize() {
nm kernelcache | grep ' __ZNK12OSSerializer9serializeEP11OSSerialize$' | awk '{ print "0x" $1 }'
}
function address_host_priv_self() {
host_priv_self_addr=$(nm kernelcache | grep host_priv_self | awk '{ print "0x" $1 }')
r2 -q -e scr.color=false -c "pd 2 @ $host_priv_self_addr" kernelcache 2> /dev/null | sed -n 's/0x//gp' | awk '{ print $NF }' | tr '[a-f]\n' '[A-F] ' | awk '{ print "obase=16;ibase=16;" $1 "+" $2 }' | bc | tr '[A-F]' '[a-f]' | awk '{ print "0x" $1 }'
}
function address_ipc_port_alloc_special() {
r2 -e scr.color=false -q -c 'pd @ sym._convert_task_suspension_token_to_port' kernelcache 2> /dev/null | sed -n 's/.*bl sym.func.\([a-z01-9]*\)/0x\1/p' | sed -n 1p
}
function address_ipc_kobject_set() {
r2 -e scr.color=false -q -c 'pd @ sym._convert_task_suspension_token_to_port' kernelcache 2> /dev/null | sed -n 's/.*bl sym.func.\([a-z01-9]*\)/0x\1/p' | sed -n 2p
}
function address_ipc_port_make_send() {
r2 -e scr.color=false -q -c 'pd @ sym._convert_task_to_port' kernelcache 2>/dev/null | sed -n 's/.*bl sym.func.\([a-z01-9]*\)/0x\1/p' | sed -n 1p
}
function address_rop_add_x0_x0_0x10() {
r2 -q -e scr.color=true -c "\"/a add x0, x0, 0x10; ret\"" kernelcache 2> /dev/null | head -n1 | awk '{ print $1 }'
}
function address_rop_ldr_x0_x0_0x10() {
r2 -q -e scr.color=true -c "\"/a ldr x0, [x0, 0x10]; ret\"" kernelcache 2> /dev/null | head -n1 | awk '{ print $1 }'
}
function address_zone_map() {
string_addr=$(r2 -q -e scr.color=false -c 'iz~zone_init: kmem_suballoc failed' kernelcache 2> /dev/null | awk '{ print $1 }' | sed 's/.*=//')
xref1_addr=$(r2 -q -e scr.color=false -c "\"/c $string_addr\"" kernelcache 2> /dev/null | awk '{ print $1 }')
xref2_addr=$(r2 -q -e scr.color=false -c "\"/c $xref1_addr\"" kernelcache 2> /dev/null | awk '{ print $1 }')
addr=$(r2 -q -e scr.color=false -c "pd -8 @ $xref2_addr" kernelcache 2> /dev/null | head -n 2 | grep 0x | awk '{ print $NF }' | sed 's/0x//' | tr '[a-f]\n' '[A-F] ' | awk '{ print "obase=16;ibase=16;" $1 "+" $2 }' | bc | tr '[A-F]' '[a-f]')
echo "0x$addr"
}
function address_chgproccnt() {
priv_check_cred_addr=$(nm kernelcache | grep ' _priv_check_cred$' | awk '{ print "0x" $1 }')
r2 -q -e scr.color=false -c "pd 31 @ $priv_check_cred_addr" kernelcache 2> /dev/null | tail -n1 | awk '{ print $1 }'
}
function address_iosurfacerootuserclient_vtab() {
# Get __DATA_CONST.__const offset and size
data_const_const=$(r2 -q -e scr.color=false -c 'S' com.apple.iokit.IOSurface.kext 2> /dev/null | grep '__DATA_CONST.__const' | tr ' ' '\n' | grep '=')
va=$(echo $data_const_const | tr ' ' '\n' | sed -n 's/va=//p')
sz=$(echo $data_const_const | tr ' ' '\n' | sed -n 's/^sz=//p')
# Dump hex to tmp file
r2 -q -e scr.color=false -c "s $va; pxr $sz" com.apple.iokit.IOSurface.kext 2> /dev/null | awk '{ print $1 " " $2 }' > /tmp/hexdump.txt
IFS=$'\n' read -d '' -r -a hd < /tmp/hexdump.txt
lines=$(wc -l /tmp/hexdump.txt | awk '{ print $1 }')
# Go through each line, check if there are 2 consecutive zeros
found=0
for (( i = 1; i < $lines; i++ )); do
# First zero
zero1=$(echo ${hd[$i]} | awk '{ print $2 }')
# Second zero
zero2=$(echo ${hd[$((i+1))]} | awk '{ print $2 }')
if [ "$zero1" == "0x0000000000000000" -a "$zero2" == "0x0000000000000000" ]; then
# vtable offset
offset=$(echo ${hd[$i+2]} | awk '{ print $1 }')
# echo "found possible offset at $offset"
# 8th pointer after vtable start
pointer8=$(echo ${hd[$((i+2+7))]} | awk '{ print $2 }')
if [ -z "$pointer8" ]; then
break
fi
# Retrieve class name
cmd_lookup=$(r2 -q -e scr.color=false -c "pd 3 @ $pointer8" com.apple.iokit.IOSurface.kext 2> /dev/null | awk '{ print $NF }' | tr '\n' ' ' | awk '{ print $1 "; " $2 }')
second_to_last=$(r2 -q -e scr.color=true -c "\"/c $cmd_lookup\"" com.apple.iokit.IOSurface.kext 2>/dev/null | tail -n 2 | head -n 1 | awk '{ print $1 }')
class_addr=$(r2 -q -e scr.color=false -c "pd 3 @ $second_to_last" com.apple.iokit.IOSurface.kext 2> /dev/null | tail -n 2 | awk '{ print $NF }' | tr '\n' ' ' | awk '{ print $1 "+" $2 }')
name=$(r2 -q -e scr.color=false -c "ps @ $class_addr" com.apple.iokit.IOSurface.kext 2> /dev/null | sed 's/[^a-zA-Z]//g')
if [[ ! -z "$name" && "$name" == "IOSurfaceRootUserClient" ]]; then
# Done!
found=1
echo "$offset"
return 0
fi
fi
done
echo "0xdeadbeefbabeface"
}
install_radare2
printf "[#] Working...\r"
offset_zone_map=$(address_zone_map)
offset_kernel_map=$(address_kernel_map)
offset_kernel_task=$(address_kernel_task)
offset_host_priv_self=$(address_host_priv_self)
offset_bzero=$(address_bzero)
offset_bcopy=$(address_bcopy)
offset_copyin=$(address_copyin)
offset_copyout=$(address_copyout)
offset_chgproccnt=$(address_chgproccnt)
offset_rootvnode=$(address_rootvnode)
offset_kauth_cred_ref=$(address_kauth_cred_ref)
offset_ipc_port_alloc_special=$(address_ipc_port_alloc_special)
offset_ipc_kobject_set=$(address_ipc_kobject_set)
offset_ipc_port_make_send=$(address_ipc_port_make_send)
offset_iosurfacerootuserclient_vtab=$(address_iosurfacerootuserclient_vtab)
offset_rop_add_x0_x0_0x10=$(address_rop_add_x0_x0_0x10)
offset_osserializer_serialize=$(address_osserializer_serialize)
offset_rop_ldr_x0_x0_0x10=$(address_rop_ldr_x0_x0_0x10)
echo "#define OFFSET_ZONE_MAP $offset_zone_map"
echo "#define OFFSET_KERNEL_MAP $offset_kernel_map"
echo "#define OFFSET_KERNEL_TASK $offset_kernel_task"
echo "#define OFFSET_REALHOST $offset_host_priv_self"
echo "#define OFFSET_BZERO $offset_bzero"
echo "#define OFFSET_BCOPY $offset_bcopy"
echo "#define OFFSET_COPYIN $offset_copyin"
echo "#define OFFSET_COPYOUT $offset_copyout"
echo "#define OFFSET_ROOTVNODE $offset_rootvnode"
echo "#define OFFSET_CHGPROCCNT $offset_chgproccnt"
echo "#define OFFSET_KAUTH_CRED_REF $offset_kauth_cred_ref"
echo "#define OFFSET_IPC_PORT_ALLOC_SPECIAL $offset_ipc_port_alloc_special"
echo "#define OFFSET_IPC_KOBJECT_SET $offset_ipc_kobject_set"
echo "#define OFFSET_IPC_PORT_MAKE_SEND $offset_ipc_port_make_send"
echo "#define OFFSET_IOSURFACEROOTUSERCLIENT_VTAB $offset_iosurfacerootuserclient_vtab"
echo "#define OFFSET_ROP_ADD_X0_X0_0x10 $offset_rop_add_x0_x0_0x10"
echo "#define OFFSET_OSSERIALIZER_SERIALIZE $offset_osserializer_serialize"
echo "#define OFFSET_ROP_LDR_X0_X0_0x10 $offset_rop_ldr_x0_x0_0x10"
# rm com.apple.iokit.IOSurface.kext kernelcache*
@kallism
Copy link

kallism commented Dec 26, 2017

Can someone please clearly explain how we can use this v0rtex offset finder script in order to find the required offsets ?

@masbog
Copy link

masbog commented Dec 26, 2017

iPad_64bit_TouchID_10.3.2_14F89_Restore.ipsw (iPad Air 2 WiFi) always got Invalid shift mask.

Darwin Kernel Version 16.6.0: Mon Apr 17 17:33:35 PDT 2017; root:xnu-3789.60.24~24/RELEASE_ARM64_S5L8960X

#define OFFSET_ZONE_MAP                        0xfffffff00754c478
#define OFFSET_KERNEL_MAP                      0xfffffff0075a8050
#define OFFSET_KERNEL_TASK                     0xfffffff0075a8048
#define OFFSET_REALHOST                        0xfffffff00752eba0
#define OFFSET_BZERO                           0xfffffff007081f80
#define OFFSET_BCOPY                           0xfffffff007081dc0
#define OFFSET_COPYIN                          0xfffffff0071811ec
#define OFFSET_COPYOUT                         0xfffffff0071813e0
#define OFFSET_ROOTVNODE                       0xfffffff0075a80b0
#define OFFSET_CHGPROCCNT                      0xfffffff00738e82c
#define OFFSET_KAUTH_CRED_REF                  0xfffffff007368be4
#define OFFSET_IPC_PORT_ALLOC_SPECIAL          0xfffffff007099f14
#define OFFSET_IPC_KOBJECT_SET                 0xfffffff0070ad1ec
#define OFFSET_IPC_PORT_MAKE_SEND              0xfffffff007099a38
#define OFFSET_IOSURFACEROOTUSERCLIENT_VTAB    0xfffffff006f2d738
#define OFFSET_ROP_ADD_X0_X0_0x10              0xfffffff0064be174
#define OFFSET_OSSERIALIZER_SERIALIZE          0xfffffff0074419b8
#define OFFSET_ROP_LDR_X0_X0_0x10              0xfffffff00640ca84

@wholivesinapineappleunderthesea
Copy link

@uroboro, you could also do something to make it easier to add offsets to v0rtex-S.

I did it in my Gist: (Line 278-295).

@calaba
Copy link

calaba commented Dec 27, 2017

iPhone 5S - iOS 10.3.1 - NOT WORKING:

./find_offsets.sh iPhone_4.0_64bit_10.3.1_14E304_Restore.ipsw
Darwin Kernel Version 16.5.0: Thu Feb 23 23:22:54 PST 2017; root:xnu-3789.52.2~7/RELEASE_ARM64_S5L8960X

#define OFFSET_ZONE_MAP 0x
#define OFFSET_KERNEL_MAP 0xfffffff0075a8050
#define OFFSET_KERNEL_TASK 0xfffffff0075a8048
#define OFFSET_REALHOST
#define OFFSET_BZERO 0xfffffff007081f80
#define OFFSET_BCOPY 0xfffffff007081dc0
#define OFFSET_COPYIN 0xfffffff007181218
#define OFFSET_COPYOUT 0xfffffff00718140c
#define OFFSET_ROOTVNODE 0xfffffff0075a80b0
#define OFFSET_CHGPROCCNT
#define OFFSET_KAUTH_CRED_REF 0xfffffff0073688a4
#define OFFSET_IPC_PORT_ALLOC_SPECIAL
#define OFFSET_IPC_KOBJECT_SET
#define OFFSET_IPC_PORT_MAKE_SEND
#define OFFSET_IOSURFACEROOTUSERCLIENT_VTAB 0xdeadbeefbabeface
#define OFFSET_ROP_ADD_X0_X0_0x10
#define OFFSET_OSSERIALIZER_SERIALIZE 0xfffffff007441424
#define OFFSET_ROP_LDR_X0_X0_0x10

@lisasu-g
Copy link

iPad mini4 10.2.1 iPad5,2 A1550

./find_offsets.sh iPad_64bit_TouchID_10.2.1_14D27_Restore.ipsw
[#] Downloading joker...
[#] Extracting...
[#] Done!
Darwin Kernel Version 16.3.0: Thu Dec 15 22:41:46 PST 2016; root:xnu-3789.42.2~1/RELEASE_ARM64_T7001

#define OFFSET_ZONE_MAP 0xfffffff007566360
#define OFFSET_KERNEL_MAP 0xfffffff0075c2058
#define OFFSET_KERNEL_TASK 0xfffffff0075c2050
#define OFFSET_REALHOST 0xfffffff007548a98
#define OFFSET_BZERO 0xfffffff00708e140
#define OFFSET_BCOPY 0xfffffff00708df80
#define OFFSET_COPYIN 0xfffffff00718f864
#define OFFSET_COPYOUT 0xfffffff00718fa6c
#define OFFSET_ROOTVNODE 0xfffffff0075c20b8
#define OFFSET_CHGPROCCNT 0xfffffff0073a4b64
#define OFFSET_KAUTH_CRED_REF 0xfffffff00737e8f8
#define OFFSET_IPC_PORT_ALLOC_SPECIAL 0xfffffff0070a6200
#define OFFSET_IPC_KOBJECT_SET 0xfffffff0070b98a0
#define OFFSET_IPC_PORT_MAKE_SEND 0xfffffff0070a5d44
#define OFFSET_IOSURFACEROOTUSERCLIENT_VTAB 0xfffffff006ed93e0
#define OFFSET_ROP_ADD_X0_X0_0x10 0xfffffff006471fb0
#define OFFSET_OSSERIALIZER_SERIALIZE 0xfffffff00745b324
#define OFFSET_ROP_LDR_X0_X0_0x10 0xfffffff0063c0ab8

@0neday
Copy link

0neday commented May 29, 2018

`
hongs-MacBook-Pro:offset hongs$ ./find_offsets.sh iPhone_7_10.3.2_14F89_Restore.ipsw.zip
Darwin Kernel Version 16.6.0: Mon Apr 17 17:33:35 PDT 2017; root:xnu-3789.60.24~24/RELEASE_ARM64_T8010

#define OFFSET_ZONE_MAP 0xfffffff0070c8098
#define OFFSET_KERNEL_MAP 0xfffffff0075ec050
#define OFFSET_KERNEL_TASK 0xfffffff0075ec048
#define OFFSET_REALHOST 0xfffffff007572ba0
#define OFFSET_BZERO 0xfffffff0070c1f80
#define OFFSET_BCOPY 0xfffffff0070c1dc0
#define OFFSET_COPYIN 0xfffffff0071c6108
#define OFFSET_COPYOUT 0xfffffff0071c63e8
#define OFFSET_ROOTVNODE 0xfffffff0075ec0b0
#define OFFSET_CHGPROCCNT 0xfffffff0073d3994
#define OFFSET_KAUTH_CRED_REF 0xfffffff0073add44
#define OFFSET_IPC_PORT_ALLOC_SPECIAL 0xfffffff0070deff4
#define OFFSET_IPC_KOBJECT_SET 0xfffffff0070f22cc
#define OFFSET_IPC_PORT_MAKE_SEND 0xfffffff0070deb18
#define OFFSET_IOSURFACEROOTUSERCLIENT_VTAB 0xfffffff006e4a238
#define OFFSET_ROP_ADD_X0_X0_0x10 0xfffffff0063ca398
#define OFFSET_OSSERIALIZER_SERIALIZE 0xfffffff007486ac4
#define OFFSET_ROP_LDR_X0_X0_0x10 0xfffffff006314a84
`

got error OFFSET_ZONE_MAP value for iphone7 10.3.2, the correct value is 0xfffffff007590478

@0neday
Copy link

0neday commented Jun 1, 2018

iPhone 6s, 9.3 offsets (partial)

// iPhone 6S - 9.3
else if (strcmp(u.machine, "iPhone8,1") == 0 && [ver isEqual:@"Version 9.3 (Build 13E234)"])
{
OFFSET_ZONE_MAP = 0xFFFFFF80044B7499; /* "zone_init: kmem_suballoc failed" /
OFFSET_KERNEL_MAP = 0xffffff8004536018;
OFFSET_KERNEL_TASK = 0xffffff8004536010;
OFFSET_REALHOST = 0xffffff8004593e90; /
host_priv_self /
OFFSET_BZERO = 0xffffff80040f2a00;
OFFSET_BCOPY = 0xffffff80040f2840;
OFFSET_COPYIN = 0xffffff80040f2c2c;
OFFSET_COPYOUT = 0xffffff80040f2e08;
OFFSET_CHGPROCCNT = 0xFFFFFF80044A444F;
OFFSET_KAUTH_CRED_REF = 0xffffff800432ec58;
OFFSET_IPC_PORT_ALLOC_SPECIAL = 0xffffff800401fe84; /
convert_task_suspension_token_to_port /
OFFSET_IPC_KOBJECT_SET = 0xffffff8004030500; /
convert_task_suspension_token_to_port /
OFFSET_IPC_PORT_MAKE_SEND = 0xffffff800401fb50; /
"ipc_host_init" */
OFFSET_IOSURFACEROOTUSERCLIENT_VTAB = 0x00; //?
OFFSET_ROP_ADD_X0_X0_0x10 = 0xffffff8004812d60;
OFFSET_ROP_LDR_X0_X0_0x10 = 0xffffff800435f7a0;
OFFSET_ROOT_MOUNT_V_NODE = 0xffffff8004536070;
LOG("loaded offsets for iPhone 6S on 9.3");
}

// use iPhone key wiki and xerub's img4 tool (do not use xpwntool to decryption 64bit kernelcache)to decryption kernelcache (N71AP), then use ida64 and this script to get offsets.

@0neday
Copy link

0neday commented Jun 11, 2018

else if (strcmp(u.machine, "iPhone6,1") == 0 && [ver isEqual:@"Version 10.2 (Build 14C92)"])
{
  OFFSET_ZONE_MAP                             = 0xFFFFFFF00755A360; /* "zone_init: kmem_suballoc failed" */
  OFFSET_KERNEL_MAP                           = 0xfffffff0075b6058;
  OFFSET_KERNEL_TASK                          = 0xfffffff0075b6050;
  OFFSET_REALHOST                             = 0xfffffff00753ca98; /* host_priv_self */
  OFFSET_BZERO                                = 0xfffffff007082140;
  OFFSET_BCOPY                                = 0xfffffff007081f80;
  OFFSET_COPYIN                               = 0xfffffff0071835b8;
  OFFSET_COPYOUT                              = 0xfffffff0071837c0;
  OFFSET_CHGPROCCNT                           = 0xfffffff00739868c;
  OFFSET_KAUTH_CRED_REF                       = 0xfffffff007372420;
  OFFSET_IPC_PORT_ALLOC_SPECIAL               = 0xfffffff00709a060; /* convert_task_suspension_token_to_port */
  OFFSET_IPC_KOBJECT_SET                      = 0xfffffff0070ad6dc; /* convert_task_suspension_token_to_port */
  OFFSET_IPC_PORT_MAKE_SEND                   = 0xfffffff007099ba4; /* "ipc_host_init" */
  OFFSET_IOSURFACEROOTUSERCLIENT_VTAB         = 0xfffffff006f2ca20;
  OFFSET_ROP_ADD_X0_X0_0x10                   = 0xfffffff006531fb0;
  OFFSET_ROP_LDR_X0_X0_0x10                   = 0xfffffff006480ab8;
  OFFSET_ROOT_MOUNT_V_NODE                    = 0xfffffff0075b60b8;
  LOG("loaded offsets for iPhone 5S on 10.2");
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment