Анализ и распаковка установщика QTInstaller вручную. С помощью HEX-редактора и такой-то матери.

Преамбула

Понадобилась мне одна программка, которая, почему-то не захотела ставиться на мою систему, причем не захотела без всяких ошибок и вылетаний. Инсталлятор просто висел на 1% и дальше двигаться не хотел. Зная, что поддержка винды у этой софтины зависит исключительно от бодуна разработчиков (то они винду вообще не поддерживали, потом прошлая версия прекрасно ставилась и работала, а тут вдруг опять нет), решил я в софтине поковыряться, небось, софтина-то работает, а инсталлятор кривой. Но о том, как я возился с софтиной, напишу как-нибудь позже. А тут будет такой простенький заметк про реверсинг инсталлятора.

Определение инсталлятора

Я уже как-то упоминал (копия), что инсталляторов и упаковщиков есть туева хуча на свете, и для начала надо определить, с каким именно инсталлером мы имеем дело. Для этого воспользуюсь программкой Detect It Easy (DiE), которая по своей базе сигнатур может определять тип экзешника, чем он упакован, чем скомпилирован, а если это инсталлятор — определить и его тип. Программка работает примерно также, как антивирусный сканер, определяя по сигнатурам, с чем мы имеем дело. Благо, почти все упаковщики, компиляторы или сборщики инсталляционных пакетов, так или иначе оставляют свою сигнатуру в файле.

Итак, скармливаю DiE исследуемый инсталлятор.

Видим тип — QT installer.

Об автоматической распаковке и дальнейших мыслях

Естественно, о ней я и подумал сразу же, не изобретать же велосипед, до нас его более умные люди изобрели. А не тут-то было! Автоматического распаковщика не нашел, так что стал думать… Qt проект открытый, значит, скорее всего, они особо не заморачивались, и инсталлятор представляет из себя самораспаковывающийся архив, который по структуре выглядит как-то так, как выглядят самораспаковывающиеся архивы RAR WinZip или 7Zip — в начале файла EXE-модуль, а после него данные, которые EXE-модуль распаковывает:

В принципе, что я иду верным путем, можно было понять из главного окна DiE, тот недвусмысленно сообщал про overlay (оверлей), в котором находятся QT installer data, т.е. данные QT-установщика.

Разглядывание и дамп оверлея

На то, что представляют собой данные установщика (оверлей) можно посмотреть, собственно, из DiE, нажав кнопку Overlay в главном окне программы. У DiE есть встроенный небольшой HEX-редактор, в котором оверлей и откроется.

А почему бы не поковырять оверлей отдельно от экзешника? Вряд ли в самом SFX-модуле найдется что-то полезное. Подумав так, я решил отделить оверлей от SFX-модуля, т.е. сдампить его в отдельный файл. Благо, функция дампа у DiE тоже была, достаточно нажать правой клавишей мыши на ту часть окна, где представлена информация в RAW-виде и нажать пункт меню Dump (или комбинацию Ctrl+D)

Сохраняю его в файл Dump.bin.

Первое, что бросается в глаза, когда посмотришь на дамп, это сигнатура qres, с которой начинается файл. QRes, соответственно, сокращение от Qt Resources, оказалось, я прав — это бинарный формат ресурсов фреймворка Qt.

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

Распаковщик ресурсов Qt

Опять же, у меня возникла мысль о том, что ну явно же кому-то надо было расковыривать бинарные ресурсы Qt, значит, умные люди уже сделали какой-нибудь распаковщик ресурсов…

Нашел, но, к дикому моему сожалению, он оказался только под Linux, а у меня вокруг одна винда. Решил собрать его в Cygwin, так что, как я его собирал, описываю тезисно:

— Устанавливаем сам Cygwin
— Добавляем пакеты gcc (я просто в поиске менеджера пакетов ввел gcc и поставил все, до чего руки дотянулись)
— Добавляем поддержку Qt5 (аналогичным образом)
— Добавляем git, если еще не установлен.

Далее выполняем:

git clone https://github.com/tatokis/qresExtract

Ответ должен быть примерно таким:

