Building Atmosphère on Windows using MSYS2

Sometimes you need to build the binaries for Atmosphère, or you want to change something on the source code, for building your starting point should be: https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/building.md
On that document you can read:
Building Atmosphère is a very straightforward process that relies almost exclusively on tools provided by the devkitPro organization.​
Dependencies:
  • devkitA64
  • devkitARM
  • Python 2 (Python 3 may work as well, but this is not guaranteed)
  • LZ4
  • PyCryptodome (optional)
  • Hactool
Setup a DevKitPro environment: (https://devkitpro.org/wiki/Getting_Started)
Install the following packages via (dkp-)pacman:​
  • switch-dev
  • switch-glm
  • switch-libjpeg-turbo
  • devkitARM
  • devkitarm-rules
  • hactool
Install the following library via python's package manager pip, required by exosphere:​
  • lz4
Finally, clone the Atmosphère repository and run make under its root directory.​

That instructions are a little plain for we the noobs.

First you need Install a MSYS environment:
The latest instructions for install the MSYS environment are on https://gbatemp.net/threads/install-msys-environment.652234/ if you don't have one working, use them.

After you have the MSYS environment working you need to install DevKitPro
For that you can follow the instructions on the tutorial https://gbatemp.net/threads/setup-a-devkitpro-environment-on-windows.652238/

Now you can install DevKitPro packages:
Bash:
pacman -S --noconfirm switch-dev devkitA64 dkp-toolchain-vars libnx switch-tools switch-mesa switch-libdrm_nouveau switch-sdl2

And Atmosphère prerequisites
Bash:
Pacman -Sy --noconfirm devkitA64 devkitARM devkitarm-rules hactool mingw-w64-x86_64-python mingw-w64-x86_64-python-lz4 mingw-w64-x86_64-python-pycryptodome switch-dev switch-glm switch-libjpeg-turbo mingw-w64-x86_64-python-pip

For me I had to add zip package because even if wasn't explicit indicated on the build page, the code needs it.

Additional you need the packages git make lz4 for all to work, use the command:

Bash:
Pacman -Sy --noconfirm zip git make lz4


The package hactool need you to copy your own prod.keys file on $HOME/.switch folder. (c:\msys64\home\USERNAME\.switch if you use the default installation folder)

LibNX Dependency
Atmosphère depends heavily on LibNX, generally when a major version of firmware is released or great changes on the code are made, changes to LibNX are also made.
The Atmosphère team works on their own repo of LibNX (https://github.com/Atmosphere-NX/libnx) and forward Pull Request to official SwitchBrew LibNX repo (https://github.com/switchbrew/libnx).

So if there are changes on LibNX you need to build it and install on your setup.
If you haven't done already, setup the environment variables

Bash:
export DEVKITPRO=/opt/devkitpro
export DEVKITARM=${DEVKITPRO}/devkitARM
export DEVKITPPC=${DEVKITPRO}/devkitPPC
export PATH=${DEVKITPRO}/tools/bin:$PATH

Test it running the command
export


Then go to the Atmosphere-NX/LibNX repo and look what is the new branch for the current firmware, by example, for Firmware 16.0.0 the branch name is "1600_Support"

1677718224337.png

Then go to your MSYS MinGW64 window and clone the Atmosphere-NX/LibNX repo

Bash:
cd ~
git clone --recursive https://github.com/Atmosphere-NX/libnx.git
cd libnx

And checkout the needed branch:

Bash:
git checkout 1600_support

Then build and install the new LibNX libraries

Bash:
make install -j$(nproc)

Now you can build Atmosphère with latest LibNX code; remember if you update the pacman LibNX package the changes get reversed and you need to build LibNX again.

Now is time to build the binaries
Clone the repository:
Bash:
cd ~
git clone --recursive https://github.com/Atmosphere-NX/Atmosphere

Go to new created Atmosphère folder
Bash:
cd Atmosphere

Be sure you have defined the environment variables for DevKitPro
Bash:
export DEVKITPRO=/opt/devkitpro
export DEVKITARM=${DEVKITPRO}/devkitARM
export DEVKITPPC=${DEVKITPRO}/devkitPPC
export PATH=${DEVKITPRO}/tools/bin:$PATH

You can test it running the command
export

Copy prod.keys file on $HOME/.switch
Bash:
mkdir ~/.switch
cp YOURCURRENTPATHTOKEYS ~/.switch/prod.keys

And now you are ready to start the building process:
Bash:
make -j$(nproc)

I do use the "-j$(nproc)" parameter to "bleed" all the available CPU to run the compiler, without that the whole process could take up to 1 hour.

I want to thank a lot to @binkinator and @godreborn for all the help and inspiration to make this guide, and want to ask you for help improving this guide.

Also special thanks to @godreborn for been a support of the users replies and suggestions to the OP.

Remember, as you are getting a new set of binaries, you need new set of sigpatches if you use it. So the great tool from @mrdude comes in hand, the latest release can be downloaded from: https://github.com/mrdude2478/IPS_Patch_Creator/releases/; you use the program to generate a new set of patches for your recently build package3 file.


Latest IPS Patch Creator:
Sigpatch-IPS-Creator_1.5.7_Yandex.png




-Edited: add sigpatches step and clean up a little-
-Edit 2, add LibNX build-
 

Attachments

  • 1695782853186.png
    1695782853186.png
    62.7 KB · Views: 94
  • 1695782902542.png
    1695782902542.png
    6.4 KB · Views: 93
Last edited by impeeza,

josete2k

Well-Known Member
Member
Joined
Apr 24, 2009
Messages
773
Trophies
1
Age
44
Location
Spain
XP
1,859
Country
Spain
# First be sure you have this environmental variables
Bash:
export DEVKITPRO=/opt/devkitpro
export DEVKITARM=${DEVKITPRO}/devkitARM
export DEVKITPPC=${DEVKITPRO}/devkitPPC
export PATH=${DEVKITPRO}/tools/bin:$PATH

You also can add these lines to your home/user/.bashrc file and all will be loaded when msys starts...
Post automatically merged:

those are the functions that check for nca signatures in loader. if you remove them then loader no longer checks signatures
I tried but I can't build AMS with these lines edited (maybe my fault)...
 

impeeza

¡Kabito!
OP
Member
Joined
Apr 5, 2011
Messages
7,439
Trophies
4
Age
46
Location
At my chair.
XP
23,921
Country
Colombia
You also can add these lines to your home/user/.bashrc file and all will be loaded when msys starts...
That variables are add to your system by the package devkit-env, you should install that package as part of the DevKitPro installation process

https://gbatemp.net/threads/setup-a-devkitpro-environment-on-windows.652238
Post automatically merged:

I tried but I can't build AMS with these lines edited (maybe my fault)...
I tried also but is a lot of modifications and some are no so clear I give up at mid of the instructions :P
 
Last edited by impeeza,

4d1xlaan

Well-Known Member
Member
Joined
Apr 21, 2024
Messages
831
Trophies
0
XP
849
Country
United States
I tried also but is a lot of modifications and some are no so clear I give up at mid of the instructions :P
I'll make a diff hold on

it's also possible I forgot some steps, if there are any unused variables left over it will give errors (normally a warning, but the build treats warnings as errors and stops the build)
Post automatically merged:

there were new changes in 18.0.0 loader that makes it so you need to remove way more stuff now. my old patch worked for 1.7.0 and for a long time before too, but any later commits a bunch more stuff needs to be changed

I havent tested it, I see no reason why it wouldnt work but I would appreciate if someone wants to test and confirm


Code:
From: 4d1xlaan <[email protected]>
Date: Wed, 5 Jun 2024 19:09:01 -0400
Subject: [PATCH] stuff

---
 stratosphere/loader/source/ldr_meta.cpp       | 42 +--------
 stratosphere/loader/source/ldr_meta.hpp       |  4 +-
 .../loader/source/ldr_process_creation.cpp    | 85 +------------------
 3 files changed, 9 insertions(+), 122 deletions(-)

diff --git a/stratosphere/loader/source/ldr_meta.cpp b/stratosphere/loader/source/ldr_meta.cpp
index ee43aeedc..f3bfc5433 100644
--- a/stratosphere/loader/source/ldr_meta.cpp
+++ b/stratosphere/loader/source/ldr_meta.cpp
@@ -103,41 +103,6 @@ namespace ams::ldr {
             R_SUCCEED();
         }
 
-        const u8 *GetAcidSignatureModulus(PlatformId platform, u8 key_generation, bool unk_unused) {
-            return fssystem::GetAcidSignatureKeyModulus(platform, !IsDevelopmentForAcidSignatureCheck(), key_generation, unk_unused);
-        }
-
-        size_t GetAcidSignatureModulusSize(PlatformId platform, bool unk_unused) {
-            return fssystem::GetAcidSignatureKeyModulusSize(platform, unk_unused);
-        }
-
-        Result ValidateAcidSignature(Meta *meta, PlatformId platform, bool unk_unused) {
-            /* Loader did not check signatures prior to 10.0.0. */
-            if (hos::GetVersion() < hos::Version_10_0_0) {
-                meta->check_verification_data = false;
-                R_SUCCEED();
-            }
-
-            /* Get the signature key generation. */
-            const auto signature_key_generation = meta->npdm->signature_key_generation;
-            R_UNLESS(fssystem::IsValidSignatureKeyGeneration(platform, signature_key_generation), ldr::ResultInvalidMeta());
-
-            /* Verify the signature. */
-            const u8 *sig         = meta->acid->signature;
-            const size_t sig_size = sizeof(meta->acid->signature);
-            const u8 *mod         = GetAcidSignatureModulus(platform, signature_key_generation, unk_unused);
-            const size_t mod_size = GetAcidSignatureModulusSize(platform, unk_unused);
-            const u8 *exp         = fssystem::GetAcidSignatureKeyPublicExponent();
-            const size_t exp_size = fssystem::AcidSignatureKeyPublicExponentSize;
-            const u8 *msg         = meta->acid->modulus;
-            const size_t msg_size = meta->acid->size;
-            const bool is_signature_valid = crypto::VerifyRsa2048PssSha256(sig, sig_size, mod, mod_size, exp, exp_size, msg, msg_size);
-            R_UNLESS(is_signature_valid || !IsEnabledProgramVerification(), ldr::ResultInvalidAcidSignature());
-
-            meta->check_verification_data = is_signature_valid;
-            R_SUCCEED();
-        }
-
         Result LoadMetaFromFile(fs::FileHandle file, MetaCache *cache) {
             /* Reset cache. */
             cache->meta = {};
@@ -190,7 +155,7 @@ namespace ams::ldr {
     }
 
     /* API. */
-    Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform, bool unk_unused) {
+    Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) {
         /* Set the cached program id back to zero. */
         g_cached_program_id = {};
 
@@ -259,7 +224,6 @@ namespace ams::ldr {
                 R_TRY(fs::OpenFile(std::addressof(file), BaseMetaPath, fs::OpenMode_Read));
                 ON_SCOPE_EXIT { fs::CloseFile(file); };
                 R_TRY(LoadMetaFromFile(file, std::addressof(g_original_meta_cache)));
-                R_TRY(ValidateAcidSignature(std::addressof(g_original_meta_cache.meta), platform, unk_unused));
                 meta->modulus                 = g_original_meta_cache.meta.modulus;
                 meta->check_verification_data = g_original_meta_cache.meta.check_verification_data;
             }
@@ -278,9 +242,9 @@ namespace ams::ldr {
         R_SUCCEED();
     }
 
-    Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform) {
+    Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) {
         if (g_cached_program_id != loc.program_id || g_cached_override_status != status) {
-            R_RETURN(LoadMeta(out_meta, loc, status, platform, false));
+            R_RETURN(LoadMeta(out_meta, loc, status));
         }
         *out_meta = g_meta_cache.meta;
         R_SUCCEED();
diff --git a/stratosphere/loader/source/ldr_meta.hpp b/stratosphere/loader/source/ldr_meta.hpp
index 2ac88b63b..7356185da 100644
--- a/stratosphere/loader/source/ldr_meta.hpp
+++ b/stratosphere/loader/source/ldr_meta.hpp
@@ -36,8 +36,8 @@ namespace ams::ldr {
     };
 
     /* Meta API. */
-    Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform, bool unk_unused);
-    Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform);
+    Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status);
+    Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status);
     void   InvalidateMetaCache();
 
 }
diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp
index a7d657897..5c885f0dc 100644
--- a/stratosphere/loader/source/ldr_process_creation.cpp
+++ b/stratosphere/loader/source/ldr_process_creation.cpp
@@ -202,61 +202,7 @@ namespace ams::ldr {
             R_SUCCEED();
         }
 
-        constexpr const ncm::ProgramId UnqualifiedApprovalProgramIds[] = {
-            { 0x010003F003A34000 }, /* Pokemon: Let's Go, Pikachu! */
-            { 0x0100152000022000 }, /* Mario Kart 8 Deluxe */
-            { 0x0100165003504000 }, /* Nintendo Labo Toy-Con 04: VR Kit */
-            { 0x0100187003A36000 }, /* Pokemon: Let's Go, Eevee! */
-            { 0x01002E5008C56000 }, /* Pokemon Sword [Live Tournament] */
-            { 0x01002FF008C24000 }, /* Ring Fit Adventure */
-            { 0x010049900F546001 }, /* Super Mario 3D All-Stars: Super Mario 64 */
-            { 0x010057D00ECE4000 }, /* Nintendo Switch Online (Nintendo 64) [for Japan] */
-            { 0x01006F8002326000 }, /* Animal Crossing: New Horizons */
-            { 0x01006FB00F50E000 }, /* [???] */
-            { 0x010070300F50C000 }, /* [???] */
-            { 0x010075100E8EC000 }, /* 马力欧卡丁车8 豪华版 [Mario Kart 8 Deluxe for China] */
-            { 0x01008DB008C2C000 }, /* Pokemon Shield */
-            { 0x01009AD008C4C000 }, /* Pokemon: Let's Go, Pikachu! [Kiosk] */
-            { 0x0100A66003384000 }, /* Hulu */
-            { 0x0100ABF008968000 }, /* Pokemon Sword */
-            { 0x0100C9A00ECE6000 }, /* Nintendo Switch Online (Nintendo 64) [for America] */
-            { 0x0100ED100BA3A000 }, /* Mario Kart Live: Home Circuit */
-            { 0x0100F38011CFE000 }, /* Animal Crossing: New Horizons Island Transfer Tool */
-            { 0x0100F6B011028000 }, /* 健身环大冒险 [Ring Fit Adventure for China] */
-        };
-
-        /* Check that the unqualified approval programs are sorted. */
-        static_assert([]() -> bool {
-            for (size_t i = 0; i < util::size(UnqualifiedApprovalProgramIds) - 1; ++i) {
-                if (UnqualifiedApprovalProgramIds[i].value >= UnqualifiedApprovalProgramIds[i + 1].value) {
-                    return false;
-                }
-            }
-
-            return true;
-        }());
-
-        bool IsUnqualifiedApprovalProgramId(ncm::ProgramId program_id) {
-            /* Check if the program id is one with unqualified approval. */
-            return std::binary_search(std::begin(UnqualifiedApprovalProgramIds), std::end(UnqualifiedApprovalProgramIds), program_id);
-        }
-
-        bool IsUnqualifiedApproval(const Meta *meta) {
-            /* If the meta has unqualified approval flag, it's unqualified approval. */
-            if (meta->acid->flags & ldr::Acid::AcidFlag_UnqualifiedApproval) {
-                return true;
-            }
-
-            /* If the unqualified approval flag is not set, the program must be an application. */
-            if (!IsApplication(meta)) {
-                return false;
-            }
-
-            /* The program id must be a force unqualified approval program id. */
-            return IsUnqualifiedApprovalProgramId(meta->acid->program_id_min) && meta->acid->program_id_min == meta->acid->program_id_max;
-        }
-
-        Result ValidateMeta(const Meta *meta, const ncm::ProgramLocation &loc, const fs::CodeVerificationData &code_verification_data) {
+        Result ValidateMeta(const Meta *meta, const ncm::ProgramLocation &loc) {
             /* Validate version. */
             R_TRY(ValidateProgramVersion(loc.program_id, meta->npdm->version));
 
@@ -267,29 +213,6 @@ namespace ams::ldr {
             /* Validate the kernel capabilities. */
             R_TRY(TestCapability(static_cast<const util::BitPack32 *>(meta->acid_kac), meta->acid->kac_size / sizeof(util::BitPack32), static_cast<const util::BitPack32 *>(meta->aci_kac), meta->aci->kac_size / sizeof(util::BitPack32)));
 
-            /* If we have data to validate, validate it. */
-            if (meta->check_verification_data) {
-                const u8 *sig         = code_verification_data.signature;
-                const size_t sig_size = sizeof(code_verification_data.signature);
-                const u8 *mod         = static_cast<u8 *>(meta->modulus);
-                const size_t mod_size = crypto::Rsa2048PssSha256Verifier::ModulusSize;
-                const u8 *exp         = fssystem::GetAcidSignatureKeyPublicExponent();
-                const size_t exp_size = fssystem::AcidSignatureKeyPublicExponentSize;
-                const u8 *hsh         = code_verification_data.target_hash;
-                const size_t hsh_size = sizeof(code_verification_data.target_hash);
-                const bool is_signature_valid = crypto::VerifyRsa2048PssSha256WithHash(sig, sig_size, mod, mod_size, exp, exp_size, hsh, hsh_size);
-
-                /* If the signature check fails, we need to check if this is allowable. */
-                if (!is_signature_valid) {
-                    /* We have to enforce signature checks on prod and when we have a signature to check on dev. */
-                    R_UNLESS(IsDevelopmentForAcidProductionCheck(), ldr::ResultInvalidNcaSignature());
-                    R_UNLESS(!code_verification_data.has_data,      ldr::ResultInvalidNcaSignature());
-
-                    /* There was no signature to check on dev. Check if this is acceptable. */
-                    R_UNLESS(IsUnqualifiedApproval(meta), ldr::ResultInvalidNcaSignature());
-                }
-            }
-
             /* All good. */
             R_SUCCEED();
         }
@@ -672,10 +595,10 @@ namespace ams::ldr {
 
         /* Load meta, possibly from cache. */
         Meta meta;
-        R_TRY(LoadMetaFromCache(std::addressof(meta), loc, override_status, platform));
+        R_TRY(LoadMetaFromCache(std::addressof(meta), loc, override_status));
 
         /* Validate meta. */
-        R_TRY(ValidateMeta(std::addressof(meta), loc, mount.GetCodeVerificationData()));
+        R_TRY(ValidateMeta(std::addressof(meta), loc));
 
         /* Load, validate NSO headers. */
         R_TRY(LoadAutoLoadHeaders(g_nso_headers, g_has_nso));
@@ -729,7 +652,7 @@ namespace ams::ldr {
 
             ScopedCodeMount mount(loc, platform);
             R_TRY(mount.GetResult());
-            R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus(), platform, false));
+            R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus()));
             if (out_status != nullptr) {
                 *out_status = mount.GetOverrideStatus();
             }
