@@ -31,6 +31,7 @@ import (
3131 "github.com/rabbitstack/fibratus/pkg/kevent/kparams"
3232 "github.com/rabbitstack/fibratus/pkg/kevent/ktypes"
3333 "github.com/rabbitstack/fibratus/pkg/util/signature"
34+ "github.com/rabbitstack/fibratus/pkg/util/va"
3435 "golang.org/x/sys/windows"
3536 "golang.org/x/sys/windows/registry"
3637 "os"
@@ -69,6 +70,8 @@ type scanner struct {
6970 config config.Config
7071
7172 psnap ps.Snapshotter
73+
74+ rwxs map [uint32 ]va.Address // contains scanned and matched RWX process allocations
7275}
7376
7477// NewScanner creates a new YARA scanner.
@@ -103,7 +106,7 @@ func NewScanner(psnap ps.Snapshotter, config config.Config) (Scanner, error) {
103106 return nil
104107 }
105108 rulesInCompiler .Add (1 )
106- log .Infof ("loading yara rule(s) from %s" , filepath . Join ( path , fi . Name ()) )
109+ log .Infof ("loading yara rule(s) from %s" , path )
107110
108111 return nil
109112 })
@@ -136,6 +139,7 @@ func NewScanner(psnap ps.Snapshotter, config config.Config) (Scanner, error) {
136139 rules : rules ,
137140 config : config ,
138141 psnap : psnap ,
142+ rwxs : make (map [uint32 ]va.Address ),
139143 }, nil
140144}
141145
@@ -165,7 +169,11 @@ func parseCompilerErrors(errors []yara.CompilerMessage) error {
165169
166170func (s scanner ) CanEnqueue () bool { return false }
167171
168- func (s scanner ) ProcessEvent (evt * kevent.Kevent ) (bool , error ) {
172+ func (s * scanner ) ProcessEvent (evt * kevent.Kevent ) (bool , error ) {
173+ if evt .IsTerminateProcess () {
174+ // cleanup
175+ delete (s .rwxs , evt .Kparams .MustGetPid ())
176+ }
169177 return s .Scan (evt )
170178}
171179
@@ -264,12 +272,16 @@ func (s scanner) Scan(e *kevent.Kevent) (bool, error) {
264272 }
265273 // scan process allocating RWX memory region
266274 pid := e .Kparams .MustGetPid ()
267- if e .PID != 4 && e .Kparams .TryGetUint32 (kparams .MemProtect ) == windows .PAGE_EXECUTE_READWRITE {
275+ addr := e .Kparams .TryGetAddress (kparams .MemBaseAddress )
276+ if e .PID != 4 && e .Kparams .TryGetUint32 (kparams .MemProtect ) == windows .PAGE_EXECUTE_READWRITE && ! s .isRwxMatched (pid ) {
268277 log .Debugf ("scanning RWX allocation. pid: %d, exe: %s, addr: %s" , pid , e .GetParamAsString (kparams .Exe ),
269278 e .GetParamAsString (kparams .MemBaseAddress ))
270279 matches , err = s .scan (pid )
271280 allocScans .Add (1 )
272281 isScanned = true
282+ if len (matches ) > 0 {
283+ s .rwxs [pid ] = addr
284+ }
273285 }
274286 case ktypes .MapViewFile :
275287 if s .config .SkipMmaps {
@@ -443,3 +455,9 @@ func (s scanner) Close() {
443455 s .c .Destroy ()
444456 }
445457}
458+
459+ // isRwxMatched returns true if the process already triggered RWX allocation rule match.
460+ func (s * scanner ) isRwxMatched (pid uint32 ) (ok bool ) {
461+ _ , ok = s .rwxs [pid ]
462+ return ok
463+ }
0 commit comments