
 突破TP,NP等游戏保护跨进程写只读内存方法
 

2021在线班
郁金香灬老师 QQ 150330575
交流群:158280115


学习目标: 
    突破TP,NP等游戏保护跨进程写只读内存方法

	VirtualProtectEx
	League of Legends.exe
	0x400000
	#include<ntifs.h>
    VirtualQueryEx 
	

#define PAGE_NOACCESS 0x01
#define PAGE_READONLY 0x02 只读
#define PAGE_READWRITE 0x04 可读可写
#define PAGE_WRITECOPY 0x08 写时复制
#define PAGE_EXECUTE 0x10   可执行
#define PAGE_EXECUTE_READ 0x20 可读可执行
#define PAGE_EXECUTE_READWRITE 0x40 可读可写可执行
#define PAGE_EXECUTE_WRITECOPY 0x80 可执行 写时复制 ntdll.dll user32.dll
#define PAGE_GUARD 0x100
#define PAGE_NOCACHE 0x200
#define PAGE_WRITECOMBINE 0x400

PAGE_READONLY： 该区域为只读。如果应用程序试图访问区域中的页的时候，将会被拒绝访
PAGE_READWRITE 区域可被应用程序读写
PAGE_EXECUTE： 区域包含可被系统执行的代码。试图读写该区域的操作将被拒绝。
PAGE_EXECUTE_READ ：区域包含可执行代码，应用程序可以读该区域。
PAGE_EXECUTE_READWRITE： 区域包含可执行代码，应用程序可以读写该区域。
PAGE_GUARD： 区域第一次被访问时进入一个STATUS_GUARD_PAGE异常，这个标志要和其他保护标志合并使用，表明区域被第一次访问的权限
PAGE_NOACCESS： 任何访问该区域的操作将被拒绝
PAGE_NOCACHE： RAM中的页映射到该区域时将不会被微处理器缓存（cached)

	
内存类型

PagedPool 和 NonPagedPool
前者可以被置换到硬盘中,一般存储数据, 如打开一个大文件, 数据结构. 

后者不能被置换到硬盘中,驻留在内存中,一般用来存储代码.  

如果执行代码到PagedPool的内存中去了,很有可能导致蓝屏

此外,在内核空间中所有内存都是可读可写可执行,故没有类似用户态下的VirtualProtect改变内存属性的函数

但是并不意味着可以随意执行和改写内存中的代码.要满足2个条件: 一个是关闭内存写保护, 二个是提升IRQL级别.(防止执行出错)

对于关闭内存写保护通过操作cr0寄存器,后者使用KeRaiseIrqlToDpcLevel 和KeLowerIrql 实现

//关闭内存写保护和提升IRQL
KIRQL irql=KeRaiseIrqlToDpcLevel();
UINT64 cr0=__readcr0();
cr0 &= 0xfffffffffffeffff;
__writecr0(cr0);
_disable();


还原:

UINT64 cr0=__readcr0();
cr0 |= 0x10000;
_enable();
__writecr0(cr0);
KeLowerIrql(irql);

  <intrin.h>
//打开可写内存的检测
UINT64 WPONx64(KIRQL irql)
{
	UINT64 cr0 = __readcr0();
	UINT64 old_cr0 =cr0;
	cr0 |= 0x10000;
	_enable();
	__writecr0(cr0);
	KeLowerIrql(irql);
	return old_cr0;
}

__writecr0(old_cr0);

//关闭可写内存的检测
KIRQL WPOFFx64()
{
	KIRQL irql = KeRaiseIrqlToDpcLevel();
	UINT64 cr0 = __readcr0();
	cr0 &= 0xfffffffffffeffff;
	__writecr0(cr0);
	_disable();
	return irql;

}

