From 3b63c55b884d73fff6517c2a74e86742dc54c7d2 Mon Sep 17 00:00:00 2001 From: Ian Skinner <56081713+IanSkinner1982@users.noreply.github.com> Date: Mon, 21 Aug 2023 04:14:33 -0400 Subject: [PATCH] --- extract-updater-rofs.sh | 58 +++++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/extract-updater-rofs.sh b/extract-updater-rofs.sh index 124a62a..a9b55c8 100644 --- a/extract-updater-rofs.sh +++ b/extract-updater-rofs.sh @@ -1,10 +1,43 @@ # extract-updater-rofs -# Extracts firmware CIAs from ROFS containers for some gigaleak SystemUpdaters. -# Place in same directory as an extracted "romfs.bin" OR "Contents.cnt" +# Extracts firmware CIAs from ROFS containers for some gigaleak SystemUpdaters. Will accept "Contents.cnt" and decrypted "romfs.bin" +# Usage: ./extract-updater-romfs (output directory) +################################################################################### +# Set input and output paths +################################################################################### +OUTPUT_DIR="extract-updater-romfs_output" +rm -r "extract-updater-romfs_output" +mkdir "extract-updater-romfs_output" +ERROR="0" +if [ "${1}" != "" ]; then + INPUT_FILE="${1}" + if [ "${2}" != "" ]; then + OUTPUT_DIR="${2}" + rm -r "${OUTPUT_DIR}" + rm -r "extract-updater-romfs_output" + mkdir "${OUTPUT_DIR}" + fi +else + echo "ERROR: No input files specified." + echo "" + echo "./extract-updater-rofs.sh (output dir)" + echo "" + echo "Note that if the output directory already exists, IT WILL BE DELETED" + ERROR=1 +fi + +################################################################################### +# CIA extraction +################################################################################### +if [ "$ERROR" == "0" ]; then echo "Finding CIA headers in file..." -od -t x -A d romfs.bin | grep "00002020 00000000 00000a00 00000350" | sed 's/ .*//' | sed 's/^0*//' > romfs-dir.txt +# od -t x -A d "${INPUT_FILE}" | grep "00002020 00000000 00000a00 00000350" | sed 's/ .*//' | sed 's/^0*//' > romfs-dir.txt # Get start address of every CIA header and store to file + +od -t x -A d "${INPUT_FILE}" | grep "00002020 00000000 00000000 00000378" | sed 's/ .*//' | sed 's/^0*//' > romfs-dir.txt +# Different header for leftover cnt in "ctr.7z/ctr/sources/firmware/CTR-Kernel/updater1st/UpdaterCardImage/Default/Contents_11_without_shareddate.cnt" +# I haven't seen this anywhere else so disable for everything but the above file. + echo "Found all headers!" echo "=================================================" @@ -24,7 +57,7 @@ do x=0 while [ "$y" = "00" ]; do x+=1 - y=$(od -j $((NEXT_HEADER - x)) -N 1 -x -A n romfs.bin | sed 's|[ ,]||g' | sed 's/^..//'); + y=$(od -j $((NEXT_HEADER - x)) -N 1 -x -A n "${INPUT_FILE}" | sed 's|[ ,]||g' | sed 's/^..//'); # Get bytes one backwards from next header # printf '%x\n' $((NEXT_HEADER - x)) # echo $y @@ -35,7 +68,7 @@ do echo "Padding from CIA $i to $((i + 1)) is $((x - 1)) bytes." echo " Extract CIA" CIA_LENGTH=$(((NEXT_HEADER - START_HEADER) - x + 1)) - dd skip=${START_HEADER} count=${CIA_LENGTH} if=romfs.bin of="$i.cia" bs=1 + dd skip=${START_HEADER} count=${CIA_LENGTH} if="${INPUT_FILE}" of="${OUTPUT_DIR}/$i.cia" bs=1 echo "CIA $i saved as '$i.cia'" echo "=================================================" i+=2 @@ -54,7 +87,7 @@ do x=0 while [ "$y" = "00" ]; do x+=1 - y=$(od -j $((NEXT_HEADER - x)) -N 1 -x -A n romfs.bin | sed 's|[ ,]||g' | sed 's/^..//'); + y=$(od -j $((NEXT_HEADER - x)) -N 1 -x -A n "${INPUT_FILE}" | sed 's|[ ,]||g' | sed 's/^..//'); # Get bytes one backwards from next header # printf '%x\n' $((NEXT_HEADER - x)) # echo $y @@ -65,7 +98,7 @@ do echo "Padding from CIA $i to $((i + 1)) is $((x - 1)) bytes." echo " Extract CIA" CIA_LENGTH=$(((NEXT_HEADER - START_HEADER) - x + 1)) - dd skip=${START_HEADER} count=${CIA_LENGTH} if=romfs.bin of="$i.cia" bs=1 + dd skip=${START_HEADER} count=${CIA_LENGTH} if="${INPUT_FILE}" of="${OUTPUT_DIR}/$i.cia" bs=1 echo "CIA $i output as '$i.cia', ${CIA_LENGTH} bytes." CIA_LENGTH="" echo "=================================================" @@ -73,9 +106,10 @@ do done START_HEADER=$( tail -n 1 romfs-dir.txt ) -NEXT_HEADER=$((16#$(xxd romfs.bin | grep "226e 6f6e 6522" | sed 's/: .*//' | sed 's/^0*//'))); +NEXT_HEADER=$((16#$(xxd "${INPUT_FILE}" | grep "226e 6f6e 6522" | sed 's/: .*//' | sed 's/^0*//'))); # Find "226e 6f6e 6522" as it is the last predictable data to mark the end of Contents.cnt and the last CIA. # Upsettingly I have to use xxd because od wouldn't turn up any results for this... I liked od's formatting more :despair: + if [ $NEXT_HEADER != "" ]; then echo " Check CIA length" echo "Final CIA header at ${START_HEADER}" @@ -86,7 +120,7 @@ if [ $NEXT_HEADER != "" ]; then # Start x as 16 to skip changing data and go right to padding while [ "$y" = "00" ]; do x+=1 - y=$(od -j $((NEXT_HEADER - x)) -N 1 -x -A n romfs.bin | sed 's|[ ,]||g' | sed 's/^..//'); + y=$(od -j $((NEXT_HEADER - x)) -N 1 -x -A n "${INPUT_FILE}" | sed 's|[ ,]||g' | sed 's/^..//'); # Get bytes one backwards from next header # printf '%x\n' $((NEXT_HEADER - x)) # echo $y @@ -97,9 +131,11 @@ if [ $NEXT_HEADER != "" ]; then echo "Padding from final CIA to Content.cnt end is $((x - 1)) bytes." echo " Extract CIA" CIA_LENGTH=$(((NEXT_HEADER - START_HEADER) - x + 1)) - dd skip=${START_HEADER} count=${CIA_LENGTH} if=romfs.bin of="0.cia" bs=1 + dd skip=${START_HEADER} count=${CIA_LENGTH} if="${INPUT_FILE}" of="${OUTPUT_DIR}/0.cia" bs=1 echo "Final CIA output as '0.cia', ${CIA_LENGTH} bytes." echo "=================================================" echo "All CIAs extracted from RomFS!" else - echo "Could not find end of last CIA! For extracting manually, start address is ${START_HEADER} (decimal)" \ No newline at end of file + echo "Could not find end of last CIA! For extracting manually, start address is ${START_HEADER} (decimal)" +fi +fi \ No newline at end of file