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

Add new address natives #2112

Closed
wants to merge 4 commits into from
Closed
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
84 changes: 80 additions & 4 deletions core/logic/smn_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -863,10 +863,17 @@ enum NumberType

static cell_t LoadFromAddress(IPluginContext *pContext, const cell_t *params)
{
// new parameter added after SM 1.12; defaults to 0 for backwards compatibility
cell_t offset = 0;
if (params[0] >= 3)
{
offset = params[3];
}

#ifdef PLATFORM_X86
void *addr = reinterpret_cast<void*>(params[1]);
void *addr = reinterpret_cast<void*>(reinterpret_cast<int8_t*>(params[1]) + offset);
#else
void *addr = pseudoAddr.FromPseudoAddress(params[1]);
void *addr = reinterpret_cast<void*>(reinterpret_cast<int8_t*>(pseudoAddr.FromPseudoAddress(params[1])) + offset);
#endif

if (addr == NULL)
Expand Down Expand Up @@ -895,10 +902,17 @@ static cell_t LoadFromAddress(IPluginContext *pContext, const cell_t *params)

static cell_t StoreToAddress(IPluginContext *pContext, const cell_t *params)
{
// new parameter added after SM 1.12; defaults to 0 for backwards compatibility
cell_t offset = 0;
if (params[0] >= 5)
{
offset = params[5];
}

#ifdef PLATFORM_X86
void *addr = reinterpret_cast<void*>(params[1]);
void *addr = reinterpret_cast<void*>(reinterpret_cast<int8_t*>(params[1]) + offset);
#else
void *addr = pseudoAddr.FromPseudoAddress(params[1]);
void *addr = reinterpret_cast<void*>(reinterpret_cast<int8_t*>(pseudoAddr.FromPseudoAddress(params[1])) + offset);
#endif

if (addr == NULL)
Expand Down Expand Up @@ -950,6 +964,66 @@ static cell_t StoreToAddress(IPluginContext *pContext, const cell_t *params)
return 0;
}

static cell_t LoadAddressFromAddress(IPluginContext *pContext, const cell_t *params)
{
cell_t offset = params[2];

#ifdef PLATFORM_X86
void **addr = reinterpret_cast<void**>(reinterpret_cast<int8_t*>(params[1]) + offset);
#else
void **addr = reinterpret_cast<void**>(reinterpret_cast<int8_t*>(pseudoAddr.FromPseudoAddress(params[1])) + offset);
#endif

if (addr == NULL)
{
return pContext->ThrowNativeError("Address cannot be null");
}
else if (reinterpret_cast<uintptr_t>(addr) < VALID_MINIMUM_MEMORY_ADDRESS)
{
return pContext->ThrowNativeError("Invalid address 0x%x is pointing to reserved memory.", addr);
}

#ifdef PLATFORM_X86
return reinterpret_cast<cell_t>(*addr);
#else
return pseudoAddr.ToPseudoAddress(*addr);
#endif
}

static cell_t StoreAddressToAddress(IPluginContext *pContext, const cell_t *params)
{
cell_t offset = params[4];

#ifdef PLATFORM_X86
void **addr = reinterpret_cast<void**>(reinterpret_cast<int8_t*>(params[1]) + offset);
#else
void **addr = reinterpret_cast<void**>(reinterpret_cast<int8_t*>(pseudoAddr.FromPseudoAddress(params[1])) + offset);
#endif

if (addr == NULL)
{
return pContext->ThrowNativeError("Address cannot be null");
}
else if (reinterpret_cast<uintptr_t>(addr) < VALID_MINIMUM_MEMORY_ADDRESS)
{
return pContext->ThrowNativeError("Invalid address 0x%x is pointing to reserved memory.", addr);
}

#ifdef PLATFORM_X86
void *store = reinterpret_cast<void*>(params[2]);
#else
void *store = pseudoAddr.FromPseudoAddress(params[2]);
#endif

if (params[3])
{
SourceHook::SetMemAccess(addr, sizeof(addr), SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC);
}

*addr = store;
return 0;
}

static cell_t IsNullVector(IPluginContext *pContext, const cell_t *params)
{
cell_t *pNullVec = pContext->GetNullRef(SP_NULL_VECTOR);
Expand Down Expand Up @@ -1157,6 +1231,8 @@ REGISTER_NATIVES(coreNatives)
{"RequireFeature", RequireFeature},
{"LoadFromAddress", LoadFromAddress},
{"StoreToAddress", StoreToAddress},
{"LoadAddressFromAddress", LoadAddressFromAddress},
{"StoreAddressToAddress", StoreAddressToAddress},
{"IsNullVector", IsNullVector},
{"IsNullString", IsNullString},
{"LogStackTrace", LogStackTrace},
Expand Down
28 changes: 26 additions & 2 deletions plugins/include/sourcemod.inc
Original file line number Diff line number Diff line change
Expand Up @@ -736,10 +736,11 @@ enum Address
* @param addr Address to a memory location.
* @param size How many bytes should be read.
* If loading a floating-point value, use NumberType_Int32.
* @param offset Amount of bytes the base address needs to be offsetted by before loading.
* @return The value that is stored at that address.
* @error Address is null or pointing to reserved memory.
*/
native any LoadFromAddress(Address addr, NumberType size);
native any LoadFromAddress(Address addr, NumberType size, int offset = 0);

/**
* Store up to 4 bytes to a memory address.
Expand All @@ -750,9 +751,32 @@ native any LoadFromAddress(Address addr, NumberType size);
* If storing a floating-point value, use NumberType_Int32.
* @param updateMemAccess If true, SourceMod will set read / write / exec permissions
* on the memory page being written to.
* @param offset Amount of bytes the base address needs to be offsetted by before storing.
* @error Address is null or pointing to reserved memory.
*/
native void StoreToAddress(Address addr, any data, NumberType size, bool updateMemAccess = true);
native void StoreToAddress(Address addr, any data, NumberType size, bool updateMemAccess = true, int offset = 0);

/**
* Load an address value from a memory address.
*
* @param addr Address to a memory location.
* @param offset Amount of bytes the base address needs to be offsetted by before loading.
* @return The address value that is stored at that address.
* @error Address is null or pointing to reserved memory.
*/
native Address LoadAddressFromAddress(Address addr, int offset = 0);

/**
* Store an address value to the given address.
*
* @param addr Address to a memory location.
* @param data Address value to store at the address.
* @param updateMemAccess If true, SourceMod will set read / write / exec permissions
* on the memory page being written to.
* @param offset Amount of bytes the base address needs to be offsetted by before storing.
* @error Address is null or pointing to reserved memory.
*/
native void StoreAddressToAddress(Address addr, Address data, bool updateMemAccess = true, int offset = 0);

methodmap FrameIterator < Handle {
// Creates a stack frame iterator to build your own stack traces.
Expand Down
Loading