如何写方案策划书(手把手教你写方案策划书)

运行环境

主机系统:Windows 10 x64

目标系统:Windows XP sp3 x86

工具环境

虚拟机:Virtual Box

编译器:Visual Studio 2017

调试器:Windbg、OllyDBG

参考书籍

《Windows 内核设计思想》

《Windows 核心编程》

《软件调试》

参考博文

《OS 学习笔记》

《详解Windows内存分页机制》

页表机制准确的说是CPU实现的特性,由OS加以利用。网上有很多陈述页表机制的文章,但以Linux居多,Windows偏少,且很多都是理论层面借图表的阐述,或许对于科班出身的人士来说是小菜一碟,可对我等自学爱好者而言却经常是一脸懵逼的感叹!因此,萌发了动手实践的想法,经过一翻折腾,总算小有心得,就此记录于网际,希望本文能给和我一样的爱好者以帮助。本文可能存在很多歪解,请各位看官多多斧正!

本文试图解决的疑问:

页有多少个?

页每个进程都有吗?

页多大?

页放在哪里?

页如何查看?

页如何修改?

页如何隔离进程?

页在何时被使用?

从test.exe开始:

// test.exe 源码#include <iostream> int main(){ std::cin.get (); // 等待做手脚 int* p = NULL; *p = 0x89abcdef ; // 向0指针写入数据 std::cout << “Hello nullptr!\n”; // 改编自经典:) return 0;}

代码很简单不出大问题的话,编译运行敲回车直接崩溃QAQ。在默认设置的Win10(17134)cmd下可正常运行和退出,但没有打印“Hello nullptr”,在XP下报错终止,错误代码0xC0000005(访问违规)。可见Win10在异常处理上有所调整(记得《Windows核心编程》有提过在Vista之后即如此)。

有C/C 基础的码友一定记得一条原则,0x00000000为空指针,设计思想很简单,例如调用malloc返回0表示失败,如果返回0指针是可用的,那错误用什么表示呢?

我的运行结果是正常的,我承认我搞事情了,嘿嘿!

如何写方案策划书(手把手教你写方案策划书)

在动手完成空指针写入数据之前先大致了解一些基本情况,在Windbg枚举进程。

kd> !process 0 0**** NT ACTIVE PROCESS DUMP ****PROCESS 8a0e59c8 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000 DirBase: 00039000 ObjectTable: e1000d10 HandleCount: 240. Image: System PROCESS 89be5020 SessionId: 0 Cid: 05d8 Peb: 7ffd6000 ParentCid: 05e4 DirBase: 19f3c000 ObjectTable: e1e27cc8 HandleCount: 35. Image: cmd.exe PROCESS 89ba8318 SessionId: 0 Cid: 0578 Peb: 7ffde000 ParentCid: 0268 DirBase: 19f97000 ObjectTable: e1b8ef08 HandleCount: 82. Image: taskmgr.exe PROCESS 89f52c10 SessionId: 0 Cid: 07c0 Peb: 7ffde000 ParentCid: 05e4 DirBase: 1d42f000 ObjectTable: e1ba5700 HandleCount: 77. Image: OllyICE.exe PROCESS 89bfc470 SessionId: 0 Cid: 01b8 Peb: 7ffde000 ParentCid: 05d8 DirBase: 24231000 ObjectTable: e1d764b8 HandleCount: 7. Image: test.exe…

信息经过删减,留下了几个比较熟悉的进程,文中类似信息也会将无关清除,清除部分会用“…”表示,不再单独注明。

这些进程分别是:taskmgr.exe任务管理器、cmd.exe控制台、System系统进程、OllyICE.exe调试器、test.exe测试程序。

每个进程的DirBase项的16进制数可以发现以下特征:

各进程不同;

可被4096整除;

以000结尾。

如果你的显示结果与特征不符,那是另外一种模式PAE,本文不做解释。从特征上分析,可被4096整除说明是4K对齐;各进程不相同说明每个进程的起始页不同,因此得以隔离进程;000结尾说明PDE没有属性,PDE为何物见下文。

在任务管理器窗口红色框部分,是各进程使用物理内存占用大小,单位Kb,这些数都可以被4整除,所得商即该程序使用的内存页数。

当test.exe在前台时(最大化)使用了193(772K/4)页内存,在后台时(最小化)使用9(36/4)页,由此可见当程序非活动状态或需求非常少时,物理内存会归还给OS。从test.exe代码可知,程序阻塞在cin.get ()调用,基本上没什么运行需求。(切换的窗口是cmd,因test运行于此)。

