diff --git a/extract-gigaleak-csu.sh b/extract-gigaleak-csu.sh index 9b11ab6..40f8345 100644 --- a/extract-gigaleak-csu.sh +++ b/extract-gigaleak-csu.sh @@ -1,6 +1,4 @@ # extract-gigaleak-csu -# Lillian Skinner -# Last modified 2023/08/19 # Extracts firmware CIAs from the RomFS of "SystemUpdater-0_13-0927-UnFixedKey.csu". This can't be done with other tools as 0.13.0 doesn't use the normal RomFS format. echo "Finding CIA headers in file..." @@ -23,7 +21,6 @@ do echo "Finding CIA $i end from CIA $((i + 1)) header... " y="00" x=0 - z="00" while [ "$y" = "00" ]; do x+=1 y=$(od -j $((NEXT_HEADER - x)) -N 1 -x -A n romfs.bin | sed 's|[ ,]||g' | sed 's/^..//'); @@ -35,7 +32,7 @@ do echo "End found!" echo "Non-zerobyte ($y) at $((NEXT_HEADER - x))" echo "Padding from CIA $i to $((i + 1)) is $((x - 1)) bytes." - echo " Extract CIA:" + 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 echo "CIA $i saved as '$i.cia'" @@ -43,6 +40,7 @@ do i+=2 done < romfs-dir.txt +i=2 echo "Extracting even CIAs..." echo "=================================================" sed 1d romfs-dir.txt | while IFS=, read -r START_HEADER; read NEXT_HEADER @@ -53,7 +51,6 @@ do echo "Finding CIA $i end from CIA $((i + 1)) header... " y="00" x=0 - z="00" while [ "$y" = "00" ]; do x+=1 y=$(od -j $((NEXT_HEADER - x)) -N 1 -x -A n romfs.bin | sed 's|[ ,]||g' | sed 's/^..//'); @@ -65,12 +62,41 @@ do echo "End found!" echo "Non-zerobyte ($y) at $((NEXT_HEADER - x))" echo "Padding from CIA $i to $((i + 1)) is $((x - 1)) bytes." - echo " Extract CIA:" + echo " Extract CIA" CIA_LENGTH=$(((NEXT_HEADER - START_HEADER) - x + 1)) - CIA_NUMBER+=1 dd skip=${START_HEADER} count=${CIA_LENGTH} if=romfs.bin of="$i.cia" bs=1 echo "CIA $i output as '$i.cia', ${CIA_LENGTH} bytes." CIA_LENGTH="" echo "=================================================" i+=2 done + +i=$((i - 1)) +START_HEADER=$( tail -n 1 romfs-dir.txt ) +NEXT_HEADER=$(xxd romfs.bin | 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: +echo " Check CIA length" +echo "CIA $i header at ${START_HEADER}" +echo "Contents.cnt end at ${NEXT_HEADER}" +echo "Finding end of CIA $i from Contents.cnt end..." +y="00" +x=16 +# 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/^..//'); + # Get bytes one backwards from next header + # printf '%x\n' $((NEXT_HEADER - x)) + # echo $y + # echo $x +done +echo "End found!" +echo "Non-zerobyte ($y) at $((NEXT_HEADER - x))" +echo "Padding from CIA $i 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="$i.cia" bs=1 +echo "CIA $i output as '$i.cia', ${CIA_LENGTH} bytes." +echo "=================================================" +echo "All CIAs extracted from RomFS!"