x64内核实验2-段机制的变化

x64内核实验2-段机制的变化

ia-32e模式简介

x86下的段描述符结构图如下
在这里插入图片描述

在x86环境下段描述符主要分为3个部分的内容:base、limit、attribute,而到了64位环境下段的限制越来越少,主要体现在base和limit已经不再使用而是直接置空,也就是默认强制为平坦模式

ia-32e模式使用的是64位内核文件,legacy是兼容模式使用的还是32位内核文件,我们这里不关注兼容模式
ia-32e模式下是支持32位和64位的文件的,此模式下就是之前说的强制平坦模式并且取消掉了任务门切换的能力(可能是本来在32位的环境下各个操作系统的实现就没有使用任务切换所以cpu在64位下把这个能力删掉了)
ia-32e模式的启动流程跟32位下差不多也是进来是实模式然后在msr寄存器里设置一些位开启ia-32e模式模式
ia-32e模式下的系统调用跟32位下差不多是通过syscall进入0环

rdmsr 命令可以查看msr寄存器的值

0: kd> rdmsr c0000080
msr[c0000080] = 00000000`00000d01
0: kd> .formats d01
Evaluate expression:Hex:     00000000`00000d01Decimal: 3329Decimal (unsigned) : 3329Octal:   0000000000000000006401Binary:  00000000 00000000 00000000 00000000 00000000 00000000 00001101 00000001Chars:   ........Time:    Thu Jan  1 08:55:29 1970Float:   low 4.66492e-042 high 0Double:  1.64474e-320

可以看到我的模式是d01通过.formats查看具体描述可以看到我当前的二进制位第8位是1(第八位是第九个)说明处于IA-32e模式

这里我们先介绍这些后面慢慢遇到了在说

非系统段描述符的变化

首先看一下白皮书里对64位代码段描述符给出的图
在这里插入图片描述

可以看到大部分段描述符的长度依旧是64位,但是基址和界限已经不再存储了,而是默认平坦,留下的大部分内容和32位是一致的,因为图例给出的是代码段所以s位是1type的第一位也是1,要说的是L位现在描述的是32位还是64位段

有区别的地方在于只有s位=1的时候段描述符是64位,s=0的时候段描述符是128位,这是因为在64位环境下我们的数据段和代码段都是强制平坦模式无需关注base和limit而系统段不是这样在系统段里存了段选择子和offset而64位环境下offset也就有64位所以他必须扩到16个字节来存储offset

举例说明就是如果是1就是64位,如果L=1那么push Xax会被翻译为push rax反之则是push eax

下面我们分析几个段描述符看一下

0: kd> r gdtr
gdtr=fffff80580a99fb0
0: kd> dq fffff80580a99fb0
fffff805`80a99fb0  00000000`00000000 00000000`00000000
fffff805`80a99fc0  00209b00`00000000 00409300`00000000
fffff805`80a99fd0  00cffb00`0000ffff 00cff300`0000ffff
fffff805`80a99fe0  0020fb00`00000000 00000000`00000000
fffff805`80a99ff0  80008ba9`80000067 00000000`fffff805
fffff805`80a9a000  0040f300`00003c00 00000000`00000000
fffff805`80a9a010  00000000`00000000 00000000`00000000
fffff805`80a9a020  00000000`00000000 00000000`00000000

00209b00 00000000 g=0 d=0 l=1 avl=0 p=1 dpl=0 s=1 type=1011
说明是一个64位的代码段描述符 dpl=0
00409300 00000000 g=0 d=1 l=0 avl=0 p=1 dpl=0 s=1 type=0011
说明是一个64位数据段描述符 dpl=0
这里要说明一下这个l位只对代码段生效
00cffb00 0000ffff g=1 d=1 l=0 avl=0 p=1 dpl=3 s=1 type=1011
是一个3环32位代码段
00cff300 0000ffff g=1 d=1 l=0 avl=0 p=1 dpl=3 s=1 type=0011
是一个3环32位数据段
00000000 fffff805 80008ba9 80000067这就是一个系统tss段
他的base是fffff805 80a98000系统段我们后面再说

怎么去验证呢,在windbg中可以使用dg命令加上段的偏移就可以显示目标段描述符的详细信息
如下可以看到我们分析的是对的

0: kd> dg 10P Si Gr Pr Lo
Sel        Base              Limit          Type    l ze an es ng Flags
---- ----------------- ----------------- ---------- - -- -- -- -- --------
0010 00000000`00000000 00000000`00000000 Code RE Ac 0 Nb By P  Lo 0000029b
0: kd> dg 3*8P Si Gr Pr Lo
Sel        Base              Limit          Type    l ze an es ng Flags
---- ----------------- ----------------- ---------- - -- -- -- -- --------
0018 00000000`00000000 00000000`00000000 Data RW Ac 0 Bg By P  Nl 00000493
系统段的变化

