yara 1.4.3 → 1.4.4

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.
@@ -1,3 +1,7 @@
1
+ == 1.4.3 / 2011-04-11
2
+ * Support optional namespaces when calling compile_file or compile_string
3
+ * Better yardoc tags
4
+
1
5
  == 1.4.3 / 2011-02-21
2
6
  * Improved documentation
3
7
  * More intuitive 'inspect' features for testing in IRB.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.3
1
+ 1.4.4
@@ -177,7 +177,7 @@ Match_NEW_from_rule(RULE *rule, unsigned char *buffer, VALUE *match) {
177
177
  * call-seq:
178
178
  * match.rule() -> String
179
179
  *
180
- * @return String The rule identifier string for this match.
180
+ * @return [String] The rule identifier string for this match.
181
181
  */
182
182
  static VALUE match_rule(VALUE self) {
183
183
  match_info *mi;
@@ -191,7 +191,7 @@ static VALUE match_rule(VALUE self) {
191
191
  * call-seq:
192
192
  * match.namespace() -> String
193
193
  *
194
- * @return String The namespace for this match.
194
+ * @return [String] The namespace for this match.
195
195
  */
196
196
  static VALUE match_namespace(VALUE self) {
197
197
  match_info *mi;
@@ -233,7 +233,7 @@ static VALUE match_strings(VALUE self) {
233
233
  * call-seq:
234
234
  * match.meta() -> Hash
235
235
  *
236
- * @return Hash Keyed values of metadata for the match object.
236
+ * @return [Hash] Keyed values of metadata for the match object.
237
237
  */
238
238
  static VALUE match_meta(VALUE self) {
239
239
  match_info *mi;
@@ -247,7 +247,7 @@ static VALUE match_meta(VALUE self) {
247
247
  * call-seq:
248
248
  * matchstring.identifier() -> String
249
249
  *
250
- * @return String The identification label for the string.
250
+ * @return [String] The identification label for the string.
251
251
  */
252
252
  static VALUE matchstring_identifier(VALUE self) {
253
253
  match_string *ms;
@@ -261,7 +261,7 @@ static VALUE matchstring_identifier(VALUE self) {
261
261
  * call-seq:
262
262
  * matchstring.offset() -> Fixnum
263
263
  *
264
- * @return Fixnum The offset where the match occurred.
264
+ * @return [Fixnum] The offset where the match occurred.
265
265
  */
266
266
  static VALUE matchstring_offset(VALUE self) {
267
267
  match_string *ms;
@@ -275,7 +275,7 @@ static VALUE matchstring_offset(VALUE self) {
275
275
  * call-seq:
276
276
  * matchstring.buffer() -> String
277
277
  *
278
- * @return String The data matched in the buffer.
278
+ * @return [String] The data matched in the buffer.
279
279
  */
280
280
  static VALUE matchstring_buffer(VALUE self) {
281
281
  match_string *ms;
@@ -36,11 +36,23 @@ VALUE rules_allocate(VALUE klass) {
36
36
  return Data_Wrap_Struct(klass, rules_mark, rules_free, ctx);
37
37
  }
38
38
 
39
+ /* used internally to lookup namespaces */
40
+ NAMESPACE * find_namespace(YARA_CONTEXT *ctx, const char *name) {
41
+ NAMESPACE *ns = ctx->namespaces;
42
+
43
+ while(ns && ns->name) {
44
+ if(strcmp(name, ns->name) == 0)
45
+ return(ns);
46
+ else
47
+ ns = ns->next;
48
+ }
49
+ return (NAMESPACE*) NULL;
50
+ }
51
+
52
+
39
53
  /*
40
- * Document-method: compile_file
41
- *
42
54
  * call-seq:
43
- * rules.compile_file(filename) -> nil
55
+ * rules.compile_file(filename, ns=nil) -> nil
44
56
  *
45
57
  * Compiles rules taken from a file by its filename. This method
46
58
  * can be called more than once using multiple rules strings and
@@ -49,24 +61,46 @@ VALUE rules_allocate(VALUE klass) {
49
61
  * To avoid namespace conflicts, you can use set_namespace
50
62
  * before compiling rules.
51
63
  *
52
- * @param String filename The name of a yara rules file to compile.
64
+ * @param [String] filename The name of a yara rules file to compile.
53
65
  *
54
- * @raise Yara::CompileError An exception is raised if a compile error occurs.
66
+ * @param [String,nil] ns Optional namespace for the rules.
67
+ *
68
+ * @raise [Yara::CompileError] An exception is raised if a compile error occurs.
55
69
  */
56
- VALUE rules_compile_file(VALUE self, VALUE rb_fname) {
57
- FILE * file;
58
- char * fname;
70
+ VALUE rules_compile_file(int argc, VALUE *argv, VALUE self) {
71
+ FILE *file;
72
+ char *fname;
59
73
  YARA_CONTEXT *ctx;
60
74
  char error_message[256];
75
+ NAMESPACE *orig_ns, *ns;
76
+
77
+ VALUE rb_fname;
78
+ VALUE rb_ns;
79
+
80
+ orig_ns = ns = NULL;
81
+
82
+ rb_scan_args(argc, argv, "11", &rb_fname, &rb_ns);
61
83
 
62
84
  Check_Type(rb_fname, T_STRING);
63
- fname = RSTRING_PTR(rb_fname);
64
85
 
86
+ if(rb_ns != Qnil) {
87
+ Check_Type(rb_ns, T_STRING);
88
+ }
89
+
90
+ fname = RSTRING_PTR(rb_fname);
65
91
  if( !(file=fopen(fname, "r")) ) {
66
92
  rb_raise(error_CompileError, "No such file: %s", fname);
67
93
  } else {
68
94
  Data_Get_Struct(self, YARA_CONTEXT, ctx);
69
95
 
96
+ if((rb_ns != Qnil) && (orig_ns = ctx->current_namespace)) {
97
+
98
+ if (!(ns = find_namespace(ctx, RSTRING_PTR(rb_ns))))
99
+ ns = yr_create_namespace(ctx, RSTRING_PTR(rb_ns));
100
+
101
+ ctx->current_namespace = ns;
102
+ }
103
+
70
104
  if( yr_compile_file(file, ctx) != 0 ) {
71
105
  yr_get_error_message(ctx, error_message, sizeof(error_message));
72
106
  fclose(file);
@@ -74,48 +108,74 @@ VALUE rules_compile_file(VALUE self, VALUE rb_fname) {
74
108
  }
75
109
 
76
110
  yr_push_file_name(ctx, fname);
111
+
112
+ if ( orig_ns )
113
+ ctx->current_namespace = orig_ns;
114
+
77
115
  fclose(file);
116
+
78
117
  return Qtrue;
79
118
  }
80
119
  }
81
120
 
82
121
  /*
83
- * Document-method: compile_string
84
- *
85
122
  * call-seq:
86
- * rules.compile_string(rules_string) -> nil
123
+ * rules.compile_string(rules_string, ns=nil) -> nil
87
124
  *
88
125
  * Compiles rules taken from a ruby string. This method
89
126
  * can be called more than once using multiple rules strings
90
127
  * and can be used in combination with compile_file.
91
128
  *
92
- * To avoid namespace conflicts, you can use set_namespace
93
- * before compiling rules.
129
+ * To avoid namespace conflicts, you can set a namespace using
130
+ * the optional 'ns' argument.
94
131
  *
95
- * @param String rules_string A string containing yara rules text.
132
+ * @param [String] rules_string A string containing yara rules text.
96
133
  *
97
- * @raise Yara::CompileError An exception is raised if a compile error occurs.
134
+ * @param [String,nil] ns An optional namespace for the rules.
135
+ *
136
+ * @raise [Yara::CompileError] An exception is raised if a compile error occurs.
98
137
  */
99
- VALUE rules_compile_string(VALUE self, VALUE rb_rules) {
138
+ VALUE rules_compile_string(int argc, VALUE *argv, VALUE self) {
100
139
  YARA_CONTEXT *ctx;
101
140
  char *rules;
102
141
  char error_message[256];
142
+ NAMESPACE *orig_ns, *ns;
143
+
144
+ VALUE rb_rules;
145
+ VALUE rb_ns;
146
+
147
+ orig_ns = ns = NULL;
148
+
149
+ rb_scan_args(argc, argv, "11", &rb_rules, &rb_ns);
103
150
 
104
151
  Check_Type(rb_rules, T_STRING);
152
+ if (rb_ns != Qnil)
153
+ Check_Type(rb_ns, T_STRING);
154
+
105
155
  rules = RSTRING_PTR(rb_rules);
106
156
  Data_Get_Struct(self, YARA_CONTEXT, ctx);
107
157
 
158
+ if((rb_ns != Qnil) && (orig_ns = ctx->current_namespace)) {
159
+ orig_ns = ctx->current_namespace;
160
+
161
+ if (!(ns = find_namespace(ctx, RSTRING_PTR(rb_ns))))
162
+ ns = yr_create_namespace(ctx, RSTRING_PTR(rb_ns));
163
+
164
+ ctx->current_namespace = ns;
165
+ }
166
+
108
167
  if( yr_compile_string(rules, ctx) != 0) {
109
168
  yr_get_error_message(ctx, error_message, sizeof(error_message));
110
169
  rb_raise(error_CompileError, "Syntax Error - line(%d): %s", ctx->last_error_line, error_message);
111
170
  }
112
171
 
172
+ if ( orig_ns )
173
+ ctx->current_namespace = orig_ns;
174
+
113
175
  return Qtrue;
114
176
  }
115
177
 
116
178
  /*
117
- * Document-method: weight
118
- *
119
179
  * call-seq:
120
180
  * rules.weight() -> Fixnum
121
181
  *
@@ -130,8 +190,6 @@ VALUE rules_weight(VALUE self) {
130
190
  }
131
191
 
132
192
  /*
133
- * Document-method: current_namespace
134
- *
135
193
  * call-seq:
136
194
  * rules.current_namespace() -> String
137
195
  *
@@ -147,8 +205,6 @@ VALUE rules_current_namespace(VALUE self) {
147
205
  }
148
206
 
149
207
  /*
150
- * Document-method: namespaces
151
- *
152
208
  * call-seq:
153
209
  * rules.namespaces() -> Array
154
210
  *
@@ -168,21 +224,7 @@ VALUE rules_namespaces(VALUE self) {
168
224
  return ary;
169
225
  }
170
226
 
171
- NAMESPACE * find_namespace(YARA_CONTEXT *ctx, const char *name) {
172
- NAMESPACE *ns = ctx->namespaces;
173
-
174
- while(ns && ns->name) {
175
- if(strcmp(name, ns->name) == 0)
176
- return(ns);
177
- else
178
- ns = ns->next;
179
- }
180
- return (NAMESPACE*) NULL;
181
- }
182
-
183
227
  /*
184
- * Document-method: set_namespace
185
- *
186
228
  * call-seq:
187
229
  * rules.set_namespace(name) -> nil
188
230
  *
@@ -192,7 +234,7 @@ NAMESPACE * find_namespace(YARA_CONTEXT *ctx, const char *name) {
192
234
  * To avoid namespace conflicts, you can use set_namespace
193
235
  * before compiling rules.
194
236
  *
195
- * @param String name The namespace to set.
237
+ * @param [String] name The namespace to set.
196
238
  */
197
239
  VALUE rules_set_namespace(VALUE self, VALUE rb_namespace) {
198
240
  YARA_CONTEXT *ctx;
@@ -233,19 +275,17 @@ scan_callback(RULE *rule, unsigned char *buffer, unsigned int buffer_size, void
233
275
  }
234
276
 
235
277
  /*
236
- * Document-method: scan_file
237
- *
238
278
  * call-seq:
239
279
  * rules.scan_file(filename) -> Array
240
280
  *
241
281
  * Scans a file using the compiled rules supplied
242
282
  * with either compile_file or compile_string (or both).
243
283
  *
244
- * @param String filename The name of a file to scan with yara.
284
+ * @param [String] filename The name of a file to scan with yara.
245
285
  *
246
286
  * @return [Yara::Match] An array of Yara::Match objects found in the file.
247
287
  *
248
- * @raise Yara::ScanError Raised if an error occurs while scanning the file.
288
+ * @raise [Yara::ScanError] Raised if an error occurs while scanning the file.
249
289
  */
250
290
  VALUE rules_scan_file(VALUE self, VALUE rb_fname) {
251
291
  YARA_CONTEXT *ctx;
@@ -270,25 +310,23 @@ VALUE rules_scan_file(VALUE self, VALUE rb_fname) {
270
310
 
271
311
 
272
312
  /*
273
- * Document-method: scan_file
274
- *
275
313
  * call-seq:
276
314
  * rules.scan_string(buf) -> Array
277
315
  *
278
316
  * Scans a ruby string using the compiled rules supplied
279
317
  * with either compile_file or compile_string (or both).
280
318
  *
281
- * @param String buf The string buffer to scan with yara.
319
+ * @param [String] buf The string buffer to scan with yara.
282
320
  *
283
321
  * @return [Yara::Match] An array of Yara::Match objects found in the string.
284
322
  *
285
- * @raise Yara::ScanError Raised if an error occurs while scanning the string.
323
+ * @raise [Yara::ScanError] Raised if an error occurs while scanning the string.
286
324
  */
287
325
  VALUE rules_scan_string(VALUE self, VALUE rb_dat) {
288
326
  YARA_CONTEXT *ctx;
289
327
  VALUE results;
290
328
  char *buf;
291
- long buflen;
329
+ size_t buflen;
292
330
  int ret;
293
331
 
294
332
  Check_Type(rb_dat, T_STRING);
@@ -319,8 +357,8 @@ void init_Rules() {
319
357
  class_Rules = rb_define_class_under(module_Yara, "Rules", rb_cObject);
320
358
  rb_define_alloc_func(class_Rules, rules_allocate);
321
359
 
322
- rb_define_method(class_Rules, "compile_file", rules_compile_file, 1);
323
- rb_define_method(class_Rules, "compile_string", rules_compile_string, 1);
360
+ rb_define_method(class_Rules, "compile_file", rules_compile_file, -1);
361
+ rb_define_method(class_Rules, "compile_string", rules_compile_string, -1);
324
362
  rb_define_method(class_Rules, "weight", rules_weight, 0);
325
363
  rb_define_method(class_Rules, "current_namespace", rules_current_namespace, 0);
326
364
  rb_define_method(class_Rules, "namespaces", rules_namespaces, 0);
@@ -213,6 +213,7 @@ describe Yara::Rules do
213
213
 
214
214
  end
215
215
 
216
+
216
217
  it "should raise an error if scanning an invalid string" do
217
218
  @rules.compile_file(sample_file("packers.yara"))
218
219
  @rules.weight.should > 0
@@ -221,5 +222,95 @@ describe Yara::Rules do
221
222
  end
222
223
 
223
224
 
225
+ it "should take an optional namespace when compiling a file" do
226
+ @rules.compile_file(sample_file("packers.yara"), "an_optional_namespace1" )
227
+ @rules.weight.should > 0
228
+ results = @rules.scan_file(sample_file("DumpMem.exe"))
229
+ results.should be_kind_of(Array)
230
+ results.size.should == 1
231
+
232
+ m = results.first
233
+ m.should be_kind_of(Yara::Match)
234
+ m.should be_frozen
235
+
236
+ m.rule.should == "UPX"
237
+
238
+ m.namespace.should == "an_optional_namespace1"
239
+ m.namespace.should be_frozen
240
+
241
+ @rules.namespaces.should == ["an_optional_namespace1", "default"]
242
+ @rules.current_namespace.should == "default"
243
+ end
244
+
245
+ it "should allow the 'default' namespace when compiling a file" do
246
+ @rules.compile_file(sample_file("packers.yara"), "default" )
247
+ @rules.weight.should > 0
248
+ results = @rules.scan_file(sample_file("DumpMem.exe"))
249
+ results.should be_kind_of(Array)
250
+ results.size.should == 1
251
+
252
+ m = results.first
253
+ m.should be_kind_of(Yara::Match)
254
+ m.should be_frozen
255
+
256
+ m.rule.should == "UPX"
257
+
258
+ m.namespace.should == "default"
259
+ m.namespace.should be_frozen
260
+
261
+ @rules.namespaces.should == ["default"]
262
+ @rules.current_namespace.should == "default"
263
+ end
264
+
265
+ it "should raise an error when compiling a file with an invalid namespace" do
266
+ lambda { @rules.compile_file(sample_file("packers.yara"), 1) }.should raise_error(TypeError)
267
+ end
268
+
269
+
270
+ it "should take an optional namespace when compiling a string" do
271
+ @rules.compile_string(File.read(sample_file("packers.yara")), "an_optional_namespace2")
272
+ @rules.weight.should > 0
273
+ results = @rules.scan_file(sample_file("DumpMem.exe"))
274
+ results.should be_kind_of(Array)
275
+ results.size.should == 1
276
+
277
+ m = results.first
278
+ m.should be_kind_of(Yara::Match)
279
+ m.should be_frozen
280
+
281
+ m.rule.should == "UPX"
282
+
283
+ m.namespace.should == "an_optional_namespace2"
284
+ m.namespace.should be_frozen
285
+
286
+ @rules.namespaces.should == ["an_optional_namespace2", "default"]
287
+ @rules.current_namespace.should == "default"
288
+ end
289
+
290
+ it "should allow the 'default' namespace when compiling a string" do
291
+ @rules.compile_string(File.read(sample_file("packers.yara")), "default")
292
+ @rules.weight.should > 0
293
+ results = @rules.scan_file(sample_file("DumpMem.exe"))
294
+ results.should be_kind_of(Array)
295
+ results.size.should == 1
296
+
297
+ m = results.first
298
+ m.should be_kind_of(Yara::Match)
299
+ m.should be_frozen
300
+
301
+ m.rule.should == "UPX"
302
+
303
+ m.namespace.should == "default"
304
+ m.namespace.should be_frozen
305
+
306
+ @rules.namespaces.should == ["default"]
307
+ @rules.current_namespace.should == "default"
308
+ end
309
+
310
+
311
+ it "should raise an error when compiling a string with an invalid namespace" do
312
+ lambda { @rules.compile_string(File.read(sample_file("packers.yara")), 1) }.should raise_error(TypeError)
313
+ end
314
+
224
315
  end
225
316
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 1
7
7
  - 4
8
- - 3
9
- version: 1.4.3
8
+ - 4
9
+ version: 1.4.4
10
10
  platform: ruby
11
11
  authors:
12
12
  - Eric Monti
@@ -14,13 +14,13 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-02-21 00:00:00 -06:00
17
+ date: 2011-04-11 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rspec
22
- prerelease: false
23
22
  requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
24
  requirements:
25
25
  - - ~>
26
26
  - !ruby/object:Gem::Version
@@ -30,11 +30,12 @@ dependencies:
30
30
  - 0
31
31
  version: 2.3.0
32
32
  type: :development
33
+ prerelease: false
33
34
  version_requirements: *id001
34
35
  - !ruby/object:Gem::Dependency
35
36
  name: yard
36
- prerelease: false
37
37
  requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
38
39
  requirements:
39
40
  - - ~>
40
41
  - !ruby/object:Gem::Version
@@ -44,11 +45,12 @@ dependencies:
44
45
  - 0
45
46
  version: 0.6.0
46
47
  type: :development
48
+ prerelease: false
47
49
  version_requirements: *id002
48
50
  - !ruby/object:Gem::Dependency
49
51
  name: bundler
50
- prerelease: false
51
52
  requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
52
54
  requirements:
53
55
  - - ~>
54
56
  - !ruby/object:Gem::Version
@@ -58,11 +60,12 @@ dependencies:
58
60
  - 0
59
61
  version: 1.0.0
60
62
  type: :development
63
+ prerelease: false
61
64
  version_requirements: *id003
62
65
  - !ruby/object:Gem::Dependency
63
66
  name: jeweler
64
- prerelease: false
65
67
  requirement: &id004 !ruby/object:Gem::Requirement
68
+ none: false
66
69
  requirements:
67
70
  - - ~>
68
71
  - !ruby/object:Gem::Version
@@ -72,11 +75,12 @@ dependencies:
72
75
  - 2
73
76
  version: 1.5.2
74
77
  type: :development
78
+ prerelease: false
75
79
  version_requirements: *id004
76
80
  - !ruby/object:Gem::Dependency
77
81
  name: rcov
78
- prerelease: false
79
82
  requirement: &id005 !ruby/object:Gem::Requirement
83
+ none: false
80
84
  requirements:
81
85
  - - ">="
82
86
  - !ruby/object:Gem::Version
@@ -84,11 +88,12 @@ dependencies:
84
88
  - 0
85
89
  version: "0"
86
90
  type: :development
91
+ prerelease: false
87
92
  version_requirements: *id005
88
93
  - !ruby/object:Gem::Dependency
89
94
  name: rake-compiler
90
- prerelease: false
91
95
  requirement: &id006 !ruby/object:Gem::Requirement
96
+ none: false
92
97
  requirements:
93
98
  - - ">="
94
99
  - !ruby/object:Gem::Version
@@ -96,6 +101,7 @@ dependencies:
96
101
  - 0
97
102
  version: "0"
98
103
  type: :development
104
+ prerelease: false
99
105
  version_requirements: *id006
100
106
  description: Ruby bindings for the yara malware analysis library
101
107
  email: emonti@trustwave.com
@@ -145,13 +151,16 @@ rdoc_options: []
145
151
  require_paths:
146
152
  - lib
147
153
  required_ruby_version: !ruby/object:Gem::Requirement
154
+ none: false
148
155
  requirements:
149
156
  - - ">="
150
157
  - !ruby/object:Gem::Version
158
+ hash: -3417020004990498226
151
159
  segments:
152
160
  - 0
153
161
  version: "0"
154
162
  required_rubygems_version: !ruby/object:Gem::Requirement
163
+ none: false
155
164
  requirements:
156
165
  - - ">="
157
166
  - !ruby/object:Gem::Version
@@ -161,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
161
170
  requirements: []
162
171
 
163
172
  rubyforge_project:
164
- rubygems_version: 1.3.6
173
+ rubygems_version: 1.3.7
165
174
  signing_key:
166
175
  specification_version: 3
167
176
  summary: Ruby bindings for libyara