Skip to content

Callback on include - #58

Closed
edhoedt wants to merge 15 commits into
VirusTotal:masterfrom
edhoedt:callback_on_include
Closed

Callback on include#58
edhoedt wants to merge 15 commits into
VirusTotal:masterfrom
edhoedt:callback_on_include

Conversation

@edhoedt

@edhoedt edhoedt commented Aug 28, 2017

Copy link
Copy Markdown

Python interface for pull request VirusTotal/yara#727

Example usage:

import yara
import sys
if sys.version_info >= (3, 0):
    import urllib.request as urllib
else:
    import urllib as urllib

def mycallback(requested_filename, filename, namespace):
    if requested_filename == 'req.yara':
        uf = urllib.urlopen('https://pastebin.com/raw/siZ2sMTM')
        sources = uf.read()
        if sys.version_info >= (3, 0):
            sources = str(sources, 'utf-8')
        return sources
    else:
        raise Exception(filename+": Can't fetch "+requested_filename)

rules = yara.compile(source='include "req.yara" rule r{ condition: true }',
                     include_callback=mycallback)

Comment thread yara-python.c
py_calling_ns = Py_None;
}

PyObject* result = PyObject_CallFunctionObjArgs(callback,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string returned by the callback is never freed. When PyObject_CallFunctionObjArgs returns the reference count for result is >=1 and your code has the ownership for that string. In order to let the garbage collector free the string you must do a Py_DECREF at some point.

The problem here is that you can't do it in yara_include_callback, because then you are returning to YARA a string that could be freed by the garbage collector at any time. But if you can't do it here, then where?

Comment thread yara-python.c

if (include_name != NULL)
{
py_incl_name = PY_STRING(include_name);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You must do a Py_DECREF(py_incl_name) when you are done with the Python string in order to let the garbage collector free the memory. The same applies to py_calling_fn and py_calling_ns.

Comment thread yara-python.c
py_calling_ns = Py_None;
}

PyObject* result = PyObject_CallFunctionObjArgs(callback,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You must do Py_INCREF(callback) before PyObject_CallFunctionObjArgs and Py_DECREF(callback) after it.

Comment thread yara-python.c
PyObject* py_calling_fn = NULL;
PyObject* py_calling_ns = NULL;

if (include_name != NULL)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before calling any Python function you must acquire the global interpreter lock (GIL) with PyGILState_Ensure and release it with PyGILState_Release.

plusvic added a commit that referenced this pull request Oct 31, 2017
@plusvic

plusvic commented Oct 31, 2017

Copy link
Copy Markdown
Member

@edhoedt please check #67

@plusvic

plusvic commented Oct 31, 2017

Copy link
Copy Markdown
Member

Closing this PR as #67 fix conflicts and some other issues.

@plusvic plusvic closed this Oct 31, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants