CE Dissect Data Scaner 1.0.2 (4 hardware breakpoints)
-
- Точное определение типа данных на смещениях структуры (те которые срабатывают на аппаратных брейкпоинтах);
- Показать в имени элемента структуры один из опкодов чтения или его часть (с регистрами и смещением);
- Найти такие смещения, с которыми работают только инструкции чтения за указанное время равное Accuracy * 10мс на байт в структуре. Чем выше Accuracy, тем выше вероятность убрать больше лишний смещений;
Плагин пока не планируется развивать из-за его особенности работы с 4мя аппаратными брейкпоинтами. С одной стороны это не тормозит игру, но с другой стороны нужно в игре совершать одни и те же действия чтобы по 4 байта в структуре срабатывали друг за другом до конца структуры.
Есть другие способы снимать показания на любой размер структур установкой брейкпоинта на большую область памяти указанного размера (в другом плагине, который я пока не выложил). При этом чем структура больше и чем больше в ней прерываний тем сильнее тормозит, но оно того стоит, потому что показания снимаются практически одновременно.
Это тестовая версия, поэтому могут быть ошибки при сканировании. О них можно написать мне в личку с названием игры, сигнатуры инструкции.
Если плагин вдруг заключил и пишет что-то в консоли, то нажать на кнопку Stop или для остановки ввести Lua команду
stopDissectDataScanner()
УстановкаРаспаковать в основную директорию с программой. В архиве форма, файл настроек и lua исходник.
Как работать с плагином
- Ищем параметр в игре
- Ставим "точку останова на доступ"(брейкпоинт) или "на запись"
- Находим одну из инструкций. Например, в игре Кредо Убийцы 3 это инструкция
AC3SP.exe+11BAEEB - 66 89 4E 5C - mov [esi+5C],cx
- Можно пойти двумя способами по переносу базового адреса в окно структур
4.1 На инструкции смотрим например базовый адрес ESI, он будет началом структуры. Его переносим в окно Dissect Data (открывается в отладчике). Отказываемся от всех диалогов, чтобы не получать структуру, которую создает Cheat Engine.
4.2 Определить адреса например на "[esi+5c]" в дизассемблере и на любом вызвать контекстное меню и перебросить базовый адрес в Dissect Data
-
В окне Dissect Data запускаем "Scanner" нажав на эту надпись и вводим имя структуры, размер в hex, и чувствительность поиска от 1 до 10
-
Идем как можно быстрее в игру, а она уже должна быть активна и в оконном режиме, и не в меню. Ждем пока завершится сканирование, что-то делая в игре или простоя стоим там. Если очень долго, можно уменьшить чувствительность или размер структуры в hex-е
-
После того как структура получена, мы основывать на своем опыте, ищем в структуре такие данные, которые могут повлиять на игровой процесс. Т.е. меняем что-то в структуре в байтовых, сингловых типах и смотрим в игру. Очень редко 4-х байтовые что-то дают,а поинтеры менять не надо их можно по аналогии смотреть в новых окнах.
Результаты
Нет 100% гарантии сразу найти все рабочие адреса, в которых что-то будет интересное. Большая часть может себя не проявить в игре или привести к вылетам. После определенного количества вылетов, вы поймете какие типы данных и как менять и вылетов будет меньше.
Перед потенциальными вылетами делаем сигнатуры, чтобы вернуться на инструкцию.
Вызов Lua кода после crash-а вернет адрес инструкции
local sign = 'F3 0F 11 80 EC 00 00 00' function GetAddress(signature) local t = AOBScan(signature, '+X-C-W',0) local s = t[0] t.destroy() return s end print(GetAddress(sign))
...Много зависит от ползания по структуре и внутри структур (об этом в блоге) и соответственно, нужно время.
Если времени мало. Получаем около 20 параметров структуре байтовых и сингловых. Безопасней всего менять сингловые. Их можно увеличить все в 2 раза и зайти в игру и увидеть, что там происходит. Не забываем перед правками сделать копию структуры и нажать на Lock, чтобы сравнить и откатить изменения. За тем уже правим по байтикам на ноль или на единицу. Редко бывают вылеты. Каждый адрес отмечаем, что его проверяли или удаляем. Если интересные, то меняем название. Сохраняем структуру.
Ищем так несколько структур. Все их сохраняем. Не забываем делать сигнатурки для каждой структуры, чтобы получить базовый адрес.
Собрали структуры. Ищем связи между ними. Об этом я скриншотил в блоге (ссылка выше). Опять сохраняем структуры.
На три игры я находил 1-3 полезных параметра и до 6 каких-то забавных или баговых. Например, я нашел коэффициент скольжения персонажей в структуре с координатами и там же гравитацию. Попадались адреса, которые запрещали двигаться, т.е. можно морозить ботов. Попадались байтовые адреса, меняющие руки с оружием в L4D2.
Структуры сохраняются в файл таблицы или экспортируются в отдельный файл.
Далее делаем читы, как обычно. Либо меняем код, либо меняем данные по базовому указателю через скрипты Аutoasembler
- Исправлены ошибки с определением смещения и типов данных. Это позволил сделать новый алгоритм, который анализирует все опкоды работающие с адресом и выбирает наиболее подходящие для определения смещения адреса в структуре и для определения типа данных в структуре.
Выбор лучшего опкода для определения типа данных:
- опкоды с перезаписываемыми регистрами не выбираются;
- опкоды работающие с float приоритетнее чем dword;
- опкоды без квадратных скобок пока пропускаются: всякие repe, movsd и другие
- опкоды с не правильным дизассемблированием пропускаются (невозможно получить адрес в скобках)
- Много новых данных в логах, после формирования структуры. С его помощью можно просмотреть все опкоды, которые сработали на смещении структуры.
На скриншоте пример структуры, после работы плагина
-
Проведено огромное количество опытов над структурами. Много переделок.
Очень кратко напишу, что поменялось.
- Название структуры состоит из адреса, количества адресов в ней и времени в миллисекундах на один байт в структуре.
Подчеркнуто красным
-
Смещения отбираются только те, на которых за X времени не было обнаружено ни одной инструкции на запись. Чем больше та самая чувствительность, тем точнее результат
-
В именах структур теперь ценная информация. Это смещение, регистр и тип
На скриншоте ниже можно посмотреть пункты 2 и 3.
Также на этом скриншоте я заморозил по соседству адрес (поставил Lock) и пару раз пострелял в игре Сталкере Зов Припяти
Выводы, которые я сделал за очень и очень скромное время пользования. За минут 15 и на паре структур оружия в двух разных играх L4D2 и Сталкер Зов Припяти-
Если править 4-х байтовые значения, то легко можно нарваться на вылет игры. Но подключившись снова, можно продолжить.
-
Правки значений с типом в 1 байт могут заблокировать оружие (в двух играх) или же устроить скорострельность на полную катушку в L4D2.
-
Правки значений с типом float. Можно легко нарваться на вылет в игре, если например поставить нолик. Деление на ноль или какая-то иная причина. Лучше ставить чуть больше нуля, можно положительные или отрицательные значения
-
Частенько бывают адреса в структуре, на которых включаются инструкции записи только после изменения значения. Тут я пока ничего не смог сделать, просто удалить их из структуры как лишние.
-
Для сканера используется 1 аппаратный брейкпоинт, остальные три штуки еще не используются, т.к. сложно их прикрутить. Если использовать все 4 аппаратных бряка, то скорость сканера была бы в 4 раза быстрее. Сейчас на 2К байт по 10 мс, у меня уходит где-то 150 секунд. Если я ставил 20мс, то находилось на 10 смещений больше или какие-то другие смещения пропадали.
Код будущего плагина все еще находится на стадии тестирования. Поэтому пока плагин не выкладываю.
upd1: инструкции cmp, add, sub, xor, and, not, test, mulss, fsub, fmul, dec, inc, mul; теперь выводятся в имя элемента структуры.
На скриншоте случайно вышел на координаты UI таймера. Сделал три скана трех структур в новых окнах
upd2: перемещение структуры
Итог перемещения двух структур в первую
-
Охота на структуры и удивительное путешествие в мир структур в L4D2
-
Игру L4D2 в оконный режим
-
Установка плагина (позже)
-
Установка VEH отладчика, иначе вылеты
-
Первая миссия. Ищем адрес патронов. Бряк на адрес. Нашли инструкцию
Красным показано, что я не всю структуру проанализирую позже. Долго было ждать. Структура больше 5К байт... -
Делаем сигнатуру любой инструкции при работе с патронами на всякий случай, если игра вылетит.
server.dll,83 BE 14 14 00 00 00 7F 4D
6. Переходим в код и ищем проскакивающие адреса на инструкции. Там один адрес нашего пистолета. Клик на него и переносим адрес начала будущей структуры в окно Dissect Window. Можно не создавать структуру (отказываемся). Кликаем "Scanner" (он будет на всех окнах dissrct data)
7. Далее работает сканирование.
В игре можно что-то делать, можно ничего не делать. Долго ждать..Меняю опции. Чувствительность как была так и осталась минимальная (это время ожидания прерывания на адресе умноженное на коэфициент чувсвительности и на 100 мс). Размер структуры меняю, до 1100
Наконец ~30 секунд дождался без вылетов (иногда бывают, возможно из-за VEH). Появился результат
Самые интересны это байтовые и float значения. и инструкции чтения. Их определит можно пока только по логам...Меняю первый байт на 1 и пистолет стал очень быстро стрелять.
Ради чего это все и делалось, чтобы похожие адреса искать...Если сравнить дефолтную расструктуризацию, она слева
Логи (для меня и для желающих) по определению типа по опкодам\+0 (2F3B49B0): vtDword 64FC73CB - mov edx,[ecx] \+28 (2F3B49D8): vtDword 6530433E - mov eax,[esi+28] \+4C (2F3B49FC): vtDword 651169A3 - cmp dword ptr [esi+30],00 \+4F (2F3B49FF): vtDword 651169B6 - mov eax,[esi+30] \+53 (2F3B4A03): vtDword 65116C60 - mov eax,[ecx+34] \+64 (2F3B4A14): vtByte 64F8627D - cmp byte ptr [esi+64],00 \+84 (2F3B4A34): vtDword 64F861F0 - movss xmm0,[esi+00000084] \+88 (2F3B4A38): vtDword 64F86215 - movss xmm2,[esi+00000088] \+8C (2F3B4A3C): vtDword 64F9F9A6 - movss xmm0,[eax+0000008C] \+90 (2F3B4A40): vtDword 64FF2CC6 - fld dword ptr [eax] \+C8 (2F3B4A78): vtDword 64FF2DA6 - mov ecx,[eax] \+CC (2F3B4A7C): vtDword 64FF2DE6 - mov ecx,[eax] \+E0 (2F3B4A90): vtDword 64FF2DA6 - mov ecx,[eax] \+104 (2F3B4AB4): vtDword 651141FA - mov eax,[eax] \+10C (2F3B4ABC): vtByte 64FF2DC6 - movzx ecx,byte ptr [eax] \+10D (2F3B4ABD): vtByte 64FF2DC6 - movzx ecx,byte ptr [eax] \+10E (2F3B4ABE): vtWord 64FF2D96 - movsx ecx,word ptr [eax] \+110 (2F3B4AC0): vtDword 64FF2DB6 - mov ecx,[eax] \+138 (2F3B4AE8): vtDword 64FBB772 - or [esi+00000138],edi \+171 (2F3B4B21): vtByte 64FBB7D4 - cmp byte ptr [esi+00000171],00 \+172 (2F3B4B22): vtByte 64FA6572 - cmp byte ptr [esi+00000172],03 \+173 (2F3B4B23): vtByte 64FF2DC6 - movzx ecx,byte ptr [eax] \+174 (2F3B4B24): vtDword 651141FA - mov eax,[eax] \+178 (2F3B4B28): vtDword 64FBB79D - mov eax,[esi+00000178] \+17C (2F3B4B2C): vtDword 64FBB7E8 - mov eax,[esi+0000017C] \+180 (2F3B4B30): vtDword 64FDD9A6 - mov eax,[ecx] \+188 (2F3B4B38): vtDword 64FF2D66 - fld dword ptr [eax] \+18C (2F3B4B3C): vtDword 64FF2D6D - fld dword ptr [eax+04] \+190 (2F3B4B40): vtDword 64FF2D73 - fld dword ptr [eax+08] \+194 (2F3B4B44): vtDword 64FF2D66 - fld dword ptr [eax] \+198 (2F3B4B48): vtDword 64FF2D6D - fld dword ptr [eax+04] \+19C (2F3B4B4C): vtDword 64FF2D73 - fld dword ptr [eax+08] \+1A0 (2F3B4B50): vtByte 64F9FD30 - movzx eax,word ptr [ecx+20] \+1A1 (2F3B4B51): vtByte 64F9FD30 - movzx eax,word ptr [ecx+20] \+1A2 (2F3B4B52): vtByte 64FDDBB0 - movzx eax,byte ptr [ecx+22] \+1A3 (2F3B4B53): vtByte 64FF2DC6 - movzx ecx,byte ptr [eax] \+1AA (2F3B4B5A): vtByte 64FF2DC6 - movzx ecx,byte ptr [eax] \+1AC (2F3B4B5C): vtDword 64FF2D66 - fld dword ptr [eax] \+1B0 (2F3B4B60): vtDword 64FF2D6D - fld dword ptr [eax+04] \+1B4 (2F3B4B64): vtDword 64FF2D73 - fld dword ptr [eax+08] \+1B8 (2F3B4B68): vtDword 64FF2D66 - fld dword ptr [eax] \+1BC (2F3B4B6C): vtDword 64FF2D6D - fld dword ptr [eax+04] \+1C0 (2F3B4B70): vtDword 64FF2D73 - fld dword ptr [eax+08] \+1E0 (2F3B4B90): vtDword 64FF2DA6 - mov ecx,[eax] \+1E4 (2F3B4B94): vtDword 64FF2DA6 - mov ecx,[eax] \+1E8 (2F3B4B98): vtDword 64FF2DA6 - mov ecx,[eax] \+1EC (2F3B4B9C): vtDword 64FF2DB6 - mov ecx,[eax] \+1F0 (2F3B4BA0): vtByte 64FF2DC6 - movzx ecx,byte ptr [eax] \+20C (2F3B4BBC): vtDword 651141FA - mov eax,[eax] \+210 (2F3B4BC0): vtDword 651141FA - mov eax,[eax] \+214 (2F3B4BC4): vtDword 64FF2CC6 - fld dword ptr [eax] \+218 (2F3B4BC8): vtDword 64FF2CC6 - fld dword ptr [eax] \+21C (2F3B4BCC): vtDword 64FF2CC6 - fld dword ptr [eax] \+220 (2F3B4BD0): vtDword 64FF2DE6 - mov ecx,[eax] \+22C (2F3B4BDC): vtDword 64FF2CC6 - fld dword ptr [eax] \+238 (2F3B4BE8): vtDword 64FF2DA6 - mov ecx,[eax] \+2B4 (2F3B4C64): vtDword 64FF2CC6 - fld dword ptr [eax] \+2E4 (2F3B4C94): vtByte 64FF2DC6 - movzx ecx,byte ptr [eax] \+2E5 (2F3B4C95): vtByte 64FF2DC6 - movzx ecx,byte ptr [eax] \+2E6 (2F3B4C96): vtByte 64FF2DC6 - movzx ecx,byte ptr [eax] \+2E7 (2F3B4C97): vtByte 64FF2DC6 - movzx ecx,byte ptr [eax] \+2E8 (2F3B4C98): vtByte 64FF2DC6 - movzx ecx,byte ptr [eax] \+2E9 (2F3B4C99): vtByte 64FF2DC6 - movzx ecx,byte ptr [eax] \+2EA (2F3B4C9A): vtByte 64FF2DC6 - movzx ecx,byte ptr [eax] \+2EB (2F3B4C9B): vtByte 64FF2DC6 - movzx ecx,byte ptr [eax] \+2EC (2F3B4C9C): vtByte 64FF2DC6 - movzx ecx,byte ptr [eax] \+374 (2F3B4D24): vtDword 64FA65AC - mov edi,[esi+00000374] \+378 (2F3B4D28): vtDword 64FF2DE6 - mov ecx,[eax] \+37C (2F3B4D2C): vtDword 64FF2DE6 - mov ecx,[eax] \+380 (2F3B4D30): vtDword 64FF2DE6 - mov ecx,[eax] \+384 (2F3B4D34): vtDword 64FF2DE6 - mov ecx,[eax] \+388 (2F3B4D38): vtDword 64FA65B8 - movss xmm1,[ecx] \+38C (2F3B4D3C): vtDword 64FA660B - movss xmm1,[ecx+04] \+390 (2F3B4D40): vtDword 64FA6653 - movss xmm1,[ecx+08] \+394 (2F3B4D44): vtDword 64FA68AD - movss xmm1,[eax] \+398 (2F3B4D48): vtDword 64FA68E1 - movss xmm2,[eax+04] \+39C (2F3B4D4C): vtDword 64FA6904 - movss xmm2,[eax+08] \+3A0 (2F3B4D50): vtDword 64FDEC3A - mov ecx,[edi] \+3B8 (2F3B4D68): vtDword 6508F54F - test [eax+000003B8],edx \+42C (2F3B4DDC): vtDword 64F84E81 - fstp dword ptr [esi+0000042C] \+434 (2F3B4DE4): vtDword 64FF2DA6 - mov ecx,[eax] \+438 (2F3B4DE8): vtDword 64FF2D66 - fld dword ptr [eax] \+43C (2F3B4DEC): vtDword 64FF2D6D - fld dword ptr [eax+04] \+440 (2F3B4DF0): vtDword 64FF2D73 - fld dword ptr [eax+08] \+444 (2F3B4DF4): vtDword 64FF2DA6 - mov ecx,[eax] \+448 (2F3B4DF8): vtDword 64FF2DA6 - mov ecx,[eax] \+44C (2F3B4DFC): vtDword 64FF2DE6 - mov ecx,[eax]
Плагин выложу позже. Надо еще доработать и потестить.
Вот к примеру float распознал как Pointer и там где fst тоже по +42C тоже фигня. Это ошибки. Это быстро поправить, но могут быть еще ошибки.
Не менее интересны еще вложенные структурки, которые удается раскрыть (не все). Вот одна из них и усеяна параметрами, которые можно покрутить
Вложенные структуры пока отдельно можно создавать в окнах, чистить сканером, потом подставлять их в основную структуру по имени. В общем пока рано об этом писать.
Больше всего меня волнует польза, т.е. что можно с этим сделать. Пока только сразу вышел на скорострельность. Еще шесть параметров покрутил байтовых, ничего не дало. Надо еще попробовать выводить только смещения, которые работают на инструкцияъ чтения, а не "чтении и записи". Запись скорее всего не нужна. Значения просто активно перезаписываются в структуре. А вот оставлять смещения, с которыми работает только "чтение" скорее всего даст куда больше вероятности найти параметр настройки.
-
-
Надо попробовать.
-
Сегодя или завтра еще выложу исходники на другой аналогичный плагин (не новый). Там breakpoint на область памяти (на структуру). Но это все старые иходники. Видео по нему у меня есть на yutube канале.
Если, кто захочет усовершенствовать плагины, то, наверно, я могу создать отдельную ветку репозитория и кто-то сможет коммитить туда изменения.
Аналогично используя форум и репозиторий возможна совместная разработка таблиц и исходников на CE для плагинов и для игр. Просто нужно чтобы, кто-то инициировал. Если, кто сможет организовать это все, то смогу дать необходимые права. Временм у меня к сожалению, не много. Но если что-то подсказать, то буду связи.
-
Это сообщение удалено!