This commit is contained in:
Ian Skinner 2023-08-20 20:55:48 -04:00 committed by GitHub
parent 83aadd766a
commit ef37aa6d64

View File

@ -1,6 +1,6 @@
# extract-updater-rofs
# Extracts firmware CIAs from ROFS containers for some gigaleak SystemUpdaters.
# Place in same directory as ROFS named "romfs.bin"
# Place in same directory as an extracted "romfs.bin" OR "Contents.cnt"
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
@ -76,27 +76,30 @@ START_HEADER=$( tail -n 1 romfs-dir.txt )
NEXT_HEADER=$((16#$(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 "Final CIA header at ${START_HEADER}"
echo "Contents.cnt end at ${NEXT_HEADER}"
echo "Finding end of final CIA 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 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
echo "Final CIA output as '0.cia', ${CIA_LENGTH} bytes."
echo "================================================="
echo "All CIAs extracted from RomFS!"
if [ $NEXT_HEADER != "" ]; then
echo " Check CIA length"
echo "Final CIA header at ${START_HEADER}"
echo "Contents.cnt end at ${NEXT_HEADER}"
echo "Finding end of final CIA 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 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
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)"