Анализ древней дискеты AVP Z.E.S Linux. Скрипты на закуску.

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

Разборка оригинального bootdisk.img и подключение ramdisk’а

#!/bin/bash

RDMP="/mnt/ramzes"
LDRKRNLPATH="./ldrkrnl/"
LDRKRNLNAME="ldrkrnl.img"

echo "Making dirs"
mkdir $RDPATH
mkdir $RDMP
mkdir $LDRKRNLPATH

echo "Extracting RAMDISK..."
dd bs=1 if=$IMGPATH of=$RDPATH$RDGZNAME skip=464896

echo "Extracting loader and kernel"
dd bs=1 if=$IMGPATH of=$LDRKRNLPATH$LDRKRNLNAME count=464896

echo "Unpacking RAMDISK..."
cd $RDPATH
gzip -d $RDGZNAME
cd ..

echo "Mount RAMDISK"
mount -o loop $RDPATH$RDNAME $RDMP

Удаление AVP

#!/bin/bash

RDMP="/mnt/ramzes"

echo "Remove AVP"

cd $RDMP

cd root/.AVP
rm *
cd ..
rmdir .AVP
rm $RDMP"/usr/bin/AVPLinux"

cd $RDMP
cd opt
cd AVP
rm *
cd ..
rmdir AVP

cd $RDMP

Сборка модифицированного bootdisk.img

#!/bin/bash

IMGPATH="./mbootdisk.img"
RDPATH="./ramdisk/"
LDRKRNL="./ldrkrnl/ldrkrnl.img"
RDNAME="ramdisk"
RDMP="/mnt/ramzes"

echo "Umount RAMDISK"
umount $RDMP

echo "Packing RAMDISK"
cd $RDPATH
gzip -9 $RDNAME
cd ..

echo "Make bootdisk"
cat $LDRKRNL $RDPATH$RDNAME".gz" >$IMGPATH
echo "Complete!"

Ссылки и файлы

Разборка оригинального диска на PasteBin
Удаление AVP из образа на PasteBin
Сборка модифицированного образа на PasteBin
Архив со скриптами
Часть I
Часть II
Все статьи (PDF, ZIP)

Препарирование AVP Z.E.S Linux Глава 2

Надо ж выдумать такое, во дурак!

Я, почему-то, не принял во внимание ясные надписи серым по черному, и попытался распаковать полученный ramdisk, думая, будто бы это стандартный initrd. А почему? Да потому что внимательнее мануалы читать надо, и гуглить лучше, если сам чего-то не знаешь.

Ramdisk, Ramdisk, only Ramdisk.

Оказывается, при создании дискеты была применена более старая технология создания диска в оперативной памяти
Полученный на прошлом этапе ramdisk.gz оказался действительно виртуальным диском в оперативной памяти, сжатым gzip’ом
Правда, при распаковке в Линуксе, gzip выдал предупреждение:
Пытаемся распаковать ранее вырезанный ramdisk.gz:

gzip -d ramdisk.gz
gzip: ramdisk.gz: decompression OK, trailing garbage ignored

Так, какой-то «мусор» после конца архива был игнорирован при распаковке. Как позже выяснится, фактически он ни на что не влияет, и на предупреждение gzip’а можно забить.

В конце образа дописано некоторое количество байт F6 (Ў) и нечто похожее на контрольную сумму и цифровую подпись.

Хотя, для чистоты эксперимента, ничто не мешает получить «чистый» архив, размером 876114 байт:
dd bs=1 count=876114 if=ramdisk.gz of=ramdiskcln.gz
И «мусорный» хвост (остаток размером 133614 байт).
dd bs=1 skip=876114 if=ramdisk.gz of=endimg

Пробую распаковать ramdiskcln.gz — никаких предупреждений, распаковка успешна:

Доступ к ramdisk’у и его модификация

Сначала создается точка монтирования:
mkdir /mnt/ramzes

Теперь монтирование распакованного образа:
mount -o loop ramdiskcln /mnt/ramzes


Доступ у ФС ramdisk’а получен

Все успешно примонтировалось, видно структуру каталогов оригинального ramdisk’а AVP Z.E.S Linux. Места, правда, маловато. Всего 3 с хвостиком Мб, а осталось свободными вообще 806 К. Но все равно, кое-что можно сделать, например, для первого раза:
— выкинуть сам AVP (директория AVP в opt, скрипт avp.run из sbin, ссылку usr/bin/AVPLinux и директорию .AVP из root)
— подправить скрипт etc/rc.d/rc.sysinit, чтоб выкинуть команды вызова AVP

Сборка модифицированного образа AVP Z.E.S Linux

1. Отмонтируем ramdisk:
umount /mnt/ramzes

2. Запакуем образ ramdisk’а:
gzip -9 ramdiskcln

3. Соберем образ диска обратно. От предыдущих экспериментов должен остаться файл ldrkrnl.img, содержащий начальный загрузчик и ядро Z.E.S. Его нужно скопировать в директорию с измененным и запакованным ramdisk’ом, и просто слить в новый образ с помощью cat:
ldrkrnl.img ramdiskcln.gz >mbootdisk.img

Но мы прошли туман!

И все-таки попытку модификации исходного образа удалось завершить, хотя бы для демонстрации того, что «а так можно было?»
Например, в образ добавлен минималистичный текстовый редактор qed, написанный на Free Pascal:

Или даже мощный консольный редактор, переделанный из примера, поставляющегося с Free Pascal:

Фейлы

Размер ramdisk’а сильно ограничен, поэтому некоторый софт, даже статически скомпилированный, туда не влез. Либо нарушалась идея «чтоб влезло на одну дискету».
-Постоянные проблемы с shared-библиотеками даже у того, что влезло. Так понимаю, что какие-то библиотеки устарели настолько, что новое не запускается, а старое, если заменить библиотеки — не работает. Или я что-то неправильно делал.

Итог

Поигрались и хватит, все равно для практического применения этот дистрибьютив не совсем подходит. Но есть и плюсы — классно поковырялся, в процессе узнал новое, в общем, удовольствие получено. Осталось даже несколько идей на будущее, например, очень понравился Free Pascal и некоторые возможности Linux, реализуемые им без геморроя, которым страдает программер на C/C++.

Источники и файлы

Начало
Использование ramdisk в Linux (ramdisk, ramfs, tmpfs)
или препарирование рамдисков

How to Create/Modify an RAM disk Image (на английском), PDF, скачать
Оригинальный образ bootdisk.img

AVP Z.E.S Linux, или исследование образа одной древней дискеты.

Чисто от нефиг делать…

Истерический экскурс

В состав древних версий Касперского антивируса входила утилита, для создания спасательной дискеты, включающая образ диска bootdisk.img и собственно утилиту, копировавшую этот образ на дискету №1, а на все остальные 2-3 штуки — антивирусные базы.
Дискеты с базами были самые обычные, они нас не интересуют, а вот на первой дискете был малюсенький Linux со встроенным антивирем. Linux автоматически монтировал локальные диски, причем поддерживал FAT, FAT32, NTFS, HPFS, EXT2, т.е. все самые популярные на 1999-2001 г. файловые системы.
После загрузки Касперского надо было вставить дискеты с базами, дождаться загрузки баз и далее шла проверка. Если же дискеты с базами не вставить, то выбрасывало в линуксовую консоль, в последней версии без всяких вопросов, а в более ранней надо было ввести имя пользователя root и аналогичный пароль. Далее, зная команды, можно было бродить по дискам, читать файлы с помощью cat, копировать их, и т.д.
Касперский линукс был неприхотлив, для работы ему хватало то ли 4, то ли 8 Мб оперативки, и нам с товарищем удавалось запустить его даже на 486 машине, а вот на 386 не получилось, памяти не хватило.
Сама же дискета не открывалась ни в 98 винде, ни в NT и 2000, ни в Линуксе. Линукс мы знали совсем мало-мало, винды ругались на то, что диск не форматирован, мануалов особо не было, интернета и подавно. В общем решили мы, что хитрый Касперский дискету зашифровал, чтоб чуть что ее вирусы не заразили ненароком, и решили, что тягаться с самим Валентинычем нам не под силу, да и забили на это дело.

Иногда они возвращаются.

Недавно товарищ вновь объявился на горизонте и принес тот самый bootdisk.img из дистрибутива AVP 5, правда, огорчил, что доступные ему виртуалки образом подавились. Microsoft Virtual PC свалилась вместе с виндовозом в синий экран, а Virtualbox и вовсе отказался принимать это за образ дискеты.
Я высказал предположение, что дискета в формате RAW и на ней просто последовательно без всякой файловой системы записаны загрузчик, ядро Линукса и что-нибудь типа initrd, откуда и запускается все остальное, скинул образ на флэшку, и опять забыл.

Дело было вечером, делать было нечего…

Точнее мне не хотелось слушать разговоры слесарей о машинах и футболе, мне они так же непонятны, как слесарям разговоры о Линуксе, и мне же о бабах, потому что про глючные девайсы я и в интернете могу почитать. Бухать тоже не перло, но на автобазе было тепло, а снаружи дул холодный ветер и сыпал мерзкий снег. К тому же обнаружился ЁЁЁ-писюк с модемом, а в кармане валялась та самая флешка с образом и Хрювером, он же HIEW. А пуркуа бы не па…

Обратный отсчет. Поехали!

Скачиваю QEMU, ставлю и скармливаю ей образ дискетки:

qemu-system-i386.exe -fda bootdisk.img -boot a

Надо же, загрузились, какие мы молодцы!

Тааак… Если загрузились, должен быть и загрузчик. Вот, кстати он работает:

Вспоминаем устройство загрузочных дисков. Сначала BIOS загружает первые 512 байт, которым передает управление. Можно попробовать эти 512 байт отрезать и посмотреть, что получится.
Устанавливаю dd
И делаю вот так:
dd bs=1 count=512 if=bootdisk.img of=512.img
bs=1
— размер блока 1 байт
count=512 — количество блоков
if=bootdisk.img — откуда читать
of=512.img — куда писать

Пробую скормить выходной файл QEMU:

И все, на этом висим. На самом деле, висим вполне закономерно — в первых 512 байтах только главная загрузочная запись и основной загрузчик, который хоть черта лысого может подгрузить по своему усмотрению.

Пространственное сжатие

Ладно, с налета, с шашкой наголо закономерно ничего не вышло, будем наблюдать дальше. Загрузимся опять с оригинального образа.
Момент раз:

Момент два, чуть погодя:

Ага! Uncompressing Linux! Compressed image found at block 454!

Похоже, моя гипотеза подтверждается: загрузчик, за ним сжатое ядро, в которое встроены необходимые модули, а за ним сжатый образ со всем остальным.
За следующую гипотезу приму то, что Касперский не изобретал крутых велосипедов, а ограничился стандартным gzip-сжатием.
Недолгое гугление дало, что gzip-архив начинается с сигнатуры 1F 8B 08 00, хорошо, что на флешке завалялся HIEW.
Загружаем в него оригинальный образ, переключаемся в HEX-режим (F4) и пробуем поискать сигнатуру архива.

Вот первое совпадение по смещению 4344h т.е. на 17221 байте от начала файла (HIEW ведет счет с 0).

А вот и второе по смещению 71800h, т.е. на 464897 байте от начала файла.
Больше сигнатур обнаружено не было. Пока с моими гипотезами все в порядке.

Мы режем, режем, режем…

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

Сначала оставлю один загрузчик, чтобы посмотреть, как он поведет себя без всего остального.
Копирую bootdisk.img под именем loader.img, открываю loader.img в HIEW. Далее надо переключиться в HEX-режим и провести поиск первого вхождения сигнатуры 1F 8B 08 00.
Теперь переключаемся в режим редактирования (F3) и обрезаем файл с этой позиции включительно (Trunc, F10)
Выходим из HIEW, получился файл размером ровно 17220 байт. Скармливаю его QEMU.

Точно загрузчик. Не обнаружил сигнатуры запакованного gzip’ом ядра, отругался и оставил нас.

Попробую теперь повторить операцию, оставив в файле загрузчик и предполагаемое ядро. Копирую оригинальный файл под именем ldrkrnl.img и делаю все то же самое, что и в первом случае, только ищу второе вхождение. В итоге получился файл размером 464896 байт. Пробую запустить.

Ага! Ядро! Вроде бы загрузка поначалу шла нормально, но потом RAMDISK не нашел образа диска на своем месте и драйвер VFS потребовал с нас дискету с корневой файловой системой. Естественно, т.к. у дискеты нестандартный формат, то смонтировать ее не удалось и получилась kernel panic. Хотя, забегая вперед, это дает возможность отвязаться от ограничений RAMDISK и модифицировать систему как угодно. Фактически это, конечно, не нужно, проще уж что-то свое собрать, чем идти таким странным способом.
Но ради развлечения я все-таки систему модифицирую, не зря же ковырялся.

Встаньте под образа!

Раз уж речь зашла о модификации, то нАчать надо с того, чтобы извлечь образ ramdisk’а.
Это последнее, что я сделал в теплом гараже и на винде. Для остального уже Линукс надобен.
Итак, имеем ldrkrnl.img размером 464 896 байт, и оригинальный bootdisk.img. Чтобы вырезать рамдиск, можно воспользоваться dd:
dd bs=1 if=bootdisk.img of=ramdisk.gz skip=464896
skip=464896
— количество блоков размером в 1 байт (bs=1), которые нужно пропустить с начала файла bootdisk.img

На выходе получился файл ramdisk.gz размером мегабайт с хвостиком, имеющий в начале вышеупомянутую сигнатуру gzip-архива. Файл успешно открылся в WinRar, и тест показал, что ошибок не обнаружено.

Начинался новый день…

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

Продолжение следует…

О gzip-архиве и сигнатуре ея
QEMU для Windows XP
dd для Windows

QEMU для Windows XP

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

1. Качаем последнюю версию, поддерживающую XP 2016-09-03 (2.7.0) или отсюда
2. Ставим стандартным для Windows образом
3. Поскольку QEMU, как и в линуксе, управляется с командной строки, а расположена установленная программа в Program Files, да и имена у виртуалок длинные и неудобные, типа qemu-system-i386.exe, то пишем батник, передающий программе параметры, примерно такой, как здесь

содержимое qemu386.bat:
@Echo Off
Setlocal EnableDelayedExpansion
Set P="C:\Program Files\qemu\qemu-system-i386.exe"
For %%A In (%*) Do SET P=!P! %%~A

start "QEMU"/B %P%

Команда start — чтоб после запуска из консоли, например из-под FAR’а, консоль не висела, ожидая завершения работы QEMU
Параметр "QEMU" — заголовок окна, создаваемого командой start. Без него start подумает, что заголовок окна это путь к исполняемому файлу и попытается безуспешно выполнить первый передаваемый QEMU параметр.
/B — указывает команде start не создавать это самое новое окно, если его не указать, то за окном QEMU будет висеть черное пустое окно новой консоли.
В переменной %P% будет путь к QEMU и передаваемые параметры, например:
qemu-system-i386.exe -fda bootdisk.img -boot a загрузка с образа дискеты bootdisk.img

4. Кладем батник в какой-нибудь каталог, имеющийся в PATH, например, в C:\Windows

Пример как раз таки загрузки с такого образа

Про эту дискету расскажу как-нибудь позже, она с хитринкой, а мне было нечем заняться в компании дальнобоев, автослесарей и ноута с XP и мамедным интернетом, кроме как ее (недо)-реверсингом %).

Батник на PasteBin или скачать