写在前面

  此系列是本人一个字一个字码出来的,包括示例和实验截图。由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新。 如有好的建议,欢迎反馈。码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作。如想转载,请把我的转载信息附在文章后面,并声明我的个人信息和本人博客地址即可,但必须事先通知我

你如果是从中间插过来看的,请仔细阅读 羽夏看Win系统内核——简述 ,方便学习本教程。

  看此教程之前,问几个问题,基础知识储备好了吗?上一节教程学会了吗?上一节课的练习做了吗?没有的话就不要继续了。


华丽的分割线


练习及参考

本次答案均为参考,可以与我的答案不一致,但必须成功通过。

2️⃣ 自己实验有和没有DEP保护的程序,看看效果。

点击查看答案

  这题目有一个坑,接下来请我娓娓道来。

  首先说一句:你设置操作系统的DEP保护所有程序有效了吗?(具体启用查看上一节教程,选中为除下列选定程序之外的所有程序和服务启用DEP,直接点确定),不然不起效果,白皮书原话:

  If IA32_EFER.NXE = 1, execute-disable (if 1, instruction fetches are not allowed from the 2-MByte region controlled by this entry; see Section 4.6); otherwise, reserved (must be 0).

  也就是说IA32_EFERNXE位为0,就算最高位是1也是无尽于是。我们更改这个选项就是使它为1,这个就是是坑。好了,根据我的代码先运行一下:

  发现报错了,这个和10-10-12分页的不同之处。然后把PAGE_READWRITE改为PAGE_EXECUTE_READWRITE,然后再运行:

  这次运行成功,既然它们的页的首地址都是一样的,我们来看看它们的PDE或者PTE哪里不同,先是PAGE_READWRITE的:


PROCESS 8947dda0 SessionId: 0 Cid: 0690 Peb: 7ffde000 ParentCid: 0204
DirBase: 13b00380 ObjectTable: e1702740 HandleCount: 18.
Image: mytest.exe
kd> !dq 13b00380
#13b00380 00000000`4ac31001 00000000`4a972001
#13b00390 00000000`4ac33001 00000000`4aa70001
#13b003a0 00000000`baf903c0 00000000`4a8a3001
#13b003b0 00000000`4a6a4001 00000000`4a5a1001
#13b003c0 00000000`baf90360 00000000`4a1a6001
#13b003d0 00000000`4a227001 00000000`4a264001
#13b003e0 00000000`baf90400 00000000`00000000
#13b003f0 00000000`00000000 00000000`00000000
kd> !dq 4ac31000
#4ac31000 00000000`4a92a067 00000000`4aa13067
#4ac31010 00000000`4aaa9067 00000000`4ab2f067
#4ac31020 00000000`00000000 00000000`00000000
#4ac31030 00000000`00000000 00000000`00000000
#4ac31040 00000000`00000000 00000000`00000000
#4ac31050 00000000`00000000 00000000`00000000
#4ac31060 00000000`00000000 00000000`00000000
#4ac31070 00000000`00000000 00000000`00000000
kd> !dq 4aa13000+1d0*8
#4aa13e80 80000000`4adc7067 00000000`00000000
#4aa13e90 00000000`00000000 00000000`00000000
#4aa13ea0 00000000`00000000 00000000`00000000
#4aa13eb0 00000000`00000000 00000000`00000000
#4aa13ec0 00000000`00000000 00000000`00000000
#4aa13ed0 00000000`00000000 00000000`00000000
#4aa13ee0 00000000`00000000 00000000`00000000
#4aa13ef0 00000000`00000000 00000000`00000000

  然后是PAGE_EXECUTE_READWRITE


PROCESS 895c8da0 SessionId: 0 Cid: 068c Peb: 7ffdf000 ParentCid: 0204
DirBase: 13b00300 ObjectTable: e168ea78 HandleCount: 18.
Image: mytest.exe
kd> !dq 13b00300
#13b00300 00000000`4711c001 00000000`472dd001
#13b00310 00000000`4735e001 00000000`4741b001
#13b00320 00000000`319e5001 00000000`31ae6001
#13b00330 00000000`31b27001 00000000`31b64001
#13b00340 00000000`37e87001 00000000`37c88001
#13b00350 00000000`37d89001 00000000`37c46001
#13b00360 00000000`baf903a0 00000000`46a2a001
#13b00370 00000000`46a6b001 00000000`46ba8001
kd> !dq 4711c000
#4711c000 00000000`475d6067 00000000`472bf067
#4711c010 00000000`47715067 00000000`4751b067
#4711c020 00000000`00000000 00000000`00000000
#4711c030 00000000`00000000 00000000`00000000
#4711c040 00000000`00000000 00000000`00000000
#4711c050 00000000`00000000 00000000`00000000
#4711c060 00000000`00000000 00000000`00000000
#4711c070 00000000`00000000 00000000`00000000
kd> !dq 472bf000+1d0*8
#472bfe80 00000000`476b3067 00000000`00000000
#472bfe90 00000000`00000000 00000000`00000000
#472bfea0 00000000`00000000 00000000`00000000
#472bfeb0 00000000`00000000 00000000`00000000
#472bfec0 00000000`00000000 00000000`00000000
#472bfed0 00000000`00000000 00000000`00000000
#472bfee0 00000000`00000000 00000000`00000000
#472bfef0 00000000`00000000 00000000`00000000

  可以看出PTE的最高位置为1,导致这个页被认为是数据,不是代码,故导致内存访问错误,如果我们在访问之前改了它,那么就能访问它吗?结果是可以的,我就不赘述了。


