mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									421c3e831a
								
							
						
					
					
						commit
						0f37096820
					
				| @ -22,8 +22,10 @@ | |||||||
| #include "core/crypto/key_manager.h" | #include "core/crypto/key_manager.h" | ||||||
| #include "core/crypto/partition_data_manager.h" | #include "core/crypto/partition_data_manager.h" | ||||||
| #include "core/crypto/xts_encryption_layer.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.h" | ||||||
| #include "core/file_sys/vfs_offset.h" | #include "core/file_sys/vfs_offset.h" | ||||||
|  | #include "core/file_sys/vfs_vector.h" | ||||||
| 
 | 
 | ||||||
| using namespace Common; | using namespace Common; | ||||||
| 
 | 
 | ||||||
| @ -45,36 +47,6 @@ struct Package2Header { | |||||||
| }; | }; | ||||||
| static_assert(sizeof(Package2Header) == 0x200, "Package2Header has incorrect size."); | 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{ | const std::array<SHA256Hash, 0x10> source_hashes{ | ||||||
|     "B24BD293259DBC7AC5D63F88E60C59792498E6FC5443402C7FFE87EE8B61A3F0"_array32, // keyblob_mac_key_source
 |     "B24BD293259DBC7AC5D63F88E60C59792498E6FC5443402C7FFE87EE8B61A3F0"_array32, // keyblob_mac_key_source
 | ||||||
|     "7944862A3A5C31C6720595EFD302245ABD1B54CCDCF33000557681E65C5664A4"_array32, // master_key_source
 |     "7944862A3A5C31C6720595EFD302245ABD1B54CCDCF33000557681E65C5664A4"_array32, // master_key_source
 | ||||||
| @ -170,65 +142,6 @@ const std::array<SHA256Hash, 0x20> master_key_hashes{ | |||||||
|     "0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1F
 |     "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() { | static u8 CalculateMaxKeyblobSourceHash() { | ||||||
|     for (s8 i = 0x1F; i >= 0; --i) { |     for (s8 i = 0x1F; i >= 0; --i) { | ||||||
|         if (keyblob_source_hashes[i] != SHA256Hash{}) |         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.SetIV({header.section_ctr[1].begin(), header.section_ctr[1].end()}); | ||||||
|     cipher.Transcode(c.data(), c.size(), c.data(), Op::Decrypt); |     cipher.Transcode(c.data(), c.size(), c.data(), Op::Decrypt); | ||||||
| 
 | 
 | ||||||
|     INIHeader ini; |     const auto ini_file = std::make_shared<FileSys::VectorVfsFile>(c); | ||||||
|     std::memcpy(&ini, c.data(), sizeof(INIHeader)); |     const FileSys::INI ini{ini_file}; | ||||||
|     if (ini.magic != Common::MakeMagic('I', 'N', 'I', '1')) |     if (ini.GetStatus() != Loader::ResultStatus::Success) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     u64 offset = sizeof(INIHeader); |     for (const auto& kip : ini.GetKIPs()) { | ||||||
|     for (size_t i = 0; i < ini.process_count; ++i) { |         if (kip.GetStatus() != Loader::ResultStatus::Success) | ||||||
|         KIPHeader kip; |  | ||||||
|         std::memcpy(&kip, c.data() + offset, sizeof(KIPHeader)); |  | ||||||
|         if (kip.magic != Common::MakeMagic('K', 'I', 'P', '1')) |  | ||||||
|             return; |             return; | ||||||
| 
 | 
 | ||||||
|         const auto name = |         if (kip.GetName() != "FS" && kip.GetName() != "spl") { | ||||||
|             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; |  | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const u64 initial_offset = sizeof(KIPHeader) + offset; |         const auto& text = kip.GetTextSection(); | ||||||
|         const auto text_begin = c.cbegin() + initial_offset; |         const auto& rodata = kip.GetRODataSection(); | ||||||
|         const auto text_end = text_begin + kip.sections[0].size_compressed; |         const auto& data = kip.GetDataSection(); | ||||||
|         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}); |  | ||||||
| 
 | 
 | ||||||
|         std::vector<u8> out; |         std::vector<u8> out; | ||||||
|         out.reserve(text.size() + rodata.size() + data.size()); |         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(), rodata.begin(), rodata.end()); | ||||||
|         out.insert(out.end(), data.begin(), data.end()); |         out.insert(out.end(), data.begin(), data.end()); | ||||||
| 
 | 
 | ||||||
|         offset += sizeof(KIPHeader) + kip.sections[0].size_compressed + |         if (kip.GetName() == "FS") | ||||||
|                   kip.sections[1].size_compressed + kip.sections[2].size_compressed; |  | ||||||
| 
 |  | ||||||
|         if (name == "FS") |  | ||||||
|             package2_fs[static_cast<size_t>(type)] = std::move(out); |             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); |             package2_spl[static_cast<size_t>(type)] = std::move(out); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Zach Hilman
						Zach Hilman