<?xml version="1.0"?>
<rss version="2.0"><channel><title>zapiso4ki</title><link>https://old.gamehacklab.ru/blogs/blog/5-zapiso4ki/</link><description><![CDATA[<p>
	Бложек!
</p>]]></description><language>ru</language><item><title>&#x422;&#x430;&#x43A; &#x434;&#x435;&#x440;&#x436;&#x430;&#x442;&#x44C;?</title><link>https://old.gamehacklab.ru/blogs/entry/68-%D1%82%D0%B0%D0%BA-%D0%B4%D0%B5%D1%80%D0%B6%D0%B0%D1%82%D1%8C/</link><description><![CDATA[
<p>
	Дорогие читатели!
</p>

<p>
	 
</p>

<p>
	Мне продолжать этот бложек в текстово-картиночном формате (возможно - с гифками!) или же перейти обратно на формат видеолекций? А может, текстовые статьи дополнять видеопояснениями? Я никак не могу определиться, потому что мне очень странно на камеру объяснять и писать текст (код). Помогите мне определиться, пжлст (в комментариях).
</p>
]]></description><guid isPermaLink="false">68</guid><pubDate>Mon, 03 Jul 2017 17:26:15 +0000</pubDate></item><item><title>&#x414;&#x432;&#x438;&#x436;&#x43E;&#x447;&#x435;&#x43A;. &#x41D;&#x430;&#x447;&#x430;&#x43B;&#x43E;.</title><link>https://old.gamehacklab.ru/blogs/entry/64-%D0%B4%D0%B2%D0%B8%D0%B6%D0%BE%D1%87%D0%B5%D0%BA-%D0%BD%D0%B0%D1%87%D0%B0%D0%BB%D0%BE/</link><description><![CDATA[
<p>
	Привет, читатель!
</p>

<p>
	 
</p>

<p>
	Ты сейчас читаешь это, потому что в тебе есть интерес ко взлому игр и низкоуровневому программированию, ибо этот мини-блог будет посвящен как раз этой тематике. Если конкретнее, то я постараюсь показать и рассказать о том, как пишутся движки для трейнеров. Если ты вдруг не в курсе, то трейнер - это программа, позволяющая всячески изменять поведение компьютерной игры. Например, сделать ГГ (главного героя) бессмертным или же выдать ему миллион игровых очков. В общем, сделать нечто такое, чего штатный игровой процесс не подразумевает. Если ты вообще не понимаешь, о чем идет речь, то сначала поищи в интернете, как создаются читы для игр, а потом уже возвращайся сюда. Я буду предполагать, что взламывать игры (искать значения в памяти и немного пользоваться отладчиком/дизассемблером) ты уже умеешь. Итак, поехали! Весь исходный код я буду хранить в репозитории на github, ссылку на него и на нужный коммит буду выдавать в конце статей, если это потребуется.
</p>

<p>
	 
</p>

<p>
	С чего начнем? А начнем мы с выбора инструментов. Мои коллеги по цеху давно и очень успешно создают подобные этому обучающие материалы, но на высокоуровневых языках - C++ и C#, а местами и на Delphi. К счастью, мы от подобного избавлены, так что выбор у нас один - Ассемблер. Первая проблема заключается в том, что их много и они местами сильно различаются, так что отныне и в обозримом будущем я буду использовать <strong>[<a href="http://flatassembler.net" rel="external nofollow">flat assembler</a>]</strong>. Идешь на сайт в раздел "Download" и качаешь последнюю версию flat assembler for Windows (на момент написания этой статьи - 1.71.63). Скачанный архив нужно куда-то распаковать и можно запускать местную среду разработки - fasmw.exe. А вот и код на сегодня:
</p>

<p>
	 
</p>

<pre class="ipsCode" id="ips_uid_6302_6">
; main.asm

format PE GUI 4.0

include 'win32wxp.inc'

invoke ExitProcess,0

data import
  library kernel32,'KERNEL32.DLL'

  import kernel32,\
         ExitProcess,'ExitProcess'
end data</pre>

<p>
	Что происходит? ААА! Да ну, все в порядке. Разберем построчно. Символ точки с запятой обозначает комментарий. Сразу берем за правило, что в каждом файле исходного кода первой же строчкой будет идти его имя. В местной среде разработке (как и в любой другой) есть возможность запустить программу на исполнение, предварительно ее скомпилировав (если язык разработки является компилируемым). В твоем случае нужно выбрать меню "<strong>Run</strong>-&gt;<strong>Run</strong>" или ткнуть <strong>F9</strong>. Если звезды сложатся удачно, то с виду ничего не произойдет. Отсутствие ошибок - это половина успеха! Но вернемся к разбору исходного кода. Первой осмысленной с точки зрения компилятора строчкой идет вторая. Она указывает, что же за формат такой должен получиться на выходе. Формат, в смысле - исполняемого файла. EXE, то есть. В Windows основным таким форматом является PE, он же Portable Executable. Подробнее про него можно почитать в Интернете, например <strong>[<a href="https://en.wikipedia.org/wiki/Portable_Executable" rel="external nofollow">тут</a>]</strong>. GUI говорит компилятору о том, что это будет приложение с графическим интерфейсом пользователя, а не консольно-текстовое, что нам и нужно. И пока хватит с этой строчки, подробности про нее можно почитать на сайте ассемблера в разделе Documentation. Далее у нас идет директива include. Тут все просто - компилятор ищет файл с таким именем и банально вставляет вместо всей этой строчки его содержимое, как есть. Или ругается, если что-нибудь пошло не так. Если ты очень любопытен, то можешь найти этот файл в папке с ассемблером и посмотреть, что в нем написано. Пока что я скажу, что в нем описываются функции WinAPI - это такой здоровенный набор функций Windows, из которых и состоят, по факту, все программы. Запустить программу? WinAPI! Открыть файл? WinAPI! Поменять картинку на рабочем столе? WinAPI! И вот так всегда. Все в Windows сводится к большой стопке разных функций WinAPI, вызванных в нужном порядке. Хочешь подробнее прямо сейчас - ищи в Интернете (подсказка: MSDN). Что там идет дальше? Точно! Единственный, на самом деле, кусочек реального кода программы, а не какой-то вспомогательной фигни. invoke - это вызов функции. После этой команды идет имя функции и ее аргументы, если они есть. Самая настоящая команда ассемблера! На самом деле, конечно, это макрос, но об этом потом. Как бы это выглядело в реальной жизни? Представь, что надо заварить 10 чашек чая. И даже есть функция (по сути - просто набор действий) под названием "СделатьЧай". Что должна делать эта функция? Взять чашку, насыпать в нее чай, налить кипяток, добавить сахар, перемешать. Так и пишем:
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_6302_9">
<span class="pln">СделатьЧай:
0. Взять чашку
1. Насыпать в чашку чай
2. Налить в чашку кипяток
3. Добавить в чашку сахар
4. Перемешать</span></pre>

