Commit 6b7269cf by Wesley Shields Committed by Victor M. Alvarez

Which callbacks (#66)

Add a 'which_callbacks' keyword to match(), which limits when the Python callback will be called.
parent a4bbe7c2
...@@ -829,6 +829,13 @@ class TestYara(unittest.TestCase): ...@@ -829,6 +829,13 @@ class TestYara(unittest.TestCase):
self.assertTrue(rule_data['matches']) self.assertTrue(rule_data['matches'])
self.assertTrue(rule_data['rule'] == 'test') self.assertTrue(rule_data['rule'] == 'test')
rule_data = None
r = yara.compile(source='rule test { condition: false }')
r.match(data='dummy', callback=callback, which_callbacks=yara.CALLBACK_NON_MATCHES)
self.assertTrue(rule_data['rule'] == 'test')
def testCompare(self): def testCompare(self):
r = yara.compile(sources={ r = yara.compile(sources={
......
...@@ -389,6 +389,7 @@ typedef struct _CALLBACK_DATA ...@@ -389,6 +389,7 @@ typedef struct _CALLBACK_DATA
PyObject* callback; PyObject* callback;
PyObject* modules_data; PyObject* modules_data;
PyObject* modules_callback; PyObject* modules_callback;
int which;
} CALLBACK_DATA; } CALLBACK_DATA;
...@@ -551,6 +552,10 @@ PyObject* convert_dictionary_to_python( ...@@ -551,6 +552,10 @@ PyObject* convert_dictionary_to_python(
} }
#define CALLBACK_MATCHES 0x01
#define CALLBACK_NON_MATCHES 0x02
#define CALLBACK_ALL CALLBACK_MATCHES | CALLBACK_NON_MATCHES
int yara_callback( int yara_callback(
int message, int message,
void* message_data, void* message_data,
...@@ -578,6 +583,7 @@ int yara_callback( ...@@ -578,6 +583,7 @@ int yara_callback(
PyObject* module_data; PyObject* module_data;
PyObject* callback_result; PyObject* callback_result;
PyObject* module_info_dict; PyObject* module_info_dict;
int which = ((CALLBACK_DATA*) user_data)->which;
Py_ssize_t data_size; Py_ssize_t data_size;
PyGILState_STATE gil_state; PyGILState_STATE gil_state;
...@@ -587,7 +593,8 @@ int yara_callback( ...@@ -587,7 +593,8 @@ int yara_callback(
if (message == CALLBACK_MSG_SCAN_FINISHED) if (message == CALLBACK_MSG_SCAN_FINISHED)
return CALLBACK_CONTINUE; return CALLBACK_CONTINUE;
if (message == CALLBACK_MSG_RULE_NOT_MATCHING && callback == NULL) if (message == CALLBACK_MSG_RULE_NOT_MATCHING &&
(callback == NULL || (which & CALLBACK_MATCHES)))
return CALLBACK_CONTINUE; return CALLBACK_CONTINUE;
if (message == CALLBACK_MSG_IMPORT_MODULE && modules_data == NULL) if (message == CALLBACK_MSG_IMPORT_MODULE && modules_data == NULL)
...@@ -758,7 +765,9 @@ int yara_callback( ...@@ -758,7 +765,9 @@ int yara_callback(
} }
} }
if (callback != NULL) if (callback != NULL &&
((message == CALLBACK_MSG_RULE_MATCHING && (which & CALLBACK_MATCHES)) ||
(message == CALLBACK_MSG_RULE_NOT_MATCHING && (which & CALLBACK_NON_MATCHES))))
{ {
Py_INCREF(callback); Py_INCREF(callback);
...@@ -1331,7 +1340,7 @@ static PyObject* Rules_match( ...@@ -1331,7 +1340,7 @@ static PyObject* Rules_match(
static char* kwlist[] = { static char* kwlist[] = {
"filepath", "pid", "data", "externals", "filepath", "pid", "data", "externals",
"callback", "fast", "timeout", "modules_data", "callback", "fast", "timeout", "modules_data",
"modules_callback", NULL "modules_callback", "which_callbacks", NULL
}; };
char* filepath = NULL; char* filepath = NULL;
...@@ -1354,11 +1363,12 @@ static PyObject* Rules_match( ...@@ -1354,11 +1363,12 @@ static PyObject* Rules_match(
callback_data.callback = NULL; callback_data.callback = NULL;
callback_data.modules_data = NULL; callback_data.modules_data = NULL;
callback_data.modules_callback = NULL; callback_data.modules_callback = NULL;
callback_data.which = CALLBACK_ALL;
if (PyArg_ParseTupleAndKeywords( if (PyArg_ParseTupleAndKeywords(
args, args,
keywords, keywords,
"|sis#OOOiOO", "|sis#OOOiOOi",
kwlist, kwlist,
&filepath, &filepath,
&pid, &pid,
...@@ -1369,7 +1379,8 @@ static PyObject* Rules_match( ...@@ -1369,7 +1379,8 @@ static PyObject* Rules_match(
&fast, &fast,
&timeout, &timeout,
&callback_data.modules_data, &callback_data.modules_data,
&callback_data.modules_callback)) &callback_data.modules_callback,
&callback_data.which))
{ {
if (filepath == NULL && data == NULL && pid == 0) if (filepath == NULL && data == NULL && pid == 0)
{ {
...@@ -2136,6 +2147,9 @@ MOD_INIT(yara) ...@@ -2136,6 +2147,9 @@ MOD_INIT(yara)
PyModule_AddIntConstant(m, "CALLBACK_CONTINUE", 0); PyModule_AddIntConstant(m, "CALLBACK_CONTINUE", 0);
PyModule_AddIntConstant(m, "CALLBACK_ABORT", 1); PyModule_AddIntConstant(m, "CALLBACK_ABORT", 1);
PyModule_AddIntConstant(m, "CALLBACK_MATCHES", CALLBACK_MATCHES);
PyModule_AddIntConstant(m, "CALLBACK_NON_MATCHES", CALLBACK_NON_MATCHES);
PyModule_AddIntConstant(m, "CALLBACK_ALL", CALLBACK_ALL);
PyModule_AddStringConstant(m, "__version__", YR_VERSION); PyModule_AddStringConstant(m, "__version__", YR_VERSION);
PyModule_AddStringConstant(m, "YARA_VERSION", YR_VERSION); PyModule_AddStringConstant(m, "YARA_VERSION", YR_VERSION);
PyModule_AddIntConstant(m, "YARA_VERSION_HEX", YR_VERSION_HEX); PyModule_AddIntConstant(m, "YARA_VERSION_HEX", YR_VERSION_HEX);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment