BetaMao

Rootkit基础

字数统计: 1.1k阅读时长: 4 min
2017/03/06 Share

今天换一个口味,继续学习底层知识,记录《rootkit系统灰色地带的潜伏者》笔记,“硬件概述篇”~

实模式

下图是IA-32处理器模式图:

兼容8086第一种模式,使用16位段选择器和16位偏移组成20位地址,在内存的低端1M处工作,和16位汇编内容一样。电脑开机即进入这种模式,即BIOS与引导代码都运行于此,接着才是操作系统。常规内存大多被操作系统级数据占用,上端内存用于扩展。

拥有的寄存器和8086差不多,只是多了两个寄存器:FS&GS,用来存储其他全局数据段基地址(ES为字符串数据段基地址,看长相就知道他们差不多吧)
对于标志寄存器,和学习汇编语言编程关注点不一样,这里看TF(陷阱)位和IF(中断允许)位。
在实模式中,中断服务例程ISR由中断向量表IVT指向,IVT即低端的1024字节,每四字节指向一个ISR,共支持容纳256个ISR,如下:

BIOS处理031号中断,DOS处理3263号,其余用户定义:


中断的分类:

跳转,INT和IRET是远转移,JMP, CALL却不一定,可能是短跳转(1字节偏移),近跳转(2字节偏移),远跳转等。。。
对中断的操作案例只能敲代码,还不知道在哪里运行呢:
操作IVT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<stdio.h>
#include<Windows.h>
#define IDT_001_ADDR 0
#define IDT_255_ADDR 255
#define IDT_VECTOR_SZ 4
int main() {
WORD csaddr, ipaddr;
for (WORD no,address = IDT_001_ADDR; address <= IDT_255_ADDR; address += IDT_VECTOR_SZ, no++) {
printf("%03d %08p ", no, address);
__asm {
PUSH ES
MOV AX, 0
MOV ES, AX
MOV BX, address
MOV AX, ES:[BX] ;ES指向第一段,BX为偏移
MOV ipaddr, AX ;从这里可以看出4字节中低地址存放偏移
INC BX
INC BX ;后移两位后,指向的就是段地址了
MOV AX, ES:[BX]
MOV csaddr, AX
POP ES
};
printf("[CS:IP] = [%04X:%04X]\n", csaddr, ipaddr);
}
return 0;
}

更改IVT表项,向内存中加载终止后驻留内存程序TSR,然后和它通信,这里是安装一个TSR,拦截BIOS键盘中断 记录击键到全局内存缓冲区,然后运行客户端程序读取内容到屏幕。

保护模式

分段

注意到,在IA-32处理器下,很多寄存器都扩展成了32位,但是几个段寄存器还没有变,原来在保护模式下段寄存器也不是存段地址,而是存段选择子,下面直接放图吧:

全局段描述符寄存器GDTR为48位,里面存储着段描述符表的起始位置和大小:

段描述符表是一个个段描述符组成的结构体数组,每一个段描述符结构体64bit长,内容如下:

图片来源
意思如图,主要关注基地址域,DPL域,界限域。
在只有分段的情况下获取线性地址的方法为(假设是全局段描述符):
段寄存器高位的索引在以GDTR寄存器所指向的GDT中找到对应的数组,通过这个数组中记录的值找到段基地址,基地址加上有效地址(偏移地址)为线性地址。

分页

可以看出来,在保护模式下分段是必须做的,但分页不是,它涉及内存管理效率等,由于之前记过分页,这里就不再重复,只是记录之前没有写到的硬件部分,之前是讲了这部分事,但是没有看到页表什么的在哪里,这里走起:

在某种某种角度上PDE和PTE是一样的,他们的结构也是一样的,只是含义有一点不同,低位代表一些属性,高位代表页(页表)基地址,他们隐式填零得实际地址,也可以说他们是页帧号。因为PDE和PTE有属性重合,但PDE作用在PTE上,PTE作用在页上,这里关注两个属性:
U/S 用户/超级用户
R/W 只读/可读写
页表,页目录被存储在内存中,页表由页目录表指向,他们中使用的是物理地址,页目录地址又由CR3寄存器指出,同样CR3存储的也是物理地址,如下图(图片来自网络):

看到这里,终于知道老师说了那么多次的CR3是什么东东了

图片来源

CATALOG
  1. 1. 实模式
  2. 2. 保护模式
    1. 2.1. 分段
    2. 2.2. 分页