Ques/Help/Req Кабинетный хак. Патчим инсталляторы MSI, содержащие CAB-архивы

XakeR

Member
Регистрация
13.05.2006
Сообщения
1 912
Реакции
0
Баллы
16
Местоположение
Ukraine
MSI — самый популярный формат инсталляторов. Для редактирования таких установочных пакетов придумано много удобных инструментов, но они могут не сработать, если инсталлятор содержит набор CAB-архивов. Сегодня я расскажу, как править данные внутри инсталляционных пакетов MSI в ручном режиме, если другими способами сделать это не получается.

В своих статьях я периодически поднимаю тему разборки и патча инсталляционных пакетов. На этот раз я хочу продолжить тему, начатую в статье «Ломаем инсталлятор. Как обмануть инсталлятор MSI методом для ленивых», — ручной патчинг нестандартных MSI-пакетов, редактировать которые традиционными средствами невозможно. В той статье мы разбирали правку и замену установочного скрипта, а сейчас попробуем поменять данные в инсталлируемых файлах.

Итак, нам нужно внести изменения в инсталлятор MSI, например заменить в нем один содержащийся в CAB-архиве файл другим. В связи с востребованностью задачи умные люди придумали множество редакторов MSI-пакетов разной степени продвинутости: Advanced Installer, Master Packager, Orka, MSI Editor и другие. Из них лично я особо выделил бы Master Packager: этот редактор, на мой взгляд, наиболее корректно выполняет разборку, редактирование и пересохранение MSI-пакетов различной сложности.

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

Причем разобрать пакет на составляющие его файлы и таблицы — как раз задача несложная, проблемы начинаются именно в процессе перекомпиляции патченного файла. В принципе, вытащить файлы из инсталлятора (как я уже писал в статье «Ломаем инсталлятор. Как обмануть инсталлятор MSI методом для ленивых») можно и без спецсредств — практически любой нормальный архиватор (7-Zip, WinRAR и другие) открывает MSI, как архив.

С помощью архиватора можно извлечь оттуда составляющие установочный пакет CAB-файлы, а они, в свою очередь, также открываются многими архиваторами (собирать CAB из составляющих умеют такие программы, как PowerArchiver, ACDzip или специализированный Cabarc). О том, как засунуть исправленный CAB обратно в MSI, я расскажу позже.

В конце концов, можно разложить MSI на составляющие файлы, минуя промежуточные CAB, просто запустив msiexec с ключом /a (при этом создается папка со всем содержимым пакета MSI). Есть еще более продвинутый способ — натравить на инсталляционный пакет утилиту с открытым исходным кодом msi2xml. Она запускается следующей командой:

msi2xml -c files installation.msi

При этом в каталог files распакуются все файлы проекта из составляющих его CAB, а также создастся файл полного описания проекта installation.msi со всеми таблицами и логикой процесса установки. С использованием этого файла становится возможным собрать инсталлятор командой

xml2msi -m installation.xml

Такая низкоуровневая операция помогает, если не работают описанные выше методы. Но, к сожалению, пересобранный подобным способом инсталлятор тоже не всегда оказывается работоспособным. Действительно, бывают случаи, когда автоматизированные способы не срабатывают. Например, если у нас имеется многотомный непрерывный архив, в середине которого нужно поменять один файл, не трогая остальную структуру. По традиции я расскажу, как руками пропатчить файл в CAB-архиве без его полной перепаковки.

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

Распишем эту структуру поподробнее:

struct CFHEADER{ // 1 красный — сигнатура файла MSCF u1 signature[4] u4 reserved1 // 2 желтый — размер файла в байтах u4 cbCabinet u4 reserved2 // 3 зеленый — смещение до первой записи CFFILE u4 coffFiles u4 reserved3 // 4 голубой — minor-байт версии файла u1 versionMinor // 5 фиолетовый — major-байт версии файла u1 versionMajor // 6 белый — количество записей CFFOLDER в файле u2 cFolders // 7 черный — количество записей CFFILE в файле u2 cFiles // 8 оранжевый — флаги формата: 3 = 1 (cfhdrPREV_CABINET у файла есть предыдущий том) | 2 (cfhdrNEXT_CABINET у файла есть следующий том) u2 flags // 9 желтый — ID кабинета, один и тот же у всех томов архива u2 setID // 10 красный — порядковый номер данного тома u2 iCabinet; // Эти поля не обязательны и в архиве не присутствуют, поскольку бит 2 поля flags не установлен u2 cbCFHeader; u1 cbCFFolder; u1 cbCFData; u1 abReserve[]; // 11 зеленый — необязательное имя предыдущего тома, строка, заканчивающаяся 0, в нашем случае Data1.cab u1 szCabinetPrev[]; // 12 белый — необязательное имя предыдущего диска, в нашем случае пустое u1 szDiskPrev[]; // 13 фиолетовый — необязательное имя следующего тома, в нашем случае Data12.cab u1 szCabinetNext[]; // 14 белый — необязательное имя следующего диска, в нашем случае пустое u1 szDiskNext[];};

Чтобы поменять файл в архиве, надо для начала его найти. В этом плане нам интересен массив записей CFFILE. Каждая из записей в этом массиве содержит данные о файле, хранящемся в архиве. На начало массива указывает поле coffFiles. Посмотрим, как оно выглядит в реальном файле.

Распишем подробно и эту структуру:

struct CFFILE{ // 1 красный — размер распакованного файла в байтах u4 cbFile; // 2 желтый — смещение до начала файла в распакованном блоке folder u4 uoffFolderStart; // 3 зеленый — номер структуры CFFOLDER, содержащей данные файла в общей таблице folder’ов // В этом примере равно ifoldCONTINUED_FROM_PREV (0xFFFD) u2 iFolder; // 4 желтый — дата создания файла u2 date; // 5 фиолетовый — время создания файла u2 time; // 6 голубой — атрибуты файла u2 attribs; // 7 оранжевый — имя файла, заканчивающееся нулем u1 szName[];};

Настало время пояснить несколько моментов. Ты, видимо, уже обратил внимание, что не все содержащиеся внутри CAB-архива файлы имеют свои оригинальные имена. Скажем так, практически все файлы, содержащиеся внутри архива CAB, используют некие промежуточные «технические» имена, чтоб нам жизнь медом не казалась. В этом можно убедиться, открыв CAB-файл в любом поддерживающем данный формат архиваторе. По сути, «технические» имена — это сокращенный GUID, который инсталлятор присваивает каждому файлу в пакете.

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!​


Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

-60%

1 год​


9990 рублей 4000 р.


[TD]

1 месяц​


920 р.
[/TD]

Я уже участник «Xakep.ru»
 
198 094Темы
635 065Сообщения
3 618 395Пользователи
ashot.Новый пользователь
Верх