/// <summary> /// Execute the given LUA command inside WoW's MainThread /// </summary> /// <param name="command">lua command to run</param> public static void LuaDoString(string command) { AmeisenLogger.Instance.Log(LogLevel.VERBOSE, $"Doing string: Command [{command}]", "AmeisenCore"); // reserve memory for our command and write its bytes to the memory uint argCC = BlackMagic.AllocateMemory(Encoding.UTF8.GetBytes(command).Length + 1); BlackMagic.WriteBytes(argCC, Encoding.UTF8.GetBytes(command)); string[] asm = new string[] { $"MOV EAX, {(argCC)}", "PUSH 0", "PUSH EAX", "PUSH EAX", $"CALL {(Offsets.luaDoString)}", "ADD ESP, 0xC", "RETN", }; // add our hook job to be executed on hook HookJob hookJob = new HookJob(asm, false); AmeisenHook.AddHookJob(ref hookJob); // wait for our hook to return while (!hookJob.IsFinished) { Thread.Sleep(1); } AmeisenLogger.Instance.Log(LogLevel.VERBOSE, $"Command returned: Command [{command}]", "AmeisenCore"); BlackMagic.FreeMemory(argCC); // free our codecaves memory }
/// <summary> /// Target a GUID by calling WoW's clientGameUITarget function /// </summary> /// <param name="guid">guid to target</param> public static void TargetGUID(ulong guid, [CallerMemberName] string functionName = "") { AmeisenLogger.Instance.Log(LogLevel.DEBUG, $"TargetGUID: {guid}", "AmeisenCore", functionName); //BlackMagic.WriteUInt64(Offsets.localTargetGuid, guid); byte[] guidBytes = BitConverter.GetBytes(Convert.ToUInt64(guid)); string[] asm = new string[] { $"PUSH {BitConverter.ToUInt32(guidBytes, 4)}", $"PUSH {BitConverter.ToUInt32(guidBytes, 0)}", $"CALL {Offsets.clientGameUITarget}", "ADD ESP, 0x8", "RETN" }; // add our hook-job to process it HookJob hookJob = new HookJob(asm, false); AmeisenHook.AddHookJob(ref hookJob); // wait for the hook-job to return to us while (!hookJob.IsFinished) { Thread.Sleep(1); } }
/// <summary> /// Get Localized Text for command aka. read a lua variable /// </summary> /// <param name="command">lua command to run</param> /// <param name="variable">variable to read</param> /// <returns> /// Localized text for the executed functions /// return value, variable content or whatever /// you want to read. /// </returns> public static string GetLocalizedText(string command, string variable) { if (command.Length > 0 && variable.Length > 0) { // allocate memory for our command uint argCCCommand = BlackMagic.AllocateMemory(Encoding.UTF8.GetBytes(command).Length + 1); BlackMagic.WriteBytes(argCCCommand, Encoding.UTF8.GetBytes(command)); string[] asmDoString = new string[] { $"MOV EAX, {(argCCCommand) }", "PUSH 0", "PUSH EAX", "PUSH EAX", $"CALL {(Offsets.luaDoString)}", "ADD ESP, 0xC", "RETN", }; // allocate memory for our variable uint argCC = BlackMagic.AllocateMemory(Encoding.UTF8.GetBytes(variable).Length + 1); BlackMagic.WriteBytes(argCC, Encoding.UTF8.GetBytes(variable)); string[] asmLocalText = new string[] { $"CALL {(Offsets.clientObjectManagerGetActivePlayerObject)}", "MOV ECX, EAX", "PUSH -1", $"PUSH {(argCC)}", $"CALL {(Offsets.luaGetLocalizedText)}", "RETN", }; HookJob hookJobLocaltext = new HookJob(asmLocalText, true); ReturnHookJob hookJobDoString = new ReturnHookJob(asmDoString, false, hookJobLocaltext); // add our hook-job to be executed AmeisenHook.AddHookJob(ref hookJobDoString); // wait for our hook-job to return while (!hookJobDoString.IsFinished) { Thread.Sleep(1); } // parse the result bytes to a readable string string result = Encoding.UTF8.GetString((byte[])hookJobDoString.ReturnValue); AmeisenLogger.Instance.Log(LogLevel.VERBOSE, "DoString(" + command + "); => " + variable + " = " + result, "AmeisenCore"); // free our memory BlackMagic.FreeMemory(argCCCommand); BlackMagic.FreeMemory(argCC); return(result); } return(""); }