Skip to content

Commit cebc578

Browse files
committed
chore(process): Populate process modules from internal events
If the event arrives from the provider and the process state hasn't been populated with the expected module, we leverage the internal load image event to append the module.
1 parent 2503dcc commit cebc578

File tree

8 files changed

+47
-4
lines changed

8 files changed

+47
-4
lines changed

internal/etw/processors/image_windows.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ func newImageProcessor(psnap ps.Snapshotter) Processor {
5555
func (*imageProcessor) Name() ProcessorType { return Image }
5656

5757
func (m *imageProcessor) ProcessEvent(e *event.Event) (*event.Event, bool, error) {
58+
if e.IsLoadImageInternal() {
59+
// state management
60+
return e, false, m.psnap.AddModule(e)
61+
}
62+
5863
if e.IsLoadImage() {
5964
// is image characteristics data cached?
6065
path := e.GetParamAsString(params.ImagePath)

internal/etw/source.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ func (e *EventSource) Open(config *config.Config) error {
168168
// additional attributes and guaranteeing that any event published by
169169
// the security telemetry session doesn't miss its respective process
170170
// from the snapshotter
171-
trace.AddProvider(etw.WindowsKernelProcessGUID, false, WithKeywords(etw.ProcessKeyword), WithCaptureState())
171+
trace.AddProvider(etw.WindowsKernelProcessGUID, false, WithKeywords(etw.ProcessKeyword|etw.ImageKeyword), WithCaptureState())
172172

173173
if config.EventSource.EnableDNSEvents {
174174
trace.AddProvider(etw.DNSClientGUID, false)

pkg/event/event_windows.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ func (e *Event) IsTerminateProcess() bool { return e.Type == TerminateProc
229229
func (e *Event) IsTerminateThread() bool { return e.Type == TerminateThread }
230230
func (e *Event) IsUnloadImage() bool { return e.Type == UnloadImage }
231231
func (e *Event) IsLoadImage() bool { return e.Type == LoadImage }
232+
func (e *Event) IsLoadImageInternal() bool { return e.Type == LoadImageInternal }
232233
func (e *Event) IsImageRundown() bool { return e.Type == ImageRundown }
233234
func (e *Event) IsFileOpEnd() bool { return e.Type == FileOpEnd }
234235
func (e *Event) IsRegSetValue() bool { return e.Type == RegSetValue }

pkg/event/metainfo_windows.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ func AllWithState() []Type {
240240
s = append(s, StackWalk)
241241
s = append(s, CreateProcessInternal)
242242
s = append(s, ProcessRundownInternal)
243+
s = append(s, LoadImageInternal)
243244

244245
return s
245246
}

pkg/event/param_windows.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,29 @@ func (e *Event) produceParams(evt *etw.EventRecord) {
459459
e.AppendParam(params.ImagePath, params.DOSPath, filename)
460460
e.AppendParam(params.ImageSignatureLevel, params.Enum, uint32(sigLevel), WithEnum(signature.Levels))
461461
e.AppendParam(params.ImageSignatureType, params.Enum, uint32(sigType), WithEnum(signature.Types))
462+
case LoadImageInternal:
463+
var (
464+
pid uint32
465+
checksum uint32
466+
defaultBase uint64
467+
imageBase uint64
468+
imageSize uint64
469+
filename string
470+
)
471+
472+
imageBase = evt.ReadUint64(0)
473+
imageSize = evt.ReadUint64(8)
474+
pid = evt.ReadUint32(16)
475+
checksum = evt.ReadUint32(20)
476+
defaultBase = evt.ReadUint64(28) // skip timestamp (4 bytes)
477+
filename = evt.ConsumeUTF16String(36)
478+
479+
e.AppendParam(params.ProcessID, params.PID, pid)
480+
e.AppendParam(params.ImageCheckSum, params.Uint32, checksum)
481+
e.AppendParam(params.ImageDefaultBase, params.Address, defaultBase)
482+
e.AppendParam(params.ImageBase, params.Address, imageBase)
483+
e.AppendParam(params.ImageSize, params.Uint64, imageSize)
484+
e.AppendParam(params.ImagePath, params.DOSPath, filename)
462485
case RegOpenKey, RegCloseKey,
463486
RegCreateKCB, RegDeleteKCB,
464487
RegKCBRundown, RegCreateKey,

pkg/event/types_windows.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ var (
156156
ImageRundown = pack(ImageEventGUID, 3)
157157
// LoadImage represents load image kernel events that are triggered when a DLL or executable file is loaded
158158
LoadImage = pack(ImageEventGUID, 10)
159+
// LoadImageInternal same as for process internal event originating from the Microsoft Windows Kernel Process provider.
160+
LoadImageInternal = pack(ProcessKernelEventGUID, 5)
159161

160162
// AcceptTCPv4 represents the TCPv4 kernel events for accepting connection requests from the socket queue.
161163
AcceptTCPv4 = pack(NetworkTCPEventGUID, 15)
@@ -309,7 +311,7 @@ func (t Type) String() string {
309311
return "RegCreateKCB"
310312
case RegSetValue:
311313
return "RegSetValue"
312-
case LoadImage:
314+
case LoadImage, LoadImageInternal:
313315
return "LoadImage"
314316
case UnloadImage:
315317
return "UnloadImage"
@@ -359,7 +361,7 @@ func (t Type) Category() Category {
359361
return Process
360362
case CreateThread, TerminateThread, OpenThread, SetThreadContext, ThreadRundown, StackWalk:
361363
return Thread
362-
case LoadImage, UnloadImage, ImageRundown:
364+
case LoadImage, UnloadImage, ImageRundown, LoadImageInternal:
363365
return Image
364366
case CreateFile, ReadFile, WriteFile, EnumDirectory, DeleteFile, RenameFile, CloseFile, SetFileInformation,
365367
FileRundown, FileOpEnd, ReleaseFile, MapViewFile, UnmapViewFile, MapFileRundown:
@@ -518,6 +520,7 @@ func (t Type) OnlyState() bool {
518520
CreateProcessInternal,
519521
ThreadRundown,
520522
ImageRundown,
523+
LoadImageInternal,
521524
FileRundown,
522525
RegKCBRundown,
523526
FileOpEnd,

pkg/ps/snapshotter_windows.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,6 @@ func (s *snapshotter) AddModule(e *event.Event) error {
246246
if err != nil {
247247
return err
248248
}
249-
moduleCount.Add(1)
250249
s.mu.Lock()
251250
defer s.mu.Unlock()
252251

@@ -265,6 +264,14 @@ func (s *snapshotter) AddModule(e *event.Event) error {
265264
module.Name = e.GetParamAsString(params.ImagePath)
266265
module.BaseAddress = e.Params.TryGetAddress(params.ImageBase)
267266
module.DefaultBaseAddress = e.Params.TryGetAddress(params.ImageDefaultBase)
267+
268+
if e.IsLoadImageInternal() {
269+
proc.AddModule(module)
270+
return nil
271+
}
272+
273+
moduleCount.Add(1)
274+
268275
module.SignatureLevel, _ = e.Params.GetUint32(params.ImageSignatureLevel)
269276
module.SignatureType, _ = e.Params.GetUint32(params.ImageSignatureType)
270277

pkg/sys/etw/types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ const (
5757
// ProcessKeyword enables process events for Microsoft Windows Kernel Process provider
5858
const ProcessKeyword = 0x10
5959

60+
// ImageKeyword enables images events for Microsoft Windows Kernel Process provider
61+
const ImageKeyword = 0x40
62+
6063
const (
6164
// EventHeaderExtTypeStackTrace64 indicates that the extended data contains the call stack if the event is captured on a 64-bit host
6265
EventHeaderExtTypeStackTrace64 uint16 = 0x0006

0 commit comments

Comments
 (0)