This is some code from my private bot Onyx. It currently injects the CLR into the target process, and does everything within the main thread (via an EndScene hook, credits to kynox for that code).
Keep in mind; EVERYTHING IN THIS CLASS MUST BE CALLED FROM WOW'S MAIN THREAD OR IT WILL FAIL! Got that? If something seems to 'not work' properly, then it's your own damned fault for not calling it from the main thread. No, I won't explain how to create an EndScene hook, you can go look it up. And no, I won't explain how to inject the CLR in WoW. You can look that up as well.
On to the nitty gritty!
Some of the stuff in this class are just quick wrappers. I do use WriteProcessMemory instead of Marshal.WriteX due to a bug that won't allow us to actually write to the targeted memory address. It happens randomly, but WPM works 100%.
I do NOT provide the code to patch the InvalidPtrCheck, or any code to get around it entirely. That's up to you. (You didn't seriously think I'd just 'hand' you this code, did you?)
The offsets are up to date. And if you do things properly, it works 100% without a single issue.
The code:
That's it. Yes, GetReturnVal<int>("GetTime()", 0); will return whatever GetTime() usually would return.Code:using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; using Onyx.WoW.Native; namespace Onyx.WoW { internal enum Luas { Lua_DoString = 0x0049AAB0, Lua_Register = 0x004998E0, Lua_GetTop = 0x0091A8B0, Lua_ToString = 0x0091ADC0, Lua_InvalidPtrCheck = 0x0046ED80, } public static class Lua { #region Delegates public delegate int ConsoleCommandCallback(); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate uint LuaRegisterCommand(string szName, IntPtr pFunc); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int RegisteredLuaCommandHandler(IntPtr pLuaState); #endregion private static readonly RegisteredLuaCommandHandler CommandParser = OnyxInputHandler; private static readonly LuaDoString DoStringHandler; private static readonly LuaGetTop GetTopHandler; private static readonly List<string> LuaValues = new List<string>(); public static readonly LuaRegisterCommand RegisterCommandHandler; private static readonly LuaToString ToStringHandler; static Lua() { Process.EnterDebugMode(); Win32.MemoryOpen(); RegisterCommandHandler = Utilities.RegisterDelegate<LuaRegisterCommand>((uint) Luas.Lua_Register); DoStringHandler = Utilities.RegisterDelegate<LuaDoString>((uint) Luas.Lua_DoString); GetTopHandler = Utilities.RegisterDelegate<LuaGetTop>((uint) Luas.Lua_GetTop); ToStringHandler = Utilities.RegisterDelegate<LuaToString>((uint) Luas.Lua_ToString); RegisterCommand("OnyxInput", CommandParser); } private static int OnyxInputHandler(IntPtr pLuaState) { LuaValues.Clear(); int num = GetTop(pLuaState); for (int i = 0; i < num; i++) { string tmp = ToString(pLuaState, i); LuaValues.Add(tmp); } return 0; } public static void DoString(string lua) { DoStringHandler(lua, "Onyx.lua", 0); } public static string[] GetReturnValues(string lua) { DoString(string.Format("OnyxInput({0})", lua)); return LuaValues.ToArray(); } public static T GetReturnVal<T>(string lua, uint retVal) { DoString(string.Format("OnyxInput({0})", lua)); object tmp; if (typeof(T) == typeof(bool)) { tmp = LuaValues[(int) retVal] == "1"; } else { tmp = (T) Convert.ChangeType(LuaValues[(int) retVal], typeof(T)); } return (T) tmp; } public static void RegisterCommand(string commandName, RegisteredLuaCommandHandler handler) { RegisterCommandHandler(commandName, WriteLuaCallback(Marshal.GetFunctionPointerForDelegate(handler))); return; } private static IntPtr WriteLuaCallback(IntPtr callbackPtr) { // You need to either patch the InvalidPtrCheck, or do something else to avoid the EndOfText scan // and check. Sorry, no code here. return callbackPtr; } private static int GetTop(IntPtr pLuaState) { return GetTopHandler(pLuaState); } private static string ToString(IntPtr pLuaState, int index) { return ToStringHandler(pLuaState, index + 1, 0); } #region Nested type: LuaDoString [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void LuaDoString(string lua, string fileName, uint pState); #endregion #region Nested type: LuaGetTop [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int LuaGetTop(IntPtr pLuaState); #endregion #region Nested type: LuaToString [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate string LuaToString(IntPtr pLuaState, int idx, int length); #endregion } }
The RegisterDelegate code (overloads removed for brevity)
Yes, I'm lazy.Code:public static T RegisterDelegate<T>(IntPtr address) where T : class { return Marshal.GetDelegateForFunctionPointer(address, typeof(T)) as T; }
Credits;
kynox - Creating the AWESOME CLR loader and EndScene hook we use in Onyx, and helping debug some things (even if you did *Something* which I shall not mention via TeamViewer).
jjaa - Helping debug stupid stuff, and the awesome code contribs.
Cypher - ******.
Other people I forgot to mention: Tough shit.
P.S; JuJu, you are specifically prohibited from using any of this code. Period. If I find this stuff in a commercial bot, you shall be ruined!
P.P.S: Yes, it IS injection. So if you're scared about it, DON'T USE IT!
P.P.P.S: No, this wasn't 'stolen' from the other thread. Ask anybody who has access to the Elite Memory Editing section. (Yes, we have one.)