Перейти к содержанию
Авторизация  
uhx

[CS:GO] Поиск видовой матрицы + сигнатура

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

Я не буду здесь объяснять, что такое видовая матрица и для чего она нужна - для этого есть специальные книжки и статьи (раз, два)

Обычный Step-by-Step гайд с пояснениями.

Искать будем в Counter-Strike: Global Offensive, но в принципе подойдет и любая другая игра.

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

 

Значит так, сначала цепляемся к процессу игры, затем устанавливаем параметры поиска:

    Scan Type: Value between... 

    Value Type: Float

Почему именно так? Дело в том, что точное значение искать довольно рискованно.

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

Например, в csgo угол наклона (pitch) варьируется от -89.0 до 89.0 градусов , а в других играх может и прямой угол получаться, т.е. 90 градусов.

Теперь опускаем камеру до упора вниз, так что наш угол наклона получится 89 градусов. По идее, в видовой матрице это значение отобразится как ~0,999, но мы все равно будем искать диапазон.

Ну а теперь выставляем диапазон: от 0.9 до 1.1 и сканируем

u2DxHtH.png

Нам тут же нашло овер9000 значений, но ща мы их отсеим. Камеру до упора вверх и сканим теперь следующий диапазон:

8jiWAt8.png

Оп-па. Теперь значений осталось всего-ничего: 521. Нет, это конечно много, но не настолько. Можно конечно по приколу отсеить те значения, что изменились за время чтения данной строки, но тут может поджидать сюрприз: в некоторых играх камера может немного "ходить" туда-сюда. Но если вы уверены в том, что она статична, то флаг вам в руки.

Сейчас осталось только и делов: отсеить весь хлам, ну а дальше будем смотреть на найденное и анализировать.

Можно так же до упора туда-сюда камеру водить, но я сделал так: направил ее примерно параллельно земле и прожал скан от -0.2 до 0.2.

После пары-тройки дополнительных сканов у меня осталось примерно 60 значений. Многовато для ручного перебора, но я знаю, что мне нужны только "зеленые", т.е. статические адреса.

Пролистав чуть ниже, я тут же натолкнулся на целый ряд таких значений:

OrB4FX0.png

Выносим все эти ячейки в список адресов и начинаем их перебирать: ПКМ по первому же адресу -> Browse this memory region ( Ctrl + B )

Выставляем тип отображаемых значений на float, чтобы проще было наблюдать за всеми значениями матрицы. ПКМ -> Display Type -> Float ( Ctrl + 9 )

Смотрим на первую матрицу:

OMiU8MF.png

На всю матрицу у нас должно быть только 3-4 больших значения и все они должны быть в одной колонке. Ну или так: каждое четвертое значение имеет большую величину. Желательно сразу их выровнять по 4 колонке. Остальные значения находятся в диапазоне от 0 до +-1.33

Тут мы видим, что она явно какая-то не такая: Nan-значения, остальные нули и тд.

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

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

Проделываем те же действия с другими матрицами: оцениваем их визуально + меняем состояние камеры в игре и смотрим на значения.

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

YSQKKDF.png

Фиолетовым я выделил адреса второй и третьей матрицы, а между ними зеленым - интересующий участок. Как видите, здесь есть 4 довольно больших значения ( на фоне других ) и одно из них (0x1F97E26C) остается неизменным. Но в других играх оно может немного меняться: оно отвечает за угол поворота ( по часовой ). Это в тех играх, где камера туда-сюда наклоняется, например, при передвижении пресонажа, но оно в таком случае все равно не будет сильно большим.

Теперь выделяем предполагаемое начало матрицы, жмем ПКМ->Add this to address list и копируем адрес. Теперь Ctrl + G и переходим по скопированному адресу. Смотрим:

AYoooHH.png

Ба! Выглядит отлично. Значения не сравнивайте между скринами, за это время я немного подвигал камеру опять, поэтому они изменились.

Ну, оффсет для статического адреса сделать вообще не сложно: берем адрес матрицы и вычитаем из него базовый адрес модуля: 

0x1F97E264 - client.dll 0x4A7E264

Если все еще не понятно, как таки найти view matrix, то можете посмотреть видеоурок от Guided Hacking: https://www.youtube.com/watch?v=-WL1Gpe9VRo

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

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

Добавляем первое значение нашей матрицы в список адресов и ставим бряк.

n7x3jaq.png

Тут же ловим кучу инструкций, которые взаимодействуют с нашей матрицей:

MmUpBRh.png

Берем самую первую и смотрим:

X7hfeE5.png

Это похоже на какой-то метод класса матрицы, который может использоваться не только нашей матрицей, но и другими. Что-то типа оператора присвоения.

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

