Как достать графику из игры. Игровая палитра

Как достать графику из игры. Игровая палитра

Вскрытие — Как достать графику из игры. Игровая палитра
Самое непростое — это раскопать графическую составляющую игры. Рассмотрим, каким именно образом ее от нас прячут. Допустим, вы интуитивно догадываетесь, в каких именно файлах в игре хранится графика (названия файлов очень часто говорят сами за себя). Дело
Игроманияhttps://www.igromania.ru/
Вскрытие
Как достать графику из игры. Игровая палитра

    Ни для кого не секрет, что практически все разработчики сознательно стараются скрыть от игроков все ресурсы игры, дабы потом не созерцать в чужом проекте свои текстуры, звуки и прочее. Для этого они изобретают множество собственных форматов хранения ресурсов, так появляются всевозможные *.scr , *.tex, *.vol и другие. Многие из них на самом деле просто стандартные звуковые, графические и текстовые файлы с измененным расширением (например, во всех играх на движке Q3 pk3-файлы — это обычные zip-архивы). Но есть и настоящие “поделки”, которые никакими универсальными просмотрщиками не откроешь.
144 Kb
Рис. 1. В глаза сразу же
бросается первая строка в
средней части экрана,
последние 4 байта имеют вид
BE 00 7C 00 (обозначена
красным цветом). А ведь эти
числа-то мы и смотрели в
калькуляторе!
Если вы освоите нижеописанный материал, то с достаточной легкостью сможете добывать практически любые графические изображения из любимой игры. А дальше из полученной картинки вы сможете сделать wallpaper или оформить фан-сайт по игре. В общем, сделать с изображением все что угодно, кроме, естественно, использования в коммерческих целях.

    Теория
   
Самое непростое — это раскопать графическую составляющую игры. Рассмотрим, каким именно образом ее от нас прячут. Допустим, вы интуитивно догадываетесь, в каких именно файлах в игре хранится графика (названия файлов очень часто говорят сами за себя). Дело за малым — определить тип данных. Если файлов немного (можно по пальцам перечесть), они большого размера, и если при просмотре их содержимого можно среди закорючек разглядеть имена каких-
141 Kb
Рис. 2. Первые 4 байта файла
являются идентификатором
“RIX3” (на рисунке он выделен
зеленым), а следом за ним идут
уже знакомые нам числа
(выделены красным цветом),
правда, написанные в обратном
порядке: вместо 02 80 записано
80 02 и вместо 01 E0 написано
E0 01. Так и должно быть, так
записываются числа формата
WORD. Далее идет FF 00 (это
число в десятичном формате
равно 256) — количество
цветов в палитре. На все
уходит ровно 10 байт, полная
состыковка!
то файлов, то это игровой архив, и его необходимо разархивировать. Если файлов достаточно много и у них одинаковый размер (в килобайтах), то, скорее всего, это графические файлы с изображениями фиксированного размера, например 256х256 пикселей, и чаще всего без заголовка (Header), но об этом ниже. Если же файлы разных размеров, то это может означать две вещи: файлы содержат заголовки и делятся на два типа — с одним изображением внутри и с несколькими изображениями.
    Рассмотрим по порядку особенности всех трех типов.
    Фиксированный размер, без заголовка. Данный тип примечателен тем, что используется только в трехмерных играх. Все дело в том, что 3D-видеокарты имеют ограничение на размер графических изображений, и разработчикам приходится мириться с этим. Распознать такие файлы очень просто: их размер в байтах должен нацело делиться на 32.
    Этот тип использовался, например, в
Warlords 4, Warlords Battlecry 2.
    Изображение с заголовком. Этот тип может использоваться во всех без исключения игр. В заголовок обычно записывается версия формата, количество бит и размер изображения в пикселях (например, 640х480). Иногда разработчики прибавляют еще несколько записей, иногда некоторые убирают — если вся игра сделана в одной цветовой палитре (например, 256 цветов), то зачем тогда указывать количество бит? За заголовком следуют данные изображения.
    Этот тип был использован в играх Will Rock, NOX.
    С несколькими изображениями и заголовком. Этот тип тоже используется довольно часто, от предыдущего он отличается тем, что файл имеет глобальный заголовок, в который записывается местонахождение (смещение до) каждой картинки в этом файле. У каждой картинки есть свой заголовок, он схож с предыдущим типом.
    Этот тип использовался в Half-Life, “Битве Героев”, Fallout.

78 Kb
Рис.3. Посмотрите, как текстура
забора выглядит в игре.
    Инструментарий
   
