Как стать автором
Обновить

Комментарии 90

Но! Как плейбой без фоток!
Простите, это мой первый пост, я пытаюсь разобраться почему habrastorage не даёт вставлять картинки
Видимо, новый хабрасторэдж глючит, так как вот тоже пост из песочницы и тоже не грузятся картинки habrahabr.ru/post/212347/
Решение там же в комментах.
Я перезалил на собственный сервер
Да, я его туда написал, когда увидел, как починились картинки в этом посте.
Так в итоге получился «командирский планшет» или нет?
Ещё нет, но принципиальных препятствий к этому не вижу. Вход в бой — серия тех же самых pickle, боевая ситуация передаётся в коротких пакетах, где номера игроков и события\параметры техники. Хотелось просто закрепить приоритет публикацией и радовать общественность новыми открытиями по мере их поступления.
принципиальных препятствий к этому не вижу

В том же QuakeWorld клиенту не передаются координаты игроков и айтемов, которые он не видит.
Поэтому даже внутри программы нет полной картины.
Здесь тоже не передаются состояния вражеских юнитов, которые пропали из засвета. Однако, миникарту с отметками мест, где их последний раз видели, это сделать не помешало.
С нетерпением жду продолжения.
Очень интересно будет узнать продолжение :)
Хм, а как интересно отнесется КВГ к разбору протокола, после публикации вашего командирского планшета?
На официальном форуме КВГ уже неделю пылится тема этого проекта, и пока за мной никто не гонялся.
А потом, чем чёрт не шутит, сделают это собственной фишкой, как произошло с OTM и таймером КД.
на самом деле это противоречит пользовательскому соглашению :) Так что вопрос очень такой… Сами пытались сделать такой планшет, но более простой — перехватывая во флешке интерфейса отрисовку мини-карты, но потом кануло в небытье из-за сильных ограничений среды.
Якобы противоречит оно в одном-единственном пункте ПС, а именно п.4.4 о запрете декомпиляции и дизасма Проекта. Однако представить себе существующий огромный зоопарк модов без дизасма и декомпиляции довольно сложно (ведь официального модостроительного API нет), поэтому пункт дополнился пояснением о «за исключением модификации Контента с разрешения правообладателя». Короче говоря, что не запрещает администрация, то и разрешено.
Потому и пишу, что очень так… как минимум еще п. 5.3 и 4.4, в котором есть несколько частей.

Мы столкнулись с проблемами даже в более благих целях — например варгейминг не только не хочет дать возможность продавать премиум-товары за криптовалюты но и мешает появлению легальных посредников, которые бы взяли на себя эту роль :(
То что КВГ не хотят ввязываться в продажу цацок за крипту, это очень даже понятно, в свете вот этого, например, да и общих неясностей с правовым статусом крипты.

А насчёт посредников — идея интересная. Чисто теоретический вопрос — кто вам мешает стать «нелегальным» посредником? Принял битки, отправил голду через WM и хрен что докажешь.
Их никто не заставляет ввязываться. Но, к примеру, их конкуренты это допускают :) Тем более мы готовы были даже заранее выкупать и гарантировать свою деятельность финансовым обеспечением.

Понимаете — второй ваш способ дает бОльшие риски — в свете того, что хотели бы строить легальный бизнес, бренд и все такое. А это бы несло риски и для нас и для клиентов.

Ссылка не применима к этой ситуации, ибо ни мы ни варгейминг не являемся, как минимум, субъектами в правовом поле РФ.
ни мы ни варгейминг не являемся, как минимум, субъектами в правовом поле РФ

Мне не кажется, что можно рассчитывать на снисхождение к (и, тем паче, легализацию) крипты в более других странах, где даже на WM с принципиально отсутствующей анонимностью транзакций оказывается систематическое давление и наезды.
Поговорим, например, про Сингапур?
Вы с Украины, Wargaming.net LLP из Лондона, давайте про Сингапур. Только это уже оффтопик и лучше в личку.
Я про то, что создать компанию, если надо другая юрисдикция, это не проблема :)
Эх, уже потерли…
Там ничего особенного и не было. Без технических деталей, «видеопрезентация» предыдущей версии, для 0.8.10.
wotpad

