Skip to content

Commit

Permalink
Merge branch 'main' into listmodules
Browse files Browse the repository at this point in the history
  • Loading branch information
wxsBSD committed Aug 16, 2024
2 parents 1e16f1e + a7aadc3 commit 8cc71ba
Show file tree
Hide file tree
Showing 101 changed files with 1,600 additions and 1,515 deletions.
386 changes: 155 additions & 231 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ bincode = "1.3.3"
bitmask = "0.5.0"
bitvec = "1.0.1"
bstr = "1.9.1"
cbindgen = "0.26.0"
cbindgen = "0.27.0"
chrono = "0.4.38"
clap = "4.5.11"
clap_complete = "4.5.11"
Expand Down
7 changes: 4 additions & 3 deletions capi/include/yara_x.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#pragma once

/* Generated with cbindgen:0.26.0 */
/* Generated with cbindgen:0.27.0 */

// This file is autogenerated by cbindgen. Don't modify it manually.

Expand Down Expand Up @@ -380,7 +380,8 @@ enum YRX_RESULT yrx_scanner_on_matching_rule(struct YRX_SCANNER *scanner,
//
// 1) When the module does not produce any output on its own.
// 2) When you already know the output of the module for the upcoming file to
// be scanned, and you prefer to reuse this data instead of generating it again.
// be scanned, and you prefer to reuse this data instead of generating it
// again.
//
// Case 1) applies to certain modules lacking a main function, thus incapable of
// producing any output on their own. For such modules, you must set the output
Expand Down Expand Up @@ -424,4 +425,4 @@ enum YRX_RESULT yrx_scanner_set_global_float(struct YRX_SCANNER *scanner,
const char *ident,
double value);

#endif /* YARA_X */
#endif /* YARA_X */
5 changes: 3 additions & 2 deletions capi/src/scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ pub unsafe extern "C" fn yrx_scanner_scan(
/// callback function is being executed, but it may be freed after the callback
/// function returns, so you cannot use the pointer outside the callback.
///
/// It also receives the `user_data` pointer that was passed to the
/// It also receives the `user_data` pointer that was passed to the
/// [`yrx_scanner_on_matching_rule`] function, which can point to arbitrary
/// data owned by the user.
pub type YRX_ON_MATCHING_RULE = extern "C" fn(
Expand Down Expand Up @@ -161,7 +161,8 @@ pub unsafe extern "C" fn yrx_scanner_on_matching_rule(
///
/// 1) When the module does not produce any output on its own.
/// 2) When you already know the output of the module for the upcoming file to
/// be scanned, and you prefer to reuse this data instead of generating it again.
/// be scanned, and you prefer to reuse this data instead of generating it
/// again.
///
/// Case 1) applies to certain modules lacking a main function, thus incapable of
/// producing any output on their own. For such modules, you must set the output
Expand Down
44 changes: 22 additions & 22 deletions go/compiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ func TestNamespaces(t *testing.T) {
c.AddSource("rule test { condition: true }")

s := NewScanner(c.Build())
matchingRules, _ := s.Scan([]byte{})
assert.Len(t, matchingRules, 2)
scanResults, _ := s.Scan([]byte{})
assert.Len(t, scanResults.MatchingRules(), 2)
}

func TestUnsupportedModules(t *testing.T) {
Expand All @@ -26,17 +26,17 @@ func TestUnsupportedModules(t *testing.T) {
IgnoreModule("unsupported_module"))

assert.NoError(t, err)
matchingRules, _ := r.Scan([]byte{})
assert.Len(t, matchingRules, 1)
scanResults, _ := r.Scan([]byte{})
assert.Len(t, scanResults.MatchingRules(), 1)
}

func TestRelaxedReSyntax(t *testing.T) {
r, err := Compile(`
rule test { strings: $a = /\Release/ condition: $a }`,
RelaxedReSyntax(true))
assert.NoError(t, err)
matchingRules, _ := r.Scan([]byte("Release"))
assert.Len(t, matchingRules, 1)
scanResults, _ := r.Scan([]byte("Release"))
assert.Len(t, scanResults.MatchingRules(), 1)
}


Expand All @@ -55,51 +55,51 @@ func TestSerialization(t *testing.T) {
r, _ = Deserialize(b)

s := NewScanner(r)
matchingRules, _ := s.Scan([]byte{})
scanResults, _ := s.Scan([]byte{})

assert.Len(t, matchingRules, 1)
assert.Len(t, scanResults.MatchingRules(), 1)
}

func TestVariables(t *testing.T) {
r, _ := Compile(
"rule test { condition: var == 1234 }",
Globals(map[string]interface{}{"var": 1234}))

matchingRules, _ := NewScanner(r).Scan([]byte{})
assert.Len(t, matchingRules, 1)
scanResults, _ := NewScanner(r).Scan([]byte{})
assert.Len(t, scanResults.MatchingRules(), 1)

c, err := NewCompiler()
assert.NoError(t, err)

c.DefineGlobal("var", 1234)
c.AddSource("rule test { condition: var == 1234 }")
matchingRules, _ = NewScanner(c.Build()).Scan([]byte{})
assert.Len(t, matchingRules, 1)
scanResults, _ = NewScanner(c.Build()).Scan([]byte{})
assert.Len(t, scanResults.MatchingRules(), 1)

c.DefineGlobal("var", -1234)
c.AddSource("rule test { condition: var == -1234 }")
matchingRules, _ = NewScanner(c.Build()).Scan([]byte{})
assert.Len(t, matchingRules, 1)
scanResults, _ = NewScanner(c.Build()).Scan([]byte{})
assert.Len(t, scanResults.MatchingRules(), 1)

c.DefineGlobal("var", true)
c.AddSource("rule test { condition: var }")
matchingRules, _ = NewScanner(c.Build()).Scan([]byte{})
assert.Len(t, matchingRules, 1)
scanResults, _ = NewScanner(c.Build()).Scan([]byte{})
assert.Len(t, scanResults.MatchingRules(), 1)

c.DefineGlobal("var", false)
c.AddSource("rule test { condition: var }")
matchingRules, _ = NewScanner(c.Build()).Scan([]byte{})
assert.Len(t, matchingRules, 0)
scanResults, _ = NewScanner(c.Build()).Scan([]byte{})
assert.Len(t, scanResults.MatchingRules(), 0)

c.DefineGlobal("var", "foo")
c.AddSource("rule test { condition: var == \"foo\" }")
matchingRules, _ = NewScanner(c.Build()).Scan([]byte{})
assert.Len(t, matchingRules, 1)
scanResults, _ = NewScanner(c.Build()).Scan([]byte{})
assert.Len(t, scanResults.MatchingRules(), 1)

c.DefineGlobal("var", 3.4)
c.AddSource("rule test { condition: var == 3.4 }")
matchingRules, _ = NewScanner(c.Build()).Scan([]byte{})
assert.Len(t, matchingRules, 1)
scanResults, _ = NewScanner(c.Build()).Scan([]byte{})
assert.Len(t, scanResults.MatchingRules(), 1)

err = c.DefineGlobal("var", struct{}{})
assert.EqualError(t, err, "variable `var` has unsupported type: struct {}")
Expand Down
8 changes: 4 additions & 4 deletions go/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ rule bar {
}`)

// Use the compiled rules for scanning some data.
matchingRules, _ := rules.Scan([]byte("foobar"))
scanResults, _ := rules.Scan([]byte("foobar"))

// Iterate over the matching rules.
for _, r := range matchingRules {
for _, r := range scanResults.MatchingRules() {
fmt.Printf("rule %s matched\n", r.Identifier())
}

Expand Down Expand Up @@ -62,10 +62,10 @@ func Example_compilerAndScanner() {
scanner := NewScanner(rules)

// Use the scanner for scanning some data.
matchingRules, _ := scanner.Scan([]byte("foobar"))
scanResults, _ := scanner.Scan([]byte("foobar"))

// Iterate over the matching rules.
for _, r := range matchingRules {
for _, r := range scanResults.MatchingRules() {
fmt.Printf("rule %s matched\n", r.Identifier())
}

Expand Down
2 changes: 1 addition & 1 deletion go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ type Rules struct{ cRules *C.YRX_RULES }
// Scan some data with the compiled rules.
//
// Returns a slice with the rules that matched.
func (r *Rules) Scan(data []byte) ([]*Rule, error) {
func (r *Rules) Scan(data []byte) (*ScanResults, error) {
scanner := NewScanner(r)
return scanner.Scan(data)
}
Expand Down
20 changes: 15 additions & 5 deletions go/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,16 @@ type Scanner struct {
matchingRules []*Rule
}

type ScanResults struct{}

// ScanResults contains the results of a Scanner.Scan.
type ScanResults struct{
matchingRules []*Rule
}

// MatchingRules returns the rules that matched during the scan.
func (s ScanResults) MatchingRules() []*Rule {
return s.matchingRules
}

// NewScanner creates a Scanner that will use the provided YARA rules.
//
Expand Down Expand Up @@ -192,7 +201,7 @@ func (s *Scanner) SetModuleOutput(data proto.Message) error {
}

// Scan scans the provided data with the Rules associated to the Scanner.
func (s *Scanner) Scan(buf []byte) ([]*Rule, error) {
func (s *Scanner) Scan(buf []byte) (*ScanResults, error) {
var ptr *C.uint8_t
// When `buf` is an empty slice `ptr` will be nil. That's ok, because
// yrx_scanner_scan allows the data pointer to be null as long as the data
Expand All @@ -201,8 +210,6 @@ func (s *Scanner) Scan(buf []byte) ([]*Rule, error) {
ptr = (*C.uint8_t)(unsafe.Pointer(&(buf[0])))
}

s.matchingRules = nil

runtime.LockOSThread()
defer runtime.UnlockOSThread()

Expand All @@ -216,7 +223,10 @@ func (s *Scanner) Scan(buf []byte) ([]*Rule, error) {
err = errors.New(C.GoString(C.yrx_last_error()))
}

return s.matchingRules, err
scanResults := &ScanResults{ s.matchingRules }
s.matchingRules = nil

return scanResults, err
}

// Destroy destroys the scanner.
Expand Down
35 changes: 19 additions & 16 deletions go/scanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import (
func TestScanner1(t *testing.T) {
r, _ := Compile("rule t { condition: true }")
s := NewScanner(r)
matchingRules, _ := s.Scan([]byte{})
scanResults, _ := s.Scan([]byte{})
matchingRules := scanResults.MatchingRules()

assert.Len(t, matchingRules, 1)
assert.Equal(t, "t", matchingRules[0].Identifier())
Expand All @@ -23,7 +24,8 @@ func TestScanner1(t *testing.T) {
func TestScanner2(t *testing.T) {
r, _ := Compile(`rule t { strings: $bar = "bar" condition: $bar }`)
s := NewScanner(r)
matchingRules, _ := s.Scan([]byte("foobar"))
scanResults, _ := s.Scan([]byte("foobar"))
matchingRules := scanResults.MatchingRules()

assert.Len(t, matchingRules, 1)
assert.Equal(t, "t", matchingRules[0].Identifier())
Expand All @@ -44,12 +46,12 @@ func TestScanner3(t *testing.T) {
Globals(map[string]interface{}{"var_bool": true}))

s := NewScanner(r)
matchingRules, _ := s.Scan([]byte{})
assert.Len(t, matchingRules, 1)
scanResults, _ := s.Scan([]byte{})
assert.Len(t, scanResults.MatchingRules(), 1)

s.SetGlobal("var_bool", false)
matchingRules, _ = s.Scan([]byte{})
assert.Len(t, matchingRules, 0)
scanResults, _ = s.Scan([]byte{})
assert.Len(t, scanResults.MatchingRules(), 0)
}

func TestScanner4(t *testing.T) {
Expand All @@ -58,20 +60,20 @@ func TestScanner4(t *testing.T) {
Globals(map[string]interface{}{"var_int": 0}))

s := NewScanner(r)
matchingRules, _ := s.Scan([]byte{})
assert.Len(t, matchingRules, 0)
scanResults, _ := s.Scan([]byte{})
assert.Len(t, scanResults.MatchingRules(), 0)

assert.NoError(t, s.SetGlobal("var_int", 1))
matchingRules, _ = s.Scan([]byte{})
assert.Len(t, matchingRules, 1)
scanResults, _ = s.Scan([]byte{})
assert.Len(t, scanResults.MatchingRules(), 1)

assert.NoError(t, s.SetGlobal("var_int", int32(1)))
matchingRules, _ = s.Scan([]byte{})
assert.Len(t, matchingRules, 1)
scanResults, _ = s.Scan([]byte{})
assert.Len(t, scanResults.MatchingRules(), 1)

assert.NoError(t, s.SetGlobal("var_int", int64(1)))
matchingRules, _ = s.Scan([]byte{})
assert.Len(t, matchingRules, 1)
scanResults, _ = s.Scan([]byte{})
assert.Len(t, scanResults.MatchingRules(), 1)
}

func TestScannerTimeout(t *testing.T) {
Expand All @@ -94,7 +96,8 @@ func TestScannerMetadata(t *testing.T) {
true
}`)
s := NewScanner(r)
matchingRules, _ := s.Scan([]byte{})
scanResults, _ := s.Scan([]byte{})
matchingRules := scanResults.MatchingRules()

assert.Len(t, matchingRules, 1)
assert.Equal(t, "some_int", matchingRules[0].Metadata()[0].Identifier)
Expand All @@ -106,5 +109,5 @@ func TestScannerMetadata(t *testing.T) {
assert.Equal(t, "some_string", matchingRules[0].Metadata()[3].Identifier)
assert.Equal(t, "hello", matchingRules[0].Metadata()[3].Value)
assert.Equal(t, "some_bytes", matchingRules[0].Metadata()[4].Identifier)
assert.Equal(t, []byte{0, 1, 2}, matchingRules[0].Metadata()[4].Value)
assert.Equal(t, []byte{0, 1, 2}, matchingRules[0].Metadata()[4].Value)
}
Loading

0 comments on commit 8cc71ba

Please sign in to comment.