Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup enum-struct address #2213

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions core/logic/smn_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -863,11 +863,22 @@ enum NumberType

static cell_t LoadFromAddress(IPluginContext *pContext, const cell_t *params)
{
void* addr = nullptr;
if (g_pSM->IsUsingPluginAddress(pContext))
{
if (!g_pSM->FromPluginAddress(pContext, params[1], &addr))
{
return pContext->ThrowNativeError("Failed to read Address!");
}
}
else
{
#ifdef PLATFORM_X86
void *addr = reinterpret_cast<void*>(params[1]);
addr = reinterpret_cast<void*>(params[1]);
#else
void *addr = pseudoAddr.FromPseudoAddress(params[1]);
addr = pseudoAddr.FromPseudoAddress(params[1]);
#endif
}

if (addr == NULL)
{
Expand Down Expand Up @@ -895,11 +906,22 @@ static cell_t LoadFromAddress(IPluginContext *pContext, const cell_t *params)

static cell_t StoreToAddress(IPluginContext *pContext, const cell_t *params)
{
void* addr = nullptr;
if (g_pSM->IsUsingPluginAddress(pContext))
{
if (!g_pSM->FromPluginAddress(pContext, params[1], &addr))
{
return pContext->ThrowNativeError("Failed to read Address!");
}
}
else
{
#ifdef PLATFORM_X86
void *addr = reinterpret_cast<void*>(params[1]);
addr = reinterpret_cast<void*>(params[1]);
#else
void *addr = pseudoAddr.FromPseudoAddress(params[1]);
addr = pseudoAddr.FromPseudoAddress(params[1]);
#endif
}

if (addr == NULL)
{
Expand Down
53 changes: 45 additions & 8 deletions core/logic/smn_gameconfigs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
* Version: $Id$
*/

#include <ISourceMod.h>
#include "common_logic.h"
#include <IHandleSys.h>
#include "GameConfigs.h"
Expand Down Expand Up @@ -134,7 +135,13 @@ static cell_t smn_GameConfGetKeyValue(IPluginContext *pCtx, const cell_t *params

static cell_t smn_GameConfGetAddress(IPluginContext *pCtx, const cell_t *params)
{
Handle_t hndl = static_cast<Handle_t>(params[1]);
int startparam = 1;
if (g_pSM->IsUsingPluginAddress(pCtx))
{
startparam++;
}

Handle_t hndl = static_cast<Handle_t>(params[startparam]);
HandleError herr;
HandleSecurity sec;
IGameConfig *gc;
Expand All @@ -150,21 +157,39 @@ static cell_t smn_GameConfGetAddress(IPluginContext *pCtx, const cell_t *params)

char *key;
void* val;
pCtx->LocalToString(params[2], &key);
pCtx->LocalToString(params[startparam], &key);

if (!gc->GetAddress(key, &val))
return 0;

// BCompat Address
if (startparam == 1)
{
#ifdef PLATFORM_X86
return (cell_t)val;
return (cell_t)val;
#else
return pseudoAddr.ToPseudoAddress(val);
return pseudoAddr.ToPseudoAddress(val);
#endif
}
else
{
if (!g_pSM->ToPluginAddress(pCtx, params[1], val))
{
return pCtx->ThrowNativeError("Failed to return Address!");
}
return 0;
}
}

static cell_t smn_GameConfGetMemSig(IPluginContext *pCtx, const cell_t *params)
{
Handle_t hndl = static_cast<Handle_t>(params[1]);
int startparam = 1;
if (g_pSM->IsUsingPluginAddress(pCtx))
{
startparam++;
}

Handle_t hndl = static_cast<Handle_t>(params[startparam]);
HandleError herr;
HandleSecurity sec;
IGameConfig *gc;
Expand All @@ -180,18 +205,30 @@ static cell_t smn_GameConfGetMemSig(IPluginContext *pCtx, const cell_t *params)

char *key;
void *val;
pCtx->LocalToString(params[2], &key);
pCtx->LocalToString(params[startparam + 1], &key);

if (!gc->GetMemSig(key, &val))
{
return 0;
}

// BCompat Address
if (startparam == 1)
{
#ifdef PLATFORM_X86
return (cell_t)val;
return (cell_t)val;
#else
return pseudoAddr.ToPseudoAddress(val);
return pseudoAddr.ToPseudoAddress(val);
#endif
}
else
{
if (!g_pSM->ToPluginAddress(pCtx, params[1], val))
{
return pCtx->ThrowNativeError("Failed to return Address!");
}
return 0;
}
}

static GameConfigsNatives s_GameConfigsNatives;
Expand Down
30 changes: 26 additions & 4 deletions core/smn_entities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -724,11 +724,22 @@ static cell_t GetEntDataEnt2(IPluginContext *pContext, const cell_t *params)

static cell_t LoadEntityFromHandleAddress(IPluginContext *pContext, const cell_t *params)
{
void* addr = nullptr;
if (g_SourceMod.IsUsingPluginAddress(pContext))
{
if (!g_SourceMod.FromPluginAddress(pContext, params[1], &addr))
{
return pContext->ThrowNativeError("Failed to read Address!");
}
}
else
{
#ifdef PLATFORM_X86
void *addr = reinterpret_cast<void*>(params[1]);
addr = reinterpret_cast<void*>(params[1]);
#else
void *addr = g_SourceMod.FromPseudoAddress(params[1]);
addr = pseudoAddr.FromPseudoAddress(params[1]);
#endif
}

if (addr == NULL)
{
Expand Down Expand Up @@ -835,11 +846,22 @@ static cell_t SetEntDataEnt2(IPluginContext *pContext, const cell_t *params)

static cell_t StoreEntityToHandleAddress(IPluginContext *pContext, const cell_t *params)
{
void* addr = nullptr;
if (g_SourceMod.IsUsingPluginAddress(pContext))
{
if (!g_SourceMod.FromPluginAddress(pContext, params[1], &addr))
{
return pContext->ThrowNativeError("Failed to read Address!");
}
}
else
{
#ifdef PLATFORM_X86
void *addr = reinterpret_cast<void*>(params[1]);
addr = reinterpret_cast<void*>(params[1]);
#else
void *addr = g_SourceMod.FromPseudoAddress(params[1]);
addr = pseudoAddr.FromPseudoAddress(params[1]);
#endif
}

if (addr == NULL)
{
Expand Down
118 changes: 118 additions & 0 deletions core/sourcemod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,124 @@ uint32_t SourceModBase::ToPseudoAddress(void *addr)
return logicore.ToPseudoAddress(addr);
}

bool SourceModBase::IsUsingPluginAddress(IPluginContext* context)
{
return context->GetRuntime()->FindPubvarByName("Address_Null", nullptr) == SP_ERROR_NONE;
}

#pragma pack(push, 1)
struct SMAddress {
cell_t bits[8];

inline void* get_ptr() const {
std::int64_t ptr = 0x0;

if (sizeof(void*) >= 8) {
ptr |= (((std::int64_t)bits[1]) << 32);
}
ptr |= ((std::int32_t)bits[0]);

return reinterpret_cast<void*>(ptr);
}

inline void set_ptr(void* ptr) {
if (ptr == nullptr) {
for (int i = 0; i < sizeof(bits) / sizeof(cell_t); i++) {
bits[i] = 0x0;
}
}

std::int64_t store = 0x0;
store = reinterpret_cast<std::intptr_t>(ptr);

if (sizeof(void*) >= 8) {
bits[1] = static_cast<std::int32_t>(store >> 32);
}
bits[0] = static_cast<std::int32_t>(store);
}
};
#pragma pack(pop)

bool SourceModBase::ToPluginAddress(IPluginContext* context, cell_t reference, void* addr)
{
// Enum struct Address active ?
uint32_t index;
auto runtime = context->GetRuntime();
if (runtime->FindPubvarByName("Address_Null", &index) == SP_ERROR_NONE) {
return false;
}

// Shouldn't happen
cell_t null_addr_addr;
if (runtime->GetPubvarAddrs(index, &null_addr_addr, nullptr) == SP_ERROR_NONE) {
return false;
}

// Local address match, it's null address
// Do nothing...
if (null_addr_addr == reference) {
return true;
}

SMAddress to;
context->LocalToPhysAddr(reference, reinterpret_cast<cell_t**>(&to));
to.set_ptr(addr);
return true;
}

bool SourceModBase::FromPluginAddress(IPluginContext* context, cell_t reference, void** addr)
{
// Enum struct Address active ?
uint32_t index;
auto runtime = context->GetRuntime();
if (runtime->FindPubvarByName("Address_Null", &index) == SP_ERROR_NONE) {
return false;
}

// Shouldn't happen
cell_t null_addr_addr;
if (runtime->GetPubvarAddrs(index, &null_addr_addr, nullptr) == SP_ERROR_NONE) {
return false;
}

// Local address match, it's null address
if (null_addr_addr == reference) {
*addr = nullptr;
return true;
}

SMAddress from;
context->LocalToPhysAddr(reference, reinterpret_cast<cell_t**>(&from));
*addr = from.get_ptr();
return true;
}

bool SourceModBase::PushPluginAddress(IPluginFunction* function, void* addr, int flags)
{
// Enum struct Address active ?
uint32_t index;
auto runtime = function->GetParentRuntime();
if (runtime->FindPubvarByName("Address_Null", &index) != SP_ERROR_NONE) {
return false;
}

// Shouldn't happen
cell_t null_addr_addr;
if (runtime->GetPubvarAddrs(index, &null_addr_addr, nullptr) != SP_ERROR_NONE) {
return false;
}

if (addr == nullptr) {
function->PushCell(null_addr_addr);
} else {
SMAddress sp_addr;
sp_addr.set_ptr(addr);

function->PushArray(sp_addr.bits, sizeof(sp_addr.bits) / sizeof(cell_t));
}
return true;
}

class ConVarRegistrar :
public IConCommandBaseAccessor,
public SMGlobalClass
Expand Down
4 changes: 4 additions & 0 deletions core/sourcemod.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ class SourceModBase :
bool IsMapRunning();
void *FromPseudoAddress(uint32_t pseudoAddr);
uint32_t ToPseudoAddress(void *addr);
virtual bool IsUsingPluginAddress(IPluginContext* context) override;
virtual bool ToPluginAddress(IPluginContext* context, cell_t reference, void* addr) override;
virtual bool FromPluginAddress(IPluginContext* context, cell_t reference, void** addr) override;
virtual bool PushPluginAddress(IPluginFunction* function, void* addr, int flags = 0) override;
private:
void ShutdownServices();
private:
Expand Down
3 changes: 1 addition & 2 deletions extensions/dhooks/dynhooks_sourcepawn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +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);
pCallback->PushCell(thisAddr);
PushThisPtr(pCallback, thisPtr, pWrapper->thisType);
}

// Create the structure for plugins to change/get the return value if the function returns something.
Expand Down
Loading