PDA

Просмотр полной версии : [Руководство] Патчим клиент на использование автопота без сферы алхимика


N00bSa1b0t
03.07.2014, 20:02
Всем привет.
Все знают, что в ПВ встроена функция автопота (с предпоследнего обновления, если не ошибаюсь), однако жадные китайцы требуют для него наличие в инвентаре некоего предмета под названием "Сфера алхимика". А где эта сферу взять? Конечно же в шопе.
Но, обогощать локализатора и разработчика - это не наш метод. Данная статья расскажет о том, как вручную пропатчить клиент так, чтобы можно было использовать автопот без всяких там сфер.

Итак, что для этого нужно:
1) Клиент ПВ. У меня был руофф клиент 1.5.1, последняя версия на текущий день.
2) Cheat Engine
3) Olly Debugger
4) Ida (необязательно)
5) Небольшое знание ассемблера.


Что есть автопот? Автопот - это автоматическое использование зелий, в зависимости от некоторых условий, например, от уровня здоровья персонажа.
Известно, что наличие "сферы алхимика" проверяется только лишь на клиенте, а сам сервер не знает, кто именно решил выпить банку - человек или автопот. А то, что проверяется на клиенте, может быть найдено и подправлено.
В качестве доказательства того, что автопот проверяется лишь на клиенте, можно сделать следующее: при помощи CE найти ID предмета из инвентаря и поменять его на сферу алхимика. Автопот сразу заработает.

Итак, для начала надо подумать: как именно клиент определяет может ли игрок вызвать окно автопота?
Сфера алхимика - обычный предмет. И она должна быть в инвентаре. Капитан очевидность подсказывает, что значит в клиенте есть некий алгоритм, который сканирует инвентарь и решает, можно или нельзя юзать автопот.
Варианта два - либо поиск сферы идет по клику на кнопку автопота (если она найдена - окно показывается, иначе - нет), либо поиск идет постоянно, а результат запоминается.
Итак, нам надо найти эту самую функцию сканирования инвентаря. Для этого запускаем пв, заходим в мир, запускаем СE, и вбиваем следующий адрес:

[Ссылки могут видеть только зарегистрированные и активированные пользователи]

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

Далее жмем на адрес правой кнопкой и выбираем пункт "Find out what accesses this address", что в переводе значит "Найти то, что читает память по данном адресу".

[Ссылки могут видеть только зарегистрированные и активированные пользователи]

Откроется окно, в котором CE найдет две инструкции. При этом числа в первом столбце постоянно будут расти.

[Ссылки могут видеть только зарегистрированные и активированные пользователи]

Теперь проверим нашу теорию о том, когда сканируется инвентарь. Передем в игру и нажмем Н (вызов окна автопота). Окно разумеется не появится, но и число строк в окне СЕ не изменится. Значит теория о том, что инв сканируется при попытке вызова неверна.

Итак, значит мы нашли 2 инструкции, которые сканируют инвентарь.
Рассмотрим их подробнее.

Итак, перед нами 2 одинаковые инструкции.
Происходит сравнение значения памяти по адрес ECX + 0xC со значением в регистре EDI. ECX + 0xC - это оффсет до айди предмета. А значит в EDI записан айди с которым и происходит сравнение.
Посмотрим на первую инструкцию. В нижней части окна СЕ заботливо нам показывает значение регистров процессора на момент исполнения команды.
EDI = 00008F9C
А теперь переведем в 10-ную систему: 8F9C = 36764
Ну-ка, глянем в базу, что это такое..Да это ж сфера алхимика!
Значит эта функция и есть то, что нам надо.
Но, давайте в этом убедимся. Нажимаем на кнопку "Show disassembler".
Данная функция должна где-то изменять регистр EDI, записывая туда айдишник вещи. Чуть выше видно команду mov edi, [...]
Опускаемся на команду ниже, щелкаем правой кнопкой и выбираем Set breakpoint. Игра тут же остановится. Запишем в отдельный файл значения регистра EDI, и нажмем F9, чтобы разрешить игре работать дальше. Она опять остановится. но значение EDI будет уже чуть другое. Через пару кликов F9 мы узнаем, что данная функция записывает в EDI айдишники карты жизни и всех видов сфер алхимика.

У тех, у кого есть IDA+hexray, могут по-другому взглянуть на эту функцию. Достаточно открыть elementclient.exe в IDA, перейти по нужному адресу и нажать F5. Перед вашими глазами предстанет си-подобный код.

[Ссылки могут видеть только зарегистрированные и активированные пользователи]

Теперь явно виден цикл прохода по инвентарю. Также видно, что второй аргумент есть ни что иное как айди вещи для проверки. Функция возвращает номер слота, если вещь найдена, либо -1, если вещи нет.

Итак, работу функции мы поняли, осталось только подкорректировать ее.


Итак, нам нужно изменить функцию так, чтоб клиент думал, что сфера алхимика у нас есть. Это можно сделать двумя путями:
1. "грязный" - изменить функцию так, чтобы она всегда возвращала, например, 0. Т.е. любой предмет будет найдет.
2. "чистый" - возвращать не -1 только тогда, когда идет поиск сферы алхимика.
Я выбрал 2й путь. Откроем клиент в Olly и найдем нашу функцию

[Ссылки могут видеть только зарегистрированные и активированные пользователи]

Видно, что после нее идет 8 свободных байт. Строчки
POP EDI
POP ESI
RETN 8
обязательны, т.к. гарантируют восстановление регистров из стека и возврат нужного значения.
Места немного, но попробуем извернуться.
Нам надо проверить регистр EDI на равенство с число 36764. В случае равенства записать в EAX единичку.
Итак, выделим вышеупомянутые строчки, скопируем их куда-нибудь, чтоб не забыть.
После команды OR EAX,FFFFFF напишем
CMP EDI, 8F9C
Не пойдет..Слишком много байт уходит, т.к. 8F9C представляется в виде dword'а и мы теряем 2 байта в никуда.
Подумаем, а надо ли нам проверять весь регистр EDI? Мы знаем, что число 8F9C вполне укладывается в 2 байта, значит из 4-х байтного регистра можно проверять лишь младшую часть.
Напишем
CMP DI, 8F9C
Во, теперь команда занимает меньше.
Но мы видим что места тут остается мало, поэтому я принял такое решение - в случае равенства сделать джамп на свободное место.
Команда джампа в случае равенства:
JE ADDRESS
На свободном участке пишем MOV EAX,1
JMP ADDRESS

Этот джамп нужен для того, что вернуться обратно в нашу функцию.

Вот что у меня вышло

[Ссылки могут видеть только зарегистрированные и активированные пользователи]

Красным помечены измененные места.

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

Жду вопросов, пожеланий и прочего.

Руководство написано специально для сайта zhyk.ru, автор N00bSa1b0t. При копировании сохраните авторство :)

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

PS
Как выяснилось данная функция еще проверяет наличие колокола телепортации. Однако с ним ничего не поделаешь, проверка на сервере.

PPS
Вторая функция чтения инвентаря ищет итемы с авто-активацией: купоны и т.п.

iGesha
04.07.2014, 10:42
Патчеры поступают проще - просто перепрыгивают инструкцию записи -1 в EAX. Способ более тупой, зато не нужно теснить код и заморачиваться с джампами.
А вот за алгоритм поиска функции спасибо.
Кстати, править код можно прямо из отладчика CE, не прибегая к Olly.

N00bSa1b0t
04.07.2014, 12:10
просто перепрыгивают инструкцию записи -1 в EAX.
Я сначала тоже сделал такой "грязный" способ. В итоге не смог пользоваться телепортом :) Данная функция проверяет еще наличие колокола, и получалось, что он вроде у меня есть. А когда сервер проверял инв - то его нету. И тп не срабатывал.

Smertig
05.07.2014, 00:23
Я тоже немного порылся.
Ставим бряк на первый адрес, сразу ловим какой-то поток. Бряк убираем, жмём Shift-F8 (выполнить до ret и после ret остановиться).
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
А вот теперь можно баловаться!
Для начала я попробовал изменить айдишник по одному из адресов:
00C1FDE0
00C1FDE4
00C1FDE8
00C1FDEC
Прописал 0 - отказался работать. FFFFFFFF - тоже
Если прописать айди вещи, которая у вас в рюкзаке всегда, то будет работать.
Итого, уже патч уложился в 4 байта. Но это не предел.
Самый банальный способ - вместо строк:
push 00
push eax
mov ecx,edi
call 4C5A50

Поставить

mov eax, 1
nop
nop
..

Способ еще проще - заменяем условный
jle 0040DDF8
на безусловный
jmp 0040DDF8
Получаем патчер, меняющий 1 байт /problem
Проверил, телепортация работает.
Какие еще способы?
Вернул всё на место, пошёл проверять, куда возвращает функция проверки один или ноль.
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Затёр je 0040E21D
Сфера работает /dgs
Вернул обратно. Сфера всё равно работает /horror Похоже, я что-то случайно испортил в предыдущей функции, поэтому пришлось переписать её так, чтобы она всегда возвращала 0. (в конце вместо mov al,01 - mov al,00)
Если прыжок не затирать, функция куда-то уходит и там совсем всё печально, поэтому я не полез в те дебри

P.S. При выходе как чувствовали /dgs
[Ссылки могут видеть только зарегистрированные и активированные пользователи]

iGesha
07.07.2014, 23:12
Извиняюсь за небольшой оффтоп, но дабы не плодить тем. Пользуясь тем же способом, нашёл вызов этого бесящего окошка, предлагающего купить карту жизни при низком уровне HP. Не мудрствуя лукаво, меняю условный переход на безусловный и - окошко больше не лезет :forward: Получился патч на 2 байта (1 если не менять адрес джампа).
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Попутно попалась функция, выводящая над головой всплывающее сообщение "Недостаточно МП/ХП" (вызывается с адресов 0x46AB94 и 0x46ABC4 для ХП и МП соответственно).
Для поиска мониторил доступ к ячейке текущего ХП. Из 5 мест они сканируются непрерывно с разной скорость. 6-е место сканирует только при активном окне игры. И ещё один адрес появляется при выскакивании окошка с предложением купить. Вот оно-то и нужно.

N00bSa1b0t
09.07.2014, 20:29
Надо делать подобный гайд на зумхак? :) Только что покопался в CE и сделал его)

VeTaL_UA
09.07.2014, 21:35
Надо делать подобный гайд на зумхак?
Может я злой очень, но как бы в зумхаке одно условие изменить, какой гайд? о_О

Smertig
09.07.2014, 21:39
Может я злой очень, но как бы в зумхаке одно условие изменить, какой гайд? о_О
Если написать только про изменение джампа, то конечно не получится гайд.
Если подробно расписать, как было найдено условие, расписать разные способы, то будет довольно полезно. И добавить туда еще джамп в качестве еще одого примера
P.S. Со сферой тоже только одно условие, если спустится на функцию ниже (мой пост выше)

Dinmaite
09.07.2014, 21:41
Угу, давайте плодить сущности и еще и джамп туда пихать :)

VeTaL_UA
09.07.2014, 21:46
Эммм... Сделаю работу за вас:
[Ссылки могут видеть только зарегистрированные и активированные пользователи]

Smertig
09.07.2014, 22:00
Может я злой очень, но как бы в зумхаке одно условие изменить, какой гайд? о_О

Угу, давайте плодить сущности и еще и джамп туда пихать

[Ссылки могут видеть только зарегистрированные и активированные пользователи]

Dinmaite
09.07.2014, 22:02
Так я о том и говорю. Зачем плодить сущности? Статьи давно на форуме и актуальность им потерять сложновато, даже за 4 года.

Smertig
09.07.2014, 22:06
Так я о том и говорю. Зачем плодить сущности? Статьи давно на форуме и актуальность им потерять сложновато, даже за 4 года.
Но зумхака нет /problem
На самом деле я просто забыл про эти статьи. Тогда и правда не стоит писать второй раз. Лучше порыть что-нибудь новое и интересное.

Если флуд, то стирайте, не люблю нарушать

N00bSa1b0t
09.07.2014, 23:03
Ну я подумал все расписать, со скриншотами и своими размышлениями :) Ну, не хотите, как хотите)

iGesha
10.07.2014, 21:25
Напиши лучше про полёт без разгона. Про это нигде не встречал информации.
Патчер добавляет инструкцию
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Вот что это за загадочное смещение такое -8E4?
В прошлой версии оно было другим.

Dinmaite
11.07.2014, 00:13
Даже и не думайте писать про полет без разгона :)
Слава богу про то знают не так много людей.
Так сказать эксклюзив.

Hilling
11.07.2014, 00:52
Ну я подумал все расписать, со скриншотами и своими размышлениями :) Ну, не хотите, как хотите)
А ты посмотри кто это писал? Люди, которые не одну собаку тут уже съели. Уж для кого этот гайд и нужен был, то уж точно не для них.
Хотя, что касается зумхака, то был где-то гайд, когда методом "моб виден - моб не виден" находился адрес.

iGesha
11.07.2014, 08:05
Даже и не думайте писать про полет без разгона :)
Ну и ладно, сам тогда ковырять буду. Так даже интересней :forward:

N00bSa1b0t
11.07.2014, 12:37
Лучше порыть что-нибудь новое и интересное.
Даже и не думайте писать про полет без разгона

Один говорит, порыть что-нить интересное, другой это запрещает =(
Хоть идею подкиньте тогда.

А ты посмотри кто это писал? Люди, которые не одну собаку тут уже съели. Уж для кого этот гайд и нужен был, то уж точно не для них.
А причем тут эти монстры жука? :)))
Гайд пишется для новичков, которые хотят чему-то научиться.

Ну и ладно, сам тогда ковырять буду. Так даже интересней
Можно скооперироваться, я тоже еще его не разбирал :)

VeTaL_UA
11.07.2014, 14:01
Разбирать то разбирайте, но выкладовать не спешите. ПыСы: готовьтесь осваивать команды препроцессора :)(

dimonpw2
12.07.2014, 02:04
я когда узнал что автопот не проверяется сервером, в 010 Editor искал ID сферы алхимика и менял на ID кирки, тоже работало на всех версиях.

N00bSa1b0t
12.07.2014, 02:36
сферы алхимика и менял на ID кирки
И, соответственно, если в инвентаре нет кирки - патч не работает :)

iGesha
22.07.2014, 19:34
Наконец дошли руки поковыряться в коде. В общем, сильно не углубляясь, механизм спидстарта понятен. Используются два значения из структуры персонажа - максимальная скорость полёта (HostPlayer+0x0510) и текущая скорость (HostPlayer+0x0E1C) и просто меняется ссылка с одного на другое.
Непонятно только, зачем в патчере используется EDI, если в исходном коде базовым регистром является EBX...
Максимальная скорость полёта ищется элементарным отсеиванием (снимая/одевая леталку) по увеличилось на <скорость леталки> / уменьшилось на <...>. Оба значения типа float.

Dinmaite
22.07.2014, 20:24
А вы почитайте для чего предназначен регистр EDI, и всё станет на место.