Встроенные кадры стека с IDebugControl5.GetContextStackTraceEx?

Как я могу разрешить символы DEBUG_STACK_FRAME_EX со встроенными кадрами?

Я в курсе DEBUG_STACK_FRAME_EX И его ULONGInlineFrameContext, но я не понимаю, как решить InlineFrameContext на соответствующий символ.

И что это FrameSignature а также FrameId в INLINE_FRAME_CONTEXT?

2 ответа

Решение

Это использует некоторые обертки, но намерение должно быть ясным. С помощью IDebugSymbols4::GetNameByInlineContext если InlineFrameContext указывает, что это встроенный фрейм, и IDebugSymbols4::GetSymbolNameByOffset в противном случае.

Пример C# ниже:

ulong displacement;
var builder = new StringBuilder(256);
var isInlineFrame = frame.InlineFrameContext.FrameType.HasFlag(StackFrameType.Inline);
if (isInlineFrame)
{
    _symbols5.GetNameByInlineContext(frame.InstructionOffset, frame.InlineFrameContext.ContextValue, ref builder, out displacement);                
}
else {
    _symbols5.GetSymbolNameByOffset(frame.InstructionOffset, ref builder, out displacement);
}
var name = builder.ToString();

InLineFrameContext только союз FrameType Определен, который является вторым байтом в ContextValue DWORD

это обычно будет 25ed0200 для встроенного кадра (в большинстве случаев я заметил, хотя это может быть b5b80200 тоже в некоторых системных dll встроенных фреймах

выход такой же, как kvf and .inline 1 (.inline enable )

если вы отключите встроенный
InlineFrameContext would be 0xffffffff

где ff is STACK_FRAME_TYPE_IGNORE

25ed / b5b8, ffff и т. Д. Подпись кадра и 00 FrameID извлекаются из символов

(если вы действительно хотите это узнать, посмотрите на колдовство dia sdk, которое загружает символы и извлекает эту подпись из pdb ( dbghelp!g+0xxxx (2360 в win10 dbghelp.dll))

какими бы они ни были, они не кажутся полезными для любой взаимосвязи с символами, и сигнатура меняется при каждом вызове или сеансе windbg, а iirc при каждом.reload /f.

даже функция OutputContextStackTraceEx, похоже, не использует сигнатуру и Id (тип используется для обозначения встроенного, если type был 02)

если вы хотите поэкспериментировать, вы можете проверить этот код (это расширение engextcpp, чтобы вы скомпилировали и загрузили его в windbg и выполнили команду, которая напечатает стек вместе с некоторым выпуском точно так же, как если бы вы issued kvf

#include <codeanalysis\warnings.h>
#pragma warning( push )
#pragma warning ( disable : ALL_CODE_ANALYSIS_WARNINGS )
#include <engextcpp.cpp>
#pragma warning( pop )
class EXT_CLASS : public ExtExtension {
public:
    EXT_COMMAND_METHOD(gcsex);
};
EXT_DECLARE_GLOBALS();
ULONG64 InstructionOffset; DEBUG_STACK_FRAME ScopeFrame; CONTEXT ScopeContext; 
DEBUG_STACK_FRAME_EX FrameEx[0x20];CONTEXT FrameContext[0x20];ULONG FramesFilled; 
INLINE_FRAME_CONTEXT Inlineframectx;
EXT_COMMAND( gcsex, "", "" ) {
    InstructionOffset = NULL; FramesFilled = NULL;
    memset(&ScopeFrame,0,sizeof(ScopeFrame));memset(&ScopeContext,0,sizeof(ScopeContext));
    memset(&FrameEx, 0, sizeof(FrameEx)); memset(&FrameContext,0,sizeof(FrameContext));
    memset(&Inlineframectx,0,sizeof(Inlineframectx));
    m_Symbols->GetScope(&InstructionOffset,&ScopeFrame,&ScopeContext,sizeof(ScopeContext));
    Out("%I64X%I64x %X\n",InstructionOffset,ScopeFrame.InstructionOffset,ScopeContext.Eip);
    m_Control5->GetContextStackTraceEx( &ScopeContext,sizeof(ScopeContext),
    FrameEx,0x20,FrameContext,0x20*sizeof(CONTEXT),sizeof(CONTEXT),&FramesFilled );
    Out("Frames Filled = %x\n" , FramesFilled);
    for(ULONG i = 0 ; i < FramesFilled; i++) {
        Inlineframectx.ContextValue = FrameEx[i].InlineFrameContext;
        Out("Inline Frame Context for frame %d=%x\n" , i , FrameEx[i].InlineFrameContext);
        Out("Frameid = %x FrameType = %x Frame Signature = %x\n" ,
        Inlineframectx.FrameId , Inlineframectx.FrameType , Inlineframectx.FrameSignature);
    }
    m_Control5->OutputContextStackTraceEx ( DEBUG_OUTCTL_ALL_CLIENTS,FrameEx,FramesFilled,
    &FrameContext,FramesFilled*sizeof(CONTEXT),sizeof(CONTEXT),0x1fff );
}

вы должны увидеть что-то подобное при выполнении расширения

0:000> kb
 # ChildEBP RetAddr  Args to Child              
00 (Inline) -------- -------- -------- -------- runasm!helper [e:\test\runasm\runasm.cpp @ 4]
01 0029fd44 0124159a 00000001 0008c5f0 00091a70 runasm!main+0x20 [e:\test\runasm\runasm.cpp @ 32]
02 (Inline) -------- -------- -------- -------- runasm!invoke_main+0x1d [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 74]
03 0029fd90 75d53c45 7ffdf000 0029fddc 778037f5 runasm!__scrt_common_main_seh+0xff [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 264]
04 0029fd9c 778037f5 7ffdf000 75826e8f 00000000 kernel32!BaseThreadInitThunk+0xe
05 0029fddc 778037c8 01241652 7ffdf000 00000000 ntdll!__RtlUserThreadStart+0x70
06 0029fdf4 00000000 01241652 7ffdf000 00000000 ntdll!_RtlUserThreadStart+0x1b
0:000> !gcsex
12412F0 12412f0 12412F0
Frames Filled = 7
Inline Frame Context = for frame 0 = 25ed0200
Frameid = 0 FrameType = 2 Frame Signature = 25ed
Inline Frame Context = for frame 1 = 25ed0100
Frameid = 0 FrameType = 1 Frame Signature = 25ed
Inline Frame Context = for frame 2 = 25ed8200
Frameid = 0 FrameType = 82 Frame Signature = 25ed
Inline Frame Context = for frame 3 = 25ed8100
Frameid = 0 FrameType = 81 Frame Signature = 25ed
Inline Frame Context = for frame 4 = 25ed8100
Frameid = 0 FrameType = 81 Frame Signature = 25ed
Inline Frame Context = for frame 5 = 25ed8100
Frameid = 0 FrameType = 81 Frame Signature = 25ed
Inline Frame Context = for frame 6 = 25ed8100
Frameid = 0 FrameType = 81 Frame Signature = 25ed
 #   Memory  ChildEBP RetAddr  Args to Child              
00           (Inline) -------- -------- -------- -------- runasm!helper (Inline Function @ 012412f0) (CONV: cdecl) [e:\test\runasm\runasm.cpp @ 4]
01           0029fd44 0124159a 00000001 0008c5f0 00091a70 runasm!main(void)+0x20 (FPO: [0,1,4]) (CONV: cdecl) [e:\test\runasm\runasm.cpp @ 32]
02        4c (Inline) -------- -------- -------- -------- runasm!invoke_main+0x1d (Inline Function @ 0124159a) (CONV: cdecl) [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 74]
03         0 0029fd90 75d53c45 7ffdf000 0029fddc 778037f5 runasm!__scrt_common_main_seh(void)+0xff (FPO: [Non-Fpo]) (CONV: cdecl) [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 264]
04         c 0029fd9c 778037f5 7ffdf000 75826e8f 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
05        40 0029fddc 778037c8 01241652 7ffdf000 00000000 ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
06        18 0029fdf4 00000000 01241652 7ffdf000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
0:000> .inline 
Include inline function queries is "enabled".
0:000> .inline 0
Include inline function queries is "disabled".
0:000> kb
 # ChildEBP RetAddr  Args to Child              
00 0029fd44 0124159a 00000001 0008c5f0 00091a70 runasm!main+0x20 [e:\test\runasm\runasm.cpp @ 32]
01 0029fd90 75d53c45 7ffdf000 0029fddc 778037f5 runasm!__scrt_common_main_seh+0xff [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 264]
02 0029fd9c 778037f5 7ffdf000 75826e8f 00000000 kernel32!BaseThreadInitThunk+0xe
03 0029fddc 778037c8 01241652 7ffdf000 00000000 ntdll!__RtlUserThreadStart+0x70
04 0029fdf4 00000000 01241652 7ffdf000 00000000 ntdll!_RtlUserThreadStart+0x1b
0:000> !gcsex
12412F0 12412f0 12412F0
Frames Filled = 5
Inline Frame Context = for frame 0 = ffffffff
Frameid = ff FrameType = ff Frame Signature = ffff
Inline Frame Context = for frame 1 = ffffffff
Frameid = ff FrameType = ff Frame Signature = ffff
Inline Frame Context = for frame 2 = ffffffff
Frameid = ff FrameType = ff Frame Signature = ffff
Inline Frame Context = for frame 3 = ffffffff
Frameid = ff FrameType = ff Frame Signature = ffff
Inline Frame Context = for frame 4 = ffffffff
Frameid = ff FrameType = ff Frame Signature = ffff
 #   Memory  ChildEBP RetAddr  Args to Child              
00           0029fd44 0124159a 00000001 0008c5f0 00091a70 runasm!main(void)+0x20 (FPO: [0,1,4]) (CONV: cdecl) [e:\test\runasm\runasm.cpp @ 32]
01        4c 0029fd90 75d53c45 7ffdf000 0029fddc 778037f5 runasm!__scrt_common_main_seh(void)+0xff (FPO: [Non-Fpo]) (CONV: cdecl) [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 264]
02         c 0029fd9c 778037f5 7ffdf000 75826e8f 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
03        40 0029fddc 778037c8 01241652 7ffdf000 00000000 ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
04        18 0029fdf4 00000000 01241652 7ffdf000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

результаты, подтверждающие редактирование, которое подпись варьируется в зависимости от сессии

cdb -c "$$>a< gcsex.txt" runasm.exe | grep -i Sign
Frameid = 0 FrameType = 1 Frame Signature = 1e7e
Frameid = 0 FrameType = 82 Frame Signature = 1e7e
Frameid = 0 FrameType = 81 Frame Signature = 1e7e
Frameid = 0 FrameType = 81 Frame Signature = 1e7e
Frameid = 0 FrameType = 81 Frame Signature = 1e7e
Frameid = 0 FrameType = 81 Frame Signature = 1e7e

cdb -c "$$>a< gcsex.txt" runasm.exe | grep -i Sign
Frameid = 0 FrameType = 1 Frame Signature = b649
Frameid = 0 FrameType = 82 Frame Signature = b649
Frameid = 0 FrameType = 81 Frame Signature = b649
Frameid = 0 FrameType = 81 Frame Signature = b649
Frameid = 0 FrameType = 81 Frame Signature = b649
Frameid = 0 FrameType = 81 Frame Signature = b649

cdb -c "$$>a< gcsex.txt" runasm.exe | grep -i Sign
Frameid = 0 FrameType = 1 Frame Signature = decf
Frameid = 0 FrameType = 82 Frame Signature = decf
Frameid = 0 FrameType = 81 Frame Signature = decf
Frameid = 0 FrameType = 81 Frame Signature = decf
Frameid = 0 FrameType = 81 Frame Signature = decf
Frameid = 0 FrameType = 81 Frame Signature = decf

cat gcsex.txt
.load gcsex
bp runasm!main "!gcsex;q"
g
Другие вопросы по тегам