Skip to content

Instantly share code, notes, and snippets.

@userlandkernel
Last active November 23, 2023 18:00
Show Gist options
  • Save userlandkernel/87968fe9040f91e3a90a57acc830b0e4 to your computer and use it in GitHub Desktop.
Save userlandkernel/87968fe9040f91e3a90a57acc830b0e4 to your computer and use it in GitHub Desktop.
Finds all symbol offsets in a decompressed XNU kernelcache
#!/bin/sh
RADARE="$(which rabin2)" #We need rabin2
KERNELCACHE_FILE="$1" #This will be the path to a decompressed kernelcace, e.g: /tmp/kernel
OFFSETS_FILE="$2" #This is the path and name of the file where the offsets should be stored in, don't add .c or .h the script will do!
STRUCTNAME="$3"
H_FILE="$OFFSETS_FILE.h" # your_chosen_name.h
C_FILE="$OFFSETS_FILE.c" # your_chosen_name.c
USAGE="Usage: $0 [decompressed_kernelcache] [offsets_outputfile] [structure name]" # Usage: ./off_finder.sh (...)
# If we did not receive any arguments, display the usage and exit
if [ $# -eq 0 ]
then
echo $USAGE
echo ""
exit;
fi
# If we did get insufficient arguments also display the usage and exit
if [ $# -eq 2 ]
then
echo $USAGE
echo ""
exit;
fi
# We must have an actual kernelcache to work with
if [ ! -f $KERNELCACHE_FILE ]; then
echo "The specified kernelcache does not seem to exist"
exit;
fi
# We substract the XNU version number and its release
XNU_VERSION=$(strings $KERNELCACHE_FILE | grep "Darwin Kernel Version" | tail -n 1 | awk '{print $11}' | sed "s/root://g" | tr -d "~" | sed "s/-/_/g" | sed "s/\./_/g" | sed "s/\//_/g" | awk '{print toupper($0);}')
# Clears the files in case they already exist
echo "" > $C_FILE
echo "" > $H_FILE
# It's nice to have some information about who generated what and when for which version
echo "/* Generated on $(date) by $USER for $XNU_VERSION */" >> $H_FILE
echo "/* Generated on $(date) by $USER for $XNU_VERSION */" >> $C_FILE
# We start off by writing the structure to the c file based off the retrieved xnu version
echo "#include \"$H_FILE\"" >> $C_FILE # Include the header file
echo "${XNU_VERSION}_offs_t $STRUCTNAME = {" >> $C_FILE
echo " " >> $C_FILE
# We now will use rabin2 to read and export the symbols of the kernelcache
# We will remove the name and addr atttibutes and simply link its values to conform to the structure format
# In the end we also remove the count rabin2 gives in the last line and we sort the lines eventually adding the comma to conform to the structure format
OFFDATA=$($RADARE -s $KERNELCACHE_FILE | awk '{print $8 " " $1}' | sed "s/name=/./" | sed "s/vaddr=/= /g" | sed '$ d' | sed '$ d' | sort -u | sed -e 's/$/,/' | awk '{print "\t" toupper($0)}' | sed 's/\:/_/g' | tr -d '[]' | sed '/^\t\.FUNC/ d'| tr -d '~')
OFFDATA_TMP=$(echo "${OFFDATA}" | awk 'cnt[$1]++{$1=$1""cnt[$1]-1}1')
echo "${OFFDATA_TMP}" | awk '{print "\t "$1" "$2" "$3}' | sed '/ SYMBOLS,/ d' >> $C_FILE # Export all offsets in structure format to the c file
echo "};" >> $C_FILE # End the structure
# We can now continue generating the header file
# We define a structure named accordingly to the XNU version retrieved earlier
echo "typedef struct $XNU_VERSION {" >> $H_FILE # Write the structure definition to the header file
# Kernel offsets are sixtyfour bit unsigned integers we must remove the trailing period to conform to ANSI C structure definition
OFFDATA_TMP=$(echo "${OFFDATA}" | tr -d '.,' | awk 'cnt[$1]++{$1=$1""cnt[$1]-1}1')
echo "${OFFDATA_TMP}" | awk '{print "\tuint64_t " $1 ";"}' | sed '/\tuint64_t SYMBOLS;/ d'>> $H_FILE # Write the body of the structure to the header file
# Finally end the structure
echo "} ${XNU_VERSION}_offs_t;" >> $H_FILE # Write the end of the structure to the header file
# Show some information about the number of exported symbols and the kernel version, substract three from the linecount as we added three lines of structure declaration
echo "Exported $(($(cat $C_FILE | wc -l)-3)) offsets to $C_FILE and generated the structure in $H_FILE for $XNU_VERSION"
# Big thanks to radare2 developers for making this possible, its so easy, fast and useful!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment