_IMAGE_DOS_HEADER symbol not found - windows

I have recently installed windbg inside windows 7 in Vmware .. Installed windows SDK and Windows Symbols.
But still when I open executable "notepad.exe" inside windbg, and run the following
dt _IMAGE_DOS_HEADER command, it says symbol not found.
I have PATH set already _NT_SYMBOL_PATH=SMVSRV*c:\Symbols*http://msdl.microsoft.com/download/symbols
Tried the same on windows XP ... same issues ..
Please advice.
Thanks !

Set it to srv**http://msdl.microsoft.com/download/symbols. Despite what documentation is saying, prefix symsrv does not work for me, while srv does:
0:000> .sympath srv**http://msdl.microsoft.com/download/symbols
Symbol search path is: srv**http://msdl.microsoft.com/download/symbols
Expanded Symbol search path is: srv**http://msdl.microsoft.com/download/symbols
0:000> .reload
Reloading current modules
...................
0:000> dt _IMAGE_DOS_HEADER
ntdll!_IMAGE_DOS_HEADER
+0x000 e_magic : Uint2B
+0x002 e_cblp : Uint2B
+0x004 e_cp : Uint2B
+0x006 e_crlc : Uint2B
+0x008 e_cparhdr : Uint2B
+0x00a e_minalloc : Uint2B
+0x00c e_maxalloc : Uint2B
+0x00e e_ss : Uint2B
+0x010 e_sp : Uint2B
+0x012 e_csum : Uint2B
+0x014 e_ip : Uint2B
+0x016 e_cs : Uint2B
+0x018 e_lfarlc : Uint2B
+0x01a e_ovno : Uint2B
+0x01c e_res : [4] Uint2B
+0x024 e_oemid : Uint2B
+0x026 e_oeminfo : Uint2B
+0x028 e_res2 : [10] Uint2B
+0x03c e_lfanew : Int4B
0:000>

Related

BSOD Crash within ExAllocatePool Occasioanlly

