Recently I encountered an exception while debugging an Intel® SGX powered enclave application. Interesting enough, unlike classic environment, where the point of problem is usually apparent, there wasn't much I could glean from the debugger with this particular instance of the exception. The call stack window was empty and the debugger didn't take me to the point of problem as it normally does.
This being an enclave application, as a first step, I wanted to find out where the exception was happening, as in, whether it was within the trusted environment or outside. So, I installed a custom trusted exception handler, using Intel® SGX SDK provided sgx_register_exception_handler API and ran the same application. The idea being, if the exception occurred within the trusted environment and if for some reason, the Intel® SGX Visual Studio add-on that handles the trusted debugging failed to capture the exception, I would be able to find out. The trusted custom exception handler I installed didn't get invoked. Based on that I could conclude that the trusted execution environment is unlikely to have been the triggering factor for this exception instance.
I then installed an exception handler within the untrusted application using vectored exception handling feature provided by Microsoft Win32 API AddVectoredExceptionHandler. Sure enough I hit the exception handler the next time I ran the application. I was then able to check whether the faulting address was within the enclave address range using Intel® SGX SDK provided sgx_is_within_enclave API, by invoking that API via the untrusted exception handler.
Admittedly, it was a developer error that caused the exception. In this case, by way of an attempt to access an enclave address space address. However, debuggers are designed to make it easier for developers to spot these developer errors. What made the problem all the more non-obvious was that it was happening during thread creation time. If the Intel® SGX Visual Studio add-on would include an exception handler to trap exceptions caused by access to trusted address space addresses, while running in untrusted context and provide more specific information, potentially along with information regarding the last OCALL or event that caused the transition from trusted context to untrusted, it can only make Intel® SGX applications development/porting all the more easier. An aggregate of such minor additions can only positively encourage further adoption of the technology.
Following is a demonstration of the problem described above:
I recently encountered what appears to be a very minor bug in Visual Studio 2015 Community Edition. I made some changes in a project I am working on, and navigated to the team explorer, to run a "diff" (i.e. invoke "Compare with Unmodified..." context menu) on a file I had changed. I then tried to search for a string within the solution, while I had the "diff" window open. The original file and thus the "diff" window file also happened to have the string being searched. I navigated to the "Find Result 1" window that listed the search results. I then used the "F8" shortcut to navigate through the search results, one after the other. When I reached the result pertaining to the file that had its equivalent "diff" file open, I was taken to the "diff" file as opposed to the actual file containing the search result. And once I reached that point, the "F8" shortcut stopped working and I could no more navigate through the rest of the search results using the "F8" shortcut. I had to further navigate the results using the mouse, to point at and select the next search result within the "Find Result 1" window.
Admittedly, this is a very minor bug but at times this kind of minor bug provide a window into a different underlying issue. And in this case, the fact that Visual Studio confuses between the temporary diff file and the actual file might be a clue as to there being potentially non obvious issues as well. Nevertheless, thought Visual Studio team might be interested to know.
Following is a quick demo of the bug:
Recently I encountered a BSOD on a Windows 10 Pro system. The BSOD appear to point at an Intel audio driver. I only took a cursory look at the problem as the problem neither appear to be in the stack we own nor did it impede my work or repeat itself enough to warrant any more of my time. Below is some minimal information pertaining to the crash, if it should interest relevant folks. For access to the crash dump, please use the form here to make a request or email to info_at_kryptoguard.com
Basic crash information -
This is a very common bugcheck. Usually the exception address pinpoints
the driver/function that caused the problem. Always note this address
as well as the link date of the driver/image that contains this address.
Arg1: ffffffffc0000005, The exception code that was not handled
Arg2: fffff80828e04096, The address that the exception occurred at
Arg3: fffff486e9b9a848, Exception Record Address
Arg4: fffff486e9b9a090, Context Record Address
Information pertaining to the module (in question) -
> lmvm IntcDAud
Browse full module list
start end module name
fffff808`28dc0000 fffff808`28e88000 IntcDAud (no symbols)
Loaded symbol image file: IntcDAud.sys
Image path: \SystemRoot\system32\DRIVERS\IntcDAud.sys
Image name: IntcDAud.sys
Browse all global symbols functions data
Timestamp: Wed Dec 6 10:01:50 2017 (5A28065E)
Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4
Offending stack and trap frame -
THREAD ffffce8c470a2700 Cid 0004.2d9c Teb: 0000000000000000 Win32Thread: 0000000000000000 RUNNING on processor 0
Owning Process ffffce8c3bd12440 Image: System
Attached Process N/A Image: N/A
Wait Start TickCount 34652705 Ticks: 0
Context Switch Count 42 IdealProcessor: 0
Win32 Start Address IntcDAud (0xfffff80828e3fd50)
Stack Init fffff486e9b9ad90 Current fffff486e9b99660
Base fffff486e9b9b000 Limit fffff486e9b95000 Call 0000000000000000
Priority 15 BasePriority 8 PriorityDecrement 0 IoPriority 2 PagePriority 5
Child-SP RetAddr : Args to Child : Call Site
fffff486`e9b99888 fffff800`70bc6cac : 00000000`0000007e ffffffff`c0000005 fffff808`28e04096 fffff486`e9b9a848 : nt!KeBugCheckEx
fffff486`e9b99890 fffff800`70b8dc3f : 00000000`00000003 00000000`00000000 fffff486`e9b95000 fffff486`e9b9b000 : nt!PspSystemThreadStartup$filt$0+0x44
fffff486`e9b998d0 fffff800`70bb8c0d : 00000000`00000000 fffff486`e9b99a70 fffff486`e9b99f30 00000000`00000293 : nt!_C_specific_handler+0x9f
fffff486`e9b99940 fffff800`70a6fae6 : fffff486`e9b99a70 fffff486`e9b99f30 00000000`00000004 fffff486`e9b9a848 : nt!RtlpExecuteHandlerForException+0xd
fffff486`e9b99970 fffff800`70a70f03 : fffff486`e9b9a848 fffff486`e9b9a590 fffff486`e9b9a848 00000000`00000000 : nt!RtlDispatchException+0x416
fffff486`e9b9a060 fffff800`70bc0f42 : 00000000`00000000 00000000`00000000 fffff486`e9b9a7e8 00000000`00000000 : nt!KiDispatchException+0x1f3
fffff486`e9b9a710 fffff800`70bbdabf : 00000000`00000001 fffff808`28ddd00f fffff808`28ddd048 ffffce8c`41e9c1c4 : nt!KiExceptionDispatch+0xc2
fffff486`e9b9a8f0 fffff808`28e04096 : ffffce8c`41e9c100 ffffce8c`41e9c000 00000000`00000000 fffff808`28ddd00f : nt!KiPageFault+0x3ff (TrapFrame @ fffff486`e9b9a8f0)
fffff486`e9b9aa80 fffff808`28e33053 : ffffce8c`41e9c010 fffff486`00000003 ffffce8c`41e9c720 00000000`00000000 : IntcDAud+0x44096
fffff486`e9b9aab0 fffff808`28e33870 : 00000000`00000000 fffff808`00000010 ffffce8c`41e9c2b8 00000000`00000001 : IntcDAud+0x73053
fffff486`e9b9ab40 fffff808`28e19a53 : ffffce8c`41eb3ae0 00000000`00000000 00000000`00000001 00000000`00000000 : IntcDAud+0x73870
fffff486`e9b9ab90 fffff808`28e41aa3 : 00000000`00000000 00000000`00000000 00000000`00000000 fffff808`28e3f4ac : IntcDAud+0x59a53
fffff486`e9b9abf0 fffff808`28e3f96c : ffffce8c`41ea4010 00000000`00000004 00000000`00000000 ffffce8c`3bd12440 : IntcDAud+0x81aa3
fffff486`e9b9ac40 fffff808`28e3ffdb : ffffffff`fffcf2c0 ffffffff`fffcf2c0 ffffffff`fffcf2c0 ffffffff`00000000 : IntcDAud+0x7f96c
fffff486`e9b9ac70 fffff808`28e3fd9b : ffffffff`fffcf2c0 ffffce8c`41ea4010 00000000`00000080 fffff808`28e3fd50 : IntcDAud+0x7ffdb
fffff486`e9b9ace0 fffff800`70afccb7 : ffffce8c`470a2700 fffff808`28e3fd50 ffffffff`ffffffff ffffffff`ffffffff : IntcDAud+0x7fd9b
fffff486`e9b9ad10 fffff800`70bb77d6 : fffff800`7007d180 ffffce8c`470a2700 fffff800`70afcc70 ffffffff`ffffffff : nt!PspSystemThreadStartup+0x47
fffff486`e9b9ad60 00000000`00000000 : fffff486`e9b9b000 fffff486`e9b95000 00000000`00000000 00000000`00000000 : nt!KiStartSystemThread+0x16
0: kd> .trap fffff486`e9b9a8f0
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=fffff486e9b9aaa8 rbx=0000000000000000 rcx=fffff80828ddfc00
rdx=0000000000000003 rsi=0000000000000000 rdi=0000000000000000
rip=fffff80828e04096 rsp=fffff486e9b9aa80 rbp=fffff486e9b9ab00
r8=ffffe30112900180 r9=0000000000000000 r10=0000000000000004
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
iopl=0 nv up ei pl zr na po nc
fffff808`28e04096 40387e18 cmp byte ptr [rsi+18h],dil ds:00000000`00000018=??
Preliminary analysis (tentative/based on cursory look) - It is quite possible the content (at certain offset) of the data at address fffff808`28ddd048 passed on (via RCX register) by the third Intel frame above (IntcDAud+0x73870), which when dereferenced later (at the crashing line above) maybe the cause.