Переходим к трудоемкой, но весьма увлекательной практике. Если вы не владеете языками программирования или у вас нет денег для покупки программ-компиляторов, то “Игроманию” с CD или DVD вы приобрели не зря. На нашем диске вы найдете программу Image Hacker v1.1. Программа представляет собой абсолютно легальный текстовый редактор с возможностью запускать специальные скрипты. Скриптовый (читайте — текстовый) файл получается очень маленький, поэтому его намного легче отослать кому-то по почте. Язык скриптов данной программы заимствует многое у языка Паскаль (Pascal), но имеет намного меньше процедур, из-за чего
становится очень простым, и в нем сложно запутаться. Команды языка вы можете прочитать на врезке. Еще я надеюсь, что у всех найдется старичок Windows Commander, в поздних версиях он называется Total Commander (далее ТС). Но если его нет, то сойдет любой HEX-viewer. А также обычный “Калькулятор”, входящий в стандартный пакет программ Windows.
    Чтобы активировать HEX-viewer в ТС, необходимо просмотреть нужный файл (клавиша F3) и выбрать шестнадцатеричный вид (клавиша 3). Желательно переключиться в ASCII, нажав кнопку S. Весь файл будет графически разбит на строки по 16 символов. Экран будет разделен на три части: первая указывает на номер первого элемента строки (в шестнадцатеричном коде), вторая (самая широкая) показывает HEX-код каждого символа, третья показывает сами 16 символов. Нам будет нужна только вторая часть.

    Структура файлов
   
Структура всех файлов делится на две части: заголовок (его может и не быть, как в первом случае) и данные изображения, где хранятся цветовые значения всех точек (пикселей) изображения. Цветовое значение состоит из трех оттенков: красного (red), зеленого (green) и синего (blue). Сокращенно RGB. Это цвет в формате 24 бита (под каждый оттенок отводится 8 бит), и он “вмещает” в себя около 16,5 миллионов цветов.
    В 32-битных изображениях к RGB добавляется уровень прозрачности (alpha), показывая
глазу уже 4 миллиарда цветов, но человек не способен увидеть десятой части этих цветов из-за своих скромных биологических возможностей. В 16-битных изображениях (это самый сложный для понимания формат) за счет понижения количества оттенков RGB в 256 раз удалось существенно снизить затраты процессорной мощи на обработку изображений, правда, цветов осталось всего 65535.
    Наконец, 256-цветные изображения. Их структура очень проста: в заголовок или в отдельный файл записывается палитра из 256 цветов в формате 24 бит, а в области данных каждой точке приписывается номер цвета в палитре от 0 до 255, этот номер умещается в размерность одного байта, поэтому этот формат также называют 8-битным (1 байт=8 бит).

27 Kb
Рис. 4. И как она же выглядит в
графическом редакторе.
    Анализ
   
Создайте в любом графическом редакторе картинку, нарисуйте что-нибудь, запомните ее размер (например, 190х124, далее я буду рассматривать именно такой размер) и сохраните в формате tga с цветовой палитрой 24bit. Запустите калькулятор, в меню нажмите “Вид” и выберите “Инженерный”. Вводите размер картинки по горизонтали (в примере это 190) и выберите оператор HEX. Вместо 190 появится число в шестнадцатеричном коде, равное BE. Запомните это число, перейдите в оператор DEC — вместо BE снова появится 190. Введите высоту картинки 124 и повторите процедуру. Запомните получившийся результат, если вы все сделали правильно, то это будет . Теперь открывайте вашу картинку HEX-viewer’ом в Total
Commander, как описано выше.
    На рис. 1 показано, что мы нашли место в файле, где записаны ширина и высота изображения. Они начинаются в файле с тринадцатого байта и записаны в формате Word (2 байта), об этом говорят байты со значением 00, идущие после BE и 7С в количестве одной штуки (за каждым).
    Это может показаться сложным, поэтому давайте еще раз разберем: на запись ширины и высоты уходит 4 байта (см. рис. 1, выделено красным цветом), логично подумать, что на запись одного параметра уходит 2 байта. Потом идет 2 байта какого-то мусора (выделено зеленым), а далее идут данные изображения, их видно в правой части экрана: если первая строка почти пуста, то все остальные наполнены разными закорючками.

73 Kb
Рис. 5. Много всего интересного
можно найти в графических
архивах игр. Например, в Call
of Duty можно найти планы
битв...
    Процесс пошел
   
