Перейти к содержанию
  • записи
    104
  • комментариев
    125
  • просмотра
    15 632

Некоторые приемы создания читов


MasterGH

964 просмотра

1. Персонаж падает с большой высоты и разбивается

 

Ищем адрес скорости прыжка прыгая под speedhack. Находим эту скорость. Ставим бряк на доступ. Прыгаем.

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

- Либо по одной

- Либо рискнем по половине от половины

- Либо рискнем и все сразу занопим

 

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

 

2. Как делать супер прыжок

Ищем под speedhack скорость float (назовем её velocityZ, Z - вертикальная ось) по вертикальной оси прыгая персонажем. Когда прыгаем. то скорость в один момент увеличивается. Затем, скорость постоянно уменьшается от положительного до отрицательного значения.  Когда на земле, то скорость быстро записывается и равна нулю.

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

Дальше ставим бряк на запись на этот адрес и снимаем speedhack

Прыгнули и увидели инструкции. Например одна из них будет

movss [rdi+0000010C],xmm0

и работает каждый раз при прыжке по одному разу за прыжок (прыгнули — сработала, прыгнули — сработала).

Вот в неё и легко сделать инъекцию с рядом стоящими адресами с умножением на scale величину. Все и персонаж будет с суперпрыжком. Чтобы он не разбивался при прыжке смотрим пункт1

Спойлер


{ Game   : HelloNeighbor-Win64-Shipping.exe
  Version: 
  Date   : 2018-03-10
  Author : MasterGH

  This script does blah blah blah
}

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

 
 
aobscanmodule(INJECT_SuperJump2,HelloNeighbor-Win64-Shipping.exe,FF 90 80 07 00 00 48 8B 07 41) // should be unique
alloc(newmem,$1000,"HelloNeighbor-Win64-Shipping.exe"+10759DE)
alloc(newmem2,$1000,"HelloNeighbor-Win64-Shipping.exe"+10759DE)

label(code)
label(return)

label(scaleXY)
label(scaleZ)
registersymbol(scaleXY)
registersymbol(scaleZ)

newmem2:
scaleXY:
 dd (float)4
scaleZ:
 dd (float)4

newmem:
  movss xmm0,[rdi+00000104] // LEFT or RIGHT
  mulss xmm0,[scaleXY]
  movss [rdi+00000104],xmm0

  movss xmm0,[rdi+00000108] // FORWARD or BACKWARD
  mulss xmm0,[scaleXY]
  movss [rdi+00000108],xmm0

  movss xmm0,[rdi+0000010C] // UP or DOWN
  mulss xmm0,[scaleZ]
  movss [rdi+0000010C],xmm0
code:
  call qword ptr [rax+00000780]
  jmp return


INJECT_SuperJump2:
  jmp newmem
  nop
return:
registersymbol(INJECT_SuperJump2)

[DISABLE]
//code from here till the end of the code will be used to disable the cheat
INJECT_SuperJump2:
  db FF 90 80 07 00 00

unregistersymbol(INJECT_SuperJump2)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "HelloNeighbor-Win64-Shipping.exe"+10759DE

