Pull to refresh

Comments 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)
Было бы там что расшифровывать.
Даже не сказали какие порты используются.
Sign up to leave a comment.

Articles