. _ . _ -|-------------------------/-//--|- // / _______________ | __ _____ | \_ _/_ \_____·/ \/ \ | / / / /_ / _ / t e a m | -/-----/\________/ \__\___/--/- 5 3 | /____/\____\ --- | . | wPx _ | _ | \ \\ -|--\\-\-------------------------|- Tutorials . Pack . Number . #13 Neocron Arcade - GameHacking Инструментарий: ArtMoney, TSearch - treinerov.net, www.artmoney.ru (или другой сканер памяти); Code-Caver by spookie - treinerov.net, www.team-x.ru (или другая программа для поиска Code Cave); Калькулятор и листочек с ручкой. Легенда: Подчеркнутые строки (=) - заголовок, Область выделенная квадратными скобками - справка, Облась выделенная тремя минусами (---) - код. Да, тема закатанная... "Сколько можно уже писать о том, как трейнеры делать?", а я отвечу в свое оправдание так - "Я ж не писал еще, мне прощается!" Короче решил я сделать трейнер для Neocron Arcade (далее NA), давно это еще было, в общем я его и сделал, сейчас где-то на www.Treinerov.net ну да это не важно, короче попросили меня еще и фильм на эту тему сделать, ну я сделал, руки-то откуда надо растут! И что-то приспичело меня сегодня тутор слепить, всё думал - надо, не надо и вот решился... Пару слов об игре ================= Обычно этот пункт у меня толще всех получается, но сегодня постараюсь много здесь не писать, так как толком об этой игре ничего не знаю. Neocron Arcade - обычная аркада, как ясно из названия, ничем не выделяющаяся из других подобных, бегаешь убиваешь монстров... ну ни какого разнообразия :( Знаю только одну особенность этой игры - эта игрушенция представляет собой рекламу, да, да именно рекламу одной такой онлайновой игры - Neocron. Сам в нее не играл, но судя по этой "рекламе" игра не очень, но не мне судить... короче идем дальше! Наша цель ========= Действовать буду как и при создании видео-тутора, буду ломать гранаты, не хочется останавливаться на подобных играх... да и работает там всё по одному принципу. Запустите игру и в нижнем левом углу вы увидите изображении гранаты со значением "3" - вот его-то мы и будем изменять. Game Hacking ============ Искать значение гранат советую с помощью ArtMoney, потому как быстро и удобно. Выбираем процесс нашей игры, затем нажимаем "Поиск" в строке значения вводим текущее значение гранат - 3 и нажимаем OK, далее программа будет искать это значение. Данное действие придется проделать несколько раз пока у вас не останется как можно меньше адресов. У меня остался только один адрес :) - 030E6A5C, естественно такой адрес у вас вряд ли будет, насколько я понимаю это DMA-игрушка, поэтому с моим адресом вам лучше не экспериментировать. [ DMA - динамичекое распределение памяти. Когда игра использует DMA, адреса в памяти, которые она использует, распределяются динамически в каждом случае, когда игре требуется следующий слот памяти и отдает этот слот какому-либо еще процессу, когда он в нем нуждается. В общем, на вашем компе столько всяких процессов, что очень уж маловероятно, что однажды полученные адреса в памяти, будут теми же при следующем запуске игры. Поэтому ваши трейнеры (обычно) работают только после того, как вы нашли нужные адреса, и только до момента перезапуска. Как только игра перезапущена, она затребует для себя новый набор адресов, делая старый набор бесполезным. ] Code-Cave Injection =================== Всё просто, как 5 копеек! Теперь перейдем к поиску инструкции, которая меняет значение в этом адресе, делается это всё очень просто, загружаем TSearch. Далее указываем процесс нашей игры "Open process", теперь в меню программы выбирем - AuthoHack -> Enable debugger, для активации отладчика TSearch и работы с AutoHack. [ Функция AutoHack сделана в TSearch специально для обмана DMA-игр и поиска инструкций, отвечающих за уменьшение интересующего нас значения. После того, как вы нажали Enable Debugger, программа TSearch как бы присоединяется к игре и если вы закроете окно TSearch, то игра тоже закроется. ] Откроем AutoHack и нажмем в панели инструментов на кнопку с изображением зеленой стрелки, для установки BreakPoint'а, или через меню - Edit -> Set BreakPoint. [ Брейкпоинт (breakpoint, бряк, BP...) - это точка остановки программы, т.е. тот адрес, на котором программа прервет свое выполнение, и мы попадем в отладчик (отладчик получит управление над прерванной программой). ] В появившемся окне в поле Address вводим адрес, найденный нами с помощью программы ArtMoney, в моем случае это - 030E6A5C и нажимаем "Set", для установки точки остановки. Чтобы наш BreakPoint сработал нужно изменить значение находящееся по этому адресу, для этого - не закрывая TSearch, перйдем в игру и бросим гранату, чтобы изменить значение. Далее минимизируем окно игры и переходим в окно AutoHack. И видим, что в главной области окна появилась запись с инструкциями ассемблера. [ Найдя инструкцию, изменяющую интересующее нас значение, вы можете заблокировать ее или другим словом заНОПить, то есть при обращении к этому адресу никаких действий выполнятся не будет, для того, чтобы это сделать достаточно поставить галочку (рожицу) слева от строки с кодом. Однако этот способ можно использовать не всегда, дело в том, что мы удаляем эту строку из кода, поэтому это может серьезно отразиться на функциональности игры, а именно программа можете вылететь. Я настоятельно советую не делать подобных вещей и делать трейнеры грамотно, ну хотя бы так, как описано в это статье. ] Любой геймхакер вам скажет, что знаю ассемблер вы сможете очень многое, ведь вы пишите свой код. Всё граничится только вашей фантазией и знаниями ассемблера. mov [ecx+0x1EC], eax - довольно простая инструкция и работает она просто: какому-то адресу [ecx+000001EC] мы присваиваем значение находящееся в регистре EAX. [ Регистры используются для хранения различных данных, значений, адресов в памяти, для арифметических операций и т.д. Процессор имеет непосредственный (прямой) доступ к регистрам. Регистры - это часть процессора, поэтому все операции с регистрами происходят внутри процессора, без обращения к оперативной памяти, что позволяет достичь максимального быстродействия. ] Вот область этого кода: --- 00430380 /$ 8B81 EC010000 MOV EAX,DWORD PTR DS:[ECX+1EC] 00430386 |. 83F8 01 CMP EAX,1 00430389 |. 7D 03 JGE SHORT Neocron_.0043038E 0043038B |. 32C0 XOR AL,AL 0043038D |. C3 RETN 0043038E |> 48 DEC EAX 0043038F |. 8981 EC010000 MOV DWORD PTR DS:[ECX+1EC],EAX 00430395 |. B0 01 MOV AL,1 00430397 \. C3 RETN --- Данный код был получен программой OllyDbg, для лучшего его вашего понимания я приведу код из TSearch, только основные инструкии: dec eax //данная инструкция вычитает единицу из значения хранящегося в регистре EAX mov [ecx+0x1EC],eax //на этой сроке мы остановились, ее действие было описано чуть выше [ Вот немного информации об инструкции DEC: Пример: DEC приёмник. Логика: Приёмник = Приёмник - 1. Описание: Эта команда отнимает от операнда приёмник единицу. Операнд приёмник, который может быть словом или байтом, ин терпретируется как двоичное число без знака. ] [ Информация об инструкции MOV (Moving, перемещение, помещение): Логика: Приёмник = Передатчик Описание: MOV копирует байт или слово из источника в приёмник. ] Всю нужную информацию мы собрали, хотя нет... Куда же мы будем писать наш код!? Место под наш код будем искать с помощью программы - Code-Caver. [ Code-Caver - небольшая программа представляющая собой сканер памяти. Данная программа ищет пустые области в памяти игры/программы с возможностью поиска Code Cave определенного размера и содержания (00h или NOP). ] Для этого в программе выбираем процесс игры и нажимаем "Find" теперь ждем, когда программа найдет Code Cave. [ Code-Cave - (code-код, cave-пещера :) спасибо Promt'у) - "дыры" в коде игры/программы не содержащие какого-либо необходимого/исполняемого кода, обычно заполнены либо нулями, либо НОПами. НОП или NOP (no operation) - означает что по данному адресу не будут выполнятся ни какие действия, этот адрес как бы пропускается, но работа программы на этом адресе не прерывается, а продолжается дальше. ] И так из появившегося списка адресов, я выбрал адрес - 00515050, прикольный такой адрес "округлый" такой, советую вам тоже его брать, также в нем много неиспользуемого программой пространство, а значет и нам для кода больше место будет. Начнем с написания скрипта, лучше всего это делать в программе TSearch, есть у этой программы такая замечательная "подпрограмма" называется EASYWRITE INTERPRETER, именно его-то мы и будем использовать. Так открываем это окошко и пишем следующий код (только без комментариев): --- offset 0043038F //это код игры, а именно адрес той самой инструкции, которая и уменьшает гранаты JMP 00515050 //с этого адреса мы делаем прыжок на наш код NOP //ставим NOP на свободный байт, т.к. инструкция mov [ecx+0x1EC],eax (6 байт) на 1 байт больше чем JMP 00515050 (5 байт). Если не поставить NOP то игра "вылетит" offset 00515050 //это наш код mov [ecx+000001EC],eax //восстанавливаем стандартную инструкцию, чтобы игра нормально функционировала jmp 00430394 //переходим обратно в код игры, но не на адрес 0043038F, а на 0043038F+5 (5 байт - занимает инструкция JMP 00515050) = 00430394. Получается мы переходим на NOP, следовательно игра работает дальше, если бы мы сделали переход на 0043038F, то игра вылетела... --- [ EASYWRITE INTERPRETER - это невероятно нужная вещь, с ее помощью вы можете писать какое-то подобие скриптов на ассемблере (с подсветкой синтаксиса), затем перевести этот код в шестнадцатеричный код, который, в будущем, понадобится при создании трейнера. Подробное описание этой функции TSearch вы можете найти в файле справки. ] Данный код пока ничего не дает, просто мы сделали основу для нашего будущего кода. Можете проверить этот код, предварительно нажмите кнопку "Check" для проверки скрипта на ошибки, затем "OK". Поставьте галочку напротив записи в Easy Write и перейдите в игру. Будем думать логично: сначала идет инструкция вычитания (dec eax) далее мы присваиваем значение регистра из которого вычитали некоему адресу [ecx+000001EC] ... Понятно? Нам нужно написать какую-то инструкцию, которая увеличивает, а не уменьшает регистр EAX. Думаю вы уже догадались, что нужна инструкция типа MOV, я решил записать это так: --- MOV EAX,0xA --- То есть я присваиваю регистру EAX значение 10 (A (HEX) = 10 (DEC) ), которое в последствии будет записано в адрес [ecx+000001EC]. Теперь модифицируем наш скрипт: --- offset 0043038F //это код игры, а именно адрес той самой инструкции, которая и уменьшает гранаты JMP 00515050 //с этого адреса мы делаем прыжок на наш код NOP //ставим NOP на свободный байт, т.к. инструкция mov [ecx+0x1EC],eax (6 байт) на 1 байт больше чем JMP 00515050 (5 байт). Если не поставить NOP то игра "вылетит" offset 00515050 //это наш код mov eax,0xA //присваиваем регистру EAX значение 10 mov [ecx+000001EC],eax //восстанавливаем стандартную инструкцию, чтобы игра нормально функционировала jmp 00430394 //переходим обратно в код игры, но не на адрес 0043038F, а на 0043038F+5 (5 байт - занимает инструкция JMP 00515050) = 00430394. Получается мы переходим на NOP, следовательно игра работает дальше, если бы мы сделали переход на 0043038F, то игра вылетела... --- По моим расчетам гранаты должны стать бесконечными и держаться всегда на уровне 10, так как после каждого броска количество гранат отнимается (dec eax), но затем наш код :) присваивает некоему адресу [ecx+000001EC] значение 10 (0A). Всё понятно? Если нет, то лучше попробовать всё с начала! Главное логически выстроить цепочку действий и понять что к чему, тогда будет понятно какой регистр и для чего служит в данном случае. Если вы решив поэкспериментировать остановились в TSearch на непонятной инструкции, не пугайтесь, а просто попробуйте поискать какие-нибудь учебники по ассемблеру и прочитать описание интересующей инструкции. Если вы думаете, что это ВСЁ... то вы ошибаетесь, есть еще один популярный способ обмана DMA-игр. DMA to Static ============== (перевод "DMA-адресов" в статический формат) Для того, чтобы использовать этот метод опять загрузим Code-Caver и найдем Code Cave в этой-же игре, мне понравился адрес 00507027, сейчас я объясню для чего это и как оно будет в скором времени работать. Данный метод, как мне кажется, используется чуть ли не в половине всех трейнеров, так как его очень легко осуществить, а работает этот метод по такому принципу, как мы знаем адрес который мы получили не так давно с помощью программы ArtMoney, не будет функционировать после перезагрузки игры, так как это DMA-игра, то есть идет динамическое распределение памяти по слотам, получается, что значения записываются туда, где сейчас ничего нет, и вероятность того, что адрес после перезагрузки игры совпадет с предыдущим, равна 0. Куда-то я не туда пошел... Короче идея заключается в том, чтобы записать в какой-то постоянный адрес, адрес необходимого нам значения, в нашем случае - гранат, мы как бы должны передать адрес. Сделать это довольно просто и сейчас я расскажу как именно... И так для начала дописываем в наш прежний скрипт такие строки: (просто добавьте строки в наш скрипт, без комментариев) --- offset 0x00507027 //в этот адрес, в будущем будет записан адрес где хранятся гранаты, мы будем всегда в курсе по какому они адресу hex 00000000 //чтобы не возникло никаких ошибок, очищаем пространство в которое будет записан адрес --- Так, так... пол дела, можно сказать, сделали идем дальше... У вас должен получиться такой скрипт: --- offset 0043038F //это код игры, а именно адрес той самой инструкции, которая и уменьшает гранаты JMP 00515050 //с этого адреса мы делаем прыжок на наш код NOP //ставим NOP на свободный байт, т.к. инструкция mov [ecx+0x1EC],eax (6 байт) на 1 байт больше чем JMP 00515050 (5 байт). Если не поставить NOP то игра "вылетит" offset 00515050 //это наш код mov [ecx+000001EC],eax //восстанавливаем стандартную инструкцию, чтобы игра нормально функционировала jmp 00430394 //переходим обратно в код игры, но не на адрес 0043038F, а на 0043038F+5 (5 байт - занимает инструкция JMP 00515050) = 00430394. Получается мы переходим на NOP, следовательно игра работает дальше, если бы мы сделали переход на 0043038F, то игра вылетела... offset 0x00507027 //в этот адрес, в будущем будет записан адрес где хранятся гранаты, мы будем всегда в курсе по какому они адресу hex 00000000 //чтобы не возникло никаких ошибок, очищаем пространство в которое будет записан адрес --- Как вы заметили инструкции, когда мы присваивали значение - нет, ведь мы работаем уже по другому принципу, обо всем по порядку. Существует такая интересная инструкция - LEA [ Описание инструкции: LEA Приёмник ¬ Источник Причем приемник всегда должен быть регистром ] Если простым русским языком, то с помощью этой команды мы сможем передать какому-нибудь регистру DMA-адрес с нашими гранатами, то есть то, что находится по адресу [ecx+000001EC]. Чтобы воспольковаться этой инструкцией (lea) модифицируем немного наш код: --- offset 0043038F //это код игры, а именно адрес той самой инструкции, которая и уменьшает гранаты JMP 00515050 //с этого адреса мы делаем прыжок на наш код NOP //ставим NOP на свободный байт, т.к. инструкция mov [ecx+0x1EC],eax (6 байт) на 1 байт больше чем JMP 00515050 (5 байт). Если не поставить NOP то игра "вылетит" offset 00515050 //это наш код lea edx, [ecx+000001EC] //как я писал, передаем регистру EDX какой-то адрес [ecx+000001EC], тот самый адрес, где хранится текущее число гранат mov [0x00507027],edx //а теперь записываем этот самый адрес, в специально отведенное нами место mov [ecx+000001EC],eax //восстанавливаем стандартную инструкцию, чтобы игра нормально функционировала jmp 00430394 //переходим обратно в код игры, но не на адрес 0043038F, а на 0043038F+5 (5 байт - занимает инструкция JMP 00515050) = 00430394. Получается мы переходим на NOP, следовательно игра работает дальше, если бы мы сделали переход на 0043038F, то игра вылетела... offset 0x00507027 //в этот адрес, в будущем будет записан адрес где хранятся гранаты, мы будем всегда в курсе по какому они адресу hex 00000000 //чтобы не возникло никаких ошибок, очищаем пространство в которое будет записан адрес --- Теперь пусть это игра хоть трижды использует динамическое распределение памяти (DMA), мы все равно будем знать где находятся гранаты. Дело в том, что после бросания гранаты адрес от которого мы отнимаем единицу записывается в наш адрес, который мы сможем впоследствии использовать. "А как это проверить?" - спросите вы у меня, да очень просто, активируем этот скрипт, затем переходим в игру и бросаем гранату, ее значение как вы видите уменьшилось, теперь минимизируем окно игры и перейдем обратно в TSearch. Теперь добавим новую запись в Cheat List программы TSearch, с такими параметрами: - Description: Granates Address - Address: 00507027 - Type: 4 bytes И нажимаем OK. Вы увидите какое-то большое значение, не пугайтесь... Просто это значение десятичное, а нам нужно шестнадцатеричное, сделайте перевод на Калькуляторе и добавьте новую запись, но уже с получившимся адресом, что вы получили в калькуляторе (шестнадцатеричное значение). После добавления в столбце Value этой записи вы должны увидит то самое значение гранат, если так, то вы все сделали верно, если нет, повторите снова. Теперь при создании трейнера можно просто считавать этот адрес и работать как с обычно игрой (без DMA), но это уже тема другото туториала. Послесловие =========== Надеюсь вы узнали что-то новое, а пока я пишу продолжение этой тутора у вас будет время потренироваться на практике, метод DMA to Static можете пока не трогать, но писать скрипты на TSearch - это вы уже должны уметь, по крайней мере я надеюсь, что вы что-то поняли, если нет... то я готов ответить на все интересующие вас вопросы. Связаться со мной можно либо посредством форума http://www.team-x.ru/xforum либо по e-mail. Так как это мой первый туториал для публики, то возможно я упустил какие-то моменты или проводил какие-то действия без должного внимания и что-то вы могли не понять... Словом буду совершенствоваться и совершенствоваться. Помимо своего тутора настоятельно рекомендую прочитать статью "Advanced Game Training by [sheep] a.k.a RECLAIM!", которая находится на сайте Team-X и переведена на русский язык Bаron'ом Gede, за что ему отдельное спасибо. Из этой статьи вы узнаете как работать с отладчиком, его краткое описание и много другого, также найдете описание еще одного метода "борьбы" с DMA. Приветы: Xipho, g-l-u-k, 6aНguT, specz, AllexY, LaZzy, XaVieR, MaGiC, Hellsp@wn, Kalian, Sfif, Button, spamer, Vinyl, The G, Razer, Grey(KU), S.N, Junic, ZaZa, SofT MANiAC, newborn, Red Bar0n, GHOST, [d1v0x], Amsterdam, lord_Phoenix, Gelios, Slip, RrayD, Vik, Avega, Z0oMiK, bugie и эвилчег. =) [ц] 2006, Guru.eXe/tPORt