diff --git a/rule.go b/rule.go index 3b7100d..87bb7ed 100644 --- a/rule.go +++ b/rule.go @@ -249,6 +249,11 @@ func (m *Match) Offset() int64 { return int64(m.cptr.offset) } +// XorKey returns the XOR value with which the string match occurred. +func (m *Match) XorKey() uint8 { + return uint8(m.cptr.xor_key) +} + // Data returns the blob of data associated with the string match. func (m *Match) Data() []byte { return C.GoBytes(unsafe.Pointer(m.cptr.data), C.int(m.cptr.data_length)) @@ -262,6 +267,7 @@ func (r *Rule) getMatchStrings(sc *ScanContext) (matchstrings []MatchString) { Base: uint64(m.Base()), Offset: uint64(m.Offset()), Data: m.Data(), + XorKey: m.XorKey(), }) } } diff --git a/rules.go b/rules.go index 77ba0e1..c8ced48 100644 --- a/rules.go +++ b/rules.go @@ -46,6 +46,7 @@ type MatchString struct { Base uint64 Offset uint64 Data []byte + XorKey uint8 } // ScanFlags are used to tweak the behavior of Scan* functions. diff --git a/rules_test.go b/rules_test.go index 504d234..6c649ed 100644 --- a/rules_test.go +++ b/rules_test.go @@ -358,3 +358,23 @@ func TestTooManyMatches(t *testing.T) { t.Errorf("too many matches does not contain regularly matching string: %v", cb.tooManyMatches) } } + +func TestXorKey(t *testing.T) { + var m MatchRules + r := makeRules(t, ` + rule t { strings: $s1 = "\x00\x01\x02\x03" xor condition: all of them } + `) + + if err := r.ScanMem([]byte{0x10, 0x11, 0x12, 0x13}, 0, 0, &m); err != nil { + t.Error(err) + } + if len(m) != 1 { + t.Fatalf("expected 1 match, got %d", len(m)) + } + if len(m[0].Strings) != 1 { + t.Fatalf("expected 1 string, got %d", len(m[0].Strings)) + } + if m[0].Strings[0].XorKey != 0x10 { + t.Fatalf("expected xor key 0x10, got 0x%x", m[0].Strings[0].XorKey) + } +}