我们这边只介绍调用门和中断门,任务门在白皮书里明确说明x64下不提供此能力,陷阱门没找到对应章节暂不处理

1.调用门

首先看一下调用门在x64下的描述符结构和32位下的对比
在这里插入图片描述

这是32位下的
在这里插入图片描述

可以看到描述符扩充到了128位低32位跟32位环境下是一模一样的只是不在提供有参的形式了(这也是对32位环境兼容的一种做法)高64位的低32字节用作offset,图中高64位的type暂时没看到有什么用
下面我们做一些实验来熟悉调用门
实验:

  1. windbg创建自己的调用门,并在应用层调用

首先描述出我们要添加的调用门的属性
selector 0013
offset 00007ff8 85420960
p=1
dpl=11
s=0
type=1100
根据属性构造出调用门(注意windbg的eq是一次写入64位而我们分两次写要小心大小端序的问题)
8542ec0000130960 0000000000007ff8

在这里插入图片描述

我们的selector是 0x63

2.TSS段描述符

tss段是变化比较大的一个系统段描述符,下面是白皮书里的段描述结构图,他变化的点不在于这个段描述符的结构变化而是TSS所描述的内存块中存储的内容发生了比较大的变化,也就是TSS这个数据结构变化是比较大的
在这里插入图片描述

我们来对比这看一下
这是我们比较熟悉的32位环境下的tss结构,然后我们在看一下64位下的变化
在这里插入图片描述

这是64位下的tss结构,可以发现里面不在存储各种各样的寄存器了而是存储的ISTX
这个IST是中断栈表,每一个都存储了64位的esp地址相当于32位下的esp0 esp1 esp2等位置,其中IST0就是esp0,IST3就是esp3,这种变化的原因我想可能有两个,一个是在64位下不再提供任务切换的能力,第二个就是tss这个结构本身在32位操作系统中也就只使用了esp0,所以在64位下干脆就不存储其他的寄存器只提供存储各种各样的esp的能力,在线程切换时候就可以直接替换对应的ist0或者ist3就可以切换当前的栈
大家可能觉得疑惑我们只有0123四种权限级别为啥提供了一大堆的ist都干到ist7了,这是因为64位的中断门也发生了变化中断门会使用这个ist位,等下我们看到中断门的时候再详细描述,现在我们只要记住tss中存储了一大堆的esp基址分别对应了一个和一个的ist变化就可以了
在这里插入图片描述

3.中断门

首先我们还是看一下白皮书里对64位中断门的描述
在这里插入图片描述

下面是我在网上找的32位下中断门描述符的图
在这里插入图片描述

可以看到64位和32位下中断门的变化跟调用门差不多属性位置都没有变然后高64位中多存储了32位的偏移地址,不过注意看一下在64位下多出了一个属性字段IST,我们回想一下刚刚的tss中是不是有一大堆istX,那个就是给这里用的,当我们通过中断进入0环的时候会根据中断门的ist位来切换当前的堆栈
我们来看一下我环境上的idt表
在这里插入图片描述

我图中圈出来的就是ist位,它代表了调用这个中断门切换esp时候所使用的tss中对应的ist编号
如下,部分中断就会用一些比较特殊的栈
在这里插入图片描述

大家可以自己调用一下中断来看一下栈的变化能够更好的理解中断门在64位环境下的变化

SAMP和SEMP

SMAP(Supervisor Mode Access Prevention,管理模式访问保护)和SMEP(Supervisor Mode Execution Prevention,管理模式执行保护)的作用分别是禁止内核CPU访问用户空间的数据和执行用户空间的代码,并不会因为你权限高就能访问/执行低权限的资源,你的就是你的,我的就是我的

这里两个检查的控制位分别是cr4的第20位和第21位
当这两位为1的时候意味着0环不可以访问和执行三环地址,运行时就会进行检查

现在我们可以做一些实验了
实验1:
通过驱动在0环读取idt表和idt表并解析出信息打印出来,大家可以试一下不开smap和开启smap的时候我们的代码运行时有什么区别

实验代码:

#include <wdm.h>
//#include <ntifs.h>
#define NTSTRSAFE_LIB
#include <ntstrsafe.h>
#include <intrin.h>
#pragma pack(1)
struct Attribute
{UINT64 offset1 : 16;UINT64 p : 1;UINT64 dpl : 2;UINT64 s : 1;UINT64 type : 4;UINT64 unuse : 6;UINT64 ist : 2;UINT64 selector : 16;UINT64 offset2 : 16;
};
typedef struct _IDT_ENTRY64 {union hightStruct{UINT64 lower;struct Attribute attribute;};UINT64 hight;
}IDT_ENTRY64, * PIDT_ENTRY64;typedef struct _IDTR
{UINT16 limit;UINT64 base;
}IDTR, *PIDTR;
#pragma pack()VOID Unload(PDRIVER_OBJECT pDriver) {KdPrint(("unload\r\n"));}NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRegPath) {NTSTATUS status = STATUS_SUCCESS;pDriver->DriverUnload = Unload;KdPrint(("start\r\n"));//关闭smap和smepUINT64 cr4 = __readcr4();cr4 &= 0xffffffffffcfffff;__writecr4(cr4);IDTR idtr = { 0 };PIDT_ENTRY64 idtEntryArr = NULL;__sidt(&idtr);KdPrint(("idt base:0x%llx, limit:0x%x\r\n",idtr.base ,idtr.limit));if (idtr.base == NULL && idtr.limit <= 0) {return STATUS_UNSUCCESSFUL;}idtEntryArr = (PIDT_ENTRY64)idtr.base;DbgBreakPoint();SIZE_T i = 0;while (i < (idtr.limit / 16)){UINT64 hight = idtEntryArr->hight << 32;UINT64 lower_1 = (idtEntryArr->lower & 0xffff000000000000) >> 32;UINT64 lower_2 = (idtEntryArr->lower & 0x000000000000ffff);UINT64 offset = hight + lower_1 + lower_2;UINT16 selector = (idtEntryArr->lower & 0x00000000ffff0000) >> 16;KdPrint(("中断门 index=%llu---offset=0x%llx---selector=0x%x---p=%d---dpl=%d---type=%d---ist=%d\r\n", i, offset, (UINT32)selector, (UINT32)idtEntryArr->attribute.p,(UINT32)idtEntryArr->attribute.dpl, (UINT32)idtEntryArr->attribute.type,(UINT32)idtEntryArr->attribute.ist));i++;idtEntryArr++;}KdPrint(("end\r\n"));return status;
}

T32)idtEntryArr->attribute.p,
(UINT32)idtEntryArr->attribute.dpl, (UINT32)idtEntryArr->attribute.type,
(UINT32)idtEntryArr->attribute.ist));
i++;
idtEntryArr++;
}
KdPrint((“end\r\n”));
return status;
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/148454.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

进程调度算法之先来先服务(FCFS),短作业优先(SJF)以及高响应比优先(HRRN)

1.先来先服务&#xff08;FCFS&#xff09; first come first service 1.算法思想 主要从“公平”的角度考虑(类似于我们生活中排队买东西的例子) 2.算法规则 按照作业/进程到达的先后顺序进行服务。 3.用于作业/进程调度 用于作业调度时&#xff0c;考虑的是哪个作业先…

商业智能系统的主要功能包括数据仓库、数据ETL、数据统计输出、分析功能

ETL服务内容包含&#xff1a; 数据迁移数据合并数据同步数据交换数据联邦数据仓库

Scala第十一章节

Scala第十一章节 1.模式匹配 2. Option 类型 3.偏函数 4.正则表达式 5.异常处理 6.提取器 7.案例&#xff1a;随机职业 scala总目录 文档资料下载

Boost程序库完全开发指南:1.1-C++基础知识点梳理

主要整理了N多年前&#xff08;2010年&#xff09;学习C的时候开始总结的知识点&#xff0c;好长时间不写C代码了&#xff0c;现在LLM量化和推理需要重新学习C编程&#xff0c;看来出来混迟早要还的。 1.shared_ptr 解析&#xff1a;shared_ptr是一种计数指针&#xff0c;当引…

U盘里文件损坏无法打开怎么恢复?

U盘&#xff0c;全称为USB闪存盘&#xff0c;是一种体积小巧、传输数据速度快的便携式存储设备。由于其出色的便捷性和高效性&#xff0c;U盘在各个工作领域和日常生活中得到了广泛应用&#xff0c;赢得了消费者的普遍好评。然而&#xff0c;使用U盘的过程中也可能会面临数据损…

Redis的java客户端-RedisTemplate光速入门

一.创建springboot项目 二.引入2个依赖 <!-- redis依赖-->这个已经引入了&#xff0c;因为创建的时候勾选了<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><…

Sublime Text 4 for Mac激活下载

Sublime Text for Mac是一款适用于Mac平台的文本编辑器。它具有快速的性能和丰富的功能&#xff0c;可以帮助用户快速进行代码编写和文本编辑。 软件下载&#xff1a;Sublime Text 4 for Mac激活下载 该软件具有直观的界面和强大的功能&#xff0c;包括多行选择、代码折叠、自动…

【项目开发 | C语言项目 | C语言病人管理系统】

该项目旨在为医院或其他医疗机构提供一个简易的病人信息管理工具。用户可以通过命令行界面进行病人信息的增、删、查和改操作&#xff0c;并将数据持久化存储在txt文件中。 一&#xff0c;开发环境需求 操作系统 &#xff1a;Windows, Linux 开发环境工具 &#xff1a;Qt, VSC…

