From e7d9bd9cb33d1a570632bb2e88bba6d04593e0a0 Mon Sep 17 00:00:00 2001 From: rabbitstack Date: Thu, 5 Feb 2026 17:55:09 +0100 Subject: [PATCH] fix(symbolizer,stackwalk): Always obtain callstack from real parent process The callstack should be obtained from the real parent process regardless of which process initiated the creation. The symbolizer now searches the process state the belongs to the real parent if the process creation event is originating from the brokered process. --- pkg/event/event_windows.go | 3 +++ pkg/event/stackwalk.go | 6 +++--- pkg/symbolize/symbolizer.go | 21 +++++++++++++++++---- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/pkg/event/event_windows.go b/pkg/event/event_windows.go index 5b1c077a9..2201eb6b6 100644 --- a/pkg/event/event_windows.go +++ b/pkg/event/event_windows.go @@ -267,6 +267,9 @@ func (e *Event) StackID() uint64 { // parent, not the process being created. func (e *Event) StackPID() uint32 { if e.IsCreateProcess() { + if e.IsSurrogateProcess() { + return e.Params.MustGetUint32(params.ProcessRealParentID) + } return e.Params.MustGetPpid() } return e.PID diff --git a/pkg/event/stackwalk.go b/pkg/event/stackwalk.go index d785c9cca..fbf905a2b 100644 --- a/pkg/event/stackwalk.go +++ b/pkg/event/stackwalk.go @@ -140,12 +140,12 @@ func (s *StackwalkDecorator) Pop(e *Event) *Event { evt.AppendParam(params.Callstack, params.Slice, callstack) // obtain the callstack from the CreateThread event - // generated by the surrogate process, such as Seclogon. + // generated by the surrogate/brokered process, such as + // Secondary Logon. // If the remote process id is present in the procs map // the stack is attached to the cached event and then // pushed to the queue immediately - if (evt.IsCreateRemoteThread() && evt.PS != nil) && - (evt.PS.IsSeclogonSvc() || evt.PS.IsAppinfoSvc()) { + if evt.IsCreateRemoteThread() { pid := evt.Params.MustGetPid() ev, ok := s.procs[pid] if ok { diff --git a/pkg/symbolize/symbolizer.go b/pkg/symbolize/symbolizer.go index 1531270ee..d8c779fc8 100644 --- a/pkg/symbolize/symbolizer.go +++ b/pkg/symbolize/symbolizer.go @@ -442,11 +442,24 @@ func (s *Symbolizer) produceFrame(addr va.Address, e *event.Event) callstack.Fra } } - if e.PS != nil { - mod := e.PS.FindModuleByVa(addr) + ps := e.PS + + // for process creation events initiated by + // brokered processes, obtain the real parent + // process state + if e.IsSurrogateProcess() { + var ok bool + ok, ps = s.psnap.Find(e.Params.MustGetUint32(params.ProcessRealParentID)) + if !ok { + ps = e.PS + } + } + + if ps != nil { + mod := ps.FindModuleByVa(addr) // perform lookup against parent modules - if mod == nil && e.PS.Parent != nil { - mod = e.PS.Parent.FindModuleByVa(addr) + if mod == nil && ps.Parent != nil { + mod = ps.Parent.FindModuleByVa(addr) } if mod == nil { // our last resort is to enumerate process modules