经过以上分析得到一个结果,程序虚拟空间远大于物理占用,实际上程序在运行时,不会将所有内容都放入物理内存,仅将当前运行所需要的代码、数据放入物理页。

有了这些线索,我们通过实验来进一步印证。利用PROCESS项的16进制数将test.exe切换至当前环境。默认当前环境是System进程,所以查询显示信息将是System进程的。

kd>!process00…PROCESS89bfc470SessionId:0Cid:01b8Peb:7ffde000ParentCid:05d8DirBase:24231000ObjectTable:e1d764b8HandleCount:7.Image:test.exe…kd>.process/i/p89bfc470kd>gkd>rcr3cr3=24231000

使用r指令查看了cr3寄存器,显示的信息与DirBase项一致,实际上OS在后台不断的自动切换cr3,让每个进程都得到一点运行时间。

实验所需的知识点简单介绍一下(以下仅是小页面,大页面请翻阅书籍):每个进程都有一页(4K)存放一个页目录(Page Directory Entry,PDE),PDE占4K空间,分成1024项,每项4B,每项描述一个页表(Page Table Entr,PTE),PTE的高20位是基址域,低12位是属性域;PTE也占4K,同样可分成1024项,每项4B,每项描述一页(Page),Page的高20位是基址域,低12位是属性域。

根据上述可得

1024(PTE 个数)*1024(Page 个数)*4096(Page 大小)=4G(总空间);

1024(PTE 个数)*1024(Page个数)*4(描述项大小)=4M(总占用);

1024(PTE个数)*1024(Page个数)=1M(总页数);

实际总占用仅是理论值,一般程序不可能达到4M,下面实验会得到证实。

查看test.exe的PDE,我将PDE分成两部分,前512项和后512项分别进行分析,因PDE管理4G虚拟空间,但其高2G(后512项)是内核态使用,剩余低2G(前512项)由用户态使用(PAE模式用户态拥有更多的空间)。

kd>!process00…PROCESS89bfc470SessionId:0Cid:01b8Peb:7ffde000ParentCid:05d8DirBase:24231000ObjectTable:e1d764b8HandleCount:7.Image:test.exe…kd>!dd24231000l200#2423100024766067245e00670000000000000000…#242317c00000000000000000247cf06700000000…#242317f0000000002459a067000000002451e067…

PDE前512项中只有5个非空PTE,前面说过1个PTE占用4K物理内存,含1024个Page描述,也就是说1个PTE维护4M(1024*4096)空间,因此可认为OS给test.exe分配了20M(4*5)虚拟空间。

范围(4M)

#24231000

00010000

003AF000

0x00000000~0x003FFFFF

#24231004

00400000

0042D000

0x00400000~0x007FFFFF

#242317c8

7C800000

7C9B0000

0x7C800000~0x7CBFFFFF

#242317f4

7F6F0000

0x7F400000~0x7F7FFFFF

#242317fc

7FFA0000

7FFE0000

0x7FC00000~0x7FFFFFFF

进一步查看PTE索引1(第二个PTE)的内容:

kd>!process00…PROCESS89bfc470SessionId:0Cid:01b8Peb:7ffde000ParentCid:05d8DirBase:24231000ObjectTable:e1d764b8HandleCount:7.Image:test.exe…kd>!dd24231000#2423100024766067245e00670000000000000000…kd>!dd245e0000l400#245e0000244300252456c0252436d025243ee025#245e0010242af0252447002524271025244f2025#245e0020242b3025242f402524375025242b6025#245e003023fb7025242b8025240f90252423a025#245e0040243fb025241bc025241bd025242be025#245e0050242bf02524540025243c102524502025#245e006024543025248c40252470502527da8025#245e00702459e025246470250000000024708025#245e008024349025000000002444a0252454b025#245e00902450c025000000000000000000000000#245e00a02436202524523025246640252465f067#245e00b024660067246250250000000000000000…

截取部分中共41项非空Page描述(省略的都是空Page),第二个PTE管理的4M空间范围是0x00400000~0x007FFFFF,回顾OD截图在这4M范围内的大小合计是46页,这里相差5个页,原因是什么我不清楚,猜测可能是软件之间的误差,有知道的请告知!

PTE和Page的低12位是属性域,数据上对应的如025、067等,属性域其中一位描述了数据是在物理内存还是在硬盘的虚拟内存,OS通过属性域控制内存,PTE可控制4M,Page可控制4K。更多属性的内容请翻阅书籍。

