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

Регенерация - постоянный рост значения


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

Здравствуйте. Меня интересует способ прикрутить регенерацию параметра в игре, где такая регенерация не предусмотрена. Для примера можно взять, допустим, первую Diablo. Здоровье и ману взломать там не так сложно, хоть они и зашифрованы (в памяти хранится умноженное в 64 раза), но с замороженными играть не очень интересно. Вот хотелось бы извратиться, и прикрутить туда регенерацию здоровья и маны.


Как я понимаю, проще всего сделать это с помощью скрипта (хотя в Cheat Engine я не сильно разбираюсь, вдруг там есть какой-то подходящий встроенный инструмент). Попробовал написать черновик первого скрипта, но поскольку раньше никогда не писал скрипты и не знаю ассемблер, прошу сильно не пинать. :)

 

Спойлер

[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat

 
aobscanmodule(MP,Diablo.exe,39 01 7E 02 89 01 C3) // should be unique
alloc(newmem,$1000)

label(code)
label(return)
label(mregen_flag) // флаг, что ману можно повышать
registersymbol(mregen_flag)
label(mregen) // значение, на которое повысится мана при регенерации (х64)
registersymbol(mregen)

newmem:
  {нужно как-то сделать, чтобы флаг становился = 1 каждые 2 секунды, например}
  cmp [ecx],[ecx+4] // сравниваем значение маны с максимальным
  jnl code // если не меньше максимума, ничего не делаем
  add [ecx],mregen // увеличиваем ману на (mregen/64)
  mov byte ptr [mregen_flag],0 // флаг обратно на 0
  {дальше проверка, чтобы полученное значение было не больше максимума, иначе меням на максимум}
  cmp [ecx],[ecx+4] // сравниваем значение маны с максимальным
  jle code // если максимум не превышен, заканчмваем
  push dword ptr [ecx+4] // максимум маны в стек
  pop dword ptr [ecx+4] // теперь мана равна максимуму

code:
  cmp [ecx],eax
  jle Diablo.exe+4FD89
  mov [ecx],eax
  jmp return

mregen_flag:
  db 0

mregen:
  db 40

MP:
  jmp newmem
  nop
return:
registersymbol(MP)

[DISABLE]
//code from here till the end of the code will be used to disable the cheat
MP:
  db 39 01 7E 02 89 01

unregistersymbol(MP)
unregistersymbol(mregen_flag)
unregistersymbol(mregen)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "Diablo.exe"+4FD83

"Diablo.exe"+4FD60: 8D 91 C4 65 68 00     -  lea edx,[ecx+Diablo.exe+2865C4]
"Diablo.exe"+4FD66: 39 02                 -  cmp [edx],eax
"Diablo.exe"+4FD68: 7E 02                 -  jle Diablo.exe+4FD6C
"Diablo.exe"+4FD6A: 89 02                 -  mov [edx],eax
"Diablo.exe"+4FD6C: 8D 91 E0 65 68 00     -  lea edx,[ecx+Diablo.exe+2865E0]
"Diablo.exe"+4FD72: B8 00 F4 01 00        -  mov eax,0001F400
"Diablo.exe"+4FD77: 39 02                 -  cmp [edx],eax
"Diablo.exe"+4FD79: 7E 02                 -  jle Diablo.exe+4FD7D
"Diablo.exe"+4FD7B: 89 02                 -  mov [edx],eax
"Diablo.exe"+4FD7D: 8D 89 F4 65 68 00     -  lea ecx,[ecx+Diablo.exe+2865F4]
// ---------- INJECTING HERE ----------
"Diablo.exe"+4FD83: 39 01                 -  cmp [ecx],eax
"Diablo.exe"+4FD85: 7E 02                 -  jle Diablo.exe+4FD89
"Diablo.exe"+4FD87: 89 01                 -  mov [ecx],eax
// ---------- DONE INJECTING  ----------
"Diablo.exe"+4FD89: C3                    -  ret 
"Diablo.exe"+4FD8A: 56                    -  push esi
"Diablo.exe"+4FD8B: 8B F1                 -  mov esi,ecx
"Diablo.exe"+4FD8D: 83 FE 04              -  cmp esi,04
"Diablo.exe"+4FD90: 72 0D                 -  jb Diablo.exe+4FD9F
"Diablo.exe"+4FD92: 56                    -  push esi
"Diablo.exe"+4FD93: 68 74 18 4A 00        -  push Diablo.exe+A1874
"Diablo.exe"+4FD98: E8 AA 1B FB FF        -  call Diablo.exe+1947
"Diablo.exe"+4FD9D: 59                    -  pop ecx
"Diablo.exe"+4FD9E: 59                    -  pop ecx
}

 

Собственно, основной затык с таймером, включающим флаг.
Кроме того, похоже, что команду cmp я использую неправильно, видимо надо как-то через промежуточный регистр сравнивать. Да и проверка превышения максимума мне не нравится - сначала может превысить, и лишь потом сравнивает...

Изменено пользователем Xpromt
Код убран под спойлер.
Ссылка на комментарий
Поделиться на другие сайты

Рекомендую повнимательнее ознакомиться с правилами форума. На первый раз без преда.

 

Ошибок в коде много синтаксических, но идея, в целом, изложена правильно. Немного дополню:

1. Хранить время, прошедшее с последнего срабатывания таймера можно также в лейбле

2. Считать время можно с помощью инструкций RDTSC (db 0F 31) - рекомендую про них почитать

Ну а остальной алгоритм подсчета прошедшего времени и триггера по достижении нужного момента уж сам набросаешь, это несложно.

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

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

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

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

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