Загружайте Image Hacker и начинайте считать, какое количество переменных нам необходимо. Ширина — раз, высота — два, Оттенки R,G,B — три, четыре, пять, и еще две возьмем для рисования изображения (координаты пикселей по осям x и y). Итого семь. Начинаем писать:
    “Showmessage(‘Это мой скрипт для чтения 24-битных tga-файлов’);” затем нажмите F9, и вы увидите окно с этим сообщением — начало положено. Давим кнопку ОК и пишем дальше:
    “Var width, height, r, g, b, x, y; {Объявляем 7 переменных}
    openfileas('*.tga'); {Просим указать нужный файл с маской *.tga}
    setpos(12); {Переходим на 12-й байт в выбранном файле}
    width:=read(3); {Читаем из файла ширину изображения}
    height:=read(3); {Читаем из файла высоту изображения}
    setpos(getpos+2); {Пропускаем 2 байта с мусором}
    setsize(width,height,24);
{Создаем в памяти картинку в формате BMP с размерами TGA-файла}
    for y:=0 to height-1 do {Организовываем цикл для загрузки 3-х оттенков для каждого пикселя по Y, а следующая строка для каждого пикселя по X}
    for x:=0 to width-1 do
    {Так как цикл мы начинаем с 0, а не с 1, от максимального значения мы отнимаем 1, чтобы не вызвать сбой в программе}
    begin {Начало обработки каждого пикселя}
    r:=read(1); {Читаем Byte с оттенком красного}
    g:=read(1); {Зеленого}
    b:=read(1); {Голубого}
    setpixelcolor(x, y ,rgb(r,g,b)); {Пикселю по данным координатам указываем полученный тремя оттенками цвет}
    end; {Завершение обработки}
    savefileas; {Сохраняем получившееся изображение в файл}
    closefile; {Очищаем память от уже ненужных данных}”
24 Kb
Рис. 6 ...и чертежи кораблей и
другой техники.
    Запускаем скрипт (F9), указываем картинку, программа запрашивает сохранение файла. Сохраняем. Смотрим, что получилось, и приходим в недоумение — картинка отражена по вертикали, и цвета какие-то странные. Ну, с тем, чтобы перевернуть изображение, проблем нет (даже Paint с этим справится), но вот что делать с цветами? Ответ прост: многие разработчики пренебрегают стандартным порядком оттенков RGB, зачастую просто меняя местами крайние из них (красный и голубой), то есть получая BGR. Меняем слегка код скрипта (меняем местами порядок чтения красного и голубого):
   
    b:=read(1); {Читаем Byte с оттенком голубого}
    g:=read(1); {Зеленого}
    r:=read(1); {Красного}
    “
   
Запускаем программу, повторяем открытие и сохранение файлов и — вуаля! — получаем правильные цвета, правда, изображение все еще перевернуто. Конечно, это не
столь важно, но если заменить строчку “setpixelcolor(x, y ,rgb(r,g,b));” на “setpixelcolor(x, height-1-y,rgb(r,g,b));”, где исправлены координаты по вертикали, вы получите правильно отображенную картинку.
2 Kb 3 Kb
Рис. 7. В процессе вскрытия могут
получаться непонятные или смещенные
изображения.
Рис. 8. Если слегка подкорректировать
скрипт, все встает на свое место.

   
Боевое крещение
   
Если tga — общедоступный формат и с ним более или менее все понятно, то вот с другими, заточенными под конкретные игры форматами, придется попотеть. И снова на операционный стол ложится старина Fallout 2. Распаковав архивы *.dat в каталоге с игрой, в папке Art\Splash вы найдете файлы в формате *.rix. Это картинки, появляющиеся при загрузке игры.
73 Kb
Рис. 9. Графика из Fallout.
    Сначала прикинем, что мы знаем о графике в этой игре. Мы знаем, что в игре строго фиксированное разрешение экрана — 640х480, и всего 256 цветов. Так как эти картинки в самой игре не используются, предположим, что у них имеется собственная палитра (записанная в заголовок). Проверим. Размер всех файлов фиксирован — 307978 байт. Данные изображения, идущие после заголовка, должны занимать 640*480*1байт=307200 байт. Я умножал на 1 байт потому, что в 256-цветных файлах для каждого пикселя просто записывается номер цвета из палитры (0-255), который умещается в 1 байт. Теперь посмотрим, сколько данных у нас остается: 307978 (размер файла)-307200 (размер данных)=778 байт. Размер палитры у нас 256*3байта (RGB)=768 байт. Палитра вполне умещается, значит, оставшиеся 10 байт идут под остальные данные заголовка (ширина, высота, количество цветов в палитре и идентификатор файла). Проверим догадку — открываем любой rix-файл в HEX-viewer.
    В калькуляторе уже известным способом вычисляем HEX-значения чисел 640 и 480. Они