kd>!process00…PROCESS89bfc470SessionId:0Cid:01b8Peb:7ffde000ParentCid:05d8DirBase:24231000ObjectTable:e1d764b8HandleCount:7.Image:test.exe…kd>!dd24231000#2423100024766067245e00670000000000000000…kd>!dd245e0000#245e0000244300252456c0252436d025243ee025…kd>!db2456c000#2456c000b9a0c14200e8242b-00006829b54100e8#2456c010d225000059c36833-b54100e8c6250000#2456c02059c3683db54100e8-ba25000059c36a01#2456c0306a0068a8c24200b9-00c34200e8823300#2456c040006847b54100e89b-25000059c356576a#2456c05000e8eeb9000059bf-a8c242008bf08bcf#2456c060e8ca3300006a0056-8bcfc705a8c24200#2456c07018ce4100e8983700-006851b54100e863

或许有人会问这些数据是什么?我们来看一张截图,看完之后自然豁然开朗……!

所谓的页内偏移就是以上数据页字节的位置,Page[0]=b9,Page[1]=a0……Page[15]=e8,偏移的范围是0~4095(4K页内)。

上文书说到:“令贵妃魏璎珞为救五阿哥永琪……”。咦!好像是走错片场了……,好吧,书接上文……。

前面分析了PDE前512项,基本清楚了含盖的内容,现在来分析PDE的后512项,我将test.exe的后512项PTE与taskmgr、cmd、System、OllyICE等4个进程的后512项PTE进行了对比,发现这些PTE只有2项不同,其它完全一致,共有414项非空PTE(含2项不同),按每项管理4M来计算(414-2)*4=1648M,可认为这些空间是所有进程共享的。

不同项和偏移如下:

kd>!process00****NTACTIVEPROCESSDUMP****PROCESS8a0e59c8SessionId:noneCid:0004Peb:00000000ParentCid:0000DirBase:00039000ObjectTable:e1000d10HandleCount:240.Image:SystemPROCESS89be5020SessionId:0Cid:05d8Peb:7ffd6000ParentCid:05e4DirBase:19f3c000ObjectTable:e1e27cc8HandleCount:35.Image:cmd.exePROCESS89ba8318SessionId:0Cid:0578Peb:7ffde000ParentCid:0268DirBase:19f97000ObjectTable:e1b8ef08HandleCount:82.Image:taskmgr.exePROCESS89f52c10SessionId:0Cid:07c0Peb:7ffde000ParentCid:05e4DirBase:1d42f000ObjectTable:e1ba5700HandleCount:77.Image:OllyICE.exePROCESS89bfc470SessionId:0Cid:01b8Peb:7ffde000ParentCid:05d8DirBase:24231000ObjectTable:e1d764b8HandleCount:7.Image:test.exe…kd>!dd00039000 c00l2#39c00000390670a640063kd>!dd19f3c000 c00l2#19f3cc0019f3c06319ffd063kd>!dd19f97000 c00l2#19f97c0019f9706319f58063kd>!dd1d42f000 c00l2#1d42fc001d42f0631d5f0063kd>!dd24231000 c00l2#24231c0024231063244b2063

kd>!process00…PROCESS89bfc470SessionId:0Cid:01b8Peb:7ffde000ParentCid:05d8DirBase:24231000ObjectTable:e1d764b8HandleCount:7.Image:test.exe…//修改之前kd>!dd24231000#2423100024766067245e00670000000000000000…//原因是没有分配页kd>!dd24766000#2476600000000000000000000000000000000000…//修改kd>!ed2476600029e3c067//修改之后kd>!dd24766000#2476600029e3c067000000000000000000000000

总结:

test.exe分析结果统计,1个PDE,5个PTE,占6个4K物理页,后512项那些PTE或复制或映射,总之这些都不属于当前进程,5个PTE所描述的是20M虚拟空间,程序仅用4M,20M是5120页,4M是1024页,急需运行的193页放入物理内存。

看雪ID:khristian

https://bbs.pediy.com/user-709052.htm

本文由看雪论坛khristian原创

热门技术文章

推荐

?? 记一次 CVE-2018-8373 利用构造过程

?? Android ro.debuggable属性调试修改(mprop逆向)

?? 简单apk脱壳工具源码

?? Office 0day(CVE-2018-0802与2017-11882)漏洞分析与利用

发表评论

登录后才能评论