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;
}