Skip to content

Commit f35c29d

Browse files
committed
Implement yr_scanner_last_error_string and yr_scanner_last_error_rule functions for getting information about the rule and string that caused a scanning error.
For implementing this feature it was necessary to add a new field to YR_STRING pointing to the YR_RULE that owns the string.
1 parent a1f724a commit f35c29d

File tree

6 files changed

+82
-12
lines changed

6 files changed

+82
-12
lines changed

libyara/include/yara/scanner.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,17 @@ YR_API int yr_scanner_scan_fd(
106106
YR_SCANNER* scanner,
107107
YR_FILE_DESCRIPTOR fd);
108108

109+
110+
YR_API int yr_scanner_scan_proc(
111+
YR_SCANNER* scanner,
112+
int pid);
113+
114+
115+
YR_API YR_RULE* yr_scanner_last_error_rule(
116+
YR_SCANNER* scanner);
117+
118+
119+
YR_API YR_STRING* yr_scanner_last_error_string(
120+
YR_SCANNER* scanner);
121+
109122
#endif

libyara/include/yara/types.h

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ typedef struct _YR_META
202202
} YR_META;
203203

204204

205+
struct _YR_RULE;
205206
struct _YR_MATCH;
206207

207208

@@ -223,6 +224,7 @@ typedef struct _YR_STRING
223224
DECLARE_REFERENCE(char*, identifier);
224225
DECLARE_REFERENCE(uint8_t*, string);
225226
DECLARE_REFERENCE(struct _YR_STRING*, chained_to);
227+
DECLARE_REFERENCE(struct _YR_RULE*, rule);
226228

227229
int32_t chain_gap_min;
228230
int32_t chain_gap_max;
@@ -481,8 +483,8 @@ typedef struct _YR_AC_AUTOMATON
481483
} YR_AC_AUTOMATON;
482484

483485

484-
typedef struct _YR_RULES {
485-
486+
typedef struct _YR_RULES
487+
{
486488
unsigned char tidx_mask[YR_BITARRAY_NCHARS(MAX_THREADS)];
487489
const uint8_t* code_start;
488490

@@ -538,30 +540,60 @@ typedef int (*YR_CALLBACK_FUNC)(
538540

539541
typedef struct _YR_SCAN_CONTEXT
540542
{
543+
// File size of the file being scanned.
541544
uint64_t file_size;
545+
546+
// Entry point of the file being scanned, if the file is PE or ELF.
542547
uint64_t entry_point;
543548

549+
// Scanning flags.
544550
int flags;
551+
552+
// Thread index for the thread using this scan context. The number of threads
553+
// that can use a YR_RULES object simultaneusly is limited by the MAX_THREADS
554+
// constant. Each thread using a YR_RULES get assigned a unique thread index
555+
// in the range [0, MAX_THREADS)
545556
int tidx;
557+
558+
// Scan timeout in seconds.
546559
int timeout;
547560

561+
// Pointer to user-provided data passed to the callback function.
548562
void* user_data;
549563

564+
// Pointer to the user-provided callback function that is called when an
565+
// event occurs during the scan (a rule matching, a module being loaded, etc)
566+
YR_CALLBACK_FUNC callback;
567+
568+
// Pointer to the YR_RULES object associated to this scan context.
550569
YR_RULES* rules;
570+
571+
// Pointer to the YR_STRING causing the most recent scan error.
572+
YR_STRING* last_error_string;
573+
574+
// Pointer to the iterator used for scanning
551575
YR_MEMORY_BLOCK_ITERATOR* iterator;
576+
577+
// Pointer to a table mapping identifiers to YR_OBJECT structures. This table
578+
// contains entries for external variables and modules.
552579
YR_HASH_TABLE* objects_table;
553-
YR_CALLBACK_FUNC callback;
554580

581+
// Arena used for storing YR_MATCH structures asociated to the matches found.
555582
YR_ARENA* matches_arena;
583+
584+
// Arena used for storing pointers to the YR_STRING struct for each matching
585+
// string. The pointers are used by _yr_scanner_clean_matches.
556586
YR_ARENA* matching_strings_arena;
557587

588+
// Fiber pool used by yr_re_exec.
558589
RE_FIBER_POOL re_fiber_pool;
559590

560591
} YR_SCAN_CONTEXT;
561592

562593

563594
struct _YR_OBJECT;
564595

596+
565597
typedef union _YR_VALUE
566598
{
567599
int64_t i;

libyara/parser.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ static int _yr_parser_write_string(
316316
offsetof(YR_STRING, identifier),
317317
offsetof(YR_STRING, string),
318318
offsetof(YR_STRING, chained_to),
319+
offsetof(YR_STRING, rule),
319320
EOL);
320321

321322
if (result != ERROR_SUCCESS)
@@ -358,6 +359,7 @@ static int _yr_parser_write_string(
358359
(*string)->g_flags = flags;
359360
(*string)->chained_to = NULL;
360361
(*string)->fixed_offset = UNDEFINED;
362+
(*string)->rule = compiler->current_rule;
361363

362364
#ifdef PROFILING_ENABLED
363365
(*string)->clock_ticks = 0;

libyara/scan.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,8 @@ int yr_scan_verify_match(
756756
{
757757
YR_STRING* string = ac_match->string;
758758

759+
int result;
760+
759761
if (data_size - offset <= 0)
760762
return ERROR_SUCCESS;
761763

@@ -778,18 +780,21 @@ int yr_scan_verify_match(
778780

779781
if (STRING_IS_LITERAL(string))
780782
{
781-
FAIL_ON_ERROR(_yr_scan_verify_literal_match(
782-
context, ac_match, data, data_size, data_base, offset));
783+
result = _yr_scan_verify_literal_match(
784+
context, ac_match, data, data_size, data_base, offset);
783785
}
784786
else
785787
{
786-
FAIL_ON_ERROR(_yr_scan_verify_re_match(
787-
context, ac_match, data, data_size, data_base, offset));
788+
result = _yr_scan_verify_re_match(
789+
context, ac_match, data, data_size, data_base, offset);
788790
}
789791

792+
if (result != ERROR_SUCCESS)
793+
context->last_error_string = string;
794+
790795
#ifdef PROFILING_ENABLED
791796
string->clock_ticks += yr_stopwatch_elapsed_ns(&stopwatch, FALSE);
792797
#endif
793798

794-
return ERROR_SUCCESS;
799+
return result;
795800
}

libyara/scanner.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,3 +600,20 @@ YR_API int yr_scanner_scan_proc(
600600

601601
return result;
602602
}
603+
604+
605+
YR_API YR_STRING* yr_scanner_last_error_string(
606+
YR_SCANNER* scanner)
607+
{
608+
return scanner->last_error_string;
609+
}
610+
611+
612+
YR_API YR_RULE* yr_scanner_last_error_rule(
613+
YR_SCANNER* scanner)
614+
{
615+
if (scanner->last_error_string == NULL)
616+
return NULL;
617+
618+
return scanner->last_error_string->rule;
619+
}

tests/test-alignment.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,15 @@ int main (int argc, char **argv)
7979
CHECK_OFFSET(YR_MATCHES, 8, head);
8080
CHECK_OFFSET(YR_MATCHES, 16, tail);
8181

82-
CHECK_SIZE(YR_STRING, 56 + 2 * 24 /* YR_MATCHES */ * MAX_THREADS);
82+
CHECK_SIZE(YR_STRING, 64 + 2 * 24 /* YR_MATCHES */ * MAX_THREADS);
8383
CHECK_OFFSET(YR_STRING, 4, length);
8484
CHECK_OFFSET(YR_STRING, 8, identifier);
8585
CHECK_OFFSET(YR_STRING, 16, string);
8686
CHECK_OFFSET(YR_STRING, 24, chained_to);
87-
CHECK_OFFSET(YR_STRING, 32, chain_gap_min);
88-
CHECK_OFFSET(YR_STRING, 36, chain_gap_max);
89-
CHECK_OFFSET(YR_STRING, 40, fixed_offset);
87+
CHECK_OFFSET(YR_STRING, 32, rule);
88+
CHECK_OFFSET(YR_STRING, 40, chain_gap_min);
89+
CHECK_OFFSET(YR_STRING, 44, chain_gap_max);
90+
CHECK_OFFSET(YR_STRING, 48, fixed_offset);
9091

9192
CHECK_SIZE(YR_RULE, 16 + 4 * MAX_THREADS + 40);
9293
CHECK_OFFSET(YR_RULE, 4, t_flags);

0 commit comments

Comments
 (0)