20110929

Статья про FPU.

Как и обещано, [ссылка]. :D

Вторая часть седьмого видеоурока - делаем спидхак для Crimsonland!

С разбегу - [ссылка]!

Во второй части я покажу, как делается взлом скорости ("быстро бегать") для замечательной аркады Crimsonland, попутно объясню значение пары новых ассемблерных команд, характерных только для данного типа взлома. А именно:

fld [eax] - загружает значение типа float (с плавающей точкой) в [математический сопроцессор] (он же FPU) для последующих операций над ним.
fstp [eax] - соответственно, выгружает результат обратно в регистр eax.

Как именно вся эта фигня работает нам знать не настолько важно. Нам будут встречаться конструкции вида:

fld [eax+1234]
fadd [edi] (то же, что и add)
fsub [esx] (то же, что и sub)
fstp [eax+1234]


Основная мысль заключается в том, что главный процессор не умеет работать с дробными числами (float), так что для этого существует процессор поменьше - сопроцессор, который умеет только это. Командой fld (float load) мы заставляем главный процессор скормить нужное нам число сопроцессору, дальше в нём происходят какие-то действия над числом (fadd, fsub и т.п.), после чего по команде fstp число грузится обратно в главный процессор. Очень похоже на code-injection, правда? :)

Наша задача - или вклиниться в действия над значением после его загрузки в сопроцессор (пример - на видео), или посмотреть, что происходит чуть раньше - скажем, какая разница в координатах прибавляется\убавляется, часто можно обнаружить некоторый множитель. Типа, идём шагом - координаты умножаются на единичку, бежим бегом - умножаются на пять (бежим впятеро быстрее, чем идём шагом). Механизм действий схож для большинства игр, т.к. практически все хранят координаты в типе float, но ньюансы встречаются - нет универсального решения.

Теорию про сопроцессор и сопутствующие ему команды я выложу тут.



20110925

Ещё немного чтива

Нашёл ещё один неплохой вводный курс по ассемблеру - [ссылка]. В нём используется flat assembler, он же fasm - один из синтаксисов этого языка. Надо сказать, что ассемблера существует достаточно дофига диалектов - есть fasm, masm, nasm, tasm, в общем - много вариантов. Между собой они различаются разными поддерживаемыми фичами и набором команд. Самый популярный - masm, или Macro Assembler производства Microsoft. Если будем писать что-то на ассемблере, то выберу я именно этот - под него пишется большинство статей и он обладает наиболее богатой документацией. :)

Не пугайтесь, что диалектов такая куча - мы не полезем в дебри, где они покажутся существенными, нам достаточно просто понимать код, который отладчик показывает, а это не так трудно.

20110924

Первая часть седьмого видеоурока, или знакомимся со структурами.

Итак!

Тянуть время дальше стало катастрофически лень, так что я быстренько сел и записал вводное видео. Простите, что так поздно, дела-дела. :)

В этом видео я постарался объяснить значение такой офигенно полезной штуки, как структура.
Это, если не обращаться к википедии и заумным книжкам, просто способ организовать какую-то информацию. Относительно игр нам надо просто понимать, что своя структура есть у каждого игрового объекта, для однотипных объектов она чаще всего одинаковая (структура "монстр" - у каждого монстра, "игрок" - у каждого игрока, "пуля" - у каждой пули и так далее), а при взломе помним самое главное - в памяти все значения конкретной структуры чаще всего хранятся рядышком, бывает что просто подряд. :D

Нам это может сильно помочь при поиске каких-то величин, которые на экране не отображаются и которые найти обычными способами довольно проблематично. Например, ломаем мы гоночки. В какой-то момент нам ВНЕЗАПНО очень захотелось найти массу нашей машины. Да-да, раз в игре есть хоть какая-то физика (а в современных играх для этого дела целые физические движки созданы) - то есть и масса и все основные законы. Все ведь помнят второй закон Ньютона из школьного курса физики? Если нет, то поясню: чем меньше будет масса нашей машины, тем быстрее она будет ускоряться. Так что на старте с машиной весом в 5 грамм мы всех уделаем. ^^

