<?xml version="1.0"?>
<rss version="2.0"><channel><title/><link>https://old.gamehacklab.ru/blogs/blog/11-%D0%BD%D0%B0%D1%87%D0%B8%D0%BD%D0%B0%D0%B5%D0%BC-%D0%BF%D0%BE%D1%81%D1%82%D0%B8%D0%B3%D0%B0%D1%82%D1%8C-%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D1%8B/</link><description/><language>ru</language><item><title>&#x421;&#x442;&#x430;&#x440;&#x430;&#x44F;,  &#x43D;&#x435;&#x430;&#x43A;&#x442;&#x443;&#x430;&#x43B;&#x44C;&#x43D;&#x430;&#x44F; &#x43C;&#x43C;&#x43E; 3</title><link>https://old.gamehacklab.ru/blogs/entry/290-%D1%81%D1%82%D0%B0%D1%80%D0%B0%D1%8F-%D0%BD%D0%B5%D0%B0%D0%BA%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F-%D0%BC%D0%BC%D0%BE-3/</link><description><![CDATA[<p>
	Вот и настало время когда я вернулся снова к этой игре<br>
	Только теперь уже для нее есть исходный код, который позволит находить всякие функции в разы быстрее и проще<br><br>
	На этот раз будем делать карту ресурсов, рисовать ее и загружать прямо в игру<br>
	Этапы которые этому способствуют<br>
	1. Распаковать саму карту из surfaces.pck<br>
	2. Достать саму карту, посмотреть каким образом она примерно отображается<br>
	3. Узнать координаты респа ресурсов Vec3 на карте<br>
	4. Перевести Vec3 игровые в Vec2 картовые<br>
	5. Нанести по Vec2 соответствующие иконки<br>
	6. Привести все в читаемый формат для игры<br>
	7. Запаковать все обратно<br><br><strong>1. </strong>Распаковка pck этой игры уже не представляется сложностью, и есть довольно много софтов делающее это (Собственно как и упаковка обратно)<br>
	А значит пункты 1 и 7 не сложны совсем<br><strong>2.</strong> Карта в игре отображается довольно специфическим образом (Незнаю как до этого додумались разработчики, или же это движок сам режет так интересно)<br>
	В целом картина такая<br><img alt="NwrsTAn.png" class="ipsImage" data-ratio="38.35" height="245" width="640" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" data-src="https://i.imgur.com/NwrsTAn.png"></p>

<p>
	 
</p>

<p>
	Мировая карта состоит из 88 частей - т.е. 8 столбцов и 11 строк (В свою очередь каждый квадрат тут 1024*1024 пикселя)<br>
	Из всех этих кусков собирается единая карта, которую можно будет увидеть в игре<br>
	Формат файла dds, т.е. в итоге мы должны получить карту в 88 dds файлов как в оригинале<br><br><strong>3. </strong>Координаты респа найти довольно легко, опять же распаковав configs.pck<br>
	Внутри будет coords_data.txt в котором некоторым списком указаны Vec3 координаты нахождения ресурса / моба и т.п.<br>
	Структура примерно такая<br><img alt="wxW5cfZ.png" class="ipsImage" data-ratio="31.11" height="154" width="495" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" data-src="https://i.imgur.com/wxW5cfZ.png"><br><br>
	Парсим нужные координаты по ID (Пишем вспомогательный парсер который выдаст c++ массив с Vec3)<br>
	3091 - ID, world - фильтрация только для основной карты<br>
	Ну и достаем Vec3 - x y z координаты<br><img alt="aRAOPop.png" class="ipsImage" data-ratio="97.04" height="480" width="494" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" data-src="https://i.imgur.com/aRAOPop.png"><br><br><strong>4. </strong>Когда есть массив всех этих ресурсов, нужно перевести Vec3 (Т.е. внутриигровое положение в мире, на карту, которая 2D)<br>
	Тут поможет исходник клиента PW, и метод который рисует стрелочку игрока на карте<br><img alt="Df1E0zc.png" class="ipsImage" data-ratio="40.54" height="259" width="640" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" data-src="https://i.imgur.com/Df1E0zc.png"><br>
	Вот та самая функция в исходном коде, далее надо ее найти и заменить координаты (т.е. оригинально передаются Vec3 игрока, и вычисляется Х-У для рисования на карте)<br>
	Ничто не помешает нам подменить эти координаты на те, где находятся ресурсы Vec3<br><br>
	Далее дело техники, и создания хука (Учитывания calling conventions, определения аргументов и т.д.)<br>
	Имея исходный код не так сложно найти функцию (Правда версия игры немного старее чем этот исходный код)<br>
	Собственно вот и хук. В цикле перебираем массив который сделали на шарпе путем парсинга файла
