summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Morph2020-11-29 10:54:09 -0500
committerGravatar Morph2020-12-18 10:33:28 -0500
commitd46ca5a0157a5267b4c2ebf0515f1a492434071a (patch)
treea10347483315f757056382b4d552098d32c4e9f8 /src
parentns_vm: Stub NeedsUpdateVulnerability (diff)
downloadyuzu-d46ca5a0157a5267b4c2ebf0515f1a492434071a.tar.gz
yuzu-d46ca5a0157a5267b4c2ebf0515f1a492434071a.tar.xz
yuzu-d46ca5a0157a5267b4c2ebf0515f1a492434071a.zip
pl_u, applets/web: Decrypt shared fonts to TTF files
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/am/applets/web_browser.cpp86
-rw-r--r--src/core/hle/service/ns/pl_u.cpp30
-rw-r--r--src/core/hle/service/ns/pl_u.h19
3 files changed, 117 insertions, 18 deletions
diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp
index c0c98ad30..02ce9f387 100644
--- a/src/core/hle/service/am/applets/web_browser.cpp
+++ b/src/core/hle/service/am/applets/web_browser.cpp
@@ -16,12 +16,14 @@
16#include "core/file_sys/romfs.h" 16#include "core/file_sys/romfs.h"
17#include "core/file_sys/system_archive/system_archive.h" 17#include "core/file_sys/system_archive/system_archive.h"
18#include "core/file_sys/vfs_types.h" 18#include "core/file_sys/vfs_types.h"
19#include "core/file_sys/vfs_vector.h"
19#include "core/frontend/applets/web_browser.h" 20#include "core/frontend/applets/web_browser.h"
20#include "core/hle/kernel/process.h" 21#include "core/hle/kernel/process.h"
21#include "core/hle/result.h" 22#include "core/hle/result.h"
22#include "core/hle/service/am/am.h" 23#include "core/hle/service/am/am.h"
23#include "core/hle/service/am/applets/web_browser.h" 24#include "core/hle/service/am/applets/web_browser.h"
24#include "core/hle/service/filesystem/filesystem.h" 25#include "core/hle/service/filesystem/filesystem.h"
26#include "core/hle/service/ns/pl_u.h"
25 27
26namespace Service::AM::Applets { 28namespace Service::AM::Applets {
27 29
@@ -123,6 +125,88 @@ FileSys::VirtualFile GetOfflineRomFS(Core::System& system, u64 title_id,
123 } 125 }
124} 126}
125 127
128void ExtractSharedFonts(Core::System& system) {
129 static constexpr std::array<const char*, 7> DECRYPTED_SHARED_FONTS{
130 "FontStandard.ttf",
131 "FontChineseSimplified.ttf",
132 "FontExtendedChineseSimplified.ttf",
133 "FontChineseTraditional.ttf",
134 "FontKorean.ttf",
135 "FontNintendoExtended.ttf",
136 "FontNintendoExtended2.ttf",
137 };
138
139 for (std::size_t i = 0; i < NS::SHARED_FONTS.size(); ++i) {
140 const auto fonts_dir = Common::FS::SanitizePath(
141 fmt::format("{}/fonts", Common::FS::GetUserPath(Common::FS::UserPath::CacheDir)),
142 Common::FS::DirectorySeparator::PlatformDefault);
143
144 const auto font_file_path =
145 Common::FS::SanitizePath(fmt::format("{}/{}", fonts_dir, DECRYPTED_SHARED_FONTS[i]),
146 Common::FS::DirectorySeparator::PlatformDefault);
147
148 if (Common::FS::Exists(font_file_path)) {
149 continue;
150 }
151
152 const auto font = NS::SHARED_FONTS[i];
153 const auto font_title_id = static_cast<u64>(font.first);
154
155 const auto nca = system.GetFileSystemController().GetSystemNANDContents()->GetEntry(
156 font_title_id, FileSys::ContentRecordType::Data);
157
158 FileSys::VirtualFile romfs;
159
160 if (!nca) {
161 romfs = FileSys::SystemArchive::SynthesizeSystemArchive(font_title_id);
162 } else {
163 romfs = nca->GetRomFS();
164 }
165
166 if (!romfs) {
167 LOG_ERROR(Service_AM, "SharedFont RomFS with title_id={:016X} cannot be extracted!",
168 font_title_id);
169 continue;
170 }
171
172 const auto extracted_romfs = FileSys::ExtractRomFS(romfs);
173
174 if (!extracted_romfs) {
175 LOG_ERROR(Service_AM, "SharedFont RomFS with title_id={:016X} failed to extract!",
176 font_title_id);
177 continue;
178 }
179
180 const auto font_file = extracted_romfs->GetFile(font.second);
181
182 if (!font_file) {
183 LOG_ERROR(Service_AM, "SharedFont RomFS with title_id={:016X} has no font file \"{}\"!",
184 font_title_id, font.second);
185 continue;
186 }
187
188 std::vector<u32> font_data_u32(font_file->GetSize() / sizeof(u32));
189 font_file->ReadBytes<u32>(font_data_u32.data(), font_file->GetSize());
190
191 std::transform(font_data_u32.begin(), font_data_u32.end(), font_data_u32.begin(),
192 Common::swap32);
193
194 std::vector<u8> decrypted_data(font_file->GetSize() - 8);
195
196 NS::DecryptSharedFontToTTF(font_data_u32, decrypted_data);
197
198 FileSys::VirtualFile decrypted_font = std::make_shared<FileSys::VectorVfsFile>(
199 std::move(decrypted_data), DECRYPTED_SHARED_FONTS[i]);
200
201 const auto temp_dir =
202 system.GetFilesystem()->CreateDirectory(fonts_dir, FileSys::Mode::ReadWrite);
203
204 const auto out_file = temp_dir->CreateFile(DECRYPTED_SHARED_FONTS[i]);
205
206 FileSys::VfsRawCopy(decrypted_font, out_file);
207 }
208}
209
126} // namespace 210} // namespace
127 211
128WebBrowser::WebBrowser(Core::System& system_, const Core::Frontend::WebBrowserApplet& frontend_) 212WebBrowser::WebBrowser(Core::System& system_, const Core::Frontend::WebBrowserApplet& frontend_)
@@ -155,6 +239,8 @@ void WebBrowser::Initialize() {
155 LOG_DEBUG(Service_AM, "WebArgHeader: total_tlv_entries={}, shim_kind={}", 239 LOG_DEBUG(Service_AM, "WebArgHeader: total_tlv_entries={}, shim_kind={}",
156 web_arg_header.total_tlv_entries, web_arg_header.shim_kind); 240 web_arg_header.total_tlv_entries, web_arg_header.shim_kind);
157 241
242 ExtractSharedFonts(system);
243
158 switch (web_arg_header.shim_kind) { 244 switch (web_arg_header.shim_kind) {
159 case ShimKind::Shop: 245 case ShimKind::Shop:
160 InitializeShop(); 246 InitializeShop();
diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp
index c8a215845..71c7587db 100644
--- a/src/core/hle/service/ns/pl_u.cpp
+++ b/src/core/hle/service/ns/pl_u.cpp
@@ -27,29 +27,11 @@
27 27
28namespace Service::NS { 28namespace Service::NS {
29 29
30enum class FontArchives : u64 {
31 Extension = 0x0100000000000810,
32 Standard = 0x0100000000000811,
33 Korean = 0x0100000000000812,
34 ChineseTraditional = 0x0100000000000813,
35 ChineseSimple = 0x0100000000000814,
36};
37
38struct FontRegion { 30struct FontRegion {
39 u32 offset; 31 u32 offset;
40 u32 size; 32 u32 size;
41}; 33};
42 34
43constexpr std::array<std::pair<FontArchives, const char*>, 7> SHARED_FONTS{
44 std::make_pair(FontArchives::Standard, "nintendo_udsg-r_std_003.bfttf"),
45 std::make_pair(FontArchives::ChineseSimple, "nintendo_udsg-r_org_zh-cn_003.bfttf"),
46 std::make_pair(FontArchives::ChineseSimple, "nintendo_udsg-r_ext_zh-cn_003.bfttf"),
47 std::make_pair(FontArchives::ChineseTraditional, "nintendo_udjxh-db_zh-tw_003.bfttf"),
48 std::make_pair(FontArchives::Korean, "nintendo_udsg-r_ko_003.bfttf"),
49 std::make_pair(FontArchives::Extension, "nintendo_ext_003.bfttf"),
50 std::make_pair(FontArchives::Extension, "nintendo_ext2_003.bfttf"),
51};
52
53// The below data is specific to shared font data dumped from Switch on f/w 2.2 35// The below data is specific to shared font data dumped from Switch on f/w 2.2
54// Virtual address and offsets/sizes likely will vary by dump 36// Virtual address and offsets/sizes likely will vary by dump
55[[maybe_unused]] constexpr VAddr SHARED_FONT_MEM_VADDR{0x00000009d3016000ULL}; 37[[maybe_unused]] constexpr VAddr SHARED_FONT_MEM_VADDR{0x00000009d3016000ULL};
@@ -80,6 +62,18 @@ static void DecryptSharedFont(const std::vector<u32>& input, Kernel::PhysicalMem
80 offset += transformed_font.size() * sizeof(u32); 62 offset += transformed_font.size() * sizeof(u32);
81} 63}
82 64
65void DecryptSharedFontToTTF(const std::vector<u32>& input, std::vector<u8>& output) {
66 ASSERT_MSG(input[0] == EXPECTED_MAGIC, "Failed to derive key, unexpected magic number");
67
68 const u32 KEY = input[0] ^ EXPECTED_RESULT; // Derive key using an inverse xor
69 std::vector<u32> transformed_font(input.size());
70 // TODO(ogniK): Figure out a better way to do this
71 std::transform(input.begin(), input.end(), transformed_font.begin(),
72 [&KEY](u32 font_data) { return Common::swap32(font_data ^ KEY); });
73 transformed_font[1] = Common::swap32(transformed_font[1]) ^ KEY; // "re-encrypt" the size
74 std::memcpy(output.data(), transformed_font.data() + 2, transformed_font.size() * sizeof(u32));
75}
76
83void EncryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output, 77void EncryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output,
84 std::size_t& offset) { 78 std::size_t& offset) {
85 ASSERT_MSG(offset + (input.size() * sizeof(u32)) < SHARED_FONT_MEM_SIZE, 79 ASSERT_MSG(offset + (input.size() * sizeof(u32)) < SHARED_FONT_MEM_SIZE,
diff --git a/src/core/hle/service/ns/pl_u.h b/src/core/hle/service/ns/pl_u.h
index 224dcb997..f920c7f69 100644
--- a/src/core/hle/service/ns/pl_u.h
+++ b/src/core/hle/service/ns/pl_u.h
@@ -16,6 +16,25 @@ class FileSystemController;
16 16
17namespace NS { 17namespace NS {
18 18
19enum class FontArchives : u64 {
20 Extension = 0x0100000000000810,
21 Standard = 0x0100000000000811,
22 Korean = 0x0100000000000812,
23 ChineseTraditional = 0x0100000000000813,
24 ChineseSimple = 0x0100000000000814,
25};
26
27constexpr std::array<std::pair<FontArchives, const char*>, 7> SHARED_FONTS{
28 std::make_pair(FontArchives::Standard, "nintendo_udsg-r_std_003.bfttf"),
29 std::make_pair(FontArchives::ChineseSimple, "nintendo_udsg-r_org_zh-cn_003.bfttf"),
30 std::make_pair(FontArchives::ChineseSimple, "nintendo_udsg-r_ext_zh-cn_003.bfttf"),
31 std::make_pair(FontArchives::ChineseTraditional, "nintendo_udjxh-db_zh-tw_003.bfttf"),
32 std::make_pair(FontArchives::Korean, "nintendo_udsg-r_ko_003.bfttf"),
33 std::make_pair(FontArchives::Extension, "nintendo_ext_003.bfttf"),
34 std::make_pair(FontArchives::Extension, "nintendo_ext2_003.bfttf"),
35};
36
37void DecryptSharedFontToTTF(const std::vector<u32>& input, std::vector<u8>& output);
19void EncryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output, std::size_t& offset); 38void EncryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output, std::size_t& offset);
20 39
21class PL_U final : public ServiceFramework<PL_U> { 40class PL_U final : public ServiceFramework<PL_U> {