From fc43157429d30766b8cae4706b8e76fbc6a02acb Mon Sep 17 00:00:00 2001 From: Pavel Bazika Date: Wed, 5 May 2021 20:29:46 +0200 Subject: [PATCH] Add etw UnicodeStringField Signed-off-by: Pavel Bazika --- pkg/etw/eventdata.go | 8 ++++++++ pkg/etw/fieldopt.go | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/pkg/etw/eventdata.go b/pkg/etw/eventdata.go index a6354754..9d7d6752 100644 --- a/pkg/etw/eventdata.go +++ b/pkg/etw/eventdata.go @@ -7,6 +7,7 @@ import ( "bytes" "encoding/binary" "syscall" + "unicode/utf16" ) // eventData maintains a buffer which builds up the data for an ETW event. It @@ -28,6 +29,13 @@ func (ed *eventData) writeString(data string) { _ = ed.buffer.WriteByte(0) } +// writeUnicodeString appends a string converted to UTF-16, including the null terminator, to the buffer. +func (ed *eventData) writeUnicodeString(data string) { + unicode := utf16.Encode([]rune(data)) + binary.Write(&ed.buffer, binary.LittleEndian, unicode) + ed.buffer.Write([]byte{0, 0}) +} + // writeInt8 appends a int8 to the buffer. func (ed *eventData) writeInt8(value int8) { _ = ed.buffer.WriteByte(uint8(value)) diff --git a/pkg/etw/fieldopt.go b/pkg/etw/fieldopt.go index 4ad9a8fb..babc4861 100644 --- a/pkg/etw/fieldopt.go +++ b/pkg/etw/fieldopt.go @@ -64,6 +64,14 @@ func JSONStringField(name string, value string) FieldOpt { } } +// UnicodeStringField adds a single UTF-16 string field to the event. +func UnicodeStringField(name string, value string) FieldOpt { + return func(em *eventMetadata, ed *eventData) { + em.writeField(name, inTypeUnicodeString, outTypeString, 0) + ed.writeUnicodeString(value) + } +} + // StringArray adds an array of string to the event. func StringArray(name string, values []string) FieldOpt { return func(em *eventMetadata, ed *eventData) { @@ -75,6 +83,17 @@ func StringArray(name string, values []string) FieldOpt { } } +// UnicodeStringArray adds an array of UTF-16 strings to the event. +func UnicodeStringArray(name string, values []string) FieldOpt { + return func(em *eventMetadata, ed *eventData) { + em.writeArray(name, inTypeUnicodeString, outTypeString, 0) + ed.writeUint16(uint16(len(values))) + for _, v := range values { + ed.writeUnicodeString(v) + } + } +} + // IntField adds a single int field to the event. func IntField(name string, value int) FieldOpt { switch unsafe.Sizeof(value) {