Проблема в том, что массу машины нигде на экране не написали (идиоты!), и вот тут-то мы и вспоминаем про то, что у каждой машины наверняка есть структура, а в этой структуре наверняка хранится и масса тоже. :)

Такие вот пироги. Смотрим, вникаем, запоминаем: [ссылка].


20110923

Следующие видеоуроки

Помните, что я указал в последнем видеоуроке? "Будем учиться быстро бегать и высоко прыгать". Это значит, что мы будем искать координаты игрока и работать с ними.

Проблема заключается в том, что просто так эти самые координаты не найдёшь, поэтому я разобью эту тему на несколько видео, в которых сначала пролью свет на несколько очень важных (и полезных!) штуковин, вместе научимся искать координаты и поломаем при этом пару-тройку игр. :)

Частей планируется 2-3, первая - про необходимые понятия и теорию, вторая - про "быстро бегать", ну а третья, очевидно, - про "высоко прыгать". Как пройдём это всё и материал более-менее усвоится - покажу, как делается "Rapid fire hack" - это когда мы из какого-то медленно стреляющего оружия будем стрелять аки из шестиствольного пулемёта - в общем, быстро, очень быстро!

На этом основной курс "как научиться ломать игры" будет в общем-то окончен, так что дальше буду выкладывать какие-то конкретные фичи (как найти то или иное труднодоступное для обычного поиска значение, более простой метод поиска указателей и т.п.), может быть коснусь темы снятия игровых защит - да, бывает и так, в современных играх - почти повсеместно.

Параллельно приступим к написанию трейнеров. Эта тема довольно объёмная и абстрактная - зависит она в основном от умения программировать. Всё ещё думаю, как к ней грамотно подойти, но какой-никакой план уже есть. :)

20110921

Видеоуроки по С++

Делюсь очень хорошим курсом из 60 видеоуроков (с комментариями на английском языке) по С++. Достойная штука для тех, кто хочет начать изучать плюсы, рекомендую! (:

[ссылка]

20110916

Шестой видеоурок, так сказать! :D

А если серьёзно - просто видеопояснение к [предыдущей записи] о Code-Injection. Ломаем таймер матча в Mortal Combat 4, а ещё - узнаём две новых команды ассемблера (совсем простеньких):

inc \ dec [регистр] - англ. increment (увеличение) \ decrement (уменьшение) - увеличивает или уменьшает содержимое [регистра] на единичку. Пример:

mov edi, 5 //кладём в edi пятёрочку
dec edi      //делаем магию!!

В итоге в edi будет лежать четыре. :)


В следующих двух видеоуроках будем учиться высоко (очень высоко!) прыгать и не менее быстро бегать. Оставайтесь на линии, Ваш звонок очень важен для нас! :D

[ссылка на урок]


Code-Injection: Подробности

В [пятом уроке] (и в четвёртом тоже ^^) мы рассматривали такую технику, как Code-Injection, или, если буквально, "инъекция кода". Давайте остановимся на этой штуке ещё немного - больно уж часто она используется. Больше скажу - одна из самых распостранённых техник взлома. :)

Итак. Представим, что имеется у нас вот такой гипотетический код игры:

Адрес   |  Команда      |    Комментарий
---------------------------------------------------------------------------------
0000000: mov eax, 3     //помещаем в регистр eax число "3"
0000001: sub eax, 1      //вычитаем из еах единичку
0000002: cmp eax, 0    //сравниваем еах с нулём
0000003: je "exit"         //если еах = 0, то выходим из игры
0000004: add eax, 2    //иначе прибавляем к еах двойку
0000005:
0000006:
0000007:
0000008:
0000009:
---------------------------------------------------------------------------------

