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