dbgmgr.h 7.3 KB
Newer Older
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
1 2
#pragma once

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
3
#include <list>
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
4
#include <string>
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
5

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
6 7 8 9 10
#include <dbgeng.h>
#include <dbghelp.h>
#include <windows.h>
#include <atlbase.h>

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
11 12 13 14
#include <boost/thread/recursive_mutex.hpp>

#include "kdlib/dbgcallbacks.h"

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
15 16
#include "exceptions.h"

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
17 18 19 20
namespace kdlib {

///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
21
class DebugManager : public DebugBaseEventCallbacksWide, public IDebugOutputCallbacksWide, public IDebugInputCallbacks
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
22 23 24 25 26
{

public:

    DebugManager();
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
27 28
    DebugManager( const std::wstring& remoteOptions );

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
29 30 31 32
    ~DebugManager();

public:

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
33
     CComPtr<IDebugClient5>         client;
ussrhero's avatar
ussrhero committed
34
     CComPtr<IDebugControl5>        control;
35
     CComPtr<IDebugSystemObjects4>  system;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
36 37
     CComPtr<IDebugDataSpaces4>     dataspace;
     CComPtr<IDebugSymbols3>        symbols;
38
     CComPtr<IDebugAdvanced3>       advanced;
39
     CComPtr<IDebugRegisters2>      registers;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
40

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
41 42
public:

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
43 44 45 46
    bool isRemoteInitialized() {
        return m_remote;
    }

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
47 48
    bool setQuietNotiification(bool quiet) {
        bool previous = m_quietNotification;
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
49
        m_quietNotification = quiet;
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
50
        return previous;
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
51
    }
52 53 54 55 56

    void registerEventsCallback(DebugEventsCallback *callback);

    void removeEventsCallback(DebugEventsCallback *callback);

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
57 58
private:

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
59
    ULONG                       m_previousExecutionStatus;
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
60
    ULONG                       m_previousCurrentThread;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
61
    bool                        m_remote;
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
62
    bool                        m_quietNotification;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
63

SND\ussrhero_cp's avatar
 
SND\ussrhero_cp committed
64 65 66 67 68 69 70 71 72 73 74 75 76 77
    template< class T, class TCast=T >
    bool QueryInterface_Case(
        _In_ REFIID InterfaceId,
        _Out_ PVOID* Interface
        )
    {
        if (!IsEqualIID(InterfaceId, __uuidof(T)))
            return false;

        *reinterpret_cast<TCast**>(Interface) = this;
        AddRef();
        return true;
    }

78 79
public:

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
80 81 82
    STDMETHOD_(ULONG, AddRef)() { return 1; }
    STDMETHOD_(ULONG, Release)() { return 1; }

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
83 84 85 86 87 88 89 90
    STDMETHOD(QueryInterface)(
        THIS_
        _In_ REFIID InterfaceId,
        _Out_ PVOID* Interface
        )
    {
        *Interface = NULL;

SND\ussrhero_cp's avatar
 
SND\ussrhero_cp committed
91 92 93 94 95
        if (QueryInterface_Case<IUnknown, IDebugEventCallbacksWide>(InterfaceId, Interface))
            return S_OK;
        if (QueryInterface_Case<IDebugEventCallbacksWide>(InterfaceId, Interface))
            return S_OK;
        if (QueryInterface_Case<IDebugOutputCallbacksWide>(InterfaceId, Interface))
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
96
            return S_OK;
SND\ussrhero_cp's avatar
 
SND\ussrhero_cp committed
97 98 99 100
        if (QueryInterface_Case<IDebugInputCallbacks>(InterfaceId, Interface))
            return S_OK;

        return E_NOINTERFACE;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
101 102
    }

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
103 104 105 106 107
    // IDebugEventCallbacks impls
    STDMETHOD(GetInterestMask)(
        __out PULONG Mask 
        )
    {
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
108 109 110
        *Mask = 0;
        *Mask |= DEBUG_EVENT_BREAKPOINT;
        *Mask |= DEBUG_EVENT_CHANGE_ENGINE_STATE;
111
        *Mask |= DEBUG_EVENT_CHANGE_SYMBOL_STATE;
112
        *Mask |= DEBUG_EVENT_EXCEPTION;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
113 114
        *Mask |= DEBUG_EVENT_LOAD_MODULE;
        *Mask |= DEBUG_EVENT_UNLOAD_MODULE;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
115 116
        *Mask |= DEBUG_EVENT_CREATE_PROCESS;
        *Mask |= DEBUG_EVENT_EXIT_PROCESS;
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
117 118
        *Mask |= DEBUG_EVENT_CREATE_THREAD;
        *Mask |= DEBUG_EVENT_EXIT_THREAD;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
119

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
120 121 122 123
        return S_OK;
    }

    STDMETHOD(Breakpoint)(
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
124
        __in IDebugBreakpoint2 *bp
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
125
    );
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
126 127 128 129

    STDMETHOD(ChangeEngineState)(
        __in ULONG Flags,
        __in ULONG64 Argument );
130

131

132 133 134
    STDMETHOD(Exception)(
        __in PEXCEPTION_RECORD64 Exception,
        __in  ULONG FirstChance );
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149

    STDMETHOD(LoadModule)(
        __in ULONG64 ImageFileHandle,
        __in ULONG64 BaseOffset,
        __in ULONG ModuleSize,
        __in PCWSTR ModuleName,
        __in PCWSTR ImageName,
        __in ULONG CheckSum,
        __in ULONG TimeDateStamp
        );

    STDMETHOD(UnloadModule)(
        __in PCWSTR ImageBaseName,
        __in ULONG64 BaseOffset
        );
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167

    STDMETHOD(CreateProcess)(
        __in ULONG64 ImageFileHandle,
        __in ULONG64 Handle,
        __in ULONG64 BaseOffset,
        __in ULONG ModuleSize,
        __in PCWSTR ModuleName,
        __in PCWSTR ImageName,
        __in ULONG CheckSum,
        __in ULONG TimeDateStamp,
        __in ULONG64 InitialThreadHandle,
        __in ULONG64 ThreadDataOffset,
        __in ULONG64 StartOffset
        );

    STDMETHOD(ExitProcess)(
        __in ULONG ExitCode
        );
168

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
169 170 171 172 173 174 175 176 177 178
    STDMETHOD(CreateThread)(
        ULONG64  handle,
        ULONG64  dataOffset,
        ULONG64  startOffset
        );

    STDMETHOD(ExitThread)(
        ULONG ExitCode
        );

179 180 181 182
    STDMETHOD(ChangeSymbolState)(
        __in ULONG Flags,
        __in ULONG64 Argument
        );
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
183 184 185 186 187

    STDMETHOD(Output)(
        __in ULONG Mask,
        __in PCWSTR Text
        );
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
188 189 190 191 192 193 194 195

    STDMETHOD(StartInput)(
        __in ULONG BufferSize
        );

    STDMETHOD(EndInput)(
        );

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
196 197
};

198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218

class DebugManagerWrapper {

public:

