Guest User

Untitled

a guest
Jul 17th, 2018
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 23.98 KB | None | 0 0
  1. #pragma unmanaged
  2.  
  3. #include "stdafx.h"
  4.  
  5. #include <ctype.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9.  
  10. #include "patcher.h"
  11.  
  12. #pragma warn -8002 // Restarting compile using assembly
  13.  
  14. namespace NativeMethods
  15. {
  16.  
  17.     #include "uosl.cpp"
  18.    
  19.     #include "pipes.cpp"
  20.     #include "process.cpp"
  21.     #include "startup_info.cpp"
  22.     #include "security_attributes.cpp"
  23.    
  24.     static InterfaceToUOSL InterfaceToUOSL;
  25.  
  26.     bool PrintConstantConversions = false;
  27.  
  28.     bool DebugOutput = true;
  29.  
  30.     /*********************************************/
  31.     /*                                           */
  32.     /* FUNCTIONS RELATED WITH THE UODEMO SCRIPTS */
  33.     /*                                           */
  34.     /*********************************************/
  35.  
  36.     int ConvertEventNameToIndex(const char *Name)
  37.     {
  38.       for(int i = 0; i < 71; i ++)
  39.       {
  40.         register char *s = (char *)*((int *) 0x5EE458 + 2 * i + 1);
  41.         if(!strcmp(s, Name))
  42.           return i;
  43.       }
  44.       return -1;
  45.     }
  46.  
  47.     const unsigned int GetLastValidScriptByte()
  48.     {
  49.       return * (unsigned int * const) 0x611984;
  50.     }
  51.  
  52.     unsigned short *GetObfuscatedScriptByteTable()
  53.     {
  54.       return (unsigned short *) 0x610B40;
  55.     }
  56.  
  57.     bool IsObfuscatedScriptByte(unsigned short ObfuscatedWord)
  58.     {
  59.       const unsigned int LastValidScriptByte = GetLastValidScriptByte();
  60.       unsigned short *ObfuscatedScriptByteTable = GetObfuscatedScriptByteTable();
  61.       for(unsigned int i = 0; i < LastValidScriptByte; i ++)
  62.         for(unsigned int j = 0; j < 5; j ++)
  63.           if(ObfuscatedWord == *(ObfuscatedScriptByteTable + i * 5 + j))
  64.             return true;
  65.       return false;
  66.     }
  67.  
  68.     unsigned short ObfuscateScriptByte(unsigned char ScriptByte)
  69.     {
  70.       if(ScriptByte > (unsigned char) GetLastValidScriptByte())
  71.         return 0xFFFF;
  72.    
  73.       return *(GetObfuscatedScriptByteTable() + ScriptByte * 5);
  74.     }
  75.  
  76.     /* FUNCTIONS THAT EXTEND THE SCRIPT OBJECT */
  77.  
  78.     unsigned char GetCurrentScriptType()
  79.     {
  80.       unsigned char _AL;
  81.       __asm
  82.       {
  83.         mov edx, 0x63E128    // Points to the current script being compiled (Being-CompiledObject class)
  84.         mov ecx, [edx]
  85.         mov al, [ecx + 0x54] // See MyCompiledObjectConstructor...
  86.         mov _AL, al
  87.       }
  88.       return _AL; // 0 = Unknown, 1 = M, 2 = non-verified UOSL, 3 = verified UOSL
  89.     }
  90.  
  91.     void SetCurrentScriptType(unsigned char sType)
  92.     {
  93.       __asm
  94.       {
  95.         mov al, sType
  96.         mov edx, 0x63E128    // Points to the current script being compiled (Being-CompiledObject class)
  97.         mov ecx, [edx]
  98.         mov [ecx + 0x54], al // See MyCompiledObjectConstructor...
  99.       }
  100.     }
  101.  
  102.     unsigned int GetCurrentScriptExtraData()
  103.     {
  104.       unsigned int _EAX;
  105.  
  106.       __asm
  107.       {
  108.         mov edx, 0x63E128    // Points to the current script being compiled (Being-CompiledObject class)
  109.         mov ecx, [edx]
  110.         mov eax, [ecx + 0x55] // See MyCompiledObjectConstructor...
  111.         mov _EAX, eax
  112.       }
  113.       return _EAX;
  114.     }
  115.    
  116.     void SetCurrentScriptExtraData(unsigned int ExtraData)
  117.     {
  118.       __asm
  119.       {
  120.         mov eax, ExtraData
  121.         mov edx, 0x63E128    // Points to the current script being compiled (Being-CompiledObject class)
  122.         mov ecx, [edx]
  123.         mov [ecx + 0x55], eax // See MyCompiledObjectConstructor...
  124.       }
  125.     }
  126.  
  127.     /*********************************************/
  128.     /*                                           */
  129.     /* FUNCTIONS USED BY THE TOKEN CONVERTOR */
  130.     /*                                           */
  131.     /*********************************************/
  132.  
  133.     void FATAL(const char *ErrorMessage)
  134.     {
  135.       puts(ErrorMessage);
  136.       MessageBox(HWND_DESKTOP, ErrorMessage, "FATAL SCRIPT ERROR", MB_OK);
  137.     }
  138.  
  139.     bool isid(char c)
  140.     {
  141.       return c == '_' || isalnum(c);
  142.     }
  143.  
  144.     bool isidstart(char c)
  145.     {
  146.       return c == '_' || isalpha(c);
  147.     }
  148.  
  149.     bool iswhitespace(char c)
  150.     {
  151.       return c && (c <= ' '); // chars between 0x01 and 0x20 are considered whitespace
  152.     }
  153.  
  154.     bool isspecial(char c)
  155.     {
  156.       switch(c)
  157.       {
  158.         case '(':
  159.         case '<':
  160.         case '{':
  161.         case '[':
  162.         case ')':
  163.         case '>':
  164.         case '}':
  165.         case ']':
  166.         case '=':
  167.         case ':':
  168.         case ';':
  169.         case '!':
  170.         case ',':
  171.         case '*':
  172.         case '/':
  173.         case '%':
  174.         case '+':
  175.         case '-':
  176.         case '^':
  177.         case '&':
  178.         case '|':
  179.                   return true;
  180.       }
  181.       return false;
  182.     }
  183.  
  184.     char *GetRawScriptToken(char *Walker, char *Target, bool ObfuscateTarget)
  185.     {
  186.       // left trim
  187.       while(iswhitespace(*Walker))
  188.         Walker ++;
  189.  
  190.       // end reached?
  191.       if(*Walker == '\0')
  192.       {
  193.         memset(Target, 0, 8);
  194.         return Walker;
  195.       }
  196.       const char cWalker = *Walker;
  197.       const char *Next   = Walker + 1;
  198.       const char cNext   = *Next;
  199.  
  200.       // const?
  201.       if(isdigit(cWalker))
  202.       {
  203.         int size = 0;
  204.         if(cWalker != '0')
  205.           size = 10;
  206.         else if(isspecial(cNext) || iswhitespace(cNext))
  207.           size = 10;
  208.         else
  209.         {
  210.           switch(cNext)
  211.           {
  212.             case '0':
  213.             case '1':
  214.             case '2':
  215.             case '3':
  216.             case '4':
  217.             case '5':
  218.             case '6':
  219.             case '7':
  220.             case '8':
  221.             case '9': size = 10;
  222.                       break;
  223.             case 'd': size = 10;
  224.                       Walker += 2;
  225.                       break;
  226.             case 'b': size = 2;
  227.                       Walker += 2;
  228.                       break;
  229.             case 'o': size = 8;
  230.                       Walker += 2;
  231.                       break;
  232.             case 'x': size = 16;
  233.                       Walker += 2;
  234.                       break;
  235.           }
  236.           if(size == 0)
  237.             FATAL("INVALID CONST");      
  238.         }
  239.         char *TempTarget = Target;
  240.         while(*Walker && !iswhitespace(*Walker) && !isspecial(*Walker))
  241.         {
  242.           char Modifier = 0;
  243.           int isvalid = 0;
  244.           switch(size)
  245.           {
  246.             case 2:  isvalid = (*Walker >= '0' && *Walker <= '1');
  247.                      break;
  248.             case 8:  isvalid = (*Walker >= '0' && *Walker <= '7');
  249.                      break;
  250.             case 10: isvalid = (*Walker >= '0' && *Walker <= '9');
  251.                      break;
  252.             case 16: isvalid = (*Walker >= '0' && *Walker <= '9');
  253.                      if(!isvalid && (*Walker >= 'A' && *Walker <= 'F'))
  254.                      {
  255.                        isvalid = 1;
  256.                        Modifier = 'A' - '0' - 10;
  257.                      }
  258.                      if(!isvalid && (*Walker >= 'a' && *Walker <= 'f'))
  259.                      {
  260.                        isvalid = 1;
  261.                        Modifier = 'a' - '0' - 10;
  262.                      }
  263.                      break;
  264.           }
  265.           if(!isvalid)
  266.             FATAL("INVALID CHARACTER IN CONST");
  267.           *TempTarget ++ = (*Walker ++) - Modifier;
  268.         }
  269.         *TempTarget = '\0';
  270.         register const unsigned int copied = TempTarget - Target;
  271.         TempTarget = Target;
  272.         unsigned int constant = 0;
  273.         if(size == 10)
  274.         {
  275.           constant = atoi(TempTarget);
  276.         }
  277.         else
  278.         {
  279.           int shifter = size == 2 ? 1 : size == 8 ? 3 : 4;
  280.           while(*TempTarget != '\0')
  281.           {
  282.             constant = (constant << shifter) | (*TempTarget - '0');
  283.             TempTarget ++;
  284.           }
  285.         }
  286.  
  287.         if(PrintConstantConversions)
  288.           printf("Create Constant: %d,%d,%s-->%u\n", size, copied, Target, constant);
  289.  
  290.         if(ObfuscateTarget)
  291.         {
  292.           *(unsigned short *)(Target + 0) = 0x188F;
  293.           *(unsigned int   *)(Target + 2) = constant;
  294.         }
  295.         else
  296.           if(DebugOutput) sprintf(Target, "%u", constant);
  297.         return Walker;
  298.       }
  299.       else if(cWalker == '"')
  300.       {
  301.         // Copy until "
  302.         do
  303.         {
  304.           if(*Walker < ' ')
  305.             FATAL("Invalid character in string constant");
  306.           *Target ++ = *Walker ++;
  307.         }
  308.         while(*Walker != '\0' && *Walker != '"');
  309.         {
  310.           if(*Walker == '\0')
  311.             FATAL("EOL in string constant");
  312.           Walker ++;
  313.         }
  314.         *Target ++ = '"';
  315.         *Target    = '\0';
  316.         return Walker;
  317.       }
  318.       else if(cWalker == '/' && cNext == '/')
  319.       {
  320.         char *ClearFrom = Walker;
  321.  
  322.         // Scan until EOL
  323.         Walker += 2;
  324.         while(*Walker != '\0' && *Walker != '\n' && *Walker != '\r')
  325.           Walker ++;
  326.  
  327.         // Replace the comment by whitespace
  328.         // NOTE: this is needed to easily implement the BackwardsScanForSM_LPAREN code
  329.         while(ClearFrom < Walker)
  330.           *ClearFrom ++ = ' ';
  331.  
  332.         // We must return a valid token
  333.         return GetRawScriptToken(Walker, Target, ObfuscateTarget);
  334.       }
  335.       else if(cWalker == '/' && cNext == '*')
  336.       {
  337.         char *ClearFrom = Walker;
  338.  
  339.         // Scan until */
  340.         Walker += 2;
  341.         while(*Walker != '\0' && *(Walker + 0) != '*' && *(Walker + 1) != '/')
  342.           Walker ++;
  343.         if(*Walker)
  344.           Walker += 2;
  345.  
  346.         // Replace the comment by whitespace
  347.         // NOTE: this is needed to easily implement the BackwardsScanForSM_LPAREN code
  348.         while(ClearFrom < Walker)
  349.           *ClearFrom ++ = ' ';
  350.  
  351.         // We must return a valid token
  352.         return GetRawScriptToken(Walker, Target, ObfuscateTarget);
  353.       }
  354.       else if(isidstart(cWalker))
  355.       {
  356.         // Copy as long as we have a valid character
  357.         char *TempTarget = Target;
  358.         while(*Walker != '\0' && isid(*Walker))
  359.           *TempTarget ++ = *Walker ++;
  360.         *TempTarget = '\0';
  361.  
  362.     #pragma warn -8008  // Condition is always false
  363.         // Some id's are keywords, detect those
  364.         char PossibleByte = -1;
  365.         if(0);
  366.         else if(!strcmp(Target, "int") || !strcmp(Target, "integer"))
  367.           PossibleByte = 0x1D;
  368.         else if(!strcmp(Target, "string") || !strcmp(Target, "str"))
  369.           PossibleByte = 0x1E;
  370.         else if(!strcmp(Target, "ustring") || !strcmp(Target, "ust"))
  371.           PossibleByte = 0x1F;
  372.         else if(!strcmp(Target, "loc") || !strcmp(Target, "location"))
  373.           PossibleByte = 0x20;
  374.         else if(!strcmp(Target, "obj") || !strcmp(Target, "object"))
  375.           PossibleByte = 0x21;
  376.         else if(!strcmp(Target, "list"))
  377.           PossibleByte = 0x22;
  378.         else if(!strcmp(Target, "void"))
  379.           PossibleByte = 0x23;
  380.         else if(!strcmp(Target, "if"))
  381.           PossibleByte = 0x25;
  382.         else if(!strcmp(Target, "else"))
  383.           PossibleByte = 0x26;
  384.         else if(!strcmp(Target, "while"))
  385.           PossibleByte = 0x28;
  386.         else if(!strcmp(Target, "for"))
  387.           PossibleByte = 0x2A;
  388.         else if(!strcmp(Target, "continue"))
  389.           PossibleByte = 0x2C;
  390.         else if(!strcmp(Target, "break"))
  391.           PossibleByte = 0x2D;
  392.         else if(!strcmp(Target, "switch"))
  393.           PossibleByte = 0x2F;
  394.         else if(!strcmp(Target, "case"))
  395.           PossibleByte = 0x31;
  396.         else if(!strcmp(Target, "default"))
  397.           PossibleByte = 0x32;
  398.         else if(!strcmp(Target, "return"))
  399.           PossibleByte = 0x33;
  400.         else if(!strcmp(Target, "scriptvar") || !strcmp(Target, "shared") || !strcmp(Target, "member"))
  401.           PossibleByte = 0x36;
  402.         else if(!strcmp(Target, "function") || !strcmp(Target, "implement"))
  403.           PossibleByte = 0x34;
  404.         else if(!strcmp(Target, "on") || !strcmp(Target, "trigger"))
  405.           PossibleByte = 0x35;
  406.         else if(!strcmp(Target, "include") || !strcmp(Target, "inherits"))
  407.           PossibleByte = 0x37;
  408.         else if(!strcmp(Target, "prototype") || !strcmp(Target, "extern") || !strcmp(Target, "forward"))
  409.           PossibleByte = 0x38;
  410.         if(PossibleByte != -1)
  411.         {
  412.           if(PossibleByte == 0x35)
  413.           {
  414.             // NOTE: the following code will not work if you put a { in a comment before the actual {
  415.             bool  isPostName = false;
  416.             bool  ClearMode  = false;
  417.             char *Current    = Walker;
  418.             char *End        = Walker;
  419.             while(*End && *End != '{')
  420.             {
  421.               if(iswhitespace(*End))
  422.                 *End = ' ';
  423.               End ++;
  424.             }
  425.             if(DebugOutput) printf("TRIGGER BEFORE: $35%.*s\n", End - Walker, Walker);
  426.             while(Current < End)
  427.             {
  428.               if(ClearMode)
  429.               {
  430.                 if(*Current == ')')
  431.                   ClearMode = false;
  432.                 *Current = ' ';
  433.               }
  434.               else
  435.               {
  436.                 if(*Current == '(')
  437.                   if(isPostName)
  438.                   {
  439.                     ClearMode  = true;
  440.                     *Current = ' ';
  441.                   }
  442.                   else
  443.                     *Current = ' ';
  444.                 if(*Current == '<')
  445.                   if(isPostName)
  446.                     *Current = '(';
  447.                   else
  448.                     *Current = ' ';
  449.                 if(*Current == '>')
  450.                   if(isPostName)
  451.                     *Current = ')';
  452.                   else
  453.                     *Current = ' ';
  454.                 if(!isPostName)
  455.                 {
  456.                   char CurrentAsToken[384];
  457.                   GetRawScriptToken(Current, CurrentAsToken, false);
  458.                   if(ConvertEventNameToIndex(CurrentAsToken) >= 0)
  459.                     isPostName = true;
  460.                 }
  461.               }
  462.               Current ++;
  463.             }
  464.             if(DebugOutput) printf("TRIGGER AFTER:  $35%.*s\n", End - Walker, Walker);
  465.           }
  466.  
  467.           char NextToken[384];
  468.           if(PossibleByte >= 0x1D && PossibleByte <= 23) // id's are types if followed by a name
  469.             GetRawScriptToken(Walker, NextToken, false);
  470.           else if(PossibleByte == 0x25 || PossibleByte == 0x28 || PossibleByte == 0x2F)
  471.           {
  472.             GetRawScriptToken(Walker, NextToken, false);
  473.             if(!strcmp(NextToken, "("))
  474.               NextToken[0] = '_';
  475.             else
  476.               NextToken[0] = '0'; // if/for/while/switch are names if not followed by (
  477.           }
  478.           else if(PossibleByte == 0x31 || PossibleByte == 0x32)
  479.           {        
  480.             if(PossibleByte == 0x31)
  481.               GetRawScriptToken(GetRawScriptToken(Walker, NextToken, false), NextToken, false);
  482.             else
  483.               GetRawScriptToken(Walker, NextToken, false);
  484.             if(!strcmp(NextToken, ":"))
  485.               NextToken[0] = '_';
  486.             else
  487.               NextToken[0] = '0'; // case/default are names if not followed by :
  488.           }
  489.           else
  490.             NextToken[0] = '_'; //
  491.  
  492.           if(isidstart(*NextToken))
  493.           {
  494.             // Convert the token to an obfuscated script byte
  495.             if(ObfuscateTarget)
  496.               *(unsigned short *)Target = ObfuscateScriptByte(PossibleByte);
  497.           }
  498.           else
  499.           {
  500.             printf("Usage of an keyword as a variable: %s\n", Target);
  501.           }
  502.         }
  503.  
  504.         return Walker;
  505.       }
  506.     #pragma warn +8008  // Condition is always false
  507.  
  508.     #pragma warn -8008  // Condition is always false
  509.       // Convert the token to an obfuscated scriptbyte
  510.       Target[0] = cWalker;
  511.       Target[1] = '\0';
  512.       char Byte = -1;
  513.       if(0);
  514.       else if(strncmp(Walker, "++", 2) == 0)
  515.       {
  516.         strcat(Target, "+");
  517.         Walker ++;
  518.         Byte = 0x1B;
  519.       }
  520.       else if(strncmp(Walker, "--", 2) == 0)
  521.       {
  522.         strcat(Target, "-");
  523.         Walker ++;
  524.         Byte = 0x1C;
  525.       }
  526.       else if(strncmp(Walker, "&&", 2) == 0)
  527.       {
  528.         strcat(Target, "&");
  529.         Walker ++;
  530.         Byte = 0x18;
  531.       }
  532.       else if(strncmp(Walker, "||", 2) == 0)
  533.       {
  534.         strcat(Target, "|");
  535.         Walker ++;
  536.         Byte = 0x19;
  537.       }
  538.       else if(strncmp(Walker, "!=", 2) == 0)
  539.       {
  540.         strcat(Target, "=");
  541.         Walker ++;
  542.         Byte = 0x12;
  543.       }
  544.       else if(strncmp(Walker, "==", 2) == 0)
  545.       {
  546.         strcat(Target, "=");
  547.         Walker ++;
  548.         Byte = 0x11;
  549.       }
  550.       else if(strncmp(Walker, "<=", 2) == 0)
  551.       {
  552.         strcat(Target, "=");
  553.         Walker ++;
  554.         Byte = 0x15;
  555.       }
  556.       else if(strncmp(Walker, ">=", 2) == 0)
  557.       {
  558.         strcpy(Target, ">");
  559.         Walker ++;
  560.         Byte = 0x16;
  561.       }
  562.       else switch(*Walker)
  563.       {
  564.         case ':': if(!ObfuscateTarget)
  565.                     return Walker + 1;
  566.                   return GetRawScriptToken(Walker + 1, Target, true);
  567.         case '(': Byte = 0x02; break;
  568.         case ')': Byte = 0x03; break;
  569.         case '{': Byte = 0x07; break;
  570.         case '}': Byte = 0x08; break;
  571.         case '[': Byte = 0x09; break;
  572.         case ']': Byte = 0x0A; break;
  573.         case ',': Byte = 0x04; break;
  574.         case ';': Byte = 0x06; break;
  575.         case '!': Byte = 0x0B; break;
  576.         case '+': Byte = 0x0C; break;
  577.         case '-': Byte = 0x0D; break;
  578.         case '*': Byte = 0x0E; break;
  579.         case '/': Byte = 0x0F; break;
  580.         case '%': Byte = 0x10; break;
  581.         case '^': Byte = 0x1A; break;
  582.         case '<': Byte = 0x13; break;
  583.         case '>': Byte = 0x14; break;
  584.         case '=': Byte = 0x17; break;
  585.       }
  586.     #pragma warn +8008  // Condition is always false
  587.  
  588.       if(Byte == -1)
  589.         FATAL("Invalid token!");
  590.  
  591.       // Convert the token to an obfuscated script byte
  592.       if(ObfuscateTarget)
  593.         *(unsigned short *)Target = ObfuscateScriptByte(Byte);
  594.  
  595.       return ++ Walker;
  596.     }
  597.  
  598.     int BackwardsScanForSM_LPAREN(char *Walker)
  599.     {
  600.       if(*Walker == '(')
  601.         return 1;
  602.       if(*Walker != '"')
  603.         return 0;
  604.       while(*--Walker != '"');
  605.       return 0;
  606.     }
  607.  
  608.     /**********************************************************************/
  609.     /*                                                                    */
  610.     /* THE FOLLOWING MyXXX FUNCTIONS INTERCEPT DEMO CORE SCRIPT FUNCTIONS */
  611.     /*                                                                    */
  612.     /*                                                                    */
  613.     /**********************************************************************/
  614.  
  615.     typedef unsigned int (* __cdecl __LoadFileByCode)(unsigned int DirectoryCode, char *ScriptNameWithM, const char *OpenMode);
  616.     __LoadFileByCode LoadFileByCode = (__LoadFileByCode) 0x480877;
  617.  
  618.     // This function is and must be declared naked!!!
  619.     // Do not modify this function unless you know enough assembler
  620.     // And also unless you know deep down in your heart what "naked" functions are
  621.     int __declspec(naked) MyCompiledObjectConstructor()
  622.     {
  623.       __asm
  624.       {
  625.          // WARNING! This also relies on the PI_Compiler_CompiledObjectSize patch!!!
  626.          mov byte  ptr [ecx + 0x54], 0 // Is verified UOSL (3), non-verified UOSL (2) or M (1) or Unknown (0) file ?
  627.          mov dword ptr [ecx + 0x55], 0 // A free to use extra byte, currently unused
  628.  
  629.          mov eax, 0x426E20
  630.          jmp eax
  631.       }
  632.     }
  633.  
  634.     void HackTheStack(unsigned int return_address_to_detect, void *should_be, void *replace_by)
  635.     {
  636.         unsigned int _ESP;
  637.          __asm
  638.          {
  639.              mov _ESP, esp
  640.          }
  641.         void **Stack = (void **) _ESP;
  642.         while(true)
  643.         {
  644.         if((unsigned int) *Stack -- != return_address_to_detect)
  645.             if(*Stack == should_be)
  646.             break;
  647.         }
  648.         *Stack = replace_by;
  649.     }
  650.    
  651.     #define USE_ORIGINAL_ALGORITHM NULL
  652.    
  653.     char * __stdcall MyGetRawScriptToken(char *Walker, char *Target)
  654.     {
  655.       if(!*Walker)
  656.         return USE_ORIGINAL_ALGORITHM;
  657.       if(GetCurrentScriptType() == 0)
  658.       {
  659.         if(IsObfuscatedScriptByte(* (unsigned short *) Walker))
  660.           SetCurrentScriptType(1);
  661.         else if(!InterfaceToUOSL.IsActive())
  662.           SetCurrentScriptType(2);
  663.         else
  664.         {
  665.           SetCurrentScriptType(3);
  666.      
  667.           char *Result = InterfaceToUOSL.TranslateScript(Walker);    
  668.           if((!Result) || (int(Result) & 0x80000000))
  669.           {
  670.             char *ErrorMessage = (char *)(int(Result) & 0x7FFFFFFF);
  671.             MessageBox(HWND_DESKTOP, Result != NULL ? ErrorMessage : "Unknown error!", "JIT/UOSL", MB_OK);
  672.             *Walker = '\0';
  673.             return USE_ORIGINAL_ALGORITHM;
  674.           }
  675.    
  676.           SetCurrentScriptExtraData((unsigned int) Result);
  677.           HackTheStack(0x427015, Walker, Result);
  678.           Walker = Result;
  679.         }
  680.       }
  681.       if(GetCurrentScriptType() == 1)
  682.         return USE_ORIGINAL_ALGORITHM;
  683.       return GetRawScriptToken(Walker, Target, true);
  684.     }
  685.  
  686.     unsigned int __cdecl MyLoadScript(const unsigned int DirectoryCode, char *ScriptNameWithM, const char * const OpenMode)
  687.     {
  688.       unsigned int RetCode;
  689.  
  690.       // NOTE: do not modify the DirectoryCode and/or OpenMode
  691.       RetCode = LoadFileByCode(DirectoryCode, ScriptNameWithM, OpenMode);
  692.       if(RetCode)
  693.       {
  694.         if(DebugOutput) printf("%s -> M-file\n", ScriptNameWithM);
  695.         return RetCode;
  696.       }
  697.  
  698.       char NewFileName[MAX_PATH];
  699.       strcpy(NewFileName, "..\\scripts.uosl\\");
  700.       strcat(NewFileName, ScriptNameWithM);
  701.       strcpy(NewFileName + strlen(NewFileName) - 1, "uosl");
  702.  
  703.       RetCode = LoadFileByCode(DirectoryCode, NewFileName, OpenMode);
  704.       if(RetCode)
  705.       {
  706.         if(DebugOutput) printf("%s -> UOC-file\n", NewFileName);
  707.         return RetCode;
  708.       }
  709.  
  710.       //
  711.       if(DebugOutput) printf("%s > Failure!\n", NewFileName);
  712.       return NULL;
  713.     }
  714.  
  715.     int __cdecl MyBackwardsScanForSM_LPAREN(char *Walker, int)
  716.     {
  717.       if(GetCurrentScriptType() == 1)
  718.       {
  719.         int _EAX;
  720.         // Use the demo's code to handle the M files
  721.         __asm
  722.         {
  723.           push 2
  724.           push Walker
  725.           mov  eax, 0x42B1B0
  726.           call eax
  727.           add  esp, 8
  728.           mov _EAX, eax
  729.         }
  730.         return _EAX;
  731.       }
  732.  
  733.       return BackwardsScanForSM_LPAREN(Walker);
  734.     }
  735.  
  736.     PATCHINFO PI_Compiler_CompiledObjectSize =
  737.     {
  738.       0x426EF4,
  739.      2, {0x6A, 0x54},
  740.      2, {0x6A, 0x59},
  741.     };
  742.  
  743.     PATCHINFO PI_Compiler_CompiledObjectConstructor =
  744.     {
  745.       0x426F1A,
  746.      5, {0xE8, 0x01, 0xFF, 0xFF, 0xFF},
  747.      5, {0xE8, 0x00, 0x00, 0x00, 0x00},
  748.     };
  749.  
  750.     PATCHINFO PI_Intercept_LoadScript =
  751.     {
  752.       0x426217,
  753.      5, {0xE8, 0x5B, 0xA6, 0x05, 0x00},
  754.      5, {0XE8, 0x00, 0x00, 0x00, 0x00},
  755.     };
  756.  
  757.     PATCHINFO PI_Intercept_GetRawScriptToken =
  758.     {
  759.       0x428407,
  760.      19, {0x66, 0xB9, 0x00, 0x00, 0x66, 0x39, 0x08, 0x75, 0x05, 0xE8, 0xEB, 0xF5, 0x0B, 0x00, 0xE8, 0xC6, 0x87, 0x19, 0x00},
  761.      19, {0xFF, 0x75, 0x0C, 0xFF, 0x75, 0x08, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x09, 0xC0, 0x0f, 0x85, 0xBF, 0x01, 0x00, 0x00},
  762.     };
  763.  
  764.     PATCHINFO PI_Intercept_HandleBackwardsScanForSM_LPAREN =
  765.     {
  766.       0x42A2F9,
  767.      11, {0x6A, 0x02, 0x8B, 0x55, 0x0C, 0x52, 0xE8, 0xAC, 0x0E, 0x00, 0x00},
  768.      11, {0x6A, 0x02, 0x8B, 0x55, 0x0C, 0x52, 0xE8, 0x00, 0x00, 0x00, 0x00},
  769.     };
  770.  
  771.  
  772.     void Initialize_jit()
  773.     {
  774.         // Prepare the patches
  775.         SetRel32_AtPatch(&PI_Compiler_CompiledObjectConstructor, MyCompiledObjectConstructor);
  776.         SetRel32_AtPatch(&PI_Intercept_LoadScript, MyLoadScript);
  777.         SetRel32_AtRelPatch(&PI_Intercept_GetRawScriptToken, 6, MyGetRawScriptToken);
  778.         SetRel32_AtRelPatch(&PI_Intercept_HandleBackwardsScanForSM_LPAREN, 6, MyBackwardsScanForSM_LPAREN);
  779.  
  780.         // Apply the patches
  781.         Patch(&PI_Compiler_CompiledObjectSize);
  782.         Patch(&PI_Compiler_CompiledObjectConstructor);
  783.         Patch(&PI_Intercept_LoadScript);
  784.         Patch(&PI_Intercept_GetRawScriptToken);
  785.         Patch(&PI_Intercept_HandleBackwardsScanForSM_LPAREN);
  786.     }
  787. }
Add Comment
Please, Sign In to add comment