I received a few PMs asking for source code on how to change page protection--I completely sympathize that it's outside the comfort zone of many programmers that aren't familiar with reverse engineering, like myself, but can't spare the time to read up on how to perform this operation. Instead of sending people it directly, I'll just post the relevant excerpts publicly here. I can't give the actual fully compilable solution as it contains many other things. I've copied and strapped together the relevant code segments.
Code:
STARTUPINFO si;
PROCESS_INFORMATION pi;
CreateProcess(_T(".\\EpsilonWoW"), _T("EpsilonWoW -console"), NULL, NULL, false, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
if (!pi.hProcess)
return EXIT_FAILURE;
// remap base image
bool remapped = false;
while (!remapped)
{
MEMORY_BASIC_INFORMATION mbi;
unsigned char* p = NULL;
std::vector<char> old_tail = {};
for (p = NULL; VirtualQueryEx(pi.hProcess, p, &mbi, sizeof(mbi)) == sizeof(mbi); p += mbi.RegionSize)
{
if (mbi.State == MEM_COMMIT && mbi.Type == MEM_MAPPED)
{
if (mbi.RegionSize == 23068672) // 7.3.5.26972
{
Remap(pi.hProcess, mbi.BaseAddress, mbi.RegionSize, 0x40);
remapped = true;
break;
}
}
}
}
ResumeThread(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
Here's the remap function. Again, taken from changeofpace's above repository and only slightly modified, and using his memory & ntapi classes.
Code:
bool Remap(HANDLE hProcess,
PVOID regionBase,
SIZE_T regionSize,
DWORD newProtection)
{
DWORD oldProtection = 0;
if (!VirtualProtectEx(hProcess, PVOID(regionBase), regionSize, newProtection, &oldProtection))
{
char buf[100];
if (!memory::RegionIsMappedView(hProcess, PVOID(regionBase), regionSize))
{
sprintf_s(buf, "Error: %p must be in a memory mapped view.", regionBase);
MessageBoxA(NULL, buf, "Error", MB_ICONERROR);
return false;
}
if (!memory::ViewHasProtectedProtection(hProcess, PVOID(regionBase), regionSize, newProtection))
{
sprintf_s(buf, "Error: Unhandled protection scenario.");
MessageBoxA(NULL, buf, "Error", MB_ICONERROR);
return false;
}
if (!memory::RemapViewOfSection(hProcess, PVOID(regionBase), regionSize, newProtection))
{
sprintf_s(buf, "Error: failed to remap the view at %p.", regionBase);
MessageBoxA(NULL, buf, "Error", MB_ICONERROR);
return false;
}
}
}
Please be advised--I have no idea if this is detected by Warden. I am my own server's owner. Use this solution outside of sandboxes at your own risk.