--
2.45.2
 
Last edited by 4d1xlaan,

josete2k

Well-Known Member
Member
Joined
Apr 24, 2009
Messages
773
Trophies
1
Age
44
Location
Spain
XP
1,859
Country
Spain
I'll make a diff hold on

it's also possible I forgot some steps, if there are any unused variables left over it will give errors (normally a warning, but the build treats warnings as errors and stops the build)
Post automatically merged:

there were new changes in 18.0.0 loader that makes it so you need to remove way more stuff now. my old patch worked for 1.7.0 and for a long time before too, but any later commits a bunch more stuff needs to be changed

I havent tested it, I see no reason why it wouldnt work but I would appreciate if someone wants to test and confirm


Code:
From: 4d1xlaan <[email protected]>
Date: Wed, 5 Jun 2024 19:09:01 -0400
Subject: [PATCH] stuff

---
 stratosphere/loader/source/ldr_meta.cpp       | 42 +--------
 stratosphere/loader/source/ldr_meta.hpp       |  4 +-
 .../loader/source/ldr_process_creation.cpp    | 85 +------------------
 3 files changed, 9 insertions(+), 122 deletions(-)

diff --git a/stratosphere/loader/source/ldr_meta.cpp b/stratosphere/loader/source/ldr_meta.cpp
index ee43aeedc..f3bfc5433 100644
--- a/stratosphere/loader/source/ldr_meta.cpp
+++ b/stratosphere/loader/source/ldr_meta.cpp
@@ -103,41 +103,6 @@ namespace ams::ldr {
             R_SUCCEED();
         }
 
