captmicro

Untitled

Mar 25th, 2011
824
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 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 __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. }
Add Comment
Please, Sign In to add comment