Ставим Breakpoint ( F5 ) на инструкцию push ebp. Это начало функции. Затем ПКМ по ней же и выбираем "Set/Change break condition" и выставляем фильтр на брейкпоинте, чтобы он остановился когда функция будет работать с нашей матрицей.

oJLmxuz.png

Тут, конечно же, адрес вашей матрицы вместо моего.

И в тот же миг "ловим" наш поток.

Смотрим на регистры и на стек:

LqD90tU.png

В регистре ecx наша матрица, стек разворачиваем на "полную" и видим такую картину:

tBWS12z.png

Это адрес функции, которая нас вызвала. В чем суть вообще того, что мы сейчас делаем? Все дело в том, что нам надо выйти на ту единственную функцию, которая работает ТОЛЬКО с нашим адресом. Т.е. там, где все начинается. Там же, вероятно, мы и сможем узнать откуда игра берет адрес этой матрицы и мы сделаем сигнатурку. Значит так, теперь снимаем наш брейкпоинт и прыгаем по адресу из нашего стека: client.dll + 67379B

Отлично. Что мы видим?

nG49HTO.png

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

Так, а с каким регистром-то у нас там работали инструкции? С ecx, точно. Смотрим буквально на пару строк выше и видим инструкцию:

lea ecx, [edi+00000284]

Похоже, тут в наш регистр загружается адрес матрицы. Хм, а сама матрица тоже лежит в какой-то структуре, адрес которой лежит в edi. А значит теперь нам надо искать ту инструкцию, которая загружает в регистр edi адрес 0x1F97DFE0.

Это уже адрес нашей структуры, т.е. ( 0x1F97E264 - 0x284 ). Теперь ищем по нему. Прокрутив в самый верх функции можно увидеть, что в edi значение перекладывается из регистра ecx.

client.dll+673740 - 55                    - push ebp
client.dll+673741 - 8B EC                 - mov ebp,esp
client.dll+673743 - 81 EC 80000000        - sub esp,00000080
client.dll+673749 - 56                    - push esi
client.dll+67374A - 57                    - push edi
client.dll+67374B - 8B F9                 - mov edi,ecx

Теперь делаем то же самое, что и в предыдущий раз: брейкпоинт (на push ebp), condition, и прыгаем на предыдущую функцию. 

Тут наблюдаем такую картину:

nbnEui9.png

Фигассе, сказал я се.

Приехали, значение вытаскивается из стека) Можно попрыгать по функции и найти когда значение пушится в стек, но мне лень, поэтому я просто прокрутил функцию в самый верх и не прогадал:

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

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

А вот и она:

qazJg1X.png

Думаю, тут все ясно. Мы поймали разрабов с поличным: адресок-то прямо вот он, в ecx кладется. Двойной клик по строчке чтоб увидеть полный адрес:

client.dll+1F2C68 - B9 E0DF971F           - mov ecx,1F97DFE0

А вот и адрес нашей структуры.

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

104ykcl.png

Получаем такую строчку:

B9 E0 DF 97 1F 50 6A 00 6A 03 83 EC 08 8D 45 DC F3 0F 11 44 24 04 F3 0F 10 45 F8 F3 0F 11 04 24

И теперь "замазываем" наш адрес, который после перезапуска игры 100% поменяется.

B9 ?? ?? ?? ?? 50 6A 00 6A 03 83 EC 08 8D 45 DC F3 0F 11 44 24 04 F3 0F 10 45 F8 F3 0F 11 04 24

Все, сигнатура готова. У меня примерно так выглядит всё в коде:

pViewMatrix = (D3DXMATRIX*) CEngine::FindPattern( "client.dll", "B9 ?? ?? ?? ?? 50 6A 00 6A 03 83 EC 08 8D 45 DC F3 0F 11 44 24 04" );

if( pViewMatrix )
{
	pViewMatrix = (D3DXMATRIX*)( *(DWORD*)( (DWORD) pViewMatrix + 1 ) + 0x284 );
}

Да, не забываем, что это адрес СТРУКТУРЫ, но не матрицы. Матрица имеет своё, внутреннее смещение по структуре: 0x284.

Сканер сигнатур сами как-нибудь сделаете, это уже к кодингу относится ;) Да и на самом деле, эту сигнатуру можно использовать даже в CE.

Изменено пользователем uhx

Поделиться сообщением


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

Не могу обычный "плюс" поставить, поэтому оставлю комментом. 

Поделиться сообщением


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

Прекрасная статья👍

Поделиться сообщением


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

Вот видео с примером подобного способа для CSS.
 


 

Поделиться сообщением


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

Хороший видео урок. Продолжай в том же духе.:)

Поделиться сообщением


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

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Предпросмотр
Авторизация  

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

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

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