22#include " dllmain.h"
33#include " crc32.h"
44
5+ EXTERN_C ULONG NtProtectVirtualMemory (
6+ IN HANDLE ProcessHandle,
7+ IN OUT PVOID* BaseAddress,
8+ IN OUT PSIZE_T RegionSize,
9+ IN ULONG NewProtect,
10+ OUT PULONG OldProtect
11+ );
12+
13+ bool VirtualProtectSyscall (LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect)
14+ {
15+ return NtProtectVirtualMemory (GetCurrentProcess (), &lpAddress, &dwSize, flNewProtect, lpflOldProtect) == 0 ;
16+ }
17+
518DWORD GetImageCrc32 ()
619{
720 char exePath[MAX_PATH]{};
@@ -20,6 +33,7 @@ DWORD GetImageCrc32()
2033
2134void PatchOriginalCode_d1b38fcb ();
2235void PatchOriginalCode_21a8959a ();
36+ void PatchOriginalCode_6ea6d1ba ();
2337
2438std::vector<void *> FindBytesOffsets (const BYTE* bytes, size_t numBytes)
2539{
@@ -57,7 +71,7 @@ std::vector<void*> FindBytesOffsets(const BYTE* bytes, size_t numBytes)
5771 return result;
5872}
5973
60- void Patch_CallAbsoluteIndirectAddress (const std::vector<void *>& offsets, void * TargetFn)
74+ void Patch_CallAbsoluteIndirectAddress (const std::vector<void *>& offsets, void * TargetFn, size_t numNopsFollowing )
6175{
6276 rslog::info_ts () << __FUNCTION__ " - num locations: " << offsets.size () << std::endl;
6377
@@ -70,7 +84,7 @@ void Patch_CallAbsoluteIndirectAddress(const std::vector<void*>& offsets, void*
7084 BYTE* bytes = (BYTE*)offset;
7185
7286 DWORD oldProtectFlags = 0 ;
73- if (!VirtualProtect (offset, 6 , PAGE_WRITECOPY, &oldProtectFlags))
87+ if (!VirtualProtectSyscall (offset, 6 , PAGE_WRITECOPY, &oldProtectFlags))
7488 {
7589 rslog::error_ts () << " Failed to change memory protection" << std::endl;
7690 }
@@ -79,10 +93,13 @@ void Patch_CallAbsoluteIndirectAddress(const std::vector<void*>& offsets, void*
7993 bytes[0 ] = 0xe8 ;
8094 void ** callAddress = (void **)(bytes + 1 );
8195 *callAddress = (void *)targetRelAddress;
82- bytes[5 ] = 0x90 ;
96+ for (size_t i = 0 ; i < numNopsFollowing; ++i)
97+ {
98+ bytes[5 +i] = 0x90 ;
99+ }
83100
84- FlushInstructionCache (GetCurrentProcess (), offset, 6 );
85- if (!VirtualProtect (offset, 6 , oldProtectFlags, &oldProtectFlags))
101+ FlushInstructionCache (GetCurrentProcess (), offset, 5 +numNopsFollowing );
102+ if (!VirtualProtectSyscall (offset, 5 + numNopsFollowing , oldProtectFlags, &oldProtectFlags))
86103 {
87104 rslog::error_ts () << " Failed to restore memory protection" << std::endl;
88105 }
@@ -106,7 +123,7 @@ void Patch_CallRelativeAddress(const std::vector<void*>& offsets, void* TargetFn
106123 bytes += 5 + relOffset;
107124
108125 DWORD oldProtectFlags = 0 ;
109- if (!VirtualProtect (bytes, 6 , PAGE_WRITECOPY, &oldProtectFlags))
126+ if (!VirtualProtectSyscall (bytes, 6 , PAGE_WRITECOPY, &oldProtectFlags))
110127 {
111128 rslog::error_ts () << " Failed to change memory protection" << std::endl;
112129 }
@@ -119,7 +136,7 @@ void Patch_CallRelativeAddress(const std::vector<void*>& offsets, void* TargetFn
119136 // ret
120137 bytes[5 ] = 0xc3 ;
121138
122- if (!VirtualProtect (bytes, 6 , oldProtectFlags, &oldProtectFlags))
139+ if (!VirtualProtectSyscall (bytes, 6 , oldProtectFlags, &oldProtectFlags))
123140 {
124141 rslog::error_ts () << " Failed to restore memory protection" << std::endl;
125142 }
@@ -130,7 +147,7 @@ void Patch_CallRelativeAddress(const std::vector<void*>& offsets, void* TargetFn
130147void Patch_ReplaceWithNops (void * offset, size_t numBytes)
131148{
132149 DWORD oldProtectFlags = 0 ;
133- if (!VirtualProtect (offset, numBytes, PAGE_WRITECOPY, &oldProtectFlags))
150+ if (!VirtualProtectSyscall (offset, numBytes, PAGE_WRITECOPY, &oldProtectFlags))
134151 {
135152 rslog::error_ts () << " Failed to change memory protection" << std::endl;
136153 }
@@ -143,7 +160,7 @@ void Patch_ReplaceWithNops(void* offset, size_t numBytes)
143160 }
144161
145162 FlushInstructionCache (GetCurrentProcess (), offset, numBytes);
146- if (!VirtualProtect (offset, numBytes, oldProtectFlags, &oldProtectFlags))
163+ if (!VirtualProtectSyscall (offset, numBytes, oldProtectFlags, &oldProtectFlags))
147164 {
148165 rslog::error_ts () << " Failed to restore memory protection" << std::endl;
149166 }
@@ -153,7 +170,7 @@ void Patch_ReplaceWithNops(void* offset, size_t numBytes)
153170void Patch_ReplaceWithBytes (void * offset, size_t numBytes, const BYTE* replaceBytes)
154171{
155172 DWORD oldProtectFlags = 0 ;
156- if (!VirtualProtect (offset, numBytes, PAGE_WRITECOPY, &oldProtectFlags))
173+ if (!VirtualProtectSyscall (offset, numBytes, PAGE_WRITECOPY, &oldProtectFlags))
157174 {
158175 rslog::error_ts () << " Failed to change memory protection" << std::endl;
159176 }
@@ -166,7 +183,7 @@ void Patch_ReplaceWithBytes(void* offset, size_t numBytes, const BYTE* replaceBy
166183 }
167184
168185 FlushInstructionCache (GetCurrentProcess (), offset, numBytes);
169- if (!VirtualProtect (offset, numBytes, oldProtectFlags, &oldProtectFlags))
186+ if (!VirtualProtectSyscall (offset, numBytes, oldProtectFlags, &oldProtectFlags))
170187 {
171188 rslog::error_ts () << " Failed to restore memory protection" << std::endl;
172189 }
@@ -192,6 +209,9 @@ void PatchOriginalCode()
192209 case 0x21a8959a :
193210 PatchOriginalCode_21a8959a ();
194211 break ;
212+ case 0x6ea6d1ba :
213+ PatchOriginalCode_6ea6d1ba ();
214+ break ;
195215 default :
196216 rslog::error_ts () << " Unknown game version" << std::endl;
197217 break ;
0 commit comments