diff --git a/RSAPatch/dllmain.cpp b/RSAPatch/dllmain.cpp index 068b635..0710efa 100644 --- a/RSAPatch/dllmain.cpp +++ b/RSAPatch/dllmain.cpp @@ -42,8 +42,27 @@ public: }; +class String +{ +public: + void* klass; + void* monitor; + uint32_t length; + wchar_t chars[]; + + wchar_t* c_str() { + return chars; + } + + size_t size() { + return length; + } +}; + + PVOID oGetPublicKey = nullptr; PVOID oGetPrivateKey = nullptr; +PVOID oReadToEnd = nullptr; LPCSTR gcpb = "xbbx2m1feHyrQ7jP+8mtDF/pyYLrJWKWAdEv3wZrOtjOZzeLGPzsmkcgncgoRhX4dT+1itSMR9j9m0/OwsH2UoF6U32LxCOQWQD1AMgIZjAkJeJvFTrtn8fMQ1701CkbaLTVIjRMlTw8kNXvNA/A9UatoiDmi4TFG6mrxTKZpIcTInvPEpkK2A7Qsp1E4skFK8jmysy7uRhMaYHtPTsBvxP0zn3lhKB3W+HTqpneewXWHjCDfL7Nbby91jbz5EKPZXWLuhXIvR1Cu4tiruorwXJxmXaP1HQZonytECNU/UOzP6GNLdq0eFDE4b04Wjp396551G99YiFP2nqHVJ5OMQ==AQAB"; PVOID Detour(PVOID func, PVOID jmp, bool attach) @@ -130,6 +149,58 @@ Array* __fastcall hkGetRSAKey() return data; } +String* __fastcall hkReadToEnd(void* rcx, void* rdx) +{ + auto result = decltype(&hkReadToEnd)(oReadToEnd)(rcx, rdx); + if (!result) + return result; + + if (!wcsstr(result->c_str(), L"")) + return result; + + bool isPrivate = wcsstr(result->c_str(), L""); + std::string customKey{}; + + if (isPrivate) + { + Utils::ConsolePrint("private\n"); + customKey = ReadFile("PrivateKey.txt"); + } + else + { + Utils::ConsolePrint("public\n"); + customKey = ReadFile("PublicKey.txt"); + if (customKey.empty()) + { + Utils::ConsolePrint("original:\n"); + Utils::ConsolePrint("%S\n\n", result->c_str()); + + Utils::ConsolePrint("using grasscutter public key\n"); + customKey = gcpb; + } + } + + if (!customKey.empty()) + { + if (customKey.size() <= result->size()) + { + ZeroMemory(result->chars, result->size() * 2); + std::wstring wstr = std::wstring(customKey.begin(), customKey.end()); // idc + memcpy_s(result->chars, result->size() * 2, wstr.data(), wstr.size() * 2); + } + else + { + Utils::ConsolePrint("custom key longer than original\n"); + } + } + + for (int i = 0; i < result->size(); i++) + Utils::ConsolePrint("%C", result->chars[i]); + Utils::ConsolePrint("\n\n"); + + return result; +} + void DisableVMP() { // restore hook at NtProtectVirtualMemory @@ -177,6 +248,30 @@ uintptr_t FindEntry(uintptr_t addr) return 0; } +void OldVersion() // <= 3.5.0 +{ + auto GetPublicKey = Utils::PatternScan("UserAssembly.dll", "48 BA 45 78 70 6F 6E 65 6E 74 48 89 90 ? ? ? ? 48 BA 3E 3C 2F 52 53 41 4B 65"); // 'Exponent> 0) + Utils::ConsolePrint("Failed to find GetPublicKey - Need to update\n"); + if (!GetPrivateKey || GetPrivateKey % 16 > 0) + Utils::ConsolePrint("Failed to find GetPrivateKey - Need to update\n"); + + oGetPublicKey = Detour((PVOID)GetPublicKey, hkGetRSAKey, true); + oGetPrivateKey = Detour((PVOID)GetPrivateKey, hkGetRSAKey, true); + + Utils::ConsolePrint("Hooked GetPublicKey - Original at: %p\n", oGetPublicKey); + Utils::ConsolePrint("Hooked GetPrivateKey - Original at: %p\n", oGetPrivateKey); +} + DWORD __stdcall Thread(LPVOID p) { Utils::AttachConsole(); @@ -211,26 +306,26 @@ DWORD __stdcall Thread(LPVOID p) } DisableVMP(); - auto GetPublicKey = Utils::PatternScan("UserAssembly.dll", "48 BA 45 78 70 6F 6E 65 6E 74 48 89 90 ? ? ? ? 48 BA 3E 3C 2F 52 53 41 4B 65"); // 'Exponent>e_lfanew); + DWORD timestamp = nt->FileHeader.TimeDateStamp; - GetPublicKey = FindEntry(GetPublicKey); - GetPrivateKey = FindEntry(GetPrivateKey); + if (timestamp <= 0x63ECA960) + { + OldVersion(); + return 0; + } - Utils::ConsolePrint("GetPublicKey: %p\n", GetPublicKey); - Utils::ConsolePrint("GetPrivateKey: %p\n", GetPrivateKey); + auto ReadToEnd = Utils::PatternScan("UserAssembly.dll", "48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 83 EC 20 48 83 79 ? ? 48 8B D9 75 05"); + Utils::ConsolePrint("ReadToEnd: %p\n", ReadToEnd); - // check for null and alignment - if (!GetPublicKey || GetPublicKey % 8 > 0) - Utils::ConsolePrint("Failed to find GetPublicKey - Need to update\n"); - if (!GetPrivateKey || GetPrivateKey % 8 > 0) - Utils::ConsolePrint("Failed to find GetPrivateKey - Need to update\n"); + if (!ReadToEnd || ReadToEnd % 16 > 0) + Utils::ConsolePrint("Failed to find ReadToEnd - Need to update\n"); - oGetPublicKey = Detour((PVOID)GetPublicKey, hkGetRSAKey, true); - oGetPrivateKey = Detour((PVOID)GetPrivateKey, hkGetRSAKey, true); - - Utils::ConsolePrint("Hooked GetPublicKey - Original at: %p\n", oGetPublicKey); - Utils::ConsolePrint("Hooked GetPrivateKey - Original at: %p\n", oGetPrivateKey); + oReadToEnd = Detour((PVOID)ReadToEnd, hkReadToEnd, true); + Utils::ConsolePrint("Hooked ReadToEnd - Original at: %p\n", oReadToEnd); return 0; }