mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2025-01-31 06:57:28 +05:00
Fixup patterns for UPX executables
Adapted ScopedUnprotect for UPX executables
This commit is contained in:
parent
92fb1798f9
commit
29cea98c70
4 changed files with 82 additions and 34 deletions
|
@ -626,46 +626,31 @@ namespace Memory
|
||||||
#include <forward_list>
|
#include <forward_list>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
class ScopedUnprotect
|
namespace ScopedUnprotect
|
||||||
{
|
{
|
||||||
public:
|
class unprotect
|
||||||
class Section
|
|
||||||
{
|
{
|
||||||
public:
|
protected:
|
||||||
Section( HINSTANCE hInstance, const char* name )
|
void UnprotectRange( DWORD_PTR BaseAddress, SIZE_T Size )
|
||||||
{
|
{
|
||||||
IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)((BYTE*)hInstance + ((IMAGE_DOS_HEADER*)hInstance)->e_lfanew);
|
|
||||||
IMAGE_SECTION_HEADER* pSection = IMAGE_FIRST_SECTION(ntHeader);
|
|
||||||
|
|
||||||
DWORD VirtualAddress = MAXDWORD;
|
|
||||||
SIZE_T VirtualSize = MAXDWORD;
|
|
||||||
for ( SIZE_T i = 0, j = ntHeader->FileHeader.NumberOfSections; i < j; ++i, ++pSection )
|
|
||||||
{
|
|
||||||
if ( strncmp( (const char*)pSection->Name, name, IMAGE_SIZEOF_SHORT_NAME ) == 0 )
|
|
||||||
{
|
|
||||||
VirtualAddress = (DWORD)hInstance + pSection->VirtualAddress;
|
|
||||||
VirtualSize = pSection->Misc.VirtualSize;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( VirtualAddress == MAXDWORD )
|
|
||||||
return;
|
|
||||||
|
|
||||||
SIZE_T QueriedSize = 0;
|
SIZE_T QueriedSize = 0;
|
||||||
while ( QueriedSize < VirtualSize )
|
while ( QueriedSize < Size )
|
||||||
{
|
{
|
||||||
MEMORY_BASIC_INFORMATION MemoryInf;
|
MEMORY_BASIC_INFORMATION MemoryInf;
|
||||||
DWORD dwOldProtect;
|
DWORD dwOldProtect;
|
||||||
|
|
||||||
VirtualQuery( (LPCVOID)(VirtualAddress + QueriedSize), &MemoryInf, sizeof(MemoryInf) );
|
VirtualQuery( (LPCVOID)(BaseAddress + QueriedSize), &MemoryInf, sizeof(MemoryInf) );
|
||||||
VirtualProtect( MemoryInf.BaseAddress, MemoryInf.RegionSize, PAGE_EXECUTE_READWRITE, &dwOldProtect );
|
if ( MemoryInf.State == MEM_COMMIT && (MemoryInf.Type & MEM_IMAGE) != 0 &&
|
||||||
m_queriedProtects.emplace_front( MemoryInf.BaseAddress, MemoryInf.RegionSize, MemoryInf.Protect );
|
(MemoryInf.Protect & (PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY|PAGE_READWRITE|PAGE_WRITECOPY)) == 0 )
|
||||||
|
{
|
||||||
|
VirtualProtect( MemoryInf.BaseAddress, MemoryInf.RegionSize, PAGE_EXECUTE_READWRITE, &dwOldProtect );
|
||||||
|
m_queriedProtects.emplace_front( MemoryInf.BaseAddress, MemoryInf.RegionSize, MemoryInf.Protect );
|
||||||
|
}
|
||||||
QueriedSize += MemoryInf.RegionSize;
|
QueriedSize += MemoryInf.RegionSize;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
~Section()
|
~unprotect()
|
||||||
{
|
{
|
||||||
for ( auto& it : m_queriedProtects )
|
for ( auto& it : m_queriedProtects )
|
||||||
{
|
{
|
||||||
|
@ -677,6 +662,49 @@ public:
|
||||||
private:
|
private:
|
||||||
std::forward_list< std::tuple< LPVOID, SIZE_T, DWORD > > m_queriedProtects;
|
std::forward_list< std::tuple< LPVOID, SIZE_T, DWORD > > m_queriedProtects;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Section : protected unprotect
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Section( HINSTANCE hInstance, const char* name )
|
||||||
|
{
|
||||||
|
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)hInstance + ((PIMAGE_DOS_HEADER)hInstance)->e_lfanew);
|
||||||
|
PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(ntHeader);
|
||||||
|
|
||||||
|
DWORD_PTR VirtualAddress = DWORD_PTR(-1);
|
||||||
|
SIZE_T VirtualSize = SIZE_T(-1);
|
||||||
|
for ( SIZE_T i = 0, j = ntHeader->FileHeader.NumberOfSections; i < j; ++i, ++pSection )
|
||||||
|
{
|
||||||
|
if ( strncmp( (const char*)pSection->Name, name, IMAGE_SIZEOF_SHORT_NAME ) == 0 )
|
||||||
|
{
|
||||||
|
VirtualAddress = (DWORD_PTR)hInstance + pSection->VirtualAddress;
|
||||||
|
VirtualSize = pSection->Misc.VirtualSize;
|
||||||
|
m_locatedSection = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( VirtualAddress == DWORD_PTR(-1) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
UnprotectRange( VirtualAddress, VirtualSize );
|
||||||
|
};
|
||||||
|
|
||||||
|
bool SectionLocated() const { return m_locatedSection; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_locatedSection = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FullModule : protected unprotect
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FullModule( HINSTANCE hInstance )
|
||||||
|
{
|
||||||
|
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)hInstance + ((PIMAGE_DOS_HEADER)hInstance)->e_lfanew);
|
||||||
|
UnprotectRange( (DWORD_PTR)hInstance, ntHeader->OptionalHeader.SizeOfImage );
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -126,7 +126,7 @@ public:
|
||||||
PIMAGE_DOS_HEADER dosHeader = getRVA<IMAGE_DOS_HEADER>(0);
|
PIMAGE_DOS_HEADER dosHeader = getRVA<IMAGE_DOS_HEADER>(0);
|
||||||
PIMAGE_NT_HEADERS ntHeader = getRVA<IMAGE_NT_HEADERS>(dosHeader->e_lfanew);
|
PIMAGE_NT_HEADERS ntHeader = getRVA<IMAGE_NT_HEADERS>(dosHeader->e_lfanew);
|
||||||
|
|
||||||
m_end = m_begin + ntHeader->OptionalHeader.SizeOfCode;
|
m_end = m_begin + ntHeader->OptionalHeader.SizeOfImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
executable_meta(uintptr_t begin, uintptr_t end)
|
executable_meta(uintptr_t begin, uintptr_t end)
|
||||||
|
@ -156,7 +156,7 @@ void pattern::Initialize(const char* pattern, size_t length)
|
||||||
|
|
||||||
if (range.first != range.second)
|
if (range.first != range.second)
|
||||||
{
|
{
|
||||||
std::for_each(range.first, range.second, [&] (const std::pair<uint64_t, uintptr_t>& hint)
|
std::for_each(range.first, range.second, [&] (const auto& hint)
|
||||||
{
|
{
|
||||||
ConsiderHint(hint.second);
|
ConsiderHint(hint.second);
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "Patterns.h"
|
#include "Patterns.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
struct PsGlobalType
|
struct PsGlobalType
|
||||||
{
|
{
|
||||||
HWND window;
|
HWND window;
|
||||||
|
@ -888,7 +890,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
GetWindowRect(GetDesktopWindow(), &desktop);
|
GetWindowRect(GetDesktopWindow(), &desktop);
|
||||||
sprintf_s(aNoDesktopMode, "Cannot find %dx%dx32 video mode", desktop.right, desktop.bottom);
|
sprintf_s(aNoDesktopMode, "Cannot find %dx%dx32 video mode", desktop.right, desktop.bottom);
|
||||||
|
|
||||||
ScopedUnprotect::Section Protect( GetModuleHandle( nullptr ), ".text" );
|
const HINSTANCE hModule = GetModuleHandle( nullptr );
|
||||||
|
std::unique_ptr<ScopedUnprotect::Section> SectionProtect = std::make_unique<ScopedUnprotect::Section>( hModule, ".text" );
|
||||||
|
std::unique_ptr<ScopedUnprotect::FullModule> ModuleProtect = nullptr;
|
||||||
|
if ( !SectionProtect->SectionLocated() )
|
||||||
|
{
|
||||||
|
SectionProtect = nullptr;
|
||||||
|
ModuleProtect = std::make_unique<ScopedUnprotect::FullModule>( hModule );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (*(DWORD*)0x5C1E75 == 0xB85548EC) Patch_III_10(desktop);
|
if (*(DWORD*)0x5C1E75 == 0xB85548EC) Patch_III_10(desktop);
|
||||||
else if (*(DWORD*)0x5C2135 == 0xB85548EC) Patch_III_11(desktop);
|
else if (*(DWORD*)0x5C2135 == 0xB85548EC) Patch_III_11(desktop);
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "Patterns.h"
|
#include "Patterns.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
struct RsGlobalType
|
struct RsGlobalType
|
||||||
{
|
{
|
||||||
const char* AppName;
|
const char* AppName;
|
||||||
|
@ -706,7 +708,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
GetWindowRect(GetDesktopWindow(), &desktop);
|
GetWindowRect(GetDesktopWindow(), &desktop);
|
||||||
sprintf_s(aNoDesktopMode, "Cannot find %dx%dx32 video mode", desktop.right, desktop.bottom);
|
sprintf_s(aNoDesktopMode, "Cannot find %dx%dx32 video mode", desktop.right, desktop.bottom);
|
||||||
|
|
||||||
ScopedUnprotect::Section Protect( GetModuleHandle( nullptr ), ".text" );
|
const HINSTANCE hModule = GetModuleHandle( nullptr );
|
||||||
|
std::unique_ptr<ScopedUnprotect::Section> SectionProtect = std::make_unique<ScopedUnprotect::Section>( hModule, ".text" );
|
||||||
|
std::unique_ptr<ScopedUnprotect::FullModule> ModuleProtect = nullptr;
|
||||||
|
if ( !SectionProtect->SectionLocated() )
|
||||||
|
{
|
||||||
|
SectionProtect = nullptr;
|
||||||
|
ModuleProtect = std::make_unique<ScopedUnprotect::FullModule>( hModule );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if(*(DWORD*)0x667BF5 == 0xB85548EC) Patch_VC_10(desktop);
|
if(*(DWORD*)0x667BF5 == 0xB85548EC) Patch_VC_10(desktop);
|
||||||
else if(*(DWORD*)0x667C45 == 0xB85548EC) Patch_VC_11(desktop);
|
else if(*(DWORD*)0x667C45 == 0xB85548EC) Patch_VC_11(desktop);
|
||||||
|
|
Loading…
Reference in a new issue