汪道之

有人的地方就有江湖

0%

病毒_DOS_引导与中断

面向文件系统的病毒——引导型病毒

大致思路

将病毒放在软盘的引导扇区,并将原来的引导代码放到数据区,在执行完病毒代码后拷贝回原来的引导代码,并将执行权交给引导代码

问题

  1. 自我覆盖的问题,所以需要我们将病毒中执行拷贝指令的代码移出被覆盖区域
  2. 如何使别的数据不使用簇2的问题,这里我们可以修改FAT1和FAT2表,将簇2改为不可用,如果改为已占用的FFF,由于没有对应目录项会很可疑,所以改为坏簇FF7

磁盘访问int 13h中断

复位磁盘系统

1
2
Xor ah, ah		;ah=0为磁盘复位
int 13h ;13h为磁盘中断

读指定从磁头,道,扇区起始,n个扇区道内存缓冲

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
AH = 02h是读扇区功能号
AL = 将读入多少个扇区
CL = 起始扇区号
CH = 磁道
DH = 磁头
DL = 磁盘,0代表a盘
ES:BX = 读缓冲的地址,一般只填写BX

Mov ah, 02
Mov al, 5 ;读5个扇区
Mov cl, 1 ;从1扇区开始
Mov ch, 0 ;读0道
Mov dh,0 ;读0头
Mov dl, 0 ;读a盘
Mov bx,7c00h ;读到7c00h处
int 13h

设计一个基于0开始的绝对扇区读函数

功能:将绝对扇区号转化为磁头,道,扇区的CHS寻址方式

如何转化?

image-20210512090322696

具体实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ReadSector:		;该函数的绝对扇区号是从0开始的
;函数参数:ax开始绝对扇区号, cl读扇区数, bx读缓冲地址
mov bp, sp
sub sp, 2
push bx ;保持读缓冲地址
mov byte [bp - 2], cl ;保持读扇区数
mov bl, 18 ;除数18
div bl ;被除数ax是绝对扇区号,除以18,余数在ah中,商在al中
inc ah ;余数加1为道内扇区号
mov cl, ah ;int 13h中断参数设置cl=道内扇区号
mov dh, al ;dh = N
and dh, 1 ;N&1为磁头,int 13h中断参数设置dh=磁头号
shr al, 1 ;N 右移1位,al = 磁道号
mov ch, al ;ch=磁道号,int 13h中断参数设置ch=道号
mov dl, 0 ;int 13参数设置,dl=0,读软盘
pop bx ;获得读缓冲地址,设置int 13h参数,bx=读缓冲地址
mov ah, 02h ;int 13h参数设置,读扇区功能号
mov al, [bp - 2] ;获得读扇区数,int 13h参数设置,al=读取扇区数
int 13h
add sp, 2
ret

执行部分程序设计

image-20210512090455764

例题

  1. 关于软盘引导型病毒,下列说法不正确的是( )
    A. 病毒感染时会将原引导扇区内容拷贝到软盘的数据区
    B. 病毒执行时会将原引导扇区内容从软盘的数据区拷贝到内存7C00处
    C. 病毒将原引导扇区的内容拷贝到7C00时需要处理自我覆盖的问题
    D. 病毒感染时必须覆盖原引导扇区的全部内容才能获得执行

参考答案:D

  1. 已知软盘上一个扇区的绝对扇区数是X,软盘1道有18个扇区,请问如何获得该扇区的CHS参数?

参考答案:image-20210512091137459

病毒的执行机制——中断替换

框架

  1. 认识中断向量表
  2. 非驻留式的中断向量修改
  3. 驻留式的中断向量修改

中断向量表

触发中断后,就会去调用中断处理程序

而找到中断处理程序的入口地址就是通过中断向量表

中断向量表在内存00:00处,每4个字节为一个项,这个项的索引就是中断向量号,其中高2个字节为段地址,低2个字节为段内偏移

中断触发指令int xxh,xx就是中断向量号,4*xx就是中断xx的入口地址在中断向量表中的存放位置

非驻留式中断向量修改

驻留程序:一直在内存中不退出的程序,例如中断处理程序

我们目的是修改中断处理程序下的入口地址(即修改中断向量表)使其执行病毒程序,但是病毒程序也需要驻留在内存才不会使中断向量表无效

在非驻留式中断替换中我们在病毒程序调用后恢复中断向量表

大致思路

image-20210512092456791

重点

病毒和中断向量表不在同一个段,因此段寄存器需要根据实际访问情况变化

跨段跳转的问题:

病毒需要由自己段跳到原中断向量程序所在的段
要跨段跳转,就要采用JMP XX:YY的形式
但是JMP CX:AX的语法是不支持的
即JMP XX:YY的指令不支持两个间接性,XXYY总有一个是立即数,而程序里面Seg和Offset都不是立即数,怎么解决?
我们可以先采用两个立即数来确定JMP指令的形式(比如JMP 00:00),然后我们再来定位到JMP指令的机器码,进行按字节的细粒度修改!

程序设计

image-20210512093103505

驻留式中断向量更改

DOS系统自己就提供了中断调用修改中断向量表,因此这里把hook变成内存驻留

获取中断入口地址的调用

1
2
3
mov al,16h	;al 中断向量号,16h为键盘IO中断号
mov ah,35h ;功能号,取中断向量地址
int 21h ;es:bx为中断程序入口地址

设定中断向量的调用

1
2
3
4
mov dx, offset		;ds:dx指出了新的中断入口地址
mov al,16h ;这个指出了要设定的中断号
mov ah,25h ;功能号,设置中断向量
int 21h

病毒代码程序设计

1
2
3
4
5
6
7
8
9
10
org	0100h
jmp initialize
Hook 驻留代码
----------------
initialize:
;改变原中断的中断向量表项指向Hook
;修改Hook最后一条JMP语句的机器码指向原中断向量程序地址

mov dx, initialize ;dx以前内容内存驻留
int 27h ;返回DOS,结束进程,但不释放驻留内存

例题

  1. 关于DOS中断和中断型病毒,下列说法不正确的是( )
    A. DOS中断程序的入口地址存放在中断向量表中
    B. 病毒在修改中断向量表时需要考虑不同段地址的问题
    C. 10h中断程序的入口段地址存放在 4*10h+2的地方
    D. 中断型病毒是通过替换原中断处理程序获得执行机会

参考答案:D

解析:并不是替换了原中断处理程序,而是修改了中断向量表使其先执行的病毒程序再执行中断处理程序