Игры Paul Potseluev
2 856

Как я мог похоронить Call of Duty 4: Modern Warfare, но воздержался. Сага об ошибках разработчиков

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

В закладки
Кадр из ролика Mazarini and Parad0x: Play with soul

Современная Call of Duty вызывает много вопросов: кто-то обвиняет игру в конвейерности, кто-то — в том, что её движок невероятно устарел. Однако в истории серии были и гораздо более светлые моменты.

Я познакомился с CoD ещё с первой части, во вторую даже пытался играть на соревновательной уровне. К выходу «четвёрки», ставшей в своё время настоящим прорывом для жанра шутер, я уже осваивал азы программирования, активно общался в нескольких сообществах вроде codru, поигрывал в паре любительских команд на непризовых турнирах и катал матчи с рандомными англоязычными игроками из IRC-канала codmix.

На тот момент — начало 2010 года — игра вполне могла занять свою нишу в киберспорте: имелся и хороший любительский мод, убиравший случайности и лишние обвесы и заточенный под соревновательную составляющую. Имелось и большое комьюнити, которое активно поддерживало как разработчиков мода, так и всевозможные оффлайновые активности. Имелись и спонсоры, готовые вкладывать в эти активности средства и проводить киберспортивные турниры. Конечно, об уровне CS мечтать было глупо, однако стать чем-то вроде современного R6: Siege «калда» в своё время вполне могла.

Но издатель так не считал. Activision уже тогда решила поставить разработку на конвейер и отказалась от дальнейшей поддержки продукта спустя семь относительно небольших патчей и один игровой год. С конца 2009 года комьюнити осталось один на один с проблемами, багами и читерами.

Qnatek Summer Battle-2012 в Киберспорт-арене в Киеве

Отчасти спасал Punkbuster, всем известный античит, позволявший делать скриншоты с экрана игрока и проверять пользовательские переменные. Отчасти спасало сообщество разработчиков, написавшее отличный мод Promod (его я упоминал выше). Отчасти от моментального вымирания игру спасла и Infinity Ward, компания-разработчик, буквально в первый год опубликовавшая набор инструментов для мододелов: в нём содержались исходники практических всех скриптов движка IW и утилиты, позволявшие эти скрипты редактировать и компилировать.

Именно наличие этих инструментов позволило тогда удержать игру на плаву. И именно оно, по иронии судьбы, могло практически моментально её похоронить.

Прежде чем продолжить историю, я постараюсь кратко пояснить как работала игра: существовали основные скрипты (файлы формата .gsc), где на близком к C языке описывалась игровая логика. Набор этих файлов компилировался в отдельные fast-файлы (.ff), через которые движок непосредственно создавал для игрока игровой мир и все происходящие в нём процессы. Fast-файлы, насколько я помню, были «исполняемыми файлами» для движка, для их выполнения ему уже не требовался интерпретатор. В этих же файлах находились все игровые меню (их написание во многом совпадало с написанием интерфейсов через win32api). Шутка была в том, что большая часть этих скриптов выполнялась на стороне сервера. Клиенту нужны были только файлы с настройками игровых режимов и те самые меню.

Самое популярное видео о CoD4 авторства российско-чешского киберспортсмена Mazarini. 13 минут крутых фрагов и мемов.

Ещё один тип файлов носил расширение .iwd: по сути это были просто rar-архивы, в которых могли находиться как некритичные для скорости работы .gsc-скипты, так и текстуры, модели и аудиофайлы. В следующих версиях игры разработчики полностью откажутся от .iwd в пользу fast-файлов. Мы последуем их примеру и не будем больше вспоминать.

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

К 2011 году я активно работал вместе с коллегой из РФ над созданием аналога HLTV: плеера, который позволял бы посторонним игрокам подключаться к киберспортивным матчам и наблюдать их от лица любого игрока. Этот плеер мог стать отличной альтернативой стандартным демкам (олды тут?) — неудобно записанному процессу матча от лица одного игрока, который без сторонних утилит невозможно было ни перемотать, ни поставить на паузу.

Скриншот из игры. Credit: IGN

Сразу скажу, что идея наша не выстрелила: во-первых, Activision заявила о запуске собственного CoDTV в Modern Warfare 3, а во-вторых, без интереса спонсоров и оказуаливания серии в целом киберспортивное её комьюнити окончательно начало погибать, хотя на стандартных игровых серверах всё ещё были тысячи игроков.

