image_patcher.sh 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. #!/bin/bash
  2. # image_patcher.sh
  3. # written based on the original by coolelectronics and r58, modified heavily for murkmod
  4. CURRENT_MAJOR=6
  5. CURRENT_MINOR=1
  6. CURRENT_VERSION=1
  7. # God damn, there are a lot of unused functions in here!
  8. # future rainestorme: finally cleaned it up! :D
  9. ascii_info() {
  10. echo -e " __ .___\n _____ __ _________| | __ _____ ____ __| _/\n / \| | \_ __ \ |/ // \ / _ \ / __ | \n| Y Y \ | /| | \/ <| Y Y ( <_> ) /_/ | \n|__|_| /____/ |__| |__|_ \__|_| /\____/\____ | \n \/ \/ \/ \/\n"
  11. echo " The fakemurk plugin manager - v$CURRENT_MAJOR.$CURRENT_MINOR.$CURRENT_VERSION"
  12. # spaces get mangled by makefile, so this must be separate
  13. }
  14. nullify_bin() {
  15. cat <<-EOF >$1
  16. #!/bin/bash
  17. exit
  18. EOF
  19. chmod 777 $1
  20. # shebangs crash makefile
  21. }
  22. . /usr/share/misc/chromeos-common.sh || :
  23. traps() {
  24. set -e
  25. trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG
  26. trap 'echo "\"${last_command}\" command failed with exit code $?. THIS IS A BUG, REPORT IT HERE https://github.com/MercuryWorkshop/fakemurk"' EXIT
  27. }
  28. leave() {
  29. trap - EXIT
  30. echo "exiting successfully"
  31. exit
  32. }
  33. sed_escape() {
  34. echo -n "$1" | while read -n1 ch; do
  35. if [[ "$ch" == "" ]]; then
  36. echo -n "\n"
  37. # dumbass shellcheck not expanding is the entire point
  38. fi
  39. echo -n "\\x$(printf %x \'"$ch")"
  40. done
  41. }
  42. move_bin() {
  43. if test -f "$1"; then
  44. mv "$1" "$1.old"
  45. fi
  46. }
  47. disable_autoupdates() {
  48. # thanks phene i guess?
  49. # this is an intentionally broken url so it 404s, but doesn't trip up network logging
  50. sed -i "$ROOT/etc/lsb-release" -e "s/CHROMEOS_AUSERVER=.*/CHROMEOS_AUSERVER=$(sed_escape "https://updates.gooole.com/update")/"
  51. # we don't want to take ANY chances
  52. move_bin "$ROOT/usr/sbin/chromeos-firmwareupdate"
  53. nullify_bin "$ROOT/usr/sbin/chromeos-firmwareupdate"
  54. # bye bye trollers! (trollers being cros devs)
  55. rm -rf "$ROOT/opt/google/cr50/firmware/" || :
  56. }
  57. SCRIPT_DIR=$(dirname "$0")
  58. configure_binaries(){
  59. if [ -f /sbin/ssd_util.sh ]; then
  60. SSD_UTIL=/sbin/ssd_util.sh
  61. elif [ -f /usr/share/vboot/bin/ssd_util.sh ]; then
  62. SSD_UTIL=/usr/share/vboot/bin/ssd_util.sh
  63. elif [ -f "${SCRIPT_DIR}/lib/ssd_util.sh" ]; then
  64. SSD_UTIL="${SCRIPT_DIR}/lib/ssd_util.sh"
  65. else
  66. echo "ERROR: Cannot find the required ssd_util script. Please make sure you're executing this script inside the directory it resides in"
  67. exit 1
  68. fi
  69. }
  70. patch_root() {
  71. echo "Staging populator..."
  72. >$ROOT/population_required
  73. >$ROOT/reco_patched
  74. echo "Murkmod-ing root..."
  75. echo "Disabling autoupdates..."
  76. disable_autoupdates
  77. local milestone=$(lsbval CHROMEOS_RELEASE_CHROME_MILESTONE $ROOT/etc/lsb-release)
  78. echo "Installing startup scripts..."
  79. move_bin "$ROOT/sbin/chromeos_startup.sh"
  80. if [ "$milestone" -gt "116" ]; then
  81. echo "Detected newer version of CrOS, using new chromeos_startup"
  82. move_bin "$ROOT/sbin/chromeos_startup"
  83. install "chromeos_startup.sh" $ROOT/sbin/chromeos_startup
  84. chmod 755 $ROOT/sbin/chromeos_startup # whoops
  85. touch $ROOT/new-startup
  86. else
  87. move_bin "$ROOT/sbin/chromeos_startup.sh"
  88. install "chromeos_startup.sh" $ROOT/sbin/chromeos_startup.sh
  89. chmod 755 $ROOT/sbin/chromeos_startup.sh
  90. fi
  91. echo "Installing murkmod components..."
  92. install "daemon.sh" $ROOT/sbin/murkmod-daemon.sh
  93. move_bin "$ROOT/usr/bin/crosh"
  94. install "mush.sh" $ROOT/usr/bin/crosh
  95. echo "Installing startup services..."
  96. install "pre-startup.conf" $ROOT/etc/init/pre-startup.conf
  97. install "cr50-update.conf" $ROOT/etc/init/cr50-update.conf
  98. echo "Installing other utilities..."
  99. install "ssd_util.sh" $ROOT/usr/share/vboot/bin/ssd_util.sh
  100. install "image_patcher.sh" $ROOT/sbin/image_patcher.sh
  101. install "crossystem_boot_populator.sh" $ROOT/sbin/crossystem_boot_populator.sh
  102. install "ssd_util.sh" $ROOT/usr/share/vboot/bin/ssd_util.sh
  103. mkdir -p "$ROOT/etc/opt/chrome/policies/managed"
  104. install "pollen.json" $ROOT/etc/opt/chrome/policies/managed/policy.json
  105. echo "Chmod-ing everything..."
  106. chmod 777 $ROOT/sbin/murkmod-daemon.sh $ROOT/usr/bin/crosh $ROOT/usr/share/vboot/bin/ssd_util.sh $ROOT/sbin/image_patcher.sh $ROOT/etc/opt/chrome/policies/managed/policy.json $ROOT/sbin/crossystem_boot_populator.sh $ROOT/usr/share/vboot/bin/ssd_util.sh
  107. echo "Done."
  108. }
  109. # https://www.chromium.org/chromium-os/developer-library/reference/infrastructure/lsb-release/
  110. lsbval() {
  111. local key="$1"
  112. local lsbfile="${2:-/etc/lsb-release}"
  113. if ! echo "${key}" | grep -Eq '^[a-zA-Z0-9_]+$'; then
  114. return 1
  115. fi
  116. sed -E -n -e \
  117. "/^[[:space:]]*${key}[[:space:]]*=/{
  118. s:^[^=]+=[[:space:]]*::
  119. s:[[:space:]]+$::
  120. p
  121. }" "${lsbfile}"
  122. }
  123. get_asset() {
  124. curl -s -f "https://api.github.com/repos/rainestorme/murkmod/contents/$1" | jq -r ".content" | base64 -d
  125. }
  126. install() {
  127. TMP=$(mktemp)
  128. get_asset "$1" >"$TMP"
  129. if [ "$?" == "1" ] || ! grep -q '[^[:space:]]' "$TMP"; then
  130. echo "Failed to install $1 to $2"
  131. rm -f "$TMP"
  132. exit
  133. fi
  134. # Don't mv, that would break permissions
  135. cat "$TMP" >"$2"
  136. rm -f "$TMP"
  137. }
  138. main() {
  139. traps
  140. ascii_info
  141. configure_binaries
  142. echo $SSD_UTIL
  143. if [ -z $1 ] || [ ! -f $1 ]; then
  144. echo "\"$1\" isn't a real file, dipshit! You need to pass the path to the recovery image. Optional args: <path to custom bootsplash: path to a png> <unfuck stateful: int 0 or 1>"
  145. exit
  146. fi
  147. if [ -z $2 ]; then
  148. echo "Not using a custom bootsplash."
  149. local bootsplash="0"
  150. elif [ "$2" == "cros" ]; then
  151. echo "Using cros bootsplash."
  152. local bootsplash="cros"
  153. elif [ ! -f $2 ]; then
  154. echo "File $2 not found for custom bootsplash"
  155. local bootsplash="0"
  156. else
  157. echo "Using custom bootsplash $2"
  158. local bootsplash=$2
  159. fi
  160. if [ -z $3 ]; then
  161. local unfuckstateful="1"
  162. else
  163. local unfuckstateful=$3
  164. fi
  165. if [ "$unfuckstateful" == "1" ]; then
  166. echo "Will unfuck stateful partition upon boot."
  167. fi
  168. local bin=$1
  169. echo "Creating loop device..."
  170. local loop=$(losetup -f | tail -1)
  171. if [[ -z "$loop" ]]; then
  172. echo "No free loop device. Exiting..."
  173. exit 1
  174. else
  175. echo $loop
  176. fi
  177. echo "Setting up loop with $loop and $bin"
  178. losetup -P "$loop" "$bin"
  179. echo "Disabling kernel verity..."
  180. $SSD_UTIL --debug --remove_rootfs_verification -i ${loop} --partitions 4
  181. echo "Enabling RW mount..."
  182. $SSD_UTIL --debug --remove_rootfs_verification --no_resign_kernel -i ${loop} --partitions 2
  183. # for good measure
  184. sync
  185. echo "Mounting target..."
  186. mkdir /tmp/mnt || :
  187. mount "${loop}p3" /tmp/mnt
  188. ROOT=/tmp/mnt
  189. patch_root
  190. if [ "$bootsplash" != "cros" ]; then
  191. if [ "$bootsplash" != "0" ]; then
  192. echo "Adding custom bootsplash..."
  193. for i in $(seq -f "%02g" 0 30); do
  194. rm $ROOT/usr/share/chromeos-assets/images_100_percent/boot_splash_frame${i}.png
  195. done
  196. cp $bootsplash $ROOT/usr/share/chromeos-assets/images_100_percent/boot_splash_frame00.png
  197. else
  198. echo "Adding murkmod bootsplash..."
  199. install "chromeos-bootsplash-v2.png" /tmp/bootsplash.png
  200. for i in $(seq -f "%02g" 0 30); do
  201. rm $ROOT/usr/share/chromeos-assets/images_100_percent/boot_splash_frame${i}.png
  202. done
  203. cp /tmp/bootsplash.png $ROOT/usr/share/chromeos-assets/images_100_percent/boot_splash_frame00.png
  204. rm /tmp/bootsplash.png
  205. fi
  206. fi
  207. if [ "$unfuckstateful" == "0" ]; then
  208. touch $ROOT/stateful_unfucked
  209. chmod 777 $ROOT/stateful_unfucked
  210. # by creating the flag in advance we can prevent running mkfs.ext4 on stateful upon next boot, thus retaining user data
  211. fi
  212. sleep 2
  213. sync
  214. echo "Done. Have fun."
  215. umount "$ROOT"
  216. sync
  217. losetup -D "$loop"
  218. sync
  219. sleep 2
  220. rm -rf /tmp/mnt
  221. leave
  222. }
  223. if [ "$0" = "$BASH_SOURCE" ]; then
  224. stty sane
  225. if [ "$EUID" -ne 0 ]; then
  226. echo "Please run as root"
  227. exit
  228. fi
  229. main "$@"
  230. fi