Guest User

Untitled

a guest
Dec 16th, 2011
870
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. ** Stack-based Gmod script enforcer bypass
  3. ** (c) TEAM METALSLAVE RAGE CO.
  4. **
  5. ** REVISION HISTORY
  6. **
  7. ** 00/00/0000 initial implementation in private release as MSSEB.DLL
  8. **
  9. ** MEET THE SCRIPT ENFORCER
  10. **
  11. ** Due to a large amount of cheaters in Gmod servers running scripts like aimbots, wallhacks
  12. ** and so on, Garry Jewman finally decided to implement something called the Script Enforcer.
  13. ** Unfortunately, like everything he's created, it didn't work out as well as he had hoped.
  14. **
  15. ** The function that blocks scripts is:
  16. **
  17. ** bool __thiscall CScriptEnforcer::CanLoadScript( void* );
  18. **
  19. ** THE BYPASS EXPLAINED
  20. **
  21. ** Before the script enforcer can block a script, it first notifies us in the console via
  22. ** Msg. Msg will pass through some formatting functions before eventually landing at whatever
  23. ** has been initialized as the SpewOutputFunc. We change the SpewOutputFunc on it and when it
  24. ** is called, we check for returns to the script enforcer and rewrite them so the program returns
  25. ** into code that is specified in our bypass DLL (see below).
  26. **
  27. ** When the Msg() call to the string is called, we catch it and redirect the code. When returning
  28. ** we pretend that the script was actually blocked by setting the "blocked" flag but returning 1,
  29. ** allowing the script to load.
  30. **
  31. ** This only works on scripts that the server has blocked entirely. It does not work on
  32. ** scripts that are different from the server's due to multiple CRC and MD5 checks that
  33. ** run in-game.
  34. **
  35. ** msseb.lib is cleared for public release.
  36. ** This source code is kept private for obvious reasons.
  37. **
  38. ** No thanks to FPS, because we are ugly and you suck!
  39. **
  40. */
  41.  
  42. #include <stdio.h>
  43. #include <windows.h>
  44. #include "convar.h"
  45. #include "dbg.h"
  46.  
  47. static SpewOutputFunc_t ZeOldSpewOutput = 0; // the old function that handles debug msgs.
  48. static UINT32 se_blockscriptaddr = 0; // the address where the script is blocked
  49. static ConVar seb_enable ( "seb_enable", "0", FCVAR_SERVER_CANNOT_QUERY, "enable dat scriptenforcer bypass mufugga");
  50.  
  51.  
  52. // GetStackPtr: obfuscated utility function for getting the stack pointer.
  53. // this doesn't return the *exact* stack frame, but hey, it works.
  54. static __stdcall UINT32* GetStackPointer() {
  55.     UINT32 *stackptr;
  56.     __asm {
  57.         mov eax, esp
  58.         mov stackptr, eax
  59.     };
  60.     return stackptr;
  61. }
  62.  
  63. UINT8 SEBypass[20] = {
  64.     0x83, 0xC4, 0x08,           // add esp, 8h
  65.     0xC6, 0x46, 0x44, 0x01,     // set scriptenforce flag as blocked
  66.     0xB0, 0x01,                 // mov al, 1h to return TRUE
  67.     0x5E,                       // pop esi
  68.     0x81, 0xC4, 0x08, 0x01, 0x00, 0x00, // add esp, 108h
  69.     0xC2, 0x08, 0x00,           // retn 8
  70. };
  71.  
  72.  
  73. /*
  74. ** ZeNewSpewOutput
  75. ** This is our new debug message handler. It just so happens that the
  76. ** Script Enforcer calls this before blocking a script.
  77. */
  78.  
  79. static SpewRetval_t ZeNewSpewOutput( SpewType_t type, const char* msg )
  80. {
  81.     if (strstr(msg,"ScriptEnforce:") && !strstr(msg, "CRC"))
  82.     {
  83.         Msg("ScriptEnforcer is attempting to block a script.\n");
  84.         // get the stack pointer
  85.         UINT32* theSp = GetStackPointer();
  86.         Msg("ESP = %p\n", theSp);
  87.  
  88.         // If the script enforcer is trying to block something, step a few stack
  89.         // frames and rewrite anything that's returning to the scriptenforcer
  90.         // validation so it goes to the bypass code when retn is hit in Msg().
  91.         // This verification is done to prevent false positives jumping into
  92.         // code that crashes the thing hilariously.            
  93.         int isFound = 0;
  94.         for (int i = 0; i < 0x1000; i ++)
  95.         {
  96.             if (theSp[i] == se_blockscriptaddr)
  97.             {
  98.                 theSp[i] = (UINT32)SEBypass;
  99.                 Msg("*** ScriptEnforcer tried to block a script. Stack modified.\n");
  100.                 isFound = 1;
  101.                 break;
  102.             }
  103.         }
  104.         if (!isFound) Msg("ERROR: Couldn't find the return address in the stack!\n");
  105.     }
  106.  
  107.     // jump off to the old spew output function
  108.     return ZeOldSpewOutput( type, msg );
  109. }
  110.  
  111. void SEBypasser_Init()
  112. {
  113.     // get the return address following the Msg()
  114.     se_blockscriptaddr = (UINT32)GetModuleHandleA("client.dll");
  115.     se_blockscriptaddr += 0x1CC22A;
  116.  
  117.     // get the original spew fcn using Msg (there's a pointer in there
  118.     // to the output function). this is yet another module garry has no
  119.     // control over so we can care less about what changes here.
  120.     ZeOldSpewOutput = GetSpewOutputFunc();
  121.  
  122.     if (!ZeOldSpewOutput) {
  123.         Msg("Old spew function was ZERO\n");
  124.         return;
  125.     }
  126.  
  127.     // Switch the output on us. All messages now go through our filter.
  128.     SpewOutputFunc( ZeNewSpewOutput );
  129.  
  130.     // just let the user know that we initialized the module OK.
  131.     Msg("*** msseb.lib built " __DATE__ " " __TIME__" ***\n");
  132.     Msg("(c) 2010 TEAM METALSLAVE RAGE CO.\n");
  133.     Msg("this software is provided to you without warranty or terms.\n");
  134.     Msg("see msseb.txt for further information.\n");
  135. }
RAW Paste Data