Использованные программы: Hellfire v2.0, W32Dasm
v8.9, Dos Navigator v1.5
В статье рассматриваются следующие вопросы:
- Заменяем в программе HellFire v2.0 проверку с диска CD-ROM на сетевой диск
- Пишем Fake-CD для OS Windows 95
Заменяем в программе HellFire v2.0 проверку с диска CD-ROM на
сетевой диск
Суть проблемы состоит в том, чтобы доказать программе, что винчестер на самом
деле совсем не винчестер, а CD-ROM. Или скажем - как в данном случае - в выдаче
за локальный CD сетевого, ну один CD на работе, а играть-то всем
охота!
Приступим. Цель - Функция GetDriveType(). Она возвращает тип
диска, имя которого ей передали. Вот ее прототип:
- UINT GetDriveType(LPCTSTR lpRootPathName);
Функция
возвращает следующие значения:
Числовое значение |
Идентификатор |
Описание диска |
0 |
- |
Невозможно определить тип |
1 |
- |
Диск не найден |
2 |
DRIVE_REMOVABLE |
Гибкий (возможна замена) |
3 |
DRIVE_FIXED |
Жесткий (замена невозможна) |
4 |
DRIVE_REMOTE |
Сетевой диск |
5 |
DRIVE_CDROM |
CD-ROM |
6 |
DRIVE_RAMDISK |
RAM - Диск |
Стандартно программа получает список всех дисков, проверяет их на
"CDромность" и по нахождению проверяет наличие нужных файлов. Для
проверки, необходимо, очевидно, сравнить возвращаемое значение с 5. Найдем этот
момент программы, вот как он выглядит после дизассемблирования HellFire с
помощью W32Dasm :
-
- Reference To: KERNEL32.GetDriveTypeA, Ord:00DFh
|
| |
:0041D976 FF151CA56F00 |
Call dword ptr [006FA51C] |
:0041D97C 83F805 |
cmp eax, 00000005 |
:0041D97F 752A |
jne
0041D9AB |
В принципе можно
использовать любой другой дизассемблер, или SoftICE, в последнем случае для
нахождения нужного куска необходимо написать:
-
- bpx GetDriveType
bpx GetDriveTypeA
В самом же W32Dasm
можно воспользоваться списком использованных функций. Ищем
KERNEL32.GetDriveTypeA и два раза щелкаем по функции мышью. В IDA такой
список есть в конце отдизассемблированного файла. Листинг полученный Sourcer'ом
придется исследовать обычным текстовым поиcком.
Запишем HEX-DUMP этого куска и найдем его в шеснадцатеричном редакторе.
Например в DN: откроем файл hellfire.exe по F3, далее F4 (переход в HEX режим),
F7 (поиск), в строке ввода HEX строки введем записанное ранне и вперед (т.е.
ENTER).
Вместо 83F805 введем 83F804 и любой из подключенных сетевых дисков теперь
будет восприпринят прораммой за CD, иначе введем 83F803 - тогда жесткие диски
будут приниматься за CD. Фантазия может развиваться по-любому, можно изменить
условие перехода после сравнения, тогда не придется заботится о типе диска.
Вот и все на сегодня, в следующий раз можно будет поговорить о минимизации
количества данных, копируемых с диска. Эта проблема отнюдь не тривиальна, так
как файлы обычно храняться в виде типа PAK как, например в QUAKE. Для простых же
программ можно посоветовать обнулить все WAV, AVI файлы. Для этого есть
специальные утилиты, но, конечно, проще создать файл нулевой длинны с таким же
именем, например по Shift-F4 в любом дисковом коммандере (DN,NC,etc.).
Пишем Fake-CD для OS Windows 95
Для DOS существовала прекрасная утилита - FakeCD, которая подменяла MSСDEX и
эмулировала таким образом CD-диск который, на самом деле, был каталогом на
винчестере. Для Win95 такую программу найти не просто, поэтому необходимо ее
сделать самим. Этим мы и займемся, тем более, что это будет прекрасная практика
по копанию в недрах 95'ого.
Посмотрим на проблему, обсуждавшуюся раннее, с другой стороны. Заменим не
использование функции, а саму функцию. Если в DOS для замены функций необходимо
только было изменить обработчик прерываний, то в Windows такой финт уже не
поможет. Выясним, где "живет" GetDriveType(). И - о ужас - это
главная библиотека Win95 KERNEL32.DLL. Что делать? Как всегда, запастись кофе и
напуcтить на KERNEL32.DLL дизассемблер. OK, ждем окончания процесса и смотрим
список экспортируемых функций. Вот нужная нам:
-
- Exported fn(): GetDriveTypeA - Ord:013Fh
:BFF777C4 57
push edi
:BFF777C5 6A21 push 00000021
...
...
...
:BFF777E1 F2
repnz
:BFF777E2 AE scasb
* Referenced by a (U)nconditional or
(C)onditional Jump at Address:
|:BFF777DA(C)
|
:BFF777E3 648F02 pop
dword ptr fs:[edx]
:BFF777E6 83C408 add esp, 00000008
:BFF777E9 5F pop
edi
:BFF777EA E9E5D4FFFF jmp BFF74CD4
Делаем переход в
конце(кнопка Jump to на панели W32Dasm) и видим продолжение. Функция,
оказывается-то, длинная! Не будем в ней разбираться, а лучше вспомним как
происходит возврат значения из функции. Т.о. ищем строку типа
-
- mov eax,03000000
Нашли? Далее, как и при
любом взломе, запомним последовательность HEX кодов нужной команды (а лучше
нескольких следующих, так как загрузка в аккумулятор числа 3 не самая редкая
операция) и найдем этот блок в копии библиотеки (в копии - потому что файл
используется системой и не может быть изменен). Все, осталось лишь в режиме DOS
подменить KERNEL32.DLL. Перезагрузимся и в Проводнике насладимся результатом -
все ваши жесткие диски представленны в виде кругленьких пластинок ранее
обозначавших CD.
А теперь - для ленивых - кусок кода, который возвращает 3:
-
- * Possible Reference to String Resource ID=00003:
"....."
| :BFF74E0F B803000000 mov eax, 00000003 //Возвращаемое
значение
:BFF74E14 EB05 jmp BFF74E1B //Переход на возврат
* Referenced
by a (U)nconditional or (C)onditional Jump at Addresses:
|:BFF74DEB(C),
:BFF74DFC(C), :BFF74E0D(C)
|
* Possible Reference to String Resource
ID=00006: "..."
Да - лучше сохранить старый KERNEL32, так как некоторые программы могут не
оценить ваш юмор, и решить, что несколько CD и ни одного винчестера - это
слишком. А вообще идеально было бы изменить функцию коренным образом. Скажем
сделать CD дисками все, начиная с T. Тогда можно было бы подключать subst'ом
каталоги, которые были бы CD, а винчестеры остануться винчестерами. Но это уже
задание на дом. Удачи!