hlsdk

Untitled

Aug 25th, 2010
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.70 KB | None | 0 0
  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 UINT32 * __stdcall GetStackPointer() {
  55.     UINT32* crap ;
  56.     __asm {
  57.         mov eax, esp
  58.         mov crap, eax
  59.     };
  60.  
  61.     return crap;
  62. }
  63.  
  64. UINT8 SEBypass[20] = {
  65.         0x83, 0xC4, 0x08,                       // add esp, 8h
  66.         0xC6, 0x46, 0x44, 0x01,                 // set scriptenforce flag as blocked
  67.         0xB0, 0x01,                             // mov al, 1h to return TRUE
  68.         0x5E,                                   // pop esi
  69.         0x81, 0xC4, 0x08, 0x01, 0x00, 0x00,     // add esp, 108h
  70.         0xC2, 0x08, 0x00,                       // retn 8
  71. };
  72.  
  73.  
  74. /*
  75. ** ZeNewSpewOutput
  76. ** This is our new debug message handler. It just so happens that the
  77. ** Script Enforcer calls this before blocking a script.
  78. */
  79.  
  80. static SpewRetval_t ZeNewSpewOutput( SpewType_t type, const char* msg ) {
  81.  
  82.  
  83.     if (strstr(msg,"ScriptEnforce:") && !strstr(msg, "CRC")) {
  84.  
  85.         Msg("ScriptEnforcer is attempting to block a script.\n");
  86.         // get the stack pointer
  87.         UINT32* theSp = GetStackPointer();
  88.         Msg("ESP = %p\n", theSp);
  89.  
  90.         // If the script enforcer is trying to block something, step a few stack
  91.         // frames and rewrite anything that's returning to the scriptenforcer
  92.         // validation so it goes to the bypass code when retn is hit in Msg().
  93.         // This verification is done to prevent false positives jumping into
  94.         // code that crashes the thing hilariously.    
  95.         int isFound = 0;
  96.         for (int i = 0; i < 0x1000; i ++) {
  97.             if (theSp[i] == se_blockscriptaddr)   {
  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.  
  108.     // jump off to the old spew output function
  109.     return ZeOldSpewOutput( type, msg );
  110. }
  111.  
  112. void SEBypasser_Init() {
  113.  
  114.     // get the return address following the Msg()
  115.     se_blockscriptaddr = (UINT32)GetModuleHandleA("client.dll");
  116.     se_blockscriptaddr += 0x1CC22A;
  117.    
  118.  
  119.     // get the original spew fcn using Msg (there's a pointer in there
  120.     // to the output function). this is yet another module garry has no
  121.     // control over so we can care less about what changes here.
  122.     ZeOldSpewOutput = GetSpewOutputFunc();
  123.  
  124.     if (!ZeOldSpewOutput) {
  125.         Msg("Old spew function was ZERO\n");
  126.         return;
  127.     }
  128.  
  129.     // Switch the output on us. All messages now go through our filter.
  130.     SpewOutputFunc( ZeNewSpewOutput );
  131.  
  132.     // just let the user know that we initialized the module OK.
  133.     Msg("*** msseb.lib built " __DATE__ " " __TIME__" ***\n");
  134.     Msg("(c) 2010 TEAM METALSLAVE RAGE CO.\n");
  135.     Msg("this software is provided to you without warranty or terms.\n");
  136.     Msg("see msseb.txt for further information.\n");
  137. }
Add Comment
Please, Sign In to add comment