</p>

<p>
	<img alt="aJEPlP6.png" class="ipsImage" data-ratio="69.38" height="444" width="640" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" data-src="https://i.imgur.com/aJEPlP6.png"><br>
	Выдаем результаты в виде массива (Далее пригодится)
</p>

<p>
	Таким образом я получил координаты для 4х видов ресурсов (Больше мне и не нужно. Vec2 координаты) ~320 штук<br><br><strong>5.</strong> Далее необходимо нанести все это дело на карту.<br>
	Дабы не скреплять все 88 кусков в каком-нибудь редакторе мне удалось найти (Не без помощи) карту 8*1024 х 11*1024 пикселей. Т.е. точно такую как и нужна<br><br>
	Для добавления иконок на общую картину была написана еще одна вспомогательная программа на шарпе, которая грузит общую карту, а потом по координатам ставит маленькую иконку 16х16 по координатам из массива<br>
	(Скрин выше)<br>
	Ну соответственно наносим сами иконки на общую карту и сохраняем в jpg. Получаем на выходе карту в 113мб с нанесенными иконками<br><br>
	Остается всего 2 пункта, один из которых пустяковый<br><strong>6.</strong> Режем эту общую карту в фотошопе (Качаем фотошоп, да да у меня его не было на этой машине) с помощью инструмента "раскройка"<br><img alt="N8I8kto.png" class="ipsImage" data-ratio="124.36" height="480" width="385" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" data-src="https://i.imgur.com/N8I8kto.png"><br><br>
	И как раз получаем 88 изображений; 8 столбцов и 11 строк, где каждая картинка по 1024*1024 пикселя. Идеально<br>
	Остается нерешенным только вопрос конвертации из jpg в dds. Но тут придется только ручками все делать.<br>
	А также ручками приводить потом названия этих кусочков в вид который на скриншоте №1. (Не смертельно, но долго)<br>
	Заменяем 88 dds файлов на новые в папке maps<br><br><strong>7.</strong> Запаковываем все обратно в единый pck файл программой из п1. и проверяем в игре.<br><img alt="Ji0RZ7E.png" class="ipsImage" data-ratio="43.87" height="280" width="640" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" data-src="https://i.imgur.com/Ji0RZ7E.png"><br><br><br>
	Все работает. Отлично..<br>
	Сама по себе идея не новая, но вот реализации именно внутри игры пока что не видел нигде
</p>
]]></description><guid isPermaLink="false">290</guid><pubDate>Thu, 05 Nov 2020 16:10:48 +0000</pubDate></item><item><title>&#x412;&#x44B;&#x437;&#x43E;&#x432; &#x432;&#x43D;&#x443;&#x442;&#x440;&#x435;&#x438;&#x433;&#x440;&#x43E;&#x432;&#x44B;&#x445; &#x444;&#x443;&#x43D;&#x43A;&#x446;&#x438;&#x439;</title><link>https://old.gamehacklab.ru/blogs/entry/276-%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2-%D0%B2%D0%BD%D1%83%D1%82%D1%80%D0%B5%D0%B8%D0%B3%D1%80%D0%BE%D0%B2%D1%8B%D1%85-%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B9/</link><description><![CDATA[<p>
	Так, давно что-то ничего не писал в блог<br>
	Собственно время пришло<br><br>
	Данная статья является примером метода о котором рассказано в данном видео
</p>

<div class="ipsEmbeddedVideo">
	<div>
		<iframe allowfullscreen="true" frameborder="0" height="270" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="480" data-embed-src="https://www.youtube.com/embed/jmgwFpVnRmU?feature=oembed"></iframe>
	</div>
</div>

<p>
	 
</p>

<p>
	Рассмотрим вызов игровой функции на примере перовой части игры Dishonored <br>
	В данном примере будем восполнять себе количество маны, которая в игре не может регенерироваться полностью после использования череды способностей<br><br>
	Для начала нам необходимо найти само значение маны, благо оно храниться 4мя байтами в памяти и тут нет ничего сложного<br><img alt="bO0W6Yq.png" class="ipsImage" height="17" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="640" data-src="https://i.imgur.com/bO0W6Yq.png"></p>

<p>
	Теперь когда у нас есть адрес маны или же указатель на данный адрес, нам необходимо найти метод который как раз и перезаписывает значение<br>
	Делается это очень просто (F6)<br><img alt="yC4CANI.png" class="ipsImage" height="480" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="521" data-src="https://i.imgur.com/yC4CANI.png"></p>

