崩溃转储意味着在顺序指令之间更改寄存器值

时间:2011-10-28 20:27:38

标签: windows winapi assembly driver crash-dumps

我目前正在分析来自BSOD产生的客户的故障转储。出于保密原因,我不能提供崩溃转储,但我已经走到了一个死胡同。

崩溃发生在DDK中的RtlSetBit函数中。这是上下文记录:

rax=0000000000000000 rbx=fffff8800282da00 rcx=fffffa8007c10340
rdx=0000000000000000 rsi=0000000000000001 rdi=fffffa8007c102e0
rip=fffff8000168d0b4 rsp=fffff880057478e8 rbp=0000000000000000
 r8=0000000000000000  r9=0000000000000000 r10=fffff88001e5dca0
r11=0000000000000000 r12=0000000000000000 r13=fffffa800812feb0
r14=0000000000000001 r15=fffff88003490af0
iopl=0         nv up ei pl zr na po nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
nt!RtlSetBit+0x4:
fffff800`0168d0b4 0fab10          bts     dword ptr [rax],edx ds:002b:00000000`00000000=????????

以下是RtlSetBit的汇编:

fffff800`0168d0b0 488b4108        mov     rax,qword ptr [rcx+8]
fffff800`0168d0b4 0fab10          bts     dword ptr [rax],edx << Exception
fffff800`0168d0b7 c3              ret

有些奇怪的是,正如您所看到的,rax不包含rcx+8的内容:

2: kd> dq rcx+8
fffffa80`07c10348  fffffa80`07c10338 0000000b`00000014

相反,rax显示为空。

这怎么可能?我错过了什么吗?

2 个答案:

答案 0 :(得分:4)

执行mov rax, qword ptr [rcx+8]时,该值可能为0。在bts可以执行之前,另一个线程修改了内存中的值。然后你在bts上崩溃了,当你看内存时,你会看到更新的值,而不是原始的值。

答案 1 :(得分:0)

你假设,之前的指令,移动被执行。但仅仅因为它在它之前的汇编程序中,它并不一定意味着它之前被执行。直接跳到bts可能会导致这种不当行为。

这种跳转的原因可能是错误的代码(不知道你是否有手写/优化的汇编程序),或者是堆栈/缓冲区/数组溢出,它修改了堆栈上的返回地址,并使bts成为返回地址,以及其他更隐蔽的错误。