Windows 核心编程研究系列之一(-改变进程PTE属性-)[已补完]

 

Windows 核心编程研究系列之一



-改 变 进 程 PTE 属性-

 

 

         这是我研究windows 核心编程的第一篇正式文章,之所以叫核心编程而不叫内核编程,是我觉得从字面上来看核心(core)比内核(kernel)更靠近windows中心,当然只是偶本人的看法的拉。

         我们知道在 win NT 中,系统把每个进程的虚拟4G空间分为两大部份,低2G归用户所有,高2G归系统所有。用户不得访问系统的空间,连读都不行,更别说写了!低2G的用户空间也并不是都能写入的。现在我要说一个特殊的区域:在每个进程虚拟地址 0x7ffe0000 开始的一段空间称为 USER_SHARED 区域,他和虚拟地址空间0xffdf0000指向同一物理地址空间,这片区域的长度为 0x2d8。所以不同进程的这一虚拟地址空间被映射到同一个物理地址空间,如果可以写入该区域就可以实现系统中所有进程共享数据的目的,注意是所有进程!但可惜的是虽然0x7ffe0000在低2G的空间,归用户所有,但它只能读不能写,写他的后果如图1所示。

                                                   

                                                     图1

 

很不爽哦!我前不久在网上看到一篇可以读写物理内存的文章,其实现的思想是:

 

1 通过系统特权API取得 System Object PhysicalMemory 的写权限;

2 通过分析 MmGetPhysicalAddress 写出其在 ring3 下的伪代码,从而得到任意虚拟地址映射的实际物理地址

3 写入物理地址

 

我用汇编重写后好像不能实现其目的,编译运行原来VC++代码也不成功。但据作者说他可以运行成功。因为这篇文章写得较早,我怀疑是 windows 在后来的PACK中关闭了这个通道。但只是猜测,也不排除还有我未考虑到的因素,希望搞成功过的朋友谈谈具体的过程。

         我实现的是另一种方法,其主要思想是:

 

1 找到该虚拟地址在进程页表中的位置;

2 将对应页表项第2位改为1

每个进程的页表被映射到其虚拟地址空间的 0xc0000000 – 0xc003fffff 空间中。经过简单的计算后得到其页表项位置为:

0xc0000000 + 0x1FFF80 = 0xC01FFF80 察看其内容如图2所示,其最低3位决定了它存在,属于用户区域,但是只读不能写入!

                                      

                                        图2

 

我们下面要做的也非常简单,就是打开其写入标志,使其可写。

就是将 0x25 改为 0x27 。关键代码如下:

 

mov   ebx,0c01fff80h

     mov   edx,[ebx]

     mov   al,27h

     mov   byte ptr [ebx],al

     mov   eax,cr3

     mov   cr3,eax

 

通过一个 kernel driver 注入,修改成功。下面就是在ring3中修改 0x7ffe0080的内容,以下是代码:

 

mov   ebx,7ffe0080h

     mov   eax,12345678h

     mov   dword ptr [ebx],eax

 

执行结果可以用任意ring3调试器来证实,就是在调试任意程序时察看其进程地址0x7ffe0080都会发现其值被改为 0x12345678。图3是验证情况。

                                                       

 

图3

 

到这里貌似可以告一段落了,但是还有更值得挖掘的东西,那就是在ring3种直接改写高2GB的系统内核区域,下面马上将给出的是就是关于改写0x80000000 – 0xffffffff 内核区域的方法,敬请期待。

OK,让我们进入这一部分,其实有了上面的基础,这个就变得轻而易举了。但是要注意的是:

 

1 要改写的 0x80000000 – 0xffffffff 区域属于内核,可能

 

搞不要就要ODBS;

 

2 要修改的不单单是 PTE 还有页目录表项

 

 

现在我们选择写入的位置,上面说过的 0xffdf0000 ~ 0xffdf02d8 是个不错的选择,因为除了开头一段最好别碰以外,后面都是“自由”区域,写入因该没什么问题。我们首先

图4

 

要确定修改的页目录项的位置,它可以通过 0xc03000000 + 0xffc 算出等于 0xc0300ffc,如图4,将63改为67。然后再找到

 

页表项的位置,通过 0xc0000000 + 0x3FF7C0 = 0xC03FF7C0,同样的要将63改为67,关键代码为:

 

 

mov   ebx,0C0300FFCh

 

     mov   edx,[ebx]

 

     mov   al,67h

 

     mov   byte ptr [ebx],al

 

     mov   eax,cr3

 

     mov   cr3,eax

 

     mov   ebx,0C03FF7C0h

 

     mov   edx,[ebx]

 

     mov   al,67h

 

     mov   byte ptr [ebx],al

 

     mov   edx,[ebx]

 

     mov   eax,cr3

 

     mov   cr3,eax

 

    

 

That’s All Right !!!,让我们看下实际的效果,如图5所示。

图5

 

 

至此我们已经成功地在ring3中修改了用户区只读区域,和位于内核的“不可见”区域。呵呵,西游记至此终~真的终么?当然只是joke了,呵呵。

 

 

 

 

 

 

时间: 2024-10-21 16:44:23

Windows 核心编程研究系列之一(-改变进程PTE属性-)[已补完]的相关文章