Скажем, нашли мы нужный адрес в Cheat Engine, включили отладчик дабы посмотреть - а с чего это у нас заканчиваются жизни (которые, как вы поняли, в еах находятся), отладчик нам выплёвывает адрес 0х00000001.

Если мы хотим, чтобы жизни просто не убавлялись, мы заменяем команду "sub eax, 1" nop'ами - командами, которые ничего не делают. Почему я написал во множественном числе? Всё просто - одна команда "nop" занимает один байт места, а вот "sub eax, 1" места занимает чуток побольше. Точные значения нас сейчас не волнуют (их можно посмотреть в отладчике), скажем, что это четыре байта. Поэтому вместо:

sub eax, 1

Мы должны будем написать четыре команды "nop", по одной на каждый байт:

nop
nop
nop
nop

Если не соблюдать это правило (количество байт кода всегда неизменно) - получите синий экран и придётся делать заново.

Идём дальше. В чём суть техники Code-Injection? Мы берём какую-то команду (в данном примере - ту, что вычитает у нас жизни) и заменяем её на команду jmp - прыжок или переход. Там выполняем какой-то код, затем возвращаемся обратно - в код игры. Смотрите:

Адрес   |  Команда      |    Комментарий
---------------------------------------------------------------------------------

0000000: mov eax, 3             //помещаем в регистр eax число "3"
0000001: jmp [0000006]      //переходим ("прыгаем") на адрес 0x0000006
0000002: cmp eax, 0            //сравниваем еах с нулём
0000003: je "exit"                 //если еах = 0, то выходим из игры
0000004: add eax, 2            //иначе прибавляем к еах двойку
0000005:
0000006: add eax, 10 //добавляем к еах десять
0000007: jmp [0000002] //прыгаем обратно - на адрес 0x0000002
0000008:
0000009:
---------------------------------------------------------------------------------
В результате этих действий мы заставили игру выполнить наш код (находящийся под адресам 0х0000006-0х0000007) а затем вернуться обратно и продолжить свой. Что нам это даёт? На самом деле - что угодно, всё зависит от фантазии и навыков программирования. Можно добавить жизней, можно патронов, можно всех врагов убить, можно любимой бабушке привет  передать - в общем, чего душа пожелает, а дальше игра послушно вернётся к своим делам. :)

Почему делать нужно именно так? Потому что про количество байт и длину кода я писал не просто так - мы не можем уместить тысячу байт кода в размеры одной трёх-четырёхбайтовой команды - поэтому засовываем код в отдельный участок памяти, обращаемся к нему, а затем продолжаем исполнение игрового кода. Прелесть в том, что код всегда будет находиться в одном и том же месте - адреса меняться не будут. Такая вот загогулина. Использовать этот не слишком хитрый приём мы будем ещё очень много раз, так что понимание успеет придти. Если же нет - пишите, задавайте вопросы. :)




20110915

Какой язык программирования выбрать?

Сижу вот, думаю, какой ЯП выбрать, записывая уроки по написанию трейнеров - маленьких таких программ, которые подключаются к процессу запущенной игры и изменяют её код и\или адреса, как мы это делали вручную в Cheat Engine. Выбор, в принципе, небольшой:

-Ассемблер. Самый низкоуровевый язык, на нём пишут все крутые чуваки из всяких там DEViATED, PizzaDOX и Razor1911. Для понимания с нуля - трудноват, кода будет довольно много, с другой стороны - мы же его используем при взломе (в отладчике), трейнеры будут очень маленького размера (максимум - 50-100 килобайт) и очень быстрые (но это не так критично).

-C\C++. Языки более высокого уровня - кода меньше, он во многом гораздо понятнее для неподготовленного человека, трейнеры будут уже чуть побольше, кода писать придётся меньше.

