본문 바로가기

세상사는 이야기/이야기들

첫번째 바이러스 백신... VACCINE... (c)Brain Virus 백신...

;
;
;        VACCINE.ASM    vaccine program  for (c) Brain
;
;                       by    Ahn Cheolsoo
;
;                       computer : IBM - PC/XT/AT
;                       language : Microsoft Macro Assembler 5.0
;                       creation : 1988. 6. 10.
;

 drive   equ   0                    ; drive A
 read    equ   2                    ; function number of INT 13h
 write   equ   3                    ; function number of INT 13h
 boot    equ   1                    ; boot sector
 FAT     equ   2                    ; start of FAT
 dir1    equ   6                    ; start of root directory
 dir2    equ   1                    ; sector of side 1 dir

Print    MACRO  string              ; string print function
         mov  dx, offset string
         mov  ah, 9
         int  21h
         ENDM

Cr_Lf    MACRO                      ; carrage return & line feed
         mov  ah, 2
         mov  dl, 0dh
         int  21h
         mov  dl, 0ah
         int  21h
         int  21h
         ENDM

Input    MACRO                      ; character input => AL
         mov  ah, 0ch
         mov  al, 1
         int  21h
         ENDM

Diskio   MACRO  func, side, track, sector, num_sec, address
                                    ; BIOS INT 13h (disk I/O)
         mov  ah, func              ; read or write
         mov  al, num_sec           ; number of sectors
         mov  bx, offset address    ; offset address of buffer
         mov  ch, track             ; track
         mov  cl, sector            ; sector
         mov  dh, side              ; side
         mov  dl, drive             ; drive No (0 = A:,1 = B:)
         int  13h
         ENDM

Data     SEGMENT  AT  0h

         ORG  004ch                 ; original INT 13h vector
 old_off dw   ?                     ;    offset  address
 old_seg dw   ?                     ;    segment address

         ORG  01b4h                 ; interrupt vector of INT 6Dh
 new_off dw   ?
 new_seg dw   ?

         ORG  0413h                 ; BIOS data area
 mem_size dw  ?                     ; (system memory size in KB)

Data     ENDS


Code     SEGMENT

         ASSUME  cs:Code, ds:Code
         ORG  0100h

entry:   jmp  start

 header  db   'VACCINE program  for (c) Brain     '
         db   'by   Ahn Cheolsoo', 0dh, 0ah, 0ah, '$'
 mess1   db   '  System is infected with (c) Brain ---> cured'
         db    0dh, 0ah, '$'
 mess2   db   '  Insert a disk in drive A: and press <Enter>$'
 mess3   db   '  This disk is not infected.',0dh,0ah,0ah,'$'
 mess4   db   '  This disk is infected with (c) Brain',0dh,0ah
         db   '  Processing the infected disk ...'
         db    0dh, 0ah, 0ah, '$'
 mess5   db   '    Test another disk (Y/N) ? $'
 r_error db   '    ***  Disk read error  ***',0dh,0ah,0ah,'$'
 w_error db   '    ***  Disk write error  ***',0dh,0ah,0ah,'$'

 m_save  dw   ?                     ; system memory size save
 vlabel  db   ' (c) Brain '         ; virus volume label
 vside   db   ?                     ; physical sector of virus
 vsector db   ?
 vtrack  db   ?
 buffer1 db   4 * 512 dup(0)        ; disk I/O buffer area
 buffer2 db   3 * 512 dup(0)

