Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Callback on include #58

Closed
wants to merge 15 commits into from
Closed

Conversation

edhoedt
Copy link

@edhoedt edhoedt commented Aug 28, 2017

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)

yara-python.c Outdated
py_calling_ns = Py_None;
}

PyObject* result = PyObject_CallFunctionObjArgs(callback,
Copy link
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?

yara-python.c Outdated

if (include_name != NULL)
{
py_incl_name = PY_STRING(include_name);
Copy link
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.

yara-python.c Outdated
py_calling_ns = Py_None;
}

PyObject* result = PyObject_CallFunctionObjArgs(callback,
Copy link
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.

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

if (include_name != NULL)
Copy link
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
Copy link
Member

plusvic commented Oct 31, 2017

@edhoedt please check #67

@plusvic
Copy link
Member

plusvic commented Oct 31, 2017

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