murkmod-devmode.sh 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. #!/bin/bash
  2. CURRENT_MAJOR=6
  3. CURRENT_MINOR=0
  4. CURRENT_VERSION=0
  5. show_logo() {
  6. clear
  7. echo -e " __ .___\n _____ __ _________| | __ _____ ____ __| _/\n / \| | \_ __ \ |/ // \ / _ \ / __ | \n| Y Y \ | /| | \/ <| Y Y ( <_> ) /_/ | \n|__|_| /____/ |__| |__|_ \__|_| /\____/\____ | \n \/ \/ \/ \/\n"
  8. echo "The fakemurk plugin manager - v$CURRENT_MAJOR.$CURRENT_MINOR.$CURRENT_VERSION - Developer mode installer"
  9. }
  10. lsbval() {
  11. local key="$1"
  12. local lsbfile="${2:-/etc/lsb-release}"
  13. if ! echo "${key}" | grep -Eq '^[a-zA-Z0-9_]+$'; then
  14. return 1
  15. fi
  16. sed -E -n -e \
  17. "/^[[:space:]]*${key}[[:space:]]*=/{
  18. s:^[^=]+=[[:space:]]*::
  19. s:[[:space:]]+$::
  20. p
  21. }" "${lsbfile}"
  22. }
  23. get_asset() {
  24. curl -s -f "https://api.github.com/repos/rainestorme/murkmod/contents/$1" | jq -r ".content" | base64 -d
  25. }
  26. install() {
  27. TMP=$(mktemp)
  28. get_asset "$1" >"$TMP"
  29. if [ "$?" == "1" ] || ! grep -q '[^[:space:]]' "$TMP"; then
  30. echo "Failed to install $1 to $2"
  31. rm -f "$TMP"
  32. exit
  33. fi
  34. # Don't mv, that would break permissions
  35. cat "$TMP" >"$2"
  36. rm -f "$TMP"
  37. }
  38. get_largest_nvme_namespace() {
  39. # this function doesn't exist if the version is old enough, so we redefine it
  40. local largest size tmp_size dev
  41. size=0
  42. dev=$(basename "$1")
  43. for nvme in /sys/block/"${dev%n*}"*; do
  44. tmp_size=$(cat "${nvme}"/size)
  45. if [ "${tmp_size}" -gt "${size}" ]; then
  46. largest="${nvme##*/}"
  47. size="${tmp_size}"
  48. fi
  49. done
  50. echo "${largest}"
  51. }
  52. get_booted_kernnum() {
  53. if (($(cgpt show -n "$dst" -i 2 -P) > $(cgpt show -n "$dst" -i 4 -P))); then
  54. echo -n 2
  55. else
  56. echo -n 4
  57. fi
  58. }
  59. opposite_num() {
  60. if [ "$1" == "2" ]; then
  61. echo -n 4
  62. elif [ "$1" == "4" ]; then
  63. echo -n 2
  64. elif [ "$1" == "3" ]; then
  65. echo -n 5
  66. elif [ "$1" == "5" ]; then
  67. echo -n 3
  68. else
  69. return 1
  70. fi
  71. }
  72. defog() {
  73. echo "Defogging..."
  74. futility gbb --set --flash --flags=0x8091 # we use futility here instead of the commented out command below because we expect newer chromeos versions and don't want to wait 30 seconds
  75. # /usr/share/vboot/bin/set_gbb_flags.sh 0x8091
  76. crossystem block_devmode=0
  77. vpd -i RW_VPD -s block_devmode=0
  78. vpd -i RW_VPD -s check_enrollment=1
  79. }
  80. murkmod() {
  81. show_logo
  82. if [ -f /sbin/fakemurk-daemon.sh ]; then
  83. echo "!!! Your system already has a fakemurk installation! Continuing anyway, but emergency revert will not work correctly. !!!"
  84. fi
  85. if [ -f /sbin/murkmod-daemon.sh ]; then
  86. echo "!!! Your system already has a murkmod installation! Continuing anyway, but emergency revert will not work correctly. !!!"
  87. fi
  88. echo "What version of murkmod do you want to install?"
  89. echo "If you're not sure, choose pheonix (v118) or the latest version. If you know what your original enterprise version was, specify that manually."
  90. echo " 1) og (chromeOS v105)"
  91. echo " 2) mercury (chromeOS v107)"
  92. echo " 3) john (chromeOS v117)"
  93. echo " 4) pheonix (chromeOS v118)"
  94. echo " 5) latest version"
  95. echo " 6) custom milestone"
  96. read -p "(1-6) > " choice
  97. case $choice in
  98. 1) VERSION="105" ;;
  99. 2) VERSION="107" ;;
  100. 3) VERSION="117" ;;
  101. 4) VERSION="118" ;;
  102. 5) VERSION="latest" ;;
  103. 6) read -p "Enter milestone to target (e.g. 105, 107, 117, 118): " VERSION ;;
  104. *) echo "Invalid choice, exiting." && exit ;;
  105. esac
  106. show_logo
  107. echo "Finding latest Chrome100 build ID..."
  108. local build_id=$(curl -s "https://chrome100.dev" | grep -o '"buildId":"[^"]*"' | cut -d':' -f2 | tr -d '"')
  109. echo "Finding recovery image..."
  110. local release_board=$(lsbval CHROMEOS_RELEASE_BOARD)
  111. #local release_board="hatch"
  112. local board=${release_board%%-*}
  113. if [ $VERSION == "latest" ]; then
  114. local builds=$(curl -ks "https://chromiumdash.appspot.com/cros/fetch_serving_builds?deviceCategory=Chrome%20OS\\")
  115. local hwid=$(jq "(.builds.$board[] | keys)[0]" <<<"$builds")
  116. local hwid=${hwid:1:-1}
  117. local milestones=$(jq ".builds.$board[].$hwid.pushRecoveries | keys | .[]" <<<"$builds")
  118. local VERSION=$(echo "$milestones" | tail -n 1 | tr -d '"')
  119. echo "Latest version is $VERSION"
  120. fi
  121. local url="https://chrome100.dev/_next/data/$build_id/board/$board.json"
  122. local json=$(curl -ks "$url")
  123. chrome_versions=$(echo "$json" | jq -r '.pageProps.images[].chrome')
  124. echo "Found $(echo "$chrome_versions" | wc -l) versions of chromeOS for your board on chrome100."
  125. echo "Searching for a match..."
  126. MATCH_FOUND=0
  127. for cros_version in $chrome_versions; do
  128. platform=$(echo "$json" | jq -r --arg version "$cros_version" '.pageProps.images[] | select(.chrome == $version) | .platform')
  129. channel=$(echo "$json" | jq -r --arg version "$cros_version" '.pageProps.images[] | select(.chrome == $version) | .channel')
  130. mp_token=$(echo "$json" | jq -r --arg version "$cros_version" '.pageProps.images[] | select(.chrome == $version) | .mp_token')
  131. mp_key=$(echo "$json" | jq -r --arg version "$cros_version" '.pageProps.images[] | select(.chrome == $version) | .mp_key')
  132. last_modified=$(echo "$json" | jq -r --arg version "$cros_version" '.pageProps.images[] | select(.chrome == $version) | .last_modified')
  133. # if $cros_version starts with $VERSION, then we have a match
  134. if [[ $cros_version == $VERSION* ]]; then
  135. echo "Found a $VERSION match on platform $platform from $last_modified."
  136. MATCH_FOUND=1
  137. #https://dl.google.com/dl/edgedl/chromeos/recovery/chromeos_15117.112.0_hatch_recovery_stable-channel_mp-v6.bin.zip
  138. FINAL_URL="https://dl.google.com/dl/edgedl/chromeos/recovery/chromeos_${platform}_${board}_recovery_${channel}_${mp_token}-v${mp_key}.bin.zip"
  139. break
  140. fi
  141. done
  142. if [ $MATCH_FOUND -eq 0 ]; then
  143. echo "No match found on chrome100. Falling back to Chromium Dash."
  144. local builds=$(curl -ks "https://chromiumdash.appspot.com/cros/fetch_serving_builds?deviceCategory=Chrome%20OS\\")
  145. local hwid=$(jq "(.builds.$board[] | keys)[0]" <<<"$builds")
  146. local hwid=${hwid:1:-1}
  147. # Get all milestones for the specified hwid
  148. milestones=$(jq ".builds.$board[].$hwid.pushRecoveries | keys | .[]" <<<"$builds")
  149. # Loop through all milestones
  150. echo "Searching for a match..."
  151. for milestone in $milestones; do
  152. milestone=$(echo "$milestone" | tr -d '"')
  153. if [[ $milestone == $VERSION* ]]; then
  154. MATCH_FOUND=1
  155. FINAL_URL=$(jq -r ".builds.$board[].$hwid.pushRecoveries[\"$milestone\"]" <<<"$builds")
  156. echo "Found a match!"
  157. break
  158. fi
  159. done
  160. fi
  161. if [ $MATCH_FOUND -eq 0 ]; then
  162. echo "No recovery image found for your board and target version. Exiting."
  163. exit
  164. fi
  165. echo "Installing unzip (this may take up to 2 minutes)..."
  166. dev_install --reinstall <<EOF > /dev/null
  167. y
  168. n
  169. EOF
  170. emerge unzip > /dev/null
  171. mkdir -p /usr/local/tmp
  172. pushd /mnt/stateful_partition
  173. set -e
  174. echo "Downloading recovery image from '$FINAL_URL'..."
  175. curl --progress-bar -k "$FINAL_URL" -o recovery.zip
  176. echo "Unzipping image..."
  177. unzip -o recovery.zip
  178. rm recovery.zip
  179. FILENAME=$(find . -maxdepth 2 -name "chromeos_*.bin") # 2 incase the zip format changes
  180. echo "Found recovery image from archive at $FILENAME"
  181. pushd /usr/local/tmp # /usr/local is mounted as exec, so we can run scripts from here
  182. echo "Installing image_patcher.sh..."
  183. install "image_patcher.sh" ./image_patcher.sh
  184. chmod 777 ./image_patcher.sh
  185. echo "Installing ssd_util.sh..."
  186. mkdir -p ./lib
  187. install "ssd_util.sh" ./lib/ssd_util.sh
  188. chmod 777 ./lib/ssd_util.sh
  189. echo "Installing common_minimal.sh..."
  190. install "common_minimal.sh" ./lib/common_minimal.sh
  191. chmod 777 ./lib/common_minimal.sh
  192. popd
  193. echo "Invoking image_patcher.sh..."
  194. bash /usr/local/tmp/image_patcher.sh "$FILENAME"
  195. echo "Patching complete. Determining target partitions..."
  196. local dst=/dev/$(get_largest_nvme_namespace)
  197. if [[ $dst == /dev/sd* ]]; then
  198. echo "WARNING: get_largest_nvme_namespace returned $dst - this doesn't seem correct!"
  199. echo "Press enter to view output from fdisk - find the correct drive and enter it below"
  200. read -r
  201. fdisk -l | more
  202. echo "Enter the target drive to use:"
  203. read dst
  204. fi
  205. local tgt_kern=$(opposite_num $(get_booted_kernnum))
  206. local tgt_root=$(( $tgt_kern + 1 ))
  207. local kerndev=${dst}p${tgt_kern}
  208. local rootdev=${dst}p${tgt_root}
  209. echo "Targeting $kerndev and $rootdev"
  210. local loop=$(losetup -f | tr -d '\r')
  211. losetup -P "$loop" "$FILENAME"
  212. echo "Press enter if nothing broke, otherwise press Ctrl+C"
  213. read -r
  214. printf "Nuking partitions in 3 (this is your last chance to cancel)..."
  215. sleep 1
  216. printf "2..."
  217. sleep 1
  218. echo "1..."
  219. sleep 1
  220. echo "Bomb has been planted! Overwriting ChromeOS..."
  221. echo "Installing kernel patch to ${kerndev}..."
  222. dd if="${loop}p4" of="$kerndev" status=progress
  223. echo "Installing root patch to ${rootdev}..."
  224. dd if="${loop}p3" of="$rootdev" status=progress
  225. echo "Setting kernel priority..."
  226. cgpt add "$dst" -i 4 -P 0
  227. cgpt add "$dst" -i 2 -P 0
  228. cgpt add "$dst" -i "$tgt_kern" -P 1
  229. echo "Defogging... (if write-protect is disabled, this will set GBB flags to 0x8091)"
  230. defog
  231. echo "Cleaning up..."
  232. losetup -d "$loop"
  233. rm -f "$FILENAME"
  234. popd
  235. read -n 1 -s -r -p "Done! Press any key to continue and your system will reboot automatically."
  236. reboot
  237. echo "Bye!"
  238. sleep 20
  239. echo "Your system should have rebooted. If it didn't please perform an EC reset (Refresh+Power)."
  240. sleep 1d
  241. exit
  242. }
  243. if [ "$0" = "$BASH_SOURCE" ]; then
  244. if [ "$EUID" -ne 0 ]; then
  245. echo "Please run as root."
  246. exit
  247. fi
  248. murkmod
  249. fi