Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- ** Stack-based Gmod script enforcer bypass
- ** (c) TEAM METALSLAVE RAGE CO.
- **
- ** REVISION HISTORY
- **
- ** 00/00/0000 initial implementation in private release as MSSEB.DLL
- **
- ** MEET THE SCRIPT ENFORCER
- **
- ** Due to a large amount of cheaters in Gmod servers running scripts like aimbots, wallhacks
- ** and so on, Garry Jewman finally decided to implement something called the Script Enforcer.
- ** Unfortunately, like everything he's created, it didn't work out as well as he had hoped.
- **
- ** The function that blocks scripts is:
- **
- ** bool __thiscall CScriptEnforcer::CanLoadScript( void* );
- **
- ** THE BYPASS EXPLAINED
- **
- ** Before the script enforcer can block a script, it first notifies us in the console via
- ** Msg. Msg will pass through some formatting functions before eventually landing at whatever
- ** has been initialized as the SpewOutputFunc. We change the SpewOutputFunc on it and when it
- ** is called, we check for returns to the script enforcer and rewrite them so the program returns
- ** into code that is specified in our bypass DLL (see below).
- **
- ** When the Msg() call to the string is called, we catch it and redirect the code. When returning
- ** we pretend that the script was actually blocked by setting the "blocked" flag but returning 1,
- ** allowing the script to load.
- **
- ** This only works on scripts that the server has blocked entirely. It does not work on
- ** scripts that are different from the server's due to multiple CRC and MD5 checks that
- ** run in-game.
- **
- ** msseb.lib is cleared for public release.
- ** This source code is kept private for obvious reasons.
- **
- ** No thanks to FPS, because we are ugly and you suck!
- **
- */
- #include <stdio.h>
- #include <windows.h>
- #include "convar.h"
- #include "dbg.h"
- static SpewOutputFunc_t ZeOldSpewOutput = 0; // the old function that handles debug msgs.
- static UINT32 se_blockscriptaddr = 0; // the address where the script is blocked
- static ConVar seb_enable ( "seb_enable", "0", FCVAR_SERVER_CANNOT_QUERY, "enable dat scriptenforcer bypass mufugga");
- // GetStackPtr: obfuscated utility function for getting the stack pointer.
- // this doesn't return the *exact* stack frame, but hey, it works.
- static __stdcall UINT32* GetStackPointer() {
- UINT32 *stackptr;
- __asm {
- mov eax, esp
- mov stackptr, eax
- };
- return stackptr;
- }
- UINT8 SEBypass[20] = {
- 0x83, 0xC4, 0x08, // add esp, 8h
- 0xC6, 0x46, 0x44, 0x01, // set scriptenforce flag as blocked
- 0xB0, 0x01, // mov al, 1h to return TRUE
- 0x5E, // pop esi
- 0x81, 0xC4, 0x08, 0x01, 0x00, 0x00, // add esp, 108h
- 0xC2, 0x08, 0x00, // retn 8
- };
- /*
- ** ZeNewSpewOutput
- ** This is our new debug message handler. It just so happens that the
- ** Script Enforcer calls this before blocking a script.
- */
- static SpewRetval_t ZeNewSpewOutput( SpewType_t type, const char* msg )
- {
- if (strstr(msg,"ScriptEnforce:") && !strstr(msg, "CRC"))
- {
- Msg("ScriptEnforcer is attempting to block a script.\n");
- // get the stack pointer
- UINT32* theSp = GetStackPointer();
- Msg("ESP = %p\n", theSp);
- // If the script enforcer is trying to block something, step a few stack
- // frames and rewrite anything that's returning to the scriptenforcer
- // validation so it goes to the bypass code when retn is hit in Msg().
- // This verification is done to prevent false positives jumping into
- // code that crashes the thing hilariously.
- int isFound = 0;
- for (int i = 0; i < 0x1000; i ++)
- {
- if (theSp[i] == se_blockscriptaddr)
- {
- theSp[i] = (UINT32)SEBypass;
- Msg("*** ScriptEnforcer tried to block a script. Stack modified.\n");
- isFound = 1;
- break;
- }
- }
- if (!isFound) Msg("ERROR: Couldn't find the return address in the stack!\n");
- }
- // jump off to the old spew output function
- return ZeOldSpewOutput( type, msg );
- }
- void SEBypasser_Init()
- {
- // get the return address following the Msg()
- se_blockscriptaddr = (UINT32)GetModuleHandleA("client.dll");
- se_blockscriptaddr += 0x1CC22A;
- // get the original spew fcn using Msg (there's a pointer in there
- // to the output function). this is yet another module garry has no
- // control over so we can care less about what changes here.
- ZeOldSpewOutput = GetSpewOutputFunc();
- if (!ZeOldSpewOutput) {
- Msg("Old spew function was ZERO\n");
- return;
- }
- // Switch the output on us. All messages now go through our filter.
- SpewOutputFunc( ZeNewSpewOutput );
- // just let the user know that we initialized the module OK.
- Msg("*** msseb.lib built " __DATE__ " " __TIME__" ***\n");
- Msg("(c) 2010 TEAM METALSLAVE RAGE CO.\n");
- Msg("this software is provided to you without warranty or terms.\n");
- Msg("see msseb.txt for further information.\n");
- }
Add Comment
Please, Sign In to add comment