diff --git a/pkg/event/param_windows.go b/pkg/event/param_windows.go index 1054260b7..4e2b9b110 100644 --- a/pkg/event/param_windows.go +++ b/pkg/event/param_windows.go @@ -22,6 +22,15 @@ import ( "encoding/binary" "expvar" "fmt" + "net" + "path/filepath" + "strconv" + "strings" + "time" + "unsafe" + + "github.com/rabbitstack/fibratus/pkg/util/utf16" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/fs" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" @@ -35,12 +44,6 @@ import ( "github.com/rabbitstack/fibratus/pkg/util/va" "golang.org/x/sys/windows" "golang.org/x/sys/windows/registry" - "net" - "path/filepath" - "strconv" - "strings" - "time" - "unsafe" ) // unknownKeysCount counts the number of times the registry key failed to convert from native format @@ -520,23 +523,28 @@ func (e *Event) produceParams(evt *etw.EventRecord) { capturedSize := evt.ReadUint16(voffset) capturedData := evt.ReadBytes(2+voffset, capturedSize) + // copy the buffer as it points to invalid + // memory when the callback function returns + b := make([]byte, capturedSize) + copy(b, capturedData) + e.AppendParam(params.RegKeyHandle, params.Address, keyObject) e.AppendParam(params.NTStatus, params.Status, status) e.AppendParam(params.RegPath, params.Key, filepath.Join(keyName, valueName)) e.AppendEnum(params.RegValueType, valueType, key.RegistryValueTypes) - if len(capturedData) > 0 { + if len(b) > 0 { switch valueType { case registry.SZ, registry.MULTI_SZ, registry.EXPAND_SZ: - e.AppendParam(params.RegData, params.UnicodeString, string(capturedData)) + e.AppendParam(params.RegData, params.UnicodeString, utf16.BytesToString(b, binary.LittleEndian)) case registry.BINARY: - e.AppendParam(params.RegData, params.Binary, capturedData) + e.AppendParam(params.RegData, params.Binary, b) case registry.DWORD: - e.AppendParam(params.RegData, params.Uint32, binary.LittleEndian.Uint32(capturedData)) + e.AppendParam(params.RegData, params.Uint32, binary.LittleEndian.Uint32(b)) case registry.DWORD_BIG_ENDIAN: - e.AppendParam(params.RegData, params.Uint32, binary.BigEndian.Uint32(capturedData)) + e.AppendParam(params.RegData, params.Uint32, binary.BigEndian.Uint32(b)) case registry.QWORD: - e.AppendParam(params.RegData, params.Uint64, binary.LittleEndian.Uint64(capturedData)) + e.AppendParam(params.RegData, params.Uint64, binary.LittleEndian.Uint64(b)) } } case CreateFile: diff --git a/pkg/util/utf16/utf16.go b/pkg/util/utf16/utf16.go index 8a387f3ff..7387cac16 100644 --- a/pkg/util/utf16/utf16.go +++ b/pkg/util/utf16/utf16.go @@ -22,6 +22,7 @@ package utf16 import ( + "encoding/binary" "unicode/utf8" ) @@ -58,3 +59,16 @@ func Decode(p []uint16) string { } return string(s) } + +// BytesToString converts the UTF16-encoded byte buffer to string. +func BytesToString(b []byte, o binary.ByteOrder) string { + utf := make([]uint16, 0, len(b)/2) + for i := 0; i+1 < len(b); i += 2 { + u := o.Uint16(b[i:]) + if u == 0 { + break // stop at null terminator + } + utf = append(utf, u) + } + return Decode(utf) +}