[原创/讨论][windows核心编程一外传]关于访问虚拟地址0的方法。

接上一篇 Windows 核心编程研究系列之一(改变进程 PTE) 内容 上一篇观赏地址 :http://community.csdn.net/Expert/topic/5124/5124747.xml?temp=.2832453 当然系统保证不让访问地址0出于一种保护的目的,是防止未初始化的指针读取数据.我说的访问地址0只是出于一种纯实现的目的,也不提倡大家这样做.说白了只是好玩罢了. 大家都知道在 windows 中读取/写入地址0的指令肯定会出错: // 写 0 地址的内容xor edx,

《windows核心编程系列》二谈谈ANSI和Unicode字符集 .

http://blog.csdn.net/ithzhang/article/details/7916732转载请注明出处!! 第二章:字符和字符串处理     使用vc编程时项目-->属性-->常规栏下我们可以设置项目字符集合,它可以是ANSI(多字节)字符集,也可以是unicode字符集.一般情况下说Unicode都是指UTF-16.也就是说每个字符编码为两个字节.65535个字符可以表示世界上大部分的语言.为了软件使国际化大家再编程时应该使用unicode字符集.由于原来学过c语言,不习惯

018_《Delphi下深入Windows核心编程》

<Delphi下深入Windows核心编程> Delphi 教程 系列书籍 (018) <Delphi下深入Windows核心编程> 网友(邦)整理 EMail: shuaihj@163.com 下载地址: Part1 Part2 Part3     书名: Delphi下深入Windows核心编程 作者: 飞思科技产品研发中心 出版社: 电子工业出版社 书号: 7505384023 出版日期:2003年1月 开本: 787*1092 1/16 页码: 525 版次: 2003年1

《windows 核心编程》 -探索虚拟内存

14.1 系统信息 操作系统中有许多值 是由系统所运行的主机所决定的.如果页面大小和分配粒度等.我们决对不应该在代码中将这些值写死. 此函数得到系统信息VOID GetSystemInfo(LPSYSTEM_INFO ps) 如果想得到机器中与处理器有关的详细信息可以调用GetLogicalProcesorInfomation函数 为了让32位应用程序在64位版本的Windows运行,Microsoft提供了一个称为windows 32 bit On Windows 64 的模拟层又称为WOW.

请教windows核心编程 ErrorShow程序例子问题

问题描述 请教windows核心编程 ErrorShow程序例子问题 刚刚学习win32 有个问题TCHAR buffer[100]; case WM_PAINT:{ hdc = BeginPaint (hwnd &ps) ; DWORD systemLocale = MAKELANGID(LANG_NEUTRAL SUBLANG_NEUTRAL); DWORD dwError = 1; HLOCAL hlocal = NULL; BOOL fOk = FormatMessage( FORMAT

chHANDLE_DLGMSG(windows核心编程)讲解

看完<Windows程序设计>后开始看<windows核心编程>, 结果看第一个案例的时候就很惊人的发现,Jeffery大牛的代码很深奥.乍一看好像没有包含<windows.h>. 看看包含的头文件发现,CmnHdr.h中已经包含了<windows.h>.而CmnHdr.h中的代码更吓人,如果没有讲解,不知道怎么看才好.后来才知道原来书的最后有专门的搭建环境的介绍,基本上全面的讲解了CmnHdr.h的东西.   CmnHdr.h中包含了大牛的很多自己的东西.

《windows核心编程》 17章 内存映射文件

内存映射文件主要用于以下三种情况: 系统使用内存映射文件载入并运行exe和dll,这大量节省了页交换文件的空间以及应用程序的启动时间 开发人员可以使用内存映射文件来访问磁盘上的数据文件.这使得我们可以避免直接对文件IO操作和对文件内存进行缓存 进程间通讯 17.1 映射到内存的可执行文件和DLL 当一个线程调用CreateProcess的时候,系统会执行收入步骤: 1.判断exe位置,如果无法找到exe那么不会创建进程,这时会CreateProcess返回FALSE 2.创建一个新的进程内核对象

《windows核心编程》 在应用程序中使用虚拟内存

  Microsoft Windows 提供了以下三种机制来对内存进行操控: 虚拟内存 最适合用来管理大型对象数组或大型结构数组 内存映射文件 最适合用来管理大型数据流(通常是文件),以及在同一台机器上运行多个进程之间共享数据 堆 最适合管理大量小型对象   本篇只讨论第一种方式 虚拟内存. 15.1 预订地址空间区域 可以使用VirtualAlloc函数来预订进程中的地址空间区域 LPVOID WINAPI VirtualAlloc( __in_opt LPVOID lpAddress, __

《windows核心编程》–Windows内存体结构(二)

13.6页面保护属性     内存页面保护属性有 PAGE_NOACCESS.PAGE_READONLY.PAGE_READWRITE.PAGE_EXECUTE.PAGE_EXECUTE_READ.PAGE_EXECUTE_READWRITE.PAGE_WRITECOPY.PAGE_EXECUTE_WRITECOPY.这些保护分别表示什么http://127.0.0.1:47873/help/1-3788/ms.help?method=page&id=09839DB7-2118-4A7D-A70