Логотип игрового форума RF-Cheats.ru    
Новости онлайн игр Гарант RF-Cheats.ru Чёрный рынок Реклама и привилегии Разработка читов Арбитраж

Регистрация Бан-лист Сообщество ПОПУЛЯРНОЕ
Вернуться   RF-Cheats.ru - форум читеров и ботоводов > > >

Читерство в RF Online

: Обсуждение читов, багов, эксплойтов и сетевого протокола игры Rising Force. А также программ и модификаций клиента, делающих игру более приятной.
Читы и обход фроста для RF Online без хайдаБоты и читы для Perfect World бесплатно без хайдаМоды и читы для World of Tanks (WoT) бесплатно без хайдаМоды и читы для Armored Warfare бесплатно без хайдаБоты и читы для DOTA 2 бесплатно без хайдаБоты и читы для Black Desert Online бесплатно без хайдаЧиты на ArcheAge бесплатно без хайдаЧиты для Warface бесплатно без хайдаВзлом ВКонтакте и ОдноклассниковСписок разделов со всеми играмиЧиты для онлайн игр






Ответ
 
Опции темы
Старый 18.11.2024, 17:30   #1
Diantro
Проф. продавец
Аватар для Diantro
OFFLINE
Регистрация: 29.10.2023
Сообщений: 1,850
Благодарностей:
251 всего
Мнения: + 458
Репутация: 754

Обход шифрования пакетов


Интро

Продолжаем предыдущую тему: Таб-таргет для любых серверов. Мы уже нашли окружающие персонажа объекты, объекты с умениями и инвентарем, функцию выбора объекта в таргет, и функцию использования скиллов и предметов. Теперь перейдем к следующему этапу — обходу шифрования пакетов на примере сервера cerberus-games. Итоговая тулза будет работать и на других серверах.

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



Содержание
  1. Зашифрованный и незашифрованный пакет
  2. Поиск функции шифрования исходящих пакетов
  3. Хукаем функцию шифрования пакетов
  4. Работа с входящими пакетами (спойлер: они не шифруются)
  5. Итоговая тулза

Зашифрованный и незашифрованный пакет

Сначала перехватим незашифрованный пакет, чтобы понять, как он устроен.
  • Запускаем клиент RF Online на сервере без шифрования (я экспериментирую на RF Altruism, также можно запустить свой сервер локально).
  • Запускаем x64dbg, аттачимся и ставим брейкпоинт на функцию send из ws2_32.dll
    Example
  • Пишем в чат "123" — срабатывает брейкпоинт. Функция send принимает в аргументах буфер, который нужно отправить. Находим его — там лежит искомый пакет.
    Example
  • То же самое мы увидим, если перехватим этот пакет в Wireshark. Буфер, который передается в send, соответствует данным в пакете стека протоколов TCP/IP.
    Example

Имеем такой пакет: 0f 00 09 00 02 02 03 31 32 33 00 04 00 00 00
  • 0f - длина пакета
  • 02 02 - тип пакета
  • 03 31 32 33 00 04 00 00 00 - данные. В данном случае 03 — длина сообщения, 31 32 33 — "123".

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

Теперь проделаем то же самое на Церберусе, где шифрование есть. Ставим брейкпоинт на send и пишем "123" в чат. Видим непонятный набор данных, не похожий на пакет, который мы перехватили выше.
Example

