Rebase for conflicts

This commit is contained in:
Kenzzer 2024-11-28 23:54:33 +01:00 committed by Headline
parent 9b6e36f6cd
commit fa5d7ffc21
13 changed files with 103 additions and 168 deletions

3
.gitmodules vendored
View File

@ -12,3 +12,6 @@
[submodule "public/safetyhook"]
path = public/safetyhook
url = https://github.com/alliedmodders/safetyhook
[submodule "core/logic/libaddrz"]
path = core/logic/libaddrz
url = https://github.com/dvander/libaddrz.git

View File

@ -86,9 +86,15 @@ for cxx in builder.targets:
'DatabaseConfBuilder.cpp',
'LumpManager.cpp',
'smn_entitylump.cpp',
'libaddrz/addrz.cpp',
'libaddrz/mapping.cpp',
'libaddrz/platform.cpp',
'libaddrz/proc_maps.cpp',
'PseudoAddrManager.cpp',
]
if binary.compiler.target.arch == 'x86_64':
binary.sources += ['PseudoAddrManager.cpp']
if binary.compiler.target.platform == 'linux':
binary.sources += ['libaddrz/platform_linux.cpp']
elif binary.compiler.target.platform == 'windows':
binary.sources += ['libaddrz/platform_windows.cpp']
SM.binaries += [builder.Add(binary)]

View File

@ -28,6 +28,7 @@
*/
#include "PseudoAddrManager.h"
#include <bridge/include/CoreProvider.h>
#ifdef PLATFORM_APPLE
#include <mach/mach.h>
#include <mach/vm_region.h>
@ -35,135 +36,62 @@
#ifdef PLATFORM_LINUX
#include <inttypes.h>
#endif
#ifdef PLATFORM_WINDOWS
#include <Psapi.h>
#endif
PseudoAddressManager::PseudoAddressManager() : m_NumEntries(0)
PseudoAddressManager::PseudoAddressManager() : m_dictionary(am::IPlatform::GetDefault())
{
}
// A pseudo address consists of a table index in the upper 6 bits and an offset in the
// lower 26 bits. The table consists of memory allocation base addresses.
void PseudoAddressManager::Initialize() {
#ifdef PLATFORM_WINDOWS
auto process = GetCurrentProcess();
auto get_module_details = [process](const char* name, void*& baseAddress, size_t& moduleSize) {
if (process == NULL) {
return false;
}
auto hndl = GetModuleHandle(name);
if (hndl == NULL) {
return false;
}
MODULEINFO info;
if (!GetModuleInformation(process, hndl, &info, sizeof(info))) {
return false;
}
moduleSize = info.SizeOfImage;
baseAddress = info.lpBaseOfDll;
return true;
};
#endif
// Early map commonly used modules, it's okay if not all of them are here
// Everything else will be caught by "ToPseudoAddress" but you risk running out of ranges by then
const char* libs[] = { "engine", "server", "tier0", "vstdlib" };
char formattedName[64];
for (int i = 0; i < sizeof(libs) / sizeof(const char*); i++) {
bridge->FormatSourceBinaryName(libs[i], formattedName, sizeof(formattedName));
void* base_addr = nullptr;
size_t module_size = 0;
if (get_module_details(formattedName, base_addr, module_size)) {
// Create the mapping (hopefully)
m_dictionary.Make32bitAddress(base_addr, module_size);
}
}
}
void *PseudoAddressManager::FromPseudoAddress(uint32_t paddr)
{
#ifdef KE_ARCH_X64
uint8_t index = paddr >> PSEUDO_OFFSET_BITS;
uint32_t offset = paddr & ((1 << PSEUDO_OFFSET_BITS) - 1);
if (index >= m_NumEntries)
if (paddr == 0) {
return nullptr;
return reinterpret_cast<void *>(uintptr_t(m_AllocBases[index]) + offset);
#else
return nullptr;
#endif
}
return m_dictionary.RecoverAddress(paddr).value_or(nullptr);
}
uint32_t PseudoAddressManager::ToPseudoAddress(void *addr)
{
#ifdef KE_ARCH_X64
uint8_t index = 0;
uint32_t offset = 0;
bool hasEntry = false;
void *base = GetAllocationBase(addr);
if (base) {
for (int i = 0; i < m_NumEntries; i++) {
if (m_AllocBases[i] == base) {
index = i;
hasEntry = true;
break;
}
}
} else {
if (addr == nullptr) {
return 0;
}
if (!hasEntry) {
index = m_NumEntries;
if (m_NumEntries < SM_ARRAYSIZE(m_AllocBases))
m_AllocBases[m_NumEntries++] = base;
else
return 0; // Table is full
}
ptrdiff_t diff = uintptr_t(addr) - uintptr_t(base);
// Ensure difference fits in 26 bits
if (diff > (UINT32_MAX >> PSEUDO_INDEX_BITS))
return 0;
return (index << PSEUDO_OFFSET_BITS) | diff;
#else
return 0;
#endif
}
void *PseudoAddressManager::GetAllocationBase(void *ptr)
{
#if defined PLATFORM_WINDOWS
MEMORY_BASIC_INFORMATION info;
if (!VirtualQuery(ptr, &info, sizeof(MEMORY_BASIC_INFORMATION)))
return nullptr;
return info.AllocationBase;
#elif defined PLATFORM_APPLE
#ifdef KE_ARCH_X86
typedef vm_region_info_t mach_vm_region_info_t;
typedef vm_region_basic_info_data_t mach_vm_region_basic_info_data_t;
const vm_region_flavor_t MACH_VM_REGION_BASIC_INFO = VM_REGION_BASIC_INFO;
const mach_msg_type_number_t MACH_VM_REGION_BASIC_INFO_COUNT = VM_REGION_BASIC_INFO_COUNT;
#define mach_vm_region vm_region
#elif defined KE_ARCH_X64
typedef vm_region_info_64_t mach_vm_region_info_t ;
typedef vm_region_basic_info_data_64_t mach_vm_region_basic_info_data_t;
const vm_region_flavor_t MACH_VM_REGION_BASIC_INFO = VM_REGION_BASIC_INFO_64;
const mach_msg_type_number_t MACH_VM_REGION_BASIC_INFO_COUNT = VM_REGION_BASIC_INFO_COUNT_64;
#define mach_vm_region vm_region_64
#endif
vm_size_t size;
vm_address_t vmaddr = reinterpret_cast<vm_address_t>(ptr);
mach_vm_region_basic_info_data_t info;
memory_object_name_t obj;
vm_region_flavor_t flavor = MACH_VM_REGION_BASIC_INFO;
mach_msg_type_number_t count = MACH_VM_REGION_BASIC_INFO_COUNT;
kern_return_t kr = mach_vm_region(mach_task_self(), &vmaddr, &size, flavor,
reinterpret_cast<mach_vm_region_info_t>(&info),
&count, &obj);
if (kr != KERN_SUCCESS)
return nullptr;
return reinterpret_cast<void *>(vmaddr);
#elif defined PLATFORM_LINUX
uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
// Format:
// lower upper prot stuff path
// 08048000-0804c000 r-xp 00000000 03:03 1010107 /bin/cat
FILE *fp = fopen("/proc/self/maps", "r");
if (fp) {
uintptr_t lower, upper;
while (fscanf(fp, "%" PRIxPTR "-%" PRIxPTR, &lower, &upper) != EOF) {
if (addr >= lower && addr <= upper) {
fclose(fp);
return reinterpret_cast<void *>(lower);
}
// Read to end of line
int c;
while ((c = fgetc(fp)) != '\n') {
if (c == EOF)
break;
}
if (c == EOF)
break;
}
fclose(fp);
}
return nullptr;
#endif
return m_dictionary.Make32bitAddress(addr).value_or(0);
}

View File

@ -31,6 +31,7 @@
#define _INCLUDE_SOURCEMOD_PSEUDOADDRESSMANAGER_H_
#include "common_logic.h"
#include "libaddrz/addrz.h"
class PseudoAddressManager
{
@ -39,13 +40,9 @@ public:
public:
void *FromPseudoAddress(uint32_t paddr);
uint32_t ToPseudoAddress(void *addr);
void Initialize();
private:
void *GetAllocationBase(void *ptr);
private:
static constexpr uint8_t PSEUDO_OFFSET_BITS = 26;
static constexpr uint8_t PSEUDO_INDEX_BITS = sizeof(uint32_t) * 8 - PSEUDO_OFFSET_BITS;
void *m_AllocBases[1 << PSEUDO_INDEX_BITS];
uint8_t m_NumEntries;
am::AddressDict m_dictionary;
};
#endif // _INCLUDE_SOURCEMOD_PSEUDOADDRESSMANAGER_H_

View File

@ -57,6 +57,7 @@
#include "RootConsoleMenu.h"
#include "CellArray.h"
#include "smn_entitylump.h"
#include "PseudoAddrManager.h"
#include <bridge/include/BridgeAPI.h>
#include <bridge/include/IProviderCallbacks.h>
@ -86,9 +87,7 @@ IScriptManager *scripts = &g_PluginSys;
IExtensionSys *extsys = &g_Extensions;
ILogger *logger = &g_Logger;
CNativeOwner g_CoreNatives;
#ifdef KE_ARCH_X64
PseudoAddressManager pseudoAddr;
#endif
EntityLumpParseResult lastParseResult;
@ -122,20 +121,12 @@ static void RegisterProfiler(IProfilingTool *tool)
static void *FromPseudoAddress(uint32_t paddr)
{
#ifdef KE_ARCH_X64
return pseudoAddr.FromPseudoAddress(paddr);
#else
return nullptr;
#endif
}
static uint32_t ToPseudoAddress(void *addr)
{
#ifdef KE_ARCH_X64
return pseudoAddr.ToPseudoAddress(addr);
#else
return 0;
#endif
}
static void SetEntityLumpWritable(bool writable)
@ -236,6 +227,7 @@ static void logic_init(CoreProvider* core, sm_logic_t* _logic)
g_pSourcePawn2 = *core->spe2;
SMGlobalClass::head = core->listeners;
pseudoAddr.Initialize();
g_ShareSys.Initialize();
g_pCoreIdent = g_ShareSys.CreateCoreIdentity();

1
core/logic/libaddrz Submodule

@ -0,0 +1 @@
Subproject commit 661cd316e6ff8e8560efa20db1794f3fa479647c

View File

@ -59,6 +59,7 @@
#include <bridge/include/CoreProvider.h>
#include <bridge/include/IScriptManager.h>
#include <bridge/include/IExtensionBridge.h>
#include "PseudoAddrManager.h"
#include <sh_vector.h>
using namespace SourceMod;
@ -863,11 +864,10 @@ enum NumberType
static cell_t LoadFromAddress(IPluginContext *pContext, const cell_t *params)
{
#ifdef KE_ARCH_X86
void *addr = reinterpret_cast<void*>(params[1]);
#else
void *addr = pseudoAddr.FromPseudoAddress(params[1]);
#endif
if (pContext->GetRuntime()->FindPubvarByName("__Virtual_Address__", nullptr) != SP_ERROR_NONE) {
addr = pseudoAddr.FromPseudoAddress(params[1]);
}
if (addr == NULL)
{
@ -895,11 +895,10 @@ static cell_t LoadFromAddress(IPluginContext *pContext, const cell_t *params)
static cell_t StoreToAddress(IPluginContext *pContext, const cell_t *params)
{
#ifdef KE_ARCH_X86
void *addr = reinterpret_cast<void*>(params[1]);
#else
void *addr = pseudoAddr.FromPseudoAddress(params[1]);
#endif
if (pContext->GetRuntime()->FindPubvarByName("__Virtual_Address__", nullptr) != SP_ERROR_NONE) {
addr = pseudoAddr.FromPseudoAddress(params[1]);
}
if (addr == NULL)
{

View File

@ -724,11 +724,10 @@ static cell_t GetEntDataEnt2(IPluginContext *pContext, const cell_t *params)
static cell_t LoadEntityFromHandleAddress(IPluginContext *pContext, const cell_t *params)
{
#ifdef KE_ARCH_X86
void *addr = reinterpret_cast<void*>(params[1]);
#else
void *addr = g_SourceMod.FromPseudoAddress(params[1]);
#endif
if (pContext->GetRuntime()->FindPubvarByName("__Virtual_Address__", nullptr) != SP_ERROR_NONE) {
addr = g_SourceMod.FromPseudoAddress(params[1]);
}
if (addr == NULL)
{

View File

@ -376,7 +376,7 @@ ReturnAction_t HandleDetour(HookType_t hookType, CHook* pDetour)
{
// The this pointer is implicitly always the first argument.
void *thisPtr = pDetour->GetArgument<void *>(0);
cell_t thisAddr = GetThisPtr(thisPtr, pWrapper->thisType);
cell_t thisAddr = GetThisPtr(pCallback->GetParentContext(), thisPtr, pWrapper->thisType);
pCallback->PushCell(thisAddr);
}

View File

@ -122,7 +122,12 @@ cell_t Native_CreateHook(IPluginContext *pContext, const cell_t *params)
//native Handle:DHookCreateDetour(Address:funcaddr, CallingConvention:callConv, ReturnType:returntype, ThisPointerType:thistype);
cell_t Native_CreateDetour(IPluginContext *pContext, const cell_t *params)
{
HookSetup *setup = new HookSetup((ReturnType)params[3], PASSFLAG_BYVAL, (CallingConvention)params[2], (ThisPointerType)params[4], (void *)params[1]);
void* addr = reinterpret_cast<void*>(params[1]);
if (pContext->GetRuntime()->FindPubvarByName("__Virtual_Address__", nullptr) != SP_ERROR_NONE) {
addr = g_pSM->FromPseudoAddress(params[1]);
}
HookSetup *setup = new HookSetup((ReturnType)params[3], PASSFLAG_BYVAL, (CallingConvention)params[2], (ThisPointerType)params[4], addr);
Handle_t hndl = handlesys->CreateHandle(g_HookSetupHandle, setup, pContext->GetIdentity(), myself->GetIdentity(), NULL);
@ -589,7 +594,10 @@ cell_t HookRawImpl(IPluginContext *pContext, const cell_t *params, int callbackI
if (removalcbIndex > 0)
removalcb = pContext->GetFunctionById(params[removalcbIndex]);
void *iface = (void *)(params[3]);
void* iface = reinterpret_cast<void*>(params[3]);
if (pContext->GetRuntime()->FindPubvarByName("__Virtual_Address__", nullptr) != SP_ERROR_NONE) {
iface = g_pSM->FromPseudoAddress(params[3]);
}
for(int i = g_pHooks.size() -1; i >= 0; i--)
{
@ -1510,6 +1518,10 @@ cell_t Native_GetParamAddress(IPluginContext *pContext, const cell_t *params)
}
size_t offset = GetParamOffset(paramStruct, index);
if (pContext->GetRuntime()->FindPubvarByName("__Virtual_Address__", nullptr) != SP_ERROR_NONE) {
return g_pSM->ToPseudoAddress(*(void**)((intptr_t)paramStruct->orgParams + offset));
}
return *(cell_t *)((intptr_t)paramStruct->orgParams + offset);
}

View File

@ -465,19 +465,18 @@ HookReturnStruct *GetReturnStruct(DHooksCallback *dg)
return res;
}
cell_t GetThisPtr(void *iface, ThisPointerType type)
cell_t GetThisPtr(IPluginContext* pContext, void *iface, ThisPointerType type)
{
if(type == ThisPointer_CBaseEntity)
if (type == ThisPointer_CBaseEntity)
{
if (!iface)
return -1;
return gamehelpers->EntityToBCompatRef((CBaseEntity *)iface);
}
#ifdef KE_ARCH_X64
return g_pSM->ToPseudoAddress(iface);
#else
if (pContext->GetRuntime()->FindPubvarByName("__Virtual_Address__", nullptr) != SP_ERROR_NONE) {
return g_pSM->ToPseudoAddress(iface);
}
return (cell_t)iface;
#endif
}
#if defined( WIN32 ) && !defined( KE_ARCH_X64 )
@ -500,7 +499,7 @@ void *Callback(DHooksCallback *dg, void **argStack)
if(dg->thisType == ThisPointer_CBaseEntity || dg->thisType == ThisPointer_Address)
{
dg->plugin_callback->PushCell(GetThisPtr(g_SHPtr->GetIfacePtr(), dg->thisType));
dg->plugin_callback->PushCell(GetThisPtr(dg->plugin_callback->GetParentContext(), g_SHPtr->GetIfacePtr(), dg->thisType));
}
if(dg->returnType != ReturnType_Void)
{
@ -684,7 +683,7 @@ float Callback_float(DHooksCallback *dg, void **argStack)
if(dg->thisType == ThisPointer_CBaseEntity || dg->thisType == ThisPointer_Address)
{
dg->plugin_callback->PushCell(GetThisPtr(g_SHPtr->GetIfacePtr(), dg->thisType));
dg->plugin_callback->PushCell(GetThisPtr(dg->plugin_callback->GetParentContext(), g_SHPtr->GetIfacePtr(), dg->thisType));
}
returnStruct = GetReturnStruct(dg);
@ -841,7 +840,7 @@ SDKVector *Callback_vector(DHooksCallback *dg, void **argStack)
if(dg->thisType == ThisPointer_CBaseEntity || dg->thisType == ThisPointer_Address)
{
dg->plugin_callback->PushCell(GetThisPtr(g_SHPtr->GetIfacePtr(), dg->thisType));
dg->plugin_callback->PushCell(GetThisPtr(dg->plugin_callback->GetParentContext(), g_SHPtr->GetIfacePtr(), dg->thisType));
}
returnStruct = GetReturnStruct(dg);
@ -995,7 +994,7 @@ string_t *Callback_stringt(DHooksCallback *dg, void **argStack)
if(dg->thisType == ThisPointer_CBaseEntity || dg->thisType == ThisPointer_Address)
{
dg->plugin_callback->PushCell(GetThisPtr(g_SHPtr->GetIfacePtr(), dg->thisType));
dg->plugin_callback->PushCell(GetThisPtr(dg->plugin_callback->GetParentContext(), g_SHPtr->GetIfacePtr(), dg->thisType));
}
returnStruct = GetReturnStruct(dg);

View File

@ -338,7 +338,7 @@ public:
};
size_t GetStackArgsSize(DHooksCallback *dg);
cell_t GetThisPtr(void *iface, ThisPointerType type);
cell_t GetThisPtr(IPluginContext* pContext, void *iface, ThisPointerType type);
extern IBinTools *g_pBinTools;
extern HandleType_t g_HookParamsHandle;

View File

@ -172,11 +172,10 @@ static cell_t PrepSDKCall_SetSignature(IPluginContext *pContext, const cell_t *p
static cell_t PrepSDKCall_SetAddress(IPluginContext *pContext, const cell_t *params)
{
#ifdef KE_ARCH_X86
s_call_addr = reinterpret_cast<void *>(params[1]);
#else
s_call_addr = g_pSM->FromPseudoAddress(params[1]);
#endif
s_call_addr = reinterpret_cast<void*>(params[1]);
if (pContext->GetRuntime()->FindPubvarByName("__Virtual_Address__", nullptr) != SP_ERROR_NONE) {
s_call_addr = g_pSM->FromPseudoAddress(params[1]);
}
return (s_call_addr != NULL) ? 1 : 0;
}