diff --git a/SilentPatch/MemoryMgr.h b/SilentPatch/MemoryMgr.h index c45e178..df46236 100644 --- a/SilentPatch/MemoryMgr.h +++ b/SilentPatch/MemoryMgr.h @@ -65,13 +65,19 @@ inline T AddressByVersion(DWORD address10, DWORD address11, DWORD addressSteam) switch ( bVer ) { case 1: +#ifdef assert assert(address11); +#endif return (T)address11; case 2: +#ifdef assert assert(addressSteam); +#endif return (T)addressSteam; default: +#ifdef assert assert(address10); +#endif return (T)address10; } } @@ -101,13 +107,19 @@ inline T AddressByVersion(DWORD address10, DWORD address11, DWORD addressSteam) switch ( bVer ) { case 1: +#ifdef assert assert(address11); +#endif return (T)address11; case 2: +#ifdef assert assert(addressSteam); +#endif return (T)addressSteam; default: +#ifdef assert assert(address10); +#endif return (T)address10; } } @@ -138,7 +150,7 @@ inline void InitializeVersions() // 1.01 US *bVer = 1; *bEuropean = false; - } + } else if ( *(DWORD*)DynBaseAddress(0x82533C) == 0x94BF ) { // 1.01 EU @@ -192,7 +204,9 @@ inline void InitializeRegion_10() } else { +#ifdef assert assert(!"AddressByRegion_10 on non-1.0 EXE!"); +#endif } } } @@ -208,7 +222,7 @@ inline void InitializeRegion_11() { *bVer = 1; *bEuropean = false; - } + } else if ( *(DWORD*)0x82533C == 0x94BF ) { *bVer = 1; @@ -216,7 +230,9 @@ inline void InitializeRegion_11() } else { +#ifdef assert assert(!"AddressByRegion_11 on non-1.01 EXE!"); +#endif } } } @@ -233,7 +249,9 @@ inline T AddressByVersion(DWORD address10, DWORD address11, DWORD addressSteam) switch ( bVer ) { case 1: +#ifdef assert assert(address11); +#endif // Safety measures - if null, return dummy var pointer to prevent a crash if ( !address11 ) @@ -249,7 +267,9 @@ inline T AddressByVersion(DWORD address10, DWORD address11, DWORD addressSteam) } return (T)address11; case 2: +#ifdef assert assert(addressSteam); +#endif // Safety measures - if null, return dummy var pointer to prevent a crash if ( !addressSteam ) return (T)GetDummy(); @@ -261,7 +281,9 @@ inline T AddressByVersion(DWORD address10, DWORD address11, DWORD addressSteam) // TODO: DO return (T)GetDummy(); default: +#ifdef assert assert(address10); +#endif // Adjust to EU if needed if ( bEuropean && address10 > 0x7466D0 ) { @@ -285,7 +307,9 @@ inline T AddressByVersion(DWORD address10, DWORD address11, DWORD addressSteam, switch ( bVer ) { case 1: +#ifdef assert assert(address11); +#endif // Safety measures - if null, return dummy var pointer to prevent a crash if ( !address11 ) @@ -301,7 +325,9 @@ inline T AddressByVersion(DWORD address10, DWORD address11, DWORD addressSteam, } return (T)address11; case 2: +#ifdef assert assert(addressSteam); +#endif // Safety measures - if null, return dummy var pointer to prevent a crash if ( !addressSteam ) return (T)GetDummy(); @@ -310,19 +336,25 @@ inline T AddressByVersion(DWORD address10, DWORD address11, DWORD addressSteam, case 3: return (T)GetDummy(); case 4: +#ifdef assert assert(addressNewsteamR2); +#endif if ( !addressNewsteamR2 ) return (T)GetDummy(); return (T)DynBaseAddress(addressNewsteamR2); case 5: +#ifdef assert assert(addressNewsteamR2_LV); +#endif if ( !addressNewsteamR2_LV ) return (T)GetDummy(); return (T)DynBaseAddress(addressNewsteamR2_LV); default: +#ifdef assert assert(address10); +#endif // Adjust to EU if needed if ( bEuropean && address10 > 0x7466D0 ) { @@ -380,9 +412,8 @@ namespace Memory {*(T*)address = value; } template - inline void Nop(AT address, unsigned int nCount) - // TODO: Finish multibyte nops - { memset((void*)address, 0x90, nCount); } + inline void Nop(AT address, size_t count) + { memset((void*)address, 0x90, count); } template inline void InjectHook(AT address, HT hook) @@ -411,90 +442,161 @@ namespace Memory *(ptrdiff_t*)((DWORD)address + 1) = dwHook - (DWORD)address - 5; } -}; - -namespace MemoryVP -{ - template - inline void Patch(AT address, T value) - { - DWORD dwProtect[2]; - VirtualProtect((void*)address, sizeof(T), PAGE_EXECUTE_READWRITE, &dwProtect[0]); - *(T*)address = value; - VirtualProtect((void*)address, sizeof(T), dwProtect[0], &dwProtect[1]); - } - - template - inline void Nop(AT address, unsigned int nCount) - { - DWORD dwProtect[2]; - VirtualProtect((void*)address, nCount, PAGE_EXECUTE_READWRITE, &dwProtect[0]); - memset((void*)address, 0x90, nCount); - VirtualProtect((void*)address, nCount, dwProtect[0], &dwProtect[1]); - } - - template - inline void InjectHook(AT address, HT hook) - { - DWORD dwProtect[2]; - - VirtualProtect((void*)((DWORD)address + 1), 4, PAGE_EXECUTE_READWRITE, &dwProtect[0]); - DWORD dwHook; - _asm - { - mov eax, hook - mov dwHook, eax - } - - *(ptrdiff_t*)((DWORD)address + 1) = (DWORD)dwHook - (DWORD)address - 5; - VirtualProtect((void*)((DWORD)address + 1), 4, dwProtect[0], &dwProtect[1]); - } - - template - inline void InjectHook(AT address, HT hook, unsigned int nType) - { - DWORD dwProtect[2]; - - VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &dwProtect[0]); - *(BYTE*)address = nType == PATCH_JUMP ? 0xE9 : 0xE8; - - DWORD dwHook; - _asm - { - mov eax, hook - mov dwHook, eax - } - - *(ptrdiff_t*)((DWORD)address + 1) = (DWORD)dwHook - (DWORD)address - 5; - VirtualProtect((void*)address, 5, dwProtect[0], &dwProtect[1]); - } namespace DynBase { template inline void Patch(AT address, T value) { - MemoryVP::Patch(DynBaseAddress(address), value); + VP::Patch(DynBaseAddress(address), value); } template - inline void Nop(AT address, unsigned int nCount) + inline void Nop(AT address, size_t count) { - MemoryVP::Nop(DynBaseAddress(address), nCount); + VP::Nop(DynBaseAddress(address), count); } template inline void InjectHook(AT address, HT hook) { - MemoryVP::InjectHook(DynBaseAddress(address), hook); + VP::InjectHook(DynBaseAddress(address), hook); } template inline void InjectHook(AT address, HT hook, unsigned int nType) { - MemoryVP::InjectHook(DynBaseAddress(address), hook, nType); + VP::InjectHook(DynBaseAddress(address), hook, nType); } }; + + namespace VP + { + template + inline void Patch(AT address, T value) + { + DWORD dwProtect[2]; + VirtualProtect((void*)address, sizeof(T), PAGE_EXECUTE_READWRITE, &dwProtect[0]); + Memory::Patch( address, value ); + VirtualProtect((void*)address, sizeof(T), dwProtect[0], &dwProtect[1]); + } + + template + inline void Nop(AT address, size_t count) + { + DWORD dwProtect[2]; + VirtualProtect((void*)address, count, PAGE_EXECUTE_READWRITE, &dwProtect[0]); + Memory::Nop( address, count ); + VirtualProtect((void*)address, count, dwProtect[0], &dwProtect[1]); + } + + template + inline void InjectHook(AT address, HT hook) + { + DWORD dwProtect[2]; + + VirtualProtect((void*)((DWORD)address + 1), 4, PAGE_EXECUTE_READWRITE, &dwProtect[0]); + Memory::InjectHook( address, hook ); + VirtualProtect((void*)((DWORD)address + 1), 4, dwProtect[0], &dwProtect[1]); + } + + template + inline void InjectHook(AT address, HT hook, unsigned int nType) + { + DWORD dwProtect[2]; + + VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &dwProtect[0]); + Memory::InjectHook( address, hook, nType ); + VirtualProtect((void*)address, 5, dwProtect[0], &dwProtect[1]); + } + + namespace DynBase + { + template + inline void Patch(AT address, T value) + { + VP::Patch(DynBaseAddress(address), value); + } + + template + inline void Nop(AT address, size_t count) + { + VP::Nop(DynBaseAddress(address), count); + } + + template + inline void InjectHook(AT address, HT hook) + { + VP::InjectHook(DynBaseAddress(address), hook); + } + + template + inline void InjectHook(AT address, HT hook, unsigned int nType) + { + VP::InjectHook(DynBaseAddress(address), hook, nType); + } + }; + }; }; +#if !defined _SIMPLE_MEMORY_ONLY + +#include +#include + +class ScopedUnprotect +{ +public: + class Section + { + public: + Section( HINSTANCE hInstance, const char* name ) + { + 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 ( WORD 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 ) + { + MEMORY_BASIC_INFORMATION MemoryInf; + DWORD dwOldProtect; + + VirtualQuery( (LPCVOID)VirtualAddress, &MemoryInf, sizeof(MemoryInf) ); + VirtualProtect( MemoryInf.BaseAddress, MemoryInf.RegionSize, PAGE_EXECUTE_READWRITE, &dwOldProtect ); + m_queriedProtects.emplace_front( MemoryInf.BaseAddress, MemoryInf.RegionSize, MemoryInf.Protect ); + QueriedSize += MemoryInf.RegionSize; + } + }; + + ~Section() + { + 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; + }; +}; + +#endif + #endif \ No newline at end of file