    void set( DebugManager*  dbgMgr ) {
        m_dbgMgr = dbgMgr;
    }

    void reset() {
        delete m_dbgMgr;
        m_dbgMgr = 0;
    }

    DebugManager* operator->() {
        if (!m_dbgMgr)
            throw DbgException("pykd is not initialized");

        return m_dbgMgr;
    }

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
219 220 221 222 223 224 225 226
    bool operator==(DebugManager* ptr) {
        return m_dbgMgr == ptr;
    }

    bool operator!=(DebugManager* ptr) {
        return !(m_dbgMgr == ptr);
    }

227 228 229 230 231 232 233
private:

    DebugManager*  m_dbgMgr;
};


extern DebugManagerWrapper   g_dbgMgr;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
234 235 236

///////////////////////////////////////////////////////////////////////////////

ussrhero's avatar
ussrhero committed
237
class OutputReader : public IDebugOutputCallbacksWide, private boost::noncopyable {
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
238 239 240

public:

241
    explicit OutputReader(IDebugClient5* client, ULONG outputMask = DEBUG_OUTPUT_NORMAL)
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
242
    {
243 244 245 246
        HRESULT  hres;

        m_callbacks = NULL;
        m_client = client;
247
        m_mask = outputMask;
248

ussrhero's avatar
ussrhero committed
249
        hres = m_client->GetOutputCallbacksWide(&m_callbacks);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
250
        if ( FAILED( hres ) )
251
            throw DbgEngException( L"IDebugClient::GetOutputCallbacks", hres);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
252

ussrhero's avatar
ussrhero committed
253
        hres = m_client->SetOutputCallbacksWide(this);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
254
        if ( FAILED( hres ) )
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
255
            throw DbgEngException( L"IDebugClient::SetOutputCallbacks", hres);
256 257

        m_client->FlushCallbacks();
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
258 259 260 261
    }

    ~OutputReader() 
    {
ussrhero's avatar
ussrhero committed
262
        m_client->SetOutputCallbacksWide(m_callbacks);
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
263 264 265 266 267 268 269
    }

    const std::wstring&
    Line() const {
        return  m_readLine;
    }

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
270 271 272 273
    CComPtr<IDebugClient5>& getClient() {
        return m_client;
    }

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
private:

     // IUnknown.
    STDMETHOD(QueryInterface)(
        __in REFIID InterfaceId,
        __out PVOID* Interface ) {
        return E_NOINTERFACE;
    }

    STDMETHOD_(ULONG, AddRef)() {
        return 1L;
    }


    STDMETHOD_(ULONG, Release)() {
        return 0L;
    }

   STDMETHOD(Output)(
        __in ULONG Mask,
ussrhero's avatar
ussrhero committed
294
        __in PCWSTR Text );
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
295 296 297

private:

SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
298
    std::wstring                        m_readLine;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
299 300

    CComPtr<IDebugClient5>              m_client;
301

ussrhero's avatar
ussrhero committed
302
    PDEBUG_OUTPUT_CALLBACKS_WIDE        m_callbacks;
303 304

    ULONG                               m_mask;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
305 306 307 308
};

///////////////////////////////////////////////////////////////////////////////

309 310 311 312
ExecutionStatus ConvertDbgEngineExecutionStatus( ULONG status );

///////////////////////////////////////////////////////////////////////////////

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
313 314
} // kdlib namespace end