Skip to content

Commit fa5d7ff

Browse files
KenzzerHeadline
authored andcommitted
Rebase for conflicts
1 parent 9b6e36f commit fa5d7ff

File tree

13 files changed

+103
-168
lines changed

13 files changed

+103
-168
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@
1212
[submodule "public/safetyhook"]
1313
path = public/safetyhook
1414
url = https://github.com/alliedmodders/safetyhook
15+
[submodule "core/logic/libaddrz"]
16+
path = core/logic/libaddrz
17+
url = https://github.com/dvander/libaddrz.git

core/logic/AMBuilder

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,15 @@ for cxx in builder.targets:
8686
'DatabaseConfBuilder.cpp',
8787
'LumpManager.cpp',
8888
'smn_entitylump.cpp',
89+
'libaddrz/addrz.cpp',
90+
'libaddrz/mapping.cpp',
91+
'libaddrz/platform.cpp',
92+
'libaddrz/proc_maps.cpp',
93+
'PseudoAddrManager.cpp',
8994
]
90-
91-
if binary.compiler.target.arch == 'x86_64':
92-
binary.sources += ['PseudoAddrManager.cpp']
95+
if binary.compiler.target.platform == 'linux':
96+
binary.sources += ['libaddrz/platform_linux.cpp']
97+
elif binary.compiler.target.platform == 'windows':
98+
binary.sources += ['libaddrz/platform_windows.cpp']
9399

94100
SM.binaries += [builder.Add(binary)]

core/logic/PseudoAddrManager.cpp

Lines changed: 46 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -28,142 +28,70 @@
2828
*/
2929

3030
#include "PseudoAddrManager.h"
31+
#include <bridge/include/CoreProvider.h>
3132
#ifdef PLATFORM_APPLE
3233
#include <mach/mach.h>
3334
#include <mach/vm_region.h>
3435
#endif
3536
#ifdef PLATFORM_LINUX
3637
#include <inttypes.h>
3738
#endif
39+
#ifdef PLATFORM_WINDOWS
40+
#include <Psapi.h>
41+
#endif
3842

39-
PseudoAddressManager::PseudoAddressManager() : m_NumEntries(0)
43+
PseudoAddressManager::PseudoAddressManager() : m_dictionary(am::IPlatform::GetDefault())
4044
{
4145
}
4246