Поиск функции шифрования исходящих пакетов
  • Ставим снова брейкпоинт на send и триггерим его, отправив сообщение в чат. Делаем это несколько раз и следим, как меняется адрес буффера.
    Example
  • Замечаем, что адреса всегда похожи, и иногда новый буфер может перетирать старый. Переходим к одному из этих адресов в памяти, убираем брейкпоинт и начинаем спамить сообщения в чат. В результате видим, что буфер при отправке сообщения всегда лежит в какой-то области из фиксированного куска памяти. На гифке значения в памяти меняются только когда я пишу сообщения в чат.
    Example
  • Ставим брейкпоинт на запись на какой-то из адресов (или на несколько), по которым может произойти запись, и начинаем спамить в чат, пока он не сработает. В итоге мы окажемся внутри RFOClient.vmp.dll
    Example
  • RFOClient.vmp.dll - это DLL с кастомной логикой клиента Церберуса. В оригинальном rf_online.bin хукаются необходимые функции и выполнение перенаправляется в данную DLL. Т.к. при каждом старте она инжектится заново, адреса в ней после рестарта клиента съезжают.
  • Начинаем выполнять возврат из функции, пока не окажемся в rf_online.bin (не забудьте перед этим деактивировать поставленные брейкпоинты, чтобы они снова не сработали). В итоге находим место, где была изменена дефолтная логика.
    Example
  • Ставим брейкпоинт на push eax и проверяем, что лежит по этому адресу. Находим что-то похожее на незашифрованный пакет: кажется, что данные зашифрованы, а тип — нет.
    Example
  • Возобновляем выполнение программы и следим за памятью. Новые пакеты добавляются после предыдущих.
    Example
  • Ставим брейкпоинт на запись где-нибудь после текущего пакета, чтобы определить, где подготавливаются данные (важно при этом попасть именно в зашифрованные данные, а не в тип пакета). После срабатывания опять окажемся в RFOClient.vmp.dll.
    Example
  • Выполняем возврат из функции, пока не окажемся в rf_online.bin. В итоге попадаем в функцию LoadSendMsg (название подсказал Cutter).
    Example
  • Делаем возврат из функции и снова оказываемся в RFOClient.vmp.dll
    Example
  • Снова делаем возврат пока не окажемся в rf_online.bin и наконец находим искомую функцию — SendNetMessage. На скриншоте справа подписаны аргументы, которые передаются в обертку над LoadSendMsg из RFOClient.vmp.dll.
    Example
  • Ставим брейкпоинт на начало функции и убеждаемся, что в функцию передаются незашифрованный тип и данные для пакета.
    Example

В итоге мы нашли функцию SendNetMessage, с помощью которой можно отправлять свои пакеты. Функция имеет такую сигнатуру:
Код на C++

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

Хукаем функцию шифрования пакетов

Хукать функцию нужно для того, чтобы логировать исходящие пакеты и понимать, какие пакеты может отправить клиент. При вызове SendNetMessage в стеке будут лежать аргументы — тип пакета, данные и их длина. Нам нужно перенаправить исполнение программы в наш заинжекченный код с помощью команды jmp, вывести значения аргументов в консоль или интерфейс программы и вернуть исполнение обратно в функцию.

Будем хукаться в этом месте, так как команда jmp имеет длину 5 байт.
Код:
0052EB91 | 8BEC      | mov ebp,esp                                                 
0052EB93 | 83EC 18  | sub esp,18
Example

Для того, чтобы хукнуться я использую такой класс
Код на C++

Первый аргумент в конструкторе - адрес для хука, второй - адрес функции, в которую нужно перенаправить исполнение, третий - количество заменяемых байтов. То есть в нашем случае его нужно вызвать так:
Hook sendHook{ (void*)0x0052EB91, reinterpret_cast<void*>(ourCustomFunction), 5 };
В деструкторе возвращается исходный код, чтобы при закрытии нашей программы игра работала как прежде.

Сама функция, в которую будет перенаправляться выполнение, может выглядеть так:
Код на C++

В этой функции мы сохраняем указатель на this, значения регистров и аргументы в переменные. Затем выполняем с этими данными необходимые действия (printSendBufferToLog()). После этого восстанавливаем значения регистров, выполняем команды, перезаписанные jmp (mov ebp, esp и sub esp, 0x18), и возвращаем исполнение в исходную функцию.

В итоге, после хука пролог функции будет выглядеть так (с добавленным нашим jmp).
Example

Более подробно про перенаправление можно почитать здесь: Code caves и Using code caves

Работа с входящими пакетами

Тут все проще, так как входящие пакеты на Церберусе не шифруются. Чтобы убедиться в этом, можно поставить брейкпоинт на recv из ws2_32.dll и нажать execute till return, чтобы в буфер записался контент из сокета.
Example

Единственная проблема здесь — непонятно, где начинается и заканчивается пакет. Начало мне удалось найти: если поставить access-брейкпоинт на буфер и проанализировать, где происходит чтение из него, то можно найти функцию AnalysisZoneServerPacket.
Example

В нее передаются два аргумента — тип пакета (в данном случае 4 байта) и контент, но нет длины. В итоге в хуке я просто логирую тип и 64 байта из контента.

Итоговая тулза

Сделано на основе такой же тулзы для Теры: https://github.com/Erarnitox/TeraProxy

