From 5b70938f9105c0e30f38511c50564fa82b3213d7 Mon Sep 17 00:00:00 2001 From: souldbminersmwc Date: Thu, 13 Aug 2026 18:40:51 -0400 Subject: [PATCH] nvservices debug unlock + license change --- .../loader/source/ldr_process_creation.cpp | 8 +- .../loader/source/oc/nvsrv/nvsrv.cpp | 102 ++++++++++++++++++ .../loader/source/oc/nvsrv/nvsrv.hpp | 23 ++++ .../loader/source/oc/oc_common.hpp | 1 + .../loader/source/oc/oc_loader.hpp | 1 + .../source/oc/pcv/mariko/pcv_mariko.cpp | 2 +- .../source/oc/pcv/mariko/pcv_mariko_cpu.cpp | 2 +- .../source/oc/pcv/mariko/pcv_mariko_cpu.hpp | 2 +- .../source/oc/pcv/mariko/pcv_mariko_gpu.cpp | 2 +- .../source/oc/pcv/mariko/pcv_mariko_gpu.hpp | 2 +- .../source/oc/pcv/mariko/pcv_mariko_mtc.cpp | 2 +- .../source/oc/pcv/mariko/pcv_mariko_mtc.hpp | 2 +- .../src/ui/gui/global_override_gui.cpp | 2 +- .../hoc-clk/sysmodule/src/file/file_utils.cpp | 2 +- .../hoc-clk/sysmodule/src/mapping/mem_map.cpp | 2 +- .../hoc-clk/sysmodule/src/mapping/mem_map.hpp | 2 +- Source/hoc-clk/sysmodule/src/mgr/governor.cpp | 2 +- Source/hoc-clk/sysmodule/src/mgr/governor.hpp | 2 +- 18 files changed, 147 insertions(+), 14 deletions(-) create mode 100644 Source/Atmosphere/stratosphere/loader/source/oc/nvsrv/nvsrv.cpp create mode 100644 Source/Atmosphere/stratosphere/loader/source/oc/nvsrv/nvsrv.hpp diff --git a/Source/Atmosphere/stratosphere/loader/source/ldr_process_creation.cpp b/Source/Atmosphere/stratosphere/loader/source/ldr_process_creation.cpp index 0baf0b56..09cafb2d 100644 --- a/Source/Atmosphere/stratosphere/loader/source/ldr_process_creation.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/ldr_process_creation.cpp @@ -121,9 +121,10 @@ namespace ams::ldr { /* Global NSO header cache. */ NsoHeader g_nso_headers[Nso_Count]; - /* Pcv/Ptm check cache */ + /* Pcv/Ptm/NvServices check cache */ bool g_is_pcv; bool g_is_ptm; + bool g_is_nvsrv; /* Global Zstd decompression context. */ constexpr size_t ZstdDctxWorkspaceSize = 0x176E8; @@ -379,6 +380,7 @@ namespace ams::ldr { /* Check if NCA is PCV or PTM */ g_is_pcv = meta->aci->program_id == ncm::SystemProgramId::Pcv; g_is_ptm = meta->aci->program_id == ncm::SystemProgramId::Ptm; + g_is_nvsrv = meta->aci->program_id == ncm::SystemProgramId::NvServices; /* If we have data to validate, validate it. */ if (meta->check_verification_data) { @@ -752,6 +754,10 @@ namespace ams::ldr { if (g_is_ptm) { hoc::ptm::Patch(map_address, nso_size); } + + if (g_is_nvsrv) { + hoc::nvsrv::Patch(map_address, nso_size, nso_address); + } } /* Set permissions. */ diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/nvsrv/nvsrv.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/nvsrv/nvsrv.cpp new file mode 100644 index 00000000..19e6bfcf --- /dev/null +++ b/Source/Atmosphere/stratosphere/loader/source/oc/nvsrv/nvsrv.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "nvsrv.hpp" + +namespace ams::ldr::hoc::nvsrv { + + namespace { + + /* NvServices device names */ + constexpr char DbgGpuPath[] = "/dev/nvhost-dbg-gpu"; + constexpr char ProfGpuPath[] = "/dev/nvhost-prof-gpu"; + + /* Permission offset to patch */ + constexpr size_t DevTablePermOffset = 0x68; + + uintptr_t FindBytes(uintptr_t start, uintptr_t end, const void *needle, size_t len) { + const u8 *pat = reinterpret_cast(needle); + for (uintptr_t addr = start; addr + len <= end; ++addr) { + if (std::memcmp(reinterpret_cast(addr), pat, len) == 0) { + return addr; + } + } + return 0; + } + + /* Unlock the devices */ + Result UnlockDevicePermission(uintptr_t mapped_nso, size_t nso_size, uintptr_t nso_address, const char *path, const char *description) { + const size_t path_len = std::strlen(path) + 1; + + const uintptr_t str_addr = FindBytes(mapped_nso, mapped_nso + nso_size, path, path_len); + if (str_addr == 0) { + LOGGING("nvsrv: %s path string not found (nso_size=%lx)", description, static_cast(nso_size)); + R_THROW(ldr::ResultInvalidNvsrvDevTable()); + } + + const uintptr_t str_offset = str_addr - mapped_nso; + const uintptr_t candidates[] = { str_offset, nso_address + str_offset }; + + uintptr_t entry_addr = 0; + for (uintptr_t ptr = mapped_nso; entry_addr == 0 && ptr + sizeof(uintptr_t) <= mapped_nso + nso_size; ptr += sizeof(uintptr_t)) { + const uintptr_t val = *reinterpret_cast(ptr); + for (uintptr_t cand : candidates) { + if (val == cand) { + entry_addr = ptr; + break; + } + } + } + if (entry_addr == 0) { + LOGGING("nvsrv: %s str@+%lx has no referencing table entry", description, + static_cast(str_offset), static_cast(candidates[0]), static_cast(candidates[1])); + R_THROW(ldr::ResultInvalidNvsrvDevTable()); + } + + const uintptr_t perm_addr = entry_addr + DevTablePermOffset; + if (perm_addr + sizeof(uintptr_t) > mapped_nso + nso_size) { + LOGGING("nvsrv: %s entry@+%lx perm field out of bounds", description, static_cast(entry_addr - mapped_nso)); + R_THROW(ldr::ResultInvalidNvsrvDevTable()); + } + + uintptr_t *perm = reinterpret_cast(perm_addr); + LOGGING("nvsrv: %s entry@+%lx perm@+%lx was %lx", description, + static_cast(entry_addr - mapped_nso), + static_cast(perm_addr - mapped_nso), + static_cast(*perm)); + + PATCH_OFFSET(perm, static_cast(0)); + R_SUCCEED(); + } + + } + + void Patch(uintptr_t mapped_nso, size_t nso_size, uintptr_t nso_address) { + struct { + const char *path; + const char *description; + } targets[] = { + { DbgGpuPath, "dbg-gpu" }, + { ProfGpuPath, "prof-gpu" }, + }; + + for (auto &t : targets) { + const Result res = UnlockDevicePermission(mapped_nso, nso_size, nso_address, t.path, t.description); + LOGGING("nvsrv: %s unlock%s", t.description, R_SUCCEEDED(res) ? "ed" : " skipped"); + } + } + +} diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/nvsrv/nvsrv.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/nvsrv/nvsrv.hpp new file mode 100644 index 00000000..4c551a33 --- /dev/null +++ b/Source/Atmosphere/stratosphere/loader/source/oc/nvsrv/nvsrv.hpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "../oc_common.hpp" + +namespace ams::ldr::hoc::nvsrv { + void Patch(uintptr_t mapped_nso, size_t nso_size, uintptr_t nso_address); +} diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/oc_common.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/oc_common.hpp index 9440aaf8..2e79da3b 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/oc_common.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/oc_common.hpp @@ -94,6 +94,7 @@ namespace ams::ldr { R_DEFINE_ERROR_RESULT(HookPayloadEscapes, 1028); R_DEFINE_ERROR_RESULT(HookDataOutOfMemory, 1029); R_DEFINE_ERROR_RESULT(HookUnavailable, 1030); + R_DEFINE_ERROR_RESULT(InvalidNvsrvDevTable, 1031); } namespace ams::ldr::hoc { diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/oc_loader.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/oc_loader.hpp index 4396226a..717f95bb 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/oc_loader.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/oc_loader.hpp @@ -21,3 +21,4 @@ #include "oc_common.hpp" #include "pcv/pcv.hpp" #include "ptm/ptm.hpp" +#include "nvsrv/nvsrv.hpp" \ No newline at end of file diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko.cpp index 331d988d..0c65ea57 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko.cpp @@ -5,7 +5,7 @@ * * Copyright (c) B3711 * - * Copyright (c) Souldbminer and Horizon OC Contributors + * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_cpu.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_cpu.cpp index 4bc8cb93..64e48b70 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_cpu.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_cpu.cpp @@ -5,7 +5,7 @@ * * Copyright (c) B3711 * - * Copyright (c) Souldbminer and Horizon OC Contributors + * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_cpu.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_cpu.hpp index d572857e..d44f90b4 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_cpu.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_cpu.hpp @@ -5,7 +5,7 @@ * * Copyright (c) B3711 * - * Copyright (c) Souldbminer and Horizon OC Contributors + * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_gpu.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_gpu.cpp index 89a68aef..8ad01318 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_gpu.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_gpu.cpp @@ -5,7 +5,7 @@ * * Copyright (c) B3711 * - * Copyright (c) Souldbminer and Horizon OC Contributors + * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_gpu.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_gpu.hpp index a56a5ff2..4c00ba74 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_gpu.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_gpu.hpp @@ -5,7 +5,7 @@ * * Copyright (c) B3711 * - * Copyright (c) Souldbminer and Horizon OC Contributors + * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_mtc.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_mtc.cpp index d230a276..e848a628 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_mtc.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_mtc.cpp @@ -5,7 +5,7 @@ * * Copyright (c) B3711 * - * Copyright (c) Souldbminer and Horizon OC Contributors + * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_mtc.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_mtc.hpp index 3072b1cf..031dff24 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_mtc.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/mariko/pcv_mariko_mtc.hpp @@ -5,7 +5,7 @@ * * Copyright (c) B3711 * - * Copyright (c) Souldbminer and Horizon OC Contributors + * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/Source/hoc-clk/overlay/src/ui/gui/global_override_gui.cpp b/Source/hoc-clk/overlay/src/ui/gui/global_override_gui.cpp index 25a8cd0f..3c16758b 100644 --- a/Source/hoc-clk/overlay/src/ui/gui/global_override_gui.cpp +++ b/Source/hoc-clk/overlay/src/ui/gui/global_override_gui.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) Souldbminer and Horizon OC Contributors + * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/Source/hoc-clk/sysmodule/src/file/file_utils.cpp b/Source/hoc-clk/sysmodule/src/file/file_utils.cpp index eb73f14a..8af7e964 100644 --- a/Source/hoc-clk/sysmodule/src/file/file_utils.cpp +++ b/Source/hoc-clk/sysmodule/src/file/file_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Souldbminer and Horizon OC Contributors + * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/Source/hoc-clk/sysmodule/src/mapping/mem_map.cpp b/Source/hoc-clk/sysmodule/src/mapping/mem_map.cpp index 860df53d..ae34021a 100644 --- a/Source/hoc-clk/sysmodule/src/mapping/mem_map.cpp +++ b/Source/hoc-clk/sysmodule/src/mapping/mem_map.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Souldbminer and Horizon OC Contributors + * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/Source/hoc-clk/sysmodule/src/mapping/mem_map.hpp b/Source/hoc-clk/sysmodule/src/mapping/mem_map.hpp index d2f76373..6cb6e1be 100644 --- a/Source/hoc-clk/sysmodule/src/mapping/mem_map.hpp +++ b/Source/hoc-clk/sysmodule/src/mapping/mem_map.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Souldbminer and Horizon OC Contributors + * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/Source/hoc-clk/sysmodule/src/mgr/governor.cpp b/Source/hoc-clk/sysmodule/src/mgr/governor.cpp index 3bd87f44..670f2636 100644 --- a/Source/hoc-clk/sysmodule/src/mgr/governor.cpp +++ b/Source/hoc-clk/sysmodule/src/mgr/governor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Souldbminer and Horizon OC Contributors + * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/Source/hoc-clk/sysmodule/src/mgr/governor.hpp b/Source/hoc-clk/sysmodule/src/mgr/governor.hpp index 0622eee1..d9f2cb43 100644 --- a/Source/hoc-clk/sysmodule/src/mgr/governor.hpp +++ b/Source/hoc-clk/sysmodule/src/mgr/governor.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Souldbminer and Horizon OC Contributors + * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License,