<p>
	Нас интересует инструкция которая перезаписывает значение 1 раз<br>
	Выходим на эту инструкцию в дизассемблере и ставим брейк<br><img alt="suWyKYF.png" class="ipsImage" height="139" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="640" data-src="https://i.imgur.com/suWyKYF.png"></p>

<p>
	Вот мы и нашли инструкцию, далее просто выходим из него (Кнопка Execute till return)<br>
	Для того чтобы вызвать метод, необходимо узнать и проанализировать его параметры. Этим и займемся<br><img alt="vDQrTqo.png" class="ipsImage" height="177" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="640" data-src="https://i.imgur.com/vDQrTqo.png"></p>

<p>
	 
</p>

<p>
	В метод передается 2 параметра, один из которых находится в ecx (Указатель на базовый класс)<br>
	А второй передается в регистре ecx, до инструкции которая перезапишет значение
</p>

<p>
	<br>
	Данный кусок:<br>
	push ecx<br>
	mov ecx,esi
</p>

<p>
	<br>
	Регистр edx содержит все время один и тот же не изменяющийся адрес, т.е он статичен<br>
	Распишу параметры чтобы было более нагляднее<br>
	push ecx (Значение 50 в данный момент)<br>
	mov ecx, esi (В ecx записывается значение из esi (0x0AD0A000))<br>
	Теперь если немного проанализировать, то можно понять что 50 - это значение маны, которое будет присвоено игроку после применения способности<br>
	А 0x0AD0A000 это указатель на начало структуры игрока, т.е PlayerController* player;
</p>

<p>
	Таким образом метод выглядит так: ManaMethod(PlayerController* player, int ManaOut);<br><br>
	Теперь можно приступать к написанию самого кода на c++, чтобы вызывать этот внутреигровой метод (При этом заранее найдем работающий указатель на класс игрока PlayerController)<br>
	Для вызова метода нам необходимо определить его соглашение о вызове, т.е в каком порядке туда передаются аргументы<br>
	Посмотреть все соглашения можно тут <a href="https://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D0%B3%D0%BB%D0%B0%D1%88%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE_%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2%D0%B5" rel="external nofollow">https://ru.wikipedia.org/wiki/Соглашение_о_вызове</a><br>
	Немного почитав можно увидеть что это соглашение __thiscall
</p>

<pre class="ghlCode">
<code class="hljs">thiscall — соглашение о вызовах, используемое компиляторами для языка C++ при вызове методов классов в объектно-ориентированном программировании.

Аргументы функции передаются через стек, справа налево. Очистку стека производит вызываемая функция. Соглашение thiscall отличается от cdecl соглашения только тем, что указатель на объект, для которого вызывается метод (указатель this), записывается в регистр ecx.</code></pre>

<p>
	<br>
	В самом коде объявляем этот метод для его вызова далее<br>
	 
</p>

<pre class="ghlCode">
<code class="cpp hljs"><span class="hljs-comment">//Метод принимает PlayerController* и ManaOut</span>
<span class="hljs-comment">//0x00AB17C0 - адрес которых хранился в edx и он статичен</span>
<span class="hljs-keyword">typedef</span> <span class="hljs-keyword">void</span>*(__thiscall * _ManaType)(PlayerController* Player, <span class="hljs-keyword">int</span> Mana);
_ManaType ManaFunc = (_ManaType)(<span class="hljs-number">0x00AB17C0</span>);</code></pre>

<p>
	Остается только написать вызов этого метода и на этом дело будет сделано
</p>

<pre class="ghlCode">
<code class="cpp hljs"><span class="hljs-comment">/*PlayerConroller.h */</span>
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">PlayerController</span> {</span>

<span class="hljs-keyword">public</span>:
	<span class="hljs-keyword">char</span> pad_0000[<span class="hljs-number">2656</span>]; <span class="hljs-comment">//0x0000</span>
	<span class="hljs-keyword">int</span> Mana; <span class="hljs-comment">//0x0A60</span>


};

<span class="hljs-comment">/*Метод который вызывается при создании потока из dll*/</span>
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">onAttach</span><span class="hljs-params">()</span>
</span>{
	<span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>)
	{
		<span class="hljs-keyword">if</span> (GetAsyncKeyState(VK_END))
		{
			PlayerController* Player = <span class="hljs-keyword">reinterpret_cast</span>&lt;PlayerController*&gt;(*(DWORD*)(Base + <span class="hljs-number">0x01052DE8</span>)); <span class="hljs-comment">//Получаем указатель на игрока PlayerController*</span>
			ManaFunc(Player, <span class="hljs-number">100</span>);
		}

		Sleep(<span class="hljs-number">150</span>);
	}
}</code></pre>

