Ejemplo n.º 1
0
 public unsafe static void DumpFunctionToCSV(string name, string filename)
 {
     using (FileStream fileStream = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.Write))
         using (StreamWriter streamWriter = new StreamWriter(fileStream))
         {
             VirtualMachine *ptr  = *GameFunctions.GetThreadLocalStorage()->Jass.AsUnsafe()->VirtualMachine;
             HT_Node *       ptr2 = ptr->FunctionTable->Lookup(name);
             if (ptr2 != null)
             {
                 OpCode *value = (OpCode *)ptr2->Value;
                 string  text  = string.Empty;
                 int     num   = -1;
                 while (value[num].OpType != OpCodeType.EndFunction)
                 {
                     text = $"{text}0x{num + 1:X4}{ByteCodeToString(value + num, ";")}{Environment.NewLine}";
                     num++;
                 }
                 streamWriter.WriteLine(text);
                 Trace.WriteLine($"Function '{name}' dumped to '{filename}'");
             }
             else
             {
                 Trace.WriteLine($"Function '{name}' could not be found!");
             }
         }
 }
Ejemplo n.º 2
0
 public unsafe bool TryGetOpCodeFunctionName(OpCode *op, out string name)
 {
     while (op->OpType != OpCodeType.Function)
     {
         op += -1;
         if (op < SymbolTable->FirstOperation)
         {
             name = string.Empty;
             return(false);
         }
     }
     name = SymbolTable->StringPool->Nodes[op->Argument]->Value;
     return(true);
 }
Ejemplo n.º 3
0
        public unsafe static void DumpFunctionToTrace(string name)
        {
            VirtualMachine *ptr  = *GameFunctions.GetThreadLocalStorage()->Jass.AsUnsafe()->VirtualMachine;
            HT_Node *       ptr2 = ptr->FunctionTable->Lookup(name);

            if (ptr2 != null)
            {
                OpCode *value = (OpCode *)ptr2->Value;
                string  text  = string.Empty;
                int     num   = -1;
                while (value[num].OpType != OpCodeType.EndFunction)
                {
                    text = $"{text}0x{num + 1:X4}{ByteCodeToString(value + num, "\t")}{Environment.NewLine}";
                    num++;
                }
                Trace.WriteLine(text);
                Trace.WriteLine($"Function '{name}'");
            }
            else
            {
                Trace.WriteLine($"Function '{name}' could not be found!");
            }
        }
Ejemplo n.º 4
0
        private static unsafe CodeResult VirtualMachine__RunCodeHook(VirtualMachine *vm, OpCode *op, IntPtr a3, uint opLimit, IntPtr a5)
        {
            CodeResult result = VirtualMachine__RunCode(vm, op, a3, opLimit, a5);

            try
            {
                VirtualMachine__RunCodeCallback?.Invoke(vm, op, a3, opLimit, a5, result);
            }
            catch (Exception ex)
            {
                Trace.WriteLine($"Unhandled Exception in {nameof(Script)}.{nameof(VirtualMachine__RunCodeHook)}!");
                Trace.WriteLine(ex.ToString());
            }
            return(result);
        }
Ejemplo n.º 5
0
        private static unsafe CodeResult VirtualMachine__RunCodeHook(VirtualMachine *vm, OpCode *op, IntPtr a3, uint opLimit, IntPtr a5)
        {
            //string value = vm->TryGetOpCodeFunctionName(op, out string name) ? name : null;
            //if (value != null) Trace.WriteLine($"[RunCode] {name} Start");
            CodeResult result = VirtualMachine__RunCode(vm, op, a3, opLimit, a5);

            try
            {
                VirtualMachine__RunCodeCallback?.Invoke(vm, op, a3, opLimit, a5, result);
                //if (value != null) Trace.WriteLine($"[RunCode] {name} End");
            }
            catch (Exception ex)
            {
                Trace.WriteLine($"Unhandled Exception in {nameof(Script)}.{nameof(VirtualMachine__RunCodeHook)}!");
                Trace.WriteLine(ex.ToString());
            }
            return(result);
        }
