From 8915cb6d3a6724110fb92a2dcc33c459f066c38b Mon Sep 17 00:00:00 2001 From: kxtzownsu Date: Sat, 9 Mar 2024 23:29:03 -0500 Subject: [PATCH] hai, infodump here :3 --- README.md | 12 +- builder/builder.sh | 145 ++++++++++------- builder/functions.sh | 124 +++++++++++++- builder/root/DATE_COMPILED | 1 + .../usr/sbin}/factory_install.sh | 9 +- .../kvs => root/usr/sbin}/functions.sh | 0 builder/root/usr/sbin/kvs/functions.sh | 154 ++++++++++++++++++ .../{scripts => root/usr/sbin}/kvs/tpmutil.sh | 0 builder/root/usr/sbin/tpmutil.sh | 15 ++ 9 files changed, 376 insertions(+), 84 deletions(-) mode change 100644 => 100755 builder/builder.sh create mode 100644 builder/root/DATE_COMPILED rename builder/{scripts => root/usr/sbin}/factory_install.sh (94%) rename builder/{scripts/kvs => root/usr/sbin}/functions.sh (100%) create mode 100755 builder/root/usr/sbin/kvs/functions.sh rename builder/{scripts => root/usr/sbin}/kvs/tpmutil.sh (100%) create mode 100755 builder/root/usr/sbin/tpmutil.sh diff --git a/README.md b/README.md index 75046b5..8edaacb 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,2 @@ -# KVS -KVS: Kernel Version Switcher - - -# Credits -kxtzownsu - Writing KVS & Providing kernver 0 & 1 files -crossystem - Providing kerner 2 files -?? - Providing kernver 3 files (very sorry, but I couldn't find their username) -katie - Getting me a working POC (told me to use `tpmc` instead of `tpm_manager_client`) -Google - y'know.. writing `tpmc` and giving me the idea for this (due to a glitch, my one chromebook got set to kernver 0) \ No newline at end of file +# kvs +KVS: Kernel Version Switcher, made to easily switch the tpm_kernver for Chromebooks. diff --git a/builder/builder.sh b/builder/builder.sh old mode 100644 new mode 100755 index fe7bd9d..4957236 --- a/builder/builder.sh +++ b/builder/builder.sh @@ -1,64 +1,112 @@ +<<<<<<< HEAD +#!/usr/bin/env bash +======= #!/bin/bash -# KVS Builder v1 -# Basically a skidded wax, please forgive me -# Credits to the Mercury Workshop team for the shim shrinking stuff :3 -# Made by kxtzownsu -# 3-6-2024 -# GNU Affero GPL v3 +>>>>>>> parent of 0ac565d (start of builder :3) SCRIPT_DIR=$(dirname "$0") -SCRIPT_DIR=${SCRIPT_DIR:-"."} -. "$SCRIPT_DIR/functions.sh" - VERSION=1 +source $SCRIPT_DIR/functions.sh + echo "KVS Shim Builder v$VERSION" echo "-=-=-=-=-=-=-=-=-=-" +<<<<<<< HEAD +echo "fdisk, e2fsprogs required. must be ran as root" +echo "-=-=-=-=-=-=-=-=-=-" +[ "$EUID" -ne 0 ] && error "Please run as root" +[ "$1" == "" ] && error "No shim specified." + + +STATE_SIZE=$((4 * 1024 * 1024)) # 4 MiB +STATE_MNT="$(mktemp -d)" +ROOT_MNT="$(mktemp -d)" +LOOPDEV="$(losetup -f)" +IMG="$1" + +echo "loop: $LOOPDEV" +echo "root mount: $ROOT_MNT" +echo "state mount: $STATE_MNT" +echo "state size: $STATE_SIZE" +echo "shim: $IMG" +echo "-=-=-=-=-=-=-=-=-=-" +echo "Before building, huge credits to the MercuryWorkshop team for their work on wax," +echo "some of this builder would have been impossible without it, at least with my disk knowledge" +echo "Press ENTER to continue, CTRL+C to quit" +read -r + +#we need this before we re-create stateful +STATE_START=$(cgpt show "$IMG" | grep "STATE" | awk '{print $1}') +shrink_partitions "$IMG" +losetup -P "$LOOPDEV" "$IMG" +enable_rw_mount "$LOOPDEV"p3 + +log "Correcting GPT errors.." +fdisk -l "$LOOPDEV" +fdisk "$LOOPDEV" < " -[ $(echo $1 | grep -qs '.bin' - && echo true || echo false) == "false" ] && error "Shim is NOT a .bin file!" -echo "Requirements: cgpt, e2fsprogs, sgdisk, raw shim" +echo "Requirements: cgpt, e2fsprogs, sgdisk" echo "-=-=-=-=-=-=-=-=-=-" -echo "Before the shim starts building, I'd like to say thank you to the Mercury Workshop team, most of the code (shim shrinking, verity disabling, etc) is from them." -echo "Pres Enter to continue building" -read -r STATE_SIZE=$((4 * 1024 * 1024)) # 4MiB STATE_MNT=$(mktemp -d) -ROOT_MNT=$(mktemp -d) LOOPDEV=$(losetup -f) -clean_mnts(){ - umount -R "$STATE_MNT" - umount -R "$ROOT_MNT" - rm -rf "$STATE_MNT" - rm -rf "$ROOT_MNT" -} - create_stateful() { - log "Creating KVS/Stateful partition (1/" + log "Creating KVS/Stateful partition" local final_sector=$(get_final_sector "$LOOPDEV") local sector_size=$(get_sector_size "$LOOPDEV") cgpt add "$LOOPDEV" -i 1 -b $((final_sector + 1)) -s $((STATE_SIZE / sector_size)) -t data -l KVS partx -u -n 1 "$LOOPDEV" mkfs.ext4 -F -L KVS "${LOOPDEV}p1" &> /dev/null - safesync + sync + sleep 0.2 mount "${LOOPDEV}p1" "$STATE_MNT" touch "$STATE_MNT/dev_image/etc/lsb-factory" chmod -R +x "$STATE_MNT" umount "$STATE_MNT" -} - -inject_stateful(){ - log "Injecting Stateful (2" - - mount + rmdir "$STATE_MNT" } shrink_root() { - log "Shrinking ROOT (4" + log "Shrinking ROOT" enable_rw_mount "${LOOPDEV}p3" suppress e2fsck -fy "${LOOPDEV}p3" @@ -69,43 +117,16 @@ shrink_root() { local block_size=$(tune2fs -l "${LOOPDEV}p3" | grep "Block size" | awk '{print $3}') local block_count=$(tune2fs -l "${LOOPDEV}p3" | grep "Block count" | awk '{print $3}') - log "sector size: ${sector_size}, block size: ${block_size}, block count: ${block_count}" + log_debug "sector size: ${sector_size}, block size: ${block_size}, block count: ${block_count}" - local original_sectors=$(cgpt show -i 3 -s -n -q "$LOOPDEV") + local original_sectors=$("$CGPT" show -i 3 -s -n -q "$LOOPDEV") local original_bytes=$((original_sectors * sector_size)) local resized_bytes=$((block_count * block_size)) local resized_sectors=$((resized_bytes / sector_size)) - log "Resizing ROOT from $(format_bytes ${original_bytes}) to $(format_bytes ${resized_bytes})" + log_info "Resizing ROOT from $(format_bytes ${original_bytes}) to $(format_bytes ${resized_bytes})" "$CGPT" add -i 3 -s "$resized_sectors" "$LOOPDEV" partx -u -n 3 "$LOOPDEV" } - -inject_root(){ - enable_rw_mount "${LOOPDEV}p3" - log "Injecting scripts (3" - - mount "${LOOPDEV}p3" "${ROOT_MNT}" - - # scary if ROOT_MNT gets set to nothing! - cp -r scripts/* "${ROOT_MNT}/usr/sbin" -} - - -create_stateful -inject_stateful -inject_root -shrink_root -shrink_partitions "$LOOPDEV" - -# for prebuilt bins hosted on dl.kxtz.dev -if [ "$2" == "--noskid" ]; then - disable_rw_mount "${LOOPDEV}p3" - log "Disabled RW mounting for ROOT-A" -fi - -clean_mnts -losetup -D "$LOOPDEV" - -truncate_image "$1" \ No newline at end of file +>>>>>>> parent of 0ac565d (start of builder :3) diff --git a/builder/functions.sh b/builder/functions.sh index 72dec46..f5c45ad 100644 --- a/builder/functions.sh +++ b/builder/functions.sh @@ -2,29 +2,49 @@ COLOR_RESET="\033[0m" COLOR_BLACK_B="\033[1;30m" -COLOR_RED="\033[0;31m" COLOR_RED_B="\033[1;31m" COLOR_GREEN="\033[0;32m" COLOR_GREEN_B="\033[1;32m" COLOR_YELLOW="\033[0;33m" COLOR_YELLOW_B="\033[1;33m" -COLOR_BLUE="\033[0;34m" COLOR_BLUE_B="\033[1;34m" -COLOR_MAGENTA="\033[0;35m" COLOR_MAGENTA_B="\033[1;35m" -COLOR_CYAN="\033[0;36m" COLOR_CYAN_B="\033[1;36m" +<<<<<<< HEAD readlink /proc/$$/exe | grep -q bash || error "You MUST execute this with Bash!" +safesync(){ + sync + sleep 0.2 +} + +log() { + printf "%b\n" "${COLOR_GREEN}Info: $*${COLOR_RESET}" +} + + +cleanup(){ + umount "$ROOT_MNT" + rm -rf "$ROOT_MNT" + + umount "$STATE_MNT" + rm -rf "$STATE_MNT" + + umount -R "$LOOPDEV"* + + losetup -d "$LOOPDEV" + losetup -D #in case of cmd above failing +======= log(){ printf '${COLOR_GREEN}Info: %b${COLOR_RESET}\n' "$*" +>>>>>>> parent of 0ac565d (start of builder :3) } error(){ - printf "${COLOR_RED_B}ERR: %b${COLOR_RESET}\n" "$*" >&2 || : - printf "${COLOR_RED}Exiting... ${COLOR_RESET}\n" >&2 || : + printf '${COLOR_RED_B}ERR: &b${COLOR_RESET}\n' "$*" exit 1 +<<<<<<< HEAD } suppress() { @@ -64,6 +84,7 @@ enable_rw_mount() { if ! is_ext2 "$rootfs" $offset; then echo "enable_rw_mount called on non-ext2 filesystem: $rootfs $offset" 1>&2 return 1 + exit 1 fi local ro_compat_offset=$((0x464 + 3)) @@ -108,7 +129,9 @@ shrink_partitions() { 5 d 4 - q + d + 1 + w EOF } @@ -118,9 +141,94 @@ truncate_image() { local final_sector=$(get_final_sector "$1") local end_bytes=$(((final_sector + buffer) * sector_size)) - log_info "Truncating image to $(format_bytes "$end_bytes")" + log "Truncating image to $(format_bytes "$end_bytes")" truncate -s "$end_bytes" "$1" # recreate backup gpt table/header suppress sgdisk -e "$1" 2>&1 | sed 's/\a//g' } + +format_bytes() { + numfmt --to=iec-i --suffix=B "$@" +} + + +create_stateful(){ + log "Creating KVS/Stateful Partition" + local final_sector=$(get_final_sector "$LOOPDEV") + local sector_size=$(get_sector_size "$LOOPDEV") + + echo $final_sector + echo $sector_size + + # special UUID is from grunt shim, dunno if this is different on other shims + cgpt add "$LOOPDEV" -i 1 -b "$STATE_START" -s $((STATE_SIZE / sector_size)) -t "9CC433E4-52DB-1F45-A951-316373C30605" + partx -u -n 1 "$LOOPDEV" + suppress mkfs.ext4 -F -L KVS "$LOOPDEV"p1 + safesync +} + +inject_stateful(){ + log "Injecting KVS/STateful Partition" + + echo "Mounting stateful.." + mount "$LOOPDEV"p1 "$STATE_MNT" + echo "Copying files.." + cp -r $SCRIPT_DIR/stateful/* "$STATE_MNT" + umount "$STATE_MNT" +} + +shrink_root() { + log "Shrinking ROOT-A Partition" + + enable_rw_mount "${LOOPDEV}p3" + suppress e2fsck -fy "${LOOPDEV}p3" + suppress resize2fs -M "${LOOPDEV}p3" + disable_rw_mount "${LOOPDEV}p3" + + local sector_size=$(get_sector_size "$LOOPDEV") + local block_size=$(tune2fs -l "${LOOPDEV}p3" | grep "Block size" | awk '{print $3}') + local block_count=$(tune2fs -l "${LOOPDEV}p3" | grep "Block count" | awk '{print $3}') + + local original_sectors=$(cgpt show -i 3 -s -n -q "$LOOPDEV") + local original_bytes=$((original_sectors * sector_size)) + + local resized_bytes=$((block_count * block_size)) + local resized_sectors=$((resized_bytes / sector_size)) + + echo "Resizing ROOT from $(format_bytes ${original_bytes}) to $(format_bytes ${resized_bytes})" + cgpt add -i 3 -s "$resized_sectors" "$LOOPDEV" + partx -u -n 3 "$LOOPDEV" + echo "Done shrinking root." +} + +inject_root(){ + log "Injecting ROOT-A Partition" + + echo "Mounting root.." + enable_rw_mount "$LOOPDEV"p3 + mount "$LOOPDEV"p3 "$ROOT_MNT" + echo "Copying files.." + cp -r "$SCRIPT_DIR"/root/* "$ROOT_MNT" + umount "$ROOT_MNT" +} + +get_parts_physical_order() { + local part_table=$(cgpt show -q "$1") + local physical_parts=$(awk '{print $1}' <<<"$part_table" | sort -n) + for part in $physical_parts; do + grep "^\s*${part}\s" <<<"$part_table" | awk '{print $3}' + done +} + +squash_partitions() { + log "Squashing partitions" + + for part in $(get_parts_physical_order "$1"); do + echo "Squashing ${1}p${part}" + suppress sfdisk -N "$part" --move-data "$1" <<<"+,-" || : + done +} +======= +} +>>>>>>> parent of 0ac565d (start of builder :3) diff --git a/builder/root/DATE_COMPILED b/builder/root/DATE_COMPILED new file mode 100644 index 0000000..d1b1118 --- /dev/null +++ b/builder/root/DATE_COMPILED @@ -0,0 +1 @@ +03-09-2024 diff --git a/builder/scripts/factory_install.sh b/builder/root/usr/sbin/factory_install.sh similarity index 94% rename from builder/scripts/factory_install.sh rename to builder/root/usr/sbin/factory_install.sh index dcf1654..7e56dba 100755 --- a/builder/scripts/factory_install.sh +++ b/builder/root/usr/sbin/factory_install.sh @@ -40,13 +40,14 @@ esac # detect if booted from usb boot or from recovery boot if [ "$(crossystem mainfw_type)" == "recovery" ]; then - source tpmutil.sh - source functions + source /usr/sbin/kvs/tpmutil.sh + source /usr/share/kvs/functions.sh mkdir /mnt/state &2> /dev/zero mount /dev/disk/by-label/KVS /mnt/state elif [ "$(crossystem mainfw_type)" == "developer" ]; then - # panic "non-reco" + panic "non-reco" clear + sleep infinity . ./functions.sh . ./tpmutil.sh source ./functions.sh @@ -91,4 +92,4 @@ main(){ while true; do main -done \ No newline at end of file +done diff --git a/builder/scripts/kvs/functions.sh b/builder/root/usr/sbin/functions.sh similarity index 100% rename from builder/scripts/kvs/functions.sh rename to builder/root/usr/sbin/functions.sh diff --git a/builder/root/usr/sbin/kvs/functions.sh b/builder/root/usr/sbin/kvs/functions.sh new file mode 100755 index 0000000..a18df80 --- /dev/null +++ b/builder/root/usr/sbin/kvs/functions.sh @@ -0,0 +1,154 @@ +#!/bin/bash + +style_text() { + printf "\033[31m\033[1m\033[5m$1\033[0m\n" +} + +panic(){ + case "$1" in + "invalid-kernver") + style_text "KVS PANIC" + printf "\033[31mERR\033[0m" + printf ": Invalid Kernel Version. Please make a GitHub issue at \033[3;34m$GITHUB_URL\033[0m with a picture of this information.\n" + echo "-=-=-=-=-=-=-=-=-=-=-=-=-=-=" + echo "tpm_kernver: $(crossystem tpm_kernver)" + echo "fwid: $(dmidecode -s bios-version) (compiled: $(dmidecode -s bios-release-date))" + echo "date: $(date +"%m-%d-%Y %I:%M:%S %p")" + echo "model: $(cat /sys/class/dmi/id/product_name) $(cat /sys/class/dmi/id/product_version)" + echo "Please shutdown your device now using REFRESH+PWR" + sleep infinity + ;; + "mount-error") + style_text "KVS PANIC" + printf "\033[31mERR\033[0m" + printf ": Unable to mount stateful. Please make a GitHub issue at \033[3;34m$GITHUB_URL\033[0m with a picture of this information.\n" + echo "-=-=-=-=-=-=-=-=-=-=-=-=-=-=" + echo "tpm_kernver: $(crossystem tpm_kernver)" + echo "fwid: $(dmidecode -s bios-version) (compiled: $(dmidecode -s bios-release-date))" + echo "state mounted: $([ -d /mnt/state/ ] && grep -qs '/mnt/state ' /proc/mounts && echo true || echo false)" + echo "date: $(date +"%m-%d-%Y %I:%M:%S %p")" + echo "model: $(cat /sys/class/dmi/id/product_name) $(cat /sys/class/dmi/id/product_version)" + echo "Please shutdown your device now using REFRESH+PWR" + sleep infinity + ;; + "non-reco") + style_text "KVS PANIC" + printf "\033[31mERR\033[0m" + printf ": Wrong Boot Method. To fix: boot the shim using the recovery method. (ESC+REFRESH+PWR) and \033[31mNOT\033[0m USB Boot.\n" + echo "-=-=-=-=-=-=-=-=-=-=-=-=-=-=" + echo "tpm_kernver: $(crossystem tpm_kernver)" + echo "fwid: $(dmidecode -s bios-version) (compiled: $(dmidecode -s bios-release-date))" + echo "fw mode: $(crossystem mainfw_type)" + echo "date: $(date +"%m-%d-%Y %I:%M:%S %p")" + echo "model: $(cat /sys/class/dmi/id/product_name) $(cat /sys/class/dmi/id/product_version)" + echo "Please shutdown your device now using REFRESH+PWR" + sleep infinity + ;; + "tpmd-not-killed") + style_text "KVS PANIC" + printf "\033[31mERR\033[0m" + printf ": $tpmdaemon unable to be killed. Please make a GitHub issue at \033[3;34m$GITHUB_URL\033[0m with a picture of this information.\n" + echo "-=-=-=-=-=-=-=-=-=-=-=-=-=-=" + echo "tpm_kernver: $(crossystem tpm_kernver)" + echo "fwid: $(dmidecode -s bios-version) (compiled: $(dmidecode -s bios-release-date))" + echo "tpmd ($tpmdaemon) running: $(status $tpmdaemon | grep stopped && echo true || echo false)" + echo "date: $(date +"%m-%d-%Y %I:%M:%S %p")" + echo "model: $(cat /sys/class/dmi/id/product_name) $(cat /sys/class/dmi/id/product_version)" + echo "Please shutdown your device now using REFRESH+PWR" + sleep infinity + ;; + "*") + echo "Panic ID unable to be found: $1" + echo "Exiting script to prevent crash, please make an issue at \033[3;34m$GITHUB_URL\033[0m." + esac +} + +stopwatch() { + display_timer() { + printf "[%02d:%02d:%02d]\n" $hh $mm $ss + } + hh=0 #hours + mm=0 #minutes + ss=0 #seconds + + while true; do + clear + echo "Initiated reboot, if this doesn't reboot please manually reboot with REFRESH+PWR" + echo "Time since reboot initiated:" + display_timer + ss=$((ss + 1)) + # if seconds reach 60, increment the minutes + if [ $ss -eq 60 ]; then + ss=0 + mm=$((mm + 1)) + fi + # if minutes reach 60, increment the hours + if [ $mm -eq 60 ]; then + mm=0 + hh=$((hh + 1)) + fi + sleep 1 + done +} + +selection(){ + case $1 in + "1") + echo "Please Enter Target kernver (0-3)" + read -rep "> " kernver + case $kernver in + "0") + echo "Setting kernver 0" + write_tpm 0x1008 $(cat /mnt/realstate/kvs/kernver0) + ;; + "1") + echo "Setting kernver 1" + write_tpm 0x1008 $(cat /mnt/realstate/kvs/kernver1) + ;; + "2") + echo "Setting kernver 2" + write_tpm 0x1008 $(cat /mnt/realstate/kvs/kernver2) + ;; + "3") + echo "Setting kernver 3" + write_tpm 0x1008 $(cat /mnt/realstate/kvs/kernver3) + ;; + *) + echo "Invalid kernver. Please check your input." + main + ;; + esac ;; + "2") + case $currentkernver in + "0x00000000") + echo "Current kernver: 0" + echo "Outputting to stateful/kernver-out" + cp /mnt/realstate/kvs/kernver0 /mnt/state/kernver-out + ;; + "0x00010001") + echo "Current kernver: 1" + echo "Outputting to stateful/kernver-out" + cp /mnt/realstate/kvs/kernver1 /mnt/state/kernver-out + ;; + "0x00010002") + echo "Current kernver: 2" + echo "Outputting to stateful/kernver-out" + cp /mnt/realstate/kvs/kernver2 /mnt/state/kernver-out + ;; + "0x00010003") + echo "Current kernver: 3" + echo "Outputting to stateful/kernver-out" + cp /mnt/realstate/kvs/kernver3 /mnt/state/kernver-out + ;; + *) + panic "invalid-kernver" + ;; + esac ;; + "3") + credits + ;; + "4") + endkvs + ;; + esac +} diff --git a/builder/scripts/kvs/tpmutil.sh b/builder/root/usr/sbin/kvs/tpmutil.sh similarity index 100% rename from builder/scripts/kvs/tpmutil.sh rename to builder/root/usr/sbin/kvs/tpmutil.sh diff --git a/builder/root/usr/sbin/tpmutil.sh b/builder/root/usr/sbin/tpmutil.sh new file mode 100755 index 0000000..fd46f03 --- /dev/null +++ b/builder/root/usr/sbin/tpmutil.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +write_tpm(){ + local index=$1 + local data=$2 + + tpmc write "$index" "$data" +} + +read_tpm(){ + local index=$1 + local bytes=$2 + + tpmc read "$index" "$bytes" +}