Hi everyone,
I was wondering whether I was the only one running into problems with WoW crashing now and then when calling injected code out of process. My program is running for like 15 to maximum 30 minutes, calling lua functions for like thousands of times and then WoW says goodbye.
Hooking EndScene is not possible for me at the moment, due to the lack of knowledge for it.
I am using the following code (code from http://www.mmowned.com/forums/wow-me...ndexecute.html by vulcanaoc inside). Anyone using this or similar way from several threads in his application without trouble? Maybe beeing able to see something what I am obviously missing?
Code:
public void DoString(string command)
{
Console.WriteLine("DoString ...");
lock (lockObj)
{
if (SuspendAndBegin())
{
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");
ExecuteAndResume();
}
}
}
public bool SuspendAndBegin()
{
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)
{
Win32Wrapper.FreeMemory(magic.ProcessHandle, lpAsmStub);
return false;
}
ctx = SThread.GetThreadContext(hThread, CONTEXT_FLAGS.CONTEXT_CONTROL);
if (ctx.Eip <= 0)
{
SThread.ResumeThread(hThread);
Win32Wrapper.FreeMemory(magic.ProcessHandle, lpAsmStub);
return false;
}
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");
}
catch
{
magic.Asm.Clear();
Win32Wrapper.FreeMemory(magic.ProcessHandle, lpAsmStub);
SThread.ResumeThread(hThread);
return false;
}
return true;
}
public bool ExecuteAndResume()
{
ProcessThread wowMainThread = SThread.GetMainThread(magic.ProcessId);
IntPtr hThread = SThread.OpenThread(wowMainThread.Id);
try {
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);
magic.Asm.Clear();
Win32Wrapper.FreeMemory(magic.ProcessHandle, lpAsmStub);
SThread.ResumeThread(hThread);
return false;
}
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);
}
}
}
else
{
SThread.ResumeThread(hThread);
}
Win32Wrapper.FreeMemory(magic.ProcessHandle, lpAsmStub);
return true;
}