Updated Memory

This commit is contained in:
Silent 2016-08-10 22:27:16 +02:00
parent 2420d0f7e9
commit e344ee91a0

View file

@ -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