| 12 | LOG_CHANNEL(dec_log, "DECRYPT"); |
| 13 | |
| 14 | usz decrypt_binaries_t::decrypt(std::string_view klic_input) |
| 15 | { |
| 16 | if (m_index >= m_modules.size()) |
| 17 | { |
| 18 | std::cout << "No paths specified" << std::endl; // For CLI |
| 19 | m_index = umax; |
| 20 | return umax; |
| 21 | } |
| 22 | |
| 23 | if (m_klics.empty()) |
| 24 | { |
| 25 | dec_log.notice("Decrypting binaries..."); |
| 26 | std::cout << "Decrypting binaries..." << std::endl; // For CLI |
| 27 | |
| 28 | // Always start with no KLIC |
| 29 | m_klics.emplace_back(u128{}); |
| 30 | |
| 31 | if (const auto keys = g_fxo->try_get<loaded_npdrm_keys>()) |
| 32 | { |
| 33 | // Second klic: get it from a running game |
| 34 | if (const u128 klic = keys->last_key()) |
| 35 | { |
| 36 | m_klics.emplace_back(klic); |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | // Try to use the key that has been for the current running ELF |
| 41 | m_klics.insert(m_klics.end(), Emu.klic.begin(), Emu.klic.end()); |
| 42 | } |
| 43 | |
| 44 | if (std::string_view text = klic_input.substr(klic_input.find_first_of('x') + 1); text.size() == 32) |
| 45 | { |
| 46 | // Allowed to fail (would simply repeat the operation if fails again) |
| 47 | u64 lo = 0; |
| 48 | u64 hi = 0; |
| 49 | bool success = false; |
| 50 | |
| 51 | if (auto res = std::from_chars(text.data() + 0, text.data() + 16, lo, 16); res.ec == std::errc() && res.ptr == text.data() + 16) |
| 52 | { |
| 53 | if (res = std::from_chars(text.data() + 16, text.data() + 32, hi, 16); res.ec == std::errc() && res.ptr == text.data() + 32) |
| 54 | { |
| 55 | success = true; |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | if (success) |
| 60 | { |
| 61 | lo = std::bit_cast<be_t<u64>>(lo); |
| 62 | hi = std::bit_cast<be_t<u64>>(hi); |
| 63 | |
| 64 | if (u128 input_key = ((u128{hi} << 64) | lo)) |
| 65 | { |
| 66 | m_klics.emplace_back(input_key); |
| 67 | } |
| 68 | } |
| 69 | } |
| 70 | |
| 71 | while (m_index < m_modules.size()) |
nothing calls this directly
no test coverage detected