点击查看代码
#include "stdafx.h"
#include <iostream>
#include <windows.h> char shellcode[]={
0x6A,0x00, //PUSH 0
0x6A,0x00, //PUSH 0
0x6A, 0x00 , //PUSH 0
0x6A ,0x00 , //PUSH 0
0xB8, 0x00 ,0x00 ,0x00, 0x00 , //MOV EAX,0000
0xFF, 0xD0 , //CALL EAX
0xC3 //RET
}; int main(int argc, char* argv[])
{ int msgbox=(int)MessageBoxW;
*(int*)&shellcode[9]=msgbox; LPVOID scaddr = VirtualAlloc(NULL,1024,MEM_COMMIT,PAGE_READWRITE);
memcpy(scaddr,shellcode,sizeof(shellcode));
printf("Shellcode物理页:%p\n",scaddr); _asm
{
mov eax,scaddr;
call eax;
} VirtualFree(scaddr,0,MEM_RELEASE);
system("pause");
return 0;
}

TLB

  CPU通过页的方式对物理内存进行了,需要通过某种运算方式才能访问真正的内存。但是,如果频繁访问某一个线性地址,每次都得通过推算到真正的物理地址然后进行读写操作,是不是挺浪费效率的?Intel就考虑到性能的问题,提供了TLB这一个机制,提供缓存提高读写效率。

  TLB的全称为Translation Lookaside Buffer,它的结构如下:

LA(线性地址) PA(物理地址) ATTR(属性) LRU(统计)
0x81010111 …… …… 1

  对于TLB,给出如下说明:

  1. ATTR(属性):属性是PDPE PDE PTE三个属性AND起来的. 如果是10-10-12分页就是PDEPTE

  2. 不同的CPU这个表的大小不一样。

  3. 只要Cr3变了,TLB立马刷新,一核一套TLB

  学到现在我们知道,操作系统的高2G映射基本不变,如果Cr3改了,TLB刷新重建高2G以上很浪费。所以PDEPTE中有个G标志位,如果G位为1刷新TLB时将不会刷新PDE/PTEG位为1的页,当TLB满了,根据统计信息将不常用的地址废弃,最近最常用的保留。

  TLB有不同的种类,用于不同的缓存目的,它在X86体系里的实际应用最早是从Intel486CPU开始的,在X86体系的CPU里边,一般都设有如下4组TLB

  第一组:缓存一般页表(4K字节页面)的指令页表缓存:Instruction-TLB

  第二组:缓存一般页表(4K字节页面)的数据页表缓存:Data-TLB

  第三组:缓存大尺寸页表(2M/4M字节页面)的指令页表缓存:Instruction-TLB

  第四组:缓存大尺寸页表(2M/4M字节页面)的数据页表缓存:Data-TLB

CPU缓存

  CPU缓存是位于CPU与物理内存之间的临时存储器,它的容量比内存小的多但是交换速度却比内存要快得多。它可以做的很大,但不是TLB,它们有很大的不同。TLB存的是线性地址与物理地址的对应关系,CPU缓存存的是物理地址与内容对应关系。

  更多的细节请参考白皮书的Chapter 11 Memory Cache Control,本篇教程主要是针对内核安全层面,就不再赘述了。

PWT 与 PCD

  PWT全称为Page Write ThroughPWT = 1时,写Cache的时候也要将数据写入内存中。

  PCD全称为Page Cache DisablePCD = 1时,禁止某个页写入缓存,直接写内存。比如,做页表用的页,已经存储在TLB中了,可能不需要再缓存了。

本节练习

本节的答案将会在下一节进行讲解,务必把本节练习做完后看下一个讲解内容。不要偷懒,实验是学习本教程的捷径。

  俗话说得好,光说不练假把式,如下是本节相关的练习。如果练习没做好,就不要看下一节教程了,越到后面,不做练习的话容易夹生了,开始还明白,后来就真的一点都不明白了。本节练习很少,请保质保量的完成。

1️⃣ 在10-10-12分页模式下体会TLB的存在。要求:通过代码挂物理页,不能通过Windbg挂。原物理页挂完写入值读取,然后把地址换物理页继续读取,看看值是否发生变化。然后改页属性为全局页,重复上述操作。然后用INVLPG指令之后再看看值是否变化。

下一篇

  保护模式篇——中断与异常和控制寄存器

