From 0728239f7b10bc1332b06228834e0ec4f6e76a42 Mon Sep 17 00:00:00 2001 From: StarlitSkies <40963841+StarlitSkies@users.noreply.github.com> Date: Sat, 28 Sep 2024 16:57:39 -0700 Subject: [PATCH] Initial commit --- 3DS/MovableMoveover.gm9 | 176 ++++++++++++ 3DS/README.md | 26 ++ 3DS/ctrcheck.gm9 | 618 ++++++++++++++++++++++++++++++++++++++++ 3DS/manual_transfer.gm9 | 187 ++++++++++++ License.txt | 21 ++ README.md | 11 + 6 files changed, 1039 insertions(+) create mode 100644 3DS/MovableMoveover.gm9 create mode 100644 3DS/README.md create mode 100644 3DS/ctrcheck.gm9 create mode 100644 3DS/manual_transfer.gm9 create mode 100644 License.txt create mode 100644 README.md diff --git a/3DS/MovableMoveover.gm9 b/3DS/MovableMoveover.gm9 new file mode 100644 index 0000000..40f94ef --- /dev/null +++ b/3DS/MovableMoveover.gm9 @@ -0,0 +1,176 @@ +# Movable Moveover script, now with less manual +# Powered by FixupMovable TM technology https://github.com/fox8091/FixupMovable +# For use in https://wiki.hacks.guide/wiki/3DS:Movable_Moveover +# Last edited: 2024-9-24 +# Version: 1.3 +# Script by: ItsCrocoSwine +if keychk SELECT #Hold Select to keep preview mode on, with fun colors! + set PREVIEW_COLOR_COMMENT 32CD32 #Lime green + set PREVIEW_COLOR_ACTIVE 5D3FD3 #Iris + set PREVIEW_COLOR_CODE E37383 #Watermelon pink +else + set PREVIEW_MODE "Movable Moveover\nVersion: 1.3" +end + +ask "This script will do the following:\n- Create an essential files backup\n- Fixup a provided movable.sed\n- Copy fixed movable to CTRNAND\n \nIf you are ok with this\npress (A) to continue." + +set MMMPATH 0:/gm9/out/MMM #Working path +set OUTPATH 0:/gm9/out/MMM_Backup #Path for backuping up files +rm -o -s $[MMMPATH] +mkdir -o -s $[MMMPATH] +mkdir -o -s $[OUTPATH] + +#Find source movable +#Select a file +@FILE_SELECT +filesel -x "Select your movable.sed or essential.exefs:" 0:/* SOURCE_FILE +strsplit SOURCE_FILENAME $[SOURCE_FILE] / + +#Check if its at least a .sed .exefs or .bin +if not strsplit SOURCE_FILE_EXT $[SOURCE_FILE] . + if chk $[SOURCE_FILENAME] movable #reject no file extension, unless its exactly "movable" + cp -w $[SOURCE_FILE] $[MMMPATH]/sourcemovable.sed + else + ask "Error: '$[SOURCE_FILENAME]' is\nnot a valid input file.\n \nPlease select a movable.sed, essential.exefs,\nor sysnand.bin from the source console." + goto FILE_SELECT + end +elif chk $[SOURCE_FILE_EXT] sed + cp -w $[SOURCE_FILE] $[MMMPATH]/sourcemovable.sed +elif chk $[SOURCE_FILE_EXT] exefs + fdummy -o -s $[MMMPATH]/sourcemovable.sed 140 + inject $[SOURCE_FILE]@600:140 $[MMMPATH]/sourcemovable.sed +elif chk $[SOURCE_FILE_EXT] bin + fdummy -o -s $[MMMPATH]/sourcemovable.sed 140 + inject $[SOURCE_FILE]@800:140 $[MMMPATH]/sourcemovable.sed +else + ask "Error: '$[SOURCE_FILENAME]' is\nnot a valid input file.\n \nPlease select a movable.sed, essential.exefs,\nor sysnand.bin from the source console." + goto FILE_SELECT +end + +#verify file integrity +fget $[MMMPATH]/sourcemovable.sed@0:4 SM_SEED +fget $[MMMPATH]/sourcemovable.sed@8:10 SM_BFMCHECK +if not shaget $[MMMPATH]/sourcemovable.sed@8:118 SM_SHA + echo "Source movable.sed is invalid:\nmovable is unreadable" + poweroff +elif chk -u $[SM_SEED] "53454544" + echo "Source movable.sed is invalid:\nSEED is missing or corrupt\n \n(Is this even a movable?)" + poweroff +elif chk $[SM_BFMCHECK] "00000000000000000000000000000000" + echo "Source movable.sed is invalid:\nmovable is from seedminer" + poweroff +end + +if find 1:/private/movable.sed NULL + fget 1:/private/movable.sed@0:4 PM_SEED + fget 1:/private/movable.sed@5:1 PM_CMAC + fget 1:/private/movable.sed@8:10 PM_BFMCHECK + if not shaget 1:/private/movable.sed@8:118 PM_SHA + echo "1:/private/movable.sed is unreadable\n \nAsk for help on Discord:\nhttps://discord.gg/MWxPgEp" + poweroff + elif chk -u $[PM_SEED] "53454544" + echo "1:/private/movable.sed is invalid:\nSEED is missing or corrupt\n \nAsk for help on Discord:\nhttps://discord.gg/MWxPgEp" + poweroff + elif chk $[PM_BFMCHECK] "00000000000000000000000000000000" + echo "1:/private/movable.sed is invalid:\nmovable is from seedminer\n \nAsk for help on Discord:\nhttps://discord.gg/MWxPgEp" + poweroff + end +else + echo "1:/private/movable.sed is missing\n \nAsk for help on Discord:\nhttps://discord.gg/MWxPgEp" + poweroff +end + +if find S:/essential.exefs NULL + if not shaget S:/essential.exefs@0:100 NULL + echo "S:/essential.exefs is unreadable\n \nAsk for help on Discord:\nhttps://discord.gg/MWxPgEp" + poweroff + end +else + echo "S:/essential.exefs is missing\n \nAsk for help on Discord:\nhttps://discord.gg/MWxPgEp" + poweroff +end + +#Compare source and private movable. If both are the same determine if FixupMovable is required. +if chk $[SM_SHA] $[PM_SHA] + if chk $[PM_CMAC] 00 + echo "Error: Source movable is the same as in NAND\nFixupMovable is not required.\n \nIf you are trying to do a\nMovable Moveover then you chose\nthe wrong essential.exefs or movable.sed" + poweroff + else + if not ask "Information: Source movable is the same as in NAND\nWould you like to run FixupMovable?\n \nNote: This is NOT a normal Movable Moveover\nand will NOT change your encryption key.\nIf you are not trying to fixup\na previous moveover, press (B) to cancel.\n \n Otherwise press (A) to continue." + echo "Script canceled\n \nPress (A) to power off." + rm -o -s $[MMMPATH] + poweroff + end + end +end + +#Calculate and check for existence of ID0 for source movable +#Write sha file for KeyY +shaget $[MMMPATH]/sourcemovable.sed@110:10 $[MMMPATH]/KeyY.sha + +#Get ID0 parts, reorder bytes, and combine +fget -e $[MMMPATH]/KeyY.sha@0:4 ID0part1 +fget -e $[MMMPATH]/KeyY.sha@4:4 ID0part2 +fget -e $[MMMPATH]/KeyY.sha@8:4 ID0part3 +fget -e $[MMMPATH]/KeyY.sha@C:4 ID0part4 +set SM_ID0 $[ID0part1]$[ID0part2]$[ID0part3]$[ID0part4] + +#Check for ID0 directory +if not isdir "0:/Nintendo 3DS/$[SM_ID0]" + echo "Error: ID0 of source movable.sed does not\nmatch any ID0 on the SD card.\n \nSource file: $[SOURCE_FILENAME]\nDetected ID0: $[SM_ID0]\n \nPlease make sure the Nintendo 3DS folder you\nare trying to transfer is on the SD card\nand you are choosing the correct movable." + rm -o -s $[MMMPATH] + poweroff +end + +#Backup movable/essential files +findnot $[OUTPATH]/$[DATESTAMP]_$[SERIAL]_movable_??.sed MOVABLEOUT +if not cp 1:/private/movable.sed $[MOVABLEOUT] + echo "Failed backing up movable.sed\n(How did this happen?)\n \nAsk for help on Discord:\nhttps://discord.gg/MWxPgEp" + poweroff +end + +findnot $[OUTPATH]/$[DATESTAMP]_$[SERIAL]_essential_??.exefs ESSENTIALOUT +if not cp S:/essential.exefs $[ESSENTIALOUT] + echo "Failed backing up essential.exefs\n(How did this happen?)\n \nAsk for help on Discord:\nhttps://discord.gg/MWxPgEp" + poweroff +end + +#FixupMovable +fdummy -o -s $[MMMPATH]/fixupmovable.sed 120 +inject $[MMMPATH]/sourcemovable.sed@0:120 $[MMMPATH]/fixupmovable.sed@0 +fill $[MMMPATH]/fixupmovable.sed@4:4 00 + +#Verify fixed up movable +#The FixupMovable section would have had to fail without throwing an exception for anything here to actually fail, but might as well be sure. +fget $[MMMPATH]/fixupmovable.sed@0:4 FM_SEED +fget $[MMMPATH]/fixupmovable.sed@4:4 FM_CMAC +if not shaget $[MMMPATH]/fixupmovable.sed@8:118 FM_SHA + echo "FixupMovable error:\nmovable is unreadable\n(How did this happen?)\n \nAsk for help on Discord:\nhttps://discord.gg/MWxPgEp" + poweroff +elif chk -u $[SM_SEED] "53454544" + echo "FixupMovable error:\nSEED is missing or corrupt\n(How did this happen?)\n \nAsk for help on Discord:\nhttps://discord.gg/MWxPgEp" + poweroff +elif chk -u $[FM_CMAC] "00000000" + echo "FixupMovable error:\nCMAC flag has not been set properly\n(How did this happen?)\n \nAsk for help on Discord:\nhttps://discord.gg/MWxPgEp" + poweroff +elif chk -u $[SM_SHA] $[FM_SHA] + echo "FixupMovable error:\nLFCS or KeyY has been changed\n(How did this happen?)\n \nAsk for help on Discord:\nhttps://discord.gg/MWxPgEp" +end + +#Copy movable +if ask "Ready to perform the Moveover.\nSource file: $[SOURCE_FILENAME]\nDetected ID0: $[SM_ID0]\n \nUnlock permissions to continue." + allow 1:/private/movable.sed + cp -w $[MMMPATH]/fixupmovable.sed 1:/private/movable.sed + fixcmac 1:/dbs + fixcmac 1:/data +else + echo "Script canceled\n \nPress (A) to power off." + rm -o -s $[MMMPATH] + poweroff +end + +#Cleanup +rm -o -s $[MMMPATH] +rm -o -s $[CURRDIR]/MovableMoveover.gm9 +echo "Movable Moveover complete!\nYour new ID0 is: $[SM_ID0]\n \nYour backup essential files can be\nfound at: $[OUTPATH]\n \nPress (A) to reboot." +reboot \ No newline at end of file diff --git a/3DS/README.md b/3DS/README.md new file mode 100644 index 0000000..27e2f9d --- /dev/null +++ b/3DS/README.md @@ -0,0 +1,26 @@ +# 3DS Scripts + +Various scripts used for recovery and system maintenance by [Nintendo Homebrew on Discord](https://discord.gg/C29hYvh). + +# Usage + +For instructions on how to use these scripts, open the links to their info pages on the [Hacks Guide Wiki](https://wiki.hacks.guide/wiki/Main_Page). + +## ctrcheck + +[ctrcheck.gm9](https://wiki.hacks.guide/wiki/3DS:Ctrcheck) is a general system maintenance and recovery tool, meant to be used in initial troubleshooting. + +## Manual Transfer + +[manual_transfer.gm9](https://wiki.hacks.guide/wiki/3DS:CTRTransfer/Manual) is the script used as part of a manual CTRTransfer. + +## Movable Moveover + +[MovableMoveover.gm9](https://wiki.hacks.guide/wiki/3DS:Movable_Moveover) is the script used as part of a Movable Moveover, which is effectively a manual System Transfer. + +# Credits + +* [FrozenChen](https://github.com/FrozenChen): Original creator of ctrcheck. +* [fox8091](https://github.com/fox8091) and AnalogMan: Original creators of manual_transfer. +* [ItsCrocoSwine](https://github.com/ItsCrocoSwine): Creator of MovableMoveover. +* [StarlitSkies](https://github.com/StarlitSkies): Current maintainer of ctrcheck and manual_transfer. \ No newline at end of file diff --git a/3DS/ctrcheck.gm9 b/3DS/ctrcheck.gm9 new file mode 100644 index 0000000..87daed7 --- /dev/null +++ b/3DS/ctrcheck.gm9 @@ -0,0 +1,618 @@ +# A script for checking all of a 3DS console's important files and their integrity. +# original script by FrozenFire +# overhaul, fixes, and current maintenance by StarlitSkies +# last modified: 2024-09-28 +# version: 3.1.1 +# if you didn't get this file from https://gist.github.com/StarlitSkies/f417c1ded9de8fceffdb532f92823377/, go there and make sure this copy wasn't tampered with + +# latest changelog: +# make message for detecting too many FIRMs more accurate + +@cleanup +set FULL "0" + +set NANDSECTORS_LOG "" +set ESSENTIALS_LOG "" +set CTRNAND_LOG "" +set TWLNAND_LOG "" +set FIRM_LOG "" +set SD_LOG "" +set RAM_LOG "" +set LOG "disabled" + +@menu +labelsel -o -s "Select which parts of the system to check.\nConsole is a $[REGION] $[RDTYPE] $[ONTYPE] using $[HAX].\nCurrent id0 is $[SYSID0].\n\nPermanent logging: $[LOG]" check_* +goto menu + +@check_All +set FULL "1" +goto NAND_Header + +@check_NAND_Only +goto NAND_Header + +@check_SD_Only +goto SD_Files + +@NAND_Header +# check whether NAND header signature is sighax, based on hashes +# sighax will always be read as valid by boot9 even without cfw, so it's just used to check whether custom partitions should be possible +set SIGHAX "0" +if find S:/nand_hdr.bin NULL + if not shaget S:/nand_hdr.bin@0:200 NULL + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Error: NAND header is an invalid size.\n" + goto NAND_Sectors + end +else + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Error: NAND header not found.\n" + goto NAND_Sectors +end + +if sha S:/nand_hdr.bin@0:100 A4AE99B93412E4643E4686987B6CFD59701D5C655CA2FF671CE680B4DDCF0948 + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Information: NAND header's signature is sighax.\n" + set SIGHAX "1" +end + +# hash-based check of NAND header partition table against retail partition tables +if sha S:/nand_hdr.bin@100:60 dfd434b883874d8b585a102f3cf3ae4cef06767801db515fdf694a7e7cd98bc2 + if chk $[ONTYPE] "N3DS" + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Information: NAND header is stock. (n3DS)\n" + else + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Critical: o3DS has an n3DS NAND header.\n" + end +elif sha S:/nand_hdr.bin@100:60 ae9b6645105f3aec22c2e3ee247715ab302874fca283343c731ca43ea1baa25d + if chk $[ONTYPE] "O3DS" + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Information: NAND header is stock. (o3DS)\n" + else + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Critical: n3DS has an o3DS NAND header.\n" + end +else + fget S:/nand_hdr.bin@100:4 NCSD + #check for the NCSD magic header, if it's not present then there's definitely something wrong + if chk $[NCSD] "4E435344" + if chk $[SIGHAX] "1" + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Warning: NAND partition table is modified, but there is sighax in the NAND header.\n" + else + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Error: NAND partition table is modified, and there is no sighax in the NAND header.\n" + end + else + # your NAND has a minor case of serious brain damage + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Error: NAND header data is invalid. You've met with a terrible fate, haven't you?\n" + end +end + +@NAND_Sectors +# verify Secret Sector, which is doubly important for N3DSes +if chk $[ONTYPE] "N3DS" + if not sha S:/sector0x96.bin 82F2730D2C2DA3F30165F987FDCCAC5CBAB24B4E5F65C981CD7BE6F438E6D9D3 + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Warning: Secret Sector data is invalid. a9lh might be installed.\n" + end +else + if fget S:/nand.bin@12C00:2 SBYTE + if chk -u $[SBYTE] "0000" + if chk -u $[SBYTE] "FFFF" + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Warning: There may be a9lh leftovers in the secret sector.\n" + end + end + else + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Critical: NAND is unreadable at offset 0x12C00...?\n" + end +end + +# verify the TWL MBR exists and is retail (there is no good reason this should ever be modified) +if find S:/twlmbr.bin NULL + if not sha S:/twlmbr.bin 77a98e31f1ff7ec4ef2bfacca5a114a49a70dcf8f1dcd23e7a486973cfd06617 + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Critical: TWL MBR data is invalid.\n" + end +else + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Critical: TWL MBR not found.\n" +end + +# get first byte in stage2 location +if not fget S:/nand.bin@B800000:1 ABYTE + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Critical: NAND is unreadable at offset 0xB800000...?\n" +end +# instead of checking the full sector against multiple stage2s, this just checks if the sector is "clean" +# (if first byte is not "clean" assume stage2 is there, can be done in a better way) +# if stage2 was replaced with trash it would trigger this warning tho +if chk -u $[ABYTE] "00" + if chk -u $[ABYTE] "FF" + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Warning: There are likely leftovers from a9lh's stage2 payload.\n" + end +end + +# check for presence of bonus drive, just because it might come in handy to know sometimes +if isdir 8: + set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Information: Bonus drive is enabled.\n" +end + + +@CTRNAND +# check if CTRNAND can be accessed, skip all CTRNAND checks if it isn't +if not isdir 1: + set CTRNAND_LOG "$[CTRNAND_LOG]Error: CTRNAND not found.\n" + goto TWLNAND +end + +# find movable.sed, check if it's valid, and check whether CMAC is set correctly based on size (288 bytes vs 320 bytes) +set MLFCSHASH "" +if not find 1:/private/movable.sed movable + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Critical: movable.sed not found.\n" + goto LFCS +end +if shaget $[movable]@0:100 NULL + fget $[movable]@8:10 ISVALID + if chk $[ISVALID] "00000000000000000000000000000000" + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Warning: movable.sed's copy of LFCS is blank.\n" + end +else + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Critical: movable.sed is an invalid size.\n" + goto LFCS +end +fget $[movable]@0:4 SEED +fget $[movable]@5:1 CMAC +shaget $[movable]@8:110 MLFCSHASH +#check if movable.sed at least has the SEED magic header, then check whether CMAC is set correctly based on size (320 vs 288 bytes) +if chk -u $[SEED] "53454544" + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Critical: movable.sed data is invalid.\n" +elif chk $[CMAC] "01" + if not fget $[movable]@120:1 NULL + if ask "movable.sed is misconfigured.\nPress (A) to reconfigure it to normal values." + fset $[movable]@5 00 + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Information: movable.sed has been fixed by removing the CMAC flag.\n" + else + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Critical: movable.sed is 288 bytes but has the CMAC flag.\n" + end + end +end + +@LFCS +# find LFCS, check if it's valid, check if it's the same as movable.sed's copy of LFCS, and check against OTP seed that's used to make part of LFCS +# account for both potential filenames of LocalFriendCodeSeed +if find 1:/rw/sys/LocalFriendCodeSeed_B LFCS +elif find 1:/rw/sys/LocalFriendCodeSeed_A LFCS +else + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Critical: LFCS not found.\n" + goto SecureInfo +end +if shaget $[LFCS]@0:100 NULL + fget $[LFCS]@0:10 ISVALID + if chk $[ISVALID] "00000000000000000000000000000000" + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Critical: LFCS data is invalid.\n" + goto SecureInfo + end +else + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Critical: LFCS is an invalid size.\n" + goto SecureInfo +end +shaget $[LFCS]@0:110 LFCSHASH +# compare the LFCS in movable.sed to the raw LFCS file, if movable.sed exists +if chk -u $[MLFCSHASH] "" + if chk -u $[MLFCSHASH] $[LFCSHASH] + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Information: LFCS doesn't match movable.sed.\n" + end +end +if find M:/otp_dec.mem OTP + fget $[LFCS]@108:8 LFCSEED + fget $[OTP]@8:8 OTPSEED + if chk -u $[LFCSEED] $[OTPSEED] + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Warning: Console is using a donor LFCS.\n" + end +end + +@SecureInfo +# find secureinfo_(a/b) and check if it's valid +set SECVALID "0" +if find 1:/rw/sys/SecureInfo_A SEC +elif find 1:/rw/sys/SecureInfo_B SEC +else + if find 1:/rw/sys/SecureInfo_C ALTSEC + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Warning: SecureInfo not found, but SecureInfo_C exists.\n" + else + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Critical: SecureInfo not found.\n" + end + goto HWCAL0 +end +if not find -s 1:/rw/sys/SecureInfo_C ALTSEC + set ALTSEC "" +end +if not shaget $[SEC]@0:110 NULL + if shaget $[ALTSEC]@0:110 NULL + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Warning: SecureInfo is an invalid size, but SecureInfo_C exists and is valid.\n" + else + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Critical: SecureInfo is an invalid size.\n" + end + goto HWCAL0 +end +# the checks here are done against the end of the file since that part contains the serial; the RSA signature isn't important for troubleshooting purposes +fget $[SEC]@100:10 ISVALID +if chk $[ISVALID] "00000000000000000000000000000000" + if chk $[ALTSEC] "" + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Critical: SecureInfo data is invalid, and there is no SecureInfo_C.\n" + else + fget $[ALTSEC]@100:10 ISVALID + if chk $[ISVALID] "00000000000000000000000000000000" + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Critical: SecureInfo and SecureInfo_C data are both invalid.\n" + else + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Warning: SecureInfo data is invalid, but SecureInfo_C exists and is valid.\n" + end + end + goto HWCAL0 +else + set SECVALID "1" + fget $[SEC]@10C:1 SECSERIALCHECK + if chk $[SECSERIALCHECK] "00" + fget $[SEC]@102:0A SECSERIAL + else + fget $[SEC]@102:0B SECSERIAL + end +end + +# then check if it matches the console region, check for region change (presence of secureinfo_c), and use that for both data comparison and to see what region was changed to +if chk -u $[ALTSEC] "" + set REGCHG "1" + fget $[ALTSEC]@100:1 ALTREGSEC + if chk $[ALTREGSEC] "00" + set ALTREG "JPN" + elif chk $[ALTREGSEC] "01" + set ALTREG "USA" + elif chk $[ALTREGSEC] "02" + set ALTREG "EUR" + elif chk $[ALTREGSEC] "04" + set ALTREG "CHN" + elif chk $[ALTREGSEC] "05" + set ALTREG "KOR" + elif chk $[ALTREGSEC] "06" + set ALTREG "TWN" + end +else + set REGCHG "0" +end +fget $[SEC]@100:1 REGSEC +if chk $[REGSEC] "00" + set REG "JPN" +elif chk $[REGSEC] "01" + set REG "USA" +elif chk $[REGSEC] "02" + set REG "EUR" +elif chk $[REGSEC] "04" + set REG "CHN" +elif chk $[REGSEC] "05" + set REG "KOR" +elif chk $[REGSEC] "06" + set REG "TWN" +end +if chk -u $[REG] $[REGION] + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Warning: SecureInfo doesn't match the console's region.\n" +end +if chk $[REGCHG] "1" + if chk -u $[ALTREG] $[REGION] + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Information: Console's region is changed from $[REG] to $[ALTREG].\n" + else + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Information: SecureInfo_C exists, but console's region is unchanged.\n" + end +end + +@HWCAL0 +# check whether first HWCAL exists +if find 1:/ro/sys/HWCAL0.dat HWCAL0 + if not shaget $[HWCAL0]@0:900 NULL + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Critical: HWCAL0 is an invalid size.\n" + goto HWCAL1 + end +else + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Critical: HWCAL0 not found.\n" + goto HWCAL1 +end +# if it's valid, check if it has the CCAL magic header +fget $[HWCAL0]@0:4 CCAL +if chk -u $[CCAL] "4343414C" + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Critical: HWCAL0 data is invalid.\n" +end + +@HWCAL1 +# check whether second HWCAL exists +if find 1:/ro/sys/HWCAL1.dat HWCAL1 + if not shaget $[HWCAL1]@0:900 NULL + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Critical: HWCAL1 is an invalid size.\n" + goto Misc_CTRNAND + end +else + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Critical: HWCAL1 not found.\n" + goto Misc_CTRNAND +end +# if it's valid, check if it has the CCAL magic header +fget $[HWCAL1]@0:4 CCAL +if chk -u $[CCAL] "4343414C" + set ESSENTIALS_LOG "$[ESSENTIALS_LOG]Critical: HWCAL1 data is invalid.\n" +end + +@Misc_CTRNAND +# check whether system can boot without SD card +if find 1:/boot.firm NULL + if find 1:/rw/luma/payloads/GodMode9.firm NULL + set CTRNAND_LOG "$[CTRNAND_LOG]Information: GodMode9 and Luma3DS are in the NAND.\n" + else + set CTRNAND_LOG "$[CTRNAND_LOG]Information: Luma3DS is in the NAND, but GodMode9 isn't.\n" + end +else + set CTRNAND_LOG "$[CTRNAND_LOG]Warning: Luma3DS is not in the NAND.\n" +end + +# check whether nand title database exists +if find 1:/dbs/title.db NANDTITLEDB + if shaget $[NANDTITLEDB]@0:400 NULL + fget $[NANDTITLEDB]@100:4 DIFF + # check whether nand title.db has the DIFF magic header + if chk -u $[DIFF] "44494646" + set CTRNAND_LOG "$[CTRNAND_LOG]Critical: CTRNAND title.db data is invalid.\n" + end + else + set CTRNAND_LOG "$[CTRNAND_LOG]Critical: CTRNAND title.db is an invalid size.\n" + end +else + set CTRNAND_LOG "$[CTRNAND_LOG]Critical: CTRNAND title.db not found.\n" +end + +@TWLNAND +#check if TWLNAND can be accessed +if not isdir 2: + set TWLNAND_LOG "$[TWLNAND_LOG]Error: TWLNAND not found.\n" + goto TWLP +end +# the console won't boot if shared2 doesn't exist, but remaking it is easy and harmless +if not isdir 2:/shared2 + if ask "A folder required to boot is missing. Press (A) to fix this issue." + mkdir 2:/shared2 + set TWLNAND_LOG "$[TWLNAND_LOG]Information: shared2 has been recreated.\n" + else + set TWLNAND_LOG "$[TWLNAND_LOG]Critical: shared2 not found.\n" + end +end +# check for inspect.log, and if it exists, compare its copy of the serial number against SecureInfo +if isdir 2:/sys/log + if find 2:/sys/log/inspect.log INSPECTLOG + if chk $[SECVALID] "1" + fget $[INSPECTLOG]@77:1 TWLNSERIALCHECK + if chk $[TWLNSERIALCHECK] "0a" + fget $[INSPECTLOG]@6D:0A TWLNSERIAL + else + fget $[INSPECTLOG]@6D:0B TWLNSERIAL + end + if chk -u $[SECSERIAL] $[TWLNSERIAL] + set TWLNAND_LOG "$[TWLNAND_LOG]Warning: inspect.log serial does not match SecureInfo.\n" + end + end + else + set TWLNAND_LOG "$[TWLNAND_LOG]Warning: inspect.log not found.\n" + end +else + set TWLNAND_LOG "$[TWLNAND_LOG]Warning: 2:/sys/log folder not found, meaning inspect.log also not found.\n" +end + +@TWLP +# you don't need TWLP to boot (or for a lot of things, really), but it's still good to check everything's in place +if not isdir 3: + set TWLNAND_LOG "$[TWLNAND_LOG]Warning: TWLP not found.\n" +end + +@FIRM_Data +# basic checks for how many FIRM partitions exist and which ones they are +set FIRMEXIST "0" +set ALTFIRMEXIST "0" +set BONUSFIRMS "0" +set TOOMANYFIRMS "0" +if find S:/firm0.bin NULL + set FIRMEXIST "1" +end +if find S:/firm1.bin NULL + set ALTFIRMEXIST "1" +end +if find S:/firm2.bin NULL + set BONUSFIRMS "1" +end +if find S:/firm5.bin NULL + set TOOMANYFIRMS "1" +end +if chk $[FIRMEXIST] "0" + if chk $[ALTFIRMEXIST] "0" + set FIRM_LOG "$[FIRM_LOG]Error: FIRM0 and FIRM1 both not found. Unless you have access to ntrboot, do NOT power off the console until you've fixed this.\n" + goto NAND_End + else + set FIRM_LOG "$[FIRM_LOG]Bruh Moment: FIRM0 not found, but FIRM1 exists. This shouldn't be possible, the console's probably having a stroke.\n" + end +else + if chk $[ALTFIRMEXIST] "0" + set FIRM_LOG "$[FIRM_LOG]Critical: FIRM1 not found, but FIRM0 exists. The console isn't dead yet, but fix this ASAP.\n" + end +end +if chk $[BONUSFIRMS] "1" + if chk $[TOOMANYFIRMS] "1" + set FIRM_LOG "$[FIRM_LOG]Bruh Moment: ...Why are there more than 5 FIRM partitions? I hope you only sacrificed the AGBSAVE.\n" + else + set FIRM_LOG "$[FIRM_LOG]Information: Extra FIRM partitions detected. But hey, rules were meant to be broken, right?\n" + end +end + +# compare firm slots against the hashes of all payloads we could reasonably expect +# todo: add hashes for new b9s/fb3ds versions as they're released +for S: firm*.bin + strsplit FIRM $[FORPATH] "/" + strsplit -b FIRM $[FIRM] "." + # immediately start with b9s checks since they're the most common, it speeds up the script if they get hit first + if sha $[FORPATH]@0:3E00 72002296D1B8B1D4E462EA340124D836BA7F8D6BF16617F369ED90983C42BB98 + set FIRM_LOG "$[FIRM_LOG]Information: b9s v1.4 installed to $[FIRM].\n" + elif sha $[FORPATH]@0:7800 79C68585B4BA1D7C4A91B858861553E768C6576B92E303810B33219736B3598B + set FIRM_LOG "$[FIRM_LOG]Warning: b9s v1.3 installed to $[FIRM].\n" + elif sha $[FORPATH]@0:10C00 A765E44844BD5667CC1D7A9A89AD45EC674F8392367F4418CCB08152581D7B3A + set FIRM_LOG "$[FIRM_LOG]Warning: b9s v1.2 installed to $[FIRM].\n" + elif sha $[FORPATH]@0:10C00 D77BEE742E7E7D528BAA20E6ADA7AC822598DDCACDFC81B1F13E32C94F4EBC50 + set FIRM_LOG "$[FIRM_LOG]Warning: b9s v1.1 installed to $[FIRM].\n" + elif sha $[FORPATH]@0:20800 43978C226D3164047051B1B534D6589608F1FA04E0B1766E1FDBEB3BC41707B6 + set FIRM_LOG "$[FIRM_LOG]Warning: b9s v1.0 installed to $[FIRM].\n" + elif verify $[FORPATH] + # check for the sighax signatures that fastboot3DS uses + # sciresm is used when fb3DS is installed by outside sources, derrek is used if fb3DS updated itself + # and that means you'll basically never see derrek sig in practice. be wary if you do see it + if sha $[FORPATH]@100:100 078CC0CFD850A27093DDA2630C3603CA0C96969BD1F26DA48AC7B1BAE5DD5219 + set FIRMSIG "SciresM" + elif sha $[FORPATH]@100:100 ADB73ABC35708EF1DFE9EF9CA5FAC8BFC2DF916BB2E38101858482409F0D450A + set FIRMSIG "derrek" + else + set FIRMSIG "none" + end + # minfirm is a special case, since it's only used by b9stool and shouldn't stick around for long after cfw setup. best to get it out of the way before fb3DS + if sha $[FORPATH]@0:100 93EE0A3799072EFB368DAD3174D8DE2EC9735BC13AC78C087DA80 + set FIRM_LOG "$[FIRM_LOG]Critical: minfirm installed to $[FIRM].\n" + elif chk -u $[FIRMSIG] "none" + if sha $[FORPATH]@0:100 D36E802EEA55B92110438D0A3B09DFCEEEC71AEB7BF05073A2E0E857827F3903 + set FIRM_LOG "$[FIRM_LOG]Information: fb3DS v1.2 ($[FIRMSIG] sig) installed to $[FIRM].\n" + elif sha $[FORPATH]@0:100 9C8D28272421C78AC796EB9023A6D1373F31176CB693CE1B04B1B78112E25226 + set FIRM_LOG "$[FIRM_LOG]Warning: fb3DS v1.1 ($[FIRMSIG] sig) installed to $[FIRM].\n" + elif sha $[FORPATH]@0:100 5E58A159C057D0762E6BFC53FE5A5CDAECA338544B252B85524DFBBB1D546DCB + set FIRM_LOG "$[FIRM_LOG]Warning: fb3DS v1.1-beta ($[FIRMSIG] sig) installed to $[FIRM].\n" + elif sha $[FORPATH]@0:100 12EBA2DDB6B5203E66CBE82A963B56AECF540814F15F8539D0CE65DAE818BBB7 + set FIRM_LOG "$[FIRM_LOG]Warning: fb3DS v1.0 ($[FIRMSIG] sig) installed to $[FIRM].\n" + else + set FIRM_LOG "$[FIRM_LOG]Warning: Valid unknown firm with $[FIRMSIG] sig installed to $[FIRM].\n" + end + else + set FIRM_LOG "$[FIRM_LOG]Information: Valid stock/unknown firm installed to $[FIRM].\n" + end + else + set FIRM_LOG "$[FIRM_LOG]Error: Invalid firm installed to $[FIRM].\n" + end +next + +@NAND_End +if chk $[FULL] "1" + goto SD_Files +else + goto Misc_Files +end + + +@SD_Files +if not isdir 0: + set SD_LOG "$[SD_LOG]Bruh Moment: No SD card is inserted. You went out of your way to find this, didn't you?\n" + goto SD_End +end +if isdir "0:/Nintendo 3DS" + if isdir A: + if find A:/dbs/title.db TITLEDB + if shaget $[TITLEDB]@0:400 NULL + fget $[TITLEDB]@100:4 DIFF + #check whether SD title.db has the DIFF magic header + if chk -u $[DIFF] "44494646" + if ask "The SD title.db is invalid.\nPress (A) to reset it.\n \n(This will delete all of your games and apps,\nbut they were likely also corrupted\nby whatever caused this.)" + rm $[TITLEDB] + fdummy $[TITLEDB] 400 + set SD_LOG "$[SD_LOG]Warning: The SD title.db needs to be reset. Reboot and go into System Settings -> Data Management -> Nintendo 3DS -> Software to do this.\n" + else + set SD_LOG "$[SD_LOG]Critical: SD title.db data is invalid.\n" + end + end + else + if ask "The SD title.db is invalid.\nPress (A) to reset it.\n \n(This will delete all of your games and apps,\nbut they were likely also corrupted\nby whatever caused this.)" + rm $[TITLEDB] + fdummy $[TITLEDB] 400 + set SD_LOG "$[SD_LOG]Warning: The SD title.db needs to be reset. Reboot and go into System Settings -> Data Management -> Nintendo 3DS -> Software to do this.\n" + else + set SD_LOG "$[SD_LOG]Critical: SD title.db is an invalid size.\n" + end + end + else + set TITLEDB A:/dbs/title.db + if ask "The SD title.db does not exist.\nPress (A) to create a blank one.\n \n(A title database is necessary\nto install games and apps.)" + if not isdir A:/dbs + mkdir A:/dbs + end + fdummy $[TITLEDB] 400 + set SD_LOG "$[SD_LOG]Warning: The SD title.db needs to be reset. Reboot and go into System Settings -> Data Management -> Nintendo 3DS -> Software to do this.\n" + else + set SD_LOG "$[SD_LOG]Critical: SD title.db not found.\n" + end + end + else + set SD_LOG "$[SD_LOG]Warning: Nintendo 3DS folder's data is inaccessible.\n" + end + if not find 0:/boot.3dsx NULL + set SD_LOG "$[SD_LOG]Warning: There is no boot.3dsx in the SD card root.\n" + end + if not find 0:/boot.firm NULL + set SD_LOG "$[SD_LOG]Warning: There is no boot.firm in the SD card root.\n" + end +else + set SD_LOG "$[SD_LOG]Warning: Nintendo 3DS folder not found.\n" +end + + +@Misc_Files +# check whether the NVRAM SPI flash works, because it's bad news if it doesn't +if not shaget M:/nvram.mem@0:400 NULL + set RAM_LOG "$[RAM_LOG]Critical: NVRAM is inaccessible.\n" +end + + +@Results +dumptxt 0:/gm9/ctrcheck_latest.txt "Date and Time: $[DATESTAMP] $[TIMESTAMP]\n---" +if chk -u $[NANDSECTORS_LOG] "" + dumptxt -p 0:/gm9/ctrcheck_latest.txt $[NANDSECTORS_LOG] +end +if chk -u $[ESSENTIALS_LOG] "" + dumptxt -p 0:/gm9/ctrcheck_latest.txt $[ESSENTIALS_LOG] +end +if chk -u $[CTRNAND_LOG] "" + dumptxt -p 0:/gm9/ctrcheck_latest.txt $[CTRNAND_LOG] +end +if chk -u $[TWLNAND_LOG] "" + dumptxt -p 0:/gm9/ctrcheck_latest.txt $[TWLNAND_LOG] +end +if chk -u $[FIRM_LOG] "" + dumptxt -p 0:/gm9/ctrcheck_latest.txt $[FIRM_LOG] +end +if chk -u $[SD_LOG] "" + dumptxt -p 0:/gm9/ctrcheck_latest.txt $[SD_LOG] +end +if chk -u $[RAM_LOG] "" + dumptxt -p 0:/gm9/ctrcheck_latest.txt $[RAM_LOG] +end +textview 0:/gm9/ctrcheck_latest.txt +if chk $[LOG] "activated" + dumptxt -p 0:/gm9/ctrcheck_log.txt "Date and Time: $[DATESTAMP] $[TIMESTAMP]\n---" + if chk -u $[NANDSECTORS_LOG] "" + dumptxt -p 0:/gm9/ctrcheck_log.txt $[NANDSECTORS_LOG] + end + if chk -u $[ESSENTIALS_LOG] "" + dumptxt -p 0:/gm9/ctrcheck_log.txt $[ESSENTIALS_LOG] + end + if chk -u $[CTRNAND_LOG] "" + dumptxt -p 0:/gm9/ctrcheck_log.txt $[CTRNAND_LOG] + end + if chk -u $[TWLNAND_LOG] "" + dumptxt -p 0:/gm9/ctrcheck_log.txt $[TWLNAND_LOG] + end + if chk -u $[FIRM_LOG] "" + dumptxt -p 0:/gm9/ctrcheck_log.txt $[FIRM_LOG] + end + if chk -u $[SD_LOG] "" + dumptxt -p 0:/gm9/ctrcheck_log.txt $[SD_LOG] + end + if chk -u $[RAM_LOG] "" + dumptxt -p 0:/gm9/ctrcheck_log.txt $[RAM_LOG] + end + echo "Check complete.\n \nThese results are also in 0:/gm9/ctrcheck_latest.txt,\nbut the file will be overwritten if you rerun this.\n \nHowever, they have also been appended to\nthe permanent log in 0:/gm9/ctrcheck_log.txt." +else + echo "Check complete.\n \nThese results are also in 0:/gm9/ctrcheck_latest.txt,\nbut the file will be overwritten if you rerun this." +end +goto cleanup + +@check_Toggle_permanent_log +if chk $[LOG] "disabled" + set LOG "activated" +else + set LOG "disabled" +end +goto menu + +@check_Exit diff --git a/3DS/manual_transfer.gm9 b/3DS/manual_transfer.gm9 new file mode 100644 index 0000000..b212a80 --- /dev/null +++ b/3DS/manual_transfer.gm9 @@ -0,0 +1,187 @@ +# Manual CTRTransfer Script +# A heavily-tweaked chimera of the original manual transfer script and the Lazarus3DS script. +# Attempts to revive a damaged NAND with a donor CTRNAND. +# last changed: 2024-09-08 +# author: AnalogMan, fox8091, StarlitSkies + +# Tell user what script does and ask for confirmation +set ERRORMSG "Script aborted by user." +ask "This script overwrites the entire CTRNAND\nwith a known working copy of that data.\nIt will try to keep all unique files intact\n but everything already missing will stay missing.\n \nOnly use this script on consoles that will not boot.\n \nContinue?" + +# Check that essentials.exefs exists as backup, mount it, and extract uniques +# If it doesn't, check for backup essentials.exefs in 0:/gm9/out, mount it, and extract uniques +# If that doesn't exist either, check for already-extracted uniques in 0:/gm9/in instead +# If any console uniques are missing, immediately end script - this isn't Lazarus, nor should it be + +if not find S:/essential.exefs ESSENTIAL + echo "Note: essential.exefs not found.\nUsing backup essential.exefs in 0:/gm9/out instead.\n\nPress A to continue." + if not find $[GM9OUT]/essential.exefs ESSENTIAL + echo "Note: Backup essential.exefs not found.\nUsing extracted files from 0:/gm9/in instead.\n\nPress A to continue." + end +end + +set ERRORMSG "Console unique(s) not found.\nThis script will not run unless all console uniques exist." + +if chk -u $[ESSENTIAL] "" + # this is if either essentials.exefs exists + imgmount $[ESSENTIAL] + set BACKUP $[GM9OUT]/backup + mkdir $[BACKUP] + cp -n -w G:/frndseed $[BACKUP]/LocalFriendCodeSeed_B + cp -n -w G:/hwcal0 $[BACKUP]/HWCAL0.dat + cp -n -w G:/hwcal1 $[BACKUP]/HWCAL1.dat + cp -n -w G:/movable $[BACKUP]/movable.sed + cp -n -w G:/secinfo $[BACKUP]/SecureInfo_A + imgumount + cp -n -w $[ESSENTIAL] $[BACKUP]/essential.exefs + find $[BACKUP]/LocalFriendCodeSeed_B SEED + find $[BACKUP]/HWCAL0.dat HWCAL0 + find $[BACKUP]/HWCAL1.dat HWCAL1 + find $[BACKUP]/movable.sed MOVABLE + find $[BACKUP]/SecureInfo_A SECINFO +else + # this is if neither essentials.exefs exists. note it is gm9/in, not gm9/out + find 0:/gm9/in/LocalFriendCodeSeed_B SEED + find 0:/gm9/in/HWCAL0.dat HWCAL0 + find 0:/gm9/in/HWCAL1.dat HWCAL1 + find 0:/gm9/in/movable.sed MOVABLE + find 0:/gm9/in/SecureInfo_A SECINFO +end + +set ERRORMSG "No valid CTRNAND images found in 0:/gm9/out." +if chk $[ONTYPE] "N3DS" + find $[GM9OUT]/*_ctrtransfer_n3ds.bin NULL +else + find $[GM9OUT]/*_ctrtransfer_o3ds.bin NULL +end + +set ERRORMSG "No CTRNAND image was selected." +if chk $[ONTYPE] "N3DS" + filesel "Select the CTRNAND image to use." $[GM9OUT]/*_ctrtransfer_n3ds.bin IMAGE +else + filesel "Select the CTRNAND image to use." $[GM9OUT]/*_ctrtransfer_o3ds.bin IMAGE +end + +# Prompt for permission +set ERRORMSG "Script denied permissions by user." +allow -a S: + +set ERRORMSG "" +if ask "Also restore non-critical data?\nThis includes things like the friends list and activity log,\nwhich would normally be reset.\n\nThis is usually safe, but may carry\na risk of preserving file corruption." + set OPTRESTORE 1 +else + set OPTRESTORE 0 + echo "Backups of this data will be preserved.\n\nIf you wish to restore them manually later on,\nthe files will be inside 0:/pit.\n\nPress A to continue." +end + + +# Preserve all other important console-unique data, to be restored after transfer +# Attempt to copy sysdata files to SD for restoring later +cp -w -o -s -n 1:/data/$[SYSID0]/sysdata/00010017/00000000 0:/pit/configsave.bin +cp -w -o -s -n 1:/data/$[SYSID0]/sysdata/00010032/00000000 0:/pit/friendsave.bin +cp -w -o -s -n 1:/data/$[SYSID0]/sysdata/0001000f/00000000 0:/pit/seedsave.bin +cp -w -o -s -n 1:/data/$[SYSID0]/sysdata/00010022/00000000 0:/pit/activitylog.bin + +# Attempt to copy system app sysdata +find -o -s 1:/data/$[SYSID0]/sysdata/000202?8 MIIPLAZA +set MIIPLAZA $[MIIPLAZA]/00000000 +cp -w -o -s -n $[MIIPLAZA] 0:/pit/miiplaza.bin +find -o -s 1:/data/$[SYSID0]/sysdata/000202?d FACERAIDERS +set FACERAIDERS $[FACERAIDERS]/00000000 +cp -w -o -s -n $[FACERAIDERS] 0:/pit/faceraiders.bin +find -o -s 1:/data/$[SYSID0]/sysdata/000202?e ARGAMES +set ARGAMES $[ARGAMES]/00000000 +cp -w -o -s -n $[ARGAMES] 0:/pit/argames.bin + +# Attempt to copy extdata files to SD for restoring later +cp -w -o -s -n 1:/data/$[SYSID0]/extdata/00048000/f0000001 0:/pit/01 # Photos +cp -w -o -s -n 1:/data/$[SYSID0]/extdata/00048000/f0000002 0:/pit/02 # Sounds +cp -w -o -s -n 1:/data/$[SYSID0]/extdata/00048000/f000000b 0:/pit/0b # MiiMaker, Game Coins, etc. + +# Overwrite CTRNAND with CTRTransfer image and then restore system uniques +set ERRORMSG "Failed to overwrite CTRNAND with image." +cp -n -w $[IMAGE] S:/ctrnand_full.bin +set ERRORMSG "Restoring LocalFriendCodeSeed_B failed." +cp -n -w $[SEED] 1:/rw/sys/LocalFriendCodeSeed_B +set ERRORMSG "Restoring SecureInfo_A failed." +cp -n -w $[SECINFO] 1:/rw/sys/SecureInfo_A +set ERRORMSG "Restoring HWCAL0.dat failed." +cp -n -w $[HWCAL0] 1:/ro/sys/HWCAL0.dat +set ERRORMSG "Restoring HWCAL1.dat failed." +cp -n -w $[HWCAL1] 1:/ro/sys/HWCAL1.dat +set ERRORMSG "Restoring movable.sed failed." +cp -n -w $[MOVABLE] 1:/private/movable.sed + +# Create SecureInfo_C if there's a region difference between SecureInfo_A and CVer +set ERRORMSG "" +if find 1:/title/000400db/00017202 NULL + set CVREG 00 +elif find 1:/title/000400db/00017302 NULL + set CVREG 01 +elif find 1:/title/000400db/00017102 NULL + set CVREG 02 +elif find 1:/title/000400db/00017402 NULL + set CVREG 04 +elif find 1:/title/000400db/00017502 NULL + set CVREG 05 +elif find 1:/title/000400db/00017602 NULL + set CVREG 06 +else + echo "The CVer title does not exist.\nYour CTRTransfer image is probably corrupted.\n\nPress A to shut down, then please obtain\n a new CTRTransfer file." + poweroff +end +fget 1:/rw/sys/SecureInfo_A@100:1 SIREG + +if chk -u $[CVREG] $[SIREG] + cp -w -o -s -n 1:/rw/sys/SecureInfo_A 1:/rw/sys/SecureInfo_C + fset 1:/rw/sys/SecureInfo_C@100:1 $[CVREG] +end + + +# Restore backed-up system data if agreed to earlier +if chk $[OPTRESTORE] 1 + cp -w -o -s -n 0:/pit/seedsave.bin 1:/data/$[SYSID0]/sysdata/0001000f/00000000 + cp -w -o -s -n 0:/pit/configsave.bin 1:/data/$[SYSID0]/sysdata/00010017/00000000 + cp -w -o -s -n 0:/pit/friendsave.bin 1:/data/$[SYSID0]/sysdata/00010032/00000000 + cp -w -o -s -n 0:/pit/activitylog.bin 1:/data/$[SYSID0]/sysdata/00010022/00000000 + + # Restore system app sysdata + if chk $[CVREG] 00 + set CHR 0 + elif chk $[CVREG] 01 + set CHR 1 + elif chk $[CVREG] 02 + set CHR 2 + elif chk $[CVREG] 04 + set CHR 6 + elif chk $[CVREG] 05 + set CHR 7 + elif chk $[CVREG] 06 + set CHR 8 + end + cp -w -o -s -n 0:/pit/miiplaza.bin 1:/data/$[SYSID0]/sysdata/000202$[CHR]8/00000000 + cp -w -o -s -n 0:/pit/faceraiders.bin 1:/data/$[SYSID0]/sysdata/000202$[CHR]d/00000000 + cp -w -o -s -n 0:/pit/argames.bin 1:/data/$[SYSID0]/sysdata/000202$[CHR]e/00000000 + + # Restore shared extdata + cp -w -o -s -n 0:/pit/01 1:/data/$[SYSID0]/extdata/00048000/f0000001 # Photos + cp -w -o -s -n 0:/pit/02 1:/data/$[SYSID0]/extdata/00048000/f0000002 # Sounds + cp -w -o -s -n 0:/pit/0b 1:/data/$[SYSID0]/extdata/00048000/f000000b # MiiMaker, Game Coins, etc. +end + +# Fix SYSNAND CTRNAND CMACs +set ERRORMSG "Failed to fix 1:/dbs CMACs." +fixcmac 1:/dbs +set ERRORMSG "Failed to fix 1:/data CMACs." +fixcmac 1:/data +set ERRORMSG "Failed to fix 1:/private CMACs." +fixcmac 1:/private + +# Wrap up +set ERRORMSG "Reboot canceled." +ask "Manual CTRTransfer complete.\n \nRemove backup files and reboot now?" +if chk $[OPTRESTORE] 1 + rm -o -s 0:/pit +end +rm -o -s 0:/gm9/scripts/manual_transfer.gm9 +reboot diff --git a/License.txt b/License.txt new file mode 100644 index 0000000..7f4b05a --- /dev/null +++ b/License.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Nintendo Homebrew Staff + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..99922b6 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# Nintendo Homebrew Scripts + +A combined space for all scripts made, used, and maintained by [Nintendo Homebrew on Discord](https://discord.gg/C29hYvh). + +# Usage + +All scripts in this repo are separated by the console they are made for. Open the README in their respective folders for specific instructions on usage. + +At current, this repo has scripts for the following consoles: + +* [Nintendo 3DS](3DS/README.md) \ No newline at end of file