From c37751ca672c4842bf12719055c4d2d6a5971db8 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Mon, 5 Feb 2024 17:04:16 +0100 Subject: [PATCH 1/4] Add new address natives --- core/logic/smn_core.cpp | 176 +++++++++++++++++++++++++++++++++- plugins/include/sourcemod.inc | 61 +++++++++++- 2 files changed, 231 insertions(+), 6 deletions(-) diff --git a/core/logic/smn_core.cpp b/core/logic/smn_core.cpp index 8e90d40310..8dbc3d15f8 100644 --- a/core/logic/smn_core.cpp +++ b/core/logic/smn_core.cpp @@ -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(params[1]); + void *addr = reinterpret_cast(reinterpret_cast(params[1]) + offset); #else - void *addr = pseudoAddr.FromPseudoAddress(params[1]); + void *addr = reinterpret_cast(reinterpret_cast(pseudoAddr.FromPseudoAddress(params[1])) + offset); #endif if (addr == NULL) @@ -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(params[1]); + void *addr = reinterpret_cast(reinterpret_cast(params[1]) + offset); #else - void *addr = pseudoAddr.FromPseudoAddress(params[1]); + void *addr = reinterpret_cast(reinterpret_cast(pseudoAddr.FromPseudoAddress(params[1])) + offset); #endif if (addr == NULL) @@ -950,6 +964,155 @@ 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(reinterpret_cast(params[1]) + offset); +#else + void **addr = reinterpret_cast(reinterpret_cast(pseudoAddr.FromPseudoAddress(params[1])) + offset); +#endif + + if (addr == NULL) + { + return pContext->ThrowNativeError("Address cannot be null"); + } + else if (reinterpret_cast(addr) < VALID_MINIMUM_MEMORY_ADDRESS) + { + return pContext->ThrowNativeError("Invalid address 0x%x is pointing to reserved memory.", addr); + } + +#ifdef PLATFORM_X86 + return reinterpret_cast(*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(reinterpret_cast(params[1]) + offset); +#else + void **addr = reinterpret_cast(reinterpret_cast(pseudoAddr.FromPseudoAddress(params[1])) + offset); +#endif + + if (addr == NULL) + { + return pContext->ThrowNativeError("Address cannot be null"); + } + else if (reinterpret_cast(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(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 LoadChunksFromAddress(IPluginContext *pContext, const cell_t *params) +{ + cell_t offset = params[4]; + +#ifdef PLATFORM_X86 + int8_t *addr = reinterpret_cast(params[1]) + offset; +#else + int8_t *addr = reinterpret_cast(pseudoAddr.FromPseudoAddress(params[1])) + offset; +#endif + + if (addr == NULL) + { + return pContext->ThrowNativeError("Address cannot be null"); + } + else if (reinterpret_cast(addr) < VALID_MINIMUM_MEMORY_ADDRESS) + { + return pContext->ThrowNativeError("Invalid address 0x%x is pointing to reserved memory.", addr); + } + + cell_t* chunks = nullptr; + pContext->LocalToPhysAddr(params[2], &chunks); + cell_t len = params[3]; + if (len <= 0) + { + return pContext->ThrowNativeError("Chunks array length must be positive!"); + } + + for (; len; chunks++, addr++, len--) + { + *chunks = *addr; + } + return 0; +} + +static cell_t StoreChunksToAddress(IPluginContext *pContext, const cell_t *params) +{ + cell_t offset = params[5]; + +#ifdef PLATFORM_X86 + int8_t *addr = reinterpret_cast(params[1]) + offset; +#else + int8_t *addr = reinterpret_cast(pseudoAddr.FromPseudoAddress(params[1])) + offset; +#endif + + if (addr == NULL) + { + return pContext->ThrowNativeError("Address cannot be null"); + } + else if (reinterpret_cast(addr) < VALID_MINIMUM_MEMORY_ADDRESS) + { + return pContext->ThrowNativeError("Invalid address 0x%x is pointing to reserved memory.", addr); + } + + cell_t* chunks = nullptr; + pContext->LocalToPhysAddr(params[2], &chunks); + cell_t len = params[3]; + if (len <= 0) + { + return pContext->ThrowNativeError("Chunks array length must be positive!"); + } + + if (params[4]) + { + SourceHook::SetMemAccess(addr, len, SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC); + } + + for (; len; chunks++, addr++, len--) + { + *addr = *chunks; + } + return 0; +} + +static cell_t OffsetAddress(IPluginContext *pContext, const cell_t *params) +{ +#ifdef PLATFORM_X86 + int8_t *addr = reinterpret_cast(params[1]); +#else + int8_t *addr = reinterpret_cast(pseudoAddr.FromPseudoAddress(params[1])); +#endif + + cell_t offset = params[2]; +#ifdef PLATFORM_X86 + return reinterpret_cast(addr + offset); +#else + return pseudoAddr.ToPseudoAddress(addr + offset); +#endif +} + static cell_t IsNullVector(IPluginContext *pContext, const cell_t *params) { cell_t *pNullVec = pContext->GetNullRef(SP_NULL_VECTOR); @@ -1157,6 +1320,11 @@ REGISTER_NATIVES(coreNatives) {"RequireFeature", RequireFeature}, {"LoadFromAddress", LoadFromAddress}, {"StoreToAddress", StoreToAddress}, + {"LoadAddressFromAddress", LoadAddressFromAddress}, + {"StoreAddressToAddress", StoreAddressToAddress}, + {"LoadChunksFromAddress", LoadChunksFromAddress}, + {"StoreChunksToAddress", StoreChunksToAddress}, + {"OffsetAddress", OffsetAddress}, {"IsNullVector", IsNullVector}, {"IsNullString", IsNullString}, {"LogStackTrace", LogStackTrace}, diff --git a/plugins/include/sourcemod.inc b/plugins/include/sourcemod.inc index 1927015680..85667bbb7f 100644 --- a/plugins/include/sourcemod.inc +++ b/plugins/include/sourcemod.inc @@ -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 addr parameter needs to be offsetted by. * @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. @@ -750,9 +751,65 @@ 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 addr parameter needs to be offsetted by. * @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. + * @return The address value that is stored at that address. + * @param offset Amount of bytes the addr parameter needs to be offsetted by. + * @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 addr parameter needs to be offsetted by. + * @error Address is null or pointing to reserved memory. + */ +native void StoreAddressToAddress(Address addr, Address data, bool updateMemAccess = true, int offset = 0); + +/** + * Load up to (len) bytes from a memory address. + * + * @param addr Address to a memory location. + * @param chunks Array of one-byte sized values. + * @param len How many bytes should be read. + * @param offset Amount of bytes the addr parameter needs to be offsetted by. + * @error Address is null or pointing to reserved memory. Chunks length is null or negative. + */ +native void LoadChunksFromAddress(Address addr, char[] chunks, int len, int offset = 0); + +/** + * Store up to (len) bytes to a memory address. + * + * @param addr Address to a memory location. + * @param chunks Array of one-byte sized values. + * @param len How many bytes should be written. + * @param updateMemAccess If true, SourceMod will set read / write / exec permissions + * on the memory page being written to. + * @param offset Amount of bytes the addr parameter needs to be offsetted by. + * @error Address is null or pointing to reserved memory. Chunks length is null or negative. + */ +native void StoreChunksToAddress(Address addr, char[] chunks, int len, bool updateMemAccess = true, int offset = 0); + +/** + * Offsets the given memory address. + * + * @param address Address to a memory location. + * @param offset How many bytes we should offset the address parameter by. + * @return The offsetted memory address. + */ +native Address OffsetAddress(Address addr, int offset); methodmap FrameIterator < Handle { // Creates a stack frame iterator to build your own stack traces. From db7b8395d4374062b6949bbea6d18b8f99251b60 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Mon, 5 Feb 2024 18:20:57 +0100 Subject: [PATCH 2/4] Rename chunks natives, add span natives --- core/logic/smn_core.cpp | 130 +++++++++++++++++++++++++++++++--- plugins/include/sourcemod.inc | 32 +++++++-- 2 files changed, 148 insertions(+), 14 deletions(-) diff --git a/core/logic/smn_core.cpp b/core/logic/smn_core.cpp index 8dbc3d15f8..fd21e3a51e 100644 --- a/core/logic/smn_core.cpp +++ b/core/logic/smn_core.cpp @@ -1024,7 +1024,16 @@ static cell_t StoreAddressToAddress(IPluginContext *pContext, const cell_t *para return 0; } -static cell_t LoadChunksFromAddress(IPluginContext *pContext, const cell_t *params) +template +static inline void AddressMemcpy(T* dest, U* src, cell_t len) +{ + for (; len; dest++, src++, len--) + { + *dest = *src; + } +} + +static cell_t LoadBytesFromAddress(IPluginContext *pContext, const cell_t *params) { cell_t offset = params[4]; @@ -1051,14 +1060,11 @@ static cell_t LoadChunksFromAddress(IPluginContext *pContext, const cell_t *para return pContext->ThrowNativeError("Chunks array length must be positive!"); } - for (; len; chunks++, addr++, len--) - { - *chunks = *addr; - } + AddressMemcpy(chunks, addr, len); return 0; } -static cell_t StoreChunksToAddress(IPluginContext *pContext, const cell_t *params) +static cell_t StoreBytesToAddress(IPluginContext *pContext, const cell_t *params) { cell_t offset = params[5]; @@ -1090,10 +1096,112 @@ static cell_t StoreChunksToAddress(IPluginContext *pContext, const cell_t *param SourceHook::SetMemAccess(addr, len, SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC); } - for (; len; chunks++, addr++, len--) + AddressMemcpy(addr, chunks, len); + return 0; +} + +static cell_t LoadSpanFromAddress(IPluginContext *pContext, const cell_t *params) +{ + cell_t offset = params[5]; + +#ifdef PLATFORM_X86 + void *addr = reinterpret_cast(reinterpret_cast(params[1]) + offset); +#else + void *addr = reinterpret_cast(reinterpret_cast(pseudoAddr.FromPseudoAddress(params[1])) + offset); +#endif + + if (addr == NULL) { - *addr = *chunks; + return pContext->ThrowNativeError("Address cannot be null"); } + else if (reinterpret_cast(addr) < VALID_MINIMUM_MEMORY_ADDRESS) + { + return pContext->ThrowNativeError("Invalid address 0x%x is pointing to reserved memory.", addr); + } + + cell_t* chunks = nullptr; + pContext->LocalToPhysAddr(params[2], &chunks); + cell_t len = params[3]; + if (len <= 0) + { + return pContext->ThrowNativeError("Chunks array length must be positive!"); + } + + NumberType size = static_cast(params[4]); + + switch(size) + { + case NumberType_Int8: + AddressMemcpy(chunks, reinterpret_cast(addr), len); + break; + case NumberType_Int16: + AddressMemcpy(chunks, reinterpret_cast(addr), len); + break; + case NumberType_Int32: + AddressMemcpy(chunks, reinterpret_cast(addr), len); + break; + default: + return pContext->ThrowNativeError("Invalid number types %d", size); + } + return 0; +} + +static cell_t StoreSpanToAddress(IPluginContext *pContext, const cell_t *params) +{ + cell_t offset = params[6]; + +#ifdef PLATFORM_X86 + void *addr = reinterpret_cast(reinterpret_cast(params[1]) + offset); +#else + void *addr = reinterpret_cast(reinterpret_cast(pseudoAddr.FromPseudoAddress(params[1])) + offset); +#endif + + if (addr == NULL) + { + return pContext->ThrowNativeError("Address cannot be null"); + } + else if (reinterpret_cast(addr) < VALID_MINIMUM_MEMORY_ADDRESS) + { + return pContext->ThrowNativeError("Invalid address 0x%x is pointing to reserved memory.", addr); + } + + cell_t* chunks = nullptr; + pContext->LocalToPhysAddr(params[2], &chunks); + cell_t len = params[3]; + if (len <= 0) + { + return pContext->ThrowNativeError("Chunks array length must be positive!"); + } + + NumberType size = static_cast(params[4]); + + switch(size) + { + case NumberType_Int8: + if (params[5]) + { + SourceHook::SetMemAccess(addr, len * sizeof(int8_t), SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC); + } + AddressMemcpy(reinterpret_cast(addr), chunks, len); + break; + case NumberType_Int16: + if (params[5]) + { + SourceHook::SetMemAccess(addr, len * sizeof(int16_t), SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC); + } + AddressMemcpy(reinterpret_cast(addr), chunks, len); + break; + case NumberType_Int32: + if (params[5]) + { + SourceHook::SetMemAccess(addr, len * sizeof(int32_t), SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC); + } + AddressMemcpy(reinterpret_cast(addr), chunks, len); + break; + default: + return pContext->ThrowNativeError("Invalid number types %d", size); + } + return 0; } @@ -1322,8 +1430,10 @@ REGISTER_NATIVES(coreNatives) {"StoreToAddress", StoreToAddress}, {"LoadAddressFromAddress", LoadAddressFromAddress}, {"StoreAddressToAddress", StoreAddressToAddress}, - {"LoadChunksFromAddress", LoadChunksFromAddress}, - {"StoreChunksToAddress", StoreChunksToAddress}, + {"LoadBytesFromAddress ", LoadBytesFromAddress}, + {"StoreBytesToAddress", StoreBytesToAddress}, + {"LoadSpanFromAddress ", LoadSpanFromAddress}, + {"StoreSpanToAddress", StoreSpanToAddress}, {"OffsetAddress", OffsetAddress}, {"IsNullVector", IsNullVector}, {"IsNullString", IsNullString}, diff --git a/plugins/include/sourcemod.inc b/plugins/include/sourcemod.inc index 85667bbb7f..38113488ac 100644 --- a/plugins/include/sourcemod.inc +++ b/plugins/include/sourcemod.inc @@ -782,25 +782,49 @@ native void StoreAddressToAddress(Address addr, Address data, bool updateMemAcce * Load up to (len) bytes from a memory address. * * @param addr Address to a memory location. - * @param chunks Array of one-byte sized values. + * @param bytes Array bytes to load. * @param len How many bytes should be read. * @param offset Amount of bytes the addr parameter needs to be offsetted by. * @error Address is null or pointing to reserved memory. Chunks length is null or negative. */ -native void LoadChunksFromAddress(Address addr, char[] chunks, int len, int offset = 0); +native void LoadBytesFromAddress(Address addr, char[] bytes, int len, int offset = 0); /** * Store up to (len) bytes to a memory address. * * @param addr Address to a memory location. - * @param chunks Array of one-byte sized values. + * @param bytes Array of bytes to store. * @param len How many bytes should be written. * @param updateMemAccess If true, SourceMod will set read / write / exec permissions * on the memory page being written to. * @param offset Amount of bytes the addr parameter needs to be offsetted by. * @error Address is null or pointing to reserved memory. Chunks length is null or negative. */ -native void StoreChunksToAddress(Address addr, char[] chunks, int len, bool updateMemAccess = true, int offset = 0); +native void StoreBytesToAddress(Address addr, char[] bytes, int len, bool updateMemAccess = true, int offset = 0); + +/** + * Load a sized span from a memory address. + * + * @param addr Address to a memory location. + * @param bytes Array of NumberType sized values that constitute the span. + * @param len Size of the span. + * @param offset Amount of bytes the addr parameter needs to be offsetted by. + * @error Address is null or pointing to reserved memory. Chunks length is null or negative. + */ +native void LoadSpanFromAddress(Address addr, any[] span, int len, NumberType size, int offset = 0); + +/** + * Store a given sized span to the given address. + * + * @param addr Address to a memory location. + * @param span Array of NumberType sized values that constitute the span. + * @param len Size of the span. + * @param updateMemAccess If true, SourceMod will set read / write / exec permissions + * on the memory page being written to. + * @param offset Amount of bytes the addr parameter needs to be offsetted by. + * @error Address is null or pointing to reserved memory. Chunks length is null or negative. + */ +native void StoreSpanToAddress(Address addr, any[] span, int len, NumberType size, bool updateMemAccess = true, int offset = 0); /** * Offsets the given memory address. From ca9e1edf10d7d01d43de89b46aa4847182d331f7 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Mon, 5 Feb 2024 18:34:18 +0100 Subject: [PATCH 3/4] update docs --- plugins/include/sourcemod.inc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/include/sourcemod.inc b/plugins/include/sourcemod.inc index 38113488ac..db5d3aeba1 100644 --- a/plugins/include/sourcemod.inc +++ b/plugins/include/sourcemod.inc @@ -785,7 +785,7 @@ native void StoreAddressToAddress(Address addr, Address data, bool updateMemAcce * @param bytes Array bytes to load. * @param len How many bytes should be read. * @param offset Amount of bytes the addr parameter needs to be offsetted by. - * @error Address is null or pointing to reserved memory. Chunks length is null or negative. + * @error Address is null or pointing to reserved memory. Bytes array length is null or negative. */ native void LoadBytesFromAddress(Address addr, char[] bytes, int len, int offset = 0); @@ -798,7 +798,7 @@ native void LoadBytesFromAddress(Address addr, char[] bytes, int len, int offset * @param updateMemAccess If true, SourceMod will set read / write / exec permissions * on the memory page being written to. * @param offset Amount of bytes the addr parameter needs to be offsetted by. - * @error Address is null or pointing to reserved memory. Chunks length is null or negative. + * @error Address is null or pointing to reserved memory. Bytes array length is null or negative. */ native void StoreBytesToAddress(Address addr, char[] bytes, int len, bool updateMemAccess = true, int offset = 0); @@ -806,10 +806,11 @@ native void StoreBytesToAddress(Address addr, char[] bytes, int len, bool update * Load a sized span from a memory address. * * @param addr Address to a memory location. - * @param bytes Array of NumberType sized values that constitute the span. - * @param len Size of the span. + * @param span Array of NumberType sized values that constitute the span. + * @param len Size of the span. + * @param size Size of each element. * @param offset Amount of bytes the addr parameter needs to be offsetted by. - * @error Address is null or pointing to reserved memory. Chunks length is null or negative. + * @error Address is null or pointing to reserved memory. Span length is null or negative. */ native void LoadSpanFromAddress(Address addr, any[] span, int len, NumberType size, int offset = 0); @@ -819,10 +820,11 @@ native void LoadSpanFromAddress(Address addr, any[] span, int len, NumberType si * @param addr Address to a memory location. * @param span Array of NumberType sized values that constitute the span. * @param len Size of the span. + * @param size Size of each element. * @param updateMemAccess If true, SourceMod will set read / write / exec permissions * on the memory page being written to. * @param offset Amount of bytes the addr parameter needs to be offsetted by. - * @error Address is null or pointing to reserved memory. Chunks length is null or negative. + * @error Address is null or pointing to reserved memory. Span length is null or negative. */ native void StoreSpanToAddress(Address addr, any[] span, int len, NumberType size, bool updateMemAccess = true, int offset = 0); From 9799883128f2450f4f5bd6a223dcd8aaa44e46a3 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Thu, 8 Feb 2024 01:31:32 +0100 Subject: [PATCH 4/4] remove some natives --- core/logic/smn_core.cpp | 202 ---------------------------------- plugins/include/sourcemod.inc | 67 +---------- 2 files changed, 4 insertions(+), 265 deletions(-) diff --git a/core/logic/smn_core.cpp b/core/logic/smn_core.cpp index fd21e3a51e..6065d7230d 100644 --- a/core/logic/smn_core.cpp +++ b/core/logic/smn_core.cpp @@ -1024,203 +1024,6 @@ static cell_t StoreAddressToAddress(IPluginContext *pContext, const cell_t *para return 0; } -template -static inline void AddressMemcpy(T* dest, U* src, cell_t len) -{ - for (; len; dest++, src++, len--) - { - *dest = *src; - } -} - -static cell_t LoadBytesFromAddress(IPluginContext *pContext, const cell_t *params) -{ - cell_t offset = params[4]; - -#ifdef PLATFORM_X86 - int8_t *addr = reinterpret_cast(params[1]) + offset; -#else - int8_t *addr = reinterpret_cast(pseudoAddr.FromPseudoAddress(params[1])) + offset; -#endif - - if (addr == NULL) - { - return pContext->ThrowNativeError("Address cannot be null"); - } - else if (reinterpret_cast(addr) < VALID_MINIMUM_MEMORY_ADDRESS) - { - return pContext->ThrowNativeError("Invalid address 0x%x is pointing to reserved memory.", addr); - } - - cell_t* chunks = nullptr; - pContext->LocalToPhysAddr(params[2], &chunks); - cell_t len = params[3]; - if (len <= 0) - { - return pContext->ThrowNativeError("Chunks array length must be positive!"); - } - - AddressMemcpy(chunks, addr, len); - return 0; -} - -static cell_t StoreBytesToAddress(IPluginContext *pContext, const cell_t *params) -{ - cell_t offset = params[5]; - -#ifdef PLATFORM_X86 - int8_t *addr = reinterpret_cast(params[1]) + offset; -#else - int8_t *addr = reinterpret_cast(pseudoAddr.FromPseudoAddress(params[1])) + offset; -#endif - - if (addr == NULL) - { - return pContext->ThrowNativeError("Address cannot be null"); - } - else if (reinterpret_cast(addr) < VALID_MINIMUM_MEMORY_ADDRESS) - { - return pContext->ThrowNativeError("Invalid address 0x%x is pointing to reserved memory.", addr); - } - - cell_t* chunks = nullptr; - pContext->LocalToPhysAddr(params[2], &chunks); - cell_t len = params[3]; - if (len <= 0) - { - return pContext->ThrowNativeError("Chunks array length must be positive!"); - } - - if (params[4]) - { - SourceHook::SetMemAccess(addr, len, SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC); - } - - AddressMemcpy(addr, chunks, len); - return 0; -} - -static cell_t LoadSpanFromAddress(IPluginContext *pContext, const cell_t *params) -{ - cell_t offset = params[5]; - -#ifdef PLATFORM_X86 - void *addr = reinterpret_cast(reinterpret_cast(params[1]) + offset); -#else - void *addr = reinterpret_cast(reinterpret_cast(pseudoAddr.FromPseudoAddress(params[1])) + offset); -#endif - - if (addr == NULL) - { - return pContext->ThrowNativeError("Address cannot be null"); - } - else if (reinterpret_cast(addr) < VALID_MINIMUM_MEMORY_ADDRESS) - { - return pContext->ThrowNativeError("Invalid address 0x%x is pointing to reserved memory.", addr); - } - - cell_t* chunks = nullptr; - pContext->LocalToPhysAddr(params[2], &chunks); - cell_t len = params[3]; - if (len <= 0) - { - return pContext->ThrowNativeError("Chunks array length must be positive!"); - } - - NumberType size = static_cast(params[4]); - - switch(size) - { - case NumberType_Int8: - AddressMemcpy(chunks, reinterpret_cast(addr), len); - break; - case NumberType_Int16: - AddressMemcpy(chunks, reinterpret_cast(addr), len); - break; - case NumberType_Int32: - AddressMemcpy(chunks, reinterpret_cast(addr), len); - break; - default: - return pContext->ThrowNativeError("Invalid number types %d", size); - } - return 0; -} - -static cell_t StoreSpanToAddress(IPluginContext *pContext, const cell_t *params) -{ - cell_t offset = params[6]; - -#ifdef PLATFORM_X86 - void *addr = reinterpret_cast(reinterpret_cast(params[1]) + offset); -#else - void *addr = reinterpret_cast(reinterpret_cast(pseudoAddr.FromPseudoAddress(params[1])) + offset); -#endif - - if (addr == NULL) - { - return pContext->ThrowNativeError("Address cannot be null"); - } - else if (reinterpret_cast(addr) < VALID_MINIMUM_MEMORY_ADDRESS) - { - return pContext->ThrowNativeError("Invalid address 0x%x is pointing to reserved memory.", addr); - } - - cell_t* chunks = nullptr; - pContext->LocalToPhysAddr(params[2], &chunks); - cell_t len = params[3]; - if (len <= 0) - { - return pContext->ThrowNativeError("Chunks array length must be positive!"); - } - - NumberType size = static_cast(params[4]); - - switch(size) - { - case NumberType_Int8: - if (params[5]) - { - SourceHook::SetMemAccess(addr, len * sizeof(int8_t), SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC); - } - AddressMemcpy(reinterpret_cast(addr), chunks, len); - break; - case NumberType_Int16: - if (params[5]) - { - SourceHook::SetMemAccess(addr, len * sizeof(int16_t), SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC); - } - AddressMemcpy(reinterpret_cast(addr), chunks, len); - break; - case NumberType_Int32: - if (params[5]) - { - SourceHook::SetMemAccess(addr, len * sizeof(int32_t), SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC); - } - AddressMemcpy(reinterpret_cast(addr), chunks, len); - break; - default: - return pContext->ThrowNativeError("Invalid number types %d", size); - } - - return 0; -} - -static cell_t OffsetAddress(IPluginContext *pContext, const cell_t *params) -{ -#ifdef PLATFORM_X86 - int8_t *addr = reinterpret_cast(params[1]); -#else - int8_t *addr = reinterpret_cast(pseudoAddr.FromPseudoAddress(params[1])); -#endif - - cell_t offset = params[2]; -#ifdef PLATFORM_X86 - return reinterpret_cast(addr + offset); -#else - return pseudoAddr.ToPseudoAddress(addr + offset); -#endif -} - static cell_t IsNullVector(IPluginContext *pContext, const cell_t *params) { cell_t *pNullVec = pContext->GetNullRef(SP_NULL_VECTOR); @@ -1430,11 +1233,6 @@ REGISTER_NATIVES(coreNatives) {"StoreToAddress", StoreToAddress}, {"LoadAddressFromAddress", LoadAddressFromAddress}, {"StoreAddressToAddress", StoreAddressToAddress}, - {"LoadBytesFromAddress ", LoadBytesFromAddress}, - {"StoreBytesToAddress", StoreBytesToAddress}, - {"LoadSpanFromAddress ", LoadSpanFromAddress}, - {"StoreSpanToAddress", StoreSpanToAddress}, - {"OffsetAddress", OffsetAddress}, {"IsNullVector", IsNullVector}, {"IsNullString", IsNullString}, {"LogStackTrace", LogStackTrace}, diff --git a/plugins/include/sourcemod.inc b/plugins/include/sourcemod.inc index db5d3aeba1..e97e231c0c 100644 --- a/plugins/include/sourcemod.inc +++ b/plugins/include/sourcemod.inc @@ -736,7 +736,7 @@ 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 addr parameter needs to be offsetted by. + * @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. */ @@ -751,7 +751,7 @@ native any LoadFromAddress(Address addr, NumberType size, int offset = 0); * 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 addr parameter needs to be offsetted by. + * @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, int offset = 0); @@ -760,8 +760,8 @@ native void StoreToAddress(Address addr, any data, NumberType size, bool updateM * 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. - * @param offset Amount of bytes the addr parameter needs to be offsetted by. * @error Address is null or pointing to reserved memory. */ native Address LoadAddressFromAddress(Address addr, int offset = 0); @@ -773,70 +773,11 @@ native Address LoadAddressFromAddress(Address addr, int offset = 0); * @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 addr parameter needs to be offsetted by. + * @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); -/** - * Load up to (len) bytes from a memory address. - * - * @param addr Address to a memory location. - * @param bytes Array bytes to load. - * @param len How many bytes should be read. - * @param offset Amount of bytes the addr parameter needs to be offsetted by. - * @error Address is null or pointing to reserved memory. Bytes array length is null or negative. - */ -native void LoadBytesFromAddress(Address addr, char[] bytes, int len, int offset = 0); - -/** - * Store up to (len) bytes to a memory address. - * - * @param addr Address to a memory location. - * @param bytes Array of bytes to store. - * @param len How many bytes should be written. - * @param updateMemAccess If true, SourceMod will set read / write / exec permissions - * on the memory page being written to. - * @param offset Amount of bytes the addr parameter needs to be offsetted by. - * @error Address is null or pointing to reserved memory. Bytes array length is null or negative. - */ -native void StoreBytesToAddress(Address addr, char[] bytes, int len, bool updateMemAccess = true, int offset = 0); - -/** - * Load a sized span from a memory address. - * - * @param addr Address to a memory location. - * @param span Array of NumberType sized values that constitute the span. - * @param len Size of the span. - * @param size Size of each element. - * @param offset Amount of bytes the addr parameter needs to be offsetted by. - * @error Address is null or pointing to reserved memory. Span length is null or negative. - */ -native void LoadSpanFromAddress(Address addr, any[] span, int len, NumberType size, int offset = 0); - -/** - * Store a given sized span to the given address. - * - * @param addr Address to a memory location. - * @param span Array of NumberType sized values that constitute the span. - * @param len Size of the span. - * @param size Size of each element. - * @param updateMemAccess If true, SourceMod will set read / write / exec permissions - * on the memory page being written to. - * @param offset Amount of bytes the addr parameter needs to be offsetted by. - * @error Address is null or pointing to reserved memory. Span length is null or negative. - */ -native void StoreSpanToAddress(Address addr, any[] span, int len, NumberType size, bool updateMemAccess = true, int offset = 0); - -/** - * Offsets the given memory address. - * - * @param address Address to a memory location. - * @param offset How many bytes we should offset the address parameter by. - * @return The offsetted memory address. - */ -native Address OffsetAddress(Address addr, int offset); - methodmap FrameIterator < Handle { // Creates a stack frame iterator to build your own stack traces. // @return New handle to a FrameIterator.