<p>
	Допустим, что мы пишем на ассемблере программу, которая заваривает чай. И что "СделатьЧай" - это функция WinAPI. Вот так будет выглядеть ее вызов:
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_6302_11">
<span class="pln">invoke СделатьЧай</span></pre>

<p>
	Ага! Ты сразу спросишь - "а нафига ноль в конце той строчки? что еще за аргументы такие?". Аргумент - это просто некое значение, передаваемое функции в момент ее вызова. Например, "СделатьЧай, 10 раз". Если бы наша функция, делающая чай, принимала аргумент "Количество" и была бы написана так, что был бы в ней цикл - "делать чай, пока количество не станет равным 0, после каждой чашки отнимать от количества 1", то делала бы она за один вызов 10 чашек и вместо:
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_6302_13">
<span class="pln">invoke СделатьЧай ; 0 чашка
invoke СделатьЧай ; 1 чашка
invoke СделатьЧай ; 2 чашка
invoke СделатьЧай ; 3 чашка
invoke СделатьЧай ; 4 чашка
invoke СделатьЧай ; 5 чашка
invoke СделатьЧай ; 6 чашка
invoke СделатьЧай ; 7 чашка
invoke СделатьЧай ; 8 чашка
invoke СделатьЧай ; 9 чашка</span></pre>

<p>
	Можно было бы написать всего лишь: 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_6302_16">
<span class="pln">invoke СделатьЧай,10 ; 10 раз</span></pre>

<p>
	И оно бы внутри в цикле 10 раз вызвалось. Удобно ведь? Конечно! И места меньше занимает.
</p>

<p>
	 
</p>

<p>
	Функция у нас вызывается всего одна - "ExitProcess" с аргументом в виде нуля. Знатоки английского языка могут догадаться, что эта функция делает. Завершает процесс. Выходит. Совсем. Да, все так - <em>все</em>, что программа делает на данный момент - это успешно завершает свою работу. Успешно, потому что аргумент у нее "0". Аргумент этой функции - это так называемый код возврата. Он сильно нужен (зачем-то) Windows и она решает именно по коду возврата, хорошо ли было программе во время работы или плохо. Вот случись ошибка - завершаешь программу с не-нулевым кодом возврата и все, Windows об этом будет знать. Когда-то давно это была единственная возможность узнать результат работы - эти самые коды возврата были описаны в документации к программам. Так-то!
</p>

<p>
	 
</p>

<p>
	Итак, выяснилось, что оно начинает работу и сразу же ее завершает, зато успешно. Ну а что, надо ведь начинать с чего-то, верно? Остался последний кусок. Кусок этот отвечает за предоставление нашей программе доступа к WinAPI. Эти все функции - не магия и не само собой оно работает, а где-то в системе хранится. Если точнее, то хранится в библиотеках, которые имеют расширение DLL, хотя тоже являются исполняемыми файлами. Да, они тоже исполняемые, просто не умеют сами запускаться - их должен загрузить в себя другой процесс (работающий EXE файл) и можно будет вызывать функции загруженной библиотеки. То, какие функции можно вызывать, а какие нельзя, определяется библиотекой, а процесс, загрузивший ее, может только попросить указать ему место, где в библиотеке нужные ему функции лежат. Этим и занимается секция data import - end data. Мы указываем, что нам нужно загрузить библиотеку kernel32.dll, а из нее - функцию по имени ExitProcess. Что происходит при запуске? EXE-файл загружает библиотеку. Та сообщает ему, где искать адрес функции ExitProcess. После этот самый адрес и подставляется команде invoke. Такой вот компилятор умный.
</p>

<p>
	 
</p>

<p>
	На этом пока закончим.
</p>

<p>
	 
</p>

<p>
	<strong>[<a href="https://github.com/remizovm/trainer_engine_tutorial" rel="external nofollow">Репозиторий</a>]</strong> на github.
</p>

<p>
	<strong>[<a href="https://github.com/remizovm/trainer_engine_tutorial/commit/169ceb780210c0519c46ceb206ff9b863b1bb2d4" rel="external nofollow">Коммит</a>]</strong>.
</p>
]]></description><guid isPermaLink="false">64</guid><pubDate>Sun, 25 Jun 2017 20:39:21 +0000</pubDate></item></channel></rss>
