forked from hillu/go-yara
-
Notifications
You must be signed in to change notification settings - Fork 4
/
example_mem_blocks_test.go
108 lines (95 loc) · 2.23 KB
/
example_mem_blocks_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright © 2015-2020 Hilko Bengen <[email protected]>
// All rights reserved.
//
// Use of this source code is governed by the license that can be
// found in the LICENSE file.
package yara_test
import (
"bytes"
"fmt"
"io"
"github.com/VirusTotal/go-yara/v4"
)
type Iterator struct {
blocksize int
rs io.ReadSeeker
offset int64
length int
}
func (s *Iterator) read(buf []byte) {
s.rs.Seek(s.offset, io.SeekStart)
s.rs.Read(buf)
}
func (s *Iterator) First() *yara.MemoryBlock {
s.offset = 0
return &yara.MemoryBlock{
Base: uint64(s.offset),
Size: uint64(s.length),
FetchData: s.read,
}
}
func (s *Iterator) Next() *yara.MemoryBlock {
s.offset += int64(s.length)
end, _ := s.rs.Seek(0, io.SeekEnd)
s.length = int(end - s.offset)
if s.length <= 0 {
return nil
}
if s.length > s.blocksize {
s.length = s.blocksize
}
return &yara.MemoryBlock{
Base: uint64(s.offset),
Size: uint64(s.length),
FetchData: s.read,
}
}
func (s *Iterator) Filesize() uint64 {
end, _ := s.rs.Seek(0, io.SeekEnd)
return uint64(end)
}
func Example_ScanMemBlocks() {
// Set up a []byte-backed io.ReadSeeker
buf := make([]byte, 65536)
buf[0] = 0x7f
buf[60000] = 0x7f
copy(buf[10000:], []byte("abc"))
copy(buf[20000:], []byte("def"))
copy(buf[1022:], []byte("ghij"))
it := &Iterator{blocksize: 1024, rs: bytes.NewReader(buf)}
rs := yara.MustCompile(`
rule A {
strings:
$abc = "abc"
$def = "def"
condition:
uint8(0) == 0x7f and uint8(60000) == 0x7f and $abc at 10000 and $def at 20000
}
// we do not expect rule B to be matched since the relevant value
// crosses the block boundary at 1024. (However, it does match when
// setting a blocksize that does not cause this value to be split.)
rule B {
strings:
$ghij = "ghij"
condition:
$ghij at 1022 or uint32be(1022) == 0x6768696a
}
`, nil)
var mrs yara.MatchRules
err := rs.ScanMemBlocks(it, 0, 0, &mrs)
if err != nil {
fmt.Printf("error: %+v\n", err)
return
}
for _, rule := range mrs {
fmt.Printf("match: %s\n strings:\n", rule.Rule)
for _, ms := range rule.Strings {
fmt.Printf(" - %s at %d\n", ms.Name, ms.Base+ms.Offset)
}
}
// Output:
// match: A
// strings:
// - $abc at 10000
// - $def at 20000
}