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

Невидимость ГГ в играх


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

На форуме была игра недавно про вьетнам или что-то типа того, был запрос сделать невидимость. Удобно когда, есть способность или шапка-невидимка, через которые можно найти инструкцию обнаружения NPC, но когда не за что зацепиться необходимо идти на отчаянные меры.:-D 

 

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

 

Если будем искать дистанцию, то тут либо искать изменилось/неизменилось(это долго и не факт, что найдем, то что нужно), либо искать координаты ГГ и врага, и рассчитывать дистанцию. Допустим наши координаты xyz(-256,-100,15), а врага (198,65,25):

iTXRPsCMs98.jpg

Произведя такие не сложные вычисления, мы получаем дистанция от нас до врага 483.157324 юнита. Это значение мы и будем искать в CE, а из него уже выходить на логику npc, на участок кода который нас обнаруживает. После защиты диплома появилось много свободного времени, так что этой ночью буду проверять свою теорию на практике.

Изменено пользователем partoftheworlD
  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

20 минуты назад, partoftheworlD сказал:

так что этой ночью буду проверять свою теорию на практике.

Интересная теория, удачи в исследовании, отпишись об удаче ( да и о неудаче тоже напиши).

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

2 часа назад, Garik66 сказал:

удачи в исследовании

Спасибо, у нее все же есть шанс на жизнь.

 

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

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

16ufVFIV1FA.jpg

Изменено пользователем partoftheworlD
  • Плюс 2
Ссылка на комментарий
Поделиться на другие сайты

Кстати, вам это ничего не напоминает?

bukg4QHxx-Q.jpg

Ага именно, формула расчета дистанции. Если её упростить:

 

dist = (((player_x) - enemy_x)^2 )*((player_y) - enemy_y)^2*((player_z) - enemy_z)^2)

 

Вся функция это цикл перебирающий координаты по количеству объектов и возвращающий их.

 

Скрытый текст

signed __int64 __fastcall GetDistance2Object(__int64 a1, __int64 a2)
{
  __int64 iterator; // rbx@1
  __int64 enemy; // rbp@1
  __int64 v4; // rsi@1
  signed __int64 result; // rax@1
  __int64 v6; // rdi@2
  __int64 v7; // rax@2
  float player_x; // [sp+20h] [bp-18h]@2
  float player_y; // [sp+24h] [bp-14h]@2
  float player_z; // [sp+28h] [bp-10h]@2

  iterator = *(a1 + 8);
  enemy = a2;
  *(a1 + 60) = *a2;
  v4 = a1;
  *(a1 + 64) = *(a2 + 4);
  *(a1 + 68) = *(a2 + 8);
  for ( result = iterator + 8i64 * *(a1 + 16); iterator != result; result = *(v4 + 8) + 8i64 * *(v4 + 16) )// перебираем объекты
  {
    v6 = *iterator;
    LODWORD(v7) = (*(*(*(*iterator + 8i64) + 64i64) + 8i64))(*(*iterator + 8i64) + 64i64);// получаем количество объектов
    IControlObject::GetWorldPosition(v7 + 24, &player_x);// Получаем наши координаты
    iterator += 8i64;
    *(v6 + 16) = (((*(enemy + 4) - player_y) * (*(enemy + 4) - player_y)) + ((*enemy - player_x) * (*enemy - player_x)))
               + ((*(enemy + 8) - player_z) * (*(enemy + 8) - player_z));// вычисляем дистанцию от наших координат, до координат перебираемых объектов
  }
  return result;
}

 

Вся игра написана с помощью структур  RUNTIME_FUNCTION<Начальный адрес функции, Конечный адрес функции, адрес очистки>

Изменено пользователем partoftheworlD
  • Плюс 2
Ссылка на комментарий
Поделиться на другие сайты

22 минуты назад, partoftheworlD сказал:

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

Молодца!!!:lol:

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

6 минут назад, Garik66 сказал:

Молодца!!!:lol:

Спасибо, но дальше тупик. Найденная функция возвращает координаты, в  RUNTIME_FUNCTION с которыми я только встретился и они меня пугают.:-D

Может у кого-нибудь информация есть о них и что с ними сделать можно?

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

Да уж, в общем можно выйти на функцию невидимости для npc, но слишком сложно, даже скорее одна функция не стоит потраченного времени.

 

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

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

 

А это скрин всех функций которые работают с нашей "кучей" проверок на прямую или косвенно. Ах чуть не забыл, наша "куча" проверок возвращает значение не равное 0, если мы не видимы, 0 если видимы. Но их нельзя изменить, игра начинает крашится или зомби начинают смотреть в сторону горизонта отворачиваясь от тебя.:-D Так что, нужен точечный метод взлома. На видео показан результат, но он работает только на зомби.

 

Ff-QeL7O7C0.jpg

 

Видео:

Скрытый текст

 

 

Коды:

Скрытый текст

.text:0000000000545A40                         Invisible_test  proc near               ; CODE XREF: sub_185920+E5Dp
.text:0000000000545A40                                                                 ; sub_185920+E6Bp ...
.text:0000000000545A40 48 83 B9 68 09 00 00 00                 cmp     qword ptr [rcx+968h], 0
.text:0000000000545A48 74 1E                                   jz      short loc_545A68
.text:0000000000545A4A 48 8B 81 70 09 00 00                    mov     rax, [rcx+970h]
.text:0000000000545A51 48 85 C0                                test    rax, rax
.text:0000000000545A54 74 12                                   jz      short loc_545A68
.text:0000000000545A56 48 83 B8 B8 05 00 00 00                 cmp     qword ptr [rax+5B8h], 0
.text:0000000000545A5E 74 08                                   jz      short loc_545A68
.text:0000000000545A60 48 8B 80 C0 05 00 00                    mov     rax, [rax+5C0h]
.text:0000000000545A67 C3                                      retn
.text:0000000000545A68                         ; ---------------------------------------------------------------------------
.text:0000000000545A68
.text:0000000000545A68                         loc_545A68:                             ; CODE XREF: Invisible_test+8j
.text:0000000000545A68                                                                 ; Invisible_test+14j ...
.text:0000000000545A68 33 C0                                   xor     eax, eax
.text:0000000000545A6A C3                                      retn
.text:0000000000545A6A                         Invisible_test  endp

// устанавливаем значение rcx+968, больше 0, пропускаем проверки
__int64 __fastcall Invisible_test(__int64 a1)
{
  __int64 v1; // rax@2
  __int64 result; // rax@4

  if ( *(a1 + 0x968) && (v1 = *(a1 + 0x970)) != 0 && *(v1 + 0x5B8) )
    result = *(v1 + 0x5C0);
  else
    result = 0i64;
  return result;
}
Изменено пользователем partoftheworlD
  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

11 минуту назад, partoftheworlD сказал:

даже скорее одна функция не стоит потраченного времени.

А можешь видео в виде урока записать? Начиная от начала поисков и до конца. Или слишком долго?

12 минуты назад, partoftheworlD сказал:

Видео:

Молодца!!! :-D

Особенно концовка, качественно ты зомбаку голову открутил.;) 

 

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

8 минут назад, Garik66 сказал:

А можешь видео в виде урока записать? Начиная от начала поисков и до конца. Или слишком долго?

Попробую упростить поиск, т.к. мы все равно выходим на структуру способностей и не надо искать дистанцию, структуру ГГ. Если получится упростить поиск, то сделаю, а так думаю минут на 20-30 затянется. Это вообще похоже на скрытие с помощью маскировки кровью.

Да и повторить надо, а то все что делал ночью вообще не помню, хорошо хоть комментировал.:-D

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

