yara-ffi 1.0.0 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/yara/ffi.rb +6 -1
- data/lib/yara/scan_result.rb +105 -0
- data/lib/yara/version.rb +1 -1
- data/lib/yara/yr_meta.rb +4 -1
- data/lib/yara/yr_rule.rb +2 -2
- data/lib/yara/yr_string.rb +11 -1
- data/lib/yara.rb +17 -18
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac111338f4038017b3eb887d2bfcea73c2a2aa5a9b409370e13cfd01985276df
|
4
|
+
data.tar.gz: 353ab52ebe038b8fbd2b3c9ce35436df1b4fb20cad1cfa0b3019e678291e0f0b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96a2ede305474b3457dcaf4256e3b57fa28becae0abc51eb3e45897667f5a971ba818a45a6b945b15d02208c2eee6adad43ff416c31d9528083ed7dd5a317046
|
7
|
+
data.tar.gz: 6b1a3fa08e02123b655d140f30fa531494d585276591f5758b6f8c26636ea0fe388eef7fa5e6253d9fce42221b19729eab0960684a87eaf95e96f701eacd4fb7
|
data/lib/yara/ffi.rb
CHANGED
@@ -35,6 +35,11 @@ module Yara
|
|
35
35
|
:pointer, # compiler_pointer
|
36
36
|
], :void
|
37
37
|
|
38
|
+
# int yr_rules_destroy(YR_RULES* rules)
|
39
|
+
attach_function :yr_rules_destroy, [
|
40
|
+
:pointer, # rules_pointer
|
41
|
+
], :void
|
42
|
+
|
38
43
|
# void callback_function(
|
39
44
|
# int error_level,
|
40
45
|
# const char* file_name,
|
@@ -100,7 +105,7 @@ module Yara
|
|
100
105
|
# int timeout)
|
101
106
|
attach_function :yr_rules_scan_mem, [
|
102
107
|
:pointer, # rules_pointer*
|
103
|
-
:
|
108
|
+
:pointer, # buffer (aka test subject)
|
104
109
|
:size_t, # buffer size (String#bytesize)
|
105
110
|
:int, # flags
|
106
111
|
:scan_callback, # proc
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Yara
|
2
|
+
class ScanResult
|
3
|
+
RULE_MATCHING = 1
|
4
|
+
RULE_NOT_MATCHING = 2
|
5
|
+
|
6
|
+
META_FLAGS_LAST_IN_RULE = 1
|
7
|
+
|
8
|
+
META_TYPE_INTEGER = 1
|
9
|
+
META_TYPE_STRING = 2
|
10
|
+
META_TYPE_BOOLEAN = 3
|
11
|
+
|
12
|
+
STRING_FLAGS_LAST_IN_RULE = 0
|
13
|
+
|
14
|
+
STRING_LENGTH = 4
|
15
|
+
STRING_POINTER = 5
|
16
|
+
|
17
|
+
RULE_IDENTIFIER = 1
|
18
|
+
METAS_IDENTIFIER = 3
|
19
|
+
STRING_IDENTIFIER = 4
|
20
|
+
|
21
|
+
attr_reader :callback_type, :rule
|
22
|
+
|
23
|
+
def initialize(callback_type, rule_ptr)
|
24
|
+
@callback_type = callback_type
|
25
|
+
@rule = YrRule.new(rule_ptr)
|
26
|
+
end
|
27
|
+
|
28
|
+
def rule_name
|
29
|
+
@rule.values[RULE_IDENTIFIER]
|
30
|
+
end
|
31
|
+
|
32
|
+
def rule_meta
|
33
|
+
metas = {}
|
34
|
+
reading_metas = true
|
35
|
+
meta_index = 0
|
36
|
+
meta_pointer = @rule.values[METAS_IDENTIFIER]
|
37
|
+
while reading_metas do
|
38
|
+
meta = YrMeta.new(meta_pointer + meta_index * YrMeta.size)
|
39
|
+
metas.merge!(meta_as_hash(meta))
|
40
|
+
flags = meta.values.last
|
41
|
+
if flags == META_FLAGS_LAST_IN_RULE
|
42
|
+
reading_metas = false
|
43
|
+
else
|
44
|
+
meta_index += 1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
metas
|
48
|
+
end
|
49
|
+
|
50
|
+
def rule_strings
|
51
|
+
strings = {}
|
52
|
+
reading_strings = true
|
53
|
+
string_index = 0
|
54
|
+
string_pointer = @rule.values[STRING_IDENTIFIER]
|
55
|
+
while reading_strings do
|
56
|
+
string = YrString.new(string_pointer + string_index * YrString.size)
|
57
|
+
string_length = string.values[STRING_LENGTH]
|
58
|
+
flags = string.values.first
|
59
|
+
if flags == STRING_FLAGS_LAST_IN_RULE
|
60
|
+
reading_strings = false
|
61
|
+
else
|
62
|
+
strings.merge!(string_as_hash(string)) unless string_length == 0
|
63
|
+
string_index += 1
|
64
|
+
end
|
65
|
+
end
|
66
|
+
strings
|
67
|
+
end
|
68
|
+
|
69
|
+
def scan_complete?
|
70
|
+
callback_type == SCAN_FINISHED
|
71
|
+
end
|
72
|
+
|
73
|
+
def rule_outcome?
|
74
|
+
[RULE_MATCHING, RULE_NOT_MATCHING].include?(callback_type)
|
75
|
+
end
|
76
|
+
|
77
|
+
def match?
|
78
|
+
callback_type == RULE_MATCHING
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def meta_as_hash(meta)
|
84
|
+
name, string_value, int_value, type, _flags = meta.values
|
85
|
+
value = meta_value(string_value, int_value, type)
|
86
|
+
{ name.to_sym => value }
|
87
|
+
end
|
88
|
+
|
89
|
+
def string_as_hash(yr_string)
|
90
|
+
string_pointer = yr_string.values[STRING_POINTER]
|
91
|
+
string_identifier = yr_string.values.last
|
92
|
+
{ string_identifier.to_sym => string_pointer.read_string }
|
93
|
+
end
|
94
|
+
|
95
|
+
def meta_value(string_value, int_value, type)
|
96
|
+
if type == META_TYPE_INTEGER
|
97
|
+
int_value
|
98
|
+
elsif type == META_TYPE_BOOLEAN
|
99
|
+
int_value == 1
|
100
|
+
else
|
101
|
+
string_value
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/lib/yara/version.rb
CHANGED
data/lib/yara/yr_meta.rb
CHANGED
data/lib/yara/yr_rule.rb
CHANGED
data/lib/yara/yr_string.rb
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
module Yara
|
2
2
|
class YrString < FFI::Struct
|
3
|
-
layout
|
3
|
+
layout \
|
4
|
+
:flags, :uint32_t,
|
5
|
+
:idx, :uint32_t,
|
6
|
+
:fixed_offset, :int64_t,
|
7
|
+
:rule_idx, :uint32_t,
|
8
|
+
:length, :int32_t,
|
9
|
+
:string, :pointer,
|
10
|
+
:chained_to, :pointer,
|
11
|
+
:chain_gap_min, :int32_t,
|
12
|
+
:chain_gap_max, :int32_t,
|
13
|
+
:identifier, :string
|
4
14
|
end
|
5
15
|
end
|
data/lib/yara.rb
CHANGED
@@ -2,22 +2,17 @@
|
|
2
2
|
|
3
3
|
require "ffi"
|
4
4
|
require "pry"
|
5
|
-
require_relative "yara/version"
|
6
5
|
require_relative "yara/ffi"
|
6
|
+
require_relative "yara/scan_result"
|
7
|
+
require_relative "yara/version"
|
7
8
|
|
8
|
-
# TBD
|
9
9
|
module Yara
|
10
|
-
|
11
|
-
|
12
|
-
CALLBACK_MSG_RULE_MATCHING = 1
|
13
|
-
CALLBACK_MSG_RULE_NOT_MATCHING = 2
|
14
|
-
CALLBACK_MSG_SCAN_FINISHED = 3
|
10
|
+
SCAN_FINISHED = 3
|
15
11
|
|
16
|
-
|
12
|
+
class Error < StandardError; end
|
17
13
|
|
18
14
|
def self.test(rule_string, test_string)
|
19
15
|
user_data = UserData.new
|
20
|
-
user_data[:number] = 42
|
21
16
|
scanning = true
|
22
17
|
results = []
|
23
18
|
|
@@ -38,23 +33,25 @@ module Yara
|
|
38
33
|
Yara::FFI.yr_compiler_get_rules(compiler_pointer, rules_pointer)
|
39
34
|
rules_pointer = rules_pointer.get_pointer(0)
|
40
35
|
|
41
|
-
result_callback = proc do |context_ptr,
|
42
|
-
|
43
|
-
|
44
|
-
case message
|
45
|
-
when CALLBACK_MSG_RULE_MATCHING
|
46
|
-
results << rule.values[RULE_IDENTIFIER]
|
47
|
-
when CALLBACK_MSG_SCAN_FINISHED
|
36
|
+
result_callback = proc do |context_ptr, callback_type, rule_ptr, user_data_ptr|
|
37
|
+
if callback_type == SCAN_FINISHED
|
48
38
|
scanning = false
|
39
|
+
else
|
40
|
+
result = ScanResult.new(callback_type, rule_ptr)
|
41
|
+
results << result if result.rule_outcome?
|
49
42
|
end
|
50
43
|
|
51
44
|
0 # ERROR_SUCCESS
|
52
45
|
end
|
53
46
|
|
47
|
+
test_string_bytesize = test_string.bytesize
|
48
|
+
test_string_pointer = ::FFI::MemoryPointer.new(:char, test_string_bytesize)
|
49
|
+
test_string_pointer.put_bytes(0, test_string)
|
50
|
+
|
54
51
|
Yara::FFI.yr_rules_scan_mem(
|
55
52
|
rules_pointer,
|
56
|
-
|
57
|
-
|
53
|
+
test_string_pointer,
|
54
|
+
test_string_bytesize,
|
58
55
|
0,
|
59
56
|
result_callback,
|
60
57
|
user_data,
|
@@ -66,6 +63,8 @@ module Yara
|
|
66
63
|
|
67
64
|
results
|
68
65
|
ensure
|
66
|
+
Yara::FFI.yr_rules_destroy(rules_pointer)
|
67
|
+
Yara::FFI.yr_compiler_destroy(compiler_pointer)
|
69
68
|
Yara::FFI.yr_finalize
|
70
69
|
end
|
71
70
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yara-ffi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 2.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Hoyt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-08-
|
11
|
+
date: 2021-08-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -45,6 +45,7 @@ files:
|
|
45
45
|
- bin/setup
|
46
46
|
- lib/yara.rb
|
47
47
|
- lib/yara/ffi.rb
|
48
|
+
- lib/yara/scan_result.rb
|
48
49
|
- lib/yara/user_data.rb
|
49
50
|
- lib/yara/version.rb
|
50
51
|
- lib/yara/yr_meta.rb
|