"HelloNeighbor-Win64-Shipping.exe"+107599E: F3 0F 58 00                    -  addss xmm0,[rax]
"HelloNeighbor-Win64-Shipping.exe"+10759A2: F3 0F 11 87 04 01 00 00        -  movss [rdi+00000104],xmm0
"HelloNeighbor-Win64-Shipping.exe"+10759AA: F3 0F 10 48 04                 -  movss xmm1,[rax+04]
"HelloNeighbor-Win64-Shipping.exe"+10759AF: F3 0F 58 8F 08 01 00 00        -  addss xmm1,[rdi+00000108]
"HelloNeighbor-Win64-Shipping.exe"+10759B7: F3 0F 11 8F 08 01 00 00        -  movss [rdi+00000108],xmm1
"HelloNeighbor-Win64-Shipping.exe"+10759BF: F3 0F 10 40 08                 -  movss xmm0,[rax+08]
"HelloNeighbor-Win64-Shipping.exe"+10759C4: F3 0F 58 87 0C 01 00 00        -  addss xmm0,[rdi+0000010C]
"HelloNeighbor-Win64-Shipping.exe"+10759CC: F3 0F 11 87 0C 01 00 00        -  movss [rdi+0000010C],xmm0
"HelloNeighbor-Win64-Shipping.exe"+10759D4: 48 8B 8F 88 01 00 00           -  mov rcx,[rdi+00000188]
"HelloNeighbor-Win64-Shipping.exe"+10759DB: 48 8B 01                       -  mov rax,[rcx]
// ---------- INJECTING HERE ----------
"HelloNeighbor-Win64-Shipping.exe"+10759DE: FF 90 80 07 00 00              -  call qword ptr [rax+00000780]
// ---------- DONE INJECTING  ----------
"HelloNeighbor-Win64-Shipping.exe"+10759E4: 48 8B 07                       -  mov rax,[rdi]
"HelloNeighbor-Win64-Shipping.exe"+10759E7: 41 B1 01                       -  mov r9l,01
"HelloNeighbor-Win64-Shipping.exe"+10759EA: 4D 8B C6                       -  mov r8,r14
"HelloNeighbor-Win64-Shipping.exe"+10759ED: 4C 89 74 24 30                 -  mov [rsp+30],r14
"HelloNeighbor-Win64-Shipping.exe"+10759F2: 33 D2                          -  xor edx,edx
"HelloNeighbor-Win64-Shipping.exe"+10759F4: 48 8B CF                       -  mov rcx,rdi
"HelloNeighbor-Win64-Shipping.exe"+10759F7: FF 90 88 06 00 00              -  call qword ptr [rax+00000688]
"HelloNeighbor-Win64-Shipping.exe"+10759FD: 44 38 B7 AC 01 00 00           -  cmp [rdi+000001AC],r14l
"HelloNeighbor-Win64-Shipping.exe"+1075A04: 75 36                          -  jne HelloNeighbor-Win64-Shipping.exe+1075A3C
"HelloNeighbor-Win64-Shipping.exe"+1075A06: 48 8B 07                       -  mov rax,[rdi]

 

 

Еще один вариант — не писать инъекцию кода, а искать адрес силы прыжка в структуре.

Это можно сделать меняя значения в структуре где-то рядом с [rdi+0000010C] и смотреть что происходит в игре. Можно найти, а можно и не найти, и возможно этот процесс будет долгий.

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

 

3. Менять данные в структурах или менять код?

 

В примере выше пришлось создать два новых поля

scaleXY:
 dd (float)4
scaleZ:
 dd (float)4

И умножать их на скорости X,Y,Z персонажа.

Спойлер

  movss xmm0,[rdi+00000104] // LEFT or RIGHT
  mulss xmm0,[scaleXY]
  movss [rdi+00000104],xmm0

  movss xmm0,[rdi+00000108] // FORWARD or BACKWARD
  mulss xmm0,[scaleXY]
  movss [rdi+00000108],xmm0

  movss xmm0,[rdi+0000010C] // UP or DOWN
  mulss xmm0,[scaleZ]
  movss [rdi+0000010C],xmm0

 

 

С одной стороны больше кода писать и добавлять новые поля, а с другой стороны выделить время и найти подход к поиску значения стартовой скорости в структуре. Можно в структуре ничего не искать, а написать скрипт выше и это может быть быстрее чем искать в структуре. С другой стороны если в структуре рандомно ставить параметры в течении времени X на 4К байт, то можно найти: адрес скорости, адрес гравитации, адрес чувствительности и много чего еще.

 

И еще одно ограничение. Расструктуризация не всегда правильная. Упорно вместо float может видеть 4 байта.  Это в лучшем случае, в худшем разные смешения смержены и выводятся разные типы данных.

В общем исследование игровой структуры эта тема интересная. Можно сказать это поиск свойств, по которым будет меняется поведения персонажа в игре. Структуру желательно обследовать какой оффест, что делает и какого он типа (через брейкпоинт). Это всего 4К байт проанализировать. Каждое смещение подписать и сохранить. Сделав это вы скажите себе я исследовал всю структуру и знаю, что делает смещение.

 

Lua может помочь автоматизировать анализ структур и пока я думаю об этом. Данные структур могут сильно повлиять на поведение персонажа,  на прохождение потоком отладочных инструкций игры по разным условиям — выполнять и не выполнять ответвления кода с разными условиям. В общем есть над чем подумать.

 

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

  • Понравилось 2
  • Плюс 2

0 Комментариев


Рекомендуемые комментарии

Комментариев нет

Пожалуйста, войдите, чтобы комментировать

Вы сможете оставить комментарий после входа в



Войти
×
×
  • Создать...

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

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