2016-08-11 41 views

回答

0

這是通過使用一些包裝每節不同的編輯,但我們的目的應該是清楚的。 如果InlineFrameContext指示它是嵌入式框架,則使用IDebugSymbols4::GetNameByInlineContext,否則使用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(); 
0

InLineFrameContext是聯盟唯一FrameType定義是在ContextValue DWORD

第二個字節這通常會是25ed0200一個內嵌框架(最讓我注意到時間的,雖然它可以b5b80200太在某些系統dll的嵌入式框架

如果禁用內嵌
InlineFrameContext would be 0xffffffff

輸出是一樣 kvf and .inline 1 (.inline enable)

其中ff is STACK_FRAME_TYPE_IGNORE

25ed/b5b8,FFFF等的幀簽名和00 FrameID 從符號

牽強

(如果你真的想知道看看它加載符號直徑SDK COM巫術並從pdb中獲取該簽名(dbghelp!g + 0xxxx(win10 dbghelp.dll中的2360))

無論它們是什麼,它們似乎都不適用於與符號的任何關聯,並且簽名在每次調用時都不相同或windbg會話 和iirc每個.reload/f

甚至OutputContextStackTraceEx功能似乎並沒有使用的簽名和Id(類型用來表示直列如果類型爲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); 
} 

你應該看到在執行擴展

一些像這樣的事情10個
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 
+0

我跟你這麼遠。我想我真正想要做的是做'IDebugControl :: OutputContextStackTraceEx',即迭代每個'FrameEx'並檢索它的內聯方法。 –

+0

我發現這個:https://blogs.msdn.microsoft.com/andrew_richards/2011/09/24/debugger-engine-dbgeng-updates-in-the-windows-8-developer-preview/ 「IDebugSymbols4界面允許您確定內聯框架的符號。「 –