如何从我的 WinDbg 扩展获取目标更改的通知 - 或者,ChangeDebuggeeState 是如何工作的?

问题描述 投票:0回答:1

当目标的虚拟或物理内存通过 DEBUG_DATA_SPACE_VIRTUALDEBUG_DATA_SPACE_PHYSICAL 标志发生更改时,我需要能够从 WinDbg 扩展接收通知。

我希望使用 ChangeDebuggeeState 回调。

我编写了自己的类

MyCallbacks
,它实现了
IDebugEventCallbacksWide
接口。然后我在 DebugExtensionInitialize 回调中的 SetEventCallbacksWide 中使用它,如下所示:

CComPtr<IDebugControl4> pDebugControl;
DebugCreate(IID_PPV(pDebugControl));

CComPtr<IDebugClient5> pDbgClient;
pDebugControl->QueryInterface(IID_PPV(pDbgClient));

MyCallbacks* pC = new MyCallbacks;
pDbgClient->SetEventCallbacksWide(pC);

我的

AddRef
类的
MyCallbacks
方法在上面的序列之后被调用,以及 GetInterestMask,我在其中指定了我到底想要捕获的内容:

HRESULT STDMETHODCALLTYPE MyCallbacks::GetInterestMask(
        _Out_ PULONG Mask
        )
{
    *Mask = DEBUG_EVENT_CHANGE_DEBUGGEE_STATE;

    return S_OK;
}

但是当我通过单步执行实时目标来使用 WinDbg 时,我实现的 ChangeDebuggeeState 函数永远不会被调用。由于目标的虚拟/物理内存正在更改,所以我期望它被调用。

知道我做错了什么吗?

PS。我尝试稍微调整一下,并使用

DEBUG_EVENT_BREAKPOINT
掩码作为
GetInterestMask
,然后检查当在 WinDbg 中击中内核断点时是否调用了我的
IDebugEventCallbacksWide::Breakpoint
方法 - 并且我的回调也从未被调用。

c++ windbg windbg-extension
1个回答
0
投票

刚刚掸掉了一段非常漂亮的旧代码并把它扔到了这里

ChangeDebugeeState 的代码如下所示

STDMETHODIMP EventCallbacks::ChangeDebuggeeState(THIS_ IN ULONG Flags, IN ULONG64 Argument)
{
       printf("ChangeDebugeeState Flags = %x\n", Flags);
       if ((Flags & DEBUG_CDS_ALL) == DEBUG_CDS_ALL)
       {
              printf("Flags = DEBUG_CDS_ALL\n");
       }
       else if ((Flags & DEBUG_CDS_REGISTERS) == DEBUG_CDS_REGISTERS)
       {
              printf("Flags = DEBUG_CDS_REGISTERS\n");
       }
       else if ((Flags & DEBUG_CDS_DATA) == DEBUG_CDS_DATA)
       {
              printf("Flags = DEBUG_CDS_DATA\n");
              if ((Argument & DEBUG_DATA_SPACE_VIRTUAL) == DEBUG_DATA_SPACE_VIRTUAL)
              {
                     printf("virtual Data Change\n");
              }
              else
              {
                     printf("some other data Change\n");
              }
       }
       else if ((Flags & DEBUG_CDS_REFRESH) == DEBUG_CDS_REFRESH)
       {
              {
                     printf("Flags = DEBUG_CDS_REFRESH\n");
              }
       }
       else
       {
              printf("unknown flags\n");
       }
       printf("ChangeDebugeeState Argument  = %I64x\n", Argument);
       State = 1;
       return DEBUG_STATUS_NO_CHANGE;
}

在编辑虚拟内存时,回调会像这样被击中

0:000>dd [rsp+8] l1
000000b2`5c2ff820  00000000
ChangeDebugeeState Flags = 4
Flags = DEBUG_CDS_REFRESH
ChangeDebugeeState Argument  = 2
testdump!__scrt_common_main_seh:
00007ff6`576e11f0 48895c2408      mov     qword ptr [rsp+8],rbx ss:000000b2`5c2ff820=0000000000000000
0:000>ed [rsp+8]             <<<<<<<<<<<<<<<<<<<<<<
000000b2`5c2ff820 00000000 2345  <<<<<<<<<<<< changing virtual memory contents
ChangeDebugeeState Flags = 2
Flags = DEBUG_CDS_DATA
virtual Data Change
ChangeDebugeeState Argument  = 0
000000b2`5c2ff824 00000000
ChangeDebugeeState Flags = 4
Flags = DEBUG_CDS_REFRESH
ChangeDebugeeState Argument  = 2
testdump!__scrt_common_main_seh:
00007ff6`576e11f0 48895c2408      mov     qword ptr [rsp+8],rbx ss:000000b2`5c2ff820=0000000000002345
0:000>

希望您能根据您的需求进行调整 请注意,它是一个独立的实用程序,而不是扩展 dll 你可能需要微调它

© www.soinside.com 2019 - 2024. All rights reserved.