I created a short class to work as a list/vector in kernel mode. However, I notice that sometime when calling the constructor of the class, it triggers a bug check and I cannot for the life of me understand how this is even remotely possible. Please take a look at the following constructor code.
template<typename T>
inline Kector<T>::Kector(unsigned int Counts)
{
this->Size = 0;
this->MaxLength = Counts;
this->Items = (T*)ExAllocatePool(NonPagedPoolNx, Counts * sizeof T);
}
This code generate the following bytes
fffff807`1c71c733 ba40840400 mov edx, 48440h
fffff807`1c71c738 b900020000 mov ecx, 200h
fffff807`1c71c73d e86942390000 call nt!ExAllocatePool
However, upon calling ExAllocatePool - I am hit with a sudden BSOD
rax=0000000000000000 rbx=0000000000000000 rcx=fffff80469054f40
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=fffff804687496f9 rsp=ffffb58d91863fb0 rbp=ffffb58d918640b0
r8=0000000000000001 r9=0000000000000001 r10=0000000000000000
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei ng nz na pe nc
nt!MiUnlinkNodeLargePages+0x49:
fffff804`687496f9 c644243000 mov byte ptr [rsp+30h],0 ss:0018:ffffb58d`91863fe0=??
STACK_TEXT:
ffffa501`5c180d28 fffff804`688295a9 : 00000000`0000007f 00000000`00000008 ffffa501`5c180e70 ffffb58d`91863fb0 : nt!KeBugCheckEx
ffffa501`5c180d30 fffff804`688241fb : 11fa7fff`1dba7ffb 2acaed5f`268aed5b 97675150`9b275154 ac57c3f0`a017c3f4 : nt!KiBugCheckDispatch+0x69
ffffa501`5c180e70 fffff804`687496f9 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!KiDoubleFaultAbort+0x2fb
ffffb58d`91863fb0 fffff804`6866b67d : fffff804`69054f40 00000000`00000083 00000000`00000001 00000000`00000001 : nt!MiUnlinkNodeLargePages+0x49
ffffb58d`91864100 fffff804`686cf6da : 00000000`00000000 00000000`00000000 00000000`00003cd9 00000000`00000019 : nt!MiGetLargePage+0xdd
ffffb58d`91864260 fffff804`686cf4fb : fffff804`69054f40 00000000`00000001 00000000`00000200 00000000`00000200 : nt!MiGetLargePagesDemoteAsNeeded+0x15a
ffffb58d`918642f0 fffff804`686f9e5f : 00000000`00000000 00000000`00000000 00000000`20001000 ffffb58d`91864548 : nt!MiGetLargePageChain+0xc3
ffffb58d`91864400 fffff804`686f9be6 : 00000000`00000000 ffffb58d`918645b0 00000000`00000000 00000000`00000000 : nt!MiInitializePoolCommitPacket+0x1cf
ffffb58d`91864470 fffff804`686f9a33 : 00000000`00200000 ffffb58d`91864570 ffffbc87`9b200000 00000000`00000004 : nt!MmAllocatePoolMemory+0xba
ffffb58d`91864530 fffff804`686f985c : ffffbc87`9b200000 00000000`00000001 00000000`00200000 00000000`20001000 : nt!RtlpHpEnvAllocVA+0xd3
ffffb58d`918645a0 fffff804`686faab0 : ffffbc87`93e02140 ffffbc87`0caf3648 00000000`00100000 fffff804`00000000 : nt!RtlpHpAllocVA+0xfc
ffffb58d`91864690 fffff804`686ee288 : 00000000`00200000 ffffbc87`9b200000 ffffbc87`9b200000 8b484024`5c8b4800 : nt!RtlpHpSegMgrCommit+0x110
ffffb58d`91864770 fffff804`686ef0d3 : 00000000`00000000 00000000`00000002 00000000`00000000 00000000`00200000 : nt!RtlpHpSegMgrAllocate+0x68
ffffb58d`918647d0 fffff804`686fb905 : ffffffff`ffffffff ffffbc87`93e02140 00000000`00000001 fffff807`1bc94b86 : nt!RtlpHpSegSegmentAllocate+0x2b
ffffb58d`91864830 fffff804`686fb34a : 00000000`00049000 fffff804`00000000 00000000`00000000 00000000`00000000 : nt!RtlpHpSegPageRangeAllocate+0x475
ffffb58d`918648a0 fffff804`687025d2 : 00000000`00049000 00000000`00049000 00000015`00000000 00000000`00000020 : nt!RtlpHpSegAlloc+0x5a
ffffb58d`91864900 fffff804`68e6b964 : 00000000`00000000 3c938a9f`e1067800 00000000`656e6f4e 00000000`00000000 : nt!ExAllocateHeapPool+0xa42
ffffb58d`91864a30 fffff804`686e6f1f : ffffb58d`91865790 ffffb58d`91865e80 00000000`00000064 00000000`00000000 : nt!ExAllocatePoolWithTag+0x64
ffffb58d`91864a80 fffff807`1c71c743 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!ExAllocatePool+0xf
This however, only happen once every 20 or so runs, on 2 of my machines with vastly different hardware and environment. I am flabbergasted at what could've caused this seemingly simple bsod. Would love to get any idea on the issue.

Windbg: what is the benefit of specifying pseudo register when using "dt" command

When using the "Dislay Type" command in Windbg you have the option to specify a pseudo register. This will add the base address. However it is unclear to me what the benefit is of specifying the pseudo register.
When adding the "#$teb" pseudo register:
dt ntdll!_TEB #$teb ThreadLocalStoragePointer
+0x02c ThreatLocalStoragePointer : (null)
Without adding the "#$teb" pseudo register:
dt ntdll!_TEB ThreadLocalStoragePointer
+0x02c ThreatLocalStoragePointer : Ptr32 Void
if you specify a pseudo register it will be evaluated to an address
the output will display the result of evaluation
it is like specifying an address like dt ntdll!_teb 12345678`9abcdef0
if you do not provide an evaluable expression dt will simply print the structure
example
0:001> dt ntdll!_TEB ProcessEnvironmentBlock->ProcessParameters->CommandLine #$teb
+0x060 ProcessEnvironmentBlock :
+0x020 ProcessParameters :
+0x070 CommandLine : _UNICODE_STRING "dbstk.exe"
0:001> dt ntdll!_TEB ProcessEnvironmentBlock->ProcessParameters->CommandLine
+0x060 ProcessEnvironmentBlock :
+0x020 ProcessParameters :
+0x070 CommandLine : _UNICODE_STRING
0:001>
to address comment
yes it is like casting (TEB *) 0x12345678`9abcdef
you can also use c++ expression evaluator like below on all builtin PseudoRegisters or use an address
0:001> ?? #$teb->ProcessEnvironmentBlock->ProcessParameters->CommandLine
struct _UNICODE_STRING
"dbstk.exe"
+0x000 Length : 0x12
+0x002 MaximumLength : 0x14
+0x008 Buffer : 0x000002a6`27290fb0 "dbstk.exe"
0:001> ? #$teb
Evaluate expression: 1080494329856 = 000000fb`927b1000
0:001> dt ntdll!_TEB ProcessEnvironmentBlock->ProcessParameters->CommandLine 000000fb`927b1000
+0x060 ProcessEnvironmentBlock :
+0x020 ProcessParameters :
+0x070 CommandLine : _UNICODE_STRING "dbstk.exe"
0:001>

What does inc dword ptr gs : [] doing here?

While debugging windows kernel with WinDbg,
I found following line:
inc dword ptr gs : [2EB8h]
Can someone please explain what this means?
(Intel Syntax, x86, Windows-10)
The GS segment in kernel mode (windows x64) points to the Kernel Processor Control Region (KPCR).
You can dump it with the !pcr command:
kd> !pcr
KPCR for Processor 0 at fffff802fbd73000:
Major 1 Minor 1
NtTib.ExceptionList: fffff802fd6d8000
NtTib.StackBase: fffff802fd6d9070
NtTib.StackLimit: 0000000000b0e968
NtTib.SubSystemTib: fffff802fbd73000
NtTib.Version: 00000000fbd73180
NtTib.UserPointer: fffff802fbd737f0
NtTib.SelfTib: 000000007f005000
SelfPcr: 0000000000000000
Prcb: fffff802fbd73180
Irql: 0000000000000000
IRR: 0000000000000000
IDR: 0000000000000000
InterruptMode: 0000000000000000
IDT: 0000000000000000
GDT: 0000000000000000
TSS: 0000000000000000
CurrentThread: ffffe001e41a3080
NextThread: 0000000000000000
IdleThread: fffff802fbde9740
DpcQueue: Unable to read nt!_KDPC_DATA.DpcListHead.Flink # fffff802fbd75f00
You can confirm that the KPCR really is pointed to by the GS segment register by reading the MSR (Model Specific Register) named IA32_GS_BASE (which value is 0xc0000101):
kd> rdmsr 0xc0000101
msr[c0000101] = fffff802`fbd73000
As you can see they both point, in my example, to 0xfffff802fbd73000.
The PCR is described by the KPCR structure:
kd> dt nt!_kpcr
+0x000 NtTib : _NT_TIB
+0x000 GdtBase : Ptr64 _KGDTENTRY64
+0x008 TssBase : Ptr64 _KTSS64
+0x010 UserRsp : Uint8B
+0x018 Self : Ptr64 _KPCR
+0x020 CurrentPrcb : Ptr64 _KPRCB //points to the _KPRCB member at 0x180
+0x028 LockArray : Ptr64 _KSPIN_LOCK_QUEUE
+0x030 Used_Self : Ptr64 Void
+0x038 IdtBase : Ptr64 _KIDTENTRY64
+0x040 Unused : [2] Uint8B
+0x050 Irql : UChar
+0x051 SecondLevelCacheAssociativity : UChar
+0x052 ObsoleteNumber : UChar
+0x053 Fill0 : UChar
+0x054 Unused0 : [3] Uint4B
+0x060 MajorVersion : Uint2B
+0x062 MinorVersion : Uint2B
+0x064 StallScaleFactor : Uint4B
+0x068 Unused1 : [3] Ptr64 Void
+0x080 KernelReserved : [15] Uint4B
+0x0bc SecondLevelCacheSize : Uint4B
+0x0c0 HalReserved : [16] Uint4B
+0x100 Unused2 : Uint4B
+0x108 KdVersionBlock : Ptr64 Void
+0x110 Unused3 : Ptr64 Void
+0x118 PcrAlign1 : [24] Uint4B
+0x180 Prcb : _KPRCB
As you can see the last field of the KPCR structure is another structure (not a pointer, but the structure itself) named KPRCB (which stands for Kernel Processor Control Block) at offset 0x180.
Here's the start of this structure:
kd> dt nt!_kprcb
+0x000 MxCsr : Uint4B
+0x004 LegacyNumber : UChar
+0x005 ReservedMustBeZero : UChar
+0x006 InterruptRequest : UChar
+0x007 IdleHalt : UChar
+0x008 CurrentThread : Ptr64 _KTHREAD
+0x010 NextThread : Ptr64 _KTHREAD
+0x018 IdleThread : Ptr64 _KTHREAD
+0x020 NestingLevel : UChar
+0x021 ClockOwner : UChar
+0x022 PendingTickFlags : UChar
+0x022 PendingTick : Pos 0, 1 Bit
+0x022 PendingBackupTick : Pos 1, 1 Bit
+0x023 IdleState : UChar
+0x024 Number : Uint4B
...
Above output truncated for brevity as this structure (and thus the PCR) is extremely large: the size of the PCR in windows 10 x64 is 0x8040 bytes (0x7EC0 for the KPRCB).
Given your 0x2eb8 offset in GS (which points to the PCR), we can just subtract the KPRCB offset from the PCR (0x180):
kd> ? 0x2eb8 - 0x180
Evaluate expression: 11576 = 00000000`00002d38
And then check which field is at offset 0x2d38 in the KPRCB:
0: kd> .shell -ci "dt nt!_kprcb" findstr /i 0x2d38
+0x2d38 KeSystemCalls : Uint4B
(note: you can just dt nt!_kprcb and look at offset 0x2d38).
So, the incremented field in your example is named KeSystemCalls and is a 32-bit field (Uint4B) as shown in your code.
Field Usage
Searching in the IDA disassembler (ntoskrnel.exe windows 10 - x64) we have 2 hits on the 0x2eb8 value:
KiSystemCall64
VslpDispatchIumSyscall
The first one is the "normal" syscall dispatcher while the second one is the syscall dispatcher for IUM processes (aka Trustlets).
In both of these functions the use of the field is exactly the same (example in KiSystemCall64):
.text:0000000140187360 call r10 ; perform syscall
.text:0000000140187363
.text:0000000140187363 loc_140187363:
.text:0000000140187363 inc dword ptr gs:2EB8h ; increment syscall counter
So this field is simply a monotonic counter for the number of system calls that happened since the system boot.
This Answer is Just an Extension to Nietsa's answer
Apart From Being used to Create Process->cookie
KeSystemCalls member in poi(nt!KiProcessorBlock) Structure
kd> ?? ##masm(poi(nt!KiProcessorBlock)) == #$prcb
bool true
kd> ? #$pcr
Evaluate expression: -2104316928 = 8292ac00
kd> ? #$pcr+120
Evaluate expression: -2104316640 = 8292ad20
kd> ? #$prcb
Evaluate expression: -2104316640 = 8292ad20
kd> ? poi(nt!KiProcessorBlock)
Evaluate expression: -2104316640 = 8292ad20
is also used to provide the performance counter values for
"\system\System Calls/sec" data
C:\>powershell -c "&{get-counter -counter \"\System\System Calls/sec\"}"
Timestamp CounterSamples
144196.186791101
if one follows the pdh api
s = PdhCollectQueryData(hQuery);
one can observe the calls to NtQueryInformationSystem with SYSTEM_INFO_CLASS 2 == SystemPerformanceInformation which Leads to nt!ExpQuerySystemInformation on the kernel side filling the information from KPRCB
kd> # \+590h nt!ExpQuerySystemInformation l 600
nt!ExpQuerySystemInformation+0x57f:
82a01d73 038290050000 add eax,dword ptr [edx+590h]
kd> ?? #FIELD_OFFSET(nt!_KPRCB , KeSystemCalls)
long 0n1424
kd> ? 0n1424
Evaluate expression: 1424 = 00000590 <<<< (windows 7 sp2 32 bit )

Does the CPU really pause during assembly debugging?

I've been learning x64 assembly language and, as in other languages, I can throw a breakpoint in when debugging and step through the program. The breakpoint is said to pause program execution and the debugging utility even displays which values are in the CPU registers at the given point in time. However, how is it possible that the values are the real values given there are many other programs running on the computer which must be using the same CPU registers to execute when I'm debugging? Are these values actually not in the CPU when the program is paused during debugging? Thanks.
Update: Windows 10 user mode code.
The operating system is scheduling threads based on various information like priority, processor affinity etc. When the OS decides to give another thread the chance to run, that's called a Context switch (Wikipedia). During the context switch, the operating system will save the current thread's registers and then restore the new thread's registers.
Internally, the operating system needs to maintain all that information. You can easily have 1000 threads, so the OS must have 1000 times all the registers somewhere in memory.
You can safely use a user mode debugger and have a look at the kernel structures. Since you're on Windows, I'll use windbg, which is part of the Debugging Tools for Windows.
In order to follow, start any program (notepad is always a good candidate) and attach WinDbg (F6).
First, let's get the correct information from Microsoft:
0:000> .symfix
0:000> .reload /f
Those commands will make sure that we have the correct symbols (PDBs).
Next, let's look at a kernel thread (not at the user mode part of the thread, since the kernel schedules it):
0:000> dt nt!_KTHREAD
+0x000 Header : _DISPATCHER_HEADER
+0x010 CycleTime : Uint8B
+0x018 HighCycleTime : Uint4B
+0x020 QuantumTarget : Uint8B
+0x028 InitialStack : Ptr32 Void
[...]
+0x1b8 WaitPrcb : Ptr32 _KPRCB
[...]
+0x1f4 ThreadCounters : Ptr32 _KTHREAD_COUNTERS
+0x1f8 XStateSave : Ptr32 _XSTATE_SAVE
As we can see, the information to maintain a thread is quite large (0x1f8+4 or 508 bytes).
If you read the Wikipedia article, you found out:
This is usually stored in a data structure called a process control block (PCB) or switchframe.
That's the _KPRCB structure at offset 1b8. Let's look at that one:
0:000> dt nt!_KPRCB
ntdll!_KPRCB
+0x000 MinorVersion : Uint2B
+0x002 MajorVersion : Uint2B
+0x004 CurrentThread : Ptr32 _KTHREAD
+0x008 NextThread : Ptr32 _KTHREAD
[...]
+0x3658 Context : Ptr32 _CONTEXT
+0x365c ContextFlags : Uint4B
+0x3660 ExtendedState : Ptr32 _XSAVE_AREA
Given we switch the context, let's assume that _CONTEXT is the right thing to look at.
0:000> dt nt!_CONTEXT
+0x000 ContextFlags : Uint4B
+0x004 Dr0 : Uint4B
+0x008 Dr1 : Uint4B
+0x00c Dr2 : Uint4B
+0x010 Dr3 : Uint4B
+0x014 Dr6 : Uint4B
+0x018 Dr7 : Uint4B
+0x01c FloatSave : _FLOATING_SAVE_AREA
+0x08c SegGs : Uint4B
+0x090 SegFs : Uint4B
+0x094 SegEs : Uint4B
+0x098 SegDs : Uint4B
+0x09c Edi : Uint4B
+0x0a0 Esi : Uint4B
+0x0a4 Ebx : Uint4B
+0x0a8 Edx : Uint4B
+0x0ac Ecx : Uint4B
+0x0b0 Eax : Uint4B
+0x0b4 Ebp : Uint4B
+0x0b8 Eip : Uint4B
+0x0bc SegCs : Uint4B
+0x0c0 EFlags : Uint4B
+0x0c4 Esp : Uint4B
+0x0c8 SegSs : Uint4B
+0x0cc ExtendedRegisters : [512] UChar
So yes, there they are: the registers.
And, know what? Seems I attached to a 32 bit process, so you probably got different results. Anyway, try again and you'll get:
0:000> dt nt!_CONTEXT
+0x000 P1Home : Uint8B
+0x008 P2Home : Uint8B
+0x010 P3Home : Uint8B
+0x018 P4Home : Uint8B
+0x020 P5Home : Uint8B
+0x028 P6Home : Uint8B
+0x030 ContextFlags : Uint4B
[...]
+0x078 Rax : Uint8B
+0x080 Rcx : Uint8B
+0x088 Rdx : Uint8B
+0x090 Rbx : Uint8B
+0x098 Rsp : Uint8B
+0x0a0 Rbp : Uint8B
+0x0a8 Rsi : Uint8B
+0x0b0 Rdi : Uint8B
+0x0b8 R8 : Uint8B
+0x0c0 R9 : Uint8B
[...]
+0x280 Xmm14 : _M128A
+0x290 Xmm15 : _M128A
+0x300 VectorRegister : [26] _M128A
+0x4a0 VectorControl : Uint8B
+0x4a8 DebugControl : Uint8B
+0x4b0 LastBranchToRip : Uint8B
+0x4b8 LastBranchFromRip : Uint8B
+0x4c0 LastExceptionToRip : Uint8B
+0x4c8 LastExceptionFromRip : Uint8B
Summary: the kernel creates as many "objects" of type _CONTEXT as needed where it maintains the registers. Whenever a context switch shall happen, the kernel saves the current registers and restores other ones.
When debugging, your thread is suspended, so it will not run on the CPU. The CPU can also not be halted, because you need to be able to interact with the debugger. The CPU is executing instructions of the debugger. However, the debugger will give the information from _KTHREAD to you.
That's all quite simplified, but maybe enough for the moment. There are things like software and hardware context switches (read at OSWiki) and other things. It's certainly also interesting how the kernel gets its registers before it restores other user mode registers etc., but that's too much for a SO post.

Debugging a NotificationEvent in Kernel Debug (Windows)

I'm debugging a process which is like frozen:
I suspect the root cause is the thread below THREAD 877f4030 Cid 0568.0fb8 that is stuck on the user-mode call to GetOverlappedResult.
I have opened the dump with kd.exe.
Namely, I'm interested into knowing more about the NotificationEvent which obviously is never releasing our thread.
In the thread info we have:
879f6fdc NotificationEvent
In what type should I cast address 879f6fdc ? or in which structure field should I search for it, so as to understand, or have a clue to what is blocking the situation ?
As far as the Thread Infos goes, this thread currently does not list any IRP that would be in undesired or unfinished state.
Below entire Thread Information for the corresponding thread:
THREAD 877f4030 Cid 0568.0fb8 Teb: 7ff3d000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
879f6fdc NotificationEvent
Not impersonating
DeviceMap 89809fc8
Owning Process 87950030 Image: OurProduct.exe
Attached Process N/A Image: N/A
Wait Start TickCount 1472232 Ticks: 5394 (0:00:01:24.146)
Context Switch Count 2791788 IdealProcessor: 0
UserTime 00:00:06.848
KernelTime 00:00:09.890
Win32 Start Address MSVCR120!_threadstartex (0x721fbfb4)
Stack Init 8c761fd0 Current 8c761bc8 Base 8c762000 Limit 8c75f000 Call 0
Priority 8 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
Kernel stack not resident.
ChildEBP RetAddr Args to Child
8c761be0 824cfced 877f4030 00000000 8ab36120 nt!KiSwapContext+0x26 (FPO: [Uses EBP] [0,0,4])
8c761c18 824ceb4b 877f40f0 877f4030 879f6fdc nt!KiSwapThread+0x266
8c761c40 824c856f 877f4030 877f40f0 00000000 nt!KiCommitThreadWait+0x1df
8c761cb8 8267ae07 879f6fdc 00000006 826bca01 nt!KeWaitForSingleObject+0x393
8c761d20 8248f8a6 00001018 00000000 00000000 nt!NtWaitForSingleObject+0xc6
8c761d20 774f7094 00001018 00000000 00000000 nt!KiSystemServicePostCall (FPO: [0,3] TrapFrame # 8c761d34)
09f9f61c 774f6a24 758b179c 00001018 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
09f9f620 758b179c 00001018 00000000 00000000 ntdll!NtWaitForSingleObject+0xc (FPO: [3,0,0])
09f9f68c 758b7841 00001018 ffffffff 00000000 KERNELBASE!WaitForSingleObjectEx+0x98 (FPO: [Non-Fpo])
09f9f6a0 758cb9e1 00001018 ffffffff 064f3d10 KERNELBASE!WaitForSingleObject+0x12 (FPO: [Non-Fpo])
09f9f6b8 745be159 00001018 0639ee0c 09f9f6ec KERNELBASE!GetOverlappedResult+0x57 (FPO: [Non-Fpo])
What is the correct way to proceed and know which event or synchronisation mechanism is faulting ?
some commands on the NotificationEvent address:
0: kd> !object 879f6fdc
879f6fdc: Not a valid object (ObjectType invalid)
0: kd> dt nt!_KEVENT 879f6fdc
+0x000 Header : _DISPATCHER_HEADER
and then:
0: kd> dt nt!_DISPATCHER_HEADER 879f6fdc
+0x000 Type : 0 ''
+0x001 TimerControlFlags : 0 ''
+0x001 Absolute : 0y0
+0x001 Coalescable : 0y0
+0x001 KeepShifting : 0y0
+0x001 EncodedTolerableDelay : 0y00000 (0)
+0x001 Abandoned : 0 ''
+0x001 Signalling : 0 ''
+0x002 ThreadControlFlags : 0x4 ''
+0x002 CpuThrottled : 0y0
+0x002 CycleProfiling : 0y0
+0x002 CounterProfiling : 0y1
+0x002 Reserved : 0y00000 (0)
+0x002 Hand : 0x4 ''
+0x002 Size : 0x4 ''
+0x003 TimerMiscFlags : 0 ''
+0x003 Index : 0y0
+0x003 Processor : 0y00000 (0)
+0x003 Inserted : 0y0
+0x003 Expired : 0y0
+0x003 DebugActive : 0 ''
+0x003 ActiveDR7 : 0y0
+0x003 Instrumented : 0y0
+0x003 Reserved2 : 0y0000
+0x003 UmsScheduled : 0y0
+0x003 UmsPrimary : 0y0
+0x003 DpcActive : 0 ''
+0x000 Lock : 0n262144
+0x004 SignalState : 0n0
+0x008 WaitListHead : _LIST_ENTRY [ 0x877f40f0 - 0x877f40f0 ]
from a former investigation I remember that if +0x003 DpcActive was 1, it would mean we'd be waiting for some hardware operation to put it to 0. But in this case it is 0.
So right now, I just don't know what this NotificationEvent is waiting for.
Any idea ?
Events do not wait, Threads do. NotificationEvents are signaled by whoever would perform the operation and then notify the the waiters about the completion of the operation. In other words your stack is an example of a Async IO where we pass an overlapped structure with an hEvent set. reference https://msdn.microsoft.com/en-us/library/windows/desktop/ms684342(v=vs.85).aspx
You should be inspecting the source which has scheduled this IO or the type of IO we are waiting for instead of dumping out the event. The event will be signaled when the operation is completed.

Resources