游戏网站服务器租用网站正在建设中提示页面
news/
2025/9/23 15:22:42/
文章来源:
游戏网站服务器租用,网站正在建设中提示页面,天津网站制作维护,国内常见响应式网站By Lthis 上个月就想写了#xff0c;一直没时间...网上大概搜了一下#xff0c;原理与操作倒是一大堆#xff0c;一直没看到源码实现#xff0c;总得有人动手#xff0c;这回轮到我了。东西写得很烂#xff0c;请大牛勿喷。一直觉得靠源码的方式驱动学习是非常好的一种学… By Lthis 上个月就想写了一直没时间...网上大概搜了一下原理与操作倒是一大堆一直没看到源码实现总得有人动手这回轮到我了。东西写得很烂请大牛勿喷。一直觉得靠源码的方式驱动学习是非常好的一种学习方法比较直观声明一下本教程只有讨论开启PAE与关闭PAE两种至于PSE是否开启没有管...我的虚拟机默认PSE貌似是开启滴不知是不是写的小工具有问题....对于x64下的等我有时间再写吧。 东西都上传在压缩包中了Codes文件夹下是工程源码Demo文件夹下是测试案例Tool文件夹放的是小工具的Demo和源码。 我的环境开发环境win7 sp1 x64 vs2013社区版 update5 wdk8.1 测试环境vm10 win7 sp1 x86 一、先说说未开启PAE的情况祭出intel手册的经典图例 这幅图就是虚拟地址转为物理地址的原理图4k页面看图说话用伪代码描述一下 1.Directory Entry(PDE) PDBR[Directory]; 2.Page-Table Entry(PTE) PDE Table * 4; 3.Physical Address PTE Offset; 由上可知Linear Address(线性地址)中的Directory和Table其实就是个索引在未开启PAE的情况下PDE、PTE均是32bit4字节所以要Table*4以上只是原理上的描述实际上PDE、PTE的后3位是属性值所以需要把后3位抹掉。 下边上关键代码基本都步骤都写了注释了有需要的可以封装成函数。此外本段代码只是测试用写的很不规范比如在调用MmMapIoSpace应该调用MmUnMapIoSpace释放内存。 // 得到ring3传入的虚拟地址size_t* pOutAddress (size_t*)MmGetSystemAddressForMdlSafe(pIrp-MdlAddress, NormalPagePriority);VIRTUAL_ADDRESS virtualAddress { 0 };virtualAddress.ulVirtualAddress *pOutAddress;ULONG pdbr;_asm{mov eax, cr3;mov pdbr, eax;}PHYSICAL_ADDRESS phyAddress { 0 };phyAddress.LowPart pdbr;PULONG pPdbr (PULONG)MmMapIoSpace(phyAddress, sizeof(PHYSICAL_ADDRESS), MmNonCached);KdPrint((pdbr 0x%08X, 映射后的地址0x%p\n, pdbr, pPdbr));// pPdbr[ulDirBaseIdx] 页目录项ULONG ulDirBaseIdx virtualAddress.stVirtualAddress.dirBaseIndex;ULONG ulDirIdx virtualAddress.stVirtualAddress.dirIndex;KdPrint((第一级已找到页目录所在项:pPdbr[%d]:0x%08X, ulDirBaseIdx,pPdbr[ulDirBaseIdx]));ULONG ulDir pPdbr[ulDirBaseIdx] 0xFFFFF000; // 抹去后3位得到真正的页目录项
ULONG ulDirPlus ulDir ulDirIdx * 4; // 页表项phyAddress.LowPart ulDirPlus;PULONG pDirPlus (PULONG)MmMapIoSpace(phyAddress, sizeof(PHYSICAL_ADDRESS), MmNonCached);KdPrint((第二级已找到页表项:ulDirPlus 0x%08X, 映射后的地址0x%p\n, ulDirPlus, pDirPlus));ULONG ulPageTable *pDirPlus 0xFFFFF000; // 抹去后3位得到真正的页表项// 得到物理地址ULONG ulPhyAddress ulPageTable virtualAddress.stVirtualAddress.offset;// 映射为虚拟地址获取其值进行验证phyAddress.LowPart ulPhyAddress;PWCHAR pPhyAddress (PWCHAR)MmMapIoSpace(phyAddress, sizeof(PHYSICAL_ADDRESS), MmNonCached);KdPrint((虚拟地址0x%08X, 对应物理地址0x%08X, Value:%S\n, *pOutAddress, ulPhyAddress, pPhyAddress));// 传出对应物理地址*pOutAddress ulPhyAddress; 二、开启PAE的情况 同样是4k页面的伪代码描述如下 1.Dir.Pointer Entry(PDPTE) PDPTR[Directory Pointer]; 2.Director Entry(PDE) PDPTE Directory * 0x8; 3.Page-Table Entry(PTE) PDE Table * 0x8; 4.Physical Address PTEOffset; 在开启PAE的情况下PDE、PTE均是64bit8字节所以要*8同样PDE、PTE的后3位是属性值所以需要把后3位抹掉。 关键代码如下 // 得到传入的ring3层虚拟地址size_t* pOutAddress (size_t*)MmGetSystemAddressForMdlSafe(pIrp-MdlAddress, NormalPagePriority);VIRTUAL_ADDRESS virtualAddress { 0 };virtualAddress.ulVirtualAddress *pOutAddress;ULONG pdbr;// 得到页目录指针物理地址_asm{mov eax, cr3;mov pdbr, eax;}// 映射为虚拟地址以便取值PHYSICAL_ADDRESS phyAddress { 0 };phyAddress.LowPart pdbr;PULONG pPdbr (PULONG)MmMapIoSpace(phyAddress, sizeof(PHYSICAL_ADDRESS), MmNonCached);KdPrint((pdbr 0x%08X, 映射后的地址0x%p\n, pdbr, pPdbr));// 定位页目录指针表并获取页目录表物理页地址// ulDirAddress 为页目录表物理页地址ULONG ulPointerIdx virtualAddress.stVirtualAddress.dirPointer;ULONG ulDirBaseAddress pPdbr[ulPointerIdx];ulDirBaseAddress 0xFFFFF000; // 中间物理地址// 定位页表项ULONG ulDirAddress ulDirBaseAddress virtualAddress.stVirtualAddress.dirIndex * 0x8;phyAddress.LowPart ulDirAddress;PULONG pPageTable (PULONG)MmMapIoSpace(phyAddress, sizeof(PHYSICAL_ADDRESS), MmNonCached);ULONG ulPageTable *pPageTable;ulPageTable 0xFFFFF000; // 中间物理地址// 定位物理页面ulPageTable virtualAddress.stVirtualAddress.tableIndex * 0x8;phyAddress.LowPart ulPageTable;PULONG pPageBase (PULONG)MmMapIoSpace(phyAddress, sizeof(PHYSICAL_ADDRESS), MmNonCached);ULONG ulPageBase *pPageBase;ulPageBase 0xFFFFF000;// 得到物理地址ULONG ulPhyAddress ulPageBase virtualAddress.stVirtualAddress.offset;// 映射为虚拟地址获取其值进行验证phyAddress.LowPart ulPhyAddress;PWCHAR pPhyAddress (PWCHAR)MmMapIoSpace(phyAddress, sizeof(PHYSICAL_ADDRESS), MmNonCached);KdPrint((虚拟地址0x%08X, 对应物理地址0x%08X, Value:%S\n, *pOutAddress, ulPhyAddress, pPhyAddress));// 传出对应物理地址*pOutAddress ulPhyAddress;pIrp-IoStatus.Information cout; 以上代码步骤是参考安于此生的文章写的看不懂的可以先看看安于此生的文章《启用PAE后虚拟地址到物理地址的转换》 另附上小工具源码该工具用于检测系统是否开启PAE、PSE等。 #define BUFFERSIZE 0x3000
char g_szMemInfo[BUFFERSIZE] { 0 };// 以下code在 DriverEntry 中DWORD dwPE 0; // Protection Enable cr0[0]DWORD dwWP 0; // Write Protect cr0[16]DWORD dwPG 0; // Paging cr0[31]DWORD dwPAE 0; // 物理地址扩展 cr4[5]DWORD dwPSE 0; // Page Size Extension cr4[4]DWORD dwCr0 0;DWORD dwCr4 0;// 注册卸载函数pDriverObj-DriverUnload driverUnload;_asm{pushad;mov eax, cr0;mov dwCr0, eax;// PE标志位and eax, 0x01;mov dwPE, eax;mov eax, cr0;// WP标志位and eax, 0x10000;mov dwWP, eax;mov eax, cr0;// PG标志位and eax, 0x80000000;mov dwPG, eax;// PAE//mov eax, cr4; 机器码如下_emit 0x0F;_emit 0x20;_emit 0xE0;mov dwCr4, eax;and eax, 0x20;mov dwPAE, eax;// PSE_emit 0x0F;_emit 0x20;_emit 0xE0;and eax, 0x10;mov dwPSE, eax;popad;}KdPrint((PE 0x%08X\r\n,dwPE));KdPrint((WP 0x%08X\r\n,dwWP));KdPrint((PG 0x%08X\r\n,dwPG));KdPrint((PAE 0x%08X\r\n,dwPAE));KdPrint((PSE 0x%08X\r\n,dwPSE));KdPrint((Cr0 0x%08X\r\n,dwCr0));KdPrint((Cr4 0x%08X\r\n,dwCr4));//----------------------------------------------------------------------------// PE标志位if (0 ! dwPE){RtlStringCchCatNA(g_szMemInfo, BUFFERSIZE, ----------------------保护模式(PE1)-------------------\r\n,BUFFERSIZE - sizeof(----------------------保护模式(PE1)-------------------\r\n));}else{RtlStringCchCatNA(g_szMemInfo,BUFFERSIZE ,----------------------实地址模式(PE0)-------------------\r\n,BUFFERSIZE - sizeof(----------------------实地址模式(PE0)-------------------\r\n));}//----------------------------------------------------------------------------// WP标志位if (0 ! dwWP){RtlStringCchCatA(g_szMemInfo,BUFFERSIZE,内存写保护(WP)开启...\r\n);}else{RtlStringCchCatA(g_szMemInfo,BUFFERSIZE,内存写保护(WP)禁止...\r\n);}//----------------------------------------------------------------------------// PG标志位if (0 ! dwPG){RtlStringCchCatA(g_szMemInfo,BUFFERSIZE,页机制(PG)启用\r\n);}else{RtlStringCchCatA(g_szMemInfo,BUFFERSIZE,页机制(PG)禁止\r\n);}//----------------------------------------------------------------------------// PAE标志位if (0 ! dwPAE){RtlStringCchCatA(g_szMemInfo,BUFFERSIZE,物理地址扩展(PAE)已开启\r\n);}else{RtlStringCchCatA(g_szMemInfo,BUFFERSIZE,物理地址扩展(PAE)未启用\r\n);}//----------------------------------------------------------------------------// PSE标志位if (0 ! dwPSE){RtlStringCchCatA(g_szMemInfo,BUFFERSIZE,页面大小扩展(PSE)已开启\r\n);}else{RtlStringCchCatA(g_szMemInfo,BUFFERSIZE,页面大小扩展(PSE)未启用\r\n);}KdPrint((%s\r\n, g_szMemInfo)); 最后看看效果运行图。Demo是在ring3层定义一个Unicoe字符串“Lthis”,然后将其虚拟地址传入ring0层ring0解析后传出对应的物理地址。 开启PAE下运行的效果 未开启PAE的运行效果 附件地址链接http://pan.baidu.com/s/1kTENdnL 密码g5j7 转载于:https://www.cnblogs.com/Lthis/p/4746795.html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/912972.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!