码迷,mamicode.com
首页 > 其他好文 > 详细

YJX_Driver_033_驱动中的内存管理

时间:2016-04-09 18:44:41      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:

1、

驱动中的内存管理
  A、 物理内存
  B、 虚拟内存
  C、 Ring0地址和Ring3地址
  D、 驱动程序和进程的关系
  E、 分页和非分页内存
  F、 分配内核内存

 

【120】了解两个概念:物理内存  虚拟内存

【140】以下概念针对 32位Windows操作系统(32位及以上的CPU)(32位 / 64位 CPU)

【210】64位下的这些概念 略有区别

【240】

A、物理内存:(Physical Memory Address)

  目前主流的操作系统还是32位的XP,而32位的系统提供的寻址能力是2^32个字节,用户最多可以使用4GB的真实物理内存。0-0xFFFFFFFF 2G+0.5G+0.1 (2.75-3.25) 2G

  【310】64位 理论寻址能力 2^64个字节

  【420】"物理内存"是一个总称。我们配备了 2G的内存,0.5G的显存,还有硬盘上的缓存0.1G,这些都是 物理内存,都会被映射到相应的地址。【565】也就是说 物理内存 是我们配备的 内存,显存,其他设备配置的一些内存  统统加起来,才是我们真是的物理内存。一般是这样的。

 

【645】

B、虚拟内存:(Virtual Memory Address)

  虽然可以寻址4GB的内存,但在PC里往往没有如此多的真实物理内存,现在的主流电脑一般是2G左右内存,操作系统和硬件提供了虚拟内存的概念。

  虚拟内存的作用:
    1、不管PC是否有足够的物理内存,操作系统总会有4GB的虚拟内存。这就允许使用者申请更多的内存,当物理内存不够的时候,可以通过将不常用的虚拟内存页交换成页面文件,等需要的时候再去读取。
    2、不同进程的虚拟内存互不干扰,为了让系统可以同时运行不同的进程,Windows操作系统让每个进程看到的虚拟内存都不同,这个方法就使不同的进程会有不同的物理内存到虚拟内存的映射。例如 进程A和进程B的内存地址 0x400123会完全不同。修改进程A的这个地址,不会影响到进程B,因为A进程的这个地址可能映射的是一段物理内存地址,而B进程是映射的另一段物理内存地址.

  【900】虚拟内存 设置的地方

  【1080】ZC: 这里的 虚拟内存的第2个作用,貌似是 分段/分页 的作用吧,并非 虚拟内存的作用 吧?

 

【1220】

C、Ring0地址和Ring3地址
  用户模式地址:
    在32位Windows操作系统中,把虚拟内存4GB的低2GB也就是虚拟地址0-0x7FFFFFFF这个范围的地址 划给 用户模式。

  内核模式地址:
    而0x80000000-0xFFFFFFFF之间虚拟内存划给 内核模式,也就是高2GB.Windows系统还规定在用户态(Ring3层)的程序,只能访问用户模式地址,而在内核态(Ring0层)的程序,可以访问整个4GB虚拟内存,即用户模式和内核模式的地址。

【1500】

D 、Windows驱动程序和进程的关系
  驱动可以看成是一个特殊的DLL函数库,只不过加载的地址是内核模式地址,只是这个DLL可以访问整个4GB的虚拟内存。

  再来看看驱动和进程的关系:
    Window驱动程序里的不同例程运行在不同的进程中。DriverEntry例程是运行在系统(System)进程中,而其它的例程如IRP_MJ_READ,IRP_MJ_WRITE,IRP_MJ_IRP_MJ_CREATE 及IRP_MJ_DEVICE_CONTROL之类的例程则运行于某个进程的环境中,所能访问的虚拟是这个进程的虚拟地址.

  【1520】驱动,∵它是不能独立运行的,一般它要通过用户层 exe的程序来载入它

    ZC: 这个说的片面了啊

  【1700】DriverEntry例程 可能很多人认为是运行在 我们的载入驱动的exe进程中,其实不是这样的,它是运行在系统(System)进程中

  【1865】ZC: "某个进程" 指 哪个进程?

  【1890】举个例子。比如 我们启动了 test_exe.exe,用它来载入了驱动,那么的话,并且用它来发送相应的IRP信息 进入我们的驱动,那么相应的驱动代码就是运行在 这个进程里面

    ZC: IRP_MJ_READ、IRP_MJ_WRITE、IRP_MJ_CREATE等 应该是运行于 发送它们的进程中。并不一定是载入驱动的进程。 

  【1980】那么 怎么来区分它运行于某一个进程环境里呢(ZC: 应该是说“怎么来区分它运行于哪一个进程环境里呢”吧?)

2、

