day_log 12月份的

12.10

_IO_STACK_LOCATION的

UCHAR MajorFunction;
UCHAR MinorFunction;
UCHAR Flags;
UCHAR Control;

字段作用

MajorFunction:
该字段定义了一个函数功能集,内核模式驱动可以实现其中的每一个函数。每一个函数由一个函数代码对应
当内核模式驱动接收到一个IRP时,驱动首先检查当前StackLocation中的MajorFunction字段,得出驱动将要执行的功能,可能的MajorFunction功能代码如下:
#define IRP_MJ_CREATE 0x00
#define IRP_MJ_CREATE_NAMED_PIPE 0x01
#define IRP_MJ_CLOSE 0x02
#define IRP_MJ_READ 0x03
#define IRP_MJ_WRITE 0x04
#define IRP_MJ_QUERY_INFORMATION 0x05
#define IRP_MJ_SET_INFORMATION 0x06
#define IRP_MJ_QUERY_EA 0x07
#define IRP_MJ_SET_EA 0x08
#define IRP_MJ_FLUSH_BUFFERS 0x09
#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a
#define IRP_MJ_SET_VOLUME_INFORMATION 0x0b
#define IRP_MJ_DIRECTORY_CONTROL 0x0c
#define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d
#define IRP_MJ_DEVICE_CONTROL 0x0e
#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f
#define IRP_MJ_SHUTDOWN 0x10
#define IRP_MJ_LOCK_CONTROL 0x11
#define IRP_MJ_CLEANUP 0x12
#define IRP_MJ_CREATE_MAILSLOT 0x13
#define IRP_MJ_QUERY_SECURITY 0x14
#define IRP_MJ_SET_SECURITY 0x15
#define IRP_MJ_POWER 0x16
#define IRP_MJ_SYSTEM_CONTROL 0x17
#define IRP_MJ_DEVICE_CHANGE 0x18
#define IRP_MJ_QUERY_QUOTA 0x19
#define IRP_MJ_SET_QUOTA 0x1a
#define IRP_MJ_PNP 0x1b
#define IRP_MJ_PNP_POWER IRP_MJ_PNP // Obsolete....
#define IRP_MJ_MAXIMUM_FUNCTION 0x1b

MinorFunction
MinorFunction提供了MajorFunction更详细的信息

Flags
Flags提供了函数期望驱动执行的附加信息
Control
当内核驱动异步处理IRP时,驱动可以通过调用IoMarkIrpPending()将IRP标记为Pending状态,以排队IRP处理。IoMarkIrpPending实际上只是将当前Stack Location的Control字段设定为SL_PENDING_RETURNED。内核驱动可以检查该字段查询是否有该标记。

12.12

1.结构化异常处理例程,对内核态地址读写异常是无法防止BSOD的

2.ProbeForRead无法校验用户态地址是否合法

3.上个模式是内核模式时,ProbeForRead不做任何检查

4.PorbeForWrite是传入长度0时,不做校验

以下转自MJ0011百度空间:

很多安全防御软件在进行用户态内存的校验时,会使用 ProbeForRead函数,这个函数的源代码如下:

   if (Length != 0) {
        if (((ULONG_PTR)Address & (Alignment - 1)) != 0) {
            ExRaiseDatatypeMisalignment();

        } else if ((((ULONG_PTR)Address + Length) > (ULONG_PTR)MM_USER_PROBE_ADDRESS) ||
                   (((ULONG_PTR)Address + Length) < (ULONG_PTR)Address)) {

            *(volatile UCHAR * const)MM_USER_PROBE_ADDRESS = 0;
        }
    }

我们可以看到它实际做了这么两件事:

1.检查缓存长度不为0后,检查内存是否按指定的字节数对其

2.检查整个缓存区是否位于用户态内存范围内

这两个检查任意一个不成功,该函数都会引发一个异常。

12.13

驱动访问用户态无效地址会BSOD,SEH可以防止。

除了ProbeForRead、ProbeForWrite等检查外,还要看看BufferLength是否为0。

MmIsAddressVaild会检查读写这一页内存是否会发生异常。

ProbeForRead不会进行读操作,ProbeForWrite会进行读写操作。

12.20

ms_exc.disabled置为1时,为有效

为-1时,无效

ms_exc.disabled代表被_try\_except包起来的代码

原文地址:https://www.cnblogs.com/ywledoc/p/2812102.html