• 驱动学习5


    5.1.2 

    直接看PAGE_SIZE的大小就可以知道当前分页的大小

    //
    // Define the page size
    //
    
    #define PAGE_SIZE 0x2000
    

    5.1.4

    驱动程序的不同函数运行在不同的进程中,DriverEntry和AddDevice函数是运行在系统进程中的(system)

    3: kd> !process sysmtem
    PROCESS 8a52a830  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
        DirBase: 0aac0020  ObjectTable: e1003e00  HandleCount: 265.
    PsGetCurrentProcess可以获得当前线程所在的进程指针(指向EPROCESS)

    可以用windbg查看这个:偏移量为0x174

       +0x174 ImageFileName    : [16]  "System"
    所以可以这样获取:

    #pragma PAGEDCODE
    VOID DisplayItsProcessName()
    {
    	PEPROCESS pEProcess = PsGetCurrentProcess();
    	PTSTR ProcessName = (PTSTR)((ULONG)pEProcess + 0x174);
    	KdPrint(("%s
    ",ProcessName));
    }

    5.1.5

    当程序的中断请求级在DISPATCH_LEVEL上(包括),程序只能使用非分页内存,否则将蓝屏

    堆中申请内存函数:

    PVOID 
      ExAllocatePool(
        IN POOL_TYPE  PoolType,
        IN SIZE_T  NumberOfBytes
        );
    
    
    对应释放内存函数:

    VOID 
      ExFreePool(
        IN PVOID  P
        );


    5.1.6 

    双向链表结构中,都需要包含LIST_ENTRY,但不一定在结构的首位,所以DDK提供了一个宏

    整个结构体的首地址=LIST_ENTRY的地址-LIST_ENTRY在整个结构体中的相对偏移

    #define CONTAINING_RECORD(address, type, field) ((type *)( 
                                                      (PCHAR)(address) - 
                                                      (ULONG_PTR)(&((type *)0)->field)))
    // 从尾部删除一个元素
    		typedef struct _MYDATASTRUCT 
    		{
    			ULONG number;
    			LIST_ENTRY ListEntry1;
    		} MYDATASTRUCT, *PMYDATASTRUCT;
    		PLIST_ENTRY pEntry = RemoveTailList(&linkListHead);
    		pData = CONTAINING_RECORD(pEntry, MYDATASTRUCT, ListEntry1);
    为了简明示例,特别把LIST_ENTRY的元素名叫个ListEntry1

    5.3 Lookaside结构

    如果驱动需要频繁从内存中申请,回收固定大小的内存,DDK提供了Lookaside对象来解决这个问题


    5.4内存系列函数

    内存复制(非重叠)

    VOID 
      RtlCopyMemory(
        IN VOID UNALIGNED  *Destination,
        IN CONST VOID UNALIGNED  *Source,
        IN SIZE_T  Length
        );
    

    内存复制(可重叠),函数内部对两个内存是否重叠进行了判断,这种判断牺牲了速度

    void RtlMoveMemory(
      __in          PVOID Destination,
      __in          const VOID* Source,
      __in          SIZE_T Length
    );
    


    填充内存

    void RtlFillMemory(
      [out]                PVOID Destination,
      [in]                 SIZE_T Length,
      [in]                 BYTE Fill
    );
    

    内存置0

    VOID 
      RtlZeroMemory(
        IN VOID UNALIGNED  *Destination,
        IN SIZE_T  Length
        );
    

    内存比较

    ULONG
      RtlEqualMemory( 
        CONST VOID  *Source1, 
        CONST VOID  *Source2, 
        SIZE_T  Length 
        );
    

    DDK提供的标准的运行时函数名都是RtlXX形式,其中,大部分是以宏的形式给出,来自wdm.h:

    #define RtlEqualMemory(Destination,Source,Length) (!memcmp((Destination),(Source),(Length)))
    #define RtlMoveMemory(Destination,Source,Length) memmove((Destination),(Source),(Length))
    #define RtlCopyMemory(Destination,Source,Length) memcpy((Destination),(Source),(Length))
    #define RtlFillMemory(Destination,Length,Fill) memset((Destination),(Fill),(Length))
    #define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))

    5.6数据类型

    DDK提供了一种新的64位整数的表示方式即

    typedef union _LARGE_INTEGER {
        struct {
            ULONG LowPart;
            LONG HighPart;
        } DUMMYSTRUCTNAME;
        struct {
            ULONG LowPart;
            LONG HighPart;
        } u;
    #endif //MIDL_PASS
        LONGLONG QuadPart;
    } LARGE_INTEGER;
    需要注意的是他是一个联合体,可以认为是LARGE_INTEGER的三个定义


    5.6.3.

    检测内存是否可读可写,在ring3用的是

    IsBadReadPtr
    IsBadWritePtr

    在ring0用的是ProbeForRead和ProbeForWrite













  • 相关阅读:
    C++——并发编程
    Poco C++——JSON解析
    #转载#我给所有新手程序员的建议
    #笔记# 如何阅读技术类书籍
    笔记:CSS hack的学习与了解…
    【笔记】CSS选择器整理(IE低版本支持性测试)
    呼吸灯效果
    ajax跨域问题-----jsonp
    【转】js里的时间函数集
    grunt与requirejs结合使用
  • 原文地址:https://www.cnblogs.com/hgy413/p/3693357.html
Copyright © 2020-2023  润新知