فهرست منبع

partition_data_manager: Remove KIP processing and use FileSys
Previously, this TU contained the necessary headers to parse KIP/INI but now it should just use the FileSys class.

Zach Hilman 7 سال پیش
والد
کامیت
0f37096820
1فایلهای تغییر یافته به همراه13 افزوده شده و 118 حذف شده
  1. 13 118
      src/core/crypto/partition_data_manager.cpp

+ 13 - 118
src/core/crypto/partition_data_manager.cpp

@@ -22,8 +22,10 @@
 #include "core/crypto/key_manager.h"
 #include "core/crypto/partition_data_manager.h"
 #include "core/crypto/xts_encryption_layer.h"
+#include "core/file_sys/kernel_executable.h"
 #include "core/file_sys/vfs.h"
 #include "core/file_sys/vfs_offset.h"
+#include "core/file_sys/vfs_vector.h"
 
 using namespace Common;
 
@@ -45,36 +47,6 @@ struct Package2Header {
 };
 static_assert(sizeof(Package2Header) == 0x200, "Package2Header has incorrect size.");
 
-struct INIHeader {
-    u32_le magic;
-    u32_le size;
-    u32_le process_count;
-    INSERT_PADDING_BYTES(4);
-};
-static_assert(sizeof(INIHeader) == 0x10, "INIHeader has incorrect size.");
-
-struct SectionHeader {
-    u32_le offset;
-    u32_le size_decompressed;
-    u32_le size_compressed;
-    u32_le attribute;
-};
-static_assert(sizeof(SectionHeader) == 0x10, "SectionHeader has incorrect size.");
-
-struct KIPHeader {
-    u32_le magic;
-    std::array<char, 12> name;
-    u64_le title_id;
-    u32_le category;
-    u8 priority;
-    u8 core;
-    INSERT_PADDING_BYTES(1);
-    u8 flags;
-    std::array<SectionHeader, 6> sections;
-    std::array<u32, 0x20> capabilities;
-};
-static_assert(sizeof(KIPHeader) == 0x100, "KIPHeader has incorrect size.");
-
 const std::array<SHA256Hash, 0x10> source_hashes{
     "B24BD293259DBC7AC5D63F88E60C59792498E6FC5443402C7FFE87EE8B61A3F0"_array32, // keyblob_mac_key_source
     "7944862A3A5C31C6720595EFD302245ABD1B54CCDCF33000557681E65C5664A4"_array32, // master_key_source
@@ -170,65 +142,6 @@ const std::array<SHA256Hash, 0x20> master_key_hashes{
     "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1F
 };
 
-static std::vector<u8> DecompressBLZ(const std::vector<u8>& in) {
-    const auto data_size = in.size() - 0xC;
-
-    u32 compressed_size{};
-    u32 init_index{};
-    u32 additional_size{};
-    std::memcpy(&compressed_size, in.data() + data_size, sizeof(u32));
-    std::memcpy(&init_index, in.data() + data_size + 0x4, sizeof(u32));
-    std::memcpy(&additional_size, in.data() + data_size + 0x8, sizeof(u32));
-
-    std::vector<u8> out(in.size() + additional_size);
-
-    if (compressed_size == in.size())
-        std::memcpy(out.data(), in.data() + in.size() - compressed_size, compressed_size);
-    else
-        std::memcpy(out.data(), in.data(), compressed_size);
-
-    auto index = in.size() - init_index;
-    auto out_index = out.size();
-
-    while (out_index > 0) {
-        --index;
-        auto control = in[index];
-        for (size_t i = 0; i < 8; ++i) {
-            if ((control & 0x80) > 0) {
-                ASSERT(index >= 2);
-                index -= 2;
-                u64 segment_offset = in[index] | in[index + 1] << 8;
-                u64 segment_size = ((segment_offset >> 12) & 0xF) + 3;
-                segment_offset &= 0xFFF;
-                segment_offset += 3;
-
-                if (out_index < segment_size)
-                    segment_size = out_index;
-
-                ASSERT(out_index >= segment_size);
-
-                out_index -= segment_size;
-
-                for (size_t j = 0; j < segment_size; ++j) {
-                    ASSERT(out_index + j + segment_offset < out.size());
-                    out[out_index + j] = out[out_index + j + segment_offset];
-                }
-            } else {
-                ASSERT(out_index >= 1);
-                --out_index;
-                --index;
-                out[out_index] = in[index];
-            }
-
-            control <<= 1;
-            if (out_index == 0)
-                return out;
-        }
-    }
-
-    return out;
-}
-
 static u8 CalculateMaxKeyblobSourceHash() {
     for (s8 i = 0x1F; i >= 0; --i) {
         if (keyblob_source_hashes[i] != SHA256Hash{})
@@ -478,37 +391,22 @@ void PartitionDataManager::DecryptPackage2(const std::array<Key128, 0x20>& packa
     cipher.SetIV({header.section_ctr[1].begin(), header.section_ctr[1].end()});
     cipher.Transcode(c.data(), c.size(), c.data(), Op::Decrypt);
 
-    INIHeader ini;
-    std::memcpy(&ini, c.data(), sizeof(INIHeader));
-    if (ini.magic != Common::MakeMagic('I', 'N', 'I', '1'))
+    const auto ini_file = std::make_shared<FileSys::VectorVfsFile>(c);
+    const FileSys::INI ini{ini_file};
+    if (ini.GetStatus() != Loader::ResultStatus::Success)
         return;
 
-    u64 offset = sizeof(INIHeader);
-    for (size_t i = 0; i < ini.process_count; ++i) {
-        KIPHeader kip;
-        std::memcpy(&kip, c.data() + offset, sizeof(KIPHeader));
-        if (kip.magic != Common::MakeMagic('K', 'I', 'P', '1'))
+    for (const auto& kip : ini.GetKIPs()) {
+        if (kip.GetStatus() != Loader::ResultStatus::Success)
             return;
 
-        const auto name =
-            Common::StringFromFixedZeroTerminatedBuffer(kip.name.data(), kip.name.size());
-
-        if (name != "FS" && name != "spl") {
-            offset += sizeof(KIPHeader) + kip.sections[0].size_compressed +
-                      kip.sections[1].size_compressed + kip.sections[2].size_compressed;
+        if (kip.GetName() != "FS" && kip.GetName() != "spl") {
             continue;
         }
 
-        const u64 initial_offset = sizeof(KIPHeader) + offset;
-        const auto text_begin = c.cbegin() + initial_offset;
-        const auto text_end = text_begin + kip.sections[0].size_compressed;
-        const std::vector<u8> text = DecompressBLZ({text_begin, text_end});
-
-        const auto rodata_end = text_end + kip.sections[1].size_compressed;
-        const std::vector<u8> rodata = DecompressBLZ({text_end, rodata_end});
-
-        const auto data_end = rodata_end + kip.sections[2].size_compressed;
-        const std::vector<u8> data = DecompressBLZ({rodata_end, data_end});
+        const auto& text = kip.GetTextSection();
+        const auto& rodata = kip.GetRODataSection();
+        const auto& data = kip.GetDataSection();
 
         std::vector<u8> out;
         out.reserve(text.size() + rodata.size() + data.size());
@@ -516,12 +414,9 @@ void PartitionDataManager::DecryptPackage2(const std::array<Key128, 0x20>& packa
         out.insert(out.end(), rodata.begin(), rodata.end());
         out.insert(out.end(), data.begin(), data.end());
 
-        offset += sizeof(KIPHeader) + kip.sections[0].size_compressed +
-                  kip.sections[1].size_compressed + kip.sections[2].size_compressed;
-
-        if (name == "FS")
+        if (kip.GetName() == "FS")
             package2_fs[static_cast<size_t>(type)] = std::move(out);
-        else if (name == "spl")
+        else if (kip.GetName() == "spl")
             package2_spl[static_cast<size_t>(type)] = std::move(out);
     }
 }