周壑x64位内核学习 (三)、x64内核之smep和smap

周壑x64位内核学习 (三)、x64内核之smep和smap

这两个位都在cr4寄存器上

一、SMEP位

不允许0环执行用户层代码页

二、SMAP位

不允许内核权限读写用户代码页

三、实验SMEP

两个文件

x64asm.asm属性:

ml64 /Fo $(IntDir)%(fileName).obj /c %(fileName).asm

$(IntDir)%(fileName).obj

项目属性:

构造中断门描述符挂idt表

idt表中第21个位置没有使用,我们导入自己的中断描述符

!idt

运行代码

我门这里直接蓝屏了,原因是发生了三重错误

这就是SMEP存在的原因

查看cr4的值

修改cr4的值

3改成2即可

再次运行程序

能正常运行且不蓝屏

四、实验(SMAP)

代码

我们运行后,任然会蓝屏,这时候我们可以同时修改smap标志位为0

但还有另一种办法,也就是系统的办法

系统难面也要从用户层读写到特权级

有一条指令叫stac指令,STAC指令相当于Set AC,用于设置AC标志位(eflag),能暂时解除系统的一些保护,包括SMAP保护。

这里我们使用 stac指令测试

代码:

我们挂上idt表,再把smep置零,再次实验,也是成功读取

注意

我们读取 KVASCODE中的代码是没问题的, 但要读text是会发生三重错误的

这是页表隔离机制引起的(KPTI),如果要读取text段的代码,需要修改页属性

目前暂时知道可读区域为 gdt表,idt表和KVACODE

代码如下:

x64asm.asm

option casemap:none

EXTERN x:qword

.DATA

.CODE

IntEntry PROC

mov rax, qword ptr [0fffff8056166efd0h]

db 0fh,01h,0cbh

;stac

mov x, rax

iretq

IntEntry ENDP

go PROC

int 21h

ret

go ENDP

END

main.cpp:

#include

#include

extern "C" void IntEntry();

extern "C" void go();

extern "C" ULONG64 x;

ULONG64 x;

void main()

{

if ((ULONG64)IntEntry != 0x0000000100001000)

{

printf("wrong IntEntry at %p \n", IntEntry);

system("pause");

exit(-1);

}

go();

printf("%p \n", x);

system("pause");

}

相关推荐

城字五行属什么
365视频游戏大厅

城字五行属什么

📅 08-30 👁️ 2850
世界时钟 :: 俄罗斯 - 当前时间
彩票365官网下载安装

世界时钟 :: 俄罗斯 - 当前时间

📅 07-29 👁️ 4470
美女主持杨茗茗:离开央视后痛失慈母 她哭过...
365bet亚洲官网网址

美女主持杨茗茗:离开央视后痛失慈母 她哭过...

📅 08-19 👁️ 5494