Windows 崩溃转储意味着在顺序指令之间更改了寄存器值
我目前正在分析由BSOD导致的客户崩溃转储。出于保密原因,我无法提供崩溃转储,但我已经走到了一条死胡同 崩溃发生在DDK内的Windows 崩溃转储意味着在顺序指令之间更改了寄存器值,windows,winapi,assembly,driver,crash-dumps,Windows,Winapi,Assembly,Driver,Crash Dumps,我目前正在分析由BSOD导致的客户崩溃转储。出于保密原因,我无法提供崩溃转储,但我已经走到了一条死胡同 崩溃发生在DDK内的RtlSetBit功能中。以下是上下文记录: rax=0000000000000000 rbx=fffff8800282da00 rcx=fffffa8007c10340 rdx=0000000000000000 rsi=0000000000000001 rdi=fffffa8007c102e0 rip=fffff8000168d0b4 rsp=fffff880057478
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
显示空值
这怎么可能?我遗漏了什么吗?执行
mov-rax,qword-ptr[rcx+8]
时,值可能是0。在bts
可以执行之前,另一个线程修改了内存中的值。然后在bts上崩溃,当查看内存时,您看到的是更新的值,而不是原始的0。您假设之前的指令执行了移动。但仅仅因为它在它之前的汇编程序中,并不一定意味着它在它之前被执行。直接跳到bts可能会导致这种不当行为
跳转的原因可能是错误的代码(不知道您是否有手写/优化的汇编程序),或者堆栈/缓冲区/数组溢出,它修改了堆栈上的返回地址,使bts成为返回地址,以及其他更模糊的错误。我认为可以安全地假设mov
执行(或试图被处决)。我提供的程序集是RtlSetBit函数的全部。我看不到任何东西会表示任何类型的溢出。@ReferentiallySethru:这与函数RtlSetBit buggy无关。它可能是整个程序中所有其他程序的跳转目标,与RtlSetBit完全无关,它只是一个随机跳转目标。如果y你没有调试器并且能够重现它,这样的错误真的很难调试。通过查看堆栈并检查调用堆栈是否正常,你可能会得到一个提示,即检查调用堆栈上之前的函数是否真的能够调用你的RtlSetBit。但这不能反驳“错误跳转”是的,调用堆栈看起来是正常的,这就是为什么我不相信“错误跳转”是罪魁祸首。我不是否认你所说的是可能的,只是在目前的情况下似乎不太可能。不过,如果我们无法进一步发展,我会记住这一点。
2: kd> dq rcx+8
fffffa80`07c10348 fffffa80`07c10338 0000000b`00000014