How to debug the BSOD with invalid memory reference, specifically, why RSI was set to 0 - windbg

My Windows 10 laptop has been BSODing recently, almost daily, around the time I am not using it (this is a work PC, so the issue happens from like 10pm to 6am). The crash dumps all look the same:
IRQL_NOT_LESS_OR_EQUAL (a)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If a kernel debugger is available get the stack backtrace.
Arguments:
Arg1: 0000000000002d30, memory referenced
Arg2: 00000000000000ff, IRQL
Arg3: 00000000000000e8, bitfield :
bit 0 : value 0 = read operation, 1 = write operation
bit 3 : value 0 = not an execute operation, 1 = execute operation (only on chips which support this level of status)
Arg4: fffff8011be4e0ff, address which referenced memory
...
DEFAULT_BUCKET_ID: WIN8_DRIVER_FAULT
BUGCHECK_STR: AV
PROCESS_NAME: System
...
LAST_CONTROL_TRANSFER: from fffff8011bf6bba9 to fffff8011bf59dc0
STACK_TEXT:
fffff801`1dc625c8 fffff801`1bf6bba9 : 00000000`0000000a 00000000`00002d30 00000000`000000ff 00000000`000000e8 : nt!KeBugCheckEx
fffff801`1dc625d0 fffff801`1bf6855a : 0000006b`b0e5bb5a fffff801`1dc62940 00000000`00000002 fffff801`1bf3aecc : nt!KiBugCheckDispatch+0x69
fffff801`1dc62710 fffff801`1be4e0ff : 00000000`00000000 fffff801`1bfed7b6 ffffe001`9510d010 ffffe001`97fc14f0 : nt!KiPageFault+0x51a
fffff801`1dc628a0 fffff801`1be4d31b : 00000000`00000000 00000000`00000002 00000000`00000000 00000000`00000000 : nt!PpmIdleExecuteTransition+0xc2f
fffff801`1dc62b00 fffff801`1bf5d24c : 00000000`00000000 fffff801`1c126180 fffff801`1c19c740 ffffe001`9355c080 : nt!PoIdle+0x33b
fffff801`1dc62c60 00000000`00000000 : fffff801`1dc63000 fffff801`1dc5d000 00000000`00000000 00000000`00000000 : nt!KiIdleLoop+0x2c
0: kd> .trap fffff801`1dc62710
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=0000000000000000 rbx=0000000000000000 rcx=0000000000000012
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=fffff8011be4e0ff rsp=fffff8011dc628a0 rbp=0000000000000000
r8=0000000000000000 r9=0000000000000000 r10=0000000000000000
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di ng nz na po nc
nt!PpmIdleExecuteTransition+0xc2f:
fffff801`1be4e0ff 0fb686302d0000 movzx eax,byte ptr [rsi+2D30h] ds:00000000`00002d30=??
And if I am not mistaken, I should look into why RSI was set to 0 before the fault happened. And the "u" command shows a "call qword ptr [rbp+198h]" instruction may have preceded the fault.
0: kd> ub rip L13
nt!PpmIdleExecuteTransition+0xbe3:
fffff801`1be4e0b3 4032ff xor dil,dil
fffff801`1be4e0b6 0fb686302d0000 movzx eax,byte ptr [rsi+2D30h]
fffff801`1be4e0bd a801 test al,1
fffff801`1be4e0bf 740f je nt!PpmIdleExecuteTransition+0xc00 (fffff801`1be4e0d0)
fffff801`1be4e0c1 a808 test al,8
fffff801`1be4e0c3 750b jne nt!PpmIdleExecuteTransition+0xc00 (fffff801`1be4e0d0)
fffff801`1be4e0c5 33c0 xor eax,eax
fffff801`1be4e0c7 b948000000 mov ecx,48h
fffff801`1be4e0cc 33d2 xor edx,edx
fffff801`1be4e0ce 0f30 wrmsr
fffff801`1be4e0d0 488b8518030000 mov rax,qword ptr [rbp+318h]
fffff801`1be4e0d7 458bc4 mov r8d,r12d
fffff801`1be4e0da 448b8d0c030000 mov r9d,dword ptr [rbp+30Ch]
fffff801`1be4e0e1 8b54244c mov edx,dword ptr [rsp+4Ch]
fffff801`1be4e0e5 488b8c2480000000 mov rcx,qword ptr [rsp+80h]
fffff801`1be4e0ed 4889442420 mov qword ptr [rsp+20h],rax
fffff801`1be4e0f2 ff9598010000 call qword ptr [rbp+198h]
fffff801`1be4e0f8 448be0 mov r12d,eax
fffff801`1be4e0fb 89442444 mov dword ptr [rsp+44h],eax
0: kd> u rip
nt!PpmIdleExecuteTransition+0xc2f:
fffff801`1be4e0ff 0fb686302d0000 movzx eax,byte ptr [rsi+2D30h]
fffff801`1be4e106 a801 test al,1
fffff801`1be4e108 7418 je nt!PpmIdleExecuteTransition+0xc52 (fffff801`1be4e122)
fffff801`1be4e10a a808 test al,8
fffff801`1be4e10c 7514 jne nt!PpmIdleExecuteTransition+0xc52 (fffff801`1be4e122)
fffff801`1be4e10e 41b801000000 mov r8d,1
fffff801`1be4e114 33d2 xor edx,edx
fffff801`1be4e116 418bc0 mov eax,r8d
Appreciate your guidance as to how to debug this BSOD further. My troubleshooting direction may be false, in which case I am all ears for your insights. Thanks in advance!

Related

How to set an exception using masm64?

How can i access the exception chain (SEH) using masm64?
Using masm32, I get the first exception looking into fs:[0]
But when I checked in Windbg if fs:[0] still pointed at the first exception in x64, I figured that it wasn't.
I'd like to set an exception in x64 the same way I did in x86. Is it feasible (maybe looking at gs register)?
If this is coding related then you use
ml64seh PROC FRAME:ExceptionFilter
this adds your exception handler to .PDATA section RUNTIME_FUNCTION
if this is how to find this exception handler in windbg when the exception has been raised
use !exchain command
or if you want to find it before executing a specific function use .fnent command
a sample for x64 seh and finding it in windbg is as follows
;assemble and link with
;ml64 /Zi ml64seh.asm /link /debug /entry:ml64seh /subsystem:console
.data
safeplace DWORD ?
.code
ExceptionFilter PROC
jmp Handler
ExceptionFilter ENDP
PUBLIC ml64seh
ml64seh PROC FRAME:ExceptionFilter
.ENDPROLOG
mov rax, 0
mov [rax], rax ;access violation
jmp exit
Handler::
lea rax, safeplace
mov [r8+078h], rax ; replacing rax in exception handler so access is possible
mov rax, 0
ret
Exit:
ret
ml64seh ENDP
END
run without stopping in windbg
:\>cdb -g ml64seh.exe
(2aa0.3024): Access violation - code c0000005 (first chance)
ml64seh!ml64seh+0x7:
00007ff7`0e3b1029 488900 mov qword ptr [rax],rax ds:00000000`00000000=????????????????
0:000>
it crashed and broke now locating exception handlers
0:000> .fnent .
Debugger function entry 0000020b`e36c47a8 for:
(00007ff7`0e3b1022) ml64seh!ml64seh+0x7 | (00007ff7`0e3b32b0) ml64seh!$xdatasym
BeginAddress = 00000000`00001022
EndAddress = 00000000`00001042
UnwindInfoAddress = 00000000`000032b0
Unwind info at 00007ff7`0e3b32b0, c bytes
version 1, flags 3, prolog 0, codes 0
handler routine: ml64seh!ILT+0(ExceptionFilter) (00007ff7`0e3b1005), data 0 <<<<<<<<<
0:000> !exchain
3 stack frames, scanning for handlers...
Frame 0x00: ml64seh!ml64seh+0x7 (00007ff7`0e3b1029)
ehandler ml64seh!ILT+0(ExceptionFilter) (00007ff7`0e3b1005) <<<<<<<<<<<<
Frame 0x02: ntdll!RtlUserThreadStart+0x21 (00007ffe`213c26a1)
ehandler ntdll!_C_specific_handler (00007ffe`213fc720)
0:000>
lets see if we go to the handler and return back to re access the faulting place
0:000> bp .
0:000> bp 00007ff7`0e3b1005
0:000> bl
0 e 00007ff7`0e3b1029 0001 (0001) 0:**** ml64seh!ml64seh+0x7
1 e 00007ff7`0e3b1005 0001 (0001) 0:**** ml64seh!ILT+0(ExceptionFilter)
0:000> g
Breakpoint 1 hit
ml64seh!ILT+0(ExceptionFilter):
00007ff7`0e3b1005 e916000000 jmp ml64seh!ExceptionFilter (00007ff7`0e3b1020)
0:000> g
Breakpoint 0 hit
ml64seh!ml64seh+0x7: is accessible now
00007ff7`0e3b1029 488900 mov qword ptr [rax],rax ds:00007ff7`0e3b4000=0000000000000000
0:000>
btw you can use dumpbin or linker to spit out all the unwindinfos in a specific binary using -unwindinfo switch
:\>dumpbin /unwindinfo ml64seh.exe
Microsoft (R) COFF/PE Dumper Version 14.29.30146.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file ml64seh.exe
File Type: EXECUTABLE IMAGE
Function Table (1)
Begin End Info Function Name
00000000 00001022 00001042 000032B0 ml64seh
Unwind version: 1
Unwind flags: EHANDLER UHANDLER
Size of prologue: 0x00
Count of codes: 0
Handler: 00001005 #ILT+0(ExceptionFilter)

Missing identifier name in WinDbg display

I'm inspecting a 64-bit executable using WinDbg(AMD64).
This is the assembly code that I'm assembling using ML64 to create my executable:
_data SEGMENT
b DWORD 0
a DWORD 0
_data ENDS
_text SEGMENT
main PROC
lea rax, a
mov dword ptr [rax], 1
lea rbx, b
mov dword ptr [rbx], 1
mov eax, dword ptr [rax]
add dword ptr [rbx], eax
inc eax
imul eax, dword ptr [rbx]
mov dword ptr [rbx], eax
ret
main ENDP
_text ENDS
END
And this is my ML64 command:
ml64.exe e:\Assembly\WindowsDebugging\PointersProject\PointersProject.asm /link /SUBSYSTEM:CONSOLE /ENTRY:main /DEBUG /OPT:NOREF,NOICF,NOLBR
All is well up to this point. But when I load this executable and disassemble the main function, the identifiers (a and b) are missing and I see <PERF> instead:
0:000> uf main
PointersProject!main:
00007ff7`b6211010 lea rax,[PointersProject!main <PERF> (PointersProject+0x4004) (00007ff7`b6214004)]
00007ff7`b6211017 mov dword ptr [rax],1
00007ff7`b621101d lea rbx,[PointersProject!main <PERF> (PointersProject+0x4000) (00007ff7`b6214000)]
00007ff7`b6211024 mov dword ptr [rbx],1
00007ff7`b621102a mov eax,dword ptr [rax]
00007ff7`b621102c add dword ptr [rbx],eax
00007ff7`b621102e inc eax
00007ff7`b6211030 imul eax,dword ptr [rbx]
00007ff7`b6211033 mov dword ptr [rbx],eax
00007ff7`b6211035 ret
I was expecting to see something like this instead for the LEA lines:
00000001`40001010 488d05ed2f0000 lea rax,[PointersProject!a (00000001`40004004)]
00000001`4000101d 488d1ddc2f0000 lea rbx,[PointersProject!b (00000001`40004000)]
What does <PERF> mean? Why is WinDbg not showing the identifiers ? Is it because of some optimization during the build process ? If so how do I avoid it ? Please help.

Is it the code, or is it the OS..?

MY CODE IS
.model small
.data
arr db 83h, 12h, 0F0h, 0Bh, 89h
cnt db 05h
.code
mov ax, #data
mov ds, ax
mov si, offset arr
mov cl, cnt
sub bl, bl
sub dl, dl
back:
mov al, [si]
and al, 80h
jz skip
inc bl
skip:
inc dl
inc si
dec cl
jnz back
mov ah, 4cH
int 21H
end
THE ERRORS ARE AS FOLLOWS
1.asm:1: error: attempt to define a local label before any non-local labels
1.asm:1: error: parser: instruction expected
1.asm:2: error: attempt to define a local label before any non-local labels
1.asm:9: error: comma, colon, decorator or end of line expected after operand

Windbg disassembler address resolution

I was analysing a complete memory dump and I applied Windbg uf command to see what a function does
0: kd> uf profsvc!CUserProfileService::_RegisterGPNotification
This is the part of the output. I wonder why the address in parentheses is different than the address of profsvc!CUserProfileService::_RegisterGPNotification+0x44 which should be
000007fe fb149276
but is
000007fe fb155019.
When I try to unassembled the address 000007fe fb155019 with u it points to
profsvc!CUserProfileService::_RegisterGPNotification+0x44:
I’m really puzzled, any help deeply appreciated.
OUTPUT from WinDBG
….
profsvc!CUserProfileService::_RegisterGPNotification+0x2e:
000007fe`fb14925e ba01000000 mov edx,1
000007fe`fb149263 488bc8 mov rcx,rax
000007fe`fb149266 ff157c410200 call qword ptr [profsvc!_imp_RegisterGPNotification (000007fe`fb16d3e8)]
000007fe`fb14926c 85c0 test eax,eax
000007fe`fb14926e 0f84a5bd0000 je profsvc!CUserProfileService::_RegisterGPNotification+0x44 (**000007fe`fb155019**)
profsvc!CUserProfileService::_RegisterGPNotification+0x40:
000007fe`fb149274 33db xor ebx,ebx
000007fe`fb149276 eb00 jmp profsvc!CUserProfileService::_RegisterGPNotification+0x66 (000007fe`fb149278) Branch
profsvc!CUserProfileService::_RegisterGPNotification+0x66:
000007fe`fb149278 488b0d31b00200 mov rcx,qword ptr [profsvc!WPP_GLOBAL_Control (000007fe`fb1742b0)]
000007fe`fb14927f 488d052ab00200 lea rax,[profsvc!WPP_GLOBAL_Control (000007fe`fb1742b0)]
000007fe`fb149286 483bc8 cmp rcx,rax
000007fe`fb149289 740a je profsvc!CUserProfileService::_RegisterGPNotification+0x94 (000007fe`fb149295) Branch
0: kd> u 000007fe`fb155019
profsvc!CUserProfileService::_RegisterGPNotification+0x44:
000007fe`fb155019 ?? ???
^ Memory access error in 'u 000007fe`fb155019'
This is due to optimization, see the following MSDN article:
https://msdn.microsoft.com/en-us/library/windows/hardware/ff541382(v=vs.85).aspx

Read a sector to address zero

%include "init.inc"
[org 0x0]
[bits 16]
jmp 0x07C0:start_boot
start_boot:
mov ax, cs
mov ds, ax
mov es, ax
load_setup:
mov ax, SETUP_SEG
mov es, ax
xor bx, bx
mov ah, 2 ; copy data to es:bx from disk.
mov al, 1 ; read a sector.
mov ch, 0 ; cylinder 0
mov cl, 2 ; read data since sector 2.
mov dh, 0 ; Head = 0
mov dl, 0 ; Drive = 0
int 0x13 ; BIOS call.
jc load_setup
lea si, [msg_load_setup]
call print
jmp $
print:
print_beg:
mov ax, 0xB800
mov es, ax
xor di, di
print_msg:
mov al, byte [si]
mov byte [es:di], al
or al, al
jz print_end
inc di
mov byte [es:di], BG_TEXT_COLOR
inc di
inc si
jmp print_msg
print_end:
ret
msg_load_setup db "Loading setup.bin was completed." , 0
times 510-($-$$) db 0
dw 0xAA55
I want to load setup.bin to memory address zero. So, I input 0 value to es register (SETUP_SEG = 0). bx, too. But it didn't work. then, I have a question about this issue. My test is below.
SETUP_SEG's value
0x0000 : fail
0x0010 : success
0x0020 : fail
0x0030 : fail
0x0040 : fail
0x0050 : success
I can't understand why this situation was happened. All test was carried out on VMware. Does anyone have an idea ?
I'm not sure if this is your problem, but your trying to load setup.bin in the Real Mode IVT (Interrupt Vector Table). The IVT contains the location of each interrupt, so I'm assuming that your boatloader is overwriting them when it loads setup.bin into memory! Interrupts can be sneaky and tricky, since they can be called even if you didn't call them. Any interrupt vector you overwrote will likely cause undefined behavior when called, which will cause some problems.
I suggest setting SETUP_SEG to a higher number like 0x2000 or 0x3000, but the lowest you could safely go is 0x07E0. The Osdev Wiki and Wikipedia have some helpful information on conventional memory and memory mapping.
I hope this helps!