Lua Class menu

User Tag List

Thread: Lua Class

Results 1 to 5 of 5
  1. #1
    Fraak's Avatar Member
    Reputation
    20
    Join Date
    Mar 2007
    Posts
    14
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Lua Class

    Hi all,

    Since its time I contributed something I wrote a class that handles LUA out of proccess, it uses the shynd's BlackMagic lib and the ThreadSusspender class also isnt mine (whoever wrote it sorry forgot to copy your name).

    Code:
        using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Threading;
    
    namespace Lua
    {
        class Lua
        {
            private uint State;
            private int LastArg;
            private Magic.BlackMagic _magic;
    
            private Process _processHandle;
            private Process ProcessHandle
            {
                get
                {
                    if (_processHandle == null)
                    {
                        _processHandle = Process.GetProcessById(_magic.ProcessId);
                    }
                    return _processHandle;
                }
            }
    
            private IntPtr _mainThread;
            private IntPtr MainThread
            {
                get
                {
                    if (_mainThread == IntPtr.Zero)
                    {
                        _mainThread = ThreadSusspender.GetWowsMainThread(ProcessHandle);
                    }
                    return _mainThread;
                }
            }
    
            private uint CurrentManager
            {
                get
                {
                    return _magic.ReadUInt(_magic.ReadUInt((uint)Offsets.ClientConnection) + (uint)Offsets.ClientManager);
                }
            }
    
            private enum Offsets : uint
            {
                ClientConnection = 0x011CA310,
                ClientManager = 0x000028A4,
    
                LuaDoString = 0x0077E060,
                LuaGetTop = 0x007AD6E0,
                LuaPushString = 0x007ADE10,
                LuaToNumber = 0x007ADB40,
                LuaToInteger = 0x007ADB80,
                LuaToString = 0x007ADBF0,
                LuaToUserdata = 0x007ADD20,
                LuaToBoolean = 0x007ADBC0,
                LuaGetState = 0x0077CCF0,
                LuaThreadLock = 0x012EA444,
            }
    
            public int CurrentArgument
            {
                get
                {
                    if (LastArg == 0)
                    {
                        return 1;
                    }
                    return LastArg;
                }
                set
                {
                    LastArg = value;
                }
            }
    
            public Lua(Magic.BlackMagic magic)
            {
                _magic = magic;
                State = GetState();
                LastArg = GetTop();
            }
    
            public void DoString(string lua)
            {
                Synchronize();
                uint codeCave = _magic.AllocateMemory(0x2048);
    
                _magic.WriteASCIIString(codeCave + 0x1024, lua);
    
                _magic.Asm.Clear();
                AsmUpdateCurrentManager();
    
                //_magic.Asm.AddLine("push {0}", State);
                _magic.Asm.AddLine("push {0}", 0);
                _magic.Asm.AddLine("mov eax, {0}", codeCave + 0x1024);
                _magic.Asm.AddLine("push eax");
                _magic.Asm.AddLine("push eax");
                _magic.Asm.AddLine("call {0}", (uint) Offsets.LuaDoString);
                _magic.Asm.AddLine("add esp, 0xC");
                _magic.Asm.AddLine("retn");
    
                _magic.Asm.InjectAndExecute(codeCave);
                _magic.FreeMemory(codeCave);
                ResumeMainThread();
            }
    
            public void CallMethod(uint method)
            {
                Synchronize();
                uint codeCave = _magic.AllocateMemory(0x1048);
                _magic.Asm.Clear();
                AsmUpdateCurrentManager();
                _magic.Asm.AddLine("push {0}", State);
                _magic.Asm.AddLine("call {0}", method);
                _magic.Asm.AddLine("add esp, 0x4");
                _magic.Asm.AddLine("retn");
    
                _magic.Asm.InjectAndExecute(codeCave);
                _magic.FreeMemory(codeCave);
                ResumeMainThread();
            }
    
            public int GetTop()
            {
                uint codeCave = _magic.AllocateMemory(0x1048);
                _magic.Asm.Clear();
                _magic.Asm.AddLine("push {0}", State);
                _magic.Asm.AddLine("call {0}", (uint) Offsets.LuaGetTop);
                _magic.Asm.AddLine("add esp, 0x4");
                _magic.Asm.AddLine("retn");
    
                uint result = _magic.Asm.InjectAndExecute(codeCave);
                _magic.FreeMemory(codeCave);
                return (int)result;
            }
    
            public void PushString(string str)
            {
                uint codeCave = _magic.AllocateMemory(0x2048);
                _magic.Asm.Clear();
    
                _magic.WriteASCIIString(codeCave + 0x1024, str);
                
                _magic.Asm.AddLine("push {0}", str.Length);
                _magic.Asm.AddLine("push {0}", codeCave + 0x1024);
                _magic.Asm.AddLine("push {0}", State);
                _magic.Asm.AddLine("call {0}", (uint) Offsets.LuaPushString);
                _magic.Asm.AddLine("add esp, 0xC");
                _magic.Asm.AddLine("retn");
    
                _magic.Asm.InjectAndExecute(codeCave);
                _magic.FreeMemory(codeCave);
    
                LastArg++;
            }
    
            public double ToNumber()
            {
                return ToNumber(GetArgument());
            }
    
            public double ToNumber(int argument)
            {
                uint codeCave = _magic.AllocateMemory(0x2048);
    
                _magic.Asm.Clear();
                _magic.Asm.AddLine("push {0}", argument);
                _magic.Asm.AddLine("push {0}", State);
                _magic.Asm.AddLine("call {0}", (uint)Offsets.LuaToNumber);
                _magic.Asm.AddLine("add esp, 0x8");
                _magic.Asm.AddLine("retn");
    
                uint result = _magic.Asm.InjectAndExecute(codeCave);
                double dbl;
    
                // TODO Not sure this is correct.
                try
                {
                    dbl = _magic.ReadDouble(result);
                }
                catch (Exception e)
                {
                    dbl = 0;
                }
                _magic.FreeMemory(codeCave);
                return (double) dbl;
            }
    
            public int ToInteger()
            {
                return ToInteger(GetArgument());
            }
    
            public int ToInteger(int argument)
            {
                uint codeCave = _magic.AllocateMemory(0x2048);
    
                _magic.Asm.Clear();
                _magic.Asm.AddLine("push {0}", argument);
                _magic.Asm.AddLine("push {0}", State);
                _magic.Asm.AddLine("call {0}", (uint)Offsets.LuaToInteger);
                _magic.Asm.AddLine("add esp, 0x8");
                _magic.Asm.AddLine("retn");
    
                uint result = _magic.Asm.InjectAndExecute(codeCave);
                _magic.FreeMemory(codeCave);
                return (int) result;
            }
    
            public override string ToString()
            {
                return ToString(GetArgument(), 50);
            }
    
            public string ToString(int argument, int length)
            {
                uint codeCave = _magic.AllocateMemory(0x2048);
    
                _magic.Asm.Clear();
                _magic.Asm.AddLine("push 0");
                _magic.Asm.AddLine("push {0}", argument);
                _magic.Asm.AddLine("push {0}", State);
                _magic.Asm.AddLine("call {0}", (uint)Offsets.LuaToString);
                _magic.Asm.AddLine("add esp, 0xC");
                _magic.Asm.AddLine("retn");
    
                uint result = _magic.Asm.InjectAndExecute(codeCave);
                _magic.FreeMemory(codeCave);
    
                try
                {
                    return _magic.ReadASCIIString(result, length);
                }
                catch (Exception e)
                {
                    return "";
                }
            }
    
            public object ToUserdata()
            {
                return ToUserdata(GetArgument());
            }
    
            public object ToUserdata(int argument)
            {
                uint codeCave = _magic.AllocateMemory(0x1024);
    
                _magic.Asm.Clear();
                _magic.Asm.AddLine("push {0}", argument);
                _magic.Asm.AddLine("push {0}", State);
                _magic.Asm.AddLine("call {0}", (uint) Offsets.LuaToUserdata);
                _magic.Asm.AddLine("add esp, 0x8");
                _magic.Asm.AddLine("retn");
    
                uint result = _magic.Asm.InjectAndExecute(codeCave);
                _magic.FreeMemory(codeCave);
                // Untested
                return _magic.ReadObject(result, typeof(object));
            }
    
            public bool ToBoolean()
            {
                return ToBoolean(GetArgument());
            }
    
            public bool ToBoolean(int argument)
            {
                uint codeCave = _magic.AllocateMemory(0x2048);
    
                _magic.Asm.Clear();
                _magic.Asm.AddLine("push {0}", argument);
                _magic.Asm.AddLine("push {0}", State);
                _magic.Asm.AddLine("call {0}", (uint) Offsets.LuaToBoolean);
                _magic.Asm.AddLine("add esp, 0x8");
                _magic.Asm.AddLine("retn");
    
                uint result = _magic.Asm.InjectAndExecute(codeCave);
                _magic.FreeMemory(codeCave);
                return (result == 1 ? true : false);
            }
    
            public uint GetState()
            {
                uint codeCave = _magic.AllocateMemory(0x1048);
    
                _magic.Asm.Clear();
                _magic.Asm.AddLine("call {0}", (uint)Offsets.LuaGetState);
                _magic.Asm.AddLine("retn");
    
                uint result = _magic.Asm.InjectAndExecute(codeCave);
                _magic.FreeMemory(codeCave);
                return result;
            }
    
            private int GetArgument()
            {
                if (LastArg < GetTop())
                {
                    LastArg++;
                }
                return LastArg;
            }
    
            private void ResumeMainThread()
            {
                ThreadSusspender.ResumeThread(MainThread);
            }
    
            private void AsmUpdateCurrentManager()
            {
                _magic.Asm.AddLine("mov EDX, {0}", CurrentManager);
                _magic.Asm.AddLine("FS mov EAX, [0x2C]");
                _magic.Asm.AddLine("mov EAX, [EAX]");
                _magic.Asm.AddLine("add EAX, 8");
                _magic.Asm.AddLine("mov [EAX], edx");
            }
    
            private void Synchronize()
            {
                while (_magic.ReadInt((uint)Offsets.LuaThreadLock) != 0)
                {
                    Thread.Sleep(0);
                }
                ThreadSusspender.SuspendThread(MainThread);
            }
        }
    
        // CREDITS NOT TO ME
        class ThreadSusspender
        {
            [DllImport("kernel32.dll", SetLastError = true)]
            public static extern uint SuspendThread(IntPtr hThread);
    
            [DllImport("kernel32.dll", SetLastError = true)]
            public static extern uint ResumeThread(IntPtr hThread);
    
            [DllImport("kernel32.dll", SetLastError = true)]
            private static extern IntPtr CreateToolhelp32Snapshot(uint dwFlags, uint th32ProcessID);
    
            [DllImport("kernel32.dll")]
            private static extern bool Thread32First(IntPtr hSnapshot, ref THREADENTRY32 lppe);
    
            [DllImport("kernel32.dll")]
            private static extern bool Thread32Next(IntPtr hSnapshot, ref THREADENTRY32 lppe);
    
            [DllImport("kernel32.dll")]
            private static extern IntPtr OpenThread(uint dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
    
            [DllImport("ntdll.dll")]
            private static extern uint NtQueryInformationThread(IntPtr handle, uint infclass, ref THREAD_BASIC_INFORMATION info, uint length, IntPtr bytesread);
    
            [DllImport("kernel32.dll")]
            private static extern bool CloseHandle(IntPtr handle);
    
            [DllImport("advapi32.dll", SetLastError = true)]
            static extern uint GetSecurityInfo(
            IntPtr handle,
            _SE_OBJECT_TYPE ObjectType,
            SECURITY_INFORMATION SecurityInfo,
            out IntPtr pSidOwner,
            out IntPtr pSidGroup,
            out IntPtr pDacl,
            out IntPtr pSacl,
            out IntPtr pSecurityDescriptor);
    
            [DllImport("advapi32.dll", SetLastError = true)]
            static extern uint SetSecurityInfo(
            IntPtr handle,
            _SE_OBJECT_TYPE ObjectType,
            SECURITY_INFORMATION SecurityInfo,
            out IntPtr pSidOwner,
            out IntPtr pSidGroup,
            out IntPtr pDacl,
            out IntPtr pSacl,
            out IntPtr pSecurityDescriptor);
    
            enum SECURITY_INFORMATION
            {
                DACL_SECURITY_INFORMATION,
                LABEL_SECURITY_INFORMATION,
                GROUP_SECURITY_INFORMATION,
                OWNER_SECURITY_INFORMATION,
                PROTECTED_DACL_SECURITY_INFORMATION,
                PROTECTED_SACL_SECURITY_INFORMATION,
                SACL_SECURITY_INFORMATION,
                UNPROTECTED_DACL_SECURITY_INFORMATION,
                UNPROTECTED_SACL_SECURITY_INFORMATION
            };
    
            enum _SE_OBJECT_TYPE
            {
                SE_UNKNOWN_OBJECT_TYPE = 0,
                SE_FILE_OBJECT,
                SE_SERVICE,
                SE_PRINTER,
                SE_REGISTRY_KEY,
                SE_LMSHARE,
                SE_KERNEL_OBJECT,
                SE_WINDOW_OBJECT,
                SE_DS_OBJECT,
                SE_DS_OBJECT_ALL,
                SE_PROVIDER_DEFINED_OBJECT,
                SE_WMIGUID_OBJECT,
                SE_REGISTRY_WOW64_32KEY,
                SE_OBJECT_TYPE,
            };
    
            [StructLayout(LayoutKind.Sequential)]
            private struct THREADENTRY32
            {
                public UInt32 dwSize;
                public UInt32 cntUsage;
                public UInt32 th32ThreadID;
                public UInt32 th32OwnerProcessID;
                public Int32 tpBasePri;
                public Int32 tpDeltaPri;
                public UInt32 dwFlags;
            }
    
            [StructLayout(LayoutKind.Sequential)]
            private struct THREAD_BASIC_INFORMATION
            {
                public bool ExitStatus;
                public IntPtr TebBaseAddress;
                public uint processid;
                public uint threadid;
                public uint AffinityMask;
                public uint Priority;
                public uint BasePriority;
            }
    
            private const uint TH32CS_SNAPTHREAD = 0x00000004;
            private const uint THREAD_SUSPEND_RESUME = 0x0002;
    
            public static IntPtr GetWowsMainThread(Process process)
            {
                uint THREAD_QUERY_INFORMATION = 0x1F03FF;
                IntPtr snaphandle = IntPtr.Zero;
                IntPtr threadhandle = IntPtr.Zero;
    
                snaphandle = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
                if (snaphandle != null)
                {
                    THREADENTRY32 info = new THREADENTRY32();
                    info.dwSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(THREADENTRY32));
                    bool morethreads = true;
                    bool found = false;
                    if (Thread32First(snaphandle, ref info))
                    {
                        while (morethreads && !found)
                        {
                            if (info.th32OwnerProcessID == process.Id)
                            {
                                threadhandle = OpenThread(THREAD_QUERY_INFORMATION, false, info.th32ThreadID);
                                if (threadhandle != null)
                                {
                                    THREAD_BASIC_INFORMATION tbi = new THREAD_BASIC_INFORMATION();
                                    NtQueryInformationThread(threadhandle, 0, ref tbi, (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(THREAD_BASIC_INFORMATION)), IntPtr.Zero);
    
                                    if (tbi.processid == process.Id)
                                    {
                                        IntPtr pSidOwner, pSidGroup, pDacl, pSacl, pSecurityDescriptor;
                                        GetSecurityInfo(threadhandle, _SE_OBJECT_TYPE.SE_UNKNOWN_OBJECT_TYPE, SECURITY_INFORMATION.UNPROTECTED_DACL_SECURITY_INFORMATION, out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor);
                                        SetSecurityInfo(threadhandle, _SE_OBJECT_TYPE.SE_UNKNOWN_OBJECT_TYPE, SECURITY_INFORMATION.UNPROTECTED_DACL_SECURITY_INFORMATION, out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSidOwner);
                                        break;
                                    }
                                }
                            }
    
                            info.dwSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(THREADENTRY32));
                            morethreads = Thread32Next(snaphandle, ref info);
                        }
                    }
                    CloseHandle(snaphandle);
                }
    
                return threadhandle;
            }
    
        }
    }
    NoMorePasting.com

    The DoScript method allows you to call all protected methods but you wont be able to get any return values from it.

    Hope anybody benefits from this and thnx for all the help from you guys!

    P.s.
    All suggestions are welcome.

    Lua Class
  2. #2
    Nesox's Avatar ★ Elder ★
    Reputation
    1280
    Join Date
    Mar 2007
    Posts
    1,238
    Thanks G/R
    0/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Oh looks very nice, rep cookies for u
    btw.. for supsending and resuming wows main thread you could do like this
    Code:
                ProcessThread wowMainThread = SThread.GetMainThread(_process.Id);
                IntPtr hThread = SThread.OpenThread(wowMainThread.Id);
    
                SThread.SuspendThread(hThread);
                SThread.ResumeThread(hThread);
    I used to do it like ure doing it but it's alot easier with the SThread class *alot less code too
    another tip for lua_dostring would be to send a message or some data to a socket so you know when to resume the main thread, ive had countless of chrashes because it resumes too early
    Code:
                uint sendmessage = (uint)GetProcAddress(LoadLibrary("User32.dll"), "SendMessageA");
                uint hwnd = (uint)Input.FindWindow(null, "Window Title");
                
                wow.Asm.AddLine("push {0}", 0x10);
                wow.Asm.AddLine("push {0}", 0x10);
                wow.Asm.AddLine("push {0}", 0xBEEF);
                wow.Asm.AddLine("push {0}", hwnd);
    
                wow.Asm.AddLine("mov eax, {0}", sendmessage);
                wow.Asm.AddLine("call eax");
                wow.Asm.AddLine("retn");
    and then you just catch it in a message loop
    Code:
            [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
            protected override void WndProc(ref Message m)
            {
                base.WndProc(ref m);
    
                if (m.Msg == 0xBEEF)
                {
                    Console.WriteLine("0xBEEF message recieved, resuming main thread!");
    
                    ProcessThread mainThread = SThread.GetMainThread(WowInstances[SelectedIndex].Id);
                    IntPtr hThread = SThread.OpenThread(mainThread.Id);
                    SThread.ResumeThread(hThread);
                }
            }
    Last edited by Nesox; 01-26-2009 at 04:42 PM.

  3. #3
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Repped for effort, nice too see someone new having a real go.

  4. #4
    SKU's Avatar Contributor
    Reputation
    306
    Join Date
    May 2007
    Posts
    565
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Repped both of you. Thanks alot for that awesome class and Nesox, that's exactly what I needed to stop my fisher from crashing. Thanks!

  5. #5
    Fraak's Avatar Member
    Reputation
    20
    Join Date
    Mar 2007
    Posts
    14
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thnx guys for the rep really appreciated!

    I am struggling here a bit to get a LUA state I am just hijacking wow's however evertime I call a method for that state the stack size increases. now this way I cant push any new values on the stack for upcomming calls to lua cfunctions becouse they will use the first couple of arguments on the stack every time.

    So I started reading in the Lua manual and i saw this:
    Lua uses a virtual stack to pass values to and from C. Each element in this stack represents a Lua value (nil, number, string, etc.).
    Whenever Lua calls C, the called function gets a new stack, which is independent of previous stacks and of stacks of C functions that are still active. This stack initially contains any arguments to the C function and it is where the C function pushes its results to be returned to the caller (see lua_CFunction).
    (Lua 5.1 Reference Manual)


    Now I am not really sure on how to procceed. I need to make sure that my stack gets "refreshed" but I dont know how to do that.


    any help would be apriciated.

Similar Threads

  1. Class Lua
    By Ozius in forum WoW Memory Editing
    Replies: 1
    Last Post: 07-01-2010, 12:45 AM
  2. [Lua] T10 Vendor for all Classes/Specs.
    By Ground Zero in forum WoW EMU General Releases
    Replies: 10
    Last Post: 02-12-2010, 04:56 PM
  3. POC Class to Manage Lua Calls and Return Values
    By Xarg0 in forum WoW Memory Editing
    Replies: 7
    Last Post: 01-22-2010, 10:38 AM
  4. Add Menu for Class? LUA++
    By Performer in forum WoW EMU Questions & Requests
    Replies: 0
    Last Post: 08-17-2008, 08:43 PM
All times are GMT -5. The time now is 03:36 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search