Cloning into 'qresExtract'...
remote: Enumerating objects: 12, done.
remote: Total 12 (delta 0), reused 0 (delta 0), pack-reused 12
Receiving objects: 100% (12/12), 11.70 KiB | 520.00 KiB/s, done.
Resolving deltas: 100% (3/3), done.

далее переходим в директорию qresExtract:

cd qresExtract

И выполняем компиляцию. Тут немножко пришлось поковыряться, т.к. стандартные qmake && make из инструкции к программе в Cygwin не сработали, оказалось, надо так:

qmake-qt5

Ответ:

Info: creating stash file /home/Nigger/tst/qresExtract/.qmake.stash

и далее:

make

Соберется экзешник qresExtract.exe. Впрочем, кому лень собирать, готовый экзешник со всеми DLL будет в ссылках в разделе «Инструменты».

Распаковка ресурсов с помощью qresExtractor и их анализ

Итак, скармливаем qresExtractor.exe наш Dump.bin.

qresExtract.exe Dump.bin

И я-то, дурак, думал, что на этом все. А вот хуй тебе, Толян!

Экстрактор наделал кучу директорий в папке с Dump.bin, но, блин, нам досталась только мета-информация: некий скрипт install.js с инструкциями по установке софта, config-internal.ini, в котором, впрочем, обнаруживался обнадеживающий параметр offlineOnly=true, т.е., скорее всего, установщик оффлайновый, и бинарники не качаются из интернетов, и они где-то с нами.

Впрочем, в одном из конфигов оказалась интересная информация, в XML-файле перечислялись названия 7zip-архивов:

<DownloadableArchives>bearer.7z,iconengines.7z,imageformats.7z,platforms.7z,
qmltooling.7z,Qt.7z,QtGraphicalEffects.7z,QtQml.7z,QtQuick.7z,
QtQuick.2.7z,styles.7z,translations.7z,content.7z</DownloadableArchives>

Детективный поиск бинарников, 7z архивы, их поиск, дампинг и распаковка

Это, конечно, надо будет потом автоматизировать, но тут покажу, как я сделал это вручную.

Итак, что такое архив 7z (7zip), это архив, начинающийся с определенной сигнатуры:
37 7A BC AF 27 1C.

Откроем файл дампа в шестнадцатеричном редакторе WinHex и попытаемся выполнить поиск по сигнатруре. В меню: Search —> Find HEX Values, вводим значения сигнатуры архива без пробелов (377ABCAF271C).

Я их последовательно нашел вручную (продолжение поиска по F3) и в результате составил такую вот таблицу:

Адрес обнаружения сигнатуры Конец архива
2513 ABDE
ABDF 113DE
113DF 9642C
9642D 15D369
15D36A 19E04D
19E04E 1C0868
1C0869 1D670C
1D670D 1E6AAC
1E6AAD 3C6FA7
3C6FA8 3CFCD0
3CFCD1 3E4392
3E4393 46FC7F
46FC80 01F20307

Я предположил, что 7z-архивы идут подряд, один за другим, потому вычислял конец предыдущего архива, как -1 байт с начала сигнатуры следующего, а за конец предыдущего архива взял конец файла. 7z-архиву пофиг, если после самого архива окажется какой-то мусор. Так что последний архив все равно должен был открыться. Так и получилось.

Сдампил архивы я тоже с помощью WinHex. На руках у меня была таблица с начальными и конечными адресами архивов, оставалось ввести их в окно Edit—>Define Block и ввести в окне начальный и конечный адрес, например, 9642D и 15D369 и установить радиокнопку в End:

Можно пойти, проверить, нужный ли блок выделило (Navigation —> Go to —>Beginning of block), если немножко покрутить полосами прокрутки, то явно будет виден заголовок архива:

А можно выделенный блок сдампить в отдельный файл (Edit —> Copy Block —> Into New File), в общем, я так и сдампил архивы, а потом еще их и распаковал. Вот вам два, как пример:

Инструменты

Detect It Easy (DiE):

На Exe-Lab
На Mega.nz

qresExtract:

Binary for Windows x86
Sources

WinHex 19.9:

Скачать с rutracker.org
Ссылка на Torrent-файл

Добавить комментарий

Ваш адрес email не будет опубликован.