diff --git a/core/adapters/dbgengadapter.cpp b/core/adapters/dbgengadapter.cpp index a837761..0e97179 100644 --- a/core/adapters/dbgengadapter.cpp +++ b/core/adapters/dbgengadapter.cpp @@ -1301,9 +1301,13 @@ std::string DbgEngAdapter::InvokeBackendCommand(const std::string& command) { if (m_debugControl) { + m_outputCallbacks.StartOutput(); this->m_debugControl->Execute(DEBUG_OUTCTL_ALL_CLIENTS, command.c_str(), DEBUG_EXECUTE_NO_REPEAT); m_debugClient->ExitDispatch(reinterpret_cast(m_debugClient)); - // The output is handled by DbgEngOutputCallbacks::Output() + // The output is handled by DbgEngOutputCallbacks::Output(), and Execute() would not return until all output + // has been dumped, so we can get the full output here + auto ret = m_outputCallbacks.EndOutput(); + return ret; } return ""; } @@ -1450,6 +1454,7 @@ HRESULT DbgEngOutputCallbacks::Output(unsigned long mask, const char* text) event.type = BackendMessageEventType; event.data.messageData.message = text; m_adapter->PostDebuggerEvent(event); + m_output += text; return S_OK; } @@ -1463,6 +1468,16 @@ unsigned long DbgEngOutputCallbacks::Release() return 0; } +void DbgEngOutputCallbacks::StartOutput() +{ + m_output.clear(); +} + +std::string DbgEngOutputCallbacks::EndOutput() +{ + return m_output; +} + HRESULT DbgEngOutputCallbacks::QueryInterface(const IID& interface_id, void** _interface) { return S_OK; diff --git a/core/adapters/dbgengadapter.h b/core/adapters/dbgengadapter.h index e5cd56b..c1c4c28 100644 --- a/core/adapters/dbgengadapter.h +++ b/core/adapters/dbgengadapter.h @@ -48,6 +48,7 @@ namespace BinaryNinjaDebugger { { private: DebugAdapter* m_adapter; + std::string m_output; public: CALLBACK_METHOD(unsigned long) AddRef() override; @@ -55,6 +56,8 @@ namespace BinaryNinjaDebugger { CALLBACK_METHOD(HRESULT) QueryInterface(const IID& interface_id, void** _interface) override; CALLBACK_METHOD(HRESULT) Output(unsigned long mask, const char* text); void SetAdapter(DebugAdapter* adapter); + void StartOutput(); + std::string EndOutput(); }; class DbgEngInputCallbacks : public IDebugInputCallbacks diff --git a/ui/debugadapterscriptingprovider.cpp b/ui/debugadapterscriptingprovider.cpp index b6b90eb..9ea3844 100644 --- a/ui/debugadapterscriptingprovider.cpp +++ b/ui/debugadapterscriptingprovider.cpp @@ -112,7 +112,15 @@ BNScriptingProviderExecuteResult DebugAdapterScriptingInstance::ExecuteScriptInp auto trimmedInput = input; trimmedInput.erase(trimmedInput.find_last_not_of('\n') + 1); auto ret = m_controller->InvokeBackendCommand(trimmedInput); - Output(ret); + // Do not output the returned string if it is DbgEng, since the output from DbgEng backend is already handled + // by the BackendMessageEventType event + if ((m_controller->GetAdapterType() != "DBGENG") && (m_controller->GetAdapterType() != "DBGENG_TTD") + && (m_controller->GetAdapterType() != "LOCAL_WINDOWS_KERNEL") + && (m_controller->GetAdapterType() != "WINDOWS_KERNEL") + && (m_controller->GetAdapterType() != "WINDOWS_DUMP_FILE")) + { + Output(ret); + } return SuccessfulScriptExecution; } return InvalidScriptInput;