From 4adf441efa8c8834d3d459892e997b0c7a9b669a Mon Sep 17 00:00:00 2001 From: Andrei KISARI Date: Thu, 13 Aug 2020 10:55:19 +0300 Subject: [PATCH] Added support for byte-like objects as input value in pybddisasm. --- pybddisasm/_pybddisasm/_pybddisasm.c | 93 +++++++++++++++++++++++----- pybddisasm/setup.py | 10 +-- 2 files changed, 83 insertions(+), 20 deletions(-) diff --git a/pybddisasm/_pybddisasm/_pybddisasm.c b/pybddisasm/_pybddisasm/_pybddisasm.c index 3e91162..d0be785 100644 --- a/pybddisasm/_pybddisasm/_pybddisasm.c +++ b/pybddisasm/_pybddisasm/_pybddisasm.c @@ -967,18 +967,60 @@ static uint8_t _pybddisasm_py_stack_to_disasm(uint8_t stack) } +static char * _pybddisasm_get_contiguous_buffer(Py_buffer *view) +{ + char *buffer = NULL; + + if (PyBuffer_IsContiguous(view, 'C')) + { + return view->buf; + } + + buffer = (char *)malloc(sizeof(char) * view->len); + if (!buffer) + { + PyErr_SetString(PyExc_ValueError, "failed to allocate memory for contiguous buffer!"); + return NULL; + } + + if (PyBuffer_ToContiguous(buffer, view, view->len, 'C') < 0) + { + PyErr_SetString(PyExc_ValueError, "PyBuffer_ToContiguous failed!"); + free (buffer); + return NULL; + } + + return buffer; +} + + +static void _pybddisasm_release_contiguous_buffer(Py_buffer *view, char *buffer) +{ + if (!PyBuffer_IsContiguous(view, 'C')) + { + free(buffer); + } +} + + static PyObject *pybddisasm_decode_ex(PyObject *self, PyObject *args) { - char *buf = NULL; - Py_ssize_t bufsize = 0; + char *buffer = NULL; uint64_t rip = 0; uint8_t code, data; + Py_buffer view; (void)self; - if (!PyArg_ParseTuple(args, "s#BB|K", &buf, &bufsize, &code, &data, &rip)) + if (!PyArg_ParseTuple(args, "y*BB|K", &view, &code, &data, &rip)) + { + PyErr_SetString(PyExc_ValueError, "invalid arguments. expected: "); + Py_RETURN_NONE; + } + + buffer = _pybddisasm_get_contiguous_buffer(&view); + if (!buffer) { - PyErr_SetString(PyExc_ValueError, "invalid arguments. expected: "); Py_RETURN_NONE; } @@ -992,29 +1034,38 @@ static PyObject *pybddisasm_decode_ex(PyObject *self, PyObject *args) INSTRUX instr; - NDSTATUS status = nd_decode_ex(&instr, buf, bufsize, code, data); + NDSTATUS status = nd_decode_ex(&instr, buffer, view.len, code, data); if (!ND_SUCCESS(status)) { Py_RETURN_NONE; } + _pybddisasm_release_contiguous_buffer(&view, buffer); + PyBuffer_Release(&view); + return _pybddisasm_build_instr_dict(&instr, rip); } static PyObject *pybddisasm_decode_ex2(PyObject *self, PyObject *args) { - char *buf = NULL; char *str_vend = NULL; - Py_ssize_t bufsize = 0; + char *buffer = NULL; uint64_t rip = 0; uint8_t code, data, stack, vend; + Py_buffer view; (void)self; - if (!PyArg_ParseTuple(args, "s#BBBs|K", &buf, &bufsize, &code, &data, &stack, &str_vend, &rip)) + if (!PyArg_ParseTuple(args, "y*BBBs|K", &view, &code, &data, &stack, &str_vend, &rip)) + { + PyErr_SetString(PyExc_ValueError, "invalid arguments. expected: "); + Py_RETURN_NONE; + } + + buffer = _pybddisasm_get_contiguous_buffer(&view); + if (!buffer) { - PyErr_SetString(PyExc_ValueError, "invalid arguments. expected: "); Py_RETURN_NONE; } @@ -1055,28 +1106,37 @@ static PyObject *pybddisasm_decode_ex2(PyObject *self, PyObject *args) INSTRUX instr; - NDSTATUS status = nd_decode_ex2(&instr, buf, bufsize, code, data, stack, vend); + NDSTATUS status = nd_decode_ex2(&instr, buffer, view.len, code, data, stack, vend); if (!ND_SUCCESS(status)) { Py_RETURN_NONE; } + _pybddisasm_release_contiguous_buffer(&view, buffer); + PyBuffer_Release(&view); + return _pybddisasm_build_instr_dict(&instr, rip); } static PyObject *pybddisasm_to_text(PyObject *self, PyObject *args) { - char *buf = NULL; - Py_ssize_t bufsize = 0; + char *buffer = NULL; uint64_t rip = 0; uint8_t code, data; + Py_buffer view; (void)self; - if (!PyArg_ParseTuple(args, "s#BB|K", &buf, &bufsize, &code, &data, &rip)) + if (!PyArg_ParseTuple(args, "y*BB|K", &view, &code, &data, &rip)) + { + PyErr_SetString(PyExc_ValueError, "invalid arguments. expected: "); + Py_RETURN_NONE; + } + + buffer = _pybddisasm_get_contiguous_buffer(&view); + if (!buffer) { - PyErr_SetString(PyExc_ValueError, "invalid arguments. expected: "); Py_RETURN_NONE; } @@ -1090,7 +1150,7 @@ static PyObject *pybddisasm_to_text(PyObject *self, PyObject *args) INSTRUX instr; - NDSTATUS status = nd_decode_ex(&instr, buf, bufsize, code, data); + NDSTATUS status = nd_decode_ex(&instr, buffer, view.len, code, data); if (!ND_SUCCESS(status)) { Py_RETURN_NONE; @@ -1104,6 +1164,9 @@ static PyObject *pybddisasm_to_text(PyObject *self, PyObject *args) Py_RETURN_NONE; } + _pybddisasm_release_contiguous_buffer(&view, buffer); + PyBuffer_Release(&view); + return Py_BuildValue("{s,s,s,y#}", "text", instr_text, "bytes", instr.InstructionBytes, instr.Length); } diff --git a/pybddisasm/setup.py b/pybddisasm/setup.py index bfcde94..29d4d14 100644 --- a/pybddisasm/setup.py +++ b/pybddisasm/setup.py @@ -11,7 +11,7 @@ import re from setuptools import find_packages, setup, Command, Extension, Distribution from codecs import open -VERSION = (0, 1, 2) +VERSION = (0, 1, 3) LIBRARY_VERSION = (1, 28, 1) LIBRARY_INSTRUX_SIZE = 856 @@ -85,14 +85,14 @@ setup( 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'License :: OSI Approved :: Apache Software License', - 'Operating System :: OS Independent', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX :: Linux' ], ext_modules = [Extension("_pybddisasm", sources = ["_pybddisasm/_pybddisasm.c", "_pybddisasm/pybddisasm.c"], - define_macros = [('AMD64', None), ('Py_LIMITED_API', None), ('LIBRARY_INSTRUX_SIZE', LIBRARY_INSTRUX_SIZE)], + define_macros = [('AMD64', None), ('LIBRARY_INSTRUX_SIZE', LIBRARY_INSTRUX_SIZE)], include_dirs = ['../inc'], libraries = ['bddisasm'], - library_dirs = ['/usr/local/lib', '../bin/x64/Release'], - py_limited_api=True)], + library_dirs = ['/usr/local/lib', '../bin/x64/Release'])], distclass=BinaryDistribution )