Здесь ещё нет уже сейчас написанного нативного парсера Pickle, о котором я расскажу в следующей статье и нет записи пакетов.
Очень круто) Интересно, заставит ли ваша работа ВГ менять протокол или хотя бы усиливать шифрование
Я сомневаюсь. Слишком много придётся переделывать ради непонятно чего. Ибо сказано: «Работает — не трогай!»
Хех, как мне это напоминает мой разбор протокола EVE Online :)
Ждем ботов! Удачи!
Не напишите ли статью? — интересно было бы почитать. Или если уже — ссылку не дадите? А то чертовски интересно…
Нет, увы, статьи нет. Давно это было, сейчас только исходники остались :)
Сейчас садиться и опять вспоминать как разбирал пакеты, пожалуй, уже и не возьмусь.
А о жизни эволюции ботов (копатели, файтеры, выполнители миссий), боюсь, что тут будет не очень интересно.
Судя по количеству плюсов и комментов к топикам с новостями из Евы — многим будет интересно.
Боты есть и очень даже ничегошные. TankLeader самый продвинутый из них.
это же, чёрт побери, Python Pickle

Этого следовало ожидать, ибо там половина клиента с Python скриптами (достаточно поглядеть в любой продвинутый мод типа DM).
Думается мне, проще было пойти по этому пути (судя по всему swf-ки в GUI уже имеют доступ к распакованным данным из клиента), чем пытаться реверсить клиент
Да знаю я насколько сильно питон интегрирован в танки. «Чёрт побери» тут имеет, скорее, саркастический смысл.
В рамках «замены swf» идея «командирского планшета» не реализуется, да и необходимых скиллов для написания swf у меня нет.
Про сарказм я понял. Как человек играющий в WoT, я вижу же скрипты в клиенте ( \res\scripts\common + \res\scripts\client ) — одни *.pyc файлы.
Да и наличие в папке с игрой стандартного набора из (libcurl, libeay32,libsndfile-1,ssleay32,zlib1, а также чудесного python.log), что скорее всего все это из под Python'a и пользуется.

Камера для спектатора, кстати вроде появилась, насколько я видел она реализована специальным «танком» с названием Камера
Но она все так же занимает слот в бою, поэтому их не может быть сколько угодно.
Я буквально минуту назад разговаривал с автором того, на что вы выложили ссылку.
Ничего там не пилится, человек сделал эмуль только процесса авторизации и забил на всё остальное, с форматом обмена внутри игры он не разбирался и не собирается.
Крипт есть, начальная логика есть — все остальное допилить не составляет проблемы.
Дамп трафика снимать — не велика наука и не думаю, что заслуживает статьи.
offtop: где-то я уже видел вашу аватарку… ЗГ?
Странно что именно на аватарку вы обратили внимание, а не на никнейм :)
Нравится мне она просто уж оч. ))
Вы про полную версию, надо думать? :)
Все то вы знаете :) Я ее не видел 2 года, пока у меня стоял этот аватар :D
*Привет минусующим за бог весть что*
Я не минусовал, но попробую пояснить. Дело в элементарном уважении к чужому труду. Вот в моей научной практике встречались два характерных явления:

1) Некто, обсуждая какую-то научно-техническую проблему, заявляет, что это очень сложно, требуется такое-то финансирование (большое), такой-то срок (большой) и такой-то штат (тоже большой) для её решения. Когда же ему через 10 минут показывают в соседнем помещении решающий эту проблему лабораторный макет, кое-как слепленный из чего попало 3-4 аспирантами, этот же человек не моргнув глазом, заявляет «а, ну так это же элементарно и тут вообще делать нечего!».

