Files
FalconOpsLLC-goexec/pkg/goexec/dcom/visualstudio.go
T
2025-10-01 13:36:44 -05:00

70 lines
2.0 KiB
Go

package dcomexec
import "github.com/rs/zerolog"
/*
See https://learn.microsoft.com/en-us/dotnet/api/envdte._dte.executecommand
*/
import (
"context"
"github.com/FalconOpsLLC/goexec/pkg/goexec"
"github.com/oiweiwei/go-msrpc/midl/uuid"
_ "github.com/oiweiwei/go-msrpc/msrpc/erref/hresult"
_ "github.com/oiweiwei/go-msrpc/msrpc/erref/ntstatus"
_ "github.com/oiweiwei/go-msrpc/msrpc/erref/win32"
)
const (
MethodVisualStudioDTE = "VisualStudio.DTE:ExecuteCommand"
VisualStudioDteUuid = "33ABD590-0400-4FEF-AF98-5F5A8A99CFC3"
VisualStudioDte2019Uuid = "2E1517DA-87BF-4443-984A-D2BF18F5A908"
)
type DcomVisualStudioDte struct {
Dispatch
// Is2019 indicates that the installation is Visual Studio 2019
Is2019 bool
// CommandName is the name of the DTE command to invoke
CommandName string
// CommandArgs are the arguments to pass to the command
CommandArgs string
}
func (m *DcomVisualStudioDte) Init(ctx context.Context) (err error) {
if err = m.Dcom.Init(ctx); err == nil {
if m.Is2019 {
return m.getDispatch(ctx, uuid.MustParse(VisualStudioDte2019Uuid))
}
return m.getDispatch(ctx, uuid.MustParse(VisualStudioDteUuid))
}
return
}
func (m *DcomVisualStudioDte) Execute(ctx context.Context, execIO *goexec.ExecutionIO) (err error) {
log := zerolog.Ctx(ctx)
dteCmd := m.CommandName
dteArgs := m.CommandArgs
if dteCmd == "" {
dteCmd = "tools.shell"
dteArgs = execIO.String()
}
defer func() {
// Terminate devenv.exe
q, err := m.callComMethod(ctx, nil, "Quit")
if err != nil {
log.Warn().Err(err).Msg("Call to Quit() failed")
return
}
zerolog.Ctx(ctx).Info().Int32("return", q.Return).Msg("Quit called")
}()
log.Info().Str("command", dteCmd).Str("args", dteArgs).Msg("Executing DTE command")
ir, err := m.callComMethod(ctx, nil, "ExecuteCommand", stringToVariant(dteArgs), stringToVariant(dteCmd))
if err == nil {
log.Info().Int32("return", ir.Return).Msg("ExecuteCommand called")
}
return
}