<p>
	Собственно на этом моменте статья закончена<br>
	При нажатии на кнопку END внутри игры, мана восполняется до 100 единиц
</p>
]]></description><guid isPermaLink="false">276</guid><pubDate>Sun, 05 Jan 2020 16:48:51 +0000</pubDate></item><item><title>&#x421;&#x442;&#x430;&#x440;&#x430;&#x44F;, &#x43D;&#x43E; &#x432;&#x441;&#x435; &#x435;&#x449;&#x435; &#x430;&#x43A;&#x442;&#x443;&#x430;&#x43B;&#x44C;&#x43D;&#x430;&#x44F; &#x43C;&#x43C;&#x43E; 2 (Packet editing)</title><link>https://old.gamehacklab.ru/blogs/entry/256-%D1%81%D1%82%D0%B0%D1%80%D0%B0%D1%8F-%D0%BD%D0%BE-%D0%B2%D1%81%D0%B5-%D0%B5%D1%89%D0%B5-%D0%B0%D0%BA%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F-%D0%BC%D0%BC%D0%BE-2-packet-editing/</link><description><![CDATA[<p>
	Вот и настало время для 2й части реверсинга данной игры <img alt=":D" data-emoticon="" height="20" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" srcset="https://old.gamehacklab.ru/uploads/emoticons/biggrin@2x.png 2x" title=":D" width="20" data-src="https://old.gamehacklab.ru/uploads/emoticons/default_biggrin.png"><br>
	Сегодня будет рассмотрен Packet Editing<br>
	В качестве основной идеи выступает данное видео 
</p>

<div class="ipsEmbeddedVideo">
	<div>
		<iframe allowfullscreen="true" frameborder="0" height="270" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="480" data-embed-src="https://www.youtube.com/embed/TG_FVzBijrk?feature=oembed"></iframe>
	</div>
</div>

<p>
	 
</p>

<p>
	Ну что же, начнем...<br>
	Для начала необходимо найти ф-ию отправки пакета на сервер игры<br>
	Эта ф-ия существует во всех онлайн играх.
</p>

<p>
	 
</p>

<p>
	На примере Perfect World, она выглядит вот так<br>
	В ф-ию передается 2 аргумента <br>
	1й аргумент это указатель на массив байтов который передается серверу<br>
	В качестве второго аргумента выступает размер пакета в байтах<br><img alt="TDXg63m.png" class="ipsImage" height="298" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="640" data-src="https://i.imgur.com/TDXg63m.png"></p>

<p>
	 
</p>

<p>
	Выглядит все это примерно так<br>
	byte data[] = { 0x0 , 0xfc, 0xbc };<br>
	int len = 3;<br>
	SendPacket(data, 3);<br>
	Таким образом можно отправлять серверу пакеты для выполнения каких-либо действий внутри игры<br><br>
	Но для того чтобы что-то сделать в игре, надо знать какой пакет мы должны отправить заранее<br>
	И для этого ниже будет представлен хук, который покажет какие пакеты отправляются от клиента на сервер<br><br>
	Приступим к самому хуку для чтения пакетов<br>
	Сам хук довольно прост, и ничем особым не выделяется, кроме того, что хук будет перед вызовом memmove<br><img alt="exgx0KH.png" class="ipsImage" height="81" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="640" data-src="https://i.imgur.com/exgx0KH.png"></p>

<p>
	 
</p>

<pre class="ghlCode">
<code class="cpp hljs"><span class="hljs-comment">//Main dll thread</span>
jmpBack = (DWORD)DetourFunction((BYTE*)(Module + <span class="hljs-number">0x419ACF</span>), (BYTE*)PacketHook);

<span class="hljs-comment">//Hook part</span>
__declspec(naked) <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">PacketHook</span><span class="hljs-params">()</span>
</span>{
	__asm {
		mov hookedPacket, ecx
		mov hPacketSize, esi
	}
	<span class="hljs-built_in">memcpy</span>(hpacket, (<span class="hljs-keyword">void</span>*)hookedPacket, <span class="hljs-number">256</span>);
	i = <span class="hljs-number">0</span>;
	<span class="hljs-keyword">if</span> (hpacket[<span class="hljs-number">0</span>] == <span class="hljs-number">0x0</span> &amp;&amp; hpacket[<span class="hljs-number">1</span>] == <span class="hljs-number">0x0</span> &amp;&amp; hPacketSize == <span class="hljs-number">41</span>) <span class="hljs-comment">//Movement 41 len</span>
	{
		<span class="hljs-built_in">printf</span>(<span class="hljs-string">"Movement Packet: "</span>);
		<span class="hljs-built_in">printf</span>(<span class="hljs-string">"Y: %.3f  X: %.3f  Z: %.3f "</span>, *(<span class="hljs-keyword">float</span>*)(hpacket+<span class="hljs-number">2</span>), *(<span class="hljs-keyword">float</span>*)(hpacket + <span class="hljs-number">6</span>), *(<span class="hljs-keyword">float</span>*)(hpacket + <span class="hljs-number">10</span>));
		<span class="hljs-built_in">printf</span>(<span class="hljs-string">"Counter %02x \n"</span>, hpacket[<span class="hljs-number">16</span>]);
	}
	<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (hpacket[<span class="hljs-number">0</span>] == <span class="hljs-number">0x07</span> &amp;&amp; hpacket[<span class="hljs-number">1</span>] == <span class="hljs-number">0x00</span> &amp;&amp; hPacketSize == <span class="hljs-number">25</span>) <span class="hljs-comment">//Stop Move</span>
	{
		<span class="hljs-built_in">printf</span>(<span class="hljs-string">"Stop Hero Packet: "</span>);
		<span class="hljs-built_in">printf</span>(<span class="hljs-string">"Y: %.3f  X: %.3f  Z: %.3f \n"</span>, *(<span class="hljs-keyword">float</span>*)(hpacket + <span class="hljs-number">2</span>), *(<span class="hljs-keyword">float</span>*)(hpacket + <span class="hljs-number">6</span>), *(<span class="hljs-keyword">float</span>*)(hpacket + <span class="hljs-number">10</span>));
	}
	<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (hpacket[<span class="hljs-number">0</span>] == <span class="hljs-number">0x03</span> &amp;&amp; hpacket[<span class="hljs-number">1</span>] == <span class="hljs-number">0x00</span> &amp;&amp; hpacket[<span class="hljs-number">2</span>] == <span class="hljs-number">0x01</span> &amp;&amp; hPacketSize == <span class="hljs-number">3</span>) <span class="hljs-comment">//Attack Packet</span>
	{
		<span class="hljs-built_in">printf</span>(<span class="hljs-string">"Standart Attack Packet\n"</span>);
	}
	<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (hpacket[<span class="hljs-number">0</span>] == <span class="hljs-number">0x02</span> &amp;&amp; hpacket[<span class="hljs-number">1</span>] == <span class="hljs-number">0x00</span> &amp;&amp; hPacketSize == <span class="hljs-number">6</span>) <span class="hljs-comment">//Select Target packet</span>
	{
		<span class="hljs-built_in">printf</span>(<span class="hljs-string">"Select target: 0x%06x\n"</span>, *(<span class="hljs-keyword">int</span>*)(hpacket+<span class="hljs-number">3</span>));
	}
	<span class="hljs-built_in">printf</span>(<span class="hljs-string">"Incoming Packet: "</span>);
	<span class="hljs-keyword">for</span> (i; i &lt; hPacketSize; i++)
	{
		<span class="hljs-built_in">printf</span>(<span class="hljs-string">"%02x "</span>, hpacket[i]);
	}
	<span class="hljs-built_in">printf</span>(<span class="hljs-string">"\n"</span>);

	_asm jmp jmpBack
}
</code></pre>

<p>
	Собственно это весь хук который нужен для чтения<br>
	Некоторые пакеты я уже расшифровал<br>
	К примеру пакет движения<br>
	У каждого пакета в игре есть некий ID - это ровно 2 байта<br>
	Для перемещения это 00 00<br>
	Остановка персонажа 07 00<br>
	Обычная атака 03 00 и т.д.<br>
	В пакете движения передаются координаты перемещения персонажа в данный момент<br><img alt="0Ra95Cg.png" class="ipsImage" height="115" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="640" data-src="https://i.imgur.com/0Ra95Cg.png"></p>

<p>
	 
</p>

<p>
	Что касается чтения пакетов, с этим все, больше тут придумывать нечего<br>
	Настало время сделать свою отправку пакета на сервер<br>
	 
</p>

<pre class="ghlCode">
<code class="cpp hljs"><span class="hljs-comment">//SendPacket Prototype</span>
<span class="hljs-keyword">using</span> Send_t = <span class="hljs-keyword">void</span>(__thiscall*)(DWORD*,DWORD*, <span class="hljs-keyword">int</span>);
<span class="hljs-keyword">auto</span>* fnc_Send = <span class="hljs-keyword">reinterpret_cast</span>&lt;Send_t&gt;(Module + <span class="hljs-number">0x419A40</span>);

		<span class="hljs-keyword">if</span> (GetAsyncKeyState(VK_NUMPAD8) &amp; <span class="hljs-number">0x1</span>)
		{
			<span class="hljs-built_in">std</span>::<span class="hljs-function">ifstream <span class="hljs-title">inFile</span><span class="hljs-params">(<span class="hljs-string">"C:\\Users\\Administrator\\Documents\\Visual Studio 2017\\Projects\\PW\\Debug\\Send.txt"</span>)</span></span>;

			<span class="hljs-built_in">std</span>::<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">uint8_t</span>&gt; data;
			data.reserve(<span class="hljs-number">512</span>);

			<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> temp;
			<span class="hljs-keyword">while</span> (!inFile.eof()) {
				inFile &gt;&gt; <span class="hljs-built_in">std</span>::hex &gt;&gt; temp;
				data.push_back(temp);
			}
			<span class="hljs-built_in">std</span>::copy(data.begin(), data.end(), hSendPacket);

			<span class="hljs-built_in">printf</span>(<span class="hljs-string">"Sent: "</span>);
			<span class="hljs-keyword">for</span> (j; j &lt; data.size(); j++)
				<span class="hljs-built_in">printf</span>(<span class="hljs-string">"%02x "</span>, (<span class="hljs-keyword">int</span>)data[j]);
			<span class="hljs-built_in">printf</span>(<span class="hljs-string">"\n"</span>);

			DWORD* Packet = (DWORD*)&amp;hSendPacket;
			DWORD BaseValue = *<span class="hljs-keyword">reinterpret_cast</span>&lt;DWORD *&gt;(<span class="hljs-number">0x00E444A4</span>);
			DWORD* Base = (DWORD*)(*<span class="hljs-keyword">reinterpret_cast</span>&lt;DWORD*&gt;(BaseValue + <span class="hljs-number">0x20</span>));
			<span class="hljs-keyword">int</span> packsize = data.size();
			fnc_Send(Base, Packet, packsize);
		}</code></pre>

<p>
	У ф-ии 3 аргумента, т.к в регистре ecx перед вызовом ф-ии должен быть еще 1 указатель<br>
	Теперь и отправка пакета готова, можно начать эксперементировать<br>
	Для примера возьму пакет использования 3ей ячейки в инвентаре, в которой лежит предмет<br>
	28 00 00 01 02 00 26 2c 00 00<br>
	28 00 - использование предмета<br>
	02 - ячейка в инвентаре<br>
	02 26 - ID предмета, которое можно посмотреть и свериться
</p>

<p>
	<img alt="2wbhqEU.png" class="ipsImage" height="304" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="640" data-src="https://i.imgur.com/2wbhqEU.png"></p>

<p>
	11302 - 0x2C26<br><br>
	Ну а теперь когда найден пакет, можно попробовать отправить его на сервер с помощью написанного выше кода
</p>

<p>
	<img alt="3hIeZSh.png" class="ipsImage" height="386" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="640" data-src="https://i.imgur.com/3hIeZSh.png"><br><br>
	На этом данная статья заканчивается. <br>
	Примерно такие же действия можно сделать и с другими онлайн играми и автоматизировать некоторые действия
</p>
]]></description><guid isPermaLink="false">256</guid><pubDate>Tue, 23 Jul 2019 13:04:00 +0000</pubDate></item><item><title>Metal Gear Rising - Revengeance &#x438;&#x43B;&#x438; &#x442;&#x440;&#x435;&#x439;&#x43D;&#x435;&#x440; &#x441; dx9</title><link>https://old.gamehacklab.ru/blogs/entry/251-metal-gear-rising-revengeance-%D0%B8%D0%BB%D0%B8-%D1%82%D1%80%D0%B5%D0%B9%D0%BD%D0%B5%D1%80-%D1%81-dx9/</link><description><![CDATA[<p>
	На днях решил с самого чистого нуля написать хук для Directx 9.<br>
	Чтобы было хоть какое-нибудь отображение для пользователя внутри игры<br>
	Собственно идея зародилась, осталось только воплотить <br>
	Хук поддерживает Режим в окне / Полноэкранный<br>
	Использование EndScene и библиотеки для рисования самого меню.
</p>

<p>
	<br>
	Использованная версия игры: Metal Gear Rising - Revengeance v2, таблетка от Skidrow<br><br>
	Пара скриншотов самого меню, все получилось довольно ярко<br><img alt="yfPAcoa.png" class="ipsImage" height="262" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="640" data-src="https://i.imgur.com/yfPAcoa.png"></p>

<p>
	<img alt="ef05oBE.png" class="ipsImage" height="352" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="640" data-src="https://i.imgur.com/ef05oBE.png"></p>

<p>
	 
</p>

<p>
	На момент тестирования багов и вылетов не обнаружил. <br>
	Для написания ф-ий и самого хука были использованы MS Detours.<br>
	Вполне возможно что функционал я буду еще доделывать, постепенно<br>
	Но это в том случае, если не переключусь на игру поинтересней <span><img alt=":D" data-emoticon="" height="20" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" srcset="https://old.gamehacklab.ru/uploads/emoticons/biggrin@2x.png 2x" title=":D" width="20" data-src="https://old.gamehacklab.ru/uploads/emoticons/default_biggrin.png"></span><br><br>
	Ну и конечно же видео
</p>

<div class="ipsEmbeddedVideo">
	<div>
		<iframe allowfullscreen="true" frameborder="0" height="270" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="480" data-embed-src="https://www.youtube.com/embed/euWtQY4MpA4?feature=oembed"></iframe>
	</div>
</div>

<p>
	 
</p>
]]></description><guid isPermaLink="false">251</guid><pubDate>Wed, 10 Jul 2019 19:48:02 +0000</pubDate></item><item><title>&#x421;&#x442;&#x430;&#x440;&#x430;&#x44F;, &#x43D;&#x43E; &#x432;&#x441;&#x435; &#x435;&#x449;&#x435; &#x430;&#x43A;&#x442;&#x443;&#x430;&#x43B;&#x44C;&#x43D;&#x430;&#x44F; &#x43C;&#x43C;&#x43E;</title><link>https://old.gamehacklab.ru/blogs/entry/247-%D1%81%D1%82%D0%B0%D1%80%D0%B0%D1%8F-%D0%BD%D0%BE-%D0%B2%D1%81%D0%B5-%D0%B5%D1%89%D0%B5-%D0%B0%D0%BA%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F-%D0%BC%D0%BC%D0%BE/</link><description><![CDATA[<p>
	Сегодня рассмотрим старую, но все еще актуальную ммо под названием Perfect World<br>
	Берем конечно же не актуальную версию официального клиента, а пиратский сервер с его старенькой версией 1.5.3 (Summer PW)<br>
	Официальная версия 1.6+<br><br>
	На данном пвп сервере изменены некоторые полеты для персонажа, введены некоторые, так называемые "рисованные" вещи которые довольно плохо влияют на баланс сервера<br>
	Да к тому же сервер заточен еще и под донат, т.к статы вещей могут быть рандомными (Классно...)
</p>

<p>
	<img alt="tNil8Fd.png" class="ipsImage" height="480" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="214" data-src="https://i.imgur.com/tNil8Fd.png"></p>

<p>
	 
</p>

<p>
	Как раз 4 стата и считаются рандомными, выпадают с некоторым шансом из общего пула.<br><br>
	Ну и начнем собственно, посмотрим что можно сделать в этой игре интересного<br>
	Начнем копать от локального игрока<br>
	Ищем его указатель. Это довольно просто, не возникает никаких трудностей<br><img alt="K5333wF.png" class="ipsImage" height="124" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="640" data-src="https://i.imgur.com/K5333wF.png"></p>

<p>
	 
</p>

<p>
	Указатель имеет всего одно смещение по типу *(LocalPlayer*) + 0x4 <br>
	И собственно так мы вышли на структуру персонажа<br>
	Далее нашли оффсеты до координат и прочего.<br><br>
	Самое интересное оказалось то, что можно изменить скорость персонажа прямо с клиента, а сервер будет воспринимать это как действительную скорость персонажа<br>
	Обычная скорость игроков на сервере порядка 5-6 м/с в зависимости от класса персонажа, довольно обычная расстановка в ммо играх<br><img alt="Raaky4F.png" class="ipsImage" height="28" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="181" data-src="https://i.imgur.com/Raaky4F.png"></p>

<p>
	 
</p>

<p>
	Изменив скорость персонажа с клиента у сервера не возникло вопросов, а легально ли это и просто съело это.<br>
	Путем проб и ошибок я подобрал значение скорости [м/с] которое допустимо записью в адрес. Это 15 м/с<br><img alt="yKhzxt1.png" class="ipsImage" height="29" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="185" data-src="https://i.imgur.com/yKhzxt1.png"></p>

<p>
	 
</p>

<p>
	Скорость 15 м/с считается максимальной скоростью передвижения персонажа на сервере (Когда мы передвигаемся пешочком)<br>
	Но скорости в 15 м/с ведь мало , без каких либо бафов на ускорение и пр. <img alt=":D" data-emoticon="" height="20" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" srcset="https://old.gamehacklab.ru/uploads/emoticons/biggrin@2x.png 2x" title=":D" width="20" data-src="https://old.gamehacklab.ru/uploads/emoticons/default_biggrin.png"><br>
	Поэтому пробуем увеличить до 20 м/с простой записью и персонажа начинает откидывать назад при перемещении<br>
	Тут у меня есть предположение исходя из пошаговой отладки, что  переходе через порог допустимого значения, сервер начинает сбрасывать скорость персонажа до 5-6 м/с опять же в зависимости от класса<br><br>
	Но на сервере есть всякие плюшки на ускорение персонажа, этим мы и воспользуемся<br>
	Установлено что максимальная скорость без бафов 5-6 м/с. С бафами 15-20 м/с<br><br>
	Опять же путем проб и ошибок было выяснено что можно преодолеть эти 15 м/с<br>
	А преодолеть их можно путем наложения бафа ускорения на персонажа, которое работает примерно по такому принципу<br>
	curSpeed = (15.0*2)<br><img alt="iuixhBD.png" class="ipsImage" height="95" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="453" data-src="https://i.imgur.com/iuixhBD.png"></p>

<p>
	 
</p>

<p>
	Значит мы можем это легко использовать и нас не будет откидывать. Звучит неплохо<br>
	Делаем бинд на запись значения в адрес скорости. Пусть это будет 30 м/с, включаем баф на ускорение и радуемся скорости в 30 м/с без каких-либо откидываний назад<br>
	Правда такое будет работать только пока на нас весит баф на ускорение, т.е ровно 15 сек<br>
	А после окончания действия бафа нам придется довольствоваться скоростью в 15 м/с, но все равно это скорость останется постоянной и уже превышает скорость обычных игроков примерно в 2-3 раза <span><img alt=":D" data-emoticon="" height="20" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" srcset="https://old.gamehacklab.ru/uploads/emoticons/biggrin@2x.png 2x" title=":D" width="20" data-src="https://old.gamehacklab.ru/uploads/emoticons/default_biggrin.png"></span><br><img alt="NaVC0z4.png" class="ipsImage" height="41" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="176" data-src="https://i.imgur.com/NaVC0z4.png"></p>

<p>
	 
</p>

<p>
	Вопрос остается в том, как же обойти или сделать так, чтобы значение подстраивалось в нужное когда на нас висит нужный баф<br>
	Делается довольно просто, путем чтения ID бафа на ускорение и его проверки на существование<br>
	Необходимо найти какой-то список бафов и после читать его каждые допустим 20 мс<br>
	А при нужном ID бафа просто менять значение скорости персонажа. Все довольно примитивно<br><br>
	Выйти на массив бафов нам поможет счетчик кол-ва бафов персонажа, который должен быть где-то в памяти игры<br>
	*Стандартные процедуры в СЕ. 1-2-3-4 бафа, сканируем, потом находим указатель на этот счетчик*<br>
	И в итоге оказывается что этот счетчик лежит прямо в структуре персонажа, хотя мб и логично<br>
	В некоторых играх может быть и иначе<br><br><img alt="SznBLog.png" class="ipsImage" height="102" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="640" data-src="https://i.imgur.com/SznBLog.png"><br>
	Выше над счетчиком и лежит наш список бафов, смещение между бафами ровно в 0x12<br><img alt="1bChTn4.png" class="ipsImage" height="109" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="640" data-src="https://i.imgur.com/1bChTn4.png"></p>

<p>
	 
</p>

<p>
	Узнаем наш ID ускорения и запоминаем<br><br>
	Остается теперь написать программу которая поможет нам делать все манипуляции с памятью<br><img alt="lWasND3.png" class="ipsImage" height="349" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="640" data-src="https://i.imgur.com/lWasND3.png"><br><br>
	Запускаем, проверяем
</p>

<div class="ipsEmbeddedVideo">
	<div>
		<iframe allowfullscreen="true" frameborder="0" height="270" src="https://gamehacklab.ru/applications/core/interface/js/spacer.png" width="480" data-embed-src="https://www.youtube.com/embed/AzToF8yse_E?start=2&amp;feature=oembed"></iframe>
	</div>
</div>

<p>
	 
</p>
]]></description><guid isPermaLink="false">247</guid><pubDate>Wed, 19 Jun 2019 14:09:37 +0000</pubDate></item></channel></rss>
