Разбор Шрифтов И Перевод Квеста 1996 - У Меня Нет Рта, И Я Должен Кричать



Всего наилучшего! По мотивам одноименной новеллы Харлан Эллисон «У меня нет рта, и я должен кричать» — один из самых мрачных квестов всех времен.

Гнетущая атмосфера не отпускает до конца.

Ближайшее будущее.

Три сверхдержавы — США, Россия и Китай — стремясь превзойти своих соперников, создали суперкомпьютеры для ведения войн.

Но они просчитались.

Объединившись в единое целое, назвав себя АМ, три суперкомпьютера, используя силу, данную им людьми, стерли человечество с лица земли.

Компьютер оставляет в живых только пятерых, которые послужат ему игрушками для бесконечных пыток.

В прошлый раз я описал 8-битный шрифт , но на этот раз нам удалось разобрать 1-битный.

Оба варианта шрифта не зашифрованы и не сжаты, что значительно облегчило задачу.

Инструменты: МАР, досбокс + отладчик Винхекс ГБС .

КДПВ

Разбор шрифтов и перевод квеста 1996 - У меня нет рта, и я должен кричать

Проблема в поиске шрифта среди файлов.

Очевидно, что здесь нет файлов и папок типа FONTS, есть файл ресурсов Scrum.res размером 75,5 МБ.

Используя Process Monitor (ex FileMon) с фильтром на dosbox, я составил таблицу порядка доступа к файлам, смещений и размеров.

Сначала я начал просматривать файл .

res с помощью GBS и искажать блоки в Scrum.res в том порядке, в котором они были вызваны, и нашел место хранения изображений шрифтов:

Разбор шрифтов и перевод квеста 1996 - У меня нет рта, и я должен кричать



Разбор шрифтов и перевод квеста 1996 - У меня нет рта, и я должен кричать

Я нацарапал свои шрифты, которые вроде бы были взяты из Arial, ширину и выравнивание не настраивал, но у меня появилась уверенность, что игру можно перевести, коды букв соответствуют cp1251. Для рисования символов также вполне подойдет Эxel:

Разбор шрифтов и перевод квеста 1996 - У меня нет рта, и я должен кричать



Разбор шрифтов и перевод квеста 1996 - У меня нет рта, и я должен кричать

Позже подсказали отличную ссылку, товарищи из SCUMMVM подхватили игру, есть руководство .

Шрифт 1-битный, то есть в одном байте можно задать 8 пикселей.

Несколько байтов образуют строку.

Несколько строк образуют высоту, получаем блок в памяти (высота*длина строки) байт или прямоугольник с разрешением (высота Х(строка*8)).

Визуально в памяти и в игре они выглядят так (зелёные и красные полоски показывают байты):

Разбор шрифтов и перевод квеста 1996 - У меня нет рта, и я должен кричать



Разбор шрифтов и перевод квеста 1996 - У меня нет рта, и я должен кричать

В игре используется небольшой шрифт R3 и диалоговый шрифт R1. Структура каждого шрифта Заголовок - 1286 байт, состоит из ITE_FONTHEADER, 6 байт INT16, c_height — максимальная высота символа, INT16 c_width — максимальная ширина символов, параметр совершенно ненужный, INT16 row_length — длина строки изображения шрифта (в байтах), Дальше 256 байт, массив индексов, сами индексы я приравнял к cp1251 (AIaya — это индексы 192-255).

INT16 index[256] - номер байта, с которого начинается изображение символа.

Затем 256 байт, массив ширины символов: BYTE width[256] — ширина символа в пикселях, может быть любой в разумных пределах, от 0 до бесконечности.

Ну до 255 :) Затем 256 байт, флаг.

Насколько я понял из серии экспериментов, он устанавливает левое поле, в пикселях.

BYTE flag[256] Флаг неизвестного символа (0 или 1) Дальше 256 байт — отслеживание того, сколько пикселей персонажа нужно отрисовать.

Счет слева направо от 0 до бесконечности.

До байта.

BYTE track[256] — отслеживание После заголовка идет блок данных (row_length * c_height) длиной в байт. Формула для доступа к любому началу строки: font_data + (длина_строки * y), где font_data — указатель на начало данных шрифта, y — номер строки.

Каждый символ занимает ((ширина[индекс] - 1)/8) + 1 байт. После этих данных художник форума создал красивый диалоговый шрифт, похожий на оригинал.

В оригинале было зарезервировано достаточно байт со всякими иконками и умлаутами, чтобы соответствовать оригинальному и русскому шрифту.

