Skip to content
51 changes: 38 additions & 13 deletions MemoryEx.inc
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
/*
[Extending opportunities for work with memory in SourcePawn]
Memory Extendвd
[Extending opportunities to work with memory in SourcePawn]
Memory Extended

Author: Rostu [vk.com/rostu13 | Discord: Rostu#7917]
Version: 3.1
Fork: Dragokas [vk.com/drago_kas | Discord: Dragokas#1453]
Version: 3.1.11

18.12.2019 First release [Windows Only]
22.12.2019 Version 1.1 [Windows Only]
Expand All @@ -12,15 +13,39 @@
05.05.2020 Version 2.7 [Export/Import Tables]
08.06.2020 Version 3.0 [malloc/free]
20.08.2020 Version 3.1 [PatternGenerator]
14.12.2020 Version 3.1.1 [MemoryAlloc - fix for VirtualAlloc/FreeMemory (Win)]
29.12.2020 Version 3.1.2 [GameDataEx]
26.02.2021 Version 3.1.3 [MemSearcher - IsValidAddress]
02.03.2021 Version 3.1.4 [BinaryFile, Fixed GetProcAddress (Linux), new Stocks]
07.04.2021 Version 3.1.5 Added mapping "matchmaking_ds" library to "matchmaking_ds_srv" for Linux/Mac.
16.01.2022 Version 3.1.6:
[ASM_Instruction.inc] Added SizeOfCode, SizeOfProc - to calculate the length of opcode instruction / procedure (thanks to Ms-Rem & The Trick).
[ASM_Instruction.inc] Added IsRelativeCmd - to check whether JMP is relative.
#define PTR & Pointer are deprecated (to prevent confusion with C-Pointers). Use ADDR instead.
#define nullptr is deprecated. Use Address_Null instead.
Added define: ADDR - to view as Address.
Added defines: LA_8, LA_16, LA_24, LA_32 - shortcuts to load 1-4 byte size data from address.
19.01.2022 Version 3.1.7: MemSearcher: Added "IsValidPointer", better read access check.
18.03.2022 Version 3.1.8: Fixed "engine" library mapping.
08.07.2022 Version 3.1.9: Fixed warnings on SM 1.11. VirtualQuery optimizations (Windows).
06.11.2022 Version 3.1.10: Fixed "array out of bounds" in FindModuleString.
01.02.2023 Version 3.1.11: Added "test x,x" (0x85) assembler instruction.
*/

//#define MEMORY_EX_DBG

#if defined _MemoryEx_included
#endinput
#endif
#define _MemoryEx_included

#include <MemoryEx/ServerLibrary>
#include <MemoryEx/BaseMemory>
#include <MemoryEx/ASM_Instruction>
#include <MemoryEx/DynamicLibrary>
#include <MemoryEx/MemoryAlloc>
#include <MemoryEx/GameDataEx>
#include <MemoryEx/MemSearcher>
//#include <MemoryEx/Smx>

#if defined MEMORY_EX_DBG
Expand All @@ -36,7 +61,7 @@ enum struct MemoryEx
{
this.mem.SetAddr(address);
}
Pointer GetAddr()
Address GetAddr()
{
return this.mem.GetAddr();
}
Expand Down Expand Up @@ -90,51 +115,51 @@ enum struct MemoryEx
{
return this.lib.GetListLibraries();
}
Pointer GetModuleHandle(const char[] sName)
Address GetModuleHandle(const char[] sName)
{
return this.lib.GetModuleHandle(sName);
}
any GetModuleSize(const char[] sName)
{
return this.lib.GetModuleSize(sName);
}
Pointer GetEndModule(const char[] sName)
Address GetEndModule(const char[] sName)
{
return this.lib.GetEndModule(sName);
}
Pointer GetProcAddress(const char[] sLibrary, const char[] sName)
Address GetProcAddress(const char[] sLibrary, const char[] sName)
{
return this.lib.GetProcAddress(sLibrary, sName);
}
Pointer GetImportAddress(const char[] sLibrary, const char[] sName)
Address GetImportAddress(const char[] sLibrary, const char[] sName)
{
return this.lib.GetImportAddress(sLibrary, sName);
}
int FindModule(const char[] sModule, char[] sResult, int iMaxLength)
{
return this.lib.FindModule(sModule, sResult, iMaxLength);
}
Pointer FindPattern(const char[] sModule, const int[] sPattern, int iLength, int iOffset = 0)
Address FindPattern(const char[] sModule, const int[] sPattern, int iLength, int iOffset = 0)
{
return this.lib.FindPattern(sModule, sPattern, iLength, iOffset);
}
Pointer FindString(const char[] sModule, const char[] sString)
Address FindString(const char[] sModule, const char[] sString)
{
return this.lib.FindString(sModule, sString);
}
ArrayList FindAllStrings(const char[] sModule, const char[] sString)
{
return this.lib.FindAllStrings(sModule, sString);
}
Pointer FindUnicodeString(const char[] sModule, const char[] sString)
Address FindUnicodeString(const char[] sModule, const char[] sString)
{
return this.lib.FindUnicodeString(sModule, sString);
}
Pointer FindValue(const char[] sModule, any iValue, int iNextByte = 0x2A )
Address FindValue(const char[] sModule, any iValue, int iNextByte = 0x2A )
{
return this.lib.FindValue(sModule, iValue, iNextByte);
}
Pointer FindValueEx(const char[] sModule, any iValue, const int[] iPattern, int iSize)
Address FindValueEx(const char[] sModule, any iValue, const int[] iPattern, int iSize)
{
return this.lib.FindValueEx(sModule, iValue, iPattern, iSize);
}
Expand Down
37 changes: 31 additions & 6 deletions MemoryEx/ASM_Instruction.inc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@


#include <MemoryEx/BaseMemory>
#include <MemoryEx/Ldasm>


