美文网首页
windows驱动内核编程

windows驱动内核编程

作者: MagicalGuy | 来源:发表于2018-10-10 00:49 被阅读0次
    image.png

    搭建驱动开发环境 sdk10 wdk10
    win7平台 降低警告级别

    8086CPU 16位汇编
    1982年 intel退出80286处理器,第一次提出保护模式
    在保护模式下,段寄存器存储的段基址,而是段选择子

    X86体系CPU支持三种模式
    实模式:兼容16位CPU的模式
    保护模式:操作系统所在模式
    虚拟8086模式:可以模拟多个8086执行多任务

    8086处理器的段寄存器是16位,共四个:
    CS,DS,ES,SS
    32位处理器内,增加两个 FS,GS
    6个寄存器分为可见部分和不可见部分

    不可见部分存放段的基地址,范围和段属性,处理器内部使用

    段寄存器可见部分存储的值称为段选择子
    13位:描述符表索引 1位:TI 2位:RPL
    TI=0 全局描述符表GDT TI=1 局部描述符表LDT(windows系统并没有使用)

    88位描述符高速缓存寄存器

    描述符表中存放的是段描述符
    描述符有效为P位
    段限长Limit
    粒度G位 0 limit字节 1 limit4KB
    基地址字段base
    s与TYPE s=0 系统段 1代码段或数据段
    TYPE:
    0EWA 数据段 扩展方向 是否可写 访问位
    1CRA 代码段 一致性 可读 访问位

    当前执行指令位置 cs eip决定
    普通跨段跳转
    非一致性
    cpl==dpl rpl< =dpl
    一致性
    cpl>=dpl

    s = 0,type=110 调用门
    中断门 type=14
    陷阱门 15
    任务门 5

    r gdtr
    dp 地址

    jmp far 跳转到同级非一致代码段
    IDT 中断门描述符 陷阱门描述符 任务门描述符
    存放中断处理函数地址 异常处理函数地址

    DPL:描述符特权(Descriptor Privilege Level)
    存储在描述符中的权限位,用于描述代码的所属的特权等级,也就是代码本身真正的特权级。一个程序可以使用多个段(Data,Code,Stack)也可以只用一个code段等。正常的情况下,当程序的环境建立好后,段描述符都不需要改变——当然DPL也不需要改变,因此每个段的DPL值是固定。

    RPL:请求特权级RPL(Request Privilege Level)
    RPL保存在选择子的最低两位。 RPL说明的是进程对段访问的请求权限,意思是当前进程想要的请求权限。RPL的值由程序员自己来自由的设置,并不一定RPL>=CPL,但是当RPL<CPL时,实际起作用的就是CPL了,因为访问时的特权检查是判断:EPL=max(RPL,CPL)<=DPL是否成立,所以RPL可以看成是每次访问时的附加限制,RPL=0时附加限制最小,RPL=3时附加限制最大。所以你不要想通过来随便设置一个rpl来访问一个比cpl更内层的段。

    CPL:当前任务特权(Current Privilege Level)
    表示当前正在执行的代码所处的特权级。CPL保存在CS中的最低两位,是针对CS而言的。当选择子成功装入CS寄存器后,相应的选择子中的RPL就变成了CPL。因为它的位置变了,已经被装入到CS寄存器中了,所表达的意思也发生了变——原来的要求等级已经得到了满足,就是当前自己的等级。

    分页机制
    windows是通过页目录,页表(page table)与页表项(page table entry,pte)这种二级表的结构将虚拟地址转译成物理地址
    页目录表PDT 页目录项PDE 页表PTT 页表索引PTE

    页目录索引 页表索引 字节索引
    10 10 12
    虚拟页号

    实验 虚拟地址转物理地址
    查看记事本程序notepad.exe的进程信息
    !process 0 0 notepad.exe
    利用记事本的进程结构的起始地址,将windbg的当前进程切换到notepad.exe
    .process 884ead40
    搜索
    s -u 0x00000000 L0x01000000 "hello 15pb"
    查看位于本进程虚拟地址处的字符串
    du 0x007c0bd4
    查看一下notepad.exe进程页目录0x32303000
    !dd 0x32303000
    PTE位于0x32103000+0x3c04
    !dd 0x32103000+0x3c0
    4

    X86映射表分两级
    第一级:页目录表
    第二级:页表

    PTE与物理页
    PTE可以没有物理页
    PTE与物理页是多对一的关系

    PDE与PTE都是4字节的数据,结构有相似性
    P位 存在
    R/W位 R/W = 0 只读 R/W = 1可读可写
    U/S:0特权用户才能访问 1 普通用户,特权用户都能访问
    P/S:只对PDE有意义
    PS=1的时候 PDE直接指向物理页无PTE,低22位是页内偏移,所谓的大页,一页4MB
    PS=0时,指向下一级页表
    A位:只要被访问过一个字节,会被置为一
    D位:是否被写过,写过就置1

    PAE 物理扩展模式
    PAE模式相比较传统模式多了一个PDPTE,PAE模式下的PDE与PTE都变成了8字节

    驱动编程
    进程空间分为用户空间与内核空间
    驱动开发分为三类
    NT WDM WDF
    nt式驱动程序
    1包含ntddk.h文件
    2编写一个DriverEntry入口函数
    3编写一个驱动卸载函数

    NTSTATUS DriverEntry(
    PDDRIVER_OBJECT driver,//驱动对象
    PUNICODE_STRING path//路径
    )
    卸载函数
    VOID DriverUnload(PDRIEVER_OBJECT driver){}

    内核编程基础
    驱动对象 设备对象 IRP io请求包(如同windows应用程序中的MSG)
    程序 窗口 消息
    设备对象
    重要字段
    DiverObject 指出设备对象属于哪个驱动对象
    NextDevice 下一个设备对象
    AttachedDevice 指向下一层驱动程序的设备对象
    CurrentIrp 用来决策当前IRP完成还是挂起等
    DeviceExtension 指向LDR链指针

    设备对象 发送接收 IRP
    驱动对象 处理 IRP

    指定自己编写的函数所占内存的属性

    pragma alloc_text(类型,函数名)

    类型
    INIT 调用完即可释放
    PAGE 位于分页内存
    NONE_PAGE 位于非分页内存

    中断请求级别 Interrupt Request Level IRQL
    dispatch apc passive

    字符串表达方式
    RTL_CONSTANT_STRING 初始化操作

    内核api前缀
    IoXX
    ExXX
    RtlXX
    ReXX
    ZwXX
    NtXX
    内存操作
    申请内存ExAllocatePool
    拷贝内存RtlCopyeMemory
    填充内存RtlFillMemory
    释放内存ExFreePool

    相关文章

      网友评论

          本文标题:windows驱动内核编程

          本文链接:https://www.haomeiwen.com/subject/dulraftx.html