diff --git a/SilentPatch/MemoryMgr.h b/SilentPatch/MemoryMgr.h index fece197..5439f14 100644 --- a/SilentPatch/MemoryMgr.h +++ b/SilentPatch/MemoryMgr.h @@ -626,57 +626,85 @@ namespace Memory #include #include -class ScopedUnprotect +namespace ScopedUnprotect { -public: - class Section + class unprotect { - public: - Section( HINSTANCE hInstance, const char* name ) + protected: + 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; - while ( QueriedSize < VirtualSize ) + while ( QueriedSize < Size ) { MEMORY_BASIC_INFORMATION MemoryInf; DWORD dwOldProtect; - VirtualQuery( (LPCVOID)(VirtualAddress + QueriedSize), &MemoryInf, sizeof(MemoryInf) ); - VirtualProtect( MemoryInf.BaseAddress, MemoryInf.RegionSize, PAGE_EXECUTE_READWRITE, &dwOldProtect ); - m_queriedProtects.emplace_front( MemoryInf.BaseAddress, MemoryInf.RegionSize, MemoryInf.Protect ); + VirtualQuery( (LPCVOID)(BaseAddress + QueriedSize), &MemoryInf, sizeof(MemoryInf) ); + if ( MemoryInf.State == MEM_COMMIT && (MemoryInf.Type & MEM_IMAGE) != 0 && + (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; } - }; + } - ~Section() + ~unprotect() { for ( auto& it : m_queriedProtects ) { DWORD dwOldProtect; VirtualProtect( std::get<0>(it), std::get<1>(it), std::get<2>(it), &dwOldProtect ); - } + } } private: 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 diff --git a/SilentPatch/Patterns.cpp b/SilentPatch/Patterns.cpp index 66aa517..07d13b5 100644 --- a/SilentPatch/Patterns.cpp +++ b/SilentPatch/Patterns.cpp @@ -126,7 +126,7 @@ public: PIMAGE_DOS_HEADER dosHeader = getRVA(0); PIMAGE_NT_HEADERS ntHeader = getRVA(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) @@ -156,7 +156,7 @@ void pattern::Initialize(const char* pattern, size_t length) if (range.first != range.second) { - std::for_each(range.first, range.second, [&] (const std::pair& hint) + std::for_each(range.first, range.second, [&] (const auto& hint) { ConsiderHint(hint.second); }); diff --git a/SilentPatchIII/SilentPatchIII.cpp b/SilentPatchIII/SilentPatchIII.cpp index 56a808b..edaf990 100644 --- a/SilentPatchIII/SilentPatchIII.cpp +++ b/SilentPatchIII/SilentPatchIII.cpp @@ -4,6 +4,8 @@ #include "Timer.h" #include "Patterns.h" +#include + struct PsGlobalType { HWND window; @@ -888,7 +890,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) GetWindowRect(GetDesktopWindow(), &desktop); 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 SectionProtect = std::make_unique( hModule, ".text" ); + std::unique_ptr ModuleProtect = nullptr; + if ( !SectionProtect->SectionLocated() ) + { + SectionProtect = nullptr; + ModuleProtect = std::make_unique( hModule ); + } + if (*(DWORD*)0x5C1E75 == 0xB85548EC) Patch_III_10(desktop); else if (*(DWORD*)0x5C2135 == 0xB85548EC) Patch_III_11(desktop); diff --git a/SilentPatchVC/SilentPatchVC.cpp b/SilentPatchVC/SilentPatchVC.cpp index 4f609bd..185d768 100644 --- a/SilentPatchVC/SilentPatchVC.cpp +++ b/SilentPatchVC/SilentPatchVC.cpp @@ -3,6 +3,8 @@ #include "Timer.h" #include "Patterns.h" +#include + struct RsGlobalType { const char* AppName; @@ -706,7 +708,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) GetWindowRect(GetDesktopWindow(), &desktop); 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 SectionProtect = std::make_unique( hModule, ".text" ); + std::unique_ptr ModuleProtect = nullptr; + if ( !SectionProtect->SectionLocated() ) + { + SectionProtect = nullptr; + ModuleProtect = std::make_unique( hModule ); + } + if(*(DWORD*)0x667BF5 == 0xB85548EC) Patch_VC_10(desktop); else if(*(DWORD*)0x667C45 == 0xB85548EC) Patch_VC_11(desktop);