И обратный пример

2) Некто, обсуждая какую-то научно-техническую проблему, заявляет, что все возможные вопросы в этой области давно уже решены (как правило, в его собственных трудах и диссертациях), и что никакие дальнейшие разработки и исследования вопроса смысла не имеют. При этом он сам и его научный коллектив почему-то оказываются неспособны не то, что собрать действующий макет, а даже осознать принципиальную текущую нерешаемость задачи в рамках уже известных наработок.

Это, конечно, не прямая аналогия; пожалуйста, не воспринимайте это буквально и лично. Но примеры характерные и вызывают у собеседников оправданные негативные эмоции. Я поэтому воздержался от комментариев, а кто-то другой, видимо, не воздержался.
Я объясню свою позицию. В реверсе\восстановлении\реализации всевозможных протоколов, крипталгоритмов и прочего имею довольно-таки богатый опыт и мне, с позволения сказать, несколько неясен смысл сей статьи в таком состоянии. Я бы на вашем месте сперва релизнул бы бета версию сей утилиты с минимальным функционалом и приурочил бы к ней выход некого обзора\how-to статьи.
Сугубое ИМХО. Против вас лично ничего не имею, как и против минусующих кемрадов.
несколько неясен смысл сей статьи в таком состоянии

Оценка интереса сообщества к этой тематике;
Удовлетворение собственного тщеславия;
Закрепление приоритета (слишком уж часто в последнее время я обнаруживал анонсы реализаций того, до чего кто-то додумался тоже)
и т.п.
Очень интересно, жду продолжения.
В свое время потратил некоторое время на попытки расшифровать водяные знаки в скриншотах из танков.
Можете развернуть пункт?
набросал в нём специализированный win32-отладчик

Я например вообще понятия не имею как писать отладчики. Если я хочу вмешаться в процесс, я подсовываю ему свою ДЛЛку взамен какой-нибудь системной, или вроде того (DLL Proxy метод).

Вот ваш метод весьма интересен.
Конкретно в этом пункте ничего особенного, всё было написано на чистом WinAPI строго по MSDNу. Я думаю, примеров минимальных отладчиков везде полно, нужен CreateProcess() с DEBUG_PROCESS, и WaitForDebugEvent() с ContinueDebugEvent() в цикле. На удивление простое и понятное API.

Но если вас интересует конкретная реализация (с брейкпоинтами и вытягиванием памяти) я могу поделиться исходником своего класса отладчика. Только он на FPC, если вас это не смутит.
Мне главное понять принцип действия API, на каком он языке не столь важно :) Если не затруднит, я бы посмотрел.
По поводу шифрования. Я увидел там RSA реализуемый библиотекой OpenSSL.

Вот тут идет вызов виртуальной функции, которая по факту есть rsa_public_encrypt
IDA Proc
image


* Что-то спойлер у меня получился саморазворачивающийся…