start    PROC  NEAR

         mov  ax, cs                ; register setting
         mov  ds, ax
         mov  es, ax
         Print  header              ; print greeting message


         ;  SYSTEM MEMORY CHECK ( VERIFY MEMORY )

         push ds
         mov  ax, data              ; ds = 0000
         mov  ds, ax
         mov  ax, mem_size          ; system memory size in AX

         mov  m_save, ax            ; save AX
         mov  cl, 06                ; segment address
         shl  ax, cl                ;       = (size in KB) X 64
         mov  ds, ax
         mov  ax, ds:[0004]         ; Virus exist in memory ?
         cmp  ax, 1234h
         jnz  system_ok

 system_infected:

         pop  ds
         Print  mess1
         push ds
         xor  ax, ax                ; ds = 0000
         mov  ds, ax
         mov  ax, new_off           ; recover changed interrupt
         mov  old_off, ax           ;                    vector
         mov  ax, new_seg
         mov  old_seg, ax

         mov  ax, m_save            ; current memory size + 7 KB
         add  ax, 07
         mov  mem_size, ax          ; write the changed size

 system_ok:                         ; System is not infected.
         pop  ds


         ;  INVESTIGATION OF DISK

 restart:
         Print  mess2

 get_key:
         Input
         cmp  al, 0dh
         jnz  get_key
         Cr_Lf

         mov  cx, 4
 retry:  push cx
         Diskio  read, 0, 0, boot, 1, buffer1
                                    ; boot sector read
         jnb  read_ok               ; if error,
         mov  ah, 0                 ;  Reset Floppy Disk System
         int  13h
         pop  cx
         loop retry                 ; try 4 times
         Print  r_error
         jmp  restart

 read_ok:
         mov  ax, word ptr [buffer1 + 4]
         cmp  ax, 1234h             ; virus ID code
         jz   re_exam

 not_virus:
         Print  mess3
         jmp  end_of_job

 re_exam:
         mov  ax, word ptr [buffer1 + 10h]
         cmp  ax, 6557h             ; message area examination
         jnz  not_virus

 disk_infected:
         Print  mess4
         mov  al, buffer1[6]        ; location of original
         mov  vside, al             ;          boot sector
         mov  al, buffer1[7]
         mov  vsector, al
         mov  al, buffer1[8]
         mov  vtrack, al


         ;  REPAIR THE BOOT SECTOR

         Diskio  read, vside, vtrack, vsector, 1, buffer1
                                    ; read original boot sector
         jnc  boot_sector_repair    ; if no error, repair boot
         Print  r_error             ;                     sector
         jmp  restart

 boot_sector_repair:
         Diskio  write, 0, 0, boot, 1, buffer1
                                    ; write original boot sector
         jnc  FAT_read              ; if no error, read FAT
         Print  w_error
         jmp  restart


         ; REPAIR THE FAT (File Allocation Table)

 FAT_read:
         Diskio  read, 0, 0, FAT, 4, buffer1
                                    ; FAT read
         jnc  cluster_calc          ; if no error, calculate
         Print  r_error             ;         cluster number
         jmp  restart

 cluster_calc:
         ; convert physical sector to logical sector
         xor  ah, ah
         mov  al, vtrack            ; logical sector =
         shl  ax, 1                 ;  (track X 2 + side) X 9
         xor  dh, dh                ;             + sector -1
         mov  dl, vside
         add  ax, dx
         mov  cl, 9
         mul  cl
         xor  dh, dh
         mov  dl, vsector
         add  ax, dx
         sub  ax, 1

         ; convert logical sector to cluster number
         shr  ax, 1                 ; cluster =
         sub  ax, 4                 ;  (logical sector/2) - 4

         mov  si, offset buffer1
         mov  dl, 3

 FAT_repair:
         push ax
         push dx
         mov  cx, ax
         shl  ax, 1                 ; cluster No X 2
         add  ax, cx                ; cluster No X 3
         test ax, 1                 ; Is it a whole number ?
         pushf                      ; save flag
         shr  ax, 1                 ; cluster No X 1.5
         mov  bx, ax
         mov  ax, [bx + si]         ; location of cluster in FAT
         popf
         jnz  not_whole_no          ; if not whole number, jump

 whole_no:
         and  ax, 0f000h            ; make cluster staus 0
         jmp  repair

 not_whole_no:
         and  ax, 000fh             ; make cluster status 0

 repair:
         mov  [bx + si], ax         ; repair FAT
         mov  [bx + si + 400h], ax  ; repair the copy of FAT
         pop  dx
         pop  ax
         inc  ax                    ; next cluster
         dec  dl
         jnz  FAT_repair

         Diskio  write, 0, 0, FAT, 4, buffer1
                                    ; write the repaired FAT
         jnc  dir_read              ; if no error, repair label
         Print  w_error
         jmp  restart


         ;  REPAIR THE LABEL

 dir_read:
         Diskio  read, 0, 0, dir1, 4, buffer1
                                    ; read the first 4 directory
         jnc  read_dir1             ;                     sector
         Print  r_error
         jmp  restart

 read_dir1:
         Diskio  read, 1, 0, dir2, 3, buffer2
                                    ; read the 2nd 3 directory
         jnc  read_dir2             ;                   sector
         Print  r_error
         jmp  restart

 read_dir2:
         mov  cl, 6ch               ; number of directory entry
         mov  si, 40h               ; third directory entry

 next_entry:
         mov  al, buffer1 [si + 0bh] ; File attribute = 8 ?
         and  al, 8
         cmp  al, 8
         jz   vl_present            ; if label present, jump
         add  si, 20h               ; next directory entry
         dec  cl
         jnz  next_entry
         jmp  end_of_job

 vl_present:
         push si
         mov  cx, 11                ; string length
         add  si, offset buffer1
         mov  di, offset vlabel
         cld
         repe cmpsb                 ; compare volume label with
                                    ;                 (c) Brain
         jcxz match                 ; if match, jump
         pop  si
         jmp  end_of_job

 match:
         pop  si
         mov  buffer1[si], 0e5h     ; delete virus label

         Diskio  write, 0, 0, dir1, 4, buffer1
                                    ; write first 4 dir sector
         jnc  end_of_job
         Print  w_error
         jmp  restart

         Diskio  write, 1, 0, dir2, 3, buffer2
                                    ; write second 3 dir sector
         jnc  end_of_job
         Print  w_error
         jmp  restart


         ;  END OF JOB

 end_of_job:
         Print  mess5               ; examine another disk ?
         Input
         push ax
         Cr_Lf
         pop  ax
         cmp  al, 'Y'
         je   re
         cmp  al, 'y'
         je   re
         jmp  exit

 re:     jmp  restart

 exit:   int  20h                   ; program temination

start    ENDP

Code     ENDS

         END  entry

----------------

안철수 교수께서 만드신 첫번째 백신...
11KB 용량이고... 자세한 소스 설명까지...
기억이 맞다면... '마이크로소프트웨어'잡지에... 소스 자체를 기고하셨었다는... ~.~