@@ -20,18 +20,20 @@ type YaraReader struct {
20
20
Infected bool
21
21
filename string
22
22
level int
23
+ maxBlockSize int
23
24
}
24
25
26
+ // ScanReader Will scan a given reader until EOF or an error happens. It will scan archives.
25
27
func (s * YaraScanner ) ScanReader (reader io.Reader , opts ... func (writer * YaraReader )) ([]* yara.Rule , error ) {
26
- bufferedReader := bufio .NewReaderSize (reader , 16 * 1024 )
27
28
testReader := & YaraReader {
28
- r : bufferedReader ,
29
- level : 10 ,
29
+ level : 10 ,
30
+ maxBlockSize : 16 * 1024 ,
30
31
}
31
32
for _ , option := range opts {
32
33
option (testReader )
33
34
}
34
- dec , err := decoder .GetDecoder ("" , testReader .r )
35
+ testReader .r = bufio .NewReaderSize (reader , testReader .maxBlockSize )
36
+ dec , err := decoder .GetDecoder (testReader .filename , testReader .r )
35
37
if err == nil {
36
38
if testReader .level < 1 {
37
39
return nil , nil
@@ -42,7 +44,11 @@ func (s *YaraScanner) ScanReader(reader io.Reader, opts ...func(writer *YaraRead
42
44
return testReader .mrs , nil
43
45
}
44
46
if entry .IsFile () {
45
- partResults , _ := s .ScanReader (dec , ReaderWithFilenameTip (entry .Filename ), ReaderWithCurrentLevel (testReader .level - 1 ))
47
+ partResults , _ := s .ScanReader (dec ,
48
+ WithFilenameTip (entry .Filename ),
49
+ WithMaxLevel (testReader .level - 1 ),
50
+ WithBlockSize (testReader .maxBlockSize ),
51
+ )
46
52
testReader .mrs = append (testReader .mrs , partResults ... )
47
53
}
48
54
}
@@ -51,13 +57,14 @@ func (s *YaraScanner) ScanReader(reader io.Reader, opts ...func(writer *YaraRead
51
57
defer testReader .scanner .Destroy ()
52
58
testReader .scanner .SetFlags (yara .ScanFlagsProcessMemory )
53
59
testReader .scanner .SetCallback (testReader )
54
- testReader .buf = make ([]byte , 16 * 1024 )
55
- testReader .firstBlockData = make ([]byte , 16 * 1024 )
60
+ testReader .buf = make ([]byte , testReader . maxBlockSize )
61
+ testReader .firstBlockData = make ([]byte , testReader . maxBlockSize )
56
62
err = testReader .scanner .ScanMemBlocks (testReader )
57
63
58
64
return testReader .mrs , err
59
65
}
60
66
67
+ // First Will fetch the first block and cache it in our reader for further calls
61
68
func (s * YaraReader ) First () * yara.MemoryBlock {
62
69
if s .firstBlock == nil {
63
70
s .firstBlock = s .Next ()
@@ -71,6 +78,7 @@ func (s *YaraReader) First() *yara.MemoryBlock {
71
78
return s .firstBlock
72
79
}
73
80
81
+ // Next Will fetch the next block for scanning
74
82
func (s * YaraReader ) Next () * yara.MemoryBlock {
75
83
n , err := s .r .Read (s .buf )
76
84
if err != nil && n == 0 {
@@ -85,29 +93,40 @@ func (s *YaraReader) Next() *yara.MemoryBlock {
85
93
}
86
94
}
87
95
96
+ // RuleMatching will be called by the engine when a rule is matched
88
97
func (y * YaraReader ) RuleMatching (_ * yara.ScanContext , rule * yara.Rule ) (bool , error ) {
89
98
y .Infected = true
90
99
y .mrs = append (y .mrs , rule )
91
100
return true , nil
92
101
}
93
102
103
+ // copy Helper for Next()
94
104
func (s * YaraReader ) copy (buf []byte ) {
95
105
copy (buf , s .buf [:s .length ])
96
106
}
107
+
108
+ // first Helper for First()
97
109
func (s * YaraReader ) first (buf []byte ) {
98
110
copy (buf , s .firstBlockData [:s .firstBlock .Size ])
99
- //log.Println(s.filename, s.firstBlock.Base, s.firstBlock.Size, string(buf))
100
-
101
111
}
102
112
103
- func ReaderWithFilenameTip (filename string ) func (writer * YaraReader ) {
113
+ // WithFilenameTip Will tip the Decoder on possible archive types
114
+ func WithFilenameTip (filename string ) func (writer * YaraReader ) {
104
115
return func (writer * YaraReader ) {
105
116
writer .filename = filename
106
117
}
107
118
}
108
119
109
- func ReaderWithCurrentLevel (level int ) func (writer * YaraReader ) {
120
+ // WithMaxLevel Will prevent the Reader to inspect archives under and given level
121
+ func WithMaxLevel (level int ) func (writer * YaraReader ) {
110
122
return func (writer * YaraReader ) {
111
123
writer .level = level
112
124
}
113
125
}
126
+
127
+ // WithBlockSize Sets the default buffer and block size for in-memory scanning
128
+ func WithBlockSize (size int ) func (writer * YaraReader ) {
129
+ return func (writer * YaraReader ) {
130
+ writer .maxBlockSize = size
131
+ }
132
+ }
0 commit comments