Умение перехватывать пакеты, отправлять, подменять — важная составляющая знаний любого разработчика читов, особенно для ММО игр. Цель руководства состоит в том, чтобы расширить знания по обратному инжинирингу с пакетами. Я предполагаю, что читатель имеет достаточный опыт в реверс-инжинирингtе (программирование, дизассемблирование и отладка).
Первые шаги: как получить пакеты
Чтобы анализировать и понимать пакеты, мы должны получить к ним доступ. Некоторые люди используют такие инструменты, как wireshark, но лично я никогда полностью не мог вникнуть в это. Вместо этого я иду прямо к двоичному коду.
В windows отправка и получение пакетов для игр осуществляется через библиотеки dll: winsock (old) или ws2_32. Зачастую это не меняется от игры к игре. Существуют и другие api для отправки данных по сети, но он, как правило, специфичны для http. Это означает, что функции ws2_32 являются основными для хуков.
Основные функции для отправки и получения данных — это «send» и «recv», однако есть и другие варианты, такие как wsasend, sendto, recvfrom и т. д. Обычно игра (программа) использует одну пару и ничего больше (например, send/recv).
Первый шаг — найти, какую пару использует игра. У maplestory это send и recv. Вы хукаете их, и теперь у вас есть доступ к пакетам! Мне нравится дампить пакеты во время моих хуков, помечая их уникальным идентификатором (счетчиком) независимо от того, send это или recv.
Вот так выглядит мой хук отправки пакетов:
void EncryptionHook(Utility::x86Registers* pRegs) {
auto dest = (char*)((void**)pRegs->ebp)[2];
auto src = (char*)((void**)pRegs->ebp)[3];
auto len = (int)((void**)pRegs->ebp)[4];
// LogB( "UNENC BUF: %p, LEN: %d", src, len );
auto pStruct = (MapleStructs::PacketStruct*)pRegs->ebx;
std::vector<char> full_packet;
full_packet.assign(src, src + len);
PacketHandler::HandlePacket(full_packet.data(), full_packet.size(), true);
memcpy(src, full_packet.data(), full_packet.size());
SendPacketToGatekeeper(src, len, false); // this is my own little
// packet-reclass thing. I don't use
// it anymore.
}
Для удобства предположим, что handlepacket - это функция, которая просто дампит пакет.
Отлично! Однако в наши дни такие вещи как пакеты часто шифруются. Способ, которым я проверяю, зашифрованы ли пакеты в играх, довольно прост. С вашим хуком, отправьте несколько сообщений в чат, затем найдите свою строку в двоичных файлах, я рекомендую использовать grep. Если вы нашли свою строку красивой и нетронутой — потрясающе! Значит, вероятно, шифрования нет, или разработчики не заботятся об отправке пакетов сообщений достаточно, чтобы шифровать их, что также возможно. Если ваши пакеты зашифрованы, то придется немного попотеть.
Нарастающая боль: расшифровка пакетов
Есть два основных способа получить чистые пакеты для использования. Вы можете либо найти методы шифрования и дешифрования (для пакетов recv) в двоичном файле и записать их на выбранном вами языке, либо найти вышеупомянутые функции и перехватить их до или после выполнения. Второй подход может сэкономить вам значительную часть времени, но он довольно трудный. Итак, как вы это будете делать?
Эта вторая часть работы с пакетами самая трудная и разочаровывающая. Я разделю их на две части.
Перехват пакетов до того, как они будут зашифрованы (send):
От вашего места отправки у вас будет адрес отправляемого буфера. Вам нужно установить аппаратную точку останова на чтение. Но что делать, если чтение происходит в одном месте, а байты обрабатываются и записываются в совершенно другое? Крутое дерьмо.
Вам придется серьезно постараться и проверять функции, пока не найдете что-то, что выглядит многообещающим. Функции, которые выглядят многообещающе, могут иметь один или несколько из этих признаков:
- они большие,
- содержат очевидные инструкции запутывания (xor, shl, shr и т. д.),
- вызываются в очень немногих местах (вероятно, только в функция, связанных с пакетами),
- потенциально имеют некоторые антиоладочные приемы или приемы антидизассемблирования, хотя это не очень распространено.
Как только вы нашли функцию, которая, по вашему мнению, может быть многообещающей, захукайтесь и дампите буфер так же, как и раньше, и попытайтесь отправить в чат. Если у вас получилось, то вы должны увидеть открытый текст.
Для справки, в maplestory функция шифрования вызывается только в 2 местах, оба из которых находятся в пределах одной и той же функции.
Перехват пакетов сразу после их расшифровки (recv):
Этот процесс в значительной степени точно похож на предыдущий, однако я хотел бы отметить, что по моему опыту, в то время как функция шифрования может иметь много вызовов до фактической отправки, расшифровка происходит довольно быстро, часто в пределах той же функции, которая вызывает recv, хотя в maplestory это не так.
Пакеты с примечаниями, которые необходимо проверить, отправляются так же как и пакеты сообщений, так как в играх, с которыми я сталкивался, сервер будет передавать ваше сообщение всем игрокам, включая вас. В противном случае вы можете поэксплуатировать друга или использовать песочницу (виртуальную машину), и получить сообщение таким образом, или ждать, когда другой игрок отправит его.
Опять же, этот процесс может быть трудным, не ожидайте, что найдете их через день или два. В моем опыте мне требуется около недели, чтобы найти незашифрованные пакеты send и recv. Тем не менее, поиск одного облегчает поиск другого, поскольку схемы, как правило, от игры к игре похожи, и вы понимаете, какую функцию необходимо искать.
Понимание и интерпретация пакетов
Теперь самая сложная часть процесса, и именно из-за нее большинство людей, вероятно, не работают с пакетами.
Если ваша цель не имеет открытый исходный код или не была «слита», то это «черный ящик».
Вы отправляете информацию и получаете информацию в виде набора байтов, которые часто не имеют смысла, например:

Да, это не зашифровано, уверяю вас.
Этому на самом деле нельзя научить, и именно поэтому я предлагаю хорошо разбираться в обратном инжиниринге, прежде чем пытаться работать с пакетами, так как это не проще, я бы сказал, что это сложнее. Вам нужно понять, как выглядят различные типы данных, как они могут быть отправлены по сети (посылают ли они копию для точности? Int/float для размера?), и иметь некоторую интуицию относительно понимания того, что вещи могут означать.
Однако я могу дать вам совет. Я рекомендую использовать инструмент hex editing tool hxd или hex workshop. Они имеют отличный интерфейс, который покажет вам все интерпретации области, на которую вы нацелили курсор или выделили.
Те поля, которые выделены серым цветом, говорят о том, что не хватает байтов для представления этого типа данных. Я нахожу это бесценным в попытках расшифровать что-либо. С помощью этого можно узнать, может ли что-то потенциально быть int, short, float, double и т. д. , Даже тип filetime был найден в одном из моих пакетов.

Возвращаясь к пакетам, идентификаторы пакета находятся обычно в пределах первых нескольких байтов пакета, однако они могут быть дополнительно зашифрованы (в maplestory это так для некоторых пакетов). Идентификаторы пакетов часто бывают short, либо int.
Что же касается содержимого пакета, то некоторые из них вы можете выяснить на глаз. Видите строку? Возможно, 2/4 байта перед ним — это длина строки. Использовали заклинание? Возможно, эти странные 4 байта, которые никогда не меняются, — это ваш идентификатор персонажа или идентификатор заклинания. Вы можете попробовать избавиться от этих вещей, изменив их в своем хуке.
Однако некоторые из них не так просты, как тот большой пакет размером 0×800a, который я только что показал вам. Вы можете попробовать применить грубую силу и я увижу вас еще через 5 дней, когда вы, без сомнения, сдадитесь.
Еще один совет: пакеты часто бывают последовательными. Если вы только что отправили пакет, то, вероятно, сразу же получите ответный пакет (мы не говорим про udp). Точно так же после получения пакета ваш клиент часто отправляет свой собственный ответ, например, когда вы получаете или отправляете heartbeat-пакет.
Наконец, повторяю: не забывайте, что у вас есть возможность перехвата! Модифицируйте вещи, прежде чем они будут отправлены, измените сообщение, замените 0 на 1, 2 на 0. Посмотрим, что получится! В худшем случае вас кикнут с сервера за неправильно сформированный пакет (или вы будете забанены). Хорошо, когда вы выясняете, что это такое. В лучшем случае вы найдете ошибку, и теперь вы грязный вонючий виртуальный богач.
Я думаю, что обработка пакетов/сетей — это отличный подраздел реверс-инжиниринга, который не получает достаточной любви. Я чувствую, что видел матрицу такой, какая она есть, всякий раз, когда я полностью понимаю новый пакет, надеюсь, что тот, кто читает это, тоже получит новообретенную любовь к нему.
