Перейти к содержанию

Взлом Titan Quest


Рекомендуемые сообщения

Боле подробно как найти указатель главному герою и сделать бессмертным только его с помощью Cheat Engine.

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

Бывает так что большинство в современных играх, та найденная инструкция отвечающая за, скажем динамический адрес жизни главного героя работает и с другими персонажами и еще бывает связаны к этой инструкции предметы (Мне когда то попалась игрушка The Suffering - Ties That Bind вот там как раз такая заморочка была) и тд. Получается когда мы записываем новое условие к инструкции к примеру добавляем 500 жизни тогда все бессмертны.

Для этого нужно найти указатель к главному герою.

И так приступим:

1. Cheat Engine 6.1 (Далее по тексту просто CE)

2. Игра Titan Quest v1.01

3. Читать статью.

Запускаем игру в оконном режиме (в этой игре есть такая возможность запускать игру в оконном режиме так намного удобнее ломать игру) загружаем уровень перед нами главный герой, смотрим какое значение жизни у главного героя в нашем случае 832. рис.1

post-1568-1324070292,82_thumb.jpg

Запускаем СЕ устанавливаем настройки перед сканированием тип float. Искать точное значение так как нам известно.

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

post-1568-1324070342,5_thumb.jpg

И так нашли один правильный адрес, поставим Точка останова на Доступ смотрим рис2, как мы видим на рис2 все инструкции работает с нашим героем и врагами при изменение без указателя все бессмертны или наоборот, закрываем окно БрейкПоинта и постараемся найти указатель к главному герою, и указатель указываем при создание скрипта.

post-1568-1324070366,31_thumb.jpg

post-1568-1324070399,13_thumb.jpg

Выбираем команду Найти указатель на этот адрес, можно это делать правой кнопкой мышке по найденному адресу смотрим ри3, и в настройках поиска сделаем как на рис4, далее на кнопку Ок и сканируем нашли примерно 4151 адресов многовато правда? рис4,1

post-1568-1324070449,71_thumb.jpg

Тут ничего страшного нет далее заходим в игру меняем значение жизни главного героя и переходим в СЕ в поиск указателя нажимаем на кнопку Поиск и Отсев смотрим в рис5

post-1568-1324070568,79_thumb.jpg

post-1568-1324070579,75_thumb.jpg

В окне Отсев_а сделаем такие настройки как в рис6

1. Включаем кнопку Значение

2. Выбираем Тип (У наc Float)

3. Пишем текущее значение жизни

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

post-1568-1324070604,29_thumb.jpg

И так после долгих мучении я нашел где то 73 адресов рис7 и они не изменялись после перехода в другой уровень, после перезапуска игры, перезапуска компа бывает и такое конечно в некоторых играх останется 1,2,6, 5, 10 адресов тогда боле удачно, но все таки я нашел статичные адреса указателя, просто создаем нового персонажа в игре и там проверяем в общем так, оказалась эт такая игра.

И так у нас есть адрес указателя плюс смещение смотрим рис8

post-1568-1324070618,27_thumb.jpg

адрес указателя -> смещение + смещение + смещение = DMA

Получается так

101BE124 -> 9C + 244 + 5D8 = DMA

Время пришло к написанию скрипта так как у нас все есть.

Поставим точка останова на Доступ на адрес жизни героя смотрим рис2 знакомая картина не правда ли как я выше описал все эти инструкции связаны с нашим героем и врагами.

post-1568-1324070651,1_thumb.jpg

Все инструкции я проверял при написании скрипта остановился на этой инструкции mov eax,[esi+18] смотрим рис2 далее просто переходим в отладчик, вот так смотрится наша выбранная инструкция в памяти игры рис9 выделяем эту инструкцию далее пишем скрипт нажимаем кнопку Инструменты, Автоассемблер, далее вставка секции и внедрение кода получаем такую картинку рис10 как мы видим это уже готовый скрипт.

post-1568-1324070660,77_thumb.jpg

Я уже поправил скрипт добавил наш указатель. Конечно скрипт можно было написать по другому но только не для этой игры.

Вот и всё если будут вопросы спрашивайте постараюсь отвечать правильно.

В каждой игре свой подход найти указатель, есть еще другие способы найти указатель об этом вы можете найти в нашем форуме.

На этом всё удачного геймхакинга.

Автор статьи: ZOCKIR

Специально для: www.GameHackLab.ru

  • Плюс 3
Ссылка на комментарий
Поделиться на другие сайты

Спасибо за статью :)

Несколько вещей, которые я никогда не делаю и не советую так делать

1) Не искать указатель сканером указателей, а искать (его в отладчике + возможно использовать сканер памяти для поиска адреса)

2) Не проверять указатель перезагрукой ПК. 99% эта необходимость отпадает если применять способ в пункте1, когда мы достаточно уверены в работе указателей.

3) Не писать в АА-скриптах mov [[[..]...]..]..],(float)100 . Вместо этого нужно писать ассемблерный код.

Дело в том что

mov [[[..]...]..]..],(float)100

Будет как:

mov [адрес],(float)100

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

Желаю успехов автору статьи :)

Ссылка на комментарий
Поделиться на другие сайты

Дело в том что по другому способу я не смог найти именно указатель жизни героя, к примеру количество золото нашел с легкостью пример видео от JIeXA :)

К примеру если поработать в отладке, если поставить точка останова на доступ на инструкцию получаем вот такую картинку:

post-1568-1324117993,01_thumb.jpg

Есть вероятность того что свободные регистры в этой инструкции они будут постоянно свободный для внедрение своего чита?

Взял регистр

ebx


[ENABLE]
alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(exit)

newmem:
push ebx
cmp esi, [101BE124]
mov [esi+18],(float)832
pop ebx
je originalcode

originalcode:
mov eax,[esi+18]
fstp dword ptr [esi+1C]

exit:
jmp returnhere

"Game.dll"+27AA1:
jmp newmem
nop
returnhere:

[DISABLE]
"Game.dll"+27AA1:
mov eax,[esi+18]
fstp dword ptr [esi+1C]
dealloc(newmem)
//Alt: db 8B 46 18 D9 5E 1C

Ссылка на комментарий
Поделиться на другие сайты

>> Есть вероятность того что свободные регистры в этой инструкции они будут постоянно свободный для внедрение своего чита?

ZOCKIR, по этому участку кода на скриншоте ничего не могу сказать. Может быть да, а может быть и нет. А ebx тут зачем класть в стек и восстанавливать, если им не пользуешься?! ))

Ссылка на комментарий
Поделиться на другие сайты

Свободный регистр, в этой инструкции берем, туда помешаем наш кусок кода, не касаясь полностью инструкции, безболезненно меняем сравнивая с нашим указателем какой либо регистр. Чтоб не получить вылет или крах игры в общем помешаем наш кусок кода в стек.

Может я немножко неправильно объяснил но смысл понятен :)

Можно переделать код так но при переходе получаем вылет.


push ebx
mov ebx,esi
cmp ebx, [101BE124]
pop ebx

В общем так.

Ссылка на комментарий
Поделиться на другие сайты

Свободный регистр, в этой инструкции берем, туда помешаем наш кусок кода, не касаясь полностью инструкции, безболезненно меняем сравнивая с нашим указателем какой либо регистр. Чтоб не получить вылет или крах игры в общем помешаем наш кусок кода в стек.

Может я немножко неправильно объяснил но смысл понятен :)

А не проще сохранить все регистры через pushad, сравнить, сделать что-то и восстановить popad'ом? В приведённом тобой участке ebx никак не используется, просто кладётся в стек и восстанавливается обратно.

Ссылка на комментарий
Поделиться на другие сайты

Ну блин. Вот оригинальная инструкция:

mov eax,[esi+18]

Тут [esi+18] - указатель на какое-то значение в структуре, где esi - базовое смещение этой структуры, а в eax помещается это самое значение. Наша задача - в зависимости от базового смещения структуры (игрок или все остальные) поместить в [esi+18] нужное значение. Я бы сделал вот так:


pushad //сохраняем состояние всех регистров
cmp esi, [01234567] //сравниваем базовое смещение структуры с нужным нам
jne original //если они не равны - выполняем оригинальный код игры
mov [esi+18],new_value //если же равны - помещаем по нужному нам смещению нужное нам значение
popad //восстанавливаем регистры обратно
mov eax,[esi+18] //пишем новое значение из структуры в eax
jmp exit //возвращаем управление игровому коду

original: //оригинальный код игры
popad //сначала восстанавливаем сохранённые регистры
mov eax,[esi+18] //выполняем оригинальную инструкцию
jmp exit

Что-то я не понимаю, зачем для сравнения левый регистр использовать, когда можно это сделать с оригинальным. huh.gif

Ссылка на комментарий
Поделиться на другие сайты

Твой пример не работает keng в наличии игры, у тебя нет так что в каждой игре свой подход к написанию скрипта, при включение твоего примера игра вылетает.

Вот что я смог.


newmem:
pushad
cmp esi, [101BE124]
je originalcode
mov [esi+18],(float)1420
originalcode:
popad
mov eax,[esi+18]
fstp dword ptr [esi+1C]

В общем спс что подсказал пример.

Ссылка на комментарий
Поделиться на другие сайты

Твой пример не работает keng в наличии игры, у тебя нет так что в каждой игре свой подход к написанию скрипта, при включение твоего примера игра вылетает.

Вот что я смог.


newmem:
pushad
cmp esi, [101BE124]
je originalcode
mov [esi+18],(float)1420
originalcode:
popad
mov eax,[esi+18]
fstp dword ptr [esi+1C]

В общем спс что подсказал пример.

Я и не говорил, что код работоспособен, просто показал прицип. laugh.gif

Не за что. Вообще, ящитаю хорошей практикой всегда сохранять регистры и флаги при выполнении своего кода - мало ли что, типа.

Ссылка на комментарий
Поделиться на другие сайты

ZOCKIR, если что-то вылетает в казалось бы нормальной инъекции, то советую проверять работоспособность твоей инъекции кода в OllyDbg, а не подбирать по какому-то странному принципу инструкции которые бы подходили :) И если можно избавиться от использования pushad/popad то лучше это и делать (зачем нам сохранять и восстанавливать данные из регистров которые мы не трогаем). Если что напоминаю, что эта команда не "кладёт" в стек EIP и не кладёт регистр флагов EFLAGS.

Ссылка на комментарий
Поделиться на другие сайты

ZOCKIR, если что-то вылетает в казалось бы нормальной инъекции, то советую проверять работоспособность твоей инъекции кода в OllyDbg, а не подбирать по какому-то странному принципу инструкции которые бы подходили :) И если можно избавиться от использования pushad/popad то лучше это и делать (зачем нам сохранять и восстанавливать данные из регистров которые мы не трогаем). Если что напоминаю, что эта команда не "кладёт" в стек EIP и не кладёт регистр флагов EFLAGS.

Для флагов надо pushfd\popfd юзать. :D

PS: Разве EIP можно поменять программно? О_о

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.