Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can I find native exceptions in an x64 stack?

I've been using WinDbg to debug dump files for a while now.
There's a nice "trick" that works with x86 native programs, you can scan the stack for the CONTEXT_ALL flags (0x1003f).

In x64 the CONTEXT_ALL flags apparently don't contain 0x1003f ...

Now the problem is that sometimes when you mix native with managed code, the regular methods of finding exceptions (like .exc or .lastevent).

What is the equivalent of this 0x1003f in x64 ? is there such a constant ?

EDIT:

BTW, if you were wondering, in theory it should have been 10003f because of the definitions:

#define CONTEXT_I386    0x00010000
#define CONTEXT_AMD64   0x00100000

#define CONTEXT_CONTROL             0x00000001L // SS:SP, CS:IP, FLAGS, BP
#define CONTEXT_INTEGER             0x00000002L // AX, BX, CX, DX, SI, DI
#define CONTEXT_SEGMENTS            0x00000004L // DS, ES, FS, GS
#define CONTEXT_FLOATING_POINT      0x00000008L // 387 state
#define CONTEXT_DEBUG_REGISTERS     0x00000010L // DB 0-3,6,7
#define CONTEXT_EXTENDED_REGISTERS  0x00000020L // cpu specific extensions
#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS)
#define CONTEXT_ALL (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS)

#define CONTEXT_I386_FULL CONTEXT_I386 | CONTEXT_FULL
#define CONTEXT_I386_ALL  CONTEXT_I386 | CONTEXT_ALL
#define CONTEXT_AMD64_FULL CONTEXT_AMD64 | CONTEXT_FULL
#define CONTEXT_AMD64_ALL  CONTEXT_AMD64 | CONTEXT_ALL

But it's not...

like image 896
Yochai Timmer Avatar asked Nov 05 '22 00:11

Yochai Timmer


1 Answers

I usually use the segment register values for my key to finding context records (ES and DS have the same value and are next to each other in the CONTEXT stucture). The flags trick is neat too though.

Forcing an exception in a test application then digging the context record structure off the stack, looks like the magic value in my case would be 0x10001f:

0:000> dt ntdll!_context 000df1d0
...
   +0x030 ContextFlags     : 0x10001f
...
   +0x03a SegDs            : 0x2b
   +0x03c SegEs            : 0x2b
...

Also note that the ContextFlags value is not at the start of the structure, so if you find that value you'll have to subtract @@c++(#FIELD_OFFSET(ntdll!_CONTEXT, ContextFlags)) from it to get the base of the context structure.

Also, just in case it wasn't obvious, this value comes from a sample size of exactly one. It may not be correct in your environment and it is of course subject to change (as is anything implementation specific such as this).

like image 118
snoone Avatar answered Nov 12 '22 12:11

snoone