Appium开发

特点 开源免费支持多个平台 IOS(苹果)、安卓App的自动化都支持 支持多种类型的自动化 支持苹果、安卓应用原生界面的自动化支持应用内嵌网络视图的自动化支持手机浏览器(Chrome)中的web网站自动化支持flutter应用的自动化 支持多种编程语言 像selenium一样&#xff0c;可以用多…

uboot启动流程-uboot内存分配工作总结

一. uboot 启动流程 _main 函数中会调用 board_init_f 函数&#xff0c;本文继续简单分析一下 board_init_f 函数。 本文继续具体分析 board_init_f 函数。 本文继上一篇文章的学习&#xff0c;地址如下&#xff1a; uboot启动流程-uboot内存分配_凌肖战的博客-CSDN博客 二…

【微信小程序开发】一文学会使用CSS控制样式布局与美化

引言 在微信小程序开发中&#xff0c;CSS样式布局和美化是非常重要的一部分&#xff0c;它能够为小程序增添美感&#xff0c;提升用户体验。本文将介绍如何学习使用CSS进行样式布局和美化&#xff0c;同时给出代码示例&#xff0c;帮助开发者更好地掌握这一技巧。 一、CSS样式布…

[VIM]spcaevim

Home | SpaceVim SpaceVim - 知乎 关于Vim/Neovim/SpaceVim的一些思考 - 知乎 vim高配版(1) – SpaceVim 简介 SpaceVim 是国内的一个大佬将一些NB的插件整合到一起的一个插件包. 一键式安装, 功能强大. 官网参见 Home | SpaceVim vim高配版(2) – vimplus 简介 vimplu…

Python:操作SQLite数据库简单示例

本文用最简单的示例演示python标准库提供的SQLite数据库进行新增、查询数据的过程。 代码文件app.py # -*- coding: UTF-8 -*- from flask import Flask import sqlite3app Flask(__name__)app.route(/) def hello_world():return Hello World!#创建数据库 app.route(/creat…

Android LitePal byte[]类型字段不被创建

我创建了以下实体类&#xff0c;主要是用户分享的内容、分享的照片、分享的标题&#xff0c;然后百度了一下LitePal可以识别byte[]&#xff0c;因为需要文件的上传与读取&#xff1a; public class Context extends LitePalSupport {private Integer ContextId;private String…

使用Pytorch构建神经网络

构建神经网络的典型流程 定义一个拥有可学习参数的神经网络遍历训练数据集处理输入数据使其流经神经网络计算损失值将网络参数的梯度进行反向传播以一定的规则更新网络的权重 我们首先定义一个Pytorch实现的神经网络: # 导入若干工具包 import torch import torch.nn as nn …

机器学习笔记(一)

1.线性回归模型 2. 损失函数 3.梯度下降算法 多元特征的线性回归 当有多个影响因素的时候,公式可以改写为: 当有多个影响因素的时候为了方便计算,可以使用 Numpy下面的点积方法, np.dot(w,x) 最后再加个b 就省略了很多书写步骤,这叫做矢量化 多元回归的梯度下降 左边是一…

小团队内部资料共享协作:有效实施策略与方法

在高效率的办公节奏下&#xff0c;传统的文件共享方式无法匹配许多团队的需求&#xff0c;并且在现实使用过程中往往存在许多问题&#xff0c;如版本混乱、权限管理困难等。那么小团队的内部资料共享协作应该怎么做呢&#xff1f; 小型团队可以借助专业的协作工具实现高效内部…

Lucene学习总结之Lucene的索引文件格式

四、具体格式 上面曾经交代过&#xff0c;Lucene保存了从Index到Segment到Document到Field一直到Term的正向信息&#xff0c;也包括了从Term到Document映射的反向信息&#xff0c;还有其他一些Lucene特有的信息。下面对这三种信息一一介绍。 4.1. 正向信息 Index –> Seg…

【网络安全---ICMP报文分析】Wireshark教程----Wireshark 分析ICMP报文数据试验

一&#xff0c;试验环境搭建 1-1 试验环境示例图 1-2 环境准备 两台kali主机&#xff08;虚拟机&#xff09; kali2022 192.168.220.129/24 kali2022 192.168.220.3/27 1-2-1 网关配置&#xff1a; 编辑-------- 虚拟网路编辑器 更改设置进来以后 &#xff0c;先选择N…

设计模式12、代理模式 Proxy

解释说明&#xff1a;代理模式&#xff08;Proxy Pattern&#xff09;为其他对象提供了一种代理&#xff0c;以控制对这个对象的访问。在某些情况下&#xff0c;一个对象不适合或者不能直接引用另一个对象&#xff0c;而代理对象可以在客户端和目标对象之间起到中介的作用。 抽…