yara-ffi 3.1.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/copilot-instructions.md +148 -0
- data/.github/workflows/ruby.yml +69 -17
- data/CHANGELOG.md +59 -1
- data/DEVELOPMENT.md +188 -0
- data/Dockerfile +19 -11
- data/Gemfile.lock +38 -23
- data/README.md +129 -14
- data/lib/yara/ffi.rb +300 -111
- data/lib/yara/scan_result.rb +171 -82
- data/lib/yara/scan_results.rb +224 -0
- data/lib/yara/scanner.rb +236 -48
- data/lib/yara/version.rb +5 -1
- data/lib/yara.rb +70 -15
- data/yara-ffi.gemspec +3 -3
- metadata +9 -14
- data/lib/yara/user_data.rb +0 -5
- data/lib/yara/yr_meta.rb +0 -10
- data/lib/yara/yr_namespace.rb +0 -5
- data/lib/yara/yr_rule.rb +0 -11
- data/lib/yara/yr_string.rb +0 -15
data/README.md
CHANGED
@@ -1,13 +1,18 @@
|
|
1
1
|
# yara-ffi
|
2
2
|
|
3
|
-
A Ruby library for using [
|
3
|
+
A Ruby library for using [YARA-X](https://virustotal.github.io/yara-x/) via FFI bindings. YARA-X is a modern, Rust-based implementation of YARA that's faster and safer than the original C implementation.
|
4
|
+
|
5
|
+
## Requirements
|
6
|
+
|
7
|
+
- Ruby 3.0 or later
|
8
|
+
- YARA-X C API library (`libyara_x_capi`) installed on your system
|
4
9
|
|
5
10
|
## Installation
|
6
11
|
|
7
12
|
Add this line to your application's Gemfile:
|
8
13
|
|
9
14
|
```ruby
|
10
|
-
gem "yara"
|
15
|
+
gem "yara-ffi"
|
11
16
|
```
|
12
17
|
|
13
18
|
And then execute:
|
@@ -20,20 +25,51 @@ Or install it yourself as:
|
|
20
25
|
|
21
26
|
## Usage
|
22
27
|
|
28
|
+
### Quick scanning with convenience methods
|
29
|
+
|
23
30
|
```ruby
|
24
|
-
|
31
|
+
rule = <<-RULE
|
32
|
+
rule ExampleRule
|
33
|
+
{
|
34
|
+
meta:
|
35
|
+
description = "Example rule for testing"
|
25
36
|
|
37
|
+
strings:
|
38
|
+
$text_string = "we were here"
|
39
|
+
$text_regex = /were here/
|
40
|
+
|
41
|
+
condition:
|
42
|
+
$text_string or $text_regex
|
43
|
+
}
|
44
|
+
RULE
|
45
|
+
|
46
|
+
# Test a rule against data
|
47
|
+
results = Yara.test(rule, "one day we were here and then we were not")
|
48
|
+
puts results.first.match? # => true
|
49
|
+
puts results.first.rule_name # => "ExampleRule"
|
50
|
+
|
51
|
+
# Scan with a block for processing results
|
52
|
+
Yara.scan(rule, "sample data") do |result|
|
53
|
+
puts "Matched: #{result.rule_name}"
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
### Manual scanner usage
|
58
|
+
|
59
|
+
```ruby
|
26
60
|
rule = <<-RULE
|
27
61
|
rule ExampleRule
|
28
62
|
{
|
29
|
-
meta:
|
63
|
+
meta:
|
30
64
|
string_meta = "an example rule for testing"
|
65
|
+
int_meta = 42
|
66
|
+
bool_meta = true
|
31
67
|
|
32
|
-
strings:
|
68
|
+
strings:
|
33
69
|
$my_text_string = "we were here"
|
34
70
|
$my_text_regex = /were here/
|
35
71
|
|
36
|
-
condition:
|
72
|
+
condition:
|
37
73
|
$my_text_string or $my_text_regex
|
38
74
|
}
|
39
75
|
RULE
|
@@ -41,21 +77,100 @@ RULE
|
|
41
77
|
scanner = Yara::Scanner.new
|
42
78
|
scanner.add_rule(rule)
|
43
79
|
scanner.compile
|
44
|
-
result = scanner.call("one day we were here and then we were not").first
|
45
|
-
result.match?
|
46
|
-
# => true
|
47
80
|
|
48
|
-
scanner.
|
49
|
-
|
81
|
+
results = scanner.scan("one day we were here and then we were not")
|
82
|
+
result = results.first
|
83
|
+
|
84
|
+
puts result.match? # => true
|
85
|
+
puts result.rule_name # => "ExampleRule"
|
86
|
+
puts result.rule_meta # => {:string_meta=>"an example rule for testing", :int_meta=>42, :bool_meta=>true}
|
87
|
+
puts result.rule_strings # => {:"$my_text_string"=>"we were here", :"$my_text_regex"=>"were here"}
|
88
|
+
|
89
|
+
scanner.close # Clean up resources when done
|
90
|
+
```
|
91
|
+
|
92
|
+
### Block-based scanner usage
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
# Automatically handles resource cleanup
|
96
|
+
Yara::Scanner.open(rule) do |scanner|
|
97
|
+
scanner.compile
|
98
|
+
results = scanner.scan("test data")
|
99
|
+
# scanner is automatically closed when block exits
|
100
|
+
end
|
101
|
+
```
|
102
|
+
|
103
|
+
### Multiple rules
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
rule1 = <<-RULE
|
107
|
+
rule RuleOne
|
108
|
+
{
|
109
|
+
strings:
|
110
|
+
$a = "pattern one"
|
111
|
+
condition:
|
112
|
+
$a
|
113
|
+
}
|
114
|
+
RULE
|
115
|
+
|
116
|
+
rule2 = <<-RULE
|
117
|
+
rule RuleTwo
|
118
|
+
{
|
119
|
+
strings:
|
120
|
+
$b = "pattern two"
|
121
|
+
condition:
|
122
|
+
$b
|
123
|
+
}
|
124
|
+
RULE
|
125
|
+
|
126
|
+
scanner = Yara::Scanner.new
|
127
|
+
scanner.add_rule(rule1)
|
128
|
+
scanner.add_rule(rule2)
|
129
|
+
scanner.compile
|
130
|
+
|
131
|
+
results = scanner.scan("text with pattern one and pattern two")
|
132
|
+
puts results.map(&:rule_name) # => ["RuleOne", "RuleTwo"]
|
133
|
+
scanner.close
|
50
134
|
```
|
51
135
|
|
136
|
+
## API Reference
|
137
|
+
|
138
|
+
### Yara module methods
|
139
|
+
|
140
|
+
- `Yara.test(rule_string, data)` - Quick test of a rule against data, returns array of ScanResult objects
|
141
|
+
- `Yara.scan(rule_string, data, &block)` - Scan data with rule, optionally yielding each result to block
|
142
|
+
|
143
|
+
### Scanner class
|
144
|
+
|
145
|
+
- `Scanner.new` - Create a new scanner instance
|
146
|
+
- `Scanner.open(rule_string, namespace: nil, &block)` - Create scanner with optional rule and namespace, auto-cleanup with block
|
147
|
+
- `#add_rule(rule_string, namespace: nil)` - Add a YARA rule to the scanner
|
148
|
+
- `#compile` - Compile all added rules (required before scanning)
|
149
|
+
- `#scan(data, &block)` - Scan data and return ScanResults, or yield each result to block
|
150
|
+
- `#close` - Free scanner resources
|
151
|
+
|
152
|
+
### ScanResult class
|
153
|
+
|
154
|
+
- `#match?` - Returns true if rule matched
|
155
|
+
- `#rule_name` - Name of the matched rule
|
156
|
+
- `#rule_meta` - Hash of rule metadata (keys are symbols)
|
157
|
+
- `#rule_strings` - Hash of rule strings (keys are symbols with $ prefix)
|
158
|
+
|
159
|
+
## Installing YARA-X
|
160
|
+
|
161
|
+
You'll need the YARA-X C API library installed on your system. You can:
|
162
|
+
|
163
|
+
1. Build from source: https://github.com/VirusTotal/yara-x
|
164
|
+
2. Install via package manager (when available)
|
165
|
+
3. Use the provided Docker environment
|
166
|
+
|
52
167
|
## Development
|
53
168
|
|
54
|
-
|
169
|
+
See [DEVELOPMENT.md](DEVELOPMENT.md) for detailed development setup instructions, testing guidelines, and contribution workflow.
|
55
170
|
|
56
171
|
## Contributing
|
57
172
|
|
58
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/jonmagic/yara-ffi. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/jonmagic/yara-ffi/blob/
|
173
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/jonmagic/yara-ffi. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/jonmagic/yara-ffi/blob/main/CODE_OF_CONDUCT.md).
|
59
174
|
|
60
175
|
## License
|
61
176
|
|
@@ -63,4 +178,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
63
178
|
|
64
179
|
## Code of Conduct
|
65
180
|
|
66
|
-
Everyone interacting in the
|
181
|
+
Everyone interacting in the yara-ffi project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/jonmagic/yara-ffi/blob/main/CODE_OF_CONDUCT.md).
|
data/lib/yara/ffi.rb
CHANGED
@@ -1,116 +1,305 @@
|
|
1
|
-
require_relative "yr_meta"
|
2
|
-
require_relative "yr_namespace"
|
3
|
-
require_relative "yr_string"
|
4
|
-
require_relative "yr_rule"
|
5
|
-
require_relative "user_data"
|
6
|
-
|
7
1
|
module Yara
|
8
|
-
# FFI bindings to
|
2
|
+
# Internal: Low-level FFI bindings to the YARA-X C API.
|
3
|
+
#
|
4
|
+
# This module provides direct Ruby FFI bindings to the yara_x_capi library.
|
5
|
+
# It handles dynamic library loading with multiple fallback paths and exposes
|
6
|
+
# the raw C functions for rule compilation, scanning, and resource management.
|
7
|
+
#
|
8
|
+
# The FFI module is primarily used internally by higher-level classes like
|
9
|
+
# Scanner. Direct usage requires careful memory management and error handling.
|
10
|
+
#
|
11
|
+
# Examples
|
12
|
+
#
|
13
|
+
# # Direct FFI usage (not recommended for normal use)
|
14
|
+
# rules_ptr = FFI::MemoryPointer.new(:pointer)
|
15
|
+
# result = Yara::FFI.yrx_compile("rule test { condition: true }", rules_ptr)
|
16
|
+
# raise "Error: #{Yara::FFI.yrx_last_error}" unless result == Yara::FFI::YRX_SUCCESS
|
9
17
|
module FFI
|
10
18
|
extend ::FFI::Library
|
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
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
19
|
+
|
20
|
+
# Internal: Library search paths for yara_x_capi shared library.
|
21
|
+
#
|
22
|
+
# These paths are tried in order to locate the YARA-X C API library.
|
23
|
+
# The first successful load is used. This supports various deployment
|
24
|
+
# scenarios including system packages, Docker containers, and CI environments.
|
25
|
+
library_paths = [
|
26
|
+
"yara_x_capi", # System library (preferred)
|
27
|
+
"/usr/local/lib/x86_64-linux-gnu/libyara_x_capi.so", # GitHub Actions/CI
|
28
|
+
"/usr/local/lib/aarch64-linux-gnu/libyara_x_capi.so", # Local Docker (ARM)
|
29
|
+
"/usr/local/lib/libyara_x_capi.so", # Generic fallback
|
30
|
+
"libyara_x_capi" # Final fallback
|
31
|
+
]
|
32
|
+
|
33
|
+
library_loaded = false
|
34
|
+
library_paths.each do |path|
|
35
|
+
begin
|
36
|
+
ffi_lib path
|
37
|
+
library_loaded = true
|
38
|
+
break
|
39
|
+
rescue LoadError
|
40
|
+
next
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
raise LoadError, "Could not load yara_x_capi library from any of: #{library_paths.join(', ')}" unless library_loaded
|
45
|
+
|
46
|
+
# Public: Compile YARA rule source into executable rules object.
|
47
|
+
#
|
48
|
+
# This is the primary compilation function that parses YARA rule source code
|
49
|
+
# and creates an optimized rules object for scanning. The rules object must
|
50
|
+
# be freed with yrx_rules_destroy when no longer needed.
|
51
|
+
#
|
52
|
+
# src - A String containing YARA rule source code
|
53
|
+
# rules - A FFI::MemoryPointer that will receive the rules object pointer
|
54
|
+
#
|
55
|
+
# Examples
|
56
|
+
#
|
57
|
+
# rules_ptr = FFI::MemoryPointer.new(:pointer)
|
58
|
+
# result = Yara::FFI.yrx_compile(rule_source, rules_ptr)
|
59
|
+
#
|
60
|
+
# Returns an Integer result code (YRX_SUCCESS on success).
|
61
|
+
# C Signature: enum YRX_RESULT yrx_compile(const char *src, struct YRX_RULES **rules)
|
62
|
+
attach_function :yrx_compile, [:string, :pointer], :int
|
63
|
+
|
64
|
+
# Public: Get the last error message from YARA-X operations.
|
65
|
+
#
|
66
|
+
# When any YARA-X function returns an error code, this function provides
|
67
|
+
# a human-readable description of what went wrong. The returned string
|
68
|
+
# is managed by YARA-X and should not be freed.
|
69
|
+
#
|
70
|
+
# Examples
|
71
|
+
#
|
72
|
+
# if result != YRX_SUCCESS
|
73
|
+
# error_msg = Yara::FFI.yrx_last_error
|
74
|
+
# raise "YARA Error: #{error_msg}"
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# Returns a String containing the last error message.
|
78
|
+
# C Signature: const char* yrx_last_error(void)
|
79
|
+
attach_function :yrx_last_error, [], :string
|
80
|
+
|
81
|
+
# Public: Free memory associated with a compiled rules object.
|
82
|
+
#
|
83
|
+
# This function must be called to free the memory allocated by yrx_compile.
|
84
|
+
# After calling this function, the rules pointer becomes invalid and should
|
85
|
+
# not be used.
|
86
|
+
#
|
87
|
+
# rules - A Pointer to the rules object to destroy
|
88
|
+
#
|
89
|
+
# Examples
|
90
|
+
#
|
91
|
+
# Yara::FFI.yrx_rules_destroy(rules_ptr)
|
92
|
+
#
|
93
|
+
# Returns nothing.
|
94
|
+
# C Signature: void yrx_rules_destroy(struct YRX_RULES *rules)
|
95
|
+
attach_function :yrx_rules_destroy, [:pointer], :void
|
96
|
+
|
97
|
+
# Public: Create a scanner object from compiled rules.
|
98
|
+
#
|
99
|
+
# A scanner is needed to perform actual pattern matching against data.
|
100
|
+
# Multiple scanners can be created from the same rules object to enable
|
101
|
+
# concurrent scanning. The scanner must be freed with yrx_scanner_destroy.
|
102
|
+
#
|
103
|
+
# rules - A Pointer to compiled rules object
|
104
|
+
# scanner - A FFI::MemoryPointer that will receive the scanner object pointer
|
105
|
+
#
|
106
|
+
# Examples
|
107
|
+
#
|
108
|
+
# scanner_ptr = FFI::MemoryPointer.new(:pointer)
|
109
|
+
# result = Yara::FFI.yrx_scanner_create(rules_ptr, scanner_ptr)
|
110
|
+
#
|
111
|
+
# Returns an Integer result code (YRX_SUCCESS on success).
|
112
|
+
# C Signature: enum YRX_RESULT yrx_scanner_create(const struct YRX_RULES *rules, struct YRX_SCANNER **scanner)
|
113
|
+
attach_function :yrx_scanner_create, [:pointer, :pointer], :int
|
114
|
+
|
115
|
+
# Public: Free memory associated with a scanner object.
|
116
|
+
#
|
117
|
+
# This function must be called to free the memory allocated by
|
118
|
+
# yrx_scanner_create. After calling this function, the scanner pointer
|
119
|
+
# becomes invalid and should not be used.
|
120
|
+
#
|
121
|
+
# scanner - A Pointer to the scanner object to destroy
|
122
|
+
#
|
123
|
+
# Examples
|
124
|
+
#
|
125
|
+
# Yara::FFI.yrx_scanner_destroy(scanner_ptr)
|
126
|
+
#
|
127
|
+
# Returns nothing.
|
128
|
+
# C Signature: void yrx_scanner_destroy(struct YRX_SCANNER *scanner)
|
129
|
+
attach_function :yrx_scanner_destroy, [:pointer], :void
|
130
|
+
|
131
|
+
# Internal: Callback function type for rule matching events.
|
132
|
+
#
|
133
|
+
# This callback is invoked for each rule that matches during scanning.
|
134
|
+
# The callback receives pointers to the matching rule and optional user data.
|
135
|
+
#
|
136
|
+
# rule - A Pointer to the YRX_RULE structure
|
137
|
+
# user_data - A Pointer to optional user-provided data
|
138
|
+
#
|
139
|
+
# C Signature: typedef void (*YRX_ON_MATCHING_RULE)(const struct YRX_RULE *rule, void *user_data)
|
140
|
+
callback :matching_rule_callback, [:pointer, :pointer], :void
|
141
|
+
|
142
|
+
# Public: Set callback for handling rule matches during scanning.
|
143
|
+
#
|
144
|
+
# This function registers a callback that will be invoked each time a rule
|
145
|
+
# matches during scanning. The callback can extract information about the
|
146
|
+
# matching rule and optionally halt scanning.
|
147
|
+
#
|
148
|
+
# scanner - A Pointer to the scanner object
|
149
|
+
# callback - A Proc matching the matching_rule_callback signature
|
150
|
+
# user_data - A Pointer to optional data passed to callback (can be nil)
|
151
|
+
#
|
152
|
+
# Examples
|
153
|
+
#
|
154
|
+
# callback = proc { |rule_ptr, user_data| puts "Rule matched!" }
|
155
|
+
# result = Yara::FFI.yrx_scanner_on_matching_rule(scanner_ptr, callback, nil)
|
156
|
+
#
|
157
|
+
# Returns an Integer result code (YRX_SUCCESS on success).
|
158
|
+
# C Signature: enum YRX_RESULT yrx_scanner_on_matching_rule(struct YRX_SCANNER *scanner, YRX_ON_MATCHING_RULE callback, void *user_data)
|
159
|
+
attach_function :yrx_scanner_on_matching_rule, [:pointer, :matching_rule_callback, :pointer], :int
|
160
|
+
|
161
|
+
# Public: Scan data using the configured scanner and rules.
|
162
|
+
#
|
163
|
+
# This function performs pattern matching against the provided data using
|
164
|
+
# all rules in the scanner. Any matching rules trigger the registered
|
165
|
+
# callback function. The data is scanned as binary regardless of content.
|
166
|
+
#
|
167
|
+
# scanner - A Pointer to the scanner object
|
168
|
+
# data - A Pointer to the data buffer to scan
|
169
|
+
# len - A size_t indicating the length of data in bytes
|
170
|
+
#
|
171
|
+
# Examples
|
172
|
+
#
|
173
|
+
# data_ptr = FFI::MemoryPointer.new(:char, data.bytesize)
|
174
|
+
# data_ptr.put_bytes(0, data)
|
175
|
+
# result = Yara::FFI.yrx_scanner_scan(scanner_ptr, data_ptr, data.bytesize)
|
176
|
+
#
|
177
|
+
# Returns an Integer result code (YRX_SUCCESS on success).
|
178
|
+
# C Signature: enum YRX_RESULT yrx_scanner_scan(struct YRX_SCANNER *scanner, const uint8_t *data, size_t len)
|
179
|
+
attach_function :yrx_scanner_scan, [:pointer, :pointer, :size_t], :int
|
180
|
+
|
181
|
+
# Public: Extract the identifier (name) from a rule object.
|
182
|
+
#
|
183
|
+
# This function retrieves the rule name from a YRX_RULE pointer, typically
|
184
|
+
# called from within a matching rule callback. The identifier is returned
|
185
|
+
# as a pointer and length rather than a null-terminated string.
|
186
|
+
#
|
187
|
+
# rule - A Pointer to the YRX_RULE structure
|
188
|
+
# ident - A FFI::MemoryPointer that will receive the identifier pointer
|
189
|
+
# len - A FFI::MemoryPointer that will receive the identifier length
|
190
|
+
#
|
191
|
+
# Examples
|
192
|
+
#
|
193
|
+
# ident_ptr = FFI::MemoryPointer.new(:pointer)
|
194
|
+
# len_ptr = FFI::MemoryPointer.new(:size_t)
|
195
|
+
# result = Yara::FFI.yrx_rule_identifier(rule_ptr, ident_ptr, len_ptr)
|
196
|
+
#
|
197
|
+
# Returns an Integer result code (YRX_SUCCESS on success).
|
198
|
+
# C Signature: enum YRX_RESULT yrx_rule_identifier(const struct YRX_RULE *rule, const uint8_t **ident, size_t *len)
|
199
|
+
attach_function :yrx_rule_identifier, [:pointer, :pointer, :pointer], :int
|
200
|
+
|
201
|
+
# Internal: Callback function type for metadata iteration.
|
202
|
+
#
|
203
|
+
# This callback is invoked for each metadata entry during rule metadata
|
204
|
+
# iteration. The callback receives pointers to the metadata and user data.
|
205
|
+
#
|
206
|
+
# metadata - A Pointer to the YRX_METADATA structure
|
207
|
+
# user_data - A Pointer to optional user-provided data
|
208
|
+
#
|
209
|
+
# C Signature: typedef void (*YRX_METADATA_CALLBACK)(const struct YRX_METADATA *metadata, void *user_data)
|
210
|
+
callback :metadata_callback, [:pointer, :pointer], :void
|
211
|
+
|
212
|
+
# Public: Iterate through all metadata entries in a rule.
|
213
|
+
#
|
214
|
+
# This function calls the provided callback for each metadata key-value pair
|
215
|
+
# defined in the rule. Metadata includes information like author, description,
|
216
|
+
# and custom tags defined in the rule's meta section.
|
217
|
+
#
|
218
|
+
# rule - A Pointer to the YRX_RULE structure
|
219
|
+
# callback - A Proc matching the metadata_callback signature
|
220
|
+
# user_data - A Pointer to optional data passed to callback (can be nil)
|
221
|
+
#
|
222
|
+
# Examples
|
223
|
+
#
|
224
|
+
# callback = proc { |metadata_ptr, user_data| puts "Found metadata" }
|
225
|
+
# result = Yara::FFI.yrx_rule_iter_metadata(rule_ptr, callback, nil)
|
226
|
+
#
|
227
|
+
# Returns an Integer result code (YRX_SUCCESS on success).
|
228
|
+
# C Signature: enum YRX_RESULT yrx_rule_iter_metadata(const struct YRX_RULE *rule, YRX_METADATA_CALLBACK callback, void *user_data)
|
229
|
+
attach_function :yrx_rule_iter_metadata, [:pointer, :metadata_callback, :pointer], :int
|
230
|
+
|
231
|
+
# Internal: Callback function type for pattern iteration.
|
232
|
+
#
|
233
|
+
# This callback is invoked for each pattern (string) during rule pattern
|
234
|
+
# iteration. The callback receives pointers to the pattern and user data.
|
235
|
+
#
|
236
|
+
# pattern - A Pointer to the YRX_PATTERN structure
|
237
|
+
# user_data - A Pointer to optional user-provided data
|
238
|
+
#
|
239
|
+
# C Signature: typedef void (*YRX_PATTERN_CALLBACK)(const struct YRX_PATTERN *pattern, void *user_data)
|
240
|
+
callback :pattern_callback, [:pointer, :pointer], :void
|
241
|
+
|
242
|
+
# Public: Iterate through all patterns (strings) in a rule.
|
243
|
+
#
|
244
|
+
# This function calls the provided callback for each string pattern defined
|
245
|
+
# in the rule. Patterns are the actual search terms that YARA looks for
|
246
|
+
# during scanning, defined in the rule's strings section.
|
247
|
+
#
|
248
|
+
# rule - A Pointer to the YRX_RULE structure
|
249
|
+
# callback - A Proc matching the pattern_callback signature
|
250
|
+
# user_data - A Pointer to optional data passed to callback (can be nil)
|
251
|
+
#
|
252
|
+
# Examples
|
253
|
+
#
|
254
|
+
# callback = proc { |pattern_ptr, user_data| puts "Found pattern" }
|
255
|
+
# result = Yara::FFI.yrx_rule_iter_patterns(rule_ptr, callback, nil)
|
256
|
+
#
|
257
|
+
# Returns an Integer result code (YRX_SUCCESS on success).
|
258
|
+
# C Signature: enum YRX_RESULT yrx_rule_iter_patterns(const struct YRX_RULE *rule, YRX_PATTERN_CALLBACK callback, void *user_data)
|
259
|
+
attach_function :yrx_rule_iter_patterns, [:pointer, :pattern_callback, :pointer], :int
|
260
|
+
|
261
|
+
# Public: Extract the identifier (name) from a pattern object.
|
262
|
+
#
|
263
|
+
# This function retrieves the pattern identifier from a YRX_PATTERN pointer,
|
264
|
+
# typically called from within a pattern iteration callback. Pattern
|
265
|
+
# identifiers are the variable names like $string1, $hex_pattern, etc.
|
266
|
+
#
|
267
|
+
# pattern - A Pointer to the YRX_PATTERN structure
|
268
|
+
# ident - A FFI::MemoryPointer that will receive the identifier pointer
|
269
|
+
# len - A FFI::MemoryPointer that will receive the identifier length
|
270
|
+
#
|
271
|
+
# Examples
|
272
|
+
#
|
273
|
+
# ident_ptr = FFI::MemoryPointer.new(:pointer)
|
274
|
+
# len_ptr = FFI::MemoryPointer.new(:size_t)
|
275
|
+
# result = Yara::FFI.yrx_pattern_identifier(pattern_ptr, ident_ptr, len_ptr)
|
276
|
+
#
|
277
|
+
# Returns an Integer result code (YRX_SUCCESS on success).
|
278
|
+
# C Signature: enum YRX_RESULT yrx_pattern_identifier(const struct YRX_PATTERN *pattern, const uint8_t **ident, size_t *len)
|
279
|
+
attach_function :yrx_pattern_identifier, [:pointer, :pointer, :pointer], :int
|
280
|
+
|
281
|
+
# Public: YARA-X result codes for operation status.
|
282
|
+
#
|
283
|
+
# These constants represent the possible return values from YARA-X functions.
|
284
|
+
# YRX_SUCCESS (0) indicates successful operation, while other values indicate
|
285
|
+
# various error conditions that can be interpreted using yrx_last_error.
|
286
|
+
|
287
|
+
# Public: Operation completed successfully.
|
288
|
+
YRX_SUCCESS = 0
|
289
|
+
|
290
|
+
# Public: YARA rule syntax error during compilation.
|
291
|
+
YRX_SYNTAX_ERROR = 1
|
292
|
+
|
293
|
+
# Public: Variable definition or reference error.
|
294
|
+
YRX_VARIABLE_ERROR = 2
|
295
|
+
|
296
|
+
# Public: Error during scanning operation.
|
297
|
+
YRX_SCAN_ERROR = 3
|
298
|
+
|
299
|
+
# Public: Scanning operation timed out.
|
300
|
+
YRX_SCAN_TIMEOUT = 4
|
301
|
+
|
302
|
+
# Public: Invalid argument passed to function.
|
303
|
+
YRX_INVALID_ARGUMENT = 5
|
115
304
|
end
|
116
305
|
end
|