mikesoft
mikesoft

Reputation: 1

Get output of executed windbg command

IDebugControl::Execute method enables executing debugger commands. How can I get the output of the executed debugger command? My aim is to check if a driver is loaded, to accomplish that I use Execute to execute the "lm" windbg command and parse the returned output.

Upvotes: 0

Views: 1484

Answers (2)

blabb
blabb

Reputation: 9007

you need to implement IDebugOutputCallbacks for a sample take a look at remmon out.cpp and out.hpp in windbg sdk sample (iirc new sdks don't contain samples you need to get it from msdn sample gallery online )

class StdioOutputCallbacks : public IDebugOutputCallbacks
{
public:
............
}

StdioOutputCallbacks g_Callback;

status = g_Client->SetOutputCallbacks( &g_Callback );

a sample dummy implementation copy the two file out.cpp and out.hpp to the local folder build and execute to show a warning and the output of .echo execution

//error,relasese() omitted Do_Nothing_sample no proc|thread warn print exit; 
#include <engextcpp.hpp>
#include "out.hpp"
#include "out.cpp"
extern StdioOutputCallbacks g_OutputCb; 
void __cdecl main( void ){
    IDebugClient*   g_Client = NULL;
    IDebugControl*  g_Control= NULL;
    DebugCreate( __uuidof(IDebugClient), (void**)&g_Client );
    g_Client->QueryInterface( __uuidof(IDebugControl), (void**)&g_Control );
    g_Client->SetOutputCallbacks( &g_OutputCb );
    g_Control->Execute( DEBUG_OUTCTL_THIS_CLIENT, 
  ".echo hello iam alive and kicking", DEBUG_EXECUTE_DEFAULT);  
}

result of build and execution

    3 files compiled
    1 executable built

WARNING: The debugger does not have a current process or thread
WARNING: Many commands will not work
hello iam alive and kicking

Upvotes: 1

Neitsa
Neitsa

Reputation: 8176

Once you have your client (IDebugClient*) and your control (IDebugControl*) instances, from the client instance you need to call IDebugClient::SetOutputCallbacks method which sets the output callback. You need to set the output callback before calling the execute() method.

This should look like this:

StdioOutputCallbacks g_OutputCb;

// ...

g_Client->SetOutputCallbacks(&g_OutputCb);
g_Control->Execute(DEBUG_OUTCTL_ALL_CLIENTS,"lm vm", DEBUG_EXECUTE_ECHO);

Your output callback must inherit from IDebugOutputCallbacks

class StdioOutputCallbacks : public IDebugOutputCallbacks

The simple way to do this is to copy and use directly the out.cpp and out.hpp files - present in some samples - that implements the callback class, for ex. in:

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\sdk\samples\dumpstk

The output itself is done in IDebugOutputCallbacks::Output implementation:

STDMETHODIMP
StdioOutputCallbacks::Output(
    THIS_
    _In_ ULONG Mask,
    _In_ PCSTR Text
    )
{
    UNREFERENCED_PARAMETER(Mask);
    fputs(Text, stdout);
    return S_OK;
}

Upvotes: 1

Related Questions