Ejemplo n.º 6
0
        private unsafe static void Jass_VirtualMachine__RunCodeCallback(VirtualMachine *vm, OpCode *op, IntPtr a3, uint opLimit, IntPtr a5, CodeResult result)
        {
            if (result == CodeResult.Success || result == CodeResult.ThreadPause || result == CodeResult.ThreadSync)
            {
                return;
            }
            if (!vm->TryGetOpCodeFunctionName(op, out string text))
            {
                text = "unknown function";
            }
            string str = string.Empty;

            switch (result)
            {
            case CodeResult.OpLimit: str = $"[Debugger] |cffff0000Error|r: Op limit({opLimit}) exceeded in {text}."; break;

            case CodeResult.VariableUninitialized: str = $"[Debugger] |cffff0000Error|r: Uninitialized variable read in {text}."; break;

            case CodeResult.DivideByZero: str = $"[Debugger] |cffff0000Error|r: Divide by zero in {text}."; break;

            default: str = $"[Debugger] |cffff0000Error|r: Unknown error({result}) in {text}."; break;
            }
            Interface.GameUI->ChatMessage->WriteLine(str, Color.White, 60f);
            Trace.WriteLine(str);
        }
Ejemplo n.º 7
0
        public unsafe static string ByteCodeToString(OpCode *op, string split)
        {
            VirtualMachine *ptr    = *GameFunctions.GetThreadLocalStorage()->Jass.AsUnsafe()->VirtualMachine;
            string          text   = $"{split}0x{op->R1:X2}";
            OpCodeType      opType = op->OpType;

            if (opType == OpCodeType.GetArray)
            {
                text = $"{text}:{JassTypeToString((JassType)op->R1)}";
            }
            text = $"{text}{split}0x{op->R2:X2}";
            switch (op->OpType)
            {
            case OpCodeType.Literal:
            case OpCodeType.GetVar:
            case OpCodeType.Code:
                text = $"{text}:{JassTypeToString((JassType)op->R2)}";
                break;
            }
            text = $"{text}{split}0x{op->R2:X2}";
            switch (op->OpType)
            {
            case OpCodeType.Local:
            case OpCodeType.Global:
            case OpCodeType.Constant:
            case OpCodeType.PopFuncArg:
                text = $"{text}:{JassTypeToString((JassType)op->R3)}";
                break;
            }
            text = $"{text}{split}0x{(byte)op->OpType:X2}{split}{op->OpType}";
            switch (op->OpType)
            {
            case OpCodeType.Function:
            case OpCodeType.Local:
            case OpCodeType.Global:
            case OpCodeType.Constant:
            case OpCodeType.PopFuncArg:
            case OpCodeType.GetVar:
            case OpCodeType.GetArray:
            case OpCodeType.SetVar:
            case OpCodeType.SetArray:
            case OpCodeType.Native:
            case OpCodeType.JassCall:
                return(text + split + (*(ptr->SymbolTable->StringPool->Nodes + op->Argument * sizeof(StringNode *) / sizeof(StringNode *)))->Value);

            case OpCodeType.Literal:
                switch (op->R2)
                {
                case 5:
                    text = $"{text}{split}{Memory.Read<float>(new IntPtr(&op->Argument))}";
                    goto IL_2FC;

                case 6:
                    text = $"{text}{split}\"{(*(ptr->SymbolTable->StringPool->Nodes + op->Argument * sizeof(StringNode*) / sizeof(StringNode*)))->Value}\"";
                    goto IL_2FC;

                case 8:
                {
                    int argument = op->Argument;
                    if (argument != 0)
                    {
                        if (argument != 1)
                        {
                            text = $"{text}{split} = (boolean){argument}";
                        }
                        else
                        {
                            text = $"{text}{split} = true";
                        }
                    }
                    else
                    {
                        text = $"{text}{split} = false";
                    }
                    goto IL_2FC;
                }
                }
                text = $"{text}{split}{op->Argument}";
IL_2FC:
                return(text);
            }
            text = $"{text}{split}{op->Argument}";
            return(text);
        }