So I could use this method for executing DoString and GetLocalizedText without WoW crashing whole the time and without injecting DLLs?
Well the following code is working, my toon is dancing (DoEmote("dance") and GetLocalizedText seem to work too. Please evaluate my code and tell me what is missing, should be better (remember I am still learning things).
Code:
public String GetLocalizedText(string variable)
{
uint lpAsmStub, returnValue = 0, initialReturnValue = 0xDEADBEEF;
Magic.CONTEXT ctx;
lpAsmStub = Win32Wrapper.AllocateMemory(magic.ProcessHandle);
// my dirty addition
ProcessThread wowMainThread = SThread.GetMainThread(magic.ProcessId);
IntPtr hThread = SThread.OpenThread(wowMainThread.Id);
// --
if (SThread.SuspendThread(hThread) != uint.MaxValue)
{
// modified SThread
ctx = SThread.GetThreadContext(hThread, CONTEXT_FLAGS.CONTEXT_CONTROL);
// --
if (ctx.Eip > 0)
{
try
{
//This is for holding a return values
magic.Asm.AddLine("lpReturnValue dd 0x{0:X}", initialReturnValue);
//This is what gets executed
magic.Asm.AddLine("push 0x{0:X}", ctx.Eip);
magic.Asm.AddLine("pushfd");
magic.Asm.AddLine("pushad");
// my asm code
// magic.Asm.AddLine(fnInAsm);
uint codecave = magic.AllocateMemory();
ulong playerGuid = magic.ReadUInt64(
manager + (uint)Globals.Constants.Offsets.LOCAL_GUID);
uint playerPointer = Globals.ObjectManager.Instance.GetObjectByGuid(playerGuid);
magic.WriteASCIIString(codecave + 0x100, variable);
magic.Asm.AddLine("mov ecx, {0}", playerPointer);
magic.Asm.AddLine("push {0}", -1);
magic.Asm.AddLine("push {0}", codecave + 0x100);
magic.Asm.AddLine("call {0}", (uint)Globals.Constants.LuaFunctions.GET_LOCALIZED_TEXT);
// ---
magic.Asm.AddLine("mov [lpReturnValue], eax");
magic.Asm.AddLine("popad");
magic.Asm.AddLine("popfd");
magic.Asm.AddLine("retn");
magic.Asm.Inject(lpAsmStub);
magic.Asm.Clear();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Win32Wrapper.FreeMemory(magic.ProcessHandle, lpAsmStub);
SThread.ResumeThread(hThread);
return "";
}
ctx.ContextFlags = CONTEXT_FLAGS.CONTEXT_CONTROL;
ctx.Eip = lpAsmStub + 4; //skip over lpReturnValue data
if (SThread.SetThreadContext(hThread, ctx))
{
if (SThread.ResumeThread(hThread) != uint.MaxValue)
{
// WHY GOD WHY ... I KNOW ...
for (int i = 0; i < 2000; i++) //wait for up to 2 seconds for the function to return
{
if ((returnValue = magic.ReadUInt(lpAsmStub)) != initialReturnValue)
break;
Thread.Sleep(1);
}
}
}
}
}
Win32Wrapper.FreeMemory(magic.ProcessHandle, lpAsmStub);
String sResult = magic.ReadASCIIString(returnValue, 256);
return sResult;
}
public uint DoString(string command)
{
uint lpAsmStub, returnValue = 0, initialReturnValue = 0xDEADBEEF;
Magic.CONTEXT ctx;
lpAsmStub = Win32Wrapper.AllocateMemory(magic.ProcessHandle);
// my dirty addition
ProcessThread wowMainThread = SThread.GetMainThread(magic.ProcessId);
IntPtr hThread = SThread.OpenThread(wowMainThread.Id);
// --
if (SThread.SuspendThread(hThread) != uint.MaxValue)
{
// modified SThread
ctx = SThread.GetThreadContext(hThread, CONTEXT_FLAGS.CONTEXT_CONTROL);
// --
if (ctx.Eip > 0)
{
try
{
//This is for holding a return values
magic.Asm.AddLine("lpReturnValue dd 0x{0:X}", initialReturnValue);
//This is what gets executed
magic.Asm.AddLine("push 0x{0:X}", ctx.Eip);
magic.Asm.AddLine("pushfd");
magic.Asm.AddLine("pushad");
// my asm code
// magic.Asm.AddLine(fnInAsm);
uint space = magic.AllocateMemory(command.Length + 1);
magic.WriteASCIIString(space, command);
magic.Asm.AddLine("mov ecx, 0");
magic.Asm.AddLine("mov eax, " + space);
magic.Asm.AddLine("push ecx");
magic.Asm.AddLine("push eax");
magic.Asm.AddLine("push eax");
magic.Asm.AddLine("mov eax, " + (uint)Globals.Constants.LuaFunctions.DO_STRING);
magic.Asm.AddLine("call eax");
magic.Asm.AddLine("add esp, 0xC");
// ---
magic.Asm.AddLine("mov [lpReturnValue], eax");
magic.Asm.AddLine("popad");
magic.Asm.AddLine("popfd");
magic.Asm.AddLine("retn");
magic.Asm.Inject(lpAsmStub);
magic.Asm.Clear();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Win32Wrapper.FreeMemory(magic.ProcessHandle, lpAsmStub);
SThread.ResumeThread(hThread);
return 0;
}
ctx.ContextFlags = CONTEXT_FLAGS.CONTEXT_CONTROL;
ctx.Eip = lpAsmStub + 4; //skip over lpReturnValue data
if (SThread.SetThreadContext(hThread, ctx))
{
if (SThread.ResumeThread(hThread) != uint.MaxValue)
{
// WHY GOD WHY ... I KNOW ...
for (int i = 0; i < 2000; i++) //wait for up to 2 seconds for the function to return
{
if ((returnValue = magic.ReadUInt(lpAsmStub)) != initialReturnValue)
break;
Thread.Sleep(1);
}
}
}
}
}
Win32Wrapper.FreeMemory(magic.ProcessHandle, lpAsmStub);
return returnValue;
}
I love you vulcanaoc. Cannot +REP you anymore 
EDIT:
Strange thing is DoString works if I test it at the beginning of my application. But it ALWAYS crashes at "ResumeThread(IntPtr hThread)" when executing somewhere in the middle. Any ideas why? It's like calling something totally different.
What can I possibly be doing "wrong" during execution of my program that it causes DoString() from above to crash WoW and why does that work at the beginning of it?
Is it possible to check whether some other part of my code is doing something with WoW's main thread so that I should wait? Something like GetThreadStatus?