Поддерживает
  • Логирование исходящих и входящих пакетов
  • Отправку пакетов
  • Отправку последовательности пакетов, предварительно загруженных из файла
  • Выгрузгу логов

Работает на всех популярных серверах (независимо от того, есть ли шифрование или нет).

В архиве два файла: RF Proxy.exe — инжектор (методом Manual Mapping) и rfproxy.dll. Вы можете использовать любой другой инжектор, например, встроенный в Cheat Engine.

Ссылка на скачивание в этом сообщении:
https://www.rf-cheats.ru/forum/showp...5&postcount=28

Последний раз редактировалось Diantro; 18.11.2025 в 23:47.
 
Ответить с цитированием
Сказали спасибо:
mcmanrizky (27.09.2025), kontol (26.07.2025), rule-z (28.05.2025), cold (09.04.2025), DungeonKeeper (19.01.2025), Werizander (19.11.2024), dark (18.11.2024), NanoTech (18.11.2024), Sitanom (18.11.2024), Jlo6aH (18.11.2024)


Старый 18.11.2024, 17:37   #2
Diantro
Проф. продавец
Аватар для Diantro
OFFLINE
Регистрация: 29.10.2023
Сообщений: 1,850
Благодарностей:
251 всего
Мнения: + 458
Репутация: 754

Исходник
Скрытый текст (вы должны войти под своим логином или зарегистрироваться и иметь 300 сообщение(ий)):
У вас нет прав чтобы видеть скрытый текст, содержащейся здесь.
Чтобы его прочитать, вы должны заработать сообщения. Как это сделать бесплатно, описано в правилах форума. Как купить доступ, описано в Платных услугах.
 
Ответить с цитированием
Сказали спасибо:
котопес (19.03.2025), danwhale (08.02.2025), Sitanom (18.11.2024), Jlo6aH (18.11.2024)
Старый 18.11.2024, 18:24   #3
Jlo6aH
Старичок форума
Аватар для Jlo6aH
OFFLINE
Регистрация: 03.01.2010
Сообщений: 1,264
Благодарностей:
6,649 всего
Мнения: + 26361
Репутация: 21217

половину не понял, но респект таким парням

Оффтоп
если я кого-то кину - я не виноват
mmm-kurganec - МОЙ СКАЙП
mmm-kurqanec - НЕ МОЙ СКАЙП. ЭТО МОШЕННИК.
SS

Триан ШИСЯТВОСЬМОЙ МАГ Лобан ушел париться в баню
Интерферирую на Асу
Дифрагирую на триане
 
Ответить с цитированием
Сказали спасибо:
Whiskers (19.11.2024)
Старый 19.11.2024, 00:45   #4
Sitanom
Читер
Аватар для Sitanom
OFFLINE
Регистрация: 08.02.2012
Сообщений: 160
Благодарностей:
2,831 всего
Мнения: + 13476
Репутация: 7284

Цитата:
Сообщение от Jlo6aH Посмотреть сообщение
половину не понял, но респект таким парням
Стыдно за тебя. Автор красава, ждём от тебя бота
 
Ответить с цитированием
Сказали спасибо:
Diantro (19.11.2024)
Старый 19.11.2024, 03:04   #5
Dino
Проф. продавец
Аватар для Dino
OFFLINE
Регистрация: 23.07.2012
Сообщений: 2,402
Благодарностей:
894 всего
Мнения: + 4246
Репутация: 2680

А зачем так костылить хук асм вставками и накед функой? Можно объявить его как __fastcall, затем вызвать логер и вернуть ориг __thiscall

Код:
typedef void(__thiscall* _SendNetMessage)(void* thisClass, DWORD zero1, const char* packetTypePtr, const char* packetContentPtr, DWORD length, DWORD zero2);
_SendNetMessage jmpBackAddrSendNetMessage;

void __fastcall sendHookFunc(void* thisClass, PVOID _EDX, DWORD zero1, const char* packetTypePtr, const char* packetContentPtr, DWORD length, DWORD zero2)
{
	printSendBufferToLog(packetTypePtr, packetContentPtr, length);
	return jmpBackAddrSendNetMessage(thisClass, zero1, packetTypePtr, packetContentPtr, length, zero2);
}
 
