Bugfix to get_bytes and add section.data.

If get_bytes does not fill the list, get a slice of what was filled and
use that to convert to a bytearray. I still want to find a way to just
use a bytearray from the start. Luckily with the rest of this commit I
don't have a need to call get_bytes() on sections anymore.

Sections now have a data attribute which is a bytearray of the data that
makes up that section. This way you can just use section.data attribute
to get the entire contents and operate on it as you wish.

Make test.py use section.data to generate an MD5 of the section. It now
also prints the first 10 bytes of each section (if there are bytes).
This commit is contained in:
Wesley Shields 2013-12-14 22:26:58 -05:00
parent 23ebc6e799
commit dae8606469
2 changed files with 38 additions and 5 deletions

View File

@ -64,6 +64,7 @@ typedef struct {
PyObject *numrelocs;
PyObject *numlinenums;
PyObject *characteristics;
PyObject *data;
} pepy_section;
typedef struct {
@ -320,7 +321,7 @@ static PyObject *pepy_section_new(PyTypeObject *type, PyObject *args, PyObject *
}
static int pepy_section_init(pepy_section *self, PyObject *args, PyObject *kwds) {
if (!PyArg_ParseTuple(args, "OOOOOOOO:pepy_section_init", &self->name, &self->base, &self->length, &self->virtaddr, &self->virtsize, &self->numrelocs, &self->numlinenums, &self->characteristics))
if (!PyArg_ParseTuple(args, "OOOOOOOOO:pepy_section_init", &self->name, &self->base, &self->length, &self->virtaddr, &self->virtsize, &self->numrelocs, &self->numlinenums, &self->characteristics, &self->data))
return -1;
return 0;
}
@ -345,6 +346,7 @@ PEPY_OBJECT_GET(section, virtsize)
PEPY_OBJECT_GET(section, numrelocs)
PEPY_OBJECT_GET(section, numlinenums)
PEPY_OBJECT_GET(section, characteristics)
PEPY_OBJECT_GET(section, data)
static PyGetSetDef pepy_section_getseters[] = {
OBJECTGETTER(section, name, "Name"),
@ -355,6 +357,7 @@ static PyGetSetDef pepy_section_getseters[] = {
OBJECTGETTER(section, numrelocs, "Number of relocations"),
OBJECTGETTER(section, numlinenums, "Number of line numbers"),
OBJECTGETTER(section, characteristics, "Characteristics"),
OBJECTGETTER(section, data, "Section data"),
{ NULL }
};
@ -450,7 +453,7 @@ static PyObject *pepy_parsed_get_bytes(PyObject *self, PyObject *args) {
uint64_t start, idx;
uint8_t b;
Py_ssize_t len;
PyObject *byte, *tmp, *ret;
PyObject *byte, *tmp, *ret, *newlist;
if (!PyArg_ParseTuple(args, "KK:pepy_parsed_get_bytes", &start, &len))
return NULL;
@ -462,7 +465,7 @@ static PyObject *pepy_parsed_get_bytes(PyObject *self, PyObject *args) {
*/
tmp = PyList_New(len);
if (!tmp) {
PyErr_SetString(pepy_error, "Unable to create new list.");
PyErr_SetString(pepy_error, "Unable to create initial list.");
return NULL;
}
@ -475,6 +478,17 @@ static PyObject *pepy_parsed_get_bytes(PyObject *self, PyObject *args) {
Py_DECREF(byte);
}
/* Didn't get all of it for some reason, so give back what we have. */
if (idx < len) {
newlist = PyList_GetSlice(tmp, 0, idx);
if (!newlist) {
PyErr_SetString(pepy_error, "Unable to create new list.");
return NULL;
}
Py_DECREF(tmp);
tmp = newlist;
}
ret = PyByteArray_FromObject(tmp);
if (!ret) {
PyErr_SetString(pepy_error, "Unable to create new list.");
@ -485,6 +499,18 @@ static PyObject *pepy_parsed_get_bytes(PyObject *self, PyObject *args) {
return ret;
}
static PyObject *pepy_section_data_converter(bounded_buffer *data) {
PyObject* ret;
ret = PyByteArray_FromStringAndSize((const char *) data->buf, data->bufLen);
if (!ret) {
PyErr_SetString(pepy_error, "Unable to convert data to byte array.");
return NULL;
}
return ret;
}
int section_callback(void *cbd, VA base, std::string &name, image_section_header s, bounded_buffer *data) {
PyObject *sect;
PyObject *tuple;
@ -494,10 +520,11 @@ int section_callback(void *cbd, VA base, std::string &name, image_section_header
* The tuple item order is important here. It is passed into the
* section type initialization and parsed there.
*/
tuple = Py_BuildValue("sKKIIHHI", name.c_str(), base, data->bufLen,
tuple = Py_BuildValue("sKKIIHHIO&", name.c_str(), base, data->bufLen,
s.VirtualAddress, s.Misc.VirtualSize,
s.NumberOfRelocations, s.NumberOfLinenumbers,
s.Characteristics);
s.Characteristics, pepy_section_data_converter,
data);
if (!tuple)
return 1;

View File

@ -3,6 +3,9 @@
import sys
import time
import pepy
import binascii
from hashlib import md5
p = pepy.parse(sys.argv[1])
print "Magic: %s" % hex(p.magic)
@ -51,6 +54,9 @@ for sect in sections:
print "\tNumber of Relocations: %i" % sect.numrelocs
print "\tNumber of Line Numbers: %i" % sect.numlinenums
print "\tCharacteristics: %s" % hex(sect.characteristics)
if sect.length:
print "\tFirst 10 bytes: 0x%s" % binascii.hexlify(sect.data[:10])
print "\tMD5: %s" % md5(sect.data).hexdigest()
imports = p.get_imports()
print "Imports: (%i)" % len(imports)
for imp in imports: