как найти собственные исключения в стеке x64?


Я уже некоторое время использую WinDbg для отладки файлов дампа.
Есть хороший "трюк", который работает с нативными программами x86, вы можете сканировать стек на наличие флагов CONTEXT_ALL (0x1003f).

В x64 флаги CONTEXT_ALL, по-видимому, не содержат0x1003f ...

Теперь проблема в том, что иногда, когда вы смешиваете машинный код с управляемым кодом, обычные методы поиска исключений (например .акциз или .lastevent).

Что эквивалентно этому 0x1003f в x64 ? есть ли такая константа ?

Редактировать:

Кстати, если вам интересно, в теории это должно было быть 10003f из-за определений:

#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

Но это не так...

1 5

1 ответ:

Я обычно использую значения сегментного регистра для моего ключа для поиска записей контекста (ES и DS имеют одинаковое значение и находятся рядом друг с другом в структуре контекста). Однако трюк с флагами тоже аккуратен.

Принудительное исключение в тестовом приложении, а затем выкапывание структуры записи контекста из стека, похоже, что магическое значение в моем случае будет 0x10001f:

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

Также обратите внимание, что значение ContextFlags не находится в начале структуры, поэтому если вы найдете это значение вам придется вычесть @@c++(#FIELD_OFFSET (ntdll!_CONTEXT, ContextFlags)) из него получаем базу структуры контекста.

Кроме того, на всякий случай, если это не очевидно, это значение берется из выборки размером ровно один. Это может быть неправильно в вашей среде, и это, конечно, может быть изменено (как и любая конкретная реализация, такая как эта).