enum ASMRegister
Expand All @@ -24,15 +25,26 @@ enum struct ASMInstructions
{
BaseMemory mem;

void Set(Pointer adr)
void Set(Address adr)
{
this.mem.pAddrBase = adr;
}
Pointer Get()
Address Get()
{
return this.mem.pAddrBase;
}

int SizeOfCode(any offset = 0)
{
return ASM_SizeOfCode(this.mem.pAddrBase + offset);
}
int SizeOfProc(any offset = 0)
{
return ASM_SizeOfProc(this.mem.pAddrBase + offset);
}
bool IsRelativeCmd(any offset = 0)
{
return ASM_IsRelativeCmd(this.mem.pAddrBase + offset);
}
void PushRegister(ASMRegister reg)
{
this.mem.WriteByte(0x50 + view_as<int>(reg), _, MemoryEx_AddAfterWrite);
Expand All @@ -46,13 +58,25 @@ enum struct ASMInstructions
{
this.mem.WriteByte(0x58 + view_as<int>(reg), _, MemoryEx_AddAfterWrite);
}

void Call (any value)
void Call(any value)
{
this.mem.WriteWord(0x15FF, _, MemoryEx_AddAfterWrite);
this.mem.WriteInt(value, _, MemoryEx_AddAfterWrite);
}

void Test(ASMRegister reg)
{
switch (reg)
{
case ASMRegister_EAX: this.mem.WriteWord(0xC085, _, MemoryEx_AddAfterWrite);
case ASMRegister_ECX: this.mem.WriteWord(0xC985, _, MemoryEx_AddAfterWrite);
case ASMRegister_EDX: this.mem.WriteWord(0xD285, _, MemoryEx_AddAfterWrite);
case ASMRegister_EBX: this.mem.WriteWord(0xDB85, _, MemoryEx_AddAfterWrite);
case ASMRegister_ESP: this.mem.WriteWord(0xE485, _, MemoryEx_AddAfterWrite);
case ASMRegister_EBP: this.mem.WriteWord(0xED85, _, MemoryEx_AddAfterWrite);
case ASMRegister_ESI: this.mem.WriteWord(0xF685, _, MemoryEx_AddAfterWrite);
case ASMRegister_EDI: this.mem.WriteWord(0xFF85, _, MemoryEx_AddAfterWrite);
}
}
void Nop()
{
this.mem.WriteByte(0x90, _, MemoryEx_AddAfterWrite);
Expand All @@ -77,6 +101,7 @@ stock ASMInstructions g_ASM;
#define PUSH(%0) g_ASM.Push(%0)
#define POP_REGISTER(%0) g_ASM.PopRegister(ASMRegister_%0)
#define CALL(%0) g_ASM.Call(%0)
#define ASM_TEST(%0) g_ASM.Test(ASMRegister_%0)
#define NOP() g_ASM.Nop()
#define XCHG(%0) g_ASM.Xchg(ASMRegister_%0)
#define RETN() g_ASM.Retn()
26 changes: 13 additions & 13 deletions MemoryEx/BaseMemory.inc
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
#endif
#define _MemoryEx_BaseMemory_include_


#include <sdktools>

#define Pointer Address
#define nullptr Address_Null
#define ADDR(%0) view_as<Address>(%0)

#define PTR(%0) view_as<Pointer>(%0)
#define Pointer Address // deprecated
#define nullptr Address_Null // deprecated
#define PTR(%0) view_as<Pointer>(%0) // deprecated

enum
{
Expand All @@ -31,7 +31,7 @@ enum

enum struct BaseMemory
{
Pointer pAddrBase;
Address pAddrBase;

void SetAddr(any address)
{
Expand All @@ -40,9 +40,9 @@ enum struct BaseMemory
return;
}

this.pAddrBase = PTR(address);
this.pAddrBase = ADDR(address);
}
Pointer GetAddr()
Address GetAddr()
{
return this.pAddrBase;
}
Expand All @@ -53,11 +53,11 @@ enum struct BaseMemory

int ReadByte(int iOffset = 0)
{
return LoadFromAddress(this.pAddrBase + PTR(iOffset), NumberType_Int8);
return LoadFromAddress(this.pAddrBase + ADDR(iOffset), NumberType_Int8);
}
void WriteByte(any iByte, int iOffset = 0, int flags = MemoryEx_NoNeedAdd)
{
Pointer addr = this.GetAddr() + PTR(iOffset);
Address addr = this.GetAddr() + ADDR(iOffset);

StoreToAddress(addr, iByte, NumberType_Int8);

Expand All @@ -69,11 +69,11 @@ enum struct BaseMemory

int ReadWord(int iOffset = 0)
{
return LoadFromAddress(this.pAddrBase + PTR(iOffset), NumberType_Int16);
return LoadFromAddress(this.pAddrBase + ADDR(iOffset), NumberType_Int16);
}
void WriteWord(any iWord, int iOffset = 0, int flags = MemoryEx_NoNeedAdd)
{
Pointer addr = this.GetAddr() + PTR(iOffset);
Address addr = this.GetAddr() + ADDR(iOffset);

StoreToAddress(addr, iWord, NumberType_Int16);

Expand All @@ -85,11 +85,11 @@ enum struct BaseMemory

int ReadInt (int iOffset = 0)
{
return LoadFromAddress(this.pAddrBase + PTR(iOffset), NumberType_Int32);
return LoadFromAddress(this.pAddrBase + ADDR(iOffset), NumberType_Int32);
}
void WriteInt(any iNumber, int iOffset = 0, int flags = MemoryEx_NoNeedAdd)
{
Pointer addr = this.GetAddr() + PTR(iOffset);
Address addr = this.GetAddr() + ADDR(iOffset);

StoreToAddress(addr, iNumber, NumberType_Int32);

Expand Down
Loading