Ответить с цитированием
Сказали спасибо:
Diantro (19.11.2024)
Старый 19.11.2024, 15:58   #6
Diantro
Проф. продавец
Аватар для Diantro
OFFLINE
Регистрация: 29.10.2023
Сообщений: 1,850
Благодарностей:
251 всего
Мнения: + 458
Репутация: 754

Цитата:
Сообщение от Dino Посмотреть сообщение
А зачем так костылить хук асм вставками и накед функой? Можно объявить его как __fastcall, затем вызвать логер и вернуть ориг __thiscall

Код:
typedef void(__thiscall* _SendNetMessage)(void* thisClass, DWORD zero1, const char* packetTypePtr, const char* packetContentPtr, DWORD length, DWORD zero2);
_SendNetMessage jmpBackAddrSendNetMessage;

void __fastcall sendHookFunc(void* thisClass, PVOID _EDX, DWORD zero1, const char* packetTypePtr, const char* packetContentPtr, DWORD length, DWORD zero2)
{
	printSendBufferToLog(packetTypePtr, packetContentPtr, length);
	return jmpBackAddrSendNetMessage(thisClass, zero1, packetTypePtr, packetContentPtr, length, zero2);
}
Попробовал, но возникла проблема с указателями на стек. В твоем примере мы вызываем jmpBackAddrSendNetMessage как __thiscall, поэтому перед выполнением функции нужно подготовить стек, а эти команды мы перетерли jmp-ом.

Скрин из дебаггера
 
Ответить с цитированием
Старый 19.11.2024, 18:09   #7
Dino
Проф. продавец
Аватар для Dino
OFFLINE
Регистрация: 23.07.2012
Сообщений: 2,402
Благодарностей:
894 всего
Мнения: + 4246
Репутация: 2680

Компилятор сам разберется, видя соглашения о вызовах, единственное что тебе нужно это создать трамплин скопировав в него пролог , затем jmp на 0x0052EB90 + 6. А сам трамплин
уже вызываешь как __thiscall функцию


Код:
//target
RF_Online.bin+12EB90 - jmp 0A035710  // ->sendHookFunc
RF_Online.bin+12EB95 - nop 
RF_Online.bin+12EB96 - mov [ebp-18],ecx
RF_Online.bin+12EB99 - cmp dword ptr [RF_Online.bin+1F3B5F8],00 
...
Код:
//sendHookFunc
0A035710 - push ebp
0A035711 - mov ebp,esp
0A035713 - push edi
0A035714 - push [ebp+0C]
0A035717 - mov eax,RF_Online.bin+195CE0 { (-2081649835) }
0A03571C - mov edi,ecx
0A03571E - call eax // -> что то делаем внутри нашей функции
0A035720 - add esp,04 { 4 }
0A035723 - mov ecx,edi
0A035725 - push [ebp+18]
0A035728 - push [ebp+14]
0A03572B - push [ebp+10]
0A03572E - push [ebp+0C]
0A035731 - push [ebp+08]
0A035734 - call dword ptr [0A0843F4] // -> jmpBackAddrSendNetMessage
0A03573A - pop edi
0A03573B - pop ebp
0A03573C - ret 0014 { 20 }
Код:
//jmpBackAddrSendNetMessage(трамплин)
03DF0FC0 - push ebp
03DF0FC1 - mov ebp,esp
03DF0FC3 - sub esp,18 { 24 }
03DF0FC6 - jmp RF_Online.bin+12EB96 // -> orig func
 
Ответить с цитированием
Старый 19.11.2024, 20:36   #8
Diantro
Проф. продавец
Аватар для Diantro
OFFLINE
Регистрация: 29.10.2023
Сообщений: 1,850
Благодарностей:
251 всего
Мнения: + 458
Репутация: 754

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

Код:
void __declspec(naked) sendNetMessageTrampoline(void* thisPtr, DWORD zero1, const char* packetTypePtr, const char* packetContentPtr, DWORD length, DWORD zero2) {
    __asm {
        push ebp
        mov ebp, esp
        sub esp, 0x18
        jmp[jmpBackAddrSendNetMessage]
    }
}
   
void __fastcall sendHookFunc(void* thisPtr, PVOID _EDX, DWORD zero1, const char* packetTypePtr, const char* packetContentPtr, DWORD length, DWORD zero2) {
    printSendBufferToLog(packetTypePtr, packetContentPtr, length);

    return reinterpret_cast<game::_SendNetMessage>(sendNetMessageTrampoline)(thisPtr, zero1, packetTypePtr, packetContentPtr, length, zero2);
}
 
Ответить с цитированием
Старый 19.11.2024, 20:59   #9
Dino
Проф. продавец
Аватар для Dino
OFFLINE
Регистрация: 23.07.2012
Сообщений: 2,402
Благодарностей:
894 всего
Мнения: + 4246
Репутация: 2680

Цитата:
Сообщение от Diantro Посмотреть сообщение
А-а, я думал можно без ассембли как-то обойтись. Вот так получилось. Выглядит и правда аккуратней.

Код:
void __declspec(naked) sendNetMessageTrampoline(void* thisPtr, DWORD zero1, const char* packetTypePtr, const char* packetContentPtr, DWORD length, DWORD zero2) {
    __asm {
        push ebp
        mov ebp, esp
        sub esp, 0x18
        jmp[jmpBackAddrSendNetMessage]
    }
}
Трамплин лучше динамически создавать, например доработав класс. А так тебе придется под каждый хук добавлять отдельную naked функцию... Желательно бы еще и дизассемблер длин прицепить, чтобы количество байт в прологе просчитывалось автоматически.
А еще лучше воспользоваться готовым решением типа
MinHook

Добавлено через 45 минут
асм вставки надо вообще избегать, пользоваться ими только где это действительно необходимо. В x64 тебе пришлось бы колхозить через .asm файл, а это то еще веселье)

Последний раз редактировалось Dino; 19.11.2024 в 21:46. Причина: Добавлено сообщение
 
Ответить с цитированием
Сказали спасибо:
Diantro (19.11.2024)
Старый 20.11.2024, 10:42   #10
dark
Читодел
Аватар для dark
OFFLINE
Регистрация: 09.04.2007
Сообщений: 965
Благодарностей:
36,565 всего
Мнения: + 37511
Репутация: 116358
Отправить сообщение для dark с помощью ICQ Отправить сообщение для dark с помощью Skype™

Цитата:
Сообщение от Diantro Посмотреть сообщение
VirtualProtect(toHook, len, PAGE_EXECUTE_READWRITE, &curProtection);
Разрешите подушнить. Если планируешь использовать этот класс в других проектах, то стоит-таки проверять возвращаемое значение, часто античиты хукают VirtualProtect, вернее NtProtectVirtualMemory

Diantro +400 постов. Отличная статья по реверсу вообще в принципе любых игр.

Добавлено через 2 минуты
Цитата:
Сообщение от Diantro Посмотреть сообщение
Единственная проблема здесь — непонятно, где начинается и заканчивается пакет.
А в чём проблема? Чёто я не помню у себя таких запар.

Последний раз редактировалось dark; 20.11.2024 в 10:45. Причина: Добавлено сообщение

Cheats Development | Создание читов на заказ

Я не оказываю услуги гаранта!
База данных кидал: blacklist.rf-cheats.ru
Обязательно проверяйте человека через чёрный список прежде чем совершать с ним сделку.
 
Ответить с цитированием
Сказали спасибо:
Diantro (20.11.2024)
Ответ



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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Многооконнка, обход бана по HWID, обход мрака для Perfect Wold от @mail.ru dark Perfect World читы 2 22.08.2021 05:32
[Работает] [Статья] Вытаскиваем алгоритм шифрования EDF Файлов Dino Установка и поддержка RFO сервера 9 29.07.2018 06:52
Помогите с поиском алгоритма шифрования данных korsaj Взлом программ (крэкинг, реверс, обход защит) 0 12.02.2017 23:04
По поводу Шифрования .edf [Maks] Установка и поддержка RFO сервера 2 02.05.2015 23:12
Обход запускатора, раскрытие RFonline.bin и обход Frost-а network Архив (Баги, Читы, Эксплойты БЕЗ ХАЙДА) 4 04.09.2010 14:27

Мир танков | Проект "Армата" | ArcheAge | Black Desert | РФ Онлайн | Айон | Майнкрафт | Браузерные игры
Элдер скролс | Р2 Онлайн | Реквием Онлайн | ПУБГ | Роял Квест | ГТА Санадреас | Контра | Дота 2
Мир кораблей | Лост Арк | Arma2 DayZ mod | The War Z | Карос: Начало | Tera Online
Читы для всех Онлайн-игр