Skip to content

Commit

Permalink
Loader fixes and improvements (intercept#291)
Browse files Browse the repository at this point in the history
* Use better and safer alternative to IsBadReadPtr;
Fix loader for vc143;
Fix hashmap poolAlloc

* Fix Linux build
  • Loading branch information
Leopard20 authored Jan 6, 2024
1 parent 7964098 commit 7a32180
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/host/loader/StateTypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ namespace intercept {
if (arr.size() != arr.capacity())
return false;

if (IsBadReadPtr(arr.data(), sizeof(void*)))
if (IsBadReadPtr(arr.data(), sizeof(void*) + 2 * sizeof(int)))
return false;

return true;
}

Expand Down
19 changes: 15 additions & 4 deletions src/host/loader/loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ namespace intercept {
auto future_poolFuncAlloc = std::async([&]() {
auto result = memorySections.findInMemoryPattern("\x40\x53\x48\x83\xEC\x20\xFF\x41\x60\x48\x8B\x41\x08\x48\x8B\xD9\x48\x3B\xC1\x74\x0B\x48\x85\xC0\x74\x06\x48\x83\xC0\xE0\x75\x2B\x48\x8D\x41\x18\x48\x8B\x49\x20\x48\x3B\xC8\x74\x0E\x48\x85\xC9\x74\x09\x48\x8D\x41\xE0\x48\x85\xC0\x75\x10\x48\x8B\xCB\xE8\x00\x00\x00\x00\x84\xC0\x0F\x84\x00\x00\x00\x00\x4C\x8B\x43\x08\x32\xC9\x45\x33\xD2\x4C\x3B\xC3\x74\x0B\x4D\x85\xC0\x74\x06\x49\x83\xC0\xE0\x75\x2A\x4C\x8B\x43\x20\x48\x8D\x43\x18\x4C\x3B\xC0", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx????xxxx????xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
if (!result) //vc143
result = memorySections.findInMemoryPattern("\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x20\xFF\x41\x60\x33\xF6\x48\x8B\x41\x08\x48\x8B\xD9\x48\x3B\xC1\x74\x0F\x48\x85\xC0\x74\x0A\x48\x83\xC0\xE0\x0F\x85\x00\x00\x00\x00\x48\x8B\x41\x20\x48\x8D\x79\x18\x48\x3B\xC7\x74\x0F\x48\x85\xC0\x74\x0A\x48\x83\xC0\xE0\x0F\x85\x00\x00\x00\x00\x48\x63\x51\x58\x48\x8B\x0D\x00\x00\x00\x00\x4C\x8B\xC2\x48\x8B\x01\xFF\x50\x38\x48\x89\x70\x28\x48\x8B\xD0\x48\x89\x70\x20\x48\x8D\x48\x20\x48\x85\xC0\x0F\x84\x00\x00\x00\x00\x89\x30\x89\x70\x10\x48\x89\x58\x08\x48\x8B\x47\x08\x48\x89\x08\x48\x8B\x47\x08\x48\x89\x39\x48\x89\x42\x28\xFF\x47\x10\x48\x89\x4F\x08\x44\x8B\x4B\x5C", "xxxx?xxxx?xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx????xxxxxxxxxxxxxxxxxxxxxxxx????xxxxxxx????xxxxxxxxxxxxxxxxxxxxxxxxxxxxx????xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
result = memorySections.findInMemoryPattern("\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x20\xFF\x41\x60\x33\xF6\x48\x8B\x41\x08\x48\x8B\xD9\x48\x3B\xC1\x74\x0F\x48\x85\xC0\x74\x0A\x48\x83\xC0\xE0\x0F\x85\xB7\x00\x00\x00\x48\x8B\x41\x20\x48\x8D\x79\x18\x48\x3B\xC7\x74\x0F\x48\x85\xC0\x74\x0A\x48\x83\xC0\xE0\x0F\x85\x9B\x00\x00\x00\x48\x63\x51\x58\x48\x8B\x0D\xDA\x02\xD5\x00\x4C\x8B\xC2\x48\x8B\x01\xFF\x50\x38\x48\x89\x70\x28\x48\x8B\xD0\x48\x89\x70\x20\x4C\x8D\x40\x20\x48\x85\xC0\x0F\x84\x6F\x01\x00\x00\x89\x30\x89\x70\x10\x48\x89\x58\x08\x48\x8B\x4F\x08\x4C\x89\x01\x48\x8B\x47\x08\x49\x89\x38\x48\x89\x42\x28\xFF\x47\x10\x4C\x89\x47\x08\x44\x8B\x43\x5C", "xxxx?xxxx?xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx????xxxxxxxxxxxxxxxxxxxxxxxx????xxxxxxx????xxxxxxxxxxxxxxxxxxxxxxxxxxxxx????xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");

return result;
});
Expand Down Expand Up @@ -318,7 +318,7 @@ namespace intercept {
const char* test = getRTTIName(allocatorVtablePtr);
bool vc143Allocator = false;
if (strlen(test) == 0) {
allocatorVtablePtr -= 0xA8; // vc143 build
allocatorVtablePtr -= 0xB0; // vc143 build
test = getRTTIName(allocatorVtablePtr);
vc143Allocator = true;
}
Expand All @@ -343,10 +343,21 @@ namespace intercept {
if (!entry->_createFunction) continue; //Some types don't have create functions. Example: VECTOR.
#if _WIN64 || __X86_64__
auto baseOffset = 0x7;
if (entry->_name == "CODE"sv) baseOffset += 2;

if (vc143Allocator)
baseOffset = 0xC;
{
if (entry->_name == "HASHMAP"sv)
baseOffset = 0xAA;
else
baseOffset = 0xC;
}
else
{
if (entry->_name == "CODE"sv)
baseOffset += 2;
else if
(entry->_name == "HASHMAP"sv) baseOffset = 0xA5;
}

const auto instructionPointer = reinterpret_cast<uintptr_t>(entry->_createFunction) + baseOffset + 0x4;
const auto offset = *reinterpret_cast<uint32_t*>(reinterpret_cast<uintptr_t>(entry->_createFunction) + baseOffset);
Expand Down
40 changes: 40 additions & 0 deletions src/host/loader/ptraccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,46 @@
#pragma once
#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#ifdef __cplusplus
// From: https://stackoverflow.com/questions/496034/most-efficient-replacement-for-isbadreadptr
// Check memory address access
static const DWORD dwForbiddenArea = PAGE_GUARD | PAGE_NOACCESS;
static const DWORD dwReadRights = PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY;
static const DWORD dwWriteRights = PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY;

template<DWORD dwAccessRights>
bool CheckAccess(const void* pAddress, size_t nSize)
{
if (!pAddress || !nSize)
{
return false;
}

MEMORY_BASIC_INFORMATION sMBI;
bool bRet = false;

UINT_PTR pCurrentAddress = UINT_PTR(pAddress);
UINT_PTR pEndAdress = pCurrentAddress + (nSize - 1);

do
{
ZeroMemory(&sMBI, sizeof(sMBI));
VirtualQuery(LPCVOID(pCurrentAddress), &sMBI, sizeof(sMBI));

bRet = (sMBI.State & MEM_COMMIT) // memory allocated and
&& !(sMBI.Protect & dwForbiddenArea) // access to page allowed and
&& (sMBI.Protect & dwAccessRights); // the required rights

pCurrentAddress = (UINT_PTR(sMBI.BaseAddress) + sMBI.RegionSize);
} while (bRet && pCurrentAddress <= pEndAdress);

return bRet;
}

#define IsBadWritePtr(p,n) (!CheckAccess<dwWriteRights>(p,n))
#define IsBadReadPtr(p,n) (!CheckAccess<dwReadRights>(p,n))
#define IsBadStringPtrW(p,n) (!CheckAccess<dwReadRights>(p,n*2))
#endif /* defined(__cplusplus) */
#else
#define __CUSTOM_ISBADREADPTR
#ifdef __cplusplus
Expand Down

0 comments on commit 7a32180

Please sign in to comment.