之前的笔记搬运
0x1 内存操作检查
在内核中不能用try catch, 可以用try \except
MmIsAddressValid 判断非分页内存是否有效(判断是否页访问异常),但是R3的内存全是分页内存
ProbeForRead ProbeForWrite, 判断内存是否可读可写, 只可以检查R3的地址,
如果不可读或不可写的话会抛一个异常, 一般和try \except配合使用
在windbg调试中有pdb却没有源文件窗口时, 用p单步几步就会出来
内核代码可以被R3的任何线程调用, 所以需要同步操作
KeEnterCriticalRegion 内核进入临界区
KeLeaveCriticalRegion 内核退出临界区
0x2 缓冲区通讯方式
驱动回调函数的调用线程正常情况下, 是调用者的现在, 但是会有几率会是其他线程,这时候如果在去访问调用者线程内存空间, 就会出现问题, 为了解决此问题,可以在调用IoCreateDevice后设置Device->Flags来决定缓冲区的通讯方式
缓冲区通讯方式:
- 缓冲区方式 2. 直接方式 3. 其他方式
缓冲区方式
1 | - pDeviceObj-\>Flags \|= DO_BUFFERED_IO |
直接方式
1 | - Device-\>Flags \|= DO_DIRECT_IO |
其他方式
不填写Flags标志位, 就默认直接使用R3的虚拟地址
0x3 控制码
R3中DeviceIoControl函数的第二个参数就是控制码
R0中MajorFunction[IRP_MJ_DEVICE_CONTROL]存放的就是回调函数指针,
控制码要定义0x800以后, 前面都被操作系统占用了
- 定义控制码
1 | CTL_CODE (设备类型, 设备码, 通讯方式, 访问权限) |
- R3使用winioctl头文件, 里面包含了R0的类型, 控制码之类的宏定义
1 | METHOD_BUFFERED: 输入输出都在systembuff里 |