zoukankan      html  css  js  c++  java
  • 【原创】FltSendMessage蓝屏分析

    INVALID_PROCESS_DETACH_ATTEMPT (6)
    Arguments:
    Arg1: 00000000
    Arg2: 00000000
    Arg3: 00000000
    Arg4: 00000000

    Debugging Details:
    ------------------


    CUSTOMER_CRASH_COUNT: 2

    DEFAULT_BUCKET_ID: DRIVER_FAULT

    BUGCHECK_STR: 0x6

    PROCESS_NAME: BAVSvc.exe

    LAST_CONTROL_TRANSFER: from 80508d2f to 805376df

    STACK_TEXT:
    ba6e5be0 80508d2f 00000006 8a715818 00000000 nt!KeBugCheck+0x14
    ba6e5c00 8062cfd8 ba6e5c18 8a715818 00000000 nt!KeUnstackDetachProcess+0x118
    ba6e5c50 f745664d 8a3105e8 8a6bdbb0 00000001 nt!MmProbeAndLockProcessPages+0x6a
    ba6e5d54 ba711870 8ab61818 ba71708c e4446410 fltMgr!FltSendMessage+0x1db
    ba6e5dac 80576320 00000000 00000000 00000000 Bfilter!ScUnInitExcludePath
    ba6e5ddc 804ec7b9 ba7118a0 00000000 00000000 nt!PspSystemThreadStartup+0x34
    00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

    深入内部,看是什么条件触发的蓝屏. 分析KeUnstackDetachProcess(x)里面的关键代码片段
    .text:0041D02F cmp byte ptr [esi+165h], 0
    .text:0041D036 jz loc_431CA1
    .text:0041D03C cmp byte ptr [esi+48h], 0
    .text:0041D040 jnz loc_431CA1
    .text:0041D046 lea eax, [esi+34h]
    .text:0041D049 cmp [eax], eax
    .text:0041D04B jnz loc_431CA1
    .text:0041D051 lea eax, [esi+3Ch]
    .text:0041D054 cmp [eax], eax
    .text:0041D056 jnz loc_431CA1

    .text:00431CA1 loc_431CA1: ; CODE XREF: KeUnstackDetachProcess(x)+3Dj
    .text:00431CA1 ; KeUnstackDetachProcess(x)+47j ...
    .text:00431CA1 push 6 ; BugCheckCode
    .text:00431CA3 call _KeBugCheck@4 ; KeBugCheck(x)

    可见有四个条件导致 INVALID_PROCESS_DETACH_ATTEMPT 蓝屏,首先我们要排查是走到哪个分支出现问题.这里 esi 是存储当前线程对象的指针.
    [esi+165h] 是取线程里 ApcStateIndex 的值, 看内存的值
    0: kd> db @esi+165 l1
    8ab544ed 01
    也就是ApcStateIndex的值为1,不是因为ApcStateIndex错误导致的蓝屏,继续[esi+48h],是取线程里面ApcState->KernelApcInProgress的值,查看内存
    0: kd> db @esi+48 l1
    8ab543d0 00
    ApcState->KernelApcInProgress的值为0,不是因为ApcState->KernelApcInProgress错误导致的蓝屏, 继续分析下面指令
    .text:0041D046 lea eax, [esi+34h]
    .text:0041D049 cmp [eax], eax
    .text:0041D04B jnz loc_431CA1

    0: kd> ? @esi+34
    Evaluate expression: -1967832132 = 8ab543bc

    0: kd> dd 8ab543bc l1
    8ab543bc 8a3f6254

    eax的值为 8ab543bc, [8ab543bc]的值为 8a3f6254, cmp [eax], eax 比较结果不相等导致蓝屏.其实这里就是判断当前线程的内核APC列表是否为空,不为空的话就蓝屏了.也就是系统往我们的线程KiInsertQueueApc插入一个内核APC,导致链表不为空,在KeUnstackDetachProcess出了问题。观察线程的线程的一些APC字段,发现 KernelApcPending 的值为1,说明KiInsertQueueApc没调用到KiDeliverApc, 很可能是APC 被禁止Deliver,调用ExAcquireFastMutex就可以禁止内核APC投递.不要调用ExAcquireFastMutex应该可以解决这类问题,但现在还有一个问题: 谁会往这个调用FltSendMessage的内核线程投递APC ?内核APC的一个主要作用是从系统空间拷贝I/O操作结果和状态信息到线程虚拟内存空间的一个缓冲中,所以有可能是FltSendMessage内部同步出现BUG.导致这个函数返回后,应用层再应答数据回来,会往这个DELAY线程插APC. 这种情况最有可能是应用层扫描出现了延迟导致.

    暂时XP SP3可行的解决办法:
    1 不要在一个线程里循环调用FltSendMessage
    2 调用之前FltSendMessage不要调用ExAcquireFastMutex
    3 只利用FltSendMessage来发送异步消息,就是不用等应用层应答结果,这样系统是不会往我们线程插入APC的.

  • 相关阅读:
    c++控制台 设置字体颜色
    c 无回显读取字符/不按回车即获取字符
    C 汉字处理
    codeblocks 汉字乱码
    [转]C/C++获取当前系统时间
    锐捷认证的一些问题&解决方法
    JAVA之BigInteger(转)【转】【很好用啊】
    常用小函数——不要重复造轮子
    字符串的朴素模式和KMP模式匹配
    直接插入排序
  • 原文地址:https://www.cnblogs.com/sysnap/p/4621871.html
Copyright © 2011-2022 走看看