# A script for checking all of a 3DS system's important files and their integrity. # original script by FrozenFire, overhaul & fixes by StarlitSkies # last modified: NaN @cleanup set FULL "0" set NAND "0" set SDCARD "0" set MISC "0" set NANDSECTORS_LOG "" set CTRNAND_LOG "" set TWLNAND_LOG "" set FIRM_LOG "" set SD_LOG "" set RAM_LOG "" set LOG "disabled" @menu labelsel -o -s "Select what system files to check.\n Console is a $[RDTYPE] $[ONTYPE] booted from $[HAX].\n Log status: $[LOG]" check_* goto menu @check_Full set FULL "1" goto NAND_Sectors @check_NAND_Only set NAND "1" goto NAND_Sectors @check_SD_Only set SDCARD "1" goto SD_Files @check_Miscellaneous_Only set MISC "1" goto MISC_Files @NAND_Sectors # this checks whether the NAND header signature is the retail sighax signature, based on their hashes # sighax will always be read as valid by boot9 even without cfw, so it's just a helpful indicator of whether custom partitions are supposed to be there set SIGHAX "0" if sha S:/nand.bin@0:100 A4AE99B93412E4643E4686987B6CFD59701D5C655CA2FF671CE680B4DDCF0948 set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Information: The NAND header has a sighax signature.\n" set SIGHAX "1" end # hash-based check of NAND header partition table against retail partition tables if sha S:/nand.bin@100:60 dfd434b883874d8b585a102f3cf3ae4cef06767801db515fdf694a7e7cd98bc2 if chk $[ONTYPE] "N3DS" set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Information: The NAND header is stock. (N3DS)\n" else set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Critical: Your O3DS has an N3DS NAND header.\n" end elif sha S:/nand.bin@100:60 ae9b6645105f3aec22c2e3ee247715ab302874fca283343c731ca43ea1baa25d if chk $[ONTYPE] "O3DS" set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Information: The NAND header is stock. (O3DS)\n" else set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Critical: Your N3DS has an O3DS NAND header.\n" end else fget S:/nand.bin@100:4 NCSD #check for the NCSD magic, if it's not present header is guaranteed invalid 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 # this next one should only ever be possible if booted from ntrboot, but i'm including it anyway else set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Error: NAND header is invalid.\n" end end #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: The Secret Sector is invalid. a9lh might be installed.\n" end else 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 end #verify twl MBR is retail (there is no good reason this should ever be modified) if not sha S:/twlmbr.bin 77a98e31f1ff7ec4ef2bfacca5a114a49a70dcf8f1dcd23e7a486973cfd06617 set NANDSECTORS_LOG "$[NANDSECTORS_LOG]Critical: TWL MBR is invalid, meaning DS mode is unusuable.\n" end # get first byte in stage2 location fget S:/nand.bin@B800000:1 ABYTE # 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 if chk $[FULL] "1" goto CTRNAND elif chk $[NAND] "1" goto CTRNAND else goto Results end @CTRNAND # check if CTRNAND can be accessed if isdir 1: #find movable.sed, check if it's valid, and get its LFCS portion hash if find 1:/private/movable.sed movable fget $[movable]@0:4 SEED fget $[movable]@5:1 CMAC shaget $[movable]@8:110 LFCSM #check if movable.sed at least has the SEED magic if chk -u $[SEED] "53454544" set CTRNAND_LOG "$[CTRNAND_LOG]Critical: movable.sed is invalid.\n" elif chk $[CMAC] "01" if not fget $[movable]@120:1 NULL if ask "movable.sed is misconfigured. Fix this issue?" fset [$movable]@5 00 set CTRNAND_LOG "$[CTRNAND_LOG]Information: movable.sed is 288 bytes but had the CMAC flag. The flag has been disabled.\n" else set CTRNAND_LOG "$[CTRNAND_LOG]Critical: movable.sed is 288 bytes but has the CMAC flag.\n" end end end else set CTRNAND_LOG "$[CTRNAND_LOG]Critical: movable.sed not found.\n" end # account for both potential filenames of LocalFriendCodeSeed if find 1:/rw/sys/LocalFriendCodeSeed_B LFCS elif find -s 1:/rw/sys/LocalFriendCodeSeed_A LFCS end if chk -u $[LFCS] "" shaget $[LFCS]@0:110 check #Compare the LFCS in movable.sed to the raw LFCS file if chk -u $[LFCSM] $[check] set CTRNAND_LOG "$[CTRNAND_LOG]Information: Your LFCS doesn't match the one inside movable.sed.\n" end if find M:/otp_dec.mem OTP fget $[LFCS]@108:8 LFCSEED fget $[OTP]@8:8 OTPSEED if chk -u $[LFCSEED] $[OTPSEED] set CTRNAND_LOG "$[CTRNAND_LOG]Warning: Your console is using a donor LFCS.\n" end end else set CTRNAND_LOG "$[CTRNAND_LOG]Critical: LFCS not found.\n" end # find secureinfo_(a/b) and check if it matches the console region, then check for region change (presence of secureinfo_c) and do checks against that file if find 1:/rw/sys/SecureInfo_A SEC elif find -s 1:/rw/sys/SecureInfo_B SEC end if find -s 1:/rw/sys/SecureInfo_C ALTSEC else set ALTSEC "" end 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" end else set REGCHG "0" end if chk -u $[SEC] "" 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" end if chk -u $[REG] $[REGION] set CTRNAND_LOG "$[CTRNAND_LOG]Warning: Your SecureInfo doesn't match your console's region.\n" end if chk $[REGCHG] "1" if chk -u $[ALTREG] $[REGION] set CTRNAND_LOG "$[CTRNAND_LOG]Information: Your console is region changed from $[REG] to $[ALTREG].\n" else set CTRNAND_LOG "$[CTRNAND_LOG]Information: Your console is region changed to the same region...?\n" end end elif chk $[REGCHG] "1" set CTRNAND_LOG "$[CTRNAND_LOG]Warning: Your console's original SecureInfo is missing. Only SecureInfo_C is present.\n" else set CTRNAND_LOG "$[CTRNAND_LOG]Critical: SecureInfo not found.\n" end # 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 fget $[NANDTITLEDB]@100:4 DIFF # check whether nand title.db has the DIFF magic if chk -u $[DIFF] "44494646" set CTRNAND_LOG "$[CTRNAND_LOG]Warning: CTRNAND title.db is invalid.\n" end else set CTRNAND_LOG "$[CTRNAND_LOG]Critical: CTRNAND title.db not found.\n" end # check whether first HWCAL exists if find 1:/ro/sys/HWCAL0.dat HWCAL0 # check if it has the CCAL magic fget $[HWCAL0]@0:4 CCAL0 if chk -u $[CCAL0] "4343414C" set CTRNAND_LOG "$[CTRNAND_LOG]Critical: HWCAL0 is invalid.\n" end else set CTRNAND_LOG "$[CTRNAND_LOG]Critical: HWCAL0 not found.\n" end # check whether second HWCAL exists if find 1:/ro/sys/HWCAL1.dat HWCAL1 # check if it has the CCAL magic fget $[HWCAL1]@0:4 CCAL1 if chk -u $[CCAL1] "4343414C" set CTRNAND_LOG "$[CTRNAND_LOG]Critical: HWCAL1 is invalid.\n" end else set CTRNAND_LOG "$[CTRNAND_LOG]Critical: HWCAL1 not found.\n" end else set CTRNAND_LOG "$[CTRNAND_LOG]Error: CTRNAND not found.\n" end if chk $[FULL] "1" goto TWLNAND elif chk $[NAND] "1" goto TWLNAND else goto Results end @TWLNAND #check if TWLNAND is accessible if isdir 2: if not isdir 2:/shared2 # the 3DS won't boot if this folder doesn't exist. # if it isn't there, remaking it is harmless if ask "An important folder in the TWLNAND is missing. Fix this issue?" mkdir 2:/shared2 set TWLNAND_LOG "$[TWLNAND_LOG]Information: The shared2 folder did not exist, but was recreated automatically.\n" else set TWLNAND_LOG "$[TWLNAND_LOG]Critical: There is no shared2 folder in the TWLNAND.\n" end end else set TWLNAND_LOG "$[TWLNAND_LOG]Error: TWLNAND not found.\n" end if not isdir 3: set TWLNAND_LOG "$[TWLNAND_LOG]Warning: TWLP not found.\n" end if chk $[FULL] "1" goto FIRM_Data elif chk $[NAND] "1" goto FIRM_Data else goto Results end @FIRM_Data # 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 so you can skip the other checks and speed up the script if it is 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 # sciresm will be the far more common one, as a result 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, so get it out of the way before signatures get involved 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 if chk $[FULL] "1" goto SD_Files else goto Results end @SD_Files if isdir "0:/Nintendo 3DS" if isdir A: if find A:/dbs/title.db TITLEDB fget $[TITLEDB]@100:4 DIFF #check whether SD title.db has the DIFF magic if chk -u $[DIFF] "44494646" if ask "The SD title.db is invalid. Fix this issue?" 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 invalid.\n" end end else if ask "The SD title.db does not exist. Fix this issue?" if not isdir A:/dbs mkdir A:/dbs end set TITLEDB A:/dbs/title.db 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." end if chk $[FULL] "1" goto MISC_Files else goto Results end @MISC_Files # check whether the NVRAM SPI flash works, because it's incredibly 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 "---$[DATESTAMP] $[TIMESTAMP]---\n" if chk -u $[NANDSECTORS_LOG] "" dumptxt -p 0:/gm9/ctrcheck_latest.txt $[NANDSECTORS_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 "\n\n---$[DATESTAMP] $[TIMESTAMP]---\n" if chk -u $[NANDSECTORS_LOG] "" dumptxt -p 0:/gm9/ctrcheck_log.txt $[NANDSECTORS_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_latest.txt $[SD_LOG] end if chk -u $[RAM_LOG] "" dumptxt -p 0:/gm9/ctrcheck_latest.txt $[RAM_LOG] end echo "These results have been appended to \nthe log in the gm9 folder." end echo "Thanks for using this script!" goto cleanup @check_Toggle_log if chk $[LOG] "disabled" set LOG "activated" else set LOG "disabled" end goto menu @check_Exit