Нашел из-за чего некоторые зомби видели нас, а некоторые нет. В первом скрипте я просто изменил переход, но дальше было условие при котором мы либо проверяем дальше остальные условия,  если значение равно 1 т.е. при нормальной маскировке, либо выходим из функции и возвращаем 0 ,если значение равно 0. Но после выхода, возвращенное значение еще раз проверялось, вот там то и была проверка для остальных зомби. Теперь можно наслаждаться видом уродцев вблизи:-D.

 

 

Обновлена таблица.

 

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

4 часа назад, Garik66 сказал:

Молодца 2!!! :D

Спасибо

 

Все равно не то, что задумывалось изначально.Я думал сейчас раз-раз быстренько одна инструкция на всех работает и отключает детектирование, :-D

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

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

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

В общем в любом случае читаются координаты игрока из адреса. Поэтому можно попробовать, найти адрес координаты Z. Поставить бряк на чтение. Побегать без преследования. Затем побегать с преследованием и новые инструкции попробовать аккуратно изменить. Нопить, скорее всего нельзя, т.к. там будет типа FLD. Подставить какой-нибудь левый адрес с другими координатами. Или же подставить координаты самого бота.
 



fakePosition:
dd 0
dd 0
dd 0

codeInjection:
fld [fakePosition]

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

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

1 час назад, MasterGH сказал:

 

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

 

Интересно, вот если npc глазами следят, крутят головой при перемещении ГГ, это можно как-нибудь использовать?

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

1 час назад, MasterGH сказал:

есть прием

Согласен с 

 

53 минуты назад, partoftheworlD сказал:

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

Только MasterGH хочу уточнить 

 

1 час назад, MasterGH сказал:

Подставить какой-нибудь левый адрес с другими координатами.

правильно ли я понял, подставляем вместо координат ГГ.

Тогда можно наверное типа двойника ГГ сделать, который будет дальше метров на 5, пусть за ним боты бегают.:D;)

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

ЗЫ: кстати partoftheworID, качнул твою табличку, чтобы посмотреть прыжки в скриптах на невидимость.

ты прыжок:

// вместо этого:
// jae gamedll_x64_rwdi.dll+BEF95C
// этот:
jmp gamedll_x64_rwdi.dll+BEF95C
// не пробовал?

Мне кажется, что там возврат

"gamedll_x64_rwdi.dll"+BEF95C: 32 C0                 -  xor al,al
"gamedll_x64_rwdi.dll"+BEF95E: 48 8B 5C 24 38        -  mov rbx,[rsp+38]
"gamedll_x64_rwdi.dll"+BEF963: 48 83 C4 20           -  add rsp,20
"gamedll_x64_rwdi.dll"+BEF967: 5E                    -  pop rsi
"gamedll_x64_rwdi.dll"+BEF968: C3                    -  ret              // Этот возврат

как раз из всех проверок.

 

Если не проверял, проверь мою догадку ПЖЛСТа:rolleyes:

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

24 минуты назад, Garik66 сказал:

Мне кажется, что там возврат

Проверил только что

JBeOuR-l6xE.jpg

 

 

Под спойлером код в виде графика, красным выделен нормальный ход кода, зеленым после взлома.Те которые не ровные линии.

Скрытый текст

6q2V6fKWQaw.jpg

 

 

jl был выбран потому что, проверка происходит comiss xmm0,[rsi+14]. Где xmm0 = 0, [rsi+14] = таймер, чтобы прыжок срабатывал когда мы не используем маскировку.

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

22 минуты назад, partoftheworlD сказал:

l был выбран потому что, проверка происходит comiss xmm0,[rsi+14]. Где xmm0 = 0, [rsi+14] = таймер, чтобы прыжок срабатывал когда мы не используем маскировку.

Жаль что интуиция меня подвела.

А твой способ всё-таки значит это использование какой-то игровой способности, а не настоящая невидимость получилось? (т.е. ты типа всегда кровью намазан и зомбаки за своего держат?:D)

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

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

Позже попробую поискать прием как описал выше MasterGH.

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

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

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

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