Я писал эту статейку в день релиза 0.8.11, поэтому разбираться с конкретным механизмом шифрования не было времени, а в 0.8.10 однажды в процессе погони за функциями брейкпоинт на чтение из буфера сработал прямо в середине BF_ecb_encrypt(). И действительно, выбор BlowFish, как мне кажется, более оправдан — это наиболее быстрый блочный шифр, в то время как RSA — не быстрый и не блочный, и даже не потоковый. Его использование для игровых целей очень сомнительно, и, ИМХО, вызвало бы неслабый оверхед по вычислительной мощности на игровом кластере.
Возможно, тот код, что вы привели, имеет отношение к авторизации, которая выполняется однократно за сессию.
Не исключено. Я занимался именно авторизацией.
Немножко не в тему, но не встречался ли кому либо снифер для RakNet протокола? Или описание самого протокола на уровне UDP пакетов?
Так он же опенсорс вроде, можно, как вариант, заглянуть в исходники да посмотреть как формируются пакеты.
Извиняюсь за нескромный вопрос, но это не вы танк этот… того..? :)
Скажите, почему был выбран метод отладки как способ перехвата пакетов, а не например тот-же dll proxy/injection + сплайсинг, разве наличие int 3 не замедляет выполнение программы?
Исключительно из соображений трудоёмкости реализации.
Прокси-DLL это вообще какой-то костыль, который мне не нравится из эстетических соображений.
Я не так давно в рамках выполнения другого проекта писал внедрение невидимой DLL в процесс, и помню, что даже если не париться с невидимостью, мороки всё равно намного больше, чем от написания простого отладчика.
Нет, int3 не замедляет, я проверял. Даже с учётом всех танцев с откатом контекста и поиском именно того потока, который трапнулся на брейкпоинте, достаточно просто не заниматься в отладочном потоке ничем, кроме сброса вытащенных буферов памяти в очередь другого потока (который и занимается анализом — такая себе «двойная буферизация»), и тогда ни FPS ни пинг не проседает. Субъективно — по игре не заметно, идёт она под такой отладкой или нет.
Ну вогнать dll-ку в чужой процесс не так уж и сложно
вот как вариант, тут, правда, не хватает пары проверок
program Injector;

uses
  shellapi,
  Windows;

type
  TInject = packed record
    PushLoadLibraryCommand: BYTE;
    LoadLibraryArg: DWORD;
    CallLoadLibrary: word;
    CallLoadLibraryAddr: DWORD;
    PushExitThread: BYTE;
    ExitThreadArg: DWORD;
    CallExitThread: word;
    CallExitThreadAddr: DWORD;
    AddrLoadLibrary: pointer;
    AddrExitThread: pointer;
    LibraryName: array [0 .. MAX_PATH] of Char;
  end;

{$R *.res}

  { Внедрение Dll в процесс }
function InjectDll(Process: DWORD; ModulePath: PChar): boolean;
  function Offset(struct, field: pointer): cardinal;
  begin
    Result := cardinal(field) - cardinal(struct);
  end;

var
  Memory: pointer;
  Code: DWORD;
  BytesWritten: DWORD;
  ThreadId: DWORD;
  hThread: DWORD;
  hKernel32: DWORD;
  Inject: TInject;
begin
  Result := false;
  Memory := VirtualAllocEx(Process, nil, sizeof(Inject), MEM_TOP_DOWN or MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  if Memory = nil then
    Exit;

  Code := DWORD(Memory);
  // инициализация внедряемого кода:
  FillChar(Inject, sizeof(Inject), 0);

  Inject.PushLoadLibraryCommand := $68;
  Inject.LoadLibraryArg := Code + Offset(@Inject, @Inject.LibraryName);
  Inject.CallLoadLibrary := $15FF;
  Inject.CallLoadLibraryAddr := Code + Offset(@Inject, @Inject.AddrLoadLibrary);

  Inject.PushExitThread := $68;
  Inject.ExitThreadArg := 0;
  Inject.CallExitThread := $15FF;
  Inject.CallExitThreadAddr := Code + Offset(@Inject, @Inject.AddrExitThread);

  hKernel32 := GetModuleHandle('kernel32.dll');
  Inject.AddrLoadLibrary := GetProcAddress(hKernel32, 'LoadLibraryW');
  Inject.AddrExitThread := GetProcAddress(hKernel32, 'ExitThread');
  lstrcpy(@Inject.LibraryName, ModulePath);
  // записать машинный код по зарезервированному адресу
  WriteProcessMemory(Process, Memory, @Inject, SIZE_T(sizeof(Inject)), SIZE_T(BytesWritten));
  // выполнить машинный код
  hThread := CreateRemoteThread(Process, nil, 0, Memory, nil, 0, ThreadId);
  if hThread = 0 then
    Exit;
  WaitForSingleObject(hThread, INFINITE);
  CloseHandle(hThread);
  VirtualFreeEx(Process, Memory, 0, MEM_RELEASE);
  // надо-надо умываться по утрам и вечерам
  Result := True;
end;

procedure StartHook;
var
  ShellInfo: SHELLEXECUTEINFO;
begin
  FillChar(ShellInfo, sizeof(ShellInfo), 0);
  ShellInfo.cbSize := sizeof(ShellInfo);
  ShellInfo.lpFile := PChar('hoockedexe.exe');
  ShellInfo.nShow := SW_NORMAL;
  ShellInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
  ShellExecuteEx(@ShellInfo);
  InjectDll(ShellInfo.hProcess, 'inject.dll');
end;

begin
  StartHook;

end.
А со сплайсингом помогает вот эта либа MinHook.
Ну вогнать dll-ку в чужой процесс не так уж и сложно

Я в курсе. Делал инжектор невидимой DLLки (т.е. без файла на диске) для win32/win64.
Но пока подход с дебагом работает, можно кодить основное направление.
Согласен, подход в данном случае не важен, а вот по поводу невидимой dll-ки не поделитесь информацией?, это ведь придётся вручную разворачивать все её структуры в памяти, довольно сложная работа.
На самом деле ничего сложного там нет. Если предварительно снять образ уже загруженной обычным порядком DLL, то потом после внедрения этого образа в целевой процесс нужно только пройти таблицу relocations и расставить защиту памяти по атрибутам секций.
Для первого есть чудесная функция LdrProcessRelocationBlock() в NTDLL, для второго — несколько раз дёрнуть VirtualProtect(). Всё вместе около сотни строк со всеми проверками.
LdrProcessRelocationBlock, ого, не знал о такой штуке, спасибо.
Интересно насколько законно реверс-инжинирить танки?
Вопрос сложный, об этом ветка комментариев выше. Как мне кажется по совокупности последних событий, КВГ не против этого проекта до тех пор, пока он не предназначен для продажи и пока он не светится на оф.форуме и не провоцирует настроения в духе «читы возможны а власти скрывают».
записи боёв в WOT шифруются BlowFish'ем, и что ключ шифрования не изменялся с того момента, как стал известен широкой публике

Можно поподробнее на этом моменте? Или может где-то уже написано?
Одно время хотел написать грамотный анализатор реплеев…
сейчас (с выходом 8.11) я вот не уверен, что есть надобность — в открытых заголовках там сейчас лежит куча инфы, раза в два больше, чем раньше (знаю так как написали и используем тот самый продвинутый анализатор реплеев, хоть и для специфических нужд, так что достаточно только открытой в нем инфы)
В 8.11 добавили новую открытую инфу? То что написали открыто или..?
Посмотрите внутрь файла реплеев от 0.8.11 — там открытым текстом лежит JSON со статистикой боя (той, что показывается в клиенте после боя). В шифрованном виде только хронология событий.
Ну так открытая часть она всегда была, интересуют именно события
Все пакеты, проигрываемые клиентом с реплея имеют json формат, покрытый Pickle. Для нормального разбора реплея нужно знать структуру исходного пакета.
А про какой blowfish с известным ключем тогда идет речь в статье?
А это уважаемый AN3O «забыл» сказать, что эти самые Pickle в реплеях таки шифруются именно blowfish'ем. Да вы всё-таки посмотрите внутрь реплея, там видно.
Я имел в виду вот это, и хотя это для 0.7.3, по слухам, ключ с тех пор не менялся.
Приветствую,

А по ватсиму вы свои разработки куда-нибудь выкладывали?
отписал в лс.
Автор, не верным путём вы идёте.
Получать игровые данные надо чисто, иначе бан не заставит себя ждать. Ваше вмешательство должно быть невычислимо. Единственный способ этого достичь (и конкретно для вашей задачи — получить данные не вмешиваясь в игру — он подходит идеально) — снифер.
Посмотрите в сторону библиотеки pcap. В итоге вы будете разбирать трафик игры параллельно с клиентом, никак не вмешиваясь в его работу.
Для этого метода придётся приложить чуть больше усилий — потребуется разобраться как осуществляется шифрование трафика и обмен ключами. Зато вам не надо будет при каждом обновлении игры искать куда переехали адреса функций, в которые вы ставите брекпоинты.
Во-первых, при грамотно сделанном шифровании с обменом ключей сниффер не поможет в принципе.
А решать проблемы буду по мере их поступления. Кстати, по опыту — NMAPI более вменяемый, чем pcap.
Я пока не сталкивался с проектами в которых было бы грамотно сделано шифрование. Хорошие надёжные шифры требуют много ресурсов.
Фогейм когда только запустил сервера Ла2 проводил эксперименты с шифрованием. Включили на пару дней. Сервера стали лагать адски. Шифрование выключили и не включали уже до фроста. Чего в фросте в итоге сделали — не знаю.
Вам стоит разобраться как игра формирует ключи. Как минимум из академического интереса :)
Надёжность шифра и количество ресурсов тут совершенно ни при чём. Вот простая схема, которую можно за пару часов реализовать на штатном crypto winapi: алиса и боб каждый у себя генерят пару публичный-приватный ключ RSA; отправляют каждый другому свой публичный ключ; шифруют не своим ключом новый сгенеренный ключ, допустим, от RC5 или того же блоуфиша; передают его на ту сторону, там его расшифровывают приватным. Всё, теперь в обе стороны может ехать поток шифротекста, закрытый двумя независимыми ключами RC5/BF, которые любой MITM принципиально не сможет узнать за время актуальности данных даже при минимальном размере ключа RSA. Можно даже обойтись и одной стороной — пусть даже только один боб передаёт алисе свой потоковый ключ закрытый парой алисовых rsa. И всё тоже самое, только проще в два раза.
У меня такое делают студенты на лабораторках, я ж думаю, товарищи из КВГ как минимум не глупее. И даже если так не сделано, сделать это легко и просто и на нагрузке игровых серверов не отразится вообще никак, потому что сессию стартует сервер авторизации, а не игровой, а его нагрузка — около десятка юзеров в секунду.
Теоретически да. Но если рассуждать в таком ключе — отрезать отладчик так же легко как снифер. Смотреть надо как сделано.
Я считаю что по возможности надо использовать методы не трогающие процесс игры. А внедрение в код, это уже крайние меры.
В любом случае в клиенте будет место, где этот «шифрованный» трафик будет декриптиться — что мешает сплайснуть эту функцию и слать\получать трафик например через свой локальный SOCKS5 прокси, где вы при желании спокойно будете видеть его (трафик) кристально чистым?

Учитывая, что клиенты КВГ вообще ничем и никак не защищены, для экспериментов там поле непаханое.
Ничего не мешает — именно так всё и сделано, за исключением того, что вместо сплайса применяется гораздо более простой в реализации дебаг.
Не в шифровании было дело а в убогости модуля обнаружения потенциально нежелательного ПО, проблему которого в данный момент решили введением WhiteList'ов, постоянно собираемых с пользователей.
Shildconsole запущенная на ОБТ. Отработала пару недель. Потом прошло обновление после которого стало всё дико лагать. Через пару дней очередное обновление и все проблемы как рукой сняло.
На тематических форумах обсуждалось. Проводился эксперимент с дополнительным шифрованием трафика. Неудачный. Остальные системы Shieldconsole работали всё время. И только после ОБТ, если мне не изменяет память, появился фрост. Какие проблемы были у фроста и как решались я не знаю.
— (Как относится WG к расшифровке на Хабре протокола игры?)
— Посмеялись, спасибо.
© Storm (Wargaming)
Было бы там что расшифровывать.
Даже не сказали какие порты используются.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации