[Memory] Add non buggy IsBadReadPtr implementation

This commit is contained in:
TheApadayo 2017-02-21 14:15:16 -05:00
parent ac4f824a7c
commit 06472685e2
5 changed files with 41 additions and 12 deletions

View File

@ -26,7 +26,7 @@ namespace Components
char** Console::GetAutoCompleteFileList(const char *path, const char *extension, Game::FsListBehavior_e behavior, int *numfiles, int allocTrackType) char** Console::GetAutoCompleteFileList(const char *path, const char *extension, Game::FsListBehavior_e behavior, int *numfiles, int allocTrackType)
{ {
if (path == reinterpret_cast<char*>(0xBAADF00D) || path == reinterpret_cast<char*>(0xCDCDCDCD) || IsBadReadPtr(path, 1)) return nullptr; if (path == reinterpret_cast<char*>(0xBAADF00D) || path == reinterpret_cast<char*>(0xCDCDCDCD) || ::Utils::Memory::IsBadReadPtr(path)) return nullptr;
return Game::FS_GetFileList(path, extension, behavior, numfiles, allocTrackType); return Game::FS_GetFileList(path, extension, behavior, numfiles, allocTrackType);
} }

View File

@ -569,7 +569,7 @@ namespace Components
HRESULT D3D9Ex::D3D9Device::SetPixelShaderConstantF(UINT StartRegister, CONST float* pConstantData, UINT Vector4fCount) HRESULT D3D9Ex::D3D9Device::SetPixelShaderConstantF(UINT StartRegister, CONST float* pConstantData, UINT Vector4fCount)
{ {
if (IsBadReadPtr(pConstantData, Vector4fCount * 16)) if (::Utils::Memory::IsBadReadPtr(pConstantData/*, Vector4fCount * 16*/))
{ {
//Logger::Print("Invalid shader constant array!\n"); //Logger::Print("Invalid shader constant array!\n");
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;

View File

@ -42,10 +42,10 @@ namespace Steam
void* Interface::lookupMethod(std::string method) void* Interface::lookupMethod(std::string method)
{ {
if (IsBadReadPtr(this->interfacePtr, 4)) return nullptr; if (::Utils::Memory::IsBadReadPtr(this->interfacePtr)) return nullptr;
unsigned char** vftbl = *static_cast<unsigned char***>(this->interfacePtr); unsigned char** vftbl = *static_cast<unsigned char***>(this->interfacePtr);
while (!IsBadReadPtr(vftbl, 4) && !IsBadCodePtr((FARPROC(*vftbl)))) while (!::Utils::Memory::IsBadReadPtr(vftbl) && !::Utils::Memory::IsBadCodePtr((FARPROC(*vftbl))))
{ {
if(this->getMethodName(*vftbl) == method) return *vftbl; if(this->getMethodName(*vftbl) == method) return *vftbl;
++vftbl; ++vftbl;
@ -57,7 +57,7 @@ namespace Steam
size_t Interface::getMethodParamSize(void* method) size_t Interface::getMethodParamSize(void* method)
{ {
unsigned char* methodPtr = static_cast<unsigned char*>(method); unsigned char* methodPtr = static_cast<unsigned char*>(method);
for (; !IsBadReadPtr(methodPtr, 3); ++methodPtr) for (; !::Utils::Memory::IsBadReadPtr(methodPtr); ++methodPtr)
{ {
if (methodPtr[0] == 0xC2 && methodPtr[2] == 0) // __stdcall return if (methodPtr[0] == 0xC2 && methodPtr[2] == 0) // __stdcall return
{ {
@ -71,12 +71,12 @@ namespace Steam
std::string Interface::getMethodName(unsigned char* methodPtr) std::string Interface::getMethodName(unsigned char* methodPtr)
{ {
for(;!IsBadReadPtr(methodPtr, 3); ++methodPtr) for(;!::Utils::Memory::IsBadReadPtr(methodPtr); ++methodPtr)
{ {
if(methodPtr[0] == 0x68) // Push if(methodPtr[0] == 0x68) // Push
{ {
char* name = *reinterpret_cast<char**>(&methodPtr[1]); char* name = *reinterpret_cast<char**>(&methodPtr[1]);
if(!IsBadReadPtr(name, 1)) return name; if(::Utils::Memory::IsBadReadPtr(name)) return name;
} }
else if(methodPtr[0] == 0xC2 && methodPtr[2] == 0) // __stdcall return else if(methodPtr[0] == 0xC2 && methodPtr[2] == 0) // __stdcall return
{ {
@ -322,11 +322,7 @@ namespace Steam
void Proxy::StartSteamIfNecessary() void Proxy::StartSteamIfNecessary()
{ {
if (Proxy::GetSteamDirectory().empty() if (Proxy::GetSteamDirectory().empty() || !Steam::Enabled()) return;
#ifndef DEBUG
|| !Steam::Enabled()
#endif
) return;
HKEY hRegKey; HKEY hRegKey;
DWORD pid = 0; DWORD pid = 0;

View File

@ -64,4 +64,34 @@ namespace Utils
return true; return true;
} }
bool Memory::IsBadReadPtr(const void* ptr)
{
MEMORY_BASIC_INFORMATION mbi = { 0 };
if (::VirtualQuery(ptr, &mbi, sizeof(mbi)))
{
DWORD mask = (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY);
bool b = !(mbi.Protect & mask);
// check the page is not a guard page
if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS)) b = true;
return b;
}
return true;
}
bool Memory::IsBadCodePtr(const void* ptr)
{
MEMORY_BASIC_INFORMATION mbi = { 0 };
if (::VirtualQuery(ptr, &mbi, sizeof(mbi)))
{
DWORD mask = (PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY);
bool b = !(mbi.Protect & mask);
// check the page is not a guard page
if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS)) b = true;
return b;
}
return true;
}
} }

View File

@ -130,5 +130,8 @@ namespace Utils
static void FreeAlign(const void* data); static void FreeAlign(const void* data);
static bool IsSet(void* mem, char chr, size_t length); static bool IsSet(void* mem, char chr, size_t length);
static bool IsBadReadPtr(const void* ptr);
static bool IsBadCodePtr(const void* ptr);
}; };
} }