Показать сообщение отдельно
Старый 07.11.2024, 02:24   #1
Diantro
Проф. продавец
Аватар для Diantro
OFFLINE
Регистрация: 29.10.2023
Сообщений: 1,850
Благодарностей:
269 всего
Мнения: + 460
Репутация: 808

Таб-таргет для любых серверов


Интро

Данная тема является продолжением предыдущей: Поиск функций в клиенте RF Online. В ней мы нашли, как использовать умения. В данной теме речь пойдет про выделение мобов/персонажей в таргет.

Вот, что мы получим в итоге: видос. Жмем "1" - выбираются персонажи, "2" - мобы.

Манипуляции будут проводиться на клиенте 2.2.3.2. Итоговый таб-таргет потестил на церберусе - работает. В теории должно работать на любом 2.2.3.2 клиенте. Если версия другая, то можно повторить шаги из гайда, чтобы найти оффсеты, либо попробовать Pattern Scanner.

Содержание:
  • Поиск функции выбора объекта в таргет
  • Поиск массива мобов, персонажей и NPC
  • Реализация простого таб-таргета

Просто напиши оффсеты не хочу ничего искать

Скролльте до параграфа "Реализация простого таб-таргета"


Поиск функции выбора объекта в таргет
  1. Заходим в игру, выбираем моба в таргет, начинаем искать в CE название монстра
    Example
  2. Видим статически адрес (RF_Online.bin+1F38E40, он же 02338E40, зеленый на скрине). Если выберите другого моба - значение изменится. По этому адресу всегда лежит имя текущего выделенного моба.
    Example
  3. Открываем x64dbg и ставим write breakpoint на данный адрес
    Example
  4. Выделяем моба, breakpoint сработает после команды, выполнившей запись по адресу
    Example
  5. Далее тактика такая: возвращаемся из функции (execute till return + step over) и NOP-ем ее. Выполняем это до тех пор пока выделение в таргет кликом не перестанет работать. То есть NOP-нули, кликнули на моба, если все еще работает - возвращаем исходный код и повторяем тоже самое с текущей функцией поднимаясь по стеку вызовов.
  6. В итоге мы найдем адрес 00522F6A, который вызывает функцию по адресу 005234E0
    Example
    Если подняться еще на одну ступеньку выше и NOP-нуть там, то персонаж еще и перестанет двигаться при клике на местность. То есть функция передвижения тоже где-то рядом.
  7. Даем функции имя SelectTarget и смотрим на аргументы. Функция вызывается от имени объекта, который лежит по адресу 12F13D10 (thiscall). Забегая вперед, первый аргумент - адрес моба, второй - константа 0.
    Example
  8. Найти оффсет для 12F13D10 просто: во всей цепочке вызовов выше данный адрес передается в ecx. Делаем execute till return + step over пока не встретим первый статический оффсет при записи в ecx. Находим адрес 007002E3. Получаем формулу [edx + 75888] = [[ebp - 4] + 75888]. В [ebp - 4] лежит ecx для текущей функции.
    Example
  9. Еще раз делаем execute till return + step over и находим базовый адрес. В итоге формула становится [23612C8 + 75888] = [23D6B50]. От имени объекта по этому адресу и вызывается SelectTarget.
    Example
  10. Статический анализатор подсказал мне, что данный класс называется CGP_MainGame.
    Example

В итоге получаем такую сигнатуру
Код на C++

UPD: Дополнение по выбору в таргет
https://www.rf-cheats.ru/forum/showp...1&postcount=91


Поиск массива мобов, персонажей и NPC
  1. Ставим breakpoint на push первого аргумента для SelectTarget в стек - это адрес моба, сохраняем его в блокнот.
    Example
  2. Ставим access breakpoint на данный адрес.
    Example
  3. Сразу же сработает breakpoint. Мы будем находиться в функции по адресу 004F5DB0. Вот так она выглядит. Я уже дал всем функциям имена. При возврате из функции мы найдем базовый адрес для массива объектов вокруг персонажа - 233b5f0
    Example
  4. В данной функции мы видим двойной цикл.
    • Первый итерируется от 0 до 0xC по массиву объектов, каждый из которых состоит из двух адресов - адрес первого элемента и адрес последнего элемента вложенного массива. То есть это своего рода матрица из объектов, с которыми персонаж может взаимодействовать. В голове можно держать эту структуру так [{firstAddress, lastAddress}, {firstAddress, lastAddress}, ... {firstAddress, lastAddress}].
    • Второй цикл берет значение по первому адресу 233b5f0 + index + 0xC + 4 и последнему адресу 233b5f0 + index + 0xc + 8 (перед подстановкой в формулу к index также применяется сдвиг влево на 4 бита - shl 4). В каждой итерации к первому значению прибавляется 4 до тех пор, пока адрес не станет равен последнему значению.
    Example

В итоге мы имеем базовый адрес для массива объектов 233b5f0. Всего в массиве 12 элементов (0xC). Каждый элемент содержит адрес первого и последнего элемента вложенного массива. Эти адреса достаются по формулам 233b5f0 + index (shl 4) + 0xc + 4 и 233b5f0 + index (shl 4) + 0xc + 8.


Реализация простого таб-таргета

Компилируем DLL и инжектим её через Cheat Engine. После инжекта нажимаем TAB для выбора мобов.

Реализация тривиальная: объекты берутся в таргет в том порядке, в каком они расположены в памяти. Сортировку по удалённости от персонажа, ХП и другим параметрам можете реализовать сами — оффсеты известны. По индексам 0, 1 и 2 находятся персонажи, мобы и НПС соответственно. Остальные массивы у меня были пустыми, но я не выходил за пределы генштаба.

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

Код на C++ (Updated 02.12.2024)


Готовое решение (Update 22.12.2024)

Допинал до рабочего состояния. Теперь умеет сортировать по HP и расстоянию.

При сортировке по ХП мобы сортируются по оставшемуся проценту ХП, если процент одинаковый — по расстоянию. Для сортировки по расстоянию — наоборот.
При сортировке по расстоянию выбирается следующий по удалённости после текущего выбранного (даже если он уже был выбран ранее).

HP
Расстояние

В архиве инжектор, DLL и README. Запускаете игру, выбираете персонажа, затем запускаете инжектор.
Тестил на церберусе и пвпваре x100.

Что нужно доработать:
  • Выбирать только вражескую расу при выборе игроков.
  • Исключать из выбора мёртвых мобов/игроков.

Архив прикреплен к комментариям:

Последний раз редактировалось Diantro; 15.07.2026 в 19:33. Причина: Добавил версию 1.2.0
 
Ответить с цитированием
Сказали спасибо:
KarabasS (25.02.2026), cold (04.09.2025), AlexCXZ (21.04.2025), Roflex (18.04.2025), Noize (17.02.2025), Eagle (03.02.2025), zagibok44 (28.01.2025), ПингвинУборшиk (24.12.2024), [Nark][Devils] (02.12.2024), Agamon (24.11.2024), Bahtry (20.11.2024), Drakosha (14.11.2024), Werizander (13.11.2024), Jlo6aH (13.11.2024), DungeonKeeper (08.11.2024), NanoTech (07.11.2024), Sitanom (07.11.2024), dark (07.11.2024)