虫趣:除0错误

作者:张佩】【原文: http://www.yiiyee.cn/Blog/0x7f-1/

内核之所以脆弱,是因为它没有办法很好地隔离自己。它是一个大整体,属于一荣俱荣、一损俱损的大整体。它需要一切都按部就班地执行有序。否则,一个角落里的蝴蝶扇动翅膀,就能招来太平洋上的绝大风暴。现在看到的是一个内核中的除0错误。用户程序中的除零导致进程崩溃,内核中则系统崩溃。

int AlwaysDivide (int par0)
{
Return random (100)/par0;
}

上面这个无意义的函数代码,写得很不慎重。如果输入参数par0为0的话,程序就崩溃了。Windbg的自动分析命令能够很好地检测这个类型错误:

0: kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

UNEXPECTED_KERNEL_MODE_TRAP (7f)
This means a trap occurred in kernel mode, and it's a trap of a kind
that the kernel isn't allowed to have/catch (bound trap) or that
is always instant death (double fault).  The first number in the
bugcheck params is the number of the trap (8 = double fault, etc)
Consult an Intel x86 family manual to learn more about what these
traps are. Here is a *portion* of those codes:
If kv shows a taskGate
        use .tss on the part before the colon, then kv.
Else if kv shows a trapframe
        use .trap on that value
Else
        .trap on the appropriate frame will show where the trap was taken
        (on x86, this will be the ebp that goes with the procedure KiTrap)
Endif
kb will then show the corrected stack.
Arguments:
Arg1: 00000000, EXCEPTION_DIVIDED_BY_ZERO
Arg2: 00000000
Arg3: 00000000
Arg4: 00000000

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

BUGCHECK_STR:  0x7f_0

TRAP_FRAME:  8969b7e0 -- (.trap 0xffffffff8969b7e0)
ErrCode = 00000000
eax=0000000a ebx=982834fc ecx=00000000 edx=00000000 esi=8991d698 edi=00000000
eip=a780dcb3 esp=8969b854 ebp=8969b874 iopl=0         nv up ei pl zr na pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010246

a780dcb3 f7f9            idiv    eax,ecx
Resetting default scope

DEFAULT_BUCKET_ID:  WIN7_DRIVER_FAULT

PROCESS_NAME:  svchost.exe

CURRENT_IRQL:  2

LAST_CONTROL_TRANSFER:  from 82efdd53 to 82e99768

上面自动分析文字中,红色字体醒目地指出了错误类型是除零错误:EXCEPTION_DIVIDED_BY_ZERO。

出现异常时候的一条指令是:idiv eax,ecx,此时ecx的值是0。构成了典型的除零异常。
这个BSOD的描述符是UNEXPECTED_KERNEL_MODE_TRAP。当一个异常发生的时候,系统根据异常类型,调用异常处理函数。除零异常的异常号是0:

0: kd> !idt 0

Dumping IDT: 80b95400
00: 82e5d670 nt!KiTrap00

因为这个异常是无法恢复的,所以异常处理函数最终会调用KeBugCheck2函数令系统崩溃:

STACK_TEXT:
8969b3ac 82efdd53 00000003 a93950d9 00000065 nt!RtlpBreakWithStatusInstruction
8969b3fc 82efe851 00000003 a780dcb3 8991d698 nt!KiBugCheckDebugBreak+0x1c
8969b7c0 82e5d6fb 0000007f 00000000 00000000 nt!KeBugCheck2+0x68b
8969b7c0 a780dcb3 0000007f 00000000 00000000 nt!KiTrap00+0x8b

3,524 total views, 2 views today

《虫趣:除0错误》有一个想法

  1. 你好,请问下,如果在驱动中直接call一个非法地址如0xffffffff,那么之后系统处理流程是什么样的呢?我调试了下,发现出现错误之后首先执行的是kiTrap0E函数,那么中间的过程是什么样的,能否给分析下??这个非法地址有没有被加载到EIP中去呢?

jack进行回复 取消回复

电子邮件地址不会被公开。