From 5950ff5b5e7b619c927b0b7a378902c288d4a991 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 3 Sep 2021 01:49:18 -0700 Subject: [PATCH] fusee_cpp: validate mtc overlay before jumping to it. mtc will jump back to us, so we need a compatible binary. This also makes some changes to our layout to minimize the likelihood of an incompatible mtc binary (I made some arbitrary .text/.rodata/.rwdata changes) and saw identical mtc binaries, so hopefully this all works out. --- fusee_cpp/program/program.ld | 3 +++ fusee_cpp/program/source/fusee_overlay_manager.cpp | 14 ++++++++++++-- fusee_cpp/program/source/fusee_stratosphere.cpp | 2 ++ fusee_cpp/program/split_bin.py | 10 +++++++--- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/fusee_cpp/program/program.ld b/fusee_cpp/program/program.ld index 8dc8e938c..a3f21a2e9 100644 --- a/fusee_cpp/program/program.ld +++ b/fusee_cpp/program/program.ld @@ -23,6 +23,9 @@ SECTIONS KEEP(*(.text._ZN3ams4util15GetMicroSecondsEv)) KEEP(*(.text._ZN3ams4util16WaitMicroSecondsEi)) KEEP(*(.text._ZN3ams6nxboot14ShowFatalErrorEPKcz)) + KEEP(*(.text.memcpy)) + KEEP(*(.text.memset)) + KEEP(*(.text.memcmp)) _*.o(SORT(.text*)) *(.text.unlikely .text.*_unlikely .text.unlikely.*) *(.text.exit .text.exit.*) diff --git a/fusee_cpp/program/source/fusee_overlay_manager.cpp b/fusee_cpp/program/source/fusee_overlay_manager.cpp index 06d2a5bc3..e4c46ba46 100644 --- a/fusee_cpp/program/source/fusee_overlay_manager.cpp +++ b/fusee_cpp/program/source/fusee_overlay_manager.cpp @@ -28,15 +28,25 @@ namespace ams::nxboot { void LoadMemoryTrainingOverlay(fs::FileHandle archive_file) { Result result; + u32 verif_hash; + u32 store_hash; if (fuse::GetSocType() == fuse::SocType_Erista) { result = fs::ReadFile(archive_file, __builtin_offsetof(SecondaryArchive, ovl_mtc_erista), GetOverlayDestination(), sizeof(SecondaryArchive{}.ovl_mtc_erista)); + verif_hash = reinterpret_cast(GetOverlayDestination())[-2]; + store_hash = reinterpret_cast(GetOverlayDestination())[(sizeof(SecondaryArchive{}.ovl_mtc_erista) / sizeof(u32)) - 1]; } else /* if (fuse::GetSocType() == fuse::SocType_Mariko) */ { result = fs::ReadFile(archive_file, __builtin_offsetof(SecondaryArchive, ovl_mtc_mariko), GetOverlayDestination(), sizeof(SecondaryArchive{}.ovl_mtc_mariko)); + verif_hash = reinterpret_cast(GetOverlayDestination())[-1]; + store_hash = reinterpret_cast(GetOverlayDestination())[(sizeof(SecondaryArchive{}.ovl_mtc_mariko) / sizeof(u32)) - 1]; } if (R_FAILED(result)) { ShowFatalError("Failed to load MTC overlay: 0x%08" PRIx32 "\n", result.GetValue()); } + + if (verif_hash != store_hash) { + ShowFatalError("Incorrect fusee version! (program=0x%08" PRIx32 ", mtc=0x%08" PRIx32 ")\n", verif_hash, store_hash); + } } } @@ -53,7 +63,7 @@ namespace ams::nxboot { if (fuse::GetSocType() == fuse::SocType_Erista) { /* NOTE: Erista does not do memory clock restoration. */ /* std::memcpy(const_cast(GetSecondaryArchive().ovl_mtc_erista), GetOverlayDestination(), sizeof(SecondaryArchive{}.ovl_mtc_erista)); */ - } else { + } else /* if (fuse::GetSocType() == fuse::SocType_Mariko) */ { std::memcpy(const_cast(GetSecondaryArchive().ovl_mtc_mariko), GetOverlayDestination(), sizeof(SecondaryArchive{}.ovl_mtc_mariko)); } } @@ -62,7 +72,7 @@ namespace ams::nxboot { if (fuse::GetSocType() == fuse::SocType_Erista) { /* NOTE: Erista does not do memory clock restoration. */ /* std::memcpy(GetOverlayDestination(), GetSecondaryArchive().ovl_mtc_erista, sizeof(SecondaryArchive{}.ovl_mtc_erista)); */ - } else { + } else /* if (fuse::GetSocType() == fuse::SocType_Mariko) */ { std::memcpy(GetOverlayDestination(), GetSecondaryArchive().ovl_mtc_mariko, sizeof(SecondaryArchive{}.ovl_mtc_mariko)); } } diff --git a/fusee_cpp/program/source/fusee_stratosphere.cpp b/fusee_cpp/program/source/fusee_stratosphere.cpp index b0a805d17..3ca16df7b 100644 --- a/fusee_cpp/program/source/fusee_stratosphere.cpp +++ b/fusee_cpp/program/source/fusee_stratosphere.cpp @@ -725,6 +725,8 @@ namespace ams::nxboot { AddNogcPatches(fs_meta, fs_version); } + /* TODO ams.tma2: add mount_host patches. */ + /* Add generic patches. */ { /* Create patch path. */ diff --git a/fusee_cpp/program/split_bin.py b/fusee_cpp/program/split_bin.py index aa1139acd..54cf41815 100644 --- a/fusee_cpp/program/split_bin.py +++ b/fusee_cpp/program/split_bin.py @@ -132,7 +132,11 @@ def main(argc, argv): all_kips = get_kips() with open('../../program%s.bin' % target, 'rb') as f: data = f.read() - fusee_program = lz4_compress(data[:0x2B000] + get_overlay(data, 0)[:0x11000]) + erista_mtc = get_overlay(data, 1) + mariko_mtc = get_overlay(data, 2) + erista_hsh = hashlib.sha256(erista_mtc[:-4]).digest()[:4] + mariko_hsh = hashlib.sha256(mariko_mtc[:-4]).digest()[:4] + fusee_program = lz4_compress(data[:0x2B000 - 8] + erista_hsh + mariko_hsh + get_overlay(data, 0)[:0x11000]) with open('../../program%s.lz4' % target, 'wb') as f: f.write(fusee_program) with open('../../fusee-boogaloo%s.bin' % target, 'wb') as f: @@ -145,9 +149,9 @@ def main(argc, argv): # Write Mariko Fatal f.write(pad(read_file('../../../../exosphere/mariko_fatal%s.bin' % target), 0x1C000)) # Write Erista MTC - f.write(get_overlay(data, 1)) + f.write(erista_mtc[:-4] + erista_hsh) # Write Mariko MTC - f.write(get_overlay(data, 2)) + f.write(mariko_mtc[:-4] + mariko_hsh) # Write exosphere f.write(pad(read_file('../../../../exosphere/exosphere%s.bin' % target), 0xE000)) # Write mesosphere