@@ -17,6 +17,7 @@ typedef enum _SECTION_INFORMATION_CLASS {
1717} SECTION_INFORMATION_CLASS, * PSECTION_INFORMATION_CLASS;
1818EXTERN_C NTSTATUS __stdcall NtQuerySection (HANDLE SectionHandle, SECTION_INFORMATION_CLASS InformationClass, PVOID InformationBuffer, ULONG InformationBufferSize, PULONG ResultLength);
1919EXTERN_C NTSTATUS __stdcall NtProtectVirtualMemory (HANDLE ProcessHandle, PVOID* BaseAddress, PULONG NumberOfBytesToProtect, ULONG NewAccessProtection, PULONG OldAccessProtection);
20+ EXTERN_C NTSTATUS __stdcall NtPulseEvent (HANDLE EventHandle, PULONG PreviousState);
2021
2122template <typename T>
2223class Array
@@ -204,9 +205,12 @@ String* __fastcall hkReadToEnd(void* rcx, void* rdx)
204205void DisableVMP ()
205206{
206207 // restore hook at NtProtectVirtualMemory
208+ auto ntdll = GetModuleHandleA (" ntdll.dll" );
209+ bool linux = GetProcAddress (ntdll, " wine_get_version" ) != nullptr ;
210+ void * routine = linux ? (void *)NtPulseEvent : (void *)NtQuerySection;
207211 DWORD old;
208212 VirtualProtect (NtProtectVirtualMemory, 1 , PAGE_EXECUTE_READWRITE, &old);
209- *(uintptr_t *)NtProtectVirtualMemory = *(uintptr_t *)NtQuerySection & ~(0xFFui64 << 32 ) | (uintptr_t )(*(uint32_t *)((uintptr_t )NtQuerySection + 4 ) - 1 ) << 32 ;
213+ *(uintptr_t *)NtProtectVirtualMemory = *(uintptr_t *)routine & ~(0xFFui64 << 32 ) | (uintptr_t )(*(uint32_t *)((uintptr_t )routine + 4 ) - 1 ) << 32 ;
210214 VirtualProtect (NtProtectVirtualMemory, 1 , old, &old);
211215}
212216
@@ -272,11 +276,67 @@ void OldVersion() // <= 3.5.0
272276 Utils::ConsolePrint (" Hooked GetPrivateKey - Original at: %p\n " , oGetPrivateKey);
273277}
274278
279+ void ACheckForThoseWhoCannotFollowInstructions (LPVOID instance)
280+ {
281+ if (!instance)
282+ {
283+ // this shouldn't happen
284+ return ;
285+ }
286+
287+ char szModulePath[MAX_PATH]{};
288+ GetModuleFileNameA ((HMODULE)instance, szModulePath, MAX_PATH);
289+
290+ std::filesystem::path ModulePath = szModulePath;
291+ std::string ModuleName = ModulePath.filename ().string ();
292+ std::transform (ModuleName.begin (), ModuleName.end (), ModuleName.begin (), ::tolower);
293+
294+ if (ModuleName == " version.dll" )
295+ {
296+ // check mhypbase.dll
297+ auto mhypbase = GetModuleHandleA (" mhypbase.dll" );
298+ if (!mhypbase)
299+ return ;
300+
301+ PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)mhypbase;
302+ PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((uintptr_t )mhypbase + dosHeader->e_lfanew );
303+ auto sizeOfImage = ntHeaders->OptionalHeader .SizeOfImage ;
304+
305+ // over 1MB
306+ if (sizeOfImage > 1 * 1024 * 1024 )
307+ return ;
308+
309+ // uh oh
310+ }
311+ else
312+ {
313+ // check version.dll
314+ auto version = GetModuleHandleA (" version.dll" );
315+ if (!version)
316+ return ; // this shouldn't happen
317+
318+ ZeroMemory (szModulePath, MAX_PATH);
319+ GetModuleFileNameA ((HMODULE)version, szModulePath, MAX_PATH);
320+ ModuleName = szModulePath;
321+ std::transform (ModuleName.begin (), ModuleName.end (), ModuleName.begin (), ::tolower);
322+
323+ if (ModuleName.find (" system32" ) != std::string::npos)
324+ return ;
325+
326+ // uh oh
327+ }
328+
329+ // https://www.youtube.com/watch?v=9a_3wQHcm_Y
330+ MessageBoxA (nullptr , " You may have more than one RSAPatch installed.\n Please only use one RSAPatch to avoid instability." , " RSAPatch" , MB_ICONWARNING);
331+ }
332+
275333DWORD __stdcall Thread (LPVOID p)
276334{
277335 Utils::AttachConsole ();
278336 Utils::ConsolePrint (" Waiting for game to startup\n " );
279337
338+ ACheckForThoseWhoCannotFollowInstructions (p);
339+
280340 auto pid = GetCurrentProcessId ();
281341 while (true )
282342 {
0 commit comments