第32课中的代码
// 如果是被保护的PID,则拒绝访问,并将句柄设置为空

          if(PID == MyPID)
          {
            KdPrint(("被保护进程 MyPID=%d \n",(int)MyPID));
            //调试输出 类似C语言的 Printf
            ProcessHandle = NULL; //这个是关键
            rc = STATUS_ACCESS_DENIED; //这个返回值
            //PsLookupProcessByProcessId((ULONG)PID,&EP);
            EP=PsGetCurrentProcess(); //获取当前进程的相关信息
            KdPrint((" ACESS Process Name --:%s-- \n",(PTSTR)((ULONG)EP+0x174))); //pid +0x84
          }

E、分页和非分页内存
  前边介绍了虚拟内存页和物理内存页之间的关系,Windows规定有些虚拟内存页面是可以交换到文件中的,这类内存被称为分页内存。而有些虚拟内存页永远不会交换到文件中,这种内存称为非分页内存。

  在编译驱动时,可以指定某个例程和某个全局变量是载入分页内存还是非分页内存。

在mini_ddk中我们也定义了这样的分页宏

#include "ctl_code.h"
#include <windef.h>
#define INITCODE code_seg("INIT") //此标志的内存在使用一次后 会及时的释放掉 节省不少内存data_seg
#define PAGECODE code_seg("PAGE") /*表示内存不足时,可以被置换到硬盘*/
#define PAGEDATA data_seg("PAGE") //定义变量和数据用的


#pragma INITCODE extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING B) //TYPEDEF LONG NTSTATUS
#pragma PAGECODE
NTSTATUS ddk_DispatchRoutine_CONTROL(IN PDEVICE_OBJECT pDevobj,IN PIRP pIrp)

注:当中断请求级别在DISPATCH_LEVEL及之上时程序只能使用 非分页内存 ,否则会蓝屏死机 加上此宏PAGED_CODE()可判断。

F、分配内核内存
  Windows驱动程序使用的内存资源非常珍贵,分配内存时要尽量节约。和应用程序一样,局部变量是放在栈(Stack)空间中的,但栈空间不会像应用程序那么大,所以驱动程序不适合递归或者局部变量是大型结构体。如果需要大型结构体,一般使用Heap中申请。

  因为在内核中分配内存 所以New Delete这类操作符 或者malloc这类分配内存的方法都不可用了。

用户态

int *pi=(int*)malloc(sizeof(int));
int *pi=(int*)new int;

内核态要用

int *pi=(int*)ExAllocatePool(PagedPool,sizeof(int));

 

暂时讲到这里 下节课我们详细的测试 各个内存相关的 内核API

  1000 物理地址

  PEPROCESS

            int ep=(int)PsGetCurrentProcess();
              ULONG* pid=(ULONG*)(ep+0x84);//Xp系统下的进程ID偏移
              PTSTR pname=(PTSTR)(ep+0x174);//Xp系统 进程名

0: kd> dt _EPROCESS