В итоге остался даже 1 байт в резерве, который я обнулил.

Я написал программу для копирования блоков из BMP, где русский шрифт рисовался подряд, прямо в игровой блок.

На выходе был набор символов cp1251, значков, цифр, английских и русских символов:

Разбор шрифтов и перевод квеста 1996 - У меня нет рта, и я должен кричать

Начал со второго шрифта:

Разбор шрифтов и перевод квеста 1996 - У меня нет рта, и я должен кричать

Здесь все пошло не так.

Места в исходном блоке было очень и очень мало, то есть из предложенного набора можно было исключить 14 дурацких символов, но для 66 русских букв этого было явно недостаточно.

Сначала я пытался поиграть с количеством байтов в строке, думая, что игра инициализирует буферы в зависимости от высоты и байтов строки.

Я посмотрел в винхексе, что следующий блок - это следующий шрифт, но он нигде в игре не используется.

Сбросил блок, увеличил длину строки, но получил тот же набор символов, но со сдвигом.

Оказалось, что размер буфера данных прописан где-то еще.

Я попробовал оставить длину строки неизменной, но поиграться с индексами.

Из всех моих начинаний у меня ничего не выходило; мусор вышел.

Но оказалось, что я забыл, что в конце файла ресурсов есть таблица смещений и размеров блоков, пришлось с ней поиграться и все бы получилось без файла patch.exe) Тут я запутался, как выкинуть дос-заголовок и вынуть LE-файл, который можно закинуть в IDA, которая с радостью распознает его как 32-битный LE-файл.

Я открыл файл в winhex и нашел строку «*** Обнаружено NULL присваивание», подошел к MZ и обрезал начало до MZ. Спасибо, Крэлаб.

Тут возникла еще одна проблема, как сравнить адрес в досбоксе (выглядит как 180:200c61) и адрес в IDA (выглядит как cseg01:0001AC1F), чтобы увидеть, где исполняется код, и проанализировать его.

Сайт SCUMMVM предлагает довольно глупый вариант, который работает, но крайне медленно.

Я все еще жду IDADOS, когда можно будет посмотреть код в IDA и сразу отследить его силами досбокса.

А пока.

в IDA мы устанавливаем поиск по последовательности около 10 байт, что и видим в отладчике dosbox. Формула этой игры: адрес в досбоксе - 1DFFFE h = адрес в IDA. К этому моменту я знал точные смещения начал шрифтовых блоков и их размеры.

Я начал искать эти цифры в IDA простым поиском, но ничего не нашел.

Затем в отладчике dosbox установите прерывание для позиционирования указателя чтения (int 21h, ah=42h, LSEEK).

Перед вызовом CX:DX должно быть указано значение, на сколько переместить указатель: (CX * 65536) + DX. После нескольких переходов я нашел 2 последовательных вызова на чтение 2-х шрифтов из игры, именно тех, которые используются.

У DX был нужный мне номер.

Я немного перемотал назад и нашел блок инициализации шрифта, который выглядел примерно так: mov eax, 6 (в конечном итоге исправлен до mov eax, 3) позвонить в InitFont мов Еакс, 8 позвонить в InitFont просто в блоке - это шрифты 5 и 7. Поигравшись с разными цифрами, я посмотрел, как выглядят в игре неиспользуемые шрифты:

Разбор шрифтов и перевод квеста 1996 - У меня нет рта, и я должен кричать



Разбор шрифтов и перевод квеста 1996 - У меня нет рта, и я должен кричать



Разбор шрифтов и перевод квеста 1996 - У меня нет рта, и я должен кричать



Разбор шрифтов и перевод квеста 1996 - У меня нет рта, и я должен кричать

Посмотрел размеры блоков шрифтов, выбрал самый большой, перенес туда маленький блок шрифтов, пропатчил исполняемый файл, импортировал русские буквы из BMP (в BMP 256 цветов один байт равен одному пикселю, преобразование байта в биты - это дело второе), поправил индексы, трекинг, ширину, длину строки, увеличил высоту на единицу, чтобы буквы сверху и снизу не сливались и получил наконец финальный шрифт. Я сохранил оригинальные символы, цифры, буквы и добавил ряд русских букв, в том числе Йойо.



Разбор шрифтов и перевод квеста 1996 - У меня нет рта, и я должен кричать

Теги: #Data Mining #обратный инжиниринг #обратный инжиниринг #квест про квест #игры #перевод #занимаюсь пиаром
Вместе с данным постом часто просматривают: