mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-12-29 15:23:02 +05:00
Updated Memory
This commit is contained in:
parent
2420d0f7e9
commit
e344ee91a0
1 changed files with 169 additions and 67 deletions
|
@ -65,13 +65,19 @@ inline T AddressByVersion(DWORD address10, DWORD address11, DWORD addressSteam)
|
||||||
switch ( bVer )
|
switch ( bVer )
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
|
#ifdef assert
|
||||||
assert(address11);
|
assert(address11);
|
||||||
|
#endif
|
||||||
return (T)address11;
|
return (T)address11;
|
||||||
case 2:
|
case 2:
|
||||||
|
#ifdef assert
|
||||||
assert(addressSteam);
|
assert(addressSteam);
|
||||||
|
#endif
|
||||||
return (T)addressSteam;
|
return (T)addressSteam;
|
||||||
default:
|
default:
|
||||||
|
#ifdef assert
|
||||||
assert(address10);
|
assert(address10);
|
||||||
|
#endif
|
||||||
return (T)address10;
|
return (T)address10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,13 +107,19 @@ inline T AddressByVersion(DWORD address10, DWORD address11, DWORD addressSteam)
|
||||||
switch ( bVer )
|
switch ( bVer )
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
|
#ifdef assert
|
||||||
assert(address11);
|
assert(address11);
|
||||||
|
#endif
|
||||||
return (T)address11;
|
return (T)address11;
|
||||||
case 2:
|
case 2:
|
||||||
|
#ifdef assert
|
||||||
assert(addressSteam);
|
assert(addressSteam);
|
||||||
|
#endif
|
||||||
return (T)addressSteam;
|
return (T)addressSteam;
|
||||||
default:
|
default:
|
||||||
|
#ifdef assert
|
||||||
assert(address10);
|
assert(address10);
|
||||||
|
#endif
|
||||||
return (T)address10;
|
return (T)address10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +150,7 @@ inline void InitializeVersions()
|
||||||
// 1.01 US
|
// 1.01 US
|
||||||
*bVer = 1;
|
*bVer = 1;
|
||||||
*bEuropean = false;
|
*bEuropean = false;
|
||||||
}
|
}
|
||||||
else if ( *(DWORD*)DynBaseAddress(0x82533C) == 0x94BF )
|
else if ( *(DWORD*)DynBaseAddress(0x82533C) == 0x94BF )
|
||||||
{
|
{
|
||||||
// 1.01 EU
|
// 1.01 EU
|
||||||
|
@ -192,7 +204,9 @@ inline void InitializeRegion_10()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef assert
|
||||||
assert(!"AddressByRegion_10 on non-1.0 EXE!");
|
assert(!"AddressByRegion_10 on non-1.0 EXE!");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,7 +222,7 @@ inline void InitializeRegion_11()
|
||||||
{
|
{
|
||||||
*bVer = 1;
|
*bVer = 1;
|
||||||
*bEuropean = false;
|
*bEuropean = false;
|
||||||
}
|
}
|
||||||
else if ( *(DWORD*)0x82533C == 0x94BF )
|
else if ( *(DWORD*)0x82533C == 0x94BF )
|
||||||
{
|
{
|
||||||
*bVer = 1;
|
*bVer = 1;
|
||||||
|
@ -216,7 +230,9 @@ inline void InitializeRegion_11()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef assert
|
||||||
assert(!"AddressByRegion_11 on non-1.01 EXE!");
|
assert(!"AddressByRegion_11 on non-1.01 EXE!");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,7 +249,9 @@ inline T AddressByVersion(DWORD address10, DWORD address11, DWORD addressSteam)
|
||||||
switch ( bVer )
|
switch ( bVer )
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
|
#ifdef assert
|
||||||
assert(address11);
|
assert(address11);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Safety measures - if null, return dummy var pointer to prevent a crash
|
// Safety measures - if null, return dummy var pointer to prevent a crash
|
||||||
if ( !address11 )
|
if ( !address11 )
|
||||||
|
@ -249,7 +267,9 @@ inline T AddressByVersion(DWORD address10, DWORD address11, DWORD addressSteam)
|
||||||
}
|
}
|
||||||
return (T)address11;
|
return (T)address11;
|
||||||
case 2:
|
case 2:
|
||||||
|
#ifdef assert
|
||||||
assert(addressSteam);
|
assert(addressSteam);
|
||||||
|
#endif
|
||||||
// Safety measures - if null, return dummy var pointer to prevent a crash
|
// Safety measures - if null, return dummy var pointer to prevent a crash
|
||||||
if ( !addressSteam )
|
if ( !addressSteam )
|
||||||
return (T)GetDummy();
|
return (T)GetDummy();
|
||||||
|
@ -261,7 +281,9 @@ inline T AddressByVersion(DWORD address10, DWORD address11, DWORD addressSteam)
|
||||||
// TODO: DO
|
// TODO: DO
|
||||||
return (T)GetDummy();
|
return (T)GetDummy();
|
||||||
default:
|
default:
|
||||||
|
#ifdef assert
|
||||||
assert(address10);
|
assert(address10);
|
||||||
|
#endif
|
||||||
// Adjust to EU if needed
|
// Adjust to EU if needed
|
||||||
if ( bEuropean && address10 > 0x7466D0 )
|
if ( bEuropean && address10 > 0x7466D0 )
|
||||||
{
|
{
|
||||||
|
@ -285,7 +307,9 @@ inline T AddressByVersion(DWORD address10, DWORD address11, DWORD addressSteam,
|
||||||
switch ( bVer )
|
switch ( bVer )
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
|
#ifdef assert
|
||||||
assert(address11);
|
assert(address11);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Safety measures - if null, return dummy var pointer to prevent a crash
|
// Safety measures - if null, return dummy var pointer to prevent a crash
|
||||||
if ( !address11 )
|
if ( !address11 )
|
||||||
|
@ -301,7 +325,9 @@ inline T AddressByVersion(DWORD address10, DWORD address11, DWORD addressSteam,
|
||||||
}
|
}
|
||||||
return (T)address11;
|
return (T)address11;
|
||||||
case 2:
|
case 2:
|
||||||
|
#ifdef assert
|
||||||
assert(addressSteam);
|
assert(addressSteam);
|
||||||
|
#endif
|
||||||
// Safety measures - if null, return dummy var pointer to prevent a crash
|
// Safety measures - if null, return dummy var pointer to prevent a crash
|
||||||
if ( !addressSteam )
|
if ( !addressSteam )
|
||||||
return (T)GetDummy();
|
return (T)GetDummy();
|
||||||
|
@ -310,19 +336,25 @@ inline T AddressByVersion(DWORD address10, DWORD address11, DWORD addressSteam,
|
||||||
case 3:
|
case 3:
|
||||||
return (T)GetDummy();
|
return (T)GetDummy();
|
||||||
case 4:
|
case 4:
|
||||||
|
#ifdef assert
|
||||||
assert(addressNewsteamR2);
|
assert(addressNewsteamR2);
|
||||||
|
#endif
|
||||||
if ( !addressNewsteamR2 )
|
if ( !addressNewsteamR2 )
|
||||||
return (T)GetDummy();
|
return (T)GetDummy();
|
||||||
|
|
||||||
return (T)DynBaseAddress(addressNewsteamR2);
|
return (T)DynBaseAddress(addressNewsteamR2);
|
||||||
case 5:
|
case 5:
|
||||||
|
#ifdef assert
|
||||||
assert(addressNewsteamR2_LV);
|
assert(addressNewsteamR2_LV);
|
||||||
|
#endif
|
||||||
if ( !addressNewsteamR2_LV )
|
if ( !addressNewsteamR2_LV )
|
||||||
return (T)GetDummy();
|
return (T)GetDummy();
|
||||||
|
|
||||||
return (T)DynBaseAddress(addressNewsteamR2_LV);
|
return (T)DynBaseAddress(addressNewsteamR2_LV);
|
||||||
default:
|
default:
|
||||||
|
#ifdef assert
|
||||||
assert(address10);
|
assert(address10);
|
||||||
|
#endif
|
||||||
// Adjust to EU if needed
|
// Adjust to EU if needed
|
||||||
if ( bEuropean && address10 > 0x7466D0 )
|
if ( bEuropean && address10 > 0x7466D0 )
|
||||||
{
|
{
|
||||||
|
@ -380,9 +412,8 @@ namespace Memory
|
||||||
{*(T*)address = value; }
|
{*(T*)address = value; }
|
||||||
|
|
||||||
template<typename AT>
|
template<typename AT>
|
||||||
inline void Nop(AT address, unsigned int nCount)
|
inline void Nop(AT address, size_t count)
|
||||||
// TODO: Finish multibyte nops
|
{ memset((void*)address, 0x90, count); }
|
||||||
{ memset((void*)address, 0x90, nCount); }
|
|
||||||
|
|
||||||
template<typename AT, typename HT>
|
template<typename AT, typename HT>
|
||||||
inline void InjectHook(AT address, HT hook)
|
inline void InjectHook(AT address, HT hook)
|
||||||
|
@ -411,90 +442,161 @@ namespace Memory
|
||||||
|
|
||||||
*(ptrdiff_t*)((DWORD)address + 1) = dwHook - (DWORD)address - 5;
|
*(ptrdiff_t*)((DWORD)address + 1) = dwHook - (DWORD)address - 5;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
namespace MemoryVP
|
|
||||||
{
|
|
||||||
template<typename T, typename AT>
|
|
||||||
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<typename AT>
|
|
||||||
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<typename AT, typename HT>
|
|
||||||
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<typename AT, typename HT>
|
|
||||||
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
|
namespace DynBase
|
||||||
{
|
{
|
||||||
template<typename T, typename AT>
|
template<typename T, typename AT>
|
||||||
inline void Patch(AT address, T value)
|
inline void Patch(AT address, T value)
|
||||||
{
|
{
|
||||||
MemoryVP::Patch(DynBaseAddress(address), value);
|
VP::Patch(DynBaseAddress(address), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename AT>
|
template<typename AT>
|
||||||
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<typename AT, typename HT>
|
template<typename AT, typename HT>
|
||||||
inline void InjectHook(AT address, HT hook)
|
inline void InjectHook(AT address, HT hook)
|
||||||
{
|
{
|
||||||
MemoryVP::InjectHook(DynBaseAddress(address), hook);
|
VP::InjectHook(DynBaseAddress(address), hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename AT, typename HT>
|
template<typename AT, typename HT>
|
||||||
inline void InjectHook(AT address, HT hook, unsigned int nType)
|
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<typename T, typename AT>
|
||||||
|
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<typename AT>
|
||||||
|
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<typename AT, typename HT>
|
||||||
|
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<typename AT, typename HT>
|
||||||
|
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<typename T, typename AT>
|
||||||
|
inline void Patch(AT address, T value)
|
||||||
|
{
|
||||||
|
VP::Patch(DynBaseAddress(address), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename AT>
|
||||||
|
inline void Nop(AT address, size_t count)
|
||||||
|
{
|
||||||
|
VP::Nop(DynBaseAddress(address), count);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename AT, typename HT>
|
||||||
|
inline void InjectHook(AT address, HT hook)
|
||||||
|
{
|
||||||
|
VP::InjectHook(DynBaseAddress(address), hook);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename AT, typename HT>
|
||||||
|
inline void InjectHook(AT address, HT hook, unsigned int nType)
|
||||||
|
{
|
||||||
|
VP::InjectHook(DynBaseAddress(address), hook, nType);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !defined _SIMPLE_MEMORY_ONLY
|
||||||
|
|
||||||
|
#include <forward_list>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
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
|
#endif
|
Loading…
Reference in a new issue