43-
// A pseudo address consists of a table index in the upper 6 bits and an offset in the
44-
// lower 26 bits. The table consists of memory allocation base addresses.
45-
void *PseudoAddressManager::FromPseudoAddress(uint32_t paddr)
46-
{
47-
#ifdef KE_ARCH_X64
48-
uint8_t index = paddr >> PSEUDO_OFFSET_BITS;
49-
uint32_t offset = paddr & ((1 << PSEUDO_OFFSET_BITS) - 1);
50-
51-
if (index >= m_NumEntries)
52-
return nullptr;
53-
54-
return reinterpret_cast<void *>(uintptr_t(m_AllocBases[index]) + offset);
55-
#else
56-
return nullptr;
47+
void PseudoAddressManager::Initialize() {
48+
#ifdef PLATFORM_WINDOWS
49+
auto process = GetCurrentProcess();
50+
auto get_module_details = [process](const char* name, void*& baseAddress, size_t& moduleSize) {
51+
if (process == NULL) {
52+
return false;
53+
}
54+
auto hndl = GetModuleHandle(name);
55+
if (hndl == NULL) {
56+
return false;
57+
}
58+
MODULEINFO info;
59+
if (!GetModuleInformation(process, hndl, &info, sizeof(info))) {
60+
return false;
61+
}
62+
moduleSize = info.SizeOfImage;
63+
baseAddress = info.lpBaseOfDll;
64+
return true;
65+
};
5766
#endif
58-
}
59-
60-
uint32_t PseudoAddressManager::ToPseudoAddress(void *addr)
61-
{
62-
#ifdef KE_ARCH_X64
63-
uint8_t index = 0;
64-
uint32_t offset = 0;
65-
bool hasEntry = false;
66-
void *base = GetAllocationBase(addr);
67-
68-
if (base) {
69-
for (int i = 0; i < m_NumEntries; i++) {
70-
if (m_AllocBases[i] == base) {
71-
index = i;
72-
hasEntry = true;
73-
break;
74-
}
67+
// Early map commonly used modules, it's okay if not all of them are here
68+
// Everything else will be caught by "ToPseudoAddress" but you risk running out of ranges by then
69+
const char* libs[] = { "engine", "server", "tier0", "vstdlib" };
70+
71+
char formattedName[64];
72+
for (int i = 0; i < sizeof(libs) / sizeof(const char*); i++) {
73+
bridge->FormatSourceBinaryName(libs[i], formattedName, sizeof(formattedName));
74+
void* base_addr = nullptr;
75+
size_t module_size = 0;
76+
if (get_module_details(formattedName, base_addr, module_size)) {
77+
// Create the mapping (hopefully)
78+
m_dictionary.Make32bitAddress(base_addr, module_size);
7579
}
76-
} else {
77-
return 0;
7880
}
79-
80-
if (!hasEntry) {
81-
index = m_NumEntries;
82-
if (m_NumEntries < SM_ARRAYSIZE(m_AllocBases))
83-
m_AllocBases[m_NumEntries++] = base;
84-
else
85-
return 0; // Table is full
86-
}
87-
88-
ptrdiff_t diff = uintptr_t(addr) - uintptr_t(base);
89-
90-
// Ensure difference fits in 26 bits
91-
if (diff > (UINT32_MAX >> PSEUDO_INDEX_BITS))
92-
return 0;
93-
94-
return (index << PSEUDO_OFFSET_BITS) | diff;
95-
#else
96-
return 0;
97-
#endif
9881
}
9982

100-
void *PseudoAddressManager::GetAllocationBase(void *ptr)
83+
void *PseudoAddressManager::FromPseudoAddress(uint32_t paddr)
10184
{
102-
#if defined PLATFORM_WINDOWS
103-
104-
MEMORY_BASIC_INFORMATION info;
105-
if (!VirtualQuery(ptr, &info, sizeof(MEMORY_BASIC_INFORMATION)))
106-
return nullptr;
107-
return info.AllocationBase;
108-
109-
#elif defined PLATFORM_APPLE
110-
111-
#ifdef KE_ARCH_X86
112-
typedef vm_region_info_t mach_vm_region_info_t;
113-
typedef vm_region_basic_info_data_t mach_vm_region_basic_info_data_t;
114-
const vm_region_flavor_t MACH_VM_REGION_BASIC_INFO = VM_REGION_BASIC_INFO;
115-
const mach_msg_type_number_t MACH_VM_REGION_BASIC_INFO_COUNT = VM_REGION_BASIC_INFO_COUNT;
116-
#define mach_vm_region vm_region
117-
#elif defined KE_ARCH_X64
118-
typedef vm_region_info_64_t mach_vm_region_info_t ;
119-
typedef vm_region_basic_info_data_64_t mach_vm_region_basic_info_data_t;
120-
const vm_region_flavor_t MACH_VM_REGION_BASIC_INFO = VM_REGION_BASIC_INFO_64;
121-
const mach_msg_type_number_t MACH_VM_REGION_BASIC_INFO_COUNT = VM_REGION_BASIC_INFO_COUNT_64;
122-
#define mach_vm_region vm_region_64
123-
#endif
124-
vm_size_t size;
125-
vm_address_t vmaddr = reinterpret_cast<vm_address_t>(ptr);
126-
mach_vm_region_basic_info_data_t info;
127-
memory_object_name_t obj;
128-
vm_region_flavor_t flavor = MACH_VM_REGION_BASIC_INFO;
129-
mach_msg_type_number_t count = MACH_VM_REGION_BASIC_INFO_COUNT;
130-
131-
kern_return_t kr = mach_vm_region(mach_task_self(), &vmaddr, &size, flavor,
132-
reinterpret_cast<mach_vm_region_info_t>(&info),
133-
&count, &obj);
134-
135-
if (kr != KERN_SUCCESS)
85+
if (paddr == 0) {
13686
return nullptr;
87+
}
88+
return m_dictionary.RecoverAddress(paddr).value_or(nullptr);
89+
}
13790

138-
return reinterpret_cast<void *>(vmaddr);
139-
140-
#elif defined PLATFORM_LINUX
141-
142-
uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
143-
144-
// Format:
145-
// lower upper prot stuff path
146-
// 08048000-0804c000 r-xp 00000000 03:03 1010107 /bin/cat
147-
FILE *fp = fopen("/proc/self/maps", "r");
148-
if (fp) {
149-
uintptr_t lower, upper;
150-
while (fscanf(fp, "%" PRIxPTR "-%" PRIxPTR, &lower, &upper) != EOF) {
151-
if (addr >= lower && addr <= upper) {
152-
fclose(fp);
153-
return reinterpret_cast<void *>(lower);
154-
}
155-
156-
// Read to end of line
157-
int c;
158-
while ((c = fgetc(fp)) != '\n') {
159-
if (c == EOF)
160-
break;
161-
}
162-
if (c == EOF)
163-
break;
164-
}
165-
fclose(fp);
91+
uint32_t PseudoAddressManager::ToPseudoAddress(void *addr)
92+
{
93+
if (addr == nullptr) {
94+
return 0;
16695
}
167-
return nullptr;
168-
#endif
96+
return m_dictionary.Make32bitAddress(addr).value_or(0);
16997
}

core/logic/PseudoAddrManager.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#define _INCLUDE_SOURCEMOD_PSEUDOADDRESSMANAGER_H_
3232

3333
#include "common_logic.h"
34+
#include "libaddrz/addrz.h"
3435

3536
class PseudoAddressManager
3637
{
@@ -39,13 +40,9 @@ class PseudoAddressManager
3940
public:
4041
void *FromPseudoAddress(uint32_t paddr);
4142
uint32_t ToPseudoAddress(void *addr);
43+
void Initialize();
4244
private:
43-
void *GetAllocationBase(void *ptr);
44-
private:
45-
static constexpr uint8_t PSEUDO_OFFSET_BITS = 26;
46-
static constexpr uint8_t PSEUDO_INDEX_BITS = sizeof(uint32_t) * 8 - PSEUDO_OFFSET_BITS;
47-
void *m_AllocBases[1 << PSEUDO_INDEX_BITS];
48-
uint8_t m_NumEntries;
45+
am::AddressDict m_dictionary;
4946
};
5047

5148
#endif // _INCLUDE_SOURCEMOD_PSEUDOADDRESSMANAGER_H_

core/logic/common_logic.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#include "RootConsoleMenu.h"
5858
#include "CellArray.h"
5959
#include "smn_entitylump.h"
60+
#include "PseudoAddrManager.h"
6061
#include <bridge/include/BridgeAPI.h>
6162
#include <bridge/include/IProviderCallbacks.h>
6263

@@ -86,9 +87,7 @@ IScriptManager *scripts = &g_PluginSys;
8687
IExtensionSys *extsys = &g_Extensions;
8788
ILogger *logger = &g_Logger;
8889
CNativeOwner g_CoreNatives;
89-
#ifdef KE_ARCH_X64
9090
PseudoAddressManager pseudoAddr;
91-
#endif
9291

9392
EntityLumpParseResult lastParseResult;
9493

@@ -122,20 +121,12 @@ static void RegisterProfiler(IProfilingTool *tool)
122121

123122
static void *FromPseudoAddress(uint32_t paddr)
124123
{
125-
#ifdef KE_ARCH_X64
126124
return pseudoAddr.FromPseudoAddress(paddr);
127-
#else
128-
return nullptr;
129-
#endif
130125
}
131126

132127
static uint32_t ToPseudoAddress(void *addr)
133128
{
134-
#ifdef KE_ARCH_X64
135129
return pseudoAddr.ToPseudoAddress(addr);
136-
#else
137-
return 0;
138-
#endif
139130
}
140131

141132
static void SetEntityLumpWritable(bool writable)
@@ -236,6 +227,7 @@ static void logic_init(CoreProvider* core, sm_logic_t* _logic)
236227
g_pSourcePawn2 = *core->spe2;
237228
SMGlobalClass::head = core->listeners;
238229

230+
pseudoAddr.Initialize();
239231
g_ShareSys.Initialize();
240232
g_pCoreIdent = g_ShareSys.CreateCoreIdentity();
241233

core/logic/libaddrz

Submodule libaddrz added at 661cd31

core/logic/smn_core.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#include <bridge/include/CoreProvider.h>
6060
#include <bridge/include/IScriptManager.h>
6161
#include <bridge/include/IExtensionBridge.h>
62+
#include "PseudoAddrManager.h"
6263
#include <sh_vector.h>
6364

6465
using namespace SourceMod;
@@ -863,11 +864,10 @@ enum NumberType
863864

864865
static cell_t LoadFromAddress(IPluginContext *pContext, const cell_t *params)
865866
{
866-
#ifdef KE_ARCH_X86
867867
void *addr = reinterpret_cast<void*>(params[1]);
868-
#else
869-
void *addr = pseudoAddr.FromPseudoAddress(params[1]);
870-
#endif
868+
if (pContext->GetRuntime()->FindPubvarByName("__Virtual_Address__", nullptr) != SP_ERROR_NONE) {
869+
addr = pseudoAddr.FromPseudoAddress(params[1]);
870+
}
871871

872872
if (addr == NULL)
873873
{
@@ -895,11 +895,10 @@ static cell_t LoadFromAddress(IPluginContext *pContext, const cell_t *params)
895895

896896
static cell_t StoreToAddress(IPluginContext *pContext, const cell_t *params)
897897
{
898-
#ifdef KE_ARCH_X86
899898
void *addr = reinterpret_cast<void*>(params[1]);
900-
#else
901-
void *addr = pseudoAddr.FromPseudoAddress(params[1]);
902-
#endif
899+
if (pContext->GetRuntime()->FindPubvarByName("__Virtual_Address__", nullptr) != SP_ERROR_NONE) {
900+
addr = pseudoAddr.FromPseudoAddress(params[1]);
901+
}
903902

904903
if (addr == NULL)
905904
{

core/smn_entities.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -724,11 +724,10 @@ static cell_t GetEntDataEnt2(IPluginContext *pContext, const cell_t *params)
724724

725725
static cell_t LoadEntityFromHandleAddress(IPluginContext *pContext, const cell_t *params)
726726
{
727-
#ifdef KE_ARCH_X86
728727
void *addr = reinterpret_cast<void*>(params[1]);
729-
#else
730-
void *addr = g_SourceMod.FromPseudoAddress(params[1]);
731-
#endif
728+
if (pContext->GetRuntime()->FindPubvarByName("__Virtual_Address__", nullptr) != SP_ERROR_NONE) {
729+
addr = g_SourceMod.FromPseudoAddress(params[1]);
730+
}
732731

733732
if (addr == NULL)
734733
{

extensions/dhooks/dynhooks_sourcepawn.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ ReturnAction_t HandleDetour(HookType_t hookType, CHook* pDetour)
376376
{
377377
// The this pointer is implicitly always the first argument.
378378
void *thisPtr = pDetour->GetArgument<void *>(0);
379-
cell_t thisAddr = GetThisPtr(thisPtr, pWrapper->thisType);
379+
cell_t thisAddr = GetThisPtr(pCallback->GetParentContext(), thisPtr, pWrapper->thisType);
380380
pCallback->PushCell(thisAddr);
381381
}
382382

extensions/dhooks/natives.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,12 @@ cell_t Native_CreateHook(IPluginContext *pContext, const cell_t *params)
122122
//native Handle:DHookCreateDetour(Address:funcaddr, CallingConvention:callConv, ReturnType:returntype, ThisPointerType:thistype);
123123
cell_t Native_CreateDetour(IPluginContext *pContext, const cell_t *params)
124124
{
125-
HookSetup *setup = new HookSetup((ReturnType)params[3], PASSFLAG_BYVAL, (CallingConvention)params[2], (ThisPointerType)params[4], (void *)params[1]);
125+
void* addr = reinterpret_cast<void*>(params[1]);
126+
if (pContext->GetRuntime()->FindPubvarByName("__Virtual_Address__", nullptr) != SP_ERROR_NONE) {
127+
addr = g_pSM->FromPseudoAddress(params[1]);
128+
}
129+
130+
HookSetup *setup = new HookSetup((ReturnType)params[3], PASSFLAG_BYVAL, (CallingConvention)params[2], (ThisPointerType)params[4], addr);
126131

127132
Handle_t hndl = handlesys->CreateHandle(g_HookSetupHandle, setup, pContext->GetIdentity(), myself->GetIdentity(), NULL);
128133

@@ -589,7 +594,10 @@ cell_t HookRawImpl(IPluginContext *pContext, const cell_t *params, int callbackI
589594
if (removalcbIndex > 0)
590595
removalcb = pContext->GetFunctionById(params[removalcbIndex]);
591596

592-
void *iface = (void *)(params[3]);
597+
void* iface = reinterpret_cast<void*>(params[3]);
598+
if (pContext->GetRuntime()->FindPubvarByName("__Virtual_Address__", nullptr) != SP_ERROR_NONE) {
599+
iface = g_pSM->FromPseudoAddress(params[3]);
600+
}
593601

594602
for(int i = g_pHooks.size() -1; i >= 0; i--)
595603
{
@@ -1510,6 +1518,10 @@ cell_t Native_GetParamAddress(IPluginContext *pContext, const cell_t *params)
15101518
}
15111519

15121520
size_t offset = GetParamOffset(paramStruct, index);
1521+
1522+
if (pContext->GetRuntime()->FindPubvarByName("__Virtual_Address__", nullptr) != SP_ERROR_NONE) {
1523+
return g_pSM->ToPseudoAddress(*(void**)((intptr_t)paramStruct->orgParams + offset));
1524+
}
15131525
return *(cell_t *)((intptr_t)paramStruct->orgParams + offset);
15141526
}
15151527

0 commit comments

Comments
 (0)