mirror of
https://gist.github.com/3793a40dd0c7930f12b79ca1931a3296.git
synced 2025-10-31 13:51:11 -04:00
103 lines
3.9 KiB
Bash
103 lines
3.9 KiB
Bash
# extract-updater-rofs
|
|
# Extracts firmware CIAs from ROFS containers for some gigaleak SystemUpdaters.
|
|
|
|
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
|
|
# Get start address of every CIA header and store to file
|
|
echo "Found all headers!"
|
|
echo "================================================="
|
|
|
|
declare -i x=0
|
|
declare -i i=1
|
|
declare -i z=1
|
|
|
|
echo "Extracting odd CIAs..."
|
|
echo "================================================="
|
|
sed 1d romfs-dir.txt | while IFS=, read -r START_HEADER; read NEXT_HEADER
|
|
do
|
|
echo " Check CIA length"
|
|
echo "CIA $i header at ${START_HEADER}"
|
|
echo "Next header at ${NEXT_HEADER}"
|
|
echo "Finding CIA $i end from CIA $((i + 1)) header... "
|
|
y="00"
|
|
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/^..//');
|
|
# 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 $((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
|
|
echo "CIA $i saved as '$i.cia'"
|
|
echo "================================================="
|
|
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
|
|
do
|
|
echo " Check CIA length"
|
|
echo "CIA $i header at ${START_HEADER}"
|
|
echo "Next header at ${NEXT_HEADER}"
|
|
echo "Finding CIA $i end from CIA $((i + 1)) header... "
|
|
y="00"
|
|
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/^..//');
|
|
# 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 $((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
|
|
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!"
|