Разработку мы забросили (хотя и были близки к цели), однако мои познания в движке и структуре игры были настолько полны, что я (и я не хвастаюсь, это просто вопрос опыта) мог превратить CoD:MW во что угодно, что позволяли ограничения этого самого движка.

А теперь к самой сути. Так уж сложилось, что, несмотря на хитрую систему Punkbuster и попытки разработчиков банально обезопасить игру от script-kiddies, проверка файловой системы игры выполнялась по принципу "если размер файла совпадает с тем, что получился у нас тут в IW, значит всё окей". В самом Punkbuster была возможность проверки md5-сумм, но эта фича использовалась только для проверки файлов модификаций (это отдельные небольшие mod.ff и mod.iwd) — чтоб игроки себе текстурки соперников не заменяли на яркие и броские. Проверять хэши стандартных фастфайлов никто не собирался, да это и было логично.

Как вы помните, IW выпустили отличный набор инструментов для моддинга, позволявший игрокам делать с игрой чего душа пожелает. Одновременно они предоставили исходники всех .gsc-файлов и меню игры. Понятное дело, что в самой компании использовали минифицированный код, без лишних комментариев, пробелов и переносов строки, но на стороне клиента для игры на обычных серверах без модов игроку (как я писал немного выше) нужны были только файлы меню.

Это вторая крупная ошибка компании. Да, если человек скомпилирует себе fast-файл, засунув туда все оригинальные скрипты и меню, весить такая штука будет в 2-3 раза больше стандартного.

Но если игрок выкинет практически все .gsc-скрипты (кроме тех, которые выполняются на его стороне) и оставит одни лишь меню, мы получим практически пустой fast-файл, с которым можно играть на любом сервере.

Но как же проверка размеров файла, спросите вы? Да никак, отвечу я. Файл считывался движком до первого неизвестного ему символа, поэтому готовый fastfile можно было просто открыть каким-нибудь блокнотом вроде Notepad++ и забить пустыми символами вплоть до необходимого размера в условные 150 миллионов байт.

Такой файл спокойно воспринимался игрой как правильный и позволял играть на стоковых серверах с пустыми файлами, содержащими только меню.

В promod можно было тренироваться бросать гранаты и простреливать стены, тонко настраивать правила матча. Но главное — он вносил в игру баланс.

Но что это нам даёт? Каким образом можно было похоронить игру? Что за кликбейт в заголовке?

Никакого кликбейта. Просто IW допустили ещё одну глупейшую ошибку. Дело в том, что пользовательские переменные можно было устанавливать командами серверных скриптов (командой setDvar) и... теми самыми menu-файлами, которые мы на этот момент уже могли спокойно редактировать!

Причём все менюшные команды выполнялись только на стороне игрока, сервер не имел к ним никакого отношения! В файлах меню можно было спокойно прописать последовательность действий: "если игрок нажал клавишу K, меняем значение переменной tod_howard с четвёрки на 76".

Как вы понимаете, не все переменные в игре предназначались для постоянного использования. Были среди них такие, которые отключали дым. Были такие, которые отмечали на мини-карте соперников красными точками в любой момент времени, вне зависимости от того, стреляют они сейчас или нет. Такой себе двухмерный wallhack.

Все игровые переменные можно было найти в исполняемом файле игры iw3mp.exe, открыв его блокнотом. И редактирование одной буквы в названии переменной позволяло обходить её отслеживание PunkBuster'ом.

И если попытка включить какой-нибудь полулегальный Wallhack консольной командой пресекалась на стороне сервера, то на стороне клиента — через меню — вы спокойно могли и дым себе отключить, и включить отображение игроков на карте. Можно было даже графический debug-режим врубить, который отключал большую часть визуальных эффектов и создавал отличный контраст между текстурами игрока и окружения.

И весь этот бандитский читерский арсенал находился в моих руках: опубликуй я его в свободном доступе, IW вместе с Punkbuster уже ничего бы не могли сделать, потому как против такой особенности движка не попрёшь.

Мало того, аналогичные меню можно было включать и в код модификаций (ведь fast-файлы открывались с помощью сторонних утилит), что окончательно добило бы не только киберспортивную часть комьюнити, но и вообще все популярные серверы.

Вот такие меню могли создавать игроки с базовыми познаниями в программировании. А я мог ещё и вешать сюда выполнение любых команд.

Сразу скажу, я своим изобретением не пользовался: на стоковых серверах я не играл, а пользоваться таким преимуществом в соревновательных режимах считал бессмысленным (в чём тогда состоит соревнование?)

Но факт остаётся фактом: простая публикация необходимых файлов или хотя бы инструкция по эксплуатации сразу нескольких уязвимостей игры могли разрушить ещё активное тогда сообщество и повредить в том числе Modern Warfare 2, чьи исходники некоторые умельцы тоже научились читать и компилировать. А в дальнейшем — Modern Warfare 3.

Я публикую эту историю сейчас, когда в CoD ниже Black Ops 3 уже никто не играет, а в новых версиях движка часть дыр была прикрыта, пускай и коряво.

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

С полей диванных баталей,
Поцелуев игровой.
Специально для TJournal.

Материал опубликован пользователем. Нажмите кнопку «Написать», чтобы рассказать свою историю.

Написать
{ "author_name": "Paul Potseluev", "author_type": "self", "tags": [], "comments": 20, "likes": 42, "favorites": 10, "is_advertisement": false, "subsite_label": "games", "id": 80982, "is_wide": false, "is_ugc": true, "date": "Sun, 02 Dec 2018 00:49:01 +0300" }
Комментарии

Необыкновенный кран

21

Ждал редизайна, чтобы не идти с этой телегой на D*F.

Виновный Паша

4

История о том как Поцелуев мог показать всем кузькину мать но пожалел

Эмоциональный американец

5

Call of Duty: Kerchensky Warships

Игры
дискуссии в сообществе доступны только владельцам клубного аккаунта
С клубным аккаунтом вы сможете
создавать записи и вести дискуссии в закрытых сообществах
наслаждаться нашим сайтом без рекламы
помочь проекту и почувствовать себя лучше
Купить за 75₽

Прямой эфир

[ { "id": 1, "label": "100%×150_Branding_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox_method": "createAdaptive", "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "ezfl" } } }, { "id": 2, "label": "1200х400", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "ezfn" } } }, { "id": 3, "label": "240х200 _ТГБ_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "i", "ps": "cndo", "p2": "fizc" } } }, { "id": 4, "label": "240х200_mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "i", "ps": "cndo", "p2": "flbq" } } }, { "id": 5, "label": "300x500_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "ezfk" } } }, { "id": 6, "disable": true, "label": "1180х250_Interpool_баннер над комментариями_Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "ffyh" } } }, { "id": 7, "label": "Article Footer 100%_desktop_mobile", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byswn", "p2": "fjxb" } } }, { "id": 8, "label": "Fullscreen Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "fjoh" } } }, { "id": 9, "label": "Fullscreen Mobile", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "fjog" } } }, { "id": 10, "disable": true, "label": "Native Partner Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyb" } } }, { "id": 11, "disable": true, "label": "Native Partner Mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyc" } } }, { "id": 12, "label": "Кнопка в шапке", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "fdhx" } } }, { "id": 13, "label": "DM InPage Video PartnerCode", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox_method": "createAdaptive", "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "cndo", "p2": "flvn" } } }, { "id": 14, "label": "Yandex context video banner", "provider": "yandex", "yandex": { "block_id": "VI-223677-0", "render_to": "inpage_VI-223677-0-130073047", "adfox_url": "//ads.adfox.ru/228129/getCode?pp=h&ps=cndo&p2=fpjw&puid1=&puid2=&puid3=&puid4=&puid8=&puid9=&puid10=&puid21=&puid22=&puid31=&puid32=&puid33=&fmt=1&dl={REFERER}&pr=" } }, { "id": 15, "label": "Плашка на главной", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byudv", "p2": "ftjf" } } }, { "id": 16, "label": "Кнопка в шапке мобайл", "provider": "adfox", "adaptive": [ "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "ccydt", "p2": "ftwx" } } }, { "id": 17, "label": "Stratum Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "fzvb" } } }, { "id": 18, "label": "Stratum Mobile", "provider": "adfox", "adaptive": [ "tablet", "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "fzvc" } } } ]
Не пропустите самое важное,
что происходит в интернете
Подписаться на push-уведомления