yara_x

package module
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 3, 2024 License: BSD-3-Clause Imports: 12 Imported by: 1

Documentation

Overview

Package yara_x provides Go bindings to the YARA-X library.

Example (Basic)
// Compile some YARA rules.
rules, _ := Compile(`
rule foo {
  strings:
    $foo = "foo"
  condition:
    $foo
}

rule bar {
  strings:
    $bar = "bar"
  condition:
    $bar
}`)

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

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

rule foo matched
rule bar matched
Example (CompilerAndScanner)
// Create a new compiler.
compiler, _ := NewCompiler()

// Add some rules to the compiler.
err := compiler.AddSource(`rule foo {
		strings:
		  $foo = "foo"
		condition:
          $foo
	}

    rule bar {
		strings:
		$bar = "bar"
		condition:
		$bar
	}`)

if err != nil {
	panic(err)
}

// Get the compiled rules.
rules := compiler.Build()

// Pass the compiled rules to a scanner.
scanner := NewScanner(rules)

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

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

rule foo matched
rule bar matched

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrTimeout = errors.New("timeout")

Functions

This section is empty.

Types

type CompileError added in v0.7.0

type CompileError struct {
	// Error code (e.g: "E001").
	Code string `json:"code"`
	// Error title (e.g: "unknown identifier `foo`").
	Title string `json:"title"`
	// Error line number. This is the line number of the first error label.
	Line int `json:"line"`
	// Error column number. This is the column number of the first error label.
	Column int `json:"column"`
	// Each of the labels in the error report.
	Labels []Label `json:"labels,omitempty"`
	// Each of the footers in the error report.
	Footers []Footer `json:"footers,omitempty"`
	// The error's full report, as shown by the command-line tool.
	Text string `json:"text"`
}

CompileError represents each of the errors returned by Compiler.Errors.

func (CompileError) Error added in v0.7.0

func (c CompileError) Error() string

Error returns the error's full report.

type CompileOption

type CompileOption func(c *Compiler) error

A CompileOption represent an option passed to NewCompiler and Compile.

func BanModule added in v0.9.0

func BanModule(module string, errTitle string, errMessage string) CompileOption

BanModule is an option for NewCompiler and Compile that allows banning the use of a given module.

Import statements for the banned module will cause an error. The error message can be customized by using the given error title and message.

If this function is called multiple times with the same module name, the error title and message will be updated.

func ErrorOnSlowLoop added in v0.9.0

func ErrorOnSlowLoop(yes bool) CompileOption

ErrorOnSlowLoop is an option for NewCompiler and Compile that tells the compiler to treat slow loops as errors instead of warnings.

func ErrorOnSlowPattern added in v0.4.0

func ErrorOnSlowPattern(yes bool) CompileOption

ErrorOnSlowPattern is an option for NewCompiler and Compile that tells the compiler to treat slow patterns as errors instead of warnings.

func Globals

func Globals(vars map[string]interface{}) CompileOption

The Globals option for NewCompiler and Compile allows you to define global variables.

Keys in the map represent variable names, and values are their initial values. Values associated with variables can be modified at scan time using Scanner.SetGlobal. If this option is used multiple times, global variables will be the union of all specified maps. If the same variable appears in multiple maps, the value from the last map will prevail.

Alternatively, you can use Compiler.DefineGlobal to define global variables. However, variables defined this way are not retained after Compiler.Build is called, unlike variables defined with the Globals option.

Valid value types include: int, int32, int64, bool, string, float32 and float64.

func IgnoreModule

func IgnoreModule(module string) CompileOption

IgnoreModule is an option for NewCompiler and Compile that allows ignoring a given module.

This option can be passed multiple times with different module names. Alternatively, you can use [Compiler.IgnoreModule], but modules ignored this way are not retained after Compiler.Build is called, unlike modules ignored with the IgnoreModule option.

func RelaxedReSyntax added in v0.3.0

func RelaxedReSyntax(yes bool) CompileOption

RelaxedReSyntax is an option for NewCompiler and Compile that determines whether the compiler should adopt a more relaxed approach while parsing regular expressions.

YARA-X enforces stricter regular expression syntax compared to YARA. For instance, YARA accepts invalid escape sequences and treats them as literal characters (e.g., \R is interpreted as a literal 'R'). It also allows some special characters to appear unescaped, inferring their meaning from the context (e.g., `{` and `}` in `/foo{}bar/` are literal, but in `/foo{0,1}bar/` they form the repetition operator `{0,1}`).

When this option is set, YARA-X mimics YARA's behavior, allowing constructs that YARA-X doesn't accept by default.

type Compiler

type Compiler struct {
	// contains filtered or unexported fields
}

Compiler represent a YARA compiler.

func NewCompiler

func NewCompiler(opts ...CompileOption) (*Compiler, error)

NewCompiler creates a new compiler.

func (*Compiler) AddSource

func (c *Compiler) AddSource(src string, opts ...SourceOption) error

AddSource adds some YARA source code to be compiled.

This method may be invoked multiple times to add several sets of YARA rules. If the rules provided in src contain errors that prevent compilation, the first error encountered will be returned. Additionally, the compiler will store this error, along with any others discovered during compilation, which can be accessed using Compiler.Errors.

Even if a previous invocation resulted in a compilation error, you can continue calling this method for adding more rules. In such cases, any rules that failed to compile will not be included in the final compiled Rules.

When adding rules to the compiler you can also provide a string containing information about the origin of the rules using the WithOrigin option. The origin is usually the path of the file containing the rules, but it can be any string that conveys information about the origin of the rules.

Examples:

c := NewCompiler()
c.AddSource("rule foo { condition: true }")
c.AddSource("rule bar { condition: true }")
c.AddSource("rule baz { condition: true }", WithOrigin("baz.yar"))

func (*Compiler) Build

func (c *Compiler) Build() *Rules

Build creates a Rules object containing a compiled version of all the YARA rules previously added to the compiler.

Once this method is called the compiler is reset to its initial state (i.e: the state it had after NewCompiler returned).

func (*Compiler) DefineGlobal

func (c *Compiler) DefineGlobal(ident string, value interface{}) error

DefineGlobal defines a global variable and sets its initial value.

Global variables must be defined before using Compiler.AddSource for adding any YARA source code that uses those variables. The variable will retain its initial value when the compiled Rules are used for scanning data, however each scanner can change the variable's initial value by calling Scanner.SetGlobal.

Valid value types are: int, int32, int64, bool, string, float32 and float64.

func (*Compiler) Destroy

func (c *Compiler) Destroy()

Destroy destroys the compiler.

Calling Destroy is not required, but it's useful for explicitly freeing the memory used by the compiler.

func (*Compiler) Errors added in v0.7.0

func (c *Compiler) Errors() []CompileError

Errors that occurred during the compilation, across multiple calls to Compiler.AddSource.

func (*Compiler) NewNamespace

func (c *Compiler) NewNamespace(namespace string)

NewNamespace creates a new namespace.

Later calls to Compiler.AddSource will put the rules under the newly created namespace.

Examples:

c := NewCompiler()
// Add some rule named "foo" under the default namespace
c.AddSource("rule foo { condition: true }")

// Create a new namespace named "bar"
c.NewNamespace("bar")

// It's ok to add another rule named "foo", as it is in a different
// namespace than the previous one.
c.AddSource("rule foo { condition: true }")

func (*Compiler) Warnings added in v0.7.0

func (c *Compiler) Warnings() []Warning

Warnings that occurred during the compilation, across multiple calls to Compiler.AddSource.

type Footer struct {
	// Footer's level (e.g: "error", "warning", "info", "note", "help").
	Level string `json:"level"`
	// Footer's text.
	Text string `json:"text"`
}

Footer represents a footer in a CompileError.

type Label added in v0.7.0

type Label struct {
	// Label's level (e.g: "error", "warning", "info", "note", "help").
	Level string `json:"level"`
	// Origin of the code where the error occurred.
	CodeOrigin string `json:"code_origin"`
	// Line number
	Line int64 `json:"line"`
	// Column number
	Column int64 `json:"column"`
	// The code span highlighted by this label.
	Span Span `json:"span"`
	// Text associated to the label.
	Text string `json:"text"`
}

Label represents a label in a CompileError.

type Match

type Match struct {
	// contains filtered or unexported fields
}

Match contains information about the offset where a match occurred and the length of the match.

func (*Match) Length

func (m *Match) Length() uint64

Length returns the length of a match in bytes.

func (*Match) Offset

func (m *Match) Offset() uint64

Offset returns the offset within the scanned data where a match occurred.

type Metadata added in v0.4.0

type Metadata struct {
	// contains filtered or unexported fields
}

Metadata represents a metadata in a Rule.

func (*Metadata) Identifier added in v0.4.0

func (m *Metadata) Identifier() string

Identifier associated to the metadata.

func (*Metadata) Value added in v0.4.0

func (m *Metadata) Value() interface{}

Value associated to the metadata.

type Pattern

type Pattern struct {
	// contains filtered or unexported fields
}

Pattern represents a pattern in a Rule.

func (*Pattern) Identifier

func (p *Pattern) Identifier() string

Identifier returns the pattern's identifier (i.e: $a, $foo).

func (*Pattern) Matches

func (p *Pattern) Matches() []Match

Matches returns the matches found for this pattern.

type Rule

type Rule struct {
	// contains filtered or unexported fields
}

Rule represents a YARA rule.

func (*Rule) Identifier

func (r *Rule) Identifier() string

Identifier returns the rule's identifier.

func (*Rule) Metadata added in v0.4.0

func (r *Rule) Metadata() []Metadata

Metadata returns the rule's metadata

func (*Rule) Namespace

func (r *Rule) Namespace() string

Namespace returns the rule's namespace.

func (*Rule) Patterns

func (r *Rule) Patterns() []Pattern

Patterns returns the patterns defined by this rule.

type Rules

type Rules struct {
	// contains filtered or unexported fields
}

Rules represents a set of compiled YARA rules.

func Compile

func Compile(src string, opts ...CompileOption) (*Rules, error)

Compile receives YARA source code and returns compiled Rules that can be used for scanning data.

func ReadFrom added in v0.9.0

func ReadFrom(r io.Reader) (*Rules, error)

ReadFrom reads compiled rules from a reader.

The counterpart is Rules.WriteTo.

func (*Rules) Count added in v0.9.0

func (r *Rules) Count() int

Count returns the total number of rules.

This is more a more efficient alternative to len(rules.Slice()).

func (*Rules) Destroy

func (r *Rules) Destroy()

Destroy destroys the compiled YARA rules represented by Rules.

Calling this method directly is not necessary, it will be invoked by the garbage collector when the rules are not used anymore.

func (*Rules) Imports added in v0.9.0

func (r *Rules) Imports() []string

Imports returns the names of the imported modules.

func (*Rules) Scan

func (r *Rules) Scan(data []byte) (*ScanResults, error)

Scan some data with the compiled rules.

func (*Rules) Slice added in v0.9.0

func (r *Rules) Slice() []*Rule

Slice returns a slice with all the individual rules contained in this set of compiled rules.

func (*Rules) WriteTo added in v0.9.0

func (r *Rules) WriteTo(w io.Writer) (int64, error)

WriteTo writes the compiled rules into a writer.

The counterpart is ReadFrom.

type ScanResults

type ScanResults struct {
	// contains filtered or unexported fields
}

ScanResults contains the results of a call to Scanner.Scan or Rules.Scan.

func (ScanResults) MatchingRules added in v0.7.0

func (s ScanResults) MatchingRules() []*Rule

MatchingRules returns the rules that matched during the scan.

type Scanner

type Scanner struct {
	// contains filtered or unexported fields
}

Scanner scans data with a set of compiled YARA rules.

func NewScanner

func NewScanner(r *Rules) *Scanner

NewScanner creates a Scanner that will use the provided YARA rules.

It's safe to pass the same Rules to multiple scanners, and use each scanner on a separate goroutine for performing multiple scans in parallel with the same set of rules.

func (*Scanner) Destroy

func (s *Scanner) Destroy()

Destroy destroys the scanner.

Calling this method directly is not necessary, it will be invoked by the garbage collector when the scanner is not used anymore.

func (*Scanner) Scan

func (s *Scanner) Scan(buf []byte) (*ScanResults, error)

Scan scans the provided data with the Rules associated to the Scanner.

func (*Scanner) SetGlobal

func (s *Scanner) SetGlobal(ident string, value interface{}) error

SetGlobal sets the value of a global variable.

The variable must has been previously defined by calling Compiler.DefineGlobal and the type it has during the definition must match the type of the new value.

The variable will retain the new value in subsequent scans, unless this method is called again for setting a new value.

func (*Scanner) SetModuleOutput

func (s *Scanner) SetModuleOutput(data proto.Message) error

SetModuleOutput sets the output data for a YARA module.

Each YARA module generates an output consisting of a data structure that contains information about the scanned file. This data structure is represented by a Protocol Buffer. Typically, you won't need to provide this data yourself, as the YARA module automatically generates different outputs for each file it scans.

However, there are two scenarios in which you may want to provide the output for a module yourself:

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.

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 before scanning the associated data. Since the module's output typically varies with each scanned file, you need to call this method prior to each invocation of Scanner.Scan. Once Scanner.Scan is executed, the module's output is consumed and will be empty unless set again before the subsequent call.

Case 2) applies when you have previously stored the module's output for certain scanned data. In such cases, when rescanning the data, you can utilize this method to supply the module's output, thereby preventing redundant computation by the module. This optimization enhances performance by eliminating the need for the module to reparse the scanned data.

The data argument must be a Protocol Buffer message corresponding to any of the existing YARA modules.

func (*Scanner) SetTimeout

func (s *Scanner) SetTimeout(timeout time.Duration)

SetTimeout sets a timeout for scan operations.

The Scanner.Scan method will return a timeout error once the provided timeout duration has elapsed. The scanner will make every effort to stop promptly after the designated timeout duration. However, in some cases, particularly with rules containing only a few patterns, the scanner could potentially continue running for a longer period than the specified timeout.

type SourceOption added in v0.7.0

type SourceOption func(opt *sourceOptions) error

A SourceOption represent an option passed to Compiler.AddSource.

func WithOrigin added in v0.7.0

func WithOrigin(origin string) SourceOption

WithOrigin is an option for Compiler.AddSource that specifies the origin of the source code.

The origin is usually the path of the file containing the source code, but it can be any arbitrary string that conveys information of the source's origin. This origin appears in error reports, for instance, if origin is "some_file.yar", error reports will look like:

error: syntax error
 --> some_file.yar:4:17
  |
4 | ... more details

Example:

c := NewCompiler()
c.AddSource("rule some_rule { condition: true }", WithOrigin("some_file.yar"))

type Span added in v0.7.0

type Span struct {
	Start int `json:"start"`
	End   int `json:"end"`
}

Span represents the starting and ending point of some piece of source code.

type Warning added in v0.7.0

type Warning struct {
	// Warning code (e.g: "slow_pattern").
	Code string `json:"code"`
	// Warning title (e.g: "slow pattern").
	Title string `json:"title"`
	// Warning line number. This is the line number of the first warning label.
	Line int `json:"line"`
	// Warning column number. This is the column number of the first warning label.
	Column int `json:"column"`
	// Each of the labels in the warning report.
	Labels []Label `json:"labels,omitempty"`
	// Each of the footers in the warning report.
	Footers []Footer `json:"footers,omitempty"`
	// The error's full report, as shown by the command-line tool.
	Text string `json:"text"`
}

Warning represents each of the warnings returned by Compiler.Warnings.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL