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

Взлом Diablo 2 Lord of Destruction v1.13d


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

Кто-нибуть ломал игру Diablo 2 LOD.

Я написал скрипт на вечное здоровье он работает.

Но я нехочу прописывать какое либо количество здоровья, а хочу просто заморозить, при этом чтоб увеличивалось значение например

при повышения опыта ну и т.д.

Подскажите ктонибуть как исправить скрипт:

Скрипт на вечное здоровье:

[ENABLE]

alloc(newmem,32)

label(returnhere)

newmem:

mov eax,[D2Client.dll+11CA04] //Указатель на здоровье

mov eax,[eax+38] \\Сравниваю регистр по смещению от казателя

mov eax,[eax+c8] \\Второе сравнивие по смещению от указателя

mov [eax+24],00002800 \\Третье сравнение от указателя + добавляю здоровье (HEX 2800 это DEC 14080 значение).

mov ecx,[eax+04] \\Оригинальная инструкция где сработала на запись

test ecx,ecx \\Иструкция ниже под оригинальной, для логики кода

jmp returnhere

"D2Common.dll"+5839B:

jmp newmem

returnhere:

[DISABLE]

dealloc(newmem)

"D2Common.dll"+5839B:

mov ecx,[eax+04]

test ecx,ecx

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

Анализируй структуру игрока, где-то рядом со здоровьем должен лежать и его возможный максимум. Делаешь сравнение с максимумом, если меньше - делаешь запись в здоровье. Тогда при увеличении опыта автоматически будет прописываться максимум здоровья.

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

Спасибо что ответил Xipho попробывал найти структуре чё не нашёл.

Другие вариант есть.

Да и ещё хочу сказать, я просто хочу заморозить, без максимального увеличения жизней,

как пологается в игре увеличивать жизни по опыту не сразу, а постепенно.

Например так-же не будет работать вот это:

newmem:

mov eax,[D2Client.dll+11CA04] //Указатель на здоровье

mov eax,[eax+38] \\Сравниваю регистр по смещению от казателя

mov eax,[eax+c8] \\Второе сравнивие по смещению от указателя

mov eax,[eax+24] \\Третье сравнивие по смещению от указателя (Без добавления жизней)

CheatEngine выдает ошибку при создании скрипта что так нельзя.

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

  • 1 год спустя...

Народ, если тема ещё актуальна могу попробовать поломать. Мне интересно сравнить две версии 1.13 и 1.09. Для 1.09 я разбирал мод Zy-El, но и Гроздья гнева тоже нормально работали с теми же скриптами.

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

  • 2 недели спустя...

Прошло столько времени...... вобщем нужно попробовать найти идентификатор игрока ID.

И написать скрипт по другому.

Интересно чё там можно сравнивать, разве что исправление игры и новые добавки.

Если чё та интересное найдёшь скажеш A1t0r.

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

Прошло столько времени...... вобщем нужно попробовать найти идентификатор игрока ID. И написать скрипт по другому. Интересно чё там можно сравнивать, разве что исправление игры и новые добавки. Если чё та интересное найдёшь скажеш A1t0r.

 

Нашёл)

Найдём инструкцию, которая модифицирует значения параметров нашего персонажа(и не только)

6FDA837F - 8D 3C 29 - lea edi,[ecx+ebp]

6FDA8382 - 85 FF - test edi,edi

6FDA8384 - 89 78 04 - mov [eax+04],edi <<

6FDA8387 - 7E 12 - jle D2Common.Ordinal11140+14B

6FDA8389 - 8B 54 24 18 - mov edx,[esp+18]

EAX=06B54F20

EBX=05816300

ECX=00000100

EDX=00060000

ESI=05816348

EDI=00002500

ESP=0018F528

EBP=00002400

EIP=6FDA8387

Пройдя всю цепочку указателей получаем такую формулу

[6FBCCA04] => ... + 38

=> ... + C8

=> ...

+ 4 - сила

+ C - энергия

+ 14 - ловкость

+ 1C - живучесть

+ 24 - здоровье +2C - макс. здоровье

+ 34 - мана +3C - макс. мана

+ 44 - выносливость +4C - макс. выносливость

+ 5C - опыт +7С - опыт для след. уровня

Фактически текущие и максимальные значения здоровья, маны и выносливости смещены на +1 байт, т. е.

+ 25 - здоровье 2D - макс. здоровье

+ 35 - мана 3D - макс. мана

+ 45 - выносливость 4D - макс. выносливость

,а в 4 и C байтах текущих значений находятся счётчики, которые при переносе увеличивают текущее значение, если не достигнут максимум - это регенерация. Поэтому НЕ НАДО модифицировать эти значения самим. Либо морозим полное значение 4 байта при записи по этому адресу, либо извращаемся дальше)

Структура персонажа без наличия очков параметров(да, это Варвар))

=========================================================

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

---------------------------------------------------------

0000|00 00 00 00 1E 00 00 00 00 00 01 00 0A 00 00 00

0010|00 00 02 00 14 00 00 00 00 00 03 00 19 00 00 00

0020|00 00 06 00 00 37 00 00 00 00 07 00 00 37 00 00

0030|00 00 08 00 00 0A 00 00 00 00 09 00 00 0A 00 00

0040|00 00 0A 00 98 50 00 00 00 00 0B 00 00 5C 00 00

0050|00 00 0C 00 01 00 00 00 00 00 0D 00 78 00 00 00

0060|00 00 15 00 03 00 00 00 00 00 16 00 06 00 00 00

0070|00 00 1D 00 FF FF FF FF 00 00 1E 00 F4 01 00 00

0080|00 00 1F 00 05 00 00 00 00 00 43 00 96 00 00 00

0090|00 00 44 00 64 00 00 00 00 00 45 00 64 00 00 00

00A0|00 00 48 00 27 00 00 00 00 00 49 00 28 00 00 00

00B0|00 00 5F 00 0A 32 00 00 00 00 AC 00 02 00 00 00

00C0|00 00 48 01 09 00 00 00 00 00 00 00 00 00 00 00

00D0|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00E0|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00F0|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

=========================================================

D2Common.Ordinal11140+103 (6FDA8353) - 8B 7C 24 10 - mov edi,[esp+10] - в [esp+10] ID параметра

например для модификации выносливости в edi будет 000A0000, ID размещены в первых 4 байтах каждых 8-ми байт. 40h - 43h для выносливости. 00070000 28h - 2Bh для макс. здоровья и т.д.

Всё бы хорошо, сравнивай адреса по которым пишутся значения и нужные нам, НО после повышения уровня, полученные 5 очков пишутся по адресам 20h - 27h с ID=4, таким образом все значения сдвигаются на 8 байт.

После распределения этих очков всё становится на место. В скрипте при каждой записи можно сравнивать значение по адресу +22h с 4, тогда делаем правку в +8.

Наброски скрипта: !!!пока есть небольшой глюк при получении очков параметров,

может кто исправит,буду рад!!!

alloc(newmem,256)

label(returnhere)

label(originalcode)

label(changedcode)

label(not8)

label(notMax)

label(exit)

newmem:

push ebx

mov ebx, [6FBCCA04]

cmp ebx, 0

je originalcode

mov ebx, [ebx+38]

mov ebx, [ebx+C8]

lea ebx, [ebx+22]

cmp [ebx], 4

jne not8

lea ebx, [ebx+8]

not8:

lea ebx, [ebx-2]

cmp eax, ebx

je changedcode

lea ebx, [ebx+10]

cmp eax, ebx

je changedcode

lea ebx, [ebx+10]

cmp eax, ebx

jne originalcode

changedcode:

push ecx

mov ecx, edi

and ecx, FFFFFF00

cmp ecx, [ebx+C]

jle notMax

pop ecx

jmp exit

notMax:

mov ebx, [ebx+4]

and ebx, FFFFFF00

cmp ecx, ebx

pop ecx

jle exit

originalcode:

mov [eax+04],edi

exit:

pop ebx

test edi,edi

jmp returnhere

6FDA8382:

jmp newmem

returnhere:

Структура персонажа при наличии очков параметров

=========================================================

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

---------------------------------------------------------

0000|00 00 00 00 1E 00 00 00 00 00 01 00 0A 00 00 00

0010|00 00 02 00 14 00 00 00 00 00 03 00 19 00 00 00

0020|00 00 04 00 05 00 00 00 00 00 06 00 00 39 00 00

0030|00 00 07 00 00 39 00 00 00 00 08 00 00 0B 00 00

0040|00 00 09 00 00 0B 00 00 00 00 0A 00 00 5D 00 00

0050|00 00 0B 00 00 5D 00 00 00 00 0C 00 02 00 00 00

0060|00 00 0D 00 F5 01 00 00 00 00 0E 00 09 00 00 00

0070|00 00 15 00 03 00 00 00 00 00 16 00 06 00 00 00

0080|00 00 1D 00 FF FF FF FF 00 00 1E 00 DC 05 00 00

0090|00 00 1F 00 05 00 00 00 00 00 43 00 64 00 00 00

00A0|00 00 44 00 64 00 00 00 00 00 45 00 64 00 00 00

00B0|00 00 48 00 25 00 00 00 00 00 49 00 28 00 00 00

00C0|00 00 5F 00 0A 32 00 00 00 00 AC 00 02 00 00 00

00D0|00 00 48 01 20 00 00 00 00 00 48 01 20 00 00 00

00E0|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00F0|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

=========================================================

Пока всё. Дальше надо тестить на наличие других лазеек игры, чтобы навредить нам)

Всё оказалось немного сложнее, чем в версии 1.09

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

А зачем указатели? Нельзя код на прямую анализировать? То есть что обращается, что пишет? Много лишнего вы не считаете? Push и pop и все 8-)

то есть по смещению находим макс значиние жизней. Пушим макс значение и попим на инструкцию техущих хп. Вся работа...

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

А зачем указатели? Нельзя код на прямую анализировать? То есть что обращается, что пишет? Много лишнего вы не считаете? Push и pop и все 8-)

то есть по смещению находим макс значиние жизней. Пушим макс значение и попим на инструкцию техущих хп. Вся работа...

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

Теперь про анализ кода. Найденная инструкция 6FDA8384 - 89 78 04 - mov [eax+04],edi отвечает не за 1 какой-то параметр. Попробовав занопить её игра не вылетает, но: опыт игроку не добавляется, скорость всех персонажей падает, зато здоровье и мана не тратятся, а враги дохнут. И при загрузке сохранённой игры у игрока остаётся 1 жизнь, 0 маны.

Попробовал найти место вызова нашей функции происходит это в 6FDA9962.

D2Common.Ordinal10815+332 - 55 - push ebp

D2Common.Ordinal10815+333 - 56 - push esi

D2Common.Ordinal10815+334 - 50 - push eax

D2Common.Ordinal10815+335 - 57 - push edi

D2Common.Ordinal10815+336 - E8 E5E9FFFF - call D2Common.Ordinal11140+100

В eax модификатор параметра. Заменил на push ecx(там был 0). Всё работает, но опять опыт не плюсуется и снаряжение сломалось сразу))) Всё равно надо фильтровать значения и где надо push'ить 0 на место eax.

И спасибо за идею перезаписи максимальным значением, я пошёл по длинному пути, а всё оказалось проще)

Вот как теперь выглядит скрипт. Кое-что убрал после тестов:

alloc(newmem,256)

label(returnhere)

label(originalcode)

label(changedcode)

label(notID4)

label(notID5)

label(exit)

newmem:

push ebx

mov ebx, [6FBCCA04]

mov ebx, [ebx+38]

mov ebx, [ebx+C8]

lea ebx, [ebx+20] - смещение на 8 байт здоровья

cmp [ebx], 00040000 - если есть очки параметров

jne notID4

lea ebx, [ebx+8] - добавляем смещение +8

notID4:

cmp [ebx], 00050000 - если есть очки навыков

jne notID5

lea ebx, [ebx+8] - добавляем смещение +8

notID5:

cmp eax, ebx - здоровье пишется

je changedcode

lea ebx, [ebx+10]

cmp eax, ebx - мана пишется

je changedcode

lea ebx, [ebx+10]

cmp eax, ebx - выносливость пишется

jne originalcode

changedcode:

push ecx

mov ecx, [ebx+C] - берём максимальное значение

mov [ebx+04], ecx - и пишем в текущее

pop ecx

jmp exit

originalcode:

mov [eax+04],edi

exit:

pop ebx

test edi,edi

jmp returnhere

6FDA8382:

jmp newmem

returnhere:

Отличия от предыдущих версий игры есть и значительные. Например, не нужны проверки на 0 в самом начале. Инструкция mov [eax+04],edi не пишет здоровье врагов, но пишет их скорость. В общем что ни версия, то сюрприз)

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

У меня была только версия 1.13d поэтому и не знаю на сколько сильно они сместились(изменились) инструкции кода игры после патчей.

Надож было так сделать чтоб с одной инструкцией работало столько вещей. Жаль что нет официальных чит-кодов на игру.

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

А так лучше ломать игру последнюю версию и бацать тренер под него.

WarCraft'e TFT модуль игры был game.dll, может и Diabl'e 2 LOD тоже там где отвечает за жизни и т.д. типа D2game.dll всё таки обе от BLIZZARD сделаны. Может с лишком много модулей в игре, поэтому так сложно взоломать её.

WarCraft'e TFT есть такой чит код на бессмертие + убить с одного удара. Интересно было отделить бессмертие от убить с одного удара.

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

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

push ecx

mov ecx, [ebx+C] - берём максимальное значение

mov [ebx+04], ecx - и пишем в текущее

pop ecx

jmp exit

можно уточнить что мне такой расклад не совсем нравится.

А вот так не круче?

push [ebx+C]

pop [ebx+04]

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

push ecx

mov ecx, [ebx+C] - берём максимальное значение

mov [ebx+04], ecx - и пишем в текущее

pop ecx

jmp exit

можно уточнить что мне такой расклад не совсем нравится.

А вот так не круче?

push [ebx+C]

pop [ebx+04]

На здоровье :-D Сколько людей, столько и способов (ну, может чуть поменьше))

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

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

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

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