[Forensics-changes] [yara] 189/415: Allow to specify a timeout in scanning functions
Hilko Bengen
bengen at moszumanska.debian.org
Thu Apr 3 05:43:04 UTC 2014
This is an automated email from the git hooks/post-receive script.
bengen pushed a commit to branch debian
in repository yara.
commit eb3bd52919c630162bdce39141af040a1ec54e15
Author: Victor M. Alvarez <plusvic at gmail.com>
Date: Tue Jul 2 14:18:00 2013 +0000
Allow to specify a timeout in scanning functions
---
libyara/rules.c | 45 ++++++++++++++++++++++++++++++++++++---------
libyara/yara.h | 10 +++++++---
yara-python/yara-python.c | 27 +++++++++++++++++++++------
yara.c | 36 ++++++++++++++++++++++++++++++------
4 files changed, 94 insertions(+), 24 deletions(-)
diff --git a/libyara/rules.c b/libyara/rules.c
index 526fb0f..32e1760 100644
--- a/libyara/rules.c
+++ b/libyara/rules.c
@@ -15,6 +15,7 @@ limitations under the License.
*/
#include <string.h>
+#include <time.h>
#include "arena.h"
#include "exec.h"
@@ -596,13 +597,18 @@ int yr_rules_scan_mem_block(
YARA_RULES* rules,
uint8_t* data,
size_t data_size,
- int fast_scan_mode)
+ int fast_scan_mode,
+ int timeout,
+ time_t start_time)
{
AC_STATE* next_state;
AC_MATCH* ac_match;
AC_STATE* current_state;
+
+ time_t current_time;
size_t i;
+
int result;
current_state = rules->automaton->root;
@@ -646,6 +652,14 @@ int yr_rules_scan_mem_block(
current_state = next_state;
i++;
+
+ if (timeout > 0 && i % 256 == 0)
+ {
+ current_time = time(NULL);
+
+ if (difftime(current_time, start_time) > timeout)
+ return ERROR_TIMEOUT;
+ }
}
ac_match = current_state->matches;
@@ -674,11 +688,14 @@ int yr_rules_scan_mem_blocks(
int scanning_process_memory,
YARACALLBACK callback,
void* user_data,
- int fast_scan_mode)
+ int fast_scan_mode,
+ int timeout)
{
RULE* rule;
EVALUATION_CONTEXT context;
+ time_t start_time;
+
char message[512];
int result;
@@ -688,6 +705,8 @@ int yr_rules_scan_mem_blocks(
yr_rules_free_matches(rules);
+ start_time = time(NULL);
+
while (block != NULL)
{
if (context.entry_point == UNDEFINED)
@@ -707,7 +726,9 @@ int yr_rules_scan_mem_blocks(
rules,
block->data,
block->size,
- fast_scan_mode);
+ fast_scan_mode,
+ timeout,
+ start_time);
if (result != ERROR_SUCCESS)
return result;
@@ -763,7 +784,8 @@ int yr_rules_scan_mem(
size_t buffer_size,
YARACALLBACK callback,
void* user_data,
- int fast_scan_mode)
+ int fast_scan_mode,
+ int timeout)
{
MEMORY_BLOCK block;
@@ -778,7 +800,8 @@ int yr_rules_scan_mem(
FALSE,
callback,
user_data,
- fast_scan_mode);
+ fast_scan_mode,
+ timeout);
}
@@ -787,7 +810,8 @@ int yr_rules_scan_file(
const char* filename,
YARACALLBACK callback,
void* user_data,
- int fast_scan_mode)
+ int fast_scan_mode,
+ int timeout)
{
MAPPED_FILE mfile;
int result;
@@ -802,7 +826,8 @@ int yr_rules_scan_file(
mfile.size,
callback,
user_data,
- fast_scan_mode);
+ fast_scan_mode,
+ timeout);
yr_filemap_unmap(&mfile);
}
@@ -816,7 +841,8 @@ int yr_rules_scan_proc(
int pid,
YARACALLBACK callback,
void* user_data,
- int fast_scan_mode)
+ int fast_scan_mode,
+ int timeout)
{
MEMORY_BLOCK* first_block;
MEMORY_BLOCK* next_block;
@@ -833,7 +859,8 @@ int yr_rules_scan_proc(
TRUE,
callback,
user_data,
- fast_scan_mode);
+ fast_scan_mode,
+ timeout);
block = first_block;
diff --git a/libyara/yara.h b/libyara/yara.h
index d0ed1a8..7fa2ff9 100644
--- a/libyara/yara.h
+++ b/libyara/yara.h
@@ -78,6 +78,7 @@ limitations under the License.
#define ERROR_INCLUDE_DEPTH_EXCEEDED 32
#define ERROR_INVALID_OR_CORRUPT_FILE 33
#define ERROR_EXEC_STACK_OVERFLOW 34
+#define ERROR_TIMEOUT 35
#define MAX_INCLUDE_DEPTH 16
#define LEX_BUF_SIZE 1024
@@ -563,7 +564,8 @@ int yr_rules_scan_mem(
size_t buffer_size,
YARACALLBACK callback,
void* user_data,
- int fast_scan_mode);
+ int fast_scan_mode,
+ int timeout);
int yr_rules_scan_file(
@@ -571,7 +573,8 @@ int yr_rules_scan_file(
const char* filename,
YARACALLBACK callback,
void* user_data,
- int fast_scan_mode);
+ int fast_scan_mode,
+ int timeout);
int yr_rules_scan_proc(
@@ -579,7 +582,8 @@ int yr_rules_scan_proc(
int pid,
YARACALLBACK callback,
void* user_data,
- int fast_scan_mode);
+ int fast_scan_mode,
+ int timeout);
int yr_rules_save(
diff --git a/yara-python/yara-python.c b/yara-python/yara-python.c
index e43b5d7..a29611b 100644
--- a/yara-python/yara-python.c
+++ b/yara-python/yara-python.c
@@ -53,6 +53,7 @@ typedef int Py_ssize_t;
static PyObject *YaraError = NULL;
static PyObject *YaraSyntaxError = NULL;
+static PyObject *YaraTimeoutError = NULL;
#define YARA_DOC "\
@@ -595,6 +596,10 @@ PyObject* handle_error(
YaraError,
"invalid or corrupt compiled rules file \"%s\"",
extra);
+ case ERROR_TIMEOUT:
+ return PyErr_Format(
+ YaraTimeoutError,
+ "scanning timed out");
default:
return PyErr_Format(
YaraError,
@@ -744,12 +749,15 @@ static PyObject * Rules_match(
PyObject *keywords)
{
static char *kwlist[] = {
- "filepath", "pid", "data", "externals", "callback", "fast", NULL};
+ "filepath", "pid", "data", "externals",
+ "callback", "fast", "timeout", NULL
+ };
char* filepath = NULL;
char* data = NULL;
int pid = 0;
+ int timeout = 0;
int length;
int error;
int fast_mode = FALSE;
@@ -766,7 +774,7 @@ static PyObject * Rules_match(
if (PyArg_ParseTupleAndKeywords(
args,
keywords,
- "|sis#OOO",
+ "|sis#OOOi",
kwlist,
&filepath,
&pid,
@@ -774,7 +782,8 @@ static PyObject * Rules_match(
&length,
&externals,
&callback_data.callback,
- &fast))
+ &fast,
+ &timeout))
{
if (externals != NULL)
{
@@ -821,7 +830,8 @@ static PyObject * Rules_match(
filepath,
yara_callback,
&callback_data,
- fast_mode);
+ fast_mode,
+ timeout);
Py_END_ALLOW_THREADS
@@ -847,7 +857,8 @@ static PyObject * Rules_match(
(unsigned int) length,
yara_callback,
&callback_data,
- fast_mode);
+ fast_mode,
+ timeout);
Py_END_ALLOW_THREADS
@@ -872,7 +883,8 @@ static PyObject * Rules_match(
pid,
yara_callback,
&callback_data,
- fast_mode);
+ fast_mode,
+ timeout);
Py_END_ALLOW_THREADS
@@ -1291,9 +1303,11 @@ MOD_INIT(yara)
#if PYTHON_API_VERSION >= 1007
YaraError = PyErr_NewException("yara.Error", PyExc_Exception, NULL);
YaraSyntaxError = PyErr_NewException("yara.SyntaxError", YaraError, NULL);
+ YaraTimeoutError = PyErr_NewException("yara.TimeoutError", YaraError, NULL);
#else
YaraError = Py_BuildValue("s", "yara.Error");
YaraSyntaxError = Py_BuildValue("s", "yara.SyntaxError");
+ YaraTimeoutError = Py_BuildValue("s", "yara.TimeoutError");
#endif
if (PyType_Ready(&Rules_Type) < 0)
@@ -1304,6 +1318,7 @@ MOD_INIT(yara)
PyModule_AddObject(m, "Error", YaraError);
PyModule_AddObject(m, "SyntaxError", YaraSyntaxError);
+ PyModule_AddObject(m, "TimeoutError", YaraTimeoutError);
yr_initialize();
diff --git a/yara.c b/yara.c
index 5394416..85eac30 100644
--- a/yara.c
+++ b/yara.c
@@ -55,6 +55,7 @@ int fast_scan = FALSE;
int negate = FALSE;
int count = 0;
int limit = 0;
+int timeout = 0;
typedef struct _TAG
@@ -104,7 +105,8 @@ EXTERNAL* externals_list = NULL;
" -g print tags.\n"\
" -m print metadata.\n"\
" -s print matching strings.\n"\
-" -l <number> abort scanning after matching <number> rules.\n"\
+" -l <number> abort scanning after matching a <number> rules.\n"\
+" -a <seconds> abort scanning after a number of seconds has elapsed.\n"\
" -d <identifier>=<value> define external variable.\n"\
" -r recursively search directories.\n"\
" -v show version information.\n"
@@ -176,7 +178,8 @@ int scan_dir(
full_path,
callback,
full_path,
- TRUE);
+ fast_scan,
+ timeout);
}
else if (recursive && FindFileData.cFileName[0] != '.' )
{
@@ -243,7 +246,8 @@ int scan_dir(
full_path,
callback,
full_path,
- fast_scan);
+ fast_scan,
+ timeout);
}
else if(recursive && S_ISDIR(st.st_mode) && de->d_name[0] != '.')
{
@@ -484,7 +488,7 @@ int process_cmd_line(
opterr = 0;
- while ((c = getopt (argc, (char**) argv, "rnsvgml:t:i:d:f")) != -1)
+ while ((c = getopt (argc, (char**) argv, "rnsvgma:l:t:i:d:f")) != -1)
{
switch (c)
{
@@ -593,6 +597,10 @@ int process_cmd_line(
limit = atoi(optarg);
break;
+ case 'a':
+ timeout = atoi(optarg);
+ break;
+
case '?':
if (optopt == 't')
@@ -682,6 +690,8 @@ int main(
int errors;
int result;
+ clock_t start, end;
+
if (!process_cmd_line(argc, argv))
return 0;
@@ -797,7 +807,8 @@ int main(
pid,
callback,
(void*) argv[argc - 1],
- fast_scan);
+ fast_scan,
+ timeout);
}
else if (is_directory(argv[argc - 1]))
{
@@ -809,12 +820,19 @@ int main(
}
else
{
+ start = clock();
+
result = yr_rules_scan_file(
rules,
argv[argc - 1],
callback,
(void*) argv[argc - 1],
- fast_scan);
+ fast_scan,
+ timeout);
+
+ end = clock();
+
+ printf( "Scanning time: %f s\n", (float)(end - start) / CLOCKS_PER_SEC);
}
switch (result)
@@ -827,6 +845,12 @@ int main(
case ERROR_INSUFICIENT_MEMORY:
fprintf(stderr, "not enough memory\n");
break;
+ case ERROR_TIMEOUT:
+ fprintf(stderr, "scanning timed out\n");
+ break;
+ case ERROR_COULD_NOT_OPEN_FILE:
+ fprintf(stderr, "could not open file\n");
+ break;
default:
fprintf(stderr, "internal error: %d\n", result);
break;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/forensics/yara.git
More information about the forensics-changes
mailing list