Пишем бот для MMORPG с ассемблером и дренейками. Часть 1
Привет, %username%! И так, продолжим написание нашего бота. Сегодня мы внедрим наш код в игровой процесс (не без помощи ассемблера), а позже позаботимся и о том, что бы его было не так просто найти, ведь наказывают не за то что жульничаешь, а за то что попался. И если быть до конца честным то даже не совсем в сам процесс игры будем его внедрять, да и 1 раз только за весь жизненный цикл.
Но обо всем по порядку, так что жду Вас под катом!
Disclaimer: Автор не несет ответственности за применение вами знаний полученных в данной статье или ущерб в результате их использования. Вся информация здесь изложена только в познавательных целях. Особенно для компаний разрабатывающих MMORPG, что бы помочь им бороться с ботоводами. И, естественно, автор статьи не ботовод, не читер и никогда ими не был.
Как вы помните из прошлой статьи, мы нашли адрес нашей DirectX функции EndScene и считали 5 первых ее байт. Если подзабыли, то вот содержание, если нет, то читайте что будем с ними делать:
Содержание
Часть 0 — Поиск точки внедрения кода
Часть 1 — Внедрение и исполнение стороннего кода
Часть 2 — Прячем код от посторонних глаз
Часть 3 — Под прицелом World of Warcraft 5.4.x (Структуры)
Часть 4 — Под прицелом World of Warcraft 5.4.x (Перемещение)
Часть 5 — Под прицелом World of Warcraft 5.4.x (Кастуем фаерболл)
1. Намечаем план внедрения
Сегодня мы внедрим наш код в эту функцию без ущерба для нее самой. Ниже я покажу как это будет происходить: HookAddress — это адрес на выделенную память в процессе игры с помощью WinApi функции VirtualAllocEx из kernel32.dll
Address — это адрес в памяти DirectX функции EndScene или ChainSwap
OpCodes — это оригинальные опкоды функции и их нам нужно сохранить, т.к. в оригинале они будут изменены.
2. Операция внедрения
Что бы открыть процесс мы вызовем WinApi OpenProcess и разрешим отладку, а затем нам необходимо открыть главный поток, нашего процесса
var ProcessHandle = OpenProcess (processId);
Process.EnterDebugMode ();
var dwThreadId = Process.GetProcessById (dwProcessId).Threads[0].Id;
var ThreadHandle = OpenThread (0×1F03FF, false, (uint)dwThreadId);
var HookAddress = Memory.AllocateMemory (6000);
var argumentAddress1 = Memory.AllocateMemory (80);
Memory.WriteBytes (argumentAddress1, new byte[80]);
var argumentAddress2 = Memory.AllocateMemory (BufferSize);
Memory.WriteBytes (argumentAddress2, new byte[80]);
var resultAddress = Memory.AllocateMemory (4);
Memory.Write
return result; } В итоге у нас значения по адресам argumentAddress1 и argumentAddress2 должны стать нулями когда наша инъекция отработает. Если у вас много потоков которые вызывают InjectAndExecute, то нужно предусмотреть очередь, для этого я и использовал 80 байт размер, как его реализовать, подумайте сами. А в следующей статье, я покажу свою реализацию и как прятать наш код.