private static unsafe IntPtr VirtualMachine__RunFunctionHook(VirtualMachine *virtualMachine, string functionName, int a3, int a4, int a5, int a6) { IntPtr num = IntPtr.Zero; try { string str = functionName; if (str == "config") { PreConfig?.Invoke(); num = VirtualMachine__RunFunction(virtualMachine, functionName, a3, a4, a5, a6); PostConfig?.Invoke(); } else { if (str == "main") { PreMain?.Invoke(); num = VirtualMachine__RunFunction(virtualMachine, functionName, a3, a4, a5, a6); PostMain?.Invoke(); } else { num = VirtualMachine__RunFunction(virtualMachine, functionName, a3, a4, a5, a6); } } } catch (Exception ex) { Trace.WriteLine($"Unhandled Exception in {nameof(Script)}.{nameof(VirtualMachine__RunFunctionHook)}!"); Trace.WriteLine(ex.ToString()); } return(num); }
private static unsafe IntPtr VirtualMachine__RunFunctionHook(VirtualMachine *virtualMachine, string functionName, int a3, int a4, int opLimit, int a6) { IntPtr num = IntPtr.Zero; try { if (functionName == "config") { PluginSystem.OnMapLoad(); } //Trace.WriteLine($"[RunFunction] {functionName} Start"); //if (Prefix.ContainsKey(functionName)) Prefix[functionName](); //if (functionName == "main") //{ // MainVM = virtualMachine; //} num = VirtualMachine__RunFunction(virtualMachine, functionName, a3, a4, opLimit, a6); //if (Postfix.ContainsKey(functionName)) Postfix[functionName](); //Trace.WriteLine($"[RunFunction] {functionName} End"); } catch (Exception ex) { Trace.WriteLine($"Unhandled Exception in {nameof(Script)}.{nameof(VirtualMachine__RunFunctionHook)}!"); Trace.WriteLine(ex.ToString()); } return(num); }
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); }
private unsafe static void HandleVarDump(List <string> commands) { Trace.WriteLine("=== VARIABLE DUMP ==="); if (commands.Count >= 1) { string text = commands[0]; Trace.WriteLine($"Variable: {text}"); VirtualMachine *ptr = *GameFunctions.GetThreadLocalStorage()->Jass.AsUnsafe()->VirtualMachine; Variable * ptr2 = (Variable *)ptr->GlobalTable->Lookup(text); if (ptr2 != null) { Trace.WriteLine($" - Value: {ptr2->Value}"); Trace.WriteLine($" - Type: {ptr2->Type}"); Trace.WriteLine($" - Type2: {ptr2->Type2}"); Trace.WriteLine($" - IsFunctionArgument: {ptr2->IsFunctionArgument}"); } else { Trace.WriteLine(" - NOT FOUND!"); } } else { Trace.WriteLine("Invalid usage"); Trace.WriteLine("Usage: SCDBG VARDUMP <name>"); } }
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!"); } } }
public unsafe static string VariableToString(Variable *variable, string split) { VirtualMachine *ptr = *GameFunctions.GetThreadLocalStorage()->Jass.AsUnsafe()->VirtualMachine; string text = $"{variable->Type}{split}{variable->Type2}{split}{variable->Name.AsString()}"; string text2; switch (variable->Type) { case JassType.IntegerArray: case JassType.RealArray: case JassType.StringArray: case JassType.HandleArray: case JassType.BooleanArray: { JassArray *ptr2 = (JassArray *)(void *)variable->Value; JassType jassType = (JassType)(variable->Type - JassType.Real); text = $"{text}{split}{jassType}"; if (ptr2 == null) { text += "[null]"; } else { try { text2 = "["; for (int i = 0; i < ptr2->Length; i++) { text2 += VariableValueToString(ptr2->Data[i * sizeof(IntPtr) / sizeof(IntPtr)], jassType); if (i < ptr2->Length - 1) { text2 += ", "; } } text += text2 + "]"; } catch { text += "[null]"; } } break; } default: text = $"{text}{split}{VariableValueToString(variable->Value, variable->Type)}"; break; } return(text); }
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); }
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); }
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!"); } }
unsafe public VirtualMachinePtr(VirtualMachine *pointer) { this.pointer = new IntPtr(pointer); }
public static unsafe IntPtr VirtualMachine__RunFunction(VirtualMachine * @this, string functionName, IntPtr a3, IntPtr a4, IntPtr a5, IntPtr a6) { return(ThisCall.Invoke <IntPtr>(GameAddresses.VirtualMachine__RunFunction, new IntPtr((void *)@this), functionName, a3, a4, a5, a6)); }
public static unsafe CodeResult VirtualMachine__RunCode(VirtualMachine * @this, IntPtr opCode, IntPtr a3, uint opLimit, IntPtr a5) { return(ThisCall.Invoke <CodeResult>(GameAddresses.VirtualMachine__RunCode, new IntPtr((void *)@this), opCode, a3, opLimit, a5)); }
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); }