From eb9b7fd76451db5c9f07a800c0394480e4b88c9c Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 16 Jan 2018 19:42:29 +0100 Subject: Improved the removal of format symbols. --- ChangeLog | 16 ++++++ plugins/pychrysa/format/format.c | 104 +++++++++++++++++++++++++++++++++++++-- plugins/pychrysa/format/symbol.c | 2 +- src/format/format.c | 15 +++--- tests/format/format.py | 66 +++++++++++++++++++++++++ 5 files changed, 192 insertions(+), 11 deletions(-) create mode 100644 tests/format/format.py diff --git a/ChangeLog b/ChangeLog index 416027c..bd8482a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +18-01-16 Cyrille Bagard + + * plugins/pychrysa/format/format.c: + Add and remove symbols from the Python API. + + * plugins/pychrysa/format/symbol.c: + Typo. + + * src/format/format.c: + Improve the removal of format symbols. + + * tests/format/format.py: + New entry: create a test suite entry for checking the addition / removal + of symbols. + 18-01-13 Cyrille Bagard * plugins/pychrysa/format/Makefile.am: @@ -17,6 +32,7 @@ * src/analysis/disass/output.c: * src/analysis/disass/routines.c: * src/analysis/disass/routines.h: + Update code. * src/arch/processor.c: Fix a compilation bug when NDEBUG is defined. diff --git a/plugins/pychrysa/format/format.c b/plugins/pychrysa/format/format.c index 5920b27..3bfc705 100644 --- a/plugins/pychrysa/format/format.c +++ b/plugins/pychrysa/format/format.c @@ -31,6 +31,7 @@ #include +#include "symbol.h" #include "symiter.h" #include "../helpers.h" #include "../arch/vmpa.h" @@ -40,6 +41,13 @@ /* ---------------------------- FORMAT BINAIRE GENERIQUE ---------------------------- */ + +/* Ajoute un symbole à la collection du format binaire. */ +static PyObject *py_binary_format_add_symbol(PyObject *, PyObject *); + +/* Retire un symbole de la collection du format binaire. */ +static PyObject *py_binary_format_remove_symbol(PyObject *, PyObject *); + /* Recherche le symbole correspondant à une étiquette. */ static PyObject *py_binary_format_find_symbol_by_label(PyObject *, PyObject *); @@ -84,6 +92,84 @@ static bool define_python_binary_format_constants(PyTypeObject *); /* ---------------------------------------------------------------------------------- */ + + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un format. * +* args = arguments fournis à l'appel. * +* * +* Description : Ajoute un symbole à la collection du format binaire. * +* * +* Retour : True si le symbole était bien localisé et a été inséré. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_binary_format_add_symbol(PyObject *self, PyObject *args) +{ + PyObject *result; /* Valeur à retourner */ + PyObject *symbol_obj; /* Version Python d'un symbole */ + int ret; /* Bilan de lecture des args. */ + GBinFormat *format; /* Format de binaire manipulé */ + GBinSymbol *symbol; /* Enventuel symbole trouvé */ + bool added; /* Bilan de l'appel interne */ + + ret = PyArg_ParseTuple(args, "O!", get_python_binary_symbol_type(), &symbol_obj); + if (!ret) return NULL; + + format = G_BIN_FORMAT(pygobject_get(self)); + symbol = G_BIN_SYMBOL(pygobject_get(symbol_obj)); + + added = g_binary_format_add_symbol(format, symbol); + + result = added ? Py_True : Py_False; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un format. * +* args = arguments fournis à l'appel. * +* * +* Description : Retire un symbole de la collection du format binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_binary_format_remove_symbol(PyObject *self, PyObject *args) +{ + PyObject *result; /* Valeur à retourner */ + PyObject *symbol_obj; /* Version Python d'un symbole */ + int ret; /* Bilan de lecture des args. */ + GBinFormat *format; /* Format de binaire manipulé */ + GBinSymbol *symbol; /* Enventuel symbole trouvé */ + + ret = PyArg_ParseTuple(args, "O!", get_python_binary_symbol_type(), &symbol_obj); + if (!ret) return NULL; + + format = G_BIN_FORMAT(pygobject_get(self)); + symbol = G_BIN_SYMBOL(pygobject_get(symbol_obj)); + + g_binary_format_remove_symbol(format, symbol); + + result = Py_None; + Py_INCREF(result); + + return result; + +} + + /****************************************************************************** * * * Paramètres : self = classe représentant un binaire. * @@ -104,7 +190,7 @@ static PyObject *py_binary_format_find_symbol_by_label(PyObject *self, PyObject int ret; /* Bilan de lecture des args. */ GBinFormat *format; /* Format de binaire manipulé */ GBinSymbol *symbol; /* Enventuel symbole trouvé */ - bool found; + bool found; /* Bilan de la recherche */ ret = PyArg_ParseTuple(args, "O", &label); if (!ret) return NULL; @@ -149,7 +235,7 @@ static PyObject *py_binary_format_find_symbol_at(PyObject *self, PyObject *args) int ret; /* Bilan de lecture des args. */ GBinFormat *format; /* Format de binaire manipulé */ GBinSymbol *symbol; /* Enventuel symbole trouvé */ - bool found; + bool found; /* Bilan de la recherche */ ret = PyArg_ParseTuple(args, "O", &py_vmpa); if (!ret) return NULL; @@ -197,7 +283,7 @@ static PyObject *py_binary_format_find_next_symbol_at(PyObject *self, PyObject * int ret; /* Bilan de lecture des args. */ GBinFormat *format; /* Format de binaire manipulé */ GBinSymbol *symbol; /* Enventuel symbole trouvé */ - bool found; + bool found; /* Bilan de la recherche */ ret = PyArg_ParseTuple(args, "O", &py_vmpa); if (!ret) return NULL; @@ -247,7 +333,7 @@ static PyObject *py_binary_format_resolve_symbol(PyObject *self, PyObject *args) GBinFormat *format; /* Format de binaire manipulé */ GBinSymbol *symbol; /* Enventuel symbole trouvé */ phys_t diff; /* Décallage éventuel mesuré */ - bool found; + bool found; /* Bilan de la recherche */ ret = PyArg_ParseTuple(args, "Op", &py_vmpa, &strict); if (!ret) return NULL; @@ -486,6 +572,16 @@ PyTypeObject *get_python_binary_format_type(void) { static PyMethodDef py_bin_format_methods[] = { { + "add_symbol", py_binary_format_add_symbol, + METH_VARARGS, + "add_symbol($self, symbol, /)\n--\n\nRegister a new symbol for the format." + }, + { + "remove_symbol", py_binary_format_remove_symbol, + METH_VARARGS, + "remove_symbol($self, symbol, /)\n--\n\nUnregister a symbol from the format." + }, + { "find_symbol_by_label", py_binary_format_find_symbol_by_label, METH_VARARGS, "find_symbol_by_label($self, label, /)\n--\n\nFind a symbol by its label." diff --git a/plugins/pychrysa/format/symbol.c b/plugins/pychrysa/format/symbol.c index 736a8d2..5ddaca2 100644 --- a/plugins/pychrysa/format/symbol.c +++ b/plugins/pychrysa/format/symbol.c @@ -138,7 +138,7 @@ static PyObject *py_binary_symbol_new(PyTypeObject *type, PyObject *args, PyObje if (stype >= STP_COUNT) { - PyErr_SetString(PyExc_ValueError, _("Invalid type of message")); + PyErr_SetString(PyExc_ValueError, _("Invalid type of symbol.")); return NULL; } diff --git a/src/format/format.c b/src/format/format.c index a188204..b975a7c 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -654,15 +654,18 @@ static void _g_binary_format_remove_symbol(GBinFormat *format, size_t index) void g_binary_format_remove_symbol(GBinFormat *format, GBinSymbol *symbol) { - size_t i; /* Boucle de parcours */ + bool found; /* Jeton de présence */ + size_t index; /* Indice du point de retrait */ + + g_binary_format_lock_unlock_symbols_wr(format, true); - // FIXME : dicho + found = bsearch_index(&symbol, format->symbols, format->sym_count, + sizeof(GBinSymbol *), (__compar_fn_t)g_binary_symbol_cmp, &index); - for (i = 0; i < format->sym_count; i++) - if (format->symbols[i] == symbol) - break; + if (found) + _g_binary_format_remove_symbol(format, index); - _g_binary_format_remove_symbol(format, i); + g_binary_format_lock_unlock_symbols_wr(format, false); } diff --git a/tests/format/format.py b/tests/format/format.py new file mode 100644 index 0000000..b6aad8f --- /dev/null +++ b/tests/format/format.py @@ -0,0 +1,66 @@ +#!/usr/bin/python3-dbg +# -*- coding: utf-8 -*- + + +# Tests minimalistes pour valider la gestion des erreurs relevées. + + +from chrysacase import ChrysalideTestCase +from pychrysalide.arch import vmpa, mrange +from pychrysalide.format import BinFormat +from pychrysalide.format import BinSymbol +import os +import sys + + +class SimpleFormat(BinFormat): + pass + + +class TestFormatErrors(ChrysalideTestCase): + """TestCase for format.BinFormat.""" + + + def create_fake_symbol(self, index): + saddr = vmpa(index * 0x10, vmpa.VMPA_NO_VIRTUAL) + srange = mrange(saddr, 0x3) + symbol = BinSymbol(BinSymbol.STP_ENTRY_POINT, srange) + return symbol + + + def testBasicSymbolOperations(self): + """Deal with the basic operations related to symbols in a binary format.""" + + sf = SimpleFormat() + + self.assertTrue(len(list(sf.symbols)) == 0) + + symbols = [ self.create_fake_symbol(i) for i in range(4) ] + s0, s1, s2, s3 = symbols + + for s in symbols: + sf.add_symbol(s) + + self.assertTrue(len(list(sf.symbols)) == len(symbols)) + + sf.remove_symbol(s2) + + self.assertTrue(list(sf.symbols) == [s0, s1, s3]) + + + def testBadParamsForAdding(self): + """Check if bad parameters fail for adding a new symbol.""" + + sf = SimpleFormat() + + with self.assertRaises(TypeError): + sf.add_symbol('s') + + + def testWrongRemoval(self): + """Try to remove a wrong symbol from a format.""" + + sf = SimpleFormat() + + s23 = self.create_fake_symbol(23) + sf.remove_symbol(s23) -- cgit v0.11.2-87-g4458