Skocz do zawartości

Nowy szablon forum

mygo.pl

Stworzyliśmy dla Was nowy wygląd forum. Z pewnością znajdziesz rzeczy, które wg Ciebie mogą zostać zmienione - wspomnij o tym w specjalnym wątku.

Czytaj więcej

Jak założyć własną sieć

serwerów CS

Zastanawiasz się nad prowadzeniem własnej sieci serwerów? Przeczytaj podstawowe informacje, na które należy zwrócić uwagę, przy takim projekcie.

Czytaj więcej

Tworzymy spis sieci

dodaj swoją

Dodaj sieć do której należysz, pozwoli to na promocję i budowę ogólnopolskiej bazy sieci CS.

Czytaj więcej

[ANY] Memory Patcher (v1.0 30/09/2018)


MYGO.pl
 Udostępnij

Rekomendowane odpowiedzi

  • RSSy
Memory Patcher

Description:
Add "memory patches" to the plugin either by natives or gamedata files that are read from a folder (gamedata/memorypatcher.games/), and restore them at any time. Mem patches that are added from gamedata/memorypatcher.games/ are automatically applied. Patches that are added by natives (MP_AddMemoryPatch or MP_AddMemoryPatchEx) also needs to be applied by using MP_Patch

"Preview":


Commands:
Quote:

sm_mp_patchall - z - Patch all existing memory patches
sm_mp_restoreall - z - Restore all existing memory patches
sm_mp_patch - z - Patch a single memory patch by siglabel
sm_mp_restore - z - Restore a single memory patch by siglabel
sm_mp_status - z - Print out status of existing memory patches
sm_mp_refresh - z - Read from gamedata folder (gamedata/memorypatcher.games/)
Gamedata template:

Using Peace-Maker's CSGO Movement Unlocker as an example.

csgo/addons/sourcemod/gamedata/memorypatcher.games/walkmove.games.txt
PHP Code:

"Games"
{
    
"csgo"
    
{
        
"Addresses"
        
{
            
"CGameMovement::WalkMove_Label"
            
{
                
"windows"
                
{
                    
"signature" "CGameMovement::WalkMove"
                
}
                
"linux"
                
{
                    
"signature" "CGameMovement::WalkMove"
                
}
            }
        }
        
        
"Signatures"
        
{
            
"CGameMovement::WalkMove"
            
{
                
"library"    "server"
                "windows"    "\xF3\x0F\x59\xC0\xF3\x0F\x59\xD2\xF3\x0F\x59\xC9\xF3\x0F\x58\xD0\xF3\x0F\x58\xD1\x0F\x28\xC2\xF3\x0F\x51\xC0\xF3\x0F\x5E\xD8"
                "linux"        "\xF3\x0F\x10\xF0\x0F\x28\xC6\xF3\x0F\x51\xC6\xF3\x0F\x5E\xE8"
            
}
        }
        
"Offsets"
        
{
            
"PatchOffset"
            
{
                
"windows"    "31"
                "linux"    "27"
            
}
            
"PatchByteCount"
            
{
                
"windows"    "42"
                "linux"    "15"
            
}
        }
        
"Keys"
        
{
            
// If the amount of opcodes are less than the PatchByteCount, then it will just append the last opcode for the remaining bytes
            // in this case it will append 41 NOPs after the first one for windows, 14 for linux
            
"opcodes_windows"    "\x90"
            "opcodes_linux"        "\x90"
            "siglabel"            "CGameMovement::WalkMove"
        
}
    }


memorypatcher.inc:
PHP Code:

#if defined _memorypatcher_included
 #endinput
#endif
#define _memorypatcher_included

#define MP_PREFIX                        " \x09[\x04MemoryPatcher\x09]"
#define MP_GAMEDATA_DIR                    "memorypatcher.games"
#define MP_DEBUG_PREFIX                    "[memorypatcher.smx]"
#define MP_TEMP_FILE                    "temp.memorypatcher.txt"
#define MP_PATCH_MAX_NAME_LENGTH         32
#define MP_PATCH_MAX_SIG_LENGTH         256
#define MP_PATCH_MAX_OP_CODES            2048

enum//OSType
{
    
OSType_Invalid 0,
    
OSType_Windows,
    
OSType_Linux,
    
OSType_Mac,
    
    
OSType_MAX,
}

enum//LIBType
{
    
LIBType_Server 0,
    
LIBType_Engine,
    
    
LIBType_MAX,
}

enum//AddMemoryPatchError
{
    
MP_PATCH_ADD_ERROR_EXCEEDED_OP_CODE_COUNT =     -2,            // Memory patch is too large
    
MP_PATCH_ADD_ERROR_PATCH_EXISTS =                 -1,            // Memory patch already exists
    
MP_PATCH_ADD_ERROR_INVALID_TEMP_FILE =             0,            // Should never happend, temp file could not be created (no permissions?)
    
MP_PATCH_ADD_SUCCESS =                             1,            // If memory patch was successfully added
}

enum//ApplyMemoryPatchError
{
    
MP_PATCH_APPLY_ERROR_NOT_FOUND =                 -4,            // Memory patch sig label was not found
    
MP_PATCH_APPLY_ERROR_IS_PATCHED =                 -3,            // Memory patch was already applied
    
MP_PATCH_APPLY_ERROR_UNKNOWN_ADDRESS =             -2,            // Could not find the sig
    
MP_PATCH_APPLY_ERROR_UNKNOWN_OFFSET =             -1,            // Should never happend, could not find offset in config file
    
MP_PATCH_APPLY_ERROR_UNKNOWN_COUNT =             0,            // Should never happend, could not find patch byte count
    
MP_PATCH_APPLY_SUCCESS =                         1            // If memory patch was successfully applied
}

enum//RestoreMemoryPatchError
{
    
MP_PATCH_RESTORE_ERROR_INDEX_NOT_FOUND =        -2,            // Should never happend, patch index was not found in stringmap
    
MP_PATCH_RESTORE_ERROR_NOT_FOUND =                 -1,            // Memory patch sig label was not found
    
MP_PATCH_RESTORE_ERROR_IS_RESTORED =             0,            // Memory patch was already restored
    
MP_PATCH_RESTORE_SUCCESS =                         1            // If memory patch was successfully restored

}

/**
 * Get server Operating System
 * 
 * @return int                ostype
 */
native int MP_GetServerOSType();

/**
 * Add a memory patch which can be patched or restored at any time
 * 
 * @param ostype            which OS is this sig for (see OSType above)
 * @param libtype            which libtype is this sig for (see LIBType above)
 * @param siglabel            label of your sig
 * @param sig                function signature
 * @param offset            offset inside the function
 * @param opcodes            an array containing all opcodes you want to patch the function with
 * @param patchbytecount    amount of bytes to patch
 * @return int                memory patch error code (see MemoryPatchError above)
 */
native int MP_AddMemoryPatch(int ostypeint libtype, const char[] siglabelchar[] sigint offsetint[] opcodesint patchbytecount);

/**
 * Add a memory patch which can be patched or restored at any time (Single OP code instead of array of opcodes)
 * 
 * @param ostype            which OS is this sig for (see OSType above)
 * @param libtype            which libtype is this sig for (see LIBType above)
 * @param siglabel            label of your sig
 * @param sig                function signature
 * @param offset            offset inside the function
 * @param opcode            the opcode you wanna patch with
 * @param patchbytecount    amount of bytes to patch
 * @return int                memory patch error code (see MemoryPatchError above)
 */
native int MP_AddMemoryPatchEx(int ostypeint libtype, const char[] siglabelchar[] sigint offsetint opcodeint patchbytecount);

/**
 * Remove a memory patch (this also restores it to its previous state automatically)
 * 
 * @param siglabel            label of your sig
 * @return bool                true if removed, false if not found
 */
native bool MP_RemoveMemoryPatch(const char[] siglabel);

/**
 * Check if memory patch exists by label
 * 
 * @param siglabel            siglabel string
 * @return bool                true if exist
 */
native bool MP_MemoryPatchExists(const char[] siglabel);

/**
 * Check if existing memory patch was patched
 * 
 * @param siglabel            siglabel string
 * @return bool                true if patched, false if not found or if not patched
 */
native bool MP_IsPatched(const char[] siglabel);

/**
 * Patch all existing memory patches
 *
 * @return int                amount patched
 */
native int MP_PatchAll();

/**
 * Restores all patches to their original state
 *
 * @return int                amount restored
 */
native int MP_RestoreAll();

/**
 * Patch existing memory patch by sig label
 *
 * @return int                patch error code (see ApplyMemoryPatchError above)
 */
native int MP_Patch(const char[] siglabel);

/**
 * Restores existing memory patch by sig label
 *
 * @return bool                true if restored, false if not found
 */
native bool MP_Restore(const char[] siglabel);

/**
 * Returns amount of existing memory patches added to the plugin
 *
 * @return int                memory patch count
 */
native int MP_GetMemoryPatchCount();

/**
 * Returns amount of existing memory patches added to the plugin
 *
 * @return int                memory patch count
 */
native int MP_GetMemoryPatchSigLabel(int indexchar[] bufferint maxlen);

/**
 * AddMemoryPatch or AddMemoryPatchEx should be called here or later (This is called server_spawn event)
 *
 * @return void
 */
forward void MP_OnMemoryPatcherReady();

public 
KeyValues MP_GenerateGameDataKeyvalues(int ostypeint libtype, const char[] siglabelchar[] sigint offsetint[] opcodesint opcodecount)
{
    
KeyValues conf = new KeyValues("Games");
    
    
char game[32];
    
GetGameFolderName(gamesizeof(game));
    
conf.JumpToKey(gametrue);
    
conf.JumpToKey("Addresses"true);
    
    
char sigNameLabel[MP_PATCH_MAX_NAME_LENGTH 16];
    
Format(sigNameLabelsizeof(sigNameLabel), "%s_Label"siglabel);
    
conf.JumpToKey(sigNameLabeltrue);
    
    
char szOsType[16], szLibType[16];
    
MP_GetOSTypeName(ostypeszOsTypesizeof(szOsType));
    
MP_GetLIBTypeName(libtypeszLibTypesizeof(szLibType));
    
    
conf.JumpToKey(szOsTypetrue);
    
conf.SetString("signature"siglabel);
    
    
// Go back to SigLabel
    
conf.GoBack();
    
    
// Go back to Addresses
    
conf.GoBack();
    
    
// Go back to game version
    
conf.GoBack();
    
    
conf.JumpToKey("Signatures"true);
    
conf.JumpToKey(siglabeltrue);
    
conf.SetString("library"szLibType);
    
conf.SetString(szOsTypesig);
    
    
// Go back to Signatures
    
conf.GoBack();
    
    
// Go back to game version
    
conf.GoBack();
    
    
conf.JumpToKey("Offsets"true);
    
conf.JumpToKey("PatchOffset"true);
    
conf.SetNum(szOsTypeoffset);
    
    
// Go back to Offsets
    
conf.GoBack();
    
    
conf.JumpToKey("PatchByteCount"true);
    
conf.SetNum(szOsTypeopcodecount);
    
    
// Go back to Offsets
    
conf.GoBack();
    
    
// Go back to game version
    
conf.GoBack();
    
    
conf.JumpToKey("Keys"true);
    
    
char[] szOPcodes = new char[opcodecount 1]; // One OP code is 2 characters (NOP = 90) add 2 more characters to that '\x'
    
for (int i 0opcodecounti++)
        
Format(szOPcodes[4], opcodecount 4"\\x%x"opcodes[i]);
    
szOPcodes[opcodecount 4] = '\0';

    
conf.SetString("opcodes"szOPcodes);
    
conf.SetString("siglabel"siglabel);
    
conf.Rewind();
    return 
conf;
}

public 
void MP_ByteStringArrayToIntArray(const char[] byteStringArrayint[] opcodesint opcodeLength)
{
    
int byteStringLength strlen(byteStringArray);
#if defined DEBUG#
    
MP_Debug("(BYTE STRLEN: %d) (OPCODELENGTH: %d)"byteStringLengthopcodeLength);
#endif    
    
int opcode 0;
    for (
int i 0byteStringLengthi++)
    {
        if(
byteStringArray[i] == 'x')
        {
            
char szHex[3];
            
szHex[0] = byteStringArray[1];
            
szHex[1] = byteStringArray[2];
            
szHex[2] = '\0';
            
opcode StringToInt(szHex16);
            
opcodes[RoundToFloor(float(i) / 4.0)] = opcode;
#if defined DEBUG
            
MP_Debug("OPCODE: %x (%d)"opcodeopcode);
#endif
        
}
    }
    
    
int itMax opcodeLength 4;
    if(
byteStringLength itMax)
    {
#if defined DEBUG
        
MP_Debug("Not enough OPcodes to satisfy array, extending last op code (%x)"opcode);
#endif
        
for (int i RoundToFloor(float(byteStringLength) / float(4)); opcodeLengthi++)
        {
            
opcodes[i] = opcode;
#if defined DEBUG
            
MP_Debug("EXTENDED OPCODE: %x (%d)"opcodeopcode);
#endif
        
}
    }
}

public 
void MP_GetRestoreErrorCodeString(int errorCodechar[] bufferint maxlen)
{
    switch(
errorCode)
    {
        case 
MP_PATCH_RESTORE_ERROR_INDEX_NOT_FOUND:
        {
            
Format(buffermaxlen"Invalid patch index");
        }
        case 
MP_PATCH_RESTORE_ERROR_NOT_FOUND:
        {
            
Format(buffermaxlen"Not found");
        }
        case 
MP_PATCH_RESTORE_ERROR_IS_RESTORED:
        {
            
Format(buffermaxlen"Already restored");
        }
        case 
MP_PATCH_RESTORE_SUCCESS:
        {
            
Format(buffermaxlen"Success");
        }
    }
}

public 
void MP_GetApplyErrorCodeString(int errorCodechar[] bufferint maxlen)
{
    switch(
errorCode)
    {
        case 
MP_PATCH_APPLY_ERROR_NOT_FOUND:
        {
            
Format(buffermaxlen"Not found");
        }
        case 
MP_PATCH_APPLY_ERROR_IS_PATCHED:
        {
            
Format(buffermaxlen"Already patched");
        }
        case 
MP_PATCH_APPLY_ERROR_UNKNOWN_ADDRESS:
        {
            
Format(buffermaxlen"Invalid address");
        }
        case 
MP_PATCH_APPLY_ERROR_UNKNOWN_OFFSET:
        {
            
Format(buffermaxlen"Offset not found");
        }
        case 
MP_PATCH_APPLY_ERROR_UNKNOWN_COUNT:
        {
            
Format(buffermaxlen"Patch byte count not found");
        }
        case 
MP_PATCH_APPLY_SUCCESS:
        {
            
Format(buffermaxlen"Success");
        }
    }
}

public 
int MP_GetOSTypeByName(const char[] os)
{
    if(
StrContains(os"WIN32"false) != -1)
        return 
OSType_Windows;
    else if(
StrContains(os"LINUX"false) != -1)
        return 
OSType_Linux;
    else
        return 
OSType_Mac;
}

public 
void MP_GetOSTypeName(int ostypechar[] bufferint maxlen)
{
    switch(
ostype)
    {
        case 
OSType_Windows:
        {
            
Format(buffermaxlen"windows");
        }
        case 
OSType_Linux:
        {
            
Format(buffermaxlen"linux");
        }
        case 
OSType_Mac:
        {
            
Format(buffermaxlen"mac");
        }
        default:
        {
            
LogError("OSType: %d is invalid"ostype);
        }
    }
}

public 
void MP_GetLIBTypeName(int libtypechar[] bufferint maxlen)
{
    switch(
libtype)
    {
        case 
LIBType_Server:
        {
            
Format(buffermaxlen"server");
        }
        case 
LIBType_Engine:
        {
            
Format(buffermaxlen"engine");
        }
        default:
        {
            
LogError("LIBType: %d is invalid"libtype);
        }
    }
}

public 
bool MP_IsValidOSType(int ostype)
{
    return 
ostype >= && ostype OSType_MAX;
}

public 
bool MP_IsValidLIBType(int libtype)
{
    return 
libtype >= && libtype LIBType_MAX;
}

public 
void MP_Debug(const char[] messageany ...)
{
    
char szBuffer[254];
    
VFormat(szBuffersizeof(szBuffer), message2);
    
    
PrintToChatAll("%s %s"MP_DEBUG_PREFIXszBuffer);
    
PrintToServer("%s %s"MP_DEBUG_PREFIXszBuffer);
}

public 
SharedPlugin __pl_memorypatcher  =
{
    
name "memorypatcher",
    
file "memorypatcher.smx",
#if defined REQUIRE_PLUGIN
    
required 1
#else
    
required 0
#endif
};

#if !defined REQUIRE_PLUGIN
public __pl_memorypatcher_SetNTVOptional()
{    

}
#endif 

Sample plugin using natives:

This would do the same as csgo_movement_unlocker.smx + csgo_movement_unlocker.games.txt does
PHP Code:

public void OnPluginStart()
{
    if(
MP_GetServerOSType() != OSType_Invalid)
    {
        switch(
MP_GetServerOSType())
        {
            case 
OSType_Windows:
            {
                
MP_AddMemoryPatchEx(OSType_WindowsLIBType_Server"CGameMovement::WalkMove""\\xF3\\x0F\\x59\\xC0\\xF3\\x0F\\x59\\xD2\\xF3\\x0F\\x59\\xC9\\xF3\\x0F\\x58\\xD0\\xF3\\x0F\\x58\\xD1\\x0F\\x28\\xC2\\xF3\\x0F\\x51\\xC0\\xF3\\x0F\\x5E\\xD8"310x9042);
                
MP_Patch("CGameMovement::WalkMove");
            }
            case 
OSType_Linux:
            {
                
MP_AddMemoryPatchEx(OSType_LinuxLIBType_Server"CGameMovement::WalkMove""\\xF3\\x0F\\x10\\xF0\\x0F\\x28\\xC6\\xF3\\x0F\\x51\\xC6\\xF3\\x0F\\x5E\\xE8"270x9015);
                
MP_Patch("CGameMovement::WalkMove");
            }
        }
    }
}


public 
void OnPluginEnd()
{
    
// Checking if it exists is not required, plugin does this.
    
MP_RemoveMemoryPatch("CGameMovement::WalkMove");
}

public 
void MP_OnMemoryPatcherReady()
{
    switch(
MP_GetServerOSType())
    {
        case 
OSType_Windows:
        {
            
MP_AddMemoryPatchEx(OSType_WindowsLIBType_Server"CGameMovement::WalkMove""\\xF3\\x0F\\x59\\xC0\\xF3\\x0F\\x59\\xD2\\xF3\\x0F\\x59\\xC9\\xF3\\x0F\\x58\\xD0\\xF3\\x0F\\x58\\xD1\\x0F\\x28\\xC2\\xF3\\x0F\\x51\\xC0\\xF3\\x0F\\x5E\\xD8"310x9042);
            
MP_Patch("CGameMovement::WalkMove");
        }
        case 
OSType_Linux:
        {
            
MP_AddMemoryPatchEx(OSType_LinuxLIBType_Server"CGameMovement::WalkMove""\\xF3\\x0F\\x10\\xF0\\x0F\\x28\\xC6\\xF3\\x0F\\x51\\xC6\\xF3\\x0F\\x5E\\xE8"270x9015);
            
MP_Patch("CGameMovement::WalkMove");
        }
    }


Extra:
As it stands in the gamedata template. You are not required to enter every single OP code if you're simply patching all the data with a single OP code, if the amount of bytes are less than PatchByteCount, it will just keep on patching using the most recent OP code found in the "opcodes_<os>" keyvalue

DOWNLOAD

Wyświetl pełny artykuł

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
 Udostępnij

  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...