Skip to content

Commit 388a037

Browse files
committed
feat(sys): Introduce synthethic extended item types
The new fs approver keeps in-flight CreateFile event records and attributes them to FileOpEnd events via IRP link. When the respective FileOpEnd event record arrives, we extract the create disposition and the system status attributes and attach them to the CreateFile event record by pushing synthethic extended items to the event record.
1 parent fcc9952 commit 388a037

1 file changed

Lines changed: 77 additions & 0 deletions

File tree

pkg/sys/etw/types.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,72 @@ type EventFilterDescriptor struct {
570570
Type uint32
571571
}
572572

573+
const (
574+
// ExtTypeDisposition represents a custom extended item type for the file disposition.
575+
ExtTypeDisposition = 0x8000
576+
// ExtTypeStatus represents a custom extended item type for the file system status.
577+
ExtTypeStatus = 0x8001
578+
)
579+
580+
// FileExtendedDataItems stores file extended data items.
581+
type FileExtendedDataItems struct {
582+
status uint32
583+
disposition uint32
584+
items []EventHeaderExtendedDataItem
585+
}
586+
587+
// AppendEventHeaderFileExtendedDataItems appends custom file extendeed data items to the event record.
588+
func AppendEventHeaderFileExtendedDataItems(r *EventRecord, disposition uint64, status uint32) *FileExtendedDataItems {
589+
f := &FileExtendedDataItems{
590+
disposition: uint32(disposition),
591+
status: status,
592+
items: make([]EventHeaderExtendedDataItem, 2),
593+
}
594+
595+
f.items[0] = EventHeaderExtendedDataItem{
596+
ExtType: ExtTypeDisposition,
597+
DataSize: 4,
598+
DataPtr: uint64(uintptr(unsafe.Pointer(&f.disposition))),
599+
}
600+
f.items[1] = EventHeaderExtendedDataItem{
601+
ExtType: ExtTypeStatus,
602+
DataSize: 4,
603+
DataPtr: uint64(uintptr(unsafe.Pointer(&f.status))),
604+
}
605+
606+
r.ExtendedDataCount = uint16(len(f.items))
607+
r.ExtendedData = &f.items[0]
608+
609+
return f
610+
}
611+
612+
// ReadEventHeaderFileExtendedDataItems reads the custom file extended data items from the event record.
613+
func (r *EventRecord) ReadEventHeaderFileExtendedDataItems() (uint32, uint32) {
614+
if r.ExtendedData == nil {
615+
return 0, 0
616+
}
617+
618+
items := unsafe.Slice(r.ExtendedData, r.ExtendedDataCount)
619+
620+
var disposition uint32
621+
var status uint32
622+
623+
for _, item := range items {
624+
switch item.ExtType {
625+
case ExtTypeDisposition:
626+
if item.DataSize == 4 && item.DataPtr != 0 {
627+
disposition = *(*uint32)(unsafe.Pointer(uintptr(item.DataPtr)))
628+
}
629+
case ExtTypeStatus:
630+
if item.DataSize == 4 && item.DataPtr != 0 {
631+
status = *(*uint32)(unsafe.Pointer(uintptr(item.DataPtr)))
632+
}
633+
}
634+
}
635+
636+
return disposition, status
637+
}
638+
573639
// NewClassicEventID creates a new instance of classic event identifier.
574640
func NewClassicEventID(guid windows.GUID, typ uint16) ClassicEventID {
575641
return ClassicEventID{GUID: guid, Type: uint8(typ)}
@@ -606,6 +672,17 @@ func (e *EventRecord) ID() uint {
606672
return id
607673
}
608674

675+
// Copy makes a copy of this event record and returns the
676+
// copy itself and the event buffer. The buffer must outlive
677+
// the event record instance.
678+
func (r *EventRecord) Copy() (*EventRecord, []byte) {
679+
c := *r
680+
buf := make([]byte, r.BufferLen)
681+
copy(buf, unsafe.Slice((*byte)(unsafe.Pointer(r.Buffer)), r.BufferLen))
682+
c.Buffer = uintptr(unsafe.Pointer(&buf[0]))
683+
return &c, buf
684+
}
685+
609686
// ReadByte reads the byte from the buffer at the specified offset.
610687
func (e *EventRecord) ReadByte(offset uint16) byte {
611688
if offset > e.BufferLen {

0 commit comments

Comments
 (0)