-Языки высокого уровня - C#\Basic\Java. Кода писать ещё меньше, но трейнеры будут уже довольно ощутимого размера (под пару-тройку мегабайт - запросто). Для понимания - ещё проще, чем предыдущие С и С++.

Я разместил опрос (слева от основных постов) - потыкайте кнопочки, а? И вам, и мне будет проще. Пару недель опрос повисит, а дальше буду на результаты смотреть.

Небольшой трюк при поиске адресов.

Бывает так, что нужный адрес ну вот никак не находится, хотя ищешь всё правильно. Что можно сделать в этом случае. Смотрим на картинку (кликаем, чтобы увеличить):

Видим несколько галочек, подчёркнутых красным. Поясню их значение:

Первые три ("Writable", "Executable" и "CopyOnWrite") влияют на диапазон адресов, в котором мы будем искать, каждая может находиться в трёх положениях (галочка поставлена, снята, "серая"). Нас интересует галочка "Writable" - то есть перезаписываемая память. Если галочка стоит, то в диапазон поиска попадут адреса, в значения которых можно изменить. Если нет - то те, что доступны только для чтения. Если же галочка "серая" - то без разницы, сканировать будем и то и другое. Это может помочь при поиске указателей (они чаще всего только для чтения).

Галочка пониже - "Fast scan" - "Быстрый поиск". С одной стороны, звучит круто - мол, искать программа будет быстрее. Но есть небольшое "но" - искать программа будет те адреса, что кратны циферке 32. Как, зачем и почему - нас не интересует, просто если галочку снять - поиск будет идти чуть медленнее (на современных компьютерах разница будет мизерная), но адресов сканироваться при этом будет больше.

Последняя, нижняя - "Pause the game while scanning" - как вы уже догадались, решает, останавливать ли процесс игры на время сканирования или нет. Полезно при отсутствии в игре "Паузы" - если ищем какую-нибудь полоску здоровья и хотим гарантированно приостановить игровой процесс, дабы никто в игре не помешал.


20110913

Скоро тест Тьюринга будет уверенно пройден!

Или очередные потуги компьютерной программы прикинуться человеком. Весьма интересно, [по ссылке]. :)

Пятый урок, товарищи, пятый урок!

Сразу же, с большого-большого разбега, [ссылка]!
Видео пришлось разбить на две части из-за врождённого рака мозга создателей органичения длины ютубного видео в 15 (!) минут - но ДЕЛАТЬ НЕЧЕГО, поделиться-то очень хотелось. ^^
В этом уроке мы познакомимся с шайтан-вещью - отладчиком - чуть поближе, ну и ещё пару клёвых штуковин:

1. Если код игры управляет вашим здоровьем - он может управлять и вражеским, ноп'ить (деактивировать) такой код будет бессмысленно - это даст бессмертие не только вам, но и вражине! В видео показан пример такой ситуации. ;)

2. Если мы меняем код игры, то нужно следить, чтобы длина старых инструкций совпадала с длиной новых, нами написанных. Иначе игра вас не поймёт и умрёт не совсем храброй смертью - придётся всё делать сначала. В видео это объяснено, но я постараюсь остановиться на этом подробнее в следующих уроках.

Ещё мы познакомимся с несколькими новыми ассемблерными командами:

1. push [что-то] - "толкнуть в стек". Про стек советую почитать подробнее в статьях\книгах по ассемблеру, но попытаюсь и объяснить:

Представьте себе стопку монеток. Можно положить сверху ещё одну ("толкнуть" в "стопку монет"), а можно:

2. pop [что-то] - "вытолкнуть из стека".

...взять монетку сверху - "вытолкнуть" из "стопки монет" обратно. Мы не можем засунуть монетку в середину или вытащить нижнюю - стопка зашатается и упадёт (не комильфо), так что принцип будет такой:

Толкаем:
Рубль, пять, два, десять

Выталкиваем:
Десять, два, пять, рубль

