Quantcast
Channel: Recent Gists from TheFreeman193
Viewing all articles
Browse latest Browse all 6

Detect offset of kernel release string

$
0
0
kr_offset.sh
#!/system/bin/sh
# Copyright (C) MIT License 2024 Nicholas Bissell (TheFreeman193)
NL="
"
SYSNMLN=65
showHeader() {
echo "
========= Kernel release offset finder =========
Buy me a coffee: https://ko-fi.com/nickbissell
===================== v1.0 =====================
" >&2
}
showUsage() {
showHeader 2>&1
echo "Usage:
$0 --auto [--hex] [--quiet]
$0 [--kernel] kernel_file [--hex] [--quiet]
$0 --image boot_img [--hex] [--quiet]
$0 --boot boot_part [--hex] [--quiet]
--auto -a Detect boot partition and extract automatically
--kernel -k Get offset from an uncompressed kernel file (kernel)
--image -i Get offset from a boot image file (boot.img)
--boot -b Get offset from a boot partition (/dev/block/...)
--hex -x Return offset in hexadecimal format
--quiet -q Quiet operation - don't print operations to stderr
kernel_file An uncompressed Linux kernel extracted with magiskboot
boot_img A boot image file containing the Linux kernel
boot_part A path to the boot partition of the device
"
exit 0
}
[ $# -eq 0 ] || [ -z "$1" ] && showUsage
if [ ! -f /data/adb/magisk/busybox ] || [ ! -f /data/adb/magisk/magiskboot ]; then
echo "ERROR: Critical Magisk components not found. Make sure magisk is installed and this is a root shell." >&2
exit 2
fi
readUtsFieldHex() {
[ -z "$SYSNMLN" ] && SYSNMLN=65
dd if="$1" skip="$2" count="$SYSNMLN" iflag="skip_bytes,count_bytes" status=none | /data/adb/magisk/busybox xxd -p -c "$SYSNMLN"
}
toUtsFieldHex() {
[ -z "$SYSNMLN" ] && SYSNMLN=65
hexSYSNMLN="$((SYSNMLN * 2))"
hexPad="$(dd if=/dev/zero iflag=count_bytes count="$SYSNMLN" status=none | /data/adb/magisk/busybox xxd -p -c "$SYSNMLN")"
echo "$(printf %s "$1" | /data/adb/magisk/busybox xxd -p -c "$SYSNMLN")$hexPad" | cut -b "-$hexSYSNMLN"
}
findStringsInBin() {
/data/adb/magisk/busybox strings -t d "$1" | grep -F "$2" | sed -r 's/^[[:space:]]*([0-9]+)[[:space:]]+.+$/\1/g' | grep -E "^[0-9]+$"
}
findUtsFieldOffset() {
file="$1"
value="$2"
[ -z "$SYSNMLN" ] && SYSNMLN=65
[ $quietMode -eq 0 ] && echo "${NL}Looking for instances of '$value' in '$file'..." >&2
curSys="$(uname -s | cut -b "-$SYSNMLN")"
curMachine="$(uname -m | cut -b "-$SYSNMLN")"
hexValue="$(toUtsFieldHex "$value")"
hexCurSys="$(toUtsFieldHex "$curSys")"
hexCurMachine="$(toUtsFieldHex "$curMachine")"
potentialOffsets="$(findStringsInBin "$file" "$value")"
validOffsets=""
[ $asHex -eq 0 ] && offsetFormat="%s%s... " || offsetFormat="%s0x%x... "
for offset in $potentialOffsets; do
[ $quietMode -eq 0 ] && printf "$offsetFormat" " Checking match at offset " "$offset" >&2
if [ "$(readUtsFieldHex "$file" "$offset")" == "$hexValue" ]; then
found=""
sysOffset="$((offset - SYSNMLN * 5))"
endOffset="$((offset + SYSNMLN * 5))"
while [ "$sysOffset" -lt "$endOffset" ]; do
curHex="$(readUtsFieldHex "$file" "$sysOffset")"
if [ "$curHex" == "$hexCurSys" ]; then
found="sysname"
break 1
elif [ "$curHex" == "$hexCurMachine" ]; then
found="machine"
break 1
fi
sysOffset="$((sysOffset + SYSNMLN))"
done
if [ -n "$found" ]; then
validOffsets+="$offset$NL"
[ $quietMode -eq 0 ] && echo "Found UTS $found field!" >&2
else
[ $quietMode -eq 0 ] && echo "Not a complete UTS structure" >&2
fi
else
[ $quietMode -eq 0 ] && echo "Partial match/not UTS" >&2
fi
done
if [ -n "$validOffsets" ]; then
echo "$validOffsets" | sed '/^$/d'
else
echo "${NL}No offsets with UTS format found for '$curRelease'" >&2
return 1
fi
}
findBootPath() {
[ $quietMode -eq 0 ] && echo "${NL}Detecting boot partition path..." >&2
bootPath="/dev/block/bootdevice/by-name"
if [ ! -d "$bootPath/" ]; then
echo "ERROR: Boot partition directory not found." >&2
exit 1
fi
if [ -e "$bootPath/boot" ]; then
echo "$bootPath/boot"
elif [ -e "$bootPath/boot_a" ] && [ -e "$bootPath/boot_b" ]; then
slot_suffix="$(getprop ro.boot.slot_suffix)"
if [ -n "$slot_suffix" ]; then
echo "$bootPath/boot$slot_suffix"
return 0
fi
current_slot="$(getprop current-slot)"
if [ -n "$current_slot" ]; then
echo "$bootPath/boot$current_slot"
return 0
fi
command -v bootctl && slot_number="$(bootctl get-current-slot)"
[ -n "$slot_number" ] && slot_suffix="$(bootctl get-suffix "$slot_number")"
if [ -n "$slot_suffix" ]; then
echo "$bootPath/boot$slot_suffix"
return 0
fi
slot_suffix="$(cat /proc/cmdline | sed 's/ /\n/g' | grep -Ei 'slot_suffix|current-slot' | sed -r 's/.+=//')"
if [ -n "$slot_suffix" ]; then
echo "$bootPath/boot$slot_suffix"
return 0
fi
echo "ERROR: Cannot get active slot." >&2
exit 1
else
echo "ERROR: Unexpected boot partition configuration." >&2
exit 1
fi
}
newStage() {
lastDir="$PWD"
stageDir="/data/local/tmp/$(uuidgen)"
mkdir "$stageDir"
if [ ! -d "$stageDir" ]; then
echo "ERROR: Couldn't create temporary directory '$stageDir'" >&2
exit 5
fi
cd "$stageDir"
}
cleanupQuit() {
if [ -n "$stageDir" ] && [ -d "$stageDir" ]; then
[ -n "$lastDir" ] && [ -d "$lastDir" ] && cd "$lastDir"
rm -rf "$stageDir"
fi
[ -n "$1" ] && exit $1 || exit 0
}
kernelFile=""
imageFile=""
bootPath=""
autoExtract=0
asHex=0
quietMode=0
while [ $# -gt 0 ]; do
param="$1"
hasShifted=0
case "$param" in
-h|-\?|--help)
showUsage
;;
--kernel|-k|-[aqx]*k)
kernelFile="$(readlink -f "$2")"
shift; shift; hasShifted=1
;;
--image|-i|-[aqx]*i)
imageFile="$(readlink -f "$2")"
shift; shift; hasShifted=1
;;
--boot|-b|-[aqx]*b)
bootPath="$2"
shift; shift; hasShifted=1
;;
--auto|-a)
autoExtract=1
shift; continue
;;
--quiet|-q)
quietMode=1
shift; continue
;;
--hex|-x)
asHex=1
shift; continue
;;
*)
if echo "$1" | grep -Eqv '^-'; then
kernelFile="$(readlink -f "$1")"
shift; continue
fi
;;
esac
echo "$param" | grep -Eq '^-[qx]*a[qx]*[kib]$' && autoExtract=1
echo "$param" | grep -Eq '^-[qa]*x[qa]*[kib]$' && asHex=1
echo "$param" | grep -Eq '^-[ax]*q[ax]*[kib]$' && quietMode=1
[ $hasShifted -eq 1 ] && continue
echo "ERROR: Couldn't parse parameter '$1'." >&2
exit 1
done
[ $quietMode -eq 0 ] && showHeader
primArgs=0
mode=0
[ -n "$kernelFile" ] && mode=1 && primArgs=$((primArgs + 1))
[ -n "$imageFile" ] && mode=2 && primArgs=$((primArgs + 1))
[ -n "$bootPath" ] && mode=3 && primArgs=$((primArgs + 1))
[ $autoExtract -eq 1 ] && mode=4 && primArgs=$((primArgs + 1))
if [ $primArgs -gt 1 ]; then
echo "ERROR: Too many parameters ($primArgs) - only 1 of --kernel, --image, --boot, --auto allowed." >&2
exit 2
fi
if [ $mode -eq 0 ]; then
echo "ERROR: You must either pass a kernel file, boot image, partition path, or use --auto."
exit 3
fi
[ $mode -ge 4 ] && bootPath="$(findBootPath)"
[ $mode -ge 2 ] && newStage
if [ $mode -ge 3 ]; then
if [ ! -e "$bootPath" ]; then
echo "ERROR: Boot partition path '$bootPath' not found." >&2
cleanupQuit 4
fi
imageFile="boot.img"
[ $quietMode -eq 0 ] && echo "${NL}Extracting boot image '$bootPath'..." >&2
dd if="$bootPath" of="$imageFile" status=none
if [ ! -f "$imageFile" ]; then
echo "ERROR: Failed to extract boot image." >&2
cleanupQuit 6
fi
fi
if [ $mode -ge 2 ]; then
kernelFile="kernel"
[ $quietMode -eq 0 ] && echo "${NL}Unpacking boot image '$imageFile'..."
/data/adb/magisk/magiskboot unpack "$imageFile" 2>/dev/null
if [ ! -f "$kernelFile" ]; then
echo "ERROR: Failed to unpack boot image." >&2
cleanupQuit 7
fi
fi
if [ $mode -eq 1 ] && [ ! -f "$kernelFile" ]; then
echo "ERROR: Failed to unpack boot image." >&2
cleanupQuit 8
fi
curRelease="$(uname -r | cut -b "-$SYSNMLN")"
releaseOffsets="$(findUtsFieldOffset "$kernelFile" "$curRelease")"
if [ -n "$releaseOffsets" ]; then
[ $quietMode -eq 0 ] && echo "" >&2
[ $asHex -eq 1 ] && printf "0x%x\n" "$releaseOffsets" || echo "$releaseOffsets"
[ $quietMode -eq 0 ] && echo "" >&2
fi
cleanupQuit 0

Viewing all articles
Browse latest Browse all 6

Latest Images

Trending Articles





Latest Images