nt!_EPROCESS
  +0x000 Pcb : _KPROCESS
  +0x06c ProcessLock : _EX_PUSH_LOCK
  +0x070 CreateTime : _LARGE_INTEGER
  +0x078 ExitTime : _LARGE_INTEGER
  +0x080 RundownProtect : _EX_RUNDOWN_REF
  +0x084 UniqueProcessId : Ptr32 Void //进程PID 不同系统下 这个偏移不同 2000 +0 2003 +0x094
  +0x088 ActiveProcessLinks : _LIST_ENTRY
  +0x090 QuotaUsage : [3] Uint4B
  +0x09c QuotaPeak : [3] Uint4B
  +0x0a8 CommitCharge : Uint4B
  +0x0ac PeakVirtualSize : Uint4B
  +0x0b0 VirtualSize : Uint4B
  +0x0b4 SessionProcessLinks : _LIST_ENTRY
  +0x0bc DebugPort : Ptr32 Void
  +0x0c0 ExceptionPort : Ptr32 Void
  +0x0c4 ObjectTable : Ptr32 _HANDLE_TABLE
  +0x0c8 Token : _EX_FAST_REF
  +0x0cc WorkingSetLock : _FAST_MUTEX
  +0x0ec WorkingSetPage : Uint4B
  +0x0f0 AddressCreationLock : _FAST_MUTEX
  +0x110 HyperSpaceLock : Uint4B
  +0x114 ForkInProgress : Ptr32 _ETHREAD
  +0x118 HardwareTrigger : Uint4B
  +0x11c VadRoot : Ptr32 Void
  +0x120 VadHint : Ptr32 Void
  +0x124 CloneRoot : Ptr32 Void
  +0x128 NumberOfPrivatePages : Uint4B
  +0x12c NumberOfLockedPages : Uint4B
  +0x130 Win32Process : Ptr32 Void
  +0x134 Job : Ptr32 _EJOB
  +0x138 SectionObject : Ptr32 Void
  +0x13c SectionBaseAddress : Ptr32 Void
  +0x140 QuotaBlock : Ptr32 _EPROCESS_QUOTA_BLOCK
  +0x144 WorkingSetWatch : Ptr32 _PAGEFAULT_HISTORY
  +0x148 Win32WindowStation : Ptr32 Void
  +0x14c InheritedFromUniqueProcessId : Ptr32 Void
  +0x150 LdtInformation : Ptr32 Void
  +0x154 VadFreeHint : Ptr32 Void
  +0x158 VdmObjects : Ptr32 Void
  +0x15c DeviceMap : Ptr32 Void
  +0x160 PhysicalVadList : _LIST_ENTRY
  +0x168 PageDirectoryPte : _HARDWARE_PTE
  +0x168 Filler : Uint8B
  +0x170 Session : Ptr32 Void
  +0x174 ImageFileName : [16] UChar
  +0x184 JobLinks : _LIST_ENTRY
  +0x18c LockedPagesList : Ptr32 Void
  +0x190 ThreadListHead : _LIST_ENTRY
  +0x198 SecurityPort : Ptr32 Void
  +0x19c PaeTop : Ptr32 Void
  +0x1a0 ActiveThreads : Uint4B
  +0x1a4 GrantedAccess : Uint4B
  +0x1a8 DefaultHardErrorProcessing : Uint4B
  +0x1ac LastThreadExitStatus : Int4B
  +0x1b0 Peb : Ptr32 _PEB
  +0x1b4 PrefetchTrace : _EX_FAST_REF
  +0x1b8 ReadOperationCount : _LARGE_INTEGER
  +0x1c0 WriteOperationCount : _LARGE_INTEGER
  +0x1c8 OtherOperationCount : _LARGE_INTEGER
  +0x1d0 ReadTransferCount : _LARGE_INTEGER
  +0x1d8 WriteTransferCount : _LARGE_INTEGER
  +0x1e0 OtherTransferCount : _LARGE_INTEGER
  +0x1e8 CommitChargeLimit : Uint4B
  +0x1ec CommitChargePeak : Uint4B
  +0x1f0 AweInfo : Ptr32 Void
  +0x1f4 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
  +0x1f8 Vm : _MMSUPPORT
  +0x238 LastFaultCount : Uint4B
  +0x23c ModifiedPageCount : Uint4B
  +0x240 NumberOfVads : Uint4B
  +0x244 JobStatus : Uint4B
  +0x248 Flags : Uint4B
  +0x248 CreateReported : Pos 0, 1 Bit
  +0x248 NoDebugInherit : Pos 1, 1 Bit
  +0x248 ProcessExiting : Pos 2, 1 Bit
  +0x248 ProcessDelete : Pos 3, 1 Bit
  +0x248 Wow64SplitPages : Pos 4, 1 Bit
  +0x248 VmDeleted : Pos 5, 1 Bit
  +0x248 OutswapEnabled : Pos 6, 1 Bit
  +0x248 Outswapped : Pos 7, 1 Bit
  +0x248 ForkFailed : Pos 8, 1 Bit
  +0x248 HasPhysicalVad : Pos 9, 1 Bit
  +0x248 AddressSpaceInitialized : Pos 10, 2 Bits
  +0x248 SetTimerResolution : Pos 12, 1 Bit
  +0x248 BreakOnTermination : Pos 13, 1 Bit
  +0x248 SessionCreationUnderway : Pos 14, 1 Bit
  +0x248 WriteWatch : Pos 15, 1 Bit
  +0x248 ProcessInSession : Pos 16, 1 Bit
  +0x248 OverrideAddressSpace : Pos 17, 1 Bit
  +0x248 HasAddressSpace : Pos 18, 1 Bit
  +0x248 LaunchPrefetched : Pos 19, 1 Bit
  +0x248 InjectInpageErrors : Pos 20, 1 Bit
  +0x248 VmTopDown : Pos 21, 1 Bit
  +0x248 Unused3 : Pos 22, 1 Bit
  +0x248 Unused4 : Pos 23, 1 Bit
  +0x248 VdmAllowed : Pos 24, 1 Bit
  +0x248 Unused : Pos 25, 5 Bits
  +0x248 Unused1 : Pos 30, 1 Bit
  +0x248 Unused2 : Pos 31, 1 Bit
  +0x24c ExitStatus : Int4B
  +0x250 NextPageColor : Uint2B
  +0x252 SubSystemMinorVersion : UChar
  +0x253 SubSystemMajorVersion : UChar
  +0x252 SubSystemVersion : Uint2B
  +0x254 PriorityClass : UChar
  +0x255 WorkingSetAcquiredUnsafe : UChar
  +0x258 Cookie : Uint4B

 

YJX_Driver_033_驱动中的内存管理

标签:

原文地址:http://www.cnblogs.com/debugskill/p/5371975.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!