保护模式篇——TLB与CPU缓存的更多相关文章

  1. 保护模式篇——PAE分页

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...

  2. 羽夏看Win系统内核——保护模式篇

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...

  3. TLB和CPU缓存

    TLB 如果每次应用程序访问一个线性地址都需要先解析(查PDT,PTT)那么效率十分低,为了提高执行效率CPU在CPU内部建立了一个TLB表,此表和寄存器一样访问速度极高.其会记录线性地址和物理地址之 ...

  4. x64 番外篇——保护模式相关

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...

  5. MIT 6.828 JOS学习笔记6. Appendix 1: 实模式(real mode)与保护模式(protected mode)

    在我们阅读boot loader代码时,遇到了两个非常重要的概念,实模式(real mode)和保护模式(protected mode). 首先我们要知道这两种模式都是CPU的工作模式,实模式是早期C ...

  6. 鸿蒙内核源码分析(工作模式篇) | CPU是韦小宝,七个老婆 | 百篇博客分析OpenHarmony源码 | v36.04

    百篇博客系列篇.本篇为: v36.xx 鸿蒙内核源码分析(工作模式篇) | CPU是韦小宝,七个老婆 | 51.c.h .o 硬件架构相关篇为: v22.xx 鸿蒙内核源码分析(汇编基础篇) | CP ...

  7. CPU保护模式深入探秘

    原文链接为:http://www.chinaunix.net/old_jh/23/483510.html 保护方式的体系结构 主要问题:          保护方式的寄存器模型          保护 ...

  8. 基础篇-Windows保护模式

    1 一般来说,80x86(80386及其以后的各代CPU)可以在三种模式下运转:实模式,保护模式,V86模式.实模式就是古老的MS-DOS的运行环境.Win95只利用了两种模式:保护模式和V86模式. ...

  9. CPU保护模式DPL、CPL简易理解

    现代INTEL CPU都有保护模式,实模式这两种CPU运行模式.当CPU加电,CPU初始化时就运行在是模式下,然后现代操作系统会从实模式跳转到保护模式! 为什么需要保护模式? 在最开始编程的汇编时代, ...

随机推荐

  1. vue element-ui 组件上传图片 之后 对上传按钮 进行隐藏,删除之后重新显示

    注:如果在当前的 vue 文件里 写了 style 样式,得 去除 scoped [私有属性必须去除,不能保留](这个是重点,不去除不生效), template 部分 <el-upload    ...

  2. 查看所有日志命令:journalctl

    journalctl命令作用:实时查看所有日志(内核日志和应用日志) 语法格式: journalctl [参数] 常用参数:-k 查看内核日志-b 查看系统本次启动的日志-u 查看指定服务的日志-n ...

  3. CommonsCollections1 反序列化利用链分析

    InvokerTransformer 首先来看 commons-collections-3.1-sources.jar!\org\apache\commons\collections\functors ...

  4. 集合Collection ----Set集合

    set系列集合:添加的元素是 无序,不重复,无索引的 ----HashSet: 无序,不重复,无索引 ------LinkHashSet<>:有序不重复无索引(添加顺序) ----Tree ...

  5. vscode 本地启动配置

    安装vscode 编辑器后,找到插件 1.安装Debugger for Chrome 2.找到本地需要启动的项目,配置文件,从左到右依次点击红圈中的按钮,然后出现launch.json文件,在里面添加 ...

  6. PHP7兼容mysql_connect的方法

    在php7版本的时候,mysql_connect已经不再被支持了,本文将讲述在代码层面实现php7兼容mysql系列,mysql_connect等操作. PHP7不再兼容mysql系列函数,入mysq ...

  7. ECSHOP任意页面显示指定分类、数量、排序的任意类型文章,包括只显示置顶or普通的文章

    1.在需要使用此功能的PHP页面里最后的?>前面添加以下代码,现在以article.php为例子 /** jinmozhe 专业ECSHOP二次开发 * 获得指定分类ID.文章类型.指定数量.排 ...

  8. 华为云计算IE面试笔记-FusionCompute上的虚拟机A和虚拟机B不能正常通信,请描述可能的故障点和排除方法(分析虚拟机A和虚拟机B不通)

    *快速定位故障点:(考到) ARP:同一二层内可以通过ARP -a命令查询到要访问的主机IP(ARP表项中记录了同一二层中的IP和MAC的对应关系),若查询不到,说明二层出现问题(Vlan 间不通)或 ...

  9. 制作python程序windows安装包(飞机大战源码)

    本文以飞机大战源码为例: 1.首先使用pyinstaller -w xxx.py打包   -w的意思是不显示命令行:飞机大战源码由多个.py文件以及一些图片,音乐文件组成,我们将main.py打包, ...

  10. 基于AM335X,如何搭建优良的Linux开发环境(下)

    接着上一篇文章的Linux开发环境搭建,文章中详细讲解了 VMware14.1.1虚拟机安装.基于虚拟机安装Ubuntu14.04.3操作系统.安装Ubuntu14.04.3操作系统.安装虚拟机工具. ...