То есть, выталкивается всегда в обратном порядке. Часто этот процесс описывается как "Первый пришёл - последним уйдёшь". Заумная штука, да, но понимание придёт. Со временем. :)

Ещё пара команд:

3. jmp [адрес] - "прыжок" (англ. jump), переход на какой-то адрес. Важно - работает всегда, не смотря ни на какие условия и ни на что не обращая внимание.

4. cmp [первое],[второе] - сравнить первое со вторым. Операция сравнения, от английского to compare - сравнивать. Этой команде чаще всего следуют:

5. je\jne [адрес] - "прыгнуть, если" (англ. Jump if Equal \ Jump if Not Equal - "Прыгнуть, если равно \ Прыгнуть, если не равно") - такой же прыжок, как и jmp, но с условием - в первом случае прыгаем, если результат предыдущей команды (почти всегда это cmp - сравнение) положительный (первое равно второму), во втором - если отрицательный (не равно, кто бы мо г подумать!).

Ещё в этом уроке попалась такая инструкция, как lea [куда-то],[что-то] - "load effective address" - "загрузить эффективный адрес". Не буду вдаваться в подробности, скажу попроще: команда загружает значение "что-то" в "куда-то". Под "куда-то" чаще всего подразумевается какой-то из регистров процессора. Команда эта используется вместо команды mov (о ней - чуть ниже), потому что последняя плохо работает с копированием адресов в регистры. Так-то!


Ну и последняя (на этот раз, хе-хе):


mov [куда],[что] - англ. "move" - "переместить" - на самом деле, не перемещает, а копирует содержимое "что" в "куда". Например: 



mov eax, 123456 //Копирует "123456" в регистр eax
mov edx, eax //Копирует содержимое eax в edx


После выполнения команды число "123456" будет находиться И в eax И в edx. Одна из самых распостранённых команд, да. ^^




Думаю, пока всё, а то теории опять на неделю вдумчивых прочтений - перегружать не хочется. :)

PS: Если команды не хотят запоминаться - не переживайте, их знать понадобится порядка 10-15 штук, не больше. Если не понимаете значения той или иной команды (или просто забыли) - то идём в гугл и вводим запрос "assembler команда" или "ассемблер команда", где "команда" - это то самое буквосочетание из отладчика, что вас так смущает. :D


20110912

И сразу, чтобы не расслабляться, четвёртый урок!

Что-то продуктивность, как я погляжу, идёт в гору. :)
В этом уроке я продемонстрирую простейшую технику взлома под названием "Code Injection" - "Инъекция кода". Само собой, всё уже серьёзно, мы уже опытные, так что практиковаться будем на самой настоящей игре (которую я указывал в предыдущих постах :). Предлагаю сначала посмотреть урок, ибо он короткий - около пяти минут - а потом почитать немного теории и позадавать вопросы, если вдруг что-то осталось неясным. Итак!

[Четвёртый урок]


А теперь - немного теории. Совсем немного, правда. Но это очень сильно облегчит дальнейшее обучение. :)

Начнём с некоторых понятий, с которыми мы уже сталкивались:

Отладчик - [заумное объяснение] - специальная программа, которая позволяет нам подсмотреть код игры, меняющий значения по определённым адресам. Например, посмотреть (и изменить!) участок кода, отвечающий за приченение игроку урона (монстр укусил, в пропасть упал, захлебнулся и тому подобное), изменение количества патронов (постреляли - патронов стало меньше. Нехорошо!) и много чего угодно ещё - всё зависит от фантазии и знания вот этого языка:

Ассемблер - [заумное объяснение] - один из первых языков программирования, на котором нам предоставляет код тот самый отладчик из предыдущего абзаца. Прелесть в том, что язык нужен только этот (для любой игры), да и знать его вдоль и поперёк для умения ломать игры совсем не требуется - нужно знать только азы и понимать, что за код нам отладчик выплюнул. :)

Остановимся на окне отладчика Cheat Engine чуть подробнее. Вот скриншот (смотрим на красные цифры):
1. Количество вызовов инструкции игрой. Один раз выстрелили - один раз вызвалась инструкция, которая забирает патроны. И так далее.
2. Адрес в коде игры, по которому находится инструкция. Важно: адреса кода никогда не меняются!
3. Представление этой инструкции в шестнадцатеричной системе счисления, или опкод этой инструкции. Например, код инструкции nop - 90. [заумное объяснение]
4. Сама инструкция в виде команд ассемблера. В данном случае - sub - subtract- вычитание.
5. Пояснение той самой команды, если вы не знаете полного значения.




С особо любопытными делюсь набором статей по введению в ассемблер - [ссылка], второй абзац, "Дневники чайника", Чтивы 0-1-2-3. Так же - архив рассылки Калашникова, на данный момент уже не очень актуален, но материал там даётся просто отлично: [ссылка], крутим вниз до абзаца "Приятного вам изучения!", качаем "Полный архив рассылки" и "Необходимое ПО".
Ещё одна неплохая статья от Криса Касперски - [ссылка].

Пока всё, вникайте, задавайте вопросы. В следующих уроках сделаем ещё что-нибудь интересное. :)

PS: В качестве небольшого домашнего задания попробуйте найти указатель для адреса здоровья и\или для патронов (для того оружия, что в руках, или для любого).




Третий видеоурок и короткий рассказ про указатели и динамическое распределение памяти.



Ребята, перед просмотром урока\практикой - это важно! - сделайте следующее:

1. Откройте Cheat Engine, нажмите на кнопочку "Settings" ("Настройки") - Рис. 1.
2. Убедитесь, что галочка "Pointer adding: Append pointerline instead of insert" нажата - Рис. 2.


3. Всё, можно нажимать "ОК" и смело приступать к изучению. :)

Добавлю немного необходимой теории. Можно, конечно, на неё и забить, но если вы хотите в дальнейшем отлично понимать, что происходит - очень рекомендую ознакомиться. [Ссылка на статью], читаем параграфы 1.1-1.4 ("Система счисления", "Регистры", "Память", "Программа"). Поначалу прочитанное будет укладываться в голове крайне смутно и неохотно, но со временем эти знания окажутся крайне полезными.

И, чуть подробнее, про DMA ("Dynamic Memory Allocation", "Динамическое аспределение памяти") - [ссылка]. Если будет с ходу понятно и интересно - можете поискать и на английском, там подробностей побольше. :)

Ах да, [ссылка на урок], чуть не забыл! :D 

20110910

В дополнение к предыдущей записи - тренироваться будем вот на этой вот игре: [Turok 2: Seeds of Evil]. Одна из любимейших игр детства была. Эх, ностальгия! :)

PS: Очень надеюсь, что у всех желающих она нормально запустится - у меня, на Win7 x32, запустилась на ура, хотя игра - аж 1998 (sic!) года выпуска.

Неожиданно, второй урок.

Привет, ребята!

Жаркое лето кончилось, наступила школа осень, а это значит что пора поучиться ещё чему-нибудь, например - взлому игр! ^^ На этот раз мы познакомимся с программой [Cheat Engine], её интерфейсом, основными возможностями, а так же попробуем побороть идущую с ней в комплекте программу-обучалку по взлому, сегодняшняя тема - поиск неизвестного значения. Что это значит? А вот что:

Все видели в играх не конкретные значения здоровья (100, 80, 47), а полоски? Такая дико раздражающая штука, которая, будучи не заполненной, всегда жутко нервирует? Кто же не мечтает о том, чтобы она вообще не убавлялась? Бесконечное здоровье, энергия в плазменной винтовке, да что угодно! И это ведь легко! Смотрим, познаём, пробуем. В следующем уроке - издевательства над настоящей игрой! :)

[А вот и ссылка на урок]