⬆️ ⬇️

We write a bot for MMORPG with assembler and draenei. Part 4

Hi% username%! So, let's continue writing our bot. From past articles, we learned how to find the address of the intercepted function for DirectX 9 and 11, execute arbitrary assembly code in the main thread of the game by hiding it from various methods of protection and receive information about the world. In other words, we can perform deliberate actions in the game. And for starters, I propose to learn how to move!



Disclaimer: The author is not responsible for your use of the knowledge gained in this article or damage as a result of their use. All information here is for educational purposes only. Especially for companies developing MMORPG, that would help them to fight with the bot. And, of course, the author of the article is not a botmaster, not a cheater, and never was.








For those who missed past articles, here is the content, and who read everything, we go further:

Content


  1. Part 0 - Search for a code injection point
  2. Part 1 - Implementing and executing third-party code
  3. Part 2 - Hide the code from prying eyes
  4. Part 3 - Under the gun World of Warcraft 5.4.x (Structures)
  5. Part 4 - Under the gun World of Warcraft 5.4.x (Moving)
  6. Part 5 - Under the gun World of Warcraft 5.4.x (Casting Fireball)


It just so happened that interaction with the game object and clicking on it in World of Warcraft is possible with a mouse click. But we will not simulate clicks, through WinApi, we will make it cooler. We intercept the place where the click is already processed by the game, like a click on the screen, and it will already be transferred from the coordinates of the screen to the coordinates of the game world. To begin with, we’ll get the addresses of some functions; we’ll really need them in the process; this is simply done with the help of our beloved IDA debugger:

public enum FunctionWow { ClntObjMgrGetActivePlayer = 0x39B615, ClntObjMgrGetActivePlayerObj = 0x4FC6, FrameScript_ExecuteBuffer = 0x4fd12, Spell_C_HandleTerrainClick = 0x38f129, FrameScript__GetLocalizedText = 0x414267, IsOutdoors = 0x414b53, UnitCanAttack = 0x41ad3c, CGUnit_C__InitializeTrackingState = 0x41fb57, CGWorldFrame__Intersect = 0x5eef7b, CGUnit_C__Interact = 0x8D01D0, } public enum ClickToMove { CTM = 0x420543, CTM_PUSH = 0xD0EEBC, CTM_X = 0xD0EF2C, CTM_Y = CTM_X+4, CTM_Z = CTM_Y+4, } 


Let's declare the WorldClick class:

 public enum ClickType { FaceTarget = 0x1, Face = 0x2, StopThrowsException = 0x3, Move = 0x4, NpcInteract = 0x5, Loot = 0x6, ObjInteract = 0x7, FaceOther = 0x8, Skin = 0x9, AttackPosition = 0xa, AttackGuid = 0xb, ConstantFace = 0xc, None = 0xd, Attack = 0x10, Idle = 0x13, } public static class WorldClick { public static void ClickTo(float x, float y, float z, ulong guid, ClickType action, float precision) { if (Mathf.Abs(x) < 0.1 && Mathf.Abs(y) < 0.1 && (Mathf.Abs(z) < 0.1 && (long)guid == 0L)) return; //  3  var positionAddress = Memory.Process.AllocateMemory(3 * sizeof(float)); //guid  ulong  8  var guidAddress = Memory.Process.AllocateMemory(sizeof(ulong)); // ,    ,   0.5f var precisionAddress = Memory.Process.AllocateMemory(sizeof(float)); if (positionAddress <= 0U || guidAddress <= 0U || precisionAddress <= 0U) return; Memory.Process.Write<ulong>(guidAddress, guid); Memory.Process.Write<float>(precisionAddress, precision); Memory.Process.Write<float>(positionAddress, x); Memory.Process.Write<float>(positionAddress + IntPtr.Size, y); Memory.Process.Write<float>(positionAddress + IntPtr.Size * 2, z); var asm = new[] { "call " + Memory.Process.GetAbsolute(FunctionWow.ClntObjMgrGetActivePlayer ), //     "test eax, eax", "je @out", //    -   "call " + Memory.Process.GetAbsolute(FunctionWow.ClntObjMgrGetActivePlayerObjAddress), "test eax, eax", "je @out", "mov edx, [" + precisionAddress + "]", "push edx", "push " + positionAddress, "push " + guidAddress, "push " + (int)action, "mov ecx, eax", // ClickToMove() "call " + Memory.Process.GetAbsolute((int)ClickToMove.CTM), "@out:", "retn" }; Memory.Hook.InjectAndExecute(asm); Memory.Process.FreeMemory(positionAddress); Memory.Process.FreeMemory(guidAddress); Memory.Process.FreeMemory(precisionAddress); } public static ClickType GetClickTypePush() { return (ClickToMoveType)Memory.Process.Read<int>((int)ClickToMove.CTM_PUSH, true); } public static Vector3 GetClickPosition() { return new Vector3( Memory.Process.Read<float>((int)ClickToMove.CTM_X, true), Memory.Process.Read<float>((int)ClickToMove.CTM_Y, true), Memory.Process.Read<float>((int)ClickToMove.CTM_Z, true)); } } 


That's all, now you can run across the expanses of Azeroth with:

 WorldClick.ClickTo(x,y,z, 0, ClickType.Move, 0.5f); 


That's all for today. You have learned a lot of interesting and practical. You can check it on some pirate, and if you are sure of your obfuscation of the code, then you can even run on the official server, with some starting record, so as not to risk it. After all, suddenly the staff of Blizzard, too, read Habr.


')

Source: https://habr.com/ru/post/251479/



All Articles