будут соответственно равны 02 80 и 01 E0. Смотрим первую строчку на рис. 2.
    Теперь можно писать скрипт.
    “{Объявляем переменные
    x,y — часто используемые переменные
83 Kb
Рис. 10. В Fallout много
“потерянных” изображений
(неиспользованных в игре),
наша цель — отыскать их.
    width,height — ширина и высота картинки
    colcount — количество цветов в палитре
    r,g,b — три составляющие цвета (красный,зеленый,синий)}
    var x,y,width,height,colcount,r,g,b;
    {Открываем файл}
    openfileas('*.rix');
    {Пропускаем идентификатор — “Rix3”}
    setpos(4);
    {Читаем ширину как Word}
    width:=read(3);
    {Читаем высоту как Word}
    height:=read(3);
    {Устанавливаем размер и количество бит будущей картинки}
    setsize(width,height,8);
    {Читаем количество цветов в палитре (максимум их 256)}
    colcount:=read(3);
    {Далее организуем цикл загрузки каждого из 256 цветов в палитру нашей BMP картинки}
    for x:=0 to colcount do
    begin
    r:=read(1);
23 Kb
Рис. 11. В некоторых играх
можно найти весьма
интересные композиции.
    g:=read(1);
    b:=read(1);
    setcolortable(x,rgb(r,g,b));
    end;
    {Далее идет цикл формирования BMP из данных изображения}
    for y:=0 to height-1 do
    for x:=0 to width-1 do
    setpixel(x,y,read(1));
    {Сохраняем полученный результат}
    savefileas();
    {Закрываем файл}
   
closefile;
    Запускаем скрипт, указываем файл, проверяем результат и видим: картинка есть, но почему-то очень темная. Вспомним, что картинка при загрузке игры как бы “появляется” из темноты, а потом так же исчезает. Значит, при загрузке игры каждый оттенок RGB-цвета в палитре умножается на какое-то число, и возникает эффект “осветления” картинки.
Методом подбора я выявил, что нормальная по освещенности картинка получается при множителе, равном четырем (4). Смело меняем строку “setcolortable(x,rgb(r,g,b));” на “setcolortable(x,rgb(r*4,g*4,b*4));” и радуемся полученному результату.

    Список процедур
   
Процедуры для работы с файлами в игровом формате
   
OpenFile('Имя файла в одинарных кавычках') — загружает в память файл с картинкой в игровом формате.
    OpenFileAs('В кавычках — маска файла. Например *.*') — открывает диалоговое окно для выбора файла для процедуры Open.
    SetPos(число) — устанавливает позицию в файле, с которой впоследствии мы будем читать данные.
    GetPos() — возвращает нынешнюю позицию в файле.
    GetSize() — возвращает размер открытого файла.
    read(число) — читает и возвращает скрипту данные из файла, где число:
    0 — букву (1 байт)
    1 — байт
    2 — integer (4 байта)
    3 — word (2 байта)
    4 — дробное
число (8 байт)
    CloseFile() — очищает память (обязательно выполняйте эту процедуру в конце скрипта).

   
Процедуры для работы с картинкой
   
setsize(ширина, высота, количество бит) — устанавливает размер картинки. Количество бит может быть 8 (256 цветов) или 24.
    setpixel(x, y, номер цвета в палитре) — устанавливает цвет пикселя с координатами x и y. Эта процедура подходит только для 256-цветных картинок!
    setpixelcolor(x, y, цвет) — устанавливает цвет пикселя с координатами x и y. Эта процедура только для 24-битных картинок!
    setcolortable(номер ячейки палитры (0-255), цвет) — устанавливает цвет для соответствующего номера палитры.
    Save('имя файла в одинарных кавычках') — сохраняет полученную картинку в bmp-файл.
    SaveFileAs() — открывает диалоговое окно для выбора файла для процедуры Save.

    Прочие процедуры
   
RGB(оттенки (числа от 0-255) красного, зеленого, синего) — возвращает полученный при смешении цвет.
    ShowMessage(любое значение) — выводит на экран значение (используйте эту процедуру для проверки прочитанных данных и для вывода указаний по дальнейшей работе).
    ToStr(любой параметр) — превращает любой параметр в строку (иногда требуется для нормальной работы предыдущей процедуры).

   
* * *
   
Все рассмотренные выше примеры входят в комплект программы Picture Hack. В этот раз мы не рассмотрели форматы, где хранится по несколько изображений. О них мы поговорим в одном из ближайших выпусков “Мании”. Напоследок бы хотелось отметить, что процедура обнаружения и вынимания графики из игры все же довольно трудоемка и требует терпения. Надо отдать должное разработчикам, которые потратили столько времени и сил на разработку своих форматов. Не забывайте про это. И помните, что коммерческое использование изображений, “вынутых” описанным в статье способом, незаконно. Вы можете их использовать только в некоммерческих целях.
Комментарии
Загрузка комментариев