-        const u8 *GetAcidSignatureModulus(PlatformId platform, u8 key_generation, bool unk_unused) {
-            return fssystem::GetAcidSignatureKeyModulus(platform, !IsDevelopmentForAcidSignatureCheck(), key_generation, unk_unused);
-        }
-
-        size_t GetAcidSignatureModulusSize(PlatformId platform, bool unk_unused) {
-            return fssystem::GetAcidSignatureKeyModulusSize(platform, unk_unused);
-        }
-
-        Result ValidateAcidSignature(Meta *meta, PlatformId platform, bool unk_unused) {
-            /* Loader did not check signatures prior to 10.0.0. */
-            if (hos::GetVersion() < hos::Version_10_0_0) {
-                meta->check_verification_data = false;
-                R_SUCCEED();
-            }
-
-            /* Get the signature key generation. */
-            const auto signature_key_generation = meta->npdm->signature_key_generation;
-            R_UNLESS(fssystem::IsValidSignatureKeyGeneration(platform, signature_key_generation), ldr::ResultInvalidMeta());
-
-            /* Verify the signature. */
-            const u8 *sig         = meta->acid->signature;
-            const size_t sig_size = sizeof(meta->acid->signature);
-            const u8 *mod         = GetAcidSignatureModulus(platform, signature_key_generation, unk_unused);
-            const size_t mod_size = GetAcidSignatureModulusSize(platform, unk_unused);
-            const u8 *exp         = fssystem::GetAcidSignatureKeyPublicExponent();
-            const size_t exp_size = fssystem::AcidSignatureKeyPublicExponentSize;
-            const u8 *msg         = meta->acid->modulus;
-            const size_t msg_size = meta->acid->size;
-            const bool is_signature_valid = crypto::VerifyRsa2048PssSha256(sig, sig_size, mod, mod_size, exp, exp_size, msg, msg_size);
-            R_UNLESS(is_signature_valid || !IsEnabledProgramVerification(), ldr::ResultInvalidAcidSignature());
-
-            meta->check_verification_data = is_signature_valid;
-            R_SUCCEED();
-        }
-
         Result LoadMetaFromFile(fs::FileHandle file, MetaCache *cache) {
             /* Reset cache. */
             cache->meta = {};
@@ -190,7 +155,7 @@ namespace ams::ldr {
     }
 
     /* API. */
-    Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform, bool unk_unused) {
+    Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) {
         /* Set the cached program id back to zero. */
         g_cached_program_id = {};
 
@@ -259,7 +224,6 @@ namespace ams::ldr {
                 R_TRY(fs::OpenFile(std::addressof(file), BaseMetaPath, fs::OpenMode_Read));
                 ON_SCOPE_EXIT { fs::CloseFile(file); };
                 R_TRY(LoadMetaFromFile(file, std::addressof(g_original_meta_cache)));
-                R_TRY(ValidateAcidSignature(std::addressof(g_original_meta_cache.meta), platform, unk_unused));
                 meta->modulus                 = g_original_meta_cache.meta.modulus;
                 meta->check_verification_data = g_original_meta_cache.meta.check_verification_data;
             }
@@ -278,9 +242,9 @@ namespace ams::ldr {
         R_SUCCEED();
     }
 
-    Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform) {
+    Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) {
         if (g_cached_program_id != loc.program_id || g_cached_override_status != status) {
-            R_RETURN(LoadMeta(out_meta, loc, status, platform, false));
+            R_RETURN(LoadMeta(out_meta, loc, status));
         }
         *out_meta = g_meta_cache.meta;
         R_SUCCEED();
diff --git a/stratosphere/loader/source/ldr_meta.hpp b/stratosphere/loader/source/ldr_meta.hpp
index 2ac88b63b..7356185da 100644
--- a/stratosphere/loader/source/ldr_meta.hpp
+++ b/stratosphere/loader/source/ldr_meta.hpp
@@ -36,8 +36,8 @@ namespace ams::ldr {
     };
 
     /* Meta API. */
-    Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform, bool unk_unused);
-    Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform);
+    Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status);
+    Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status);
     void   InvalidateMetaCache();
 
 }
diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp
index a7d657897..5c885f0dc 100644
--- a/stratosphere/loader/source/ldr_process_creation.cpp
+++ b/stratosphere/loader/source/ldr_process_creation.cpp
@@ -202,61 +202,7 @@ namespace ams::ldr {
             R_SUCCEED();
         }
 
-        constexpr const ncm::ProgramId UnqualifiedApprovalProgramIds[] = {
-            { 0x010003F003A34000 }, /* Pokemon: Let's Go, Pikachu! */
-            { 0x0100152000022000 }, /* Mario Kart 8 Deluxe */
-            { 0x0100165003504000 }, /* Nintendo Labo Toy-Con 04: VR Kit */
-            { 0x0100187003A36000 }, /* Pokemon: Let's Go, Eevee! */
-            { 0x01002E5008C56000 }, /* Pokemon Sword [Live Tournament] */
-            { 0x01002FF008C24000 }, /* Ring Fit Adventure */
-            { 0x010049900F546001 }, /* Super Mario 3D All-Stars: Super Mario 64 */
-            { 0x010057D00ECE4000 }, /* Nintendo Switch Online (Nintendo 64) [for Japan] */
-            { 0x01006F8002326000 }, /* Animal Crossing: New Horizons */
-            { 0x01006FB00F50E000 }, /* [???] */
-            { 0x010070300F50C000 }, /* [???] */
-            { 0x010075100E8EC000 }, /* 马力欧卡丁车8 豪华版 [Mario Kart 8 Deluxe for China] */
-            { 0x01008DB008C2C000 }, /* Pokemon Shield */
-            { 0x01009AD008C4C000 }, /* Pokemon: Let's Go, Pikachu! [Kiosk] */
-            { 0x0100A66003384000 }, /* Hulu */
-            { 0x0100ABF008968000 }, /* Pokemon Sword */
-            { 0x0100C9A00ECE6000 }, /* Nintendo Switch Online (Nintendo 64) [for America] */
-            { 0x0100ED100BA3A000 }, /* Mario Kart Live: Home Circuit */
-            { 0x0100F38011CFE000 }, /* Animal Crossing: New Horizons Island Transfer Tool */
-            { 0x0100F6B011028000 }, /* 健身环大冒险 [Ring Fit Adventure for China] */
-        };
-
-        /* Check that the unqualified approval programs are sorted. */
-        static_assert([]() -> bool {
-            for (size_t i = 0; i < util::size(UnqualifiedApprovalProgramIds) - 1; ++i) {
-                if (UnqualifiedApprovalProgramIds[i].value >= UnqualifiedApprovalProgramIds[i + 1].value) {
-                    return false;
-                }
-            }
-
-            return true;
-        }());
-
-        bool IsUnqualifiedApprovalProgramId(ncm::ProgramId program_id) {
-            /* Check if the program id is one with unqualified approval. */
-            return std::binary_search(std::begin(UnqualifiedApprovalProgramIds), std::end(UnqualifiedApprovalProgramIds), program_id);
-        }
-
-        bool IsUnqualifiedApproval(const Meta *meta) {
-            /* If the meta has unqualified approval flag, it's unqualified approval. */
-            if (meta->acid->flags & ldr::Acid::AcidFlag_UnqualifiedApproval) {
-                return true;
-            }
-
-            /* If the unqualified approval flag is not set, the program must be an application. */
-            if (!IsApplication(meta)) {
-                return false;
-            }
-
-            /* The program id must be a force unqualified approval program id. */
-            return IsUnqualifiedApprovalProgramId(meta->acid->program_id_min) && meta->acid->program_id_min == meta->acid->program_id_max;
-        }
-
-        Result ValidateMeta(const Meta *meta, const ncm::ProgramLocation &loc, const fs::CodeVerificationData &code_verification_data) {
+        Result ValidateMeta(const Meta *meta, const ncm::ProgramLocation &loc) {
             /* Validate version. */
             R_TRY(ValidateProgramVersion(loc.program_id, meta->npdm->version));
 
@@ -267,29 +213,6 @@ namespace ams::ldr {
             /* Validate the kernel capabilities. */
             R_TRY(TestCapability(static_cast<const util::BitPack32 *>(meta->acid_kac), meta->acid->kac_size / sizeof(util::BitPack32), static_cast<const util::BitPack32 *>(meta->aci_kac), meta->aci->kac_size / sizeof(util::BitPack32)));
 
-            /* If we have data to validate, validate it. */
-            if (meta->check_verification_data) {
-                const u8 *sig         = code_verification_data.signature;
-                const size_t sig_size = sizeof(code_verification_data.signature);
-                const u8 *mod         = static_cast<u8 *>(meta->modulus);
-                const size_t mod_size = crypto::Rsa2048PssSha256Verifier::ModulusSize;
-                const u8 *exp         = fssystem::GetAcidSignatureKeyPublicExponent();
-                const size_t exp_size = fssystem::AcidSignatureKeyPublicExponentSize;
-                const u8 *hsh         = code_verification_data.target_hash;
-                const size_t hsh_size = sizeof(code_verification_data.target_hash);
-                const bool is_signature_valid = crypto::VerifyRsa2048PssSha256WithHash(sig, sig_size, mod, mod_size, exp, exp_size, hsh, hsh_size);
-
-                /* If the signature check fails, we need to check if this is allowable. */
-                if (!is_signature_valid) {
-                    /* We have to enforce signature checks on prod and when we have a signature to check on dev. */
-                    R_UNLESS(IsDevelopmentForAcidProductionCheck(), ldr::ResultInvalidNcaSignature());
-                    R_UNLESS(!code_verification_data.has_data,      ldr::ResultInvalidNcaSignature());
-
-                    /* There was no signature to check on dev. Check if this is acceptable. */
-                    R_UNLESS(IsUnqualifiedApproval(meta), ldr::ResultInvalidNcaSignature());
-                }
-            }
-
             /* All good. */
             R_SUCCEED();
         }
@@ -672,10 +595,10 @@ namespace ams::ldr {
 
         /* Load meta, possibly from cache. */
         Meta meta;
-        R_TRY(LoadMetaFromCache(std::addressof(meta), loc, override_status, platform));
+        R_TRY(LoadMetaFromCache(std::addressof(meta), loc, override_status));
 
         /* Validate meta. */
-        R_TRY(ValidateMeta(std::addressof(meta), loc, mount.GetCodeVerificationData()));
+        R_TRY(ValidateMeta(std::addressof(meta), loc));
 
         /* Load, validate NSO headers. */
         R_TRY(LoadAutoLoadHeaders(g_nso_headers, g_has_nso));
@@ -729,7 +652,7 @@ namespace ams::ldr {
 
             ScopedCodeMount mount(loc, platform);
             R_TRY(mount.GetResult());
-            R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus(), platform, false));
+            R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus()));
             if (out_status != nullptr) {
                 *out_status = mount.GetOverrideStatus();
             }
--
2.45.2
Wow...

Thanks. I'll test tomorrow
 

4d1xlaan

Well-Known Member
Member
Joined
Apr 21, 2024
Messages
831
Trophies
0
XP
849
Country
United States
you could also patch it in a smaller way by just forcing the functions to return success, but removing the signature checking functionality entirely is cleaner imo. we like clean code here, no hacks

Done!

Working here, thanks.

EDIT: I've reenabled sys-patch ldr pacth and now it is shown as green.
working, as in, stuff runs on console, or working as in just the build?

green in sys patch implies it wasnt already pre-patched and sys patch had to do it

I need to know if this removes signature checking correctly, I already know it builds fine
 

4d1xlaan

Well-Known Member
Member
Joined
Apr 21, 2024
Messages
831
Trophies
0
XP
849
Country
United States
save that text into a .patch file, put it at the root of your repo

then git apply name-of-file.patch

edit: it does not actually work, I dont know why. but if you manually apply the changes, it should be good?

edit 2: use patch -p1 < name-of-file.patch
 
Last edited by 4d1xlaan,
  • Like
Reactions: josete2k

impeeza

¡Kabito!
OP
Member
Joined
Apr 5, 2011
Messages
7,439
Trophies
4
Age
46
Location
At my chair.
XP
23,921
Country
Colombia
save that text into a .patch file, put it at the root of your repo

then git apply name-of-file.patch

edit: it does not actually work, I dont know why. but if you manually apply the changes, it should be good?

edit 2: use patch -p1 < name-of-file.patch
Ah, OK, I haven't see your full message :P

thanks
 

josete2k

Well-Known Member
Member
Joined
Apr 24, 2009
Messages
773
Trophies
1
Age
44
Location
Spain
XP
1,859
Country
Spain
you could also patch it in a smaller way by just forcing the functions to return success, but removing the signature checking functionality entirely is cleaner imo. we like clean code here, no hacks


working, as in, stuff runs on console, or working as in just the build?

green in sys patch implies it wasnt already pre-patched and sys patch had to do it

I need to know if this removes signature checking correctly, I already know it builds fine
Yes yes, it's working even without sys-patch.

But if I enable sys-patch, the ldr noacidchk is on Green again, so that means that sys-patch pattern is present again with your changes (that pattern was missing with the unedited ldr with latest ams commit).
 
  • Love
Reactions: impeeza

4d1xlaan

Well-Known Member
Member
Joined
Apr 21, 2024
Messages
831
Trophies
0
XP
849
Country
United States
did sys patch work on atmosphere latest commit, without these changes?

what you're telling me is that sys patch couldnt find the pattern on unedited atmosphere loader, so it wasnt patching anything. which to me sounds like sys patch isnt working on atmosphere 18.0.0 loader, yes? so sys patch would need an update for 18.0.0 loader
 
  • Like
Reactions: impeeza

4d1xlaan

Well-Known Member
Member
Joined
Apr 21, 2024
Messages
831
Trophies
0
XP
849
Country
United States
ok, well there you go. y'all can use this in the meantime

I dont think it will take them too long to figure it out since the code is open
 
  • Like
Reactions: impeeza

impeeza

¡Kabito!
OP
Member
Joined
Apr 5, 2011
Messages
7,439
Trophies
4
Age
46
Location
At my chair.
XP
23,921
Country
Colombia
Ok testing your file and creating one for the re-enable of FS patch processing, SciresM yesterday committed the GCC-14 branch so no need to manually commit it.
Post automatically merged:

Ok testing your file and creating one for the re-enable of FS patch processing, SciresM yesterday committed the GCC-14 branch so no need to manually commit it.
Well

After applying the patches for disable checks and re-enable the FS Sigpatches processing all working «fine»:

1717712731468.png

So far I am using this two patches
 

Attachments

  • Remoción procesamiento parches FS.zip
    5.1 KB · Views: 13
Last edited by impeeza,

4d1xlaan

Well-Known Member
Member
Joined
Apr 21, 2024
Messages
831
Trophies
0
XP
849
Country
United States
Including es or fs patches in the source is not useful imo, because atmosphere doesnt reimplement these modules so it's always the same for every given hos version. You can just have exefs patches for es + the fs patches in hekate and they'll always work. For loader it's different since the module is entirely reimplemented in atmosphere, loader might be different depending on your build so a one size fits all patch isnt helpful, so you remove the signature checking in the code because you can

I mean yeah I guess it's cool not to need patch files on the sd card, but you need to hardcode the patch data in the source for each module revision and rebuild the entire thing just to add support for new es/fs, might as well just add one file in sd and a couple lines in patches.ini instead because the end result is the same and it's less effort. It's the exact same patch data, just applied in a different way

If atmosphere ever reimplements es and fs then it might be cool to custom build it with the signature checking functionality stripped out, instead of patching it to force it to return true
 
  • Like
Reactions: josete2k

impeeza

¡Kabito!
OP
Member
Joined
Apr 5, 2011
Messages
7,439
Trophies
4
Age
46
Location
At my chair.
XP
23,921
Country
Colombia
Hi. Can't compile with updated packages (ModuleNotFoundError: No module named 'lz4')


...
Let me try. Be sure you have the packages «lz4» & «mingw-w64-x86_64-python-lz4» installed on your MinGW.

I will try to build just now.
Post automatically merged:

For me the steps are working fine:

1721074085719.png

your error is not all prerequisites are meet, install al packages

If you use MSYS2's MSYS environment
Bash:
Pacman -Syuu --noconfirm --needed zip git make lz4 libnx devkitA64 devkitARM devkitarm-rules hactool switch-dev dkp-toolchain-vars switch-tools switch-mesa switch-libdrm_nouveau switch-sdl2 switch-libjpeg-turbo switch-glm gcc python python-pip
pip install lz4 pycryptodome


If you use MSYS2's MinGW64 environment
Code:
Pacman -Syuu --noconfirm --needed zip git make lz4 libnx devkitA64 devkitARM devkitarm-rules hactool switch-dev dkp-toolchain-vars switch-tools switch-mesa switch-libdrm_nouveau switch-sdl2 switch-libjpeg-turbo switch-glm mingw-w64-x86_64-python mingw-w64-x86_64-python-lz4 mingw-w64-x86_64-python-pycryptodome mingw-w64-x86_64-python-pip
 
Last edited by impeeza,
  • Like
Reactions: josete2k

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    Cranesbill @ Cranesbill: Greetings, Gentlemen