summaryrefslogtreecommitdiff
path: root/plugins/pychrysa
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2017-03-19 13:02:54 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2017-03-19 13:02:54 (GMT)
commit94fd405bb0c2e6dfa43324b04a336ffb611c58ce (patch)
treef3170587b4006fa358665a6bbfa301731503d3b3 /plugins/pychrysa
parent499f00977cd7f50ce0c4cf24dd59b1e920e5b180 (diff)
Provided initial features for debugging using GDB.
Diffstat (limited to 'plugins/pychrysa')
-rw-r--r--plugins/pychrysa/Makefile.am4
-rw-r--r--plugins/pychrysa/arch/vmpa.c62
-rw-r--r--plugins/pychrysa/arch/vmpa.h3
-rw-r--r--plugins/pychrysa/debug/Makefile.am4
-rw-r--r--plugins/pychrysa/debug/debugger.c1101
-rw-r--r--plugins/pychrysa/debug/debugger.h17
-rw-r--r--plugins/pychrysa/debug/gdbrsp/Makefile.am15
-rw-r--r--plugins/pychrysa/debug/gdbrsp/gdb.c165
-rw-r--r--plugins/pychrysa/debug/gdbrsp/gdb.h42
-rw-r--r--plugins/pychrysa/debug/gdbrsp/module.c86
-rw-r--r--plugins/pychrysa/debug/gdbrsp/module.h39
-rw-r--r--plugins/pychrysa/debug/module.c39
-rw-r--r--plugins/pychrysa/debug/module.h6
-rw-r--r--plugins/pychrysa/format/Makefile.am1
-rw-r--r--plugins/pychrysa/format/elf/elf.c2
-rw-r--r--plugins/pychrysa/format/symbol.c9
-rw-r--r--plugins/pychrysa/pychrysa.c2
17 files changed, 1473 insertions, 124 deletions
diff --git a/plugins/pychrysa/Makefile.am b/plugins/pychrysa/Makefile.am
index 7ab98fa..8bc5e0c 100644
--- a/plugins/pychrysa/Makefile.am
+++ b/plugins/pychrysa/Makefile.am
@@ -13,6 +13,7 @@ pychrysalide_la_LIBADD = \
arch/libpychrysaarch.la \
common/libpychrysacommon.la \
core/libpychrysacore.la \
+ debug/libpychrysadebug.la \
format/libpychrysaformat.la \
glibext/libpychrysaglibext.la \
gtkext/libpychrysagtkext.la \
@@ -29,5 +30,4 @@ AM_CPPFLAGS = $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) $(LIBGTK_CFLAGS) $(LIBX
AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
-SUBDIRS = analysis arch common core format glibext gtkext gui
-#SUBDIRS = analysis arch common core debug format glibext gtkext gui
+SUBDIRS = analysis arch common core debug format glibext gtkext gui
diff --git a/plugins/pychrysa/arch/vmpa.c b/plugins/pychrysa/arch/vmpa.c
index d747f8d..10acf35 100644
--- a/plugins/pychrysa/arch/vmpa.c
+++ b/plugins/pychrysa/arch/vmpa.c
@@ -729,6 +729,68 @@ PyObject *build_from_internal_vmpa(const vmpa2t *addr)
}
+/******************************************************************************
+* *
+* Paramètres : arg = argument quelconque à tenter de convertir. *
+* dst = destination des valeurs récupérées en cas de succès. *
+* *
+* Description : Tente de convertir en adresse n'importe quoi. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_any_to_vmpa(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+ int ret; /* Test intermédiaire */
+ vmpa2t *src; /* Modèle de données à copier */
+ PY_LONG_LONG value; /* Valeur de type générique */
+ int overflow; /* Détection d'une grosse val. */
+
+ result = 0;
+
+ /* Si l'objet est au bon format, rien à faire ! */
+
+ ret = PyObject_IsInstance(arg, (PyObject *)get_python_vmpa_type());
+
+ if (ret == 1)
+ {
+ src = get_internal_vmpa(arg);
+ copy_vmpa((vmpa2t *)dst, src);
+
+ result = 1;
+ goto catv_done;
+
+ }
+
+ /* Sinon on demande à Python... */
+
+ value = PyLong_AsLongLongAndOverflow(arg, &overflow);
+
+ if (value == -1 && (overflow == 1 || PyErr_Occurred()))
+ PyErr_Clear();
+
+ else
+ {
+ init_vmpa((vmpa2t *)dst, VMPA_NO_PHYSICAL, value);
+
+ result = 1;
+ goto catv_done;
+
+ }
+
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to vmpa");
+
+ catv_done:
+
+ return result;
+
+}
+
+
/* ---------------------------------------------------------------------------------- */
/* DEFINITION D'UNE ZONE EN MEMOIRE */
diff --git a/plugins/pychrysa/arch/vmpa.h b/plugins/pychrysa/arch/vmpa.h
index 793f24a..46828f5 100644
--- a/plugins/pychrysa/arch/vmpa.h
+++ b/plugins/pychrysa/arch/vmpa.h
@@ -46,6 +46,9 @@ vmpa2t *get_internal_vmpa(PyObject *);
/* Convertit une structure de type 'vmpa2t' en objet Python. */
PyObject *build_from_internal_vmpa(const vmpa2t *);
+/* Tente de convertir en adresse n'importe quoi. */
+int convert_any_to_vmpa(PyObject *, void *);
+
/* ------------------------ DEFINITION D'UNE ZONE EN MEMOIRE ------------------------ */
diff --git a/plugins/pychrysa/debug/Makefile.am b/plugins/pychrysa/debug/Makefile.am
index 503d228..8011c49 100644
--- a/plugins/pychrysa/debug/Makefile.am
+++ b/plugins/pychrysa/debug/Makefile.am
@@ -5,6 +5,8 @@ libpychrysadebug_la_SOURCES = \
debugger.h debugger.c \
module.h module.c
+libpychrysadebug_la_LIBADD = \
+ gdbrsp/libpychrysadebuggdbrsp.la
libpychrysadebug_la_LDFLAGS =
@@ -13,3 +15,5 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJE
-I../../../src
AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+SUBDIRS = gdbrsp
diff --git a/plugins/pychrysa/debug/debugger.c b/plugins/pychrysa/debug/debugger.c
index fb55f65..6f930a4 100644
--- a/plugins/pychrysa/debug/debugger.c
+++ b/plugins/pychrysa/debug/debugger.c
@@ -25,138 +25,499 @@
#include "debugger.h"
-#if 0
+#include <assert.h>
#include <malloc.h>
#include <pygobject.h>
-#include "../quirks.h"
+#include <debug/debugger.h>
+#include "../helpers.h"
+#include "../arch/vmpa.h"
-/* Crée un nouvel objet Python de type 'BinaryDebugger'. */
-static PyObject *py_binary_debugger_new(PyTypeObject *, PyObject *, PyObject *);
-/* Fournit les identifiants de tous les threads actifs. */
+
+
+
+/* Fournit les identifiants de tous les threads actifs. */
static PyObject *py_binary_debugger_list_all_threads(PyObject *, PyObject *);
-/* Fournit la pile d'exécution courante via un débogueur. */
-static PyObject *py_binary_debugger_get_frames_stack(PyObject *, PyObject *);
+
+
+/* Lit une valeur de 8 bits à une adresse arbitraire. */
+static PyObject *py_binary_debugger_read_memory_u8(PyObject *, PyObject *);
+
+/* Lit une valeur de 16 bits à une adresse arbitraire. */
+static PyObject *py_binary_debugger_read_memory_u16(PyObject *, PyObject *);
+
+/* Lit une valeur de 32 bits à une adresse arbitraire. */
+static PyObject *py_binary_debugger_read_memory_u32(PyObject *, PyObject *);
+
+/* Lit une valeur de 64 bits à une adresse arbitraire. */
+static PyObject *py_binary_debugger_read_memory_u64(PyObject *, PyObject *);
+
+/* Liste l'ensemble des registres appartenant à un groupe. */
+static PyObject *py_binary_debugger_get_register_names(PyObject *, PyObject *);
+
+/* Indique la taille associée à un registre donné. */
+static PyObject *py_binary_debugger_get_register_size(PyObject *, PyObject *);
+
+/* Lit une valeur de 8 bits à partir d'un registre. */
+static PyObject *py_binary_debugger_read_register_u8(PyObject *, PyObject *);
+
+/* Lit une valeur de 16 bits à partir d'un registre. */
+static PyObject *py_binary_debugger_read_register_u16(PyObject *, PyObject *);
+
+/* Lit une valeur de 32 bits à partir d'un registre. */
+static PyObject *py_binary_debugger_read_register_u32(PyObject *, PyObject *);
+
+/* Lit une valeur de 64 bits à partir d'un registre. */
+static PyObject *py_binary_debugger_read_register_u64(PyObject *, PyObject *);
+
+/* Ecrit une valeur de 8 bits dans un registre. */
+static PyObject *py_binary_debugger_write_register_u8(PyObject *, PyObject *);
+
+/* Ecrit une valeur de 16 bits dans un registre. */
+static PyObject *py_binary_debugger_write_register_u16(PyObject *, PyObject *);
+
+/* Ecrit une valeur de 32 bits dans un registre. */
+static PyObject *py_binary_debugger_write_register_u32(PyObject *, PyObject *);
+
+/* Ecrit une valeur de 64 bits dans un registre. */
+static PyObject *py_binary_debugger_write_register_u64(PyObject *, PyObject *);
+
+
+
+/* Remonte la pile d'appels jusqu'au point courant. */
+static PyObject *py_binary_debugger_get_call_stack(PyObject *, PyObject *);
+
+
+
+/* Ajoute un point d'arrêt basique en mémoire. */
+static PyObject *py_binary_debugger_add_mem_bp(PyObject *, PyObject *);
+
+/* Retire un point d'arrêt basique en mémoire. */
+static PyObject *py_binary_debugger_delete_mem_bp(PyObject *, PyObject *);
+
+
+
+/* Redémarre le processus de débogage. */
+static PyObject *py_binary_debugger_restart(PyObject *, PyObject *);
+
+/* Remet en marche le débogueur courant. */
+static PyObject *py_binary_debugger_resume(PyObject *, PyObject *);
+
+/* Relance l'exécution pour une seule instruction. */
+static PyObject *py_binary_debugger_stepi(PyObject *, PyObject *);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments non utilisés ici. *
+* *
+* Description : Fournit les identifiants de tous les threads actifs. *
+* *
+* Retour : Liste contenant identifiants et désignations de threads. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_list_all_threads(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ size_t count; /* Quantité de threads actifs */
+ dbg_thread_desc *threads; /* Liste des threads actifs */
+ size_t i; /* Boucle de parcours */
+ PyObject *thread; /* Détails sur un thread donné */
+
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ threads = g_binary_debugger_list_all_threads(debugger, &count);
+
+ result = PyTuple_New(count);
+
+ for (i = 0; i < count; i++)
+ {
+ thread = PyTuple_New(2);
+ PyTuple_SetItem(result, i, thread);
+
+ PyTuple_SetItem(thread, 0, PyLong_FromLong(threads[i].id));
+ PyTuple_SetItem(thread, 1, PyUnicode_FromString(threads[i].name));
+
+ }
+
+ delete_dbg_thread_desc(threads, count);
+
+ return result;
+
+}
+
+
+
/******************************************************************************
* *
-* Paramètres : type = type de l'objet à instancier. *
-* args = arguments fournis à l'appel. *
-* kwds = arguments de type key=val fournis. *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments accompagnant l'appel. *
* *
-* Description : Crée un nouvel objet Python de type 'BinaryDebugger'. *
+* Description : Lit une valeur de 8 bits à une adresse arbitraire. *
* *
-* Retour : Instance Python mise en place. *
+* Retour : Valeur lue ou None. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_binary_debugger_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+static PyObject *py_binary_debugger_read_memory_u8(PyObject *self, PyObject *args)
{
PyObject *result; /* Instance à retourner */
- DebuggerType dtype; /* Type de débogueur à créer */
+ GBinaryDebugger *debugger; /* Version GLib du format */
int ret; /* Bilan de lecture des args. */
+ vmpa2t addr; /* Position interne associée */
+ uint8_t value; /* Valeur lue en mémoire */
+ bool status; /* Bilan de l'opération */
+
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
+ if (!ret) return NULL;
+
+ status = g_binary_debugger_read_memory_u8(debugger, get_virt_addr(&addr), &value);
+
+ if (status)
+ result = PyLong_FromUnsignedLongLong(value);
+
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments accompagnant l'appel. *
+* *
+* Description : Lit une valeur de 16 bits à une adresse arbitraire. *
+* *
+* Retour : Valeur lue ou None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_read_memory_u16(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
GBinaryDebugger *debugger; /* Version GLib du format */
+ int ret; /* Bilan de lecture des args. */
+ vmpa2t addr; /* Position interne associée */
+ uint16_t value; /* Valeur lue en mémoire */
+ bool status; /* Bilan de l'opération */
- ret = PyArg_ParseTuple(args, "l", &dtype);
- if (!ret) Py_RETURN_NONE;
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
+ if (!ret) return NULL;
- debugger = g_new_binary_debugger(dtype, NULL/* FIXME */);
+ status = g_binary_debugger_read_memory_u16(debugger, get_virt_addr(&addr), &value);
- result = py_binary_debugger_from_c(debugger);
- g_object_unref(debugger);
+ if (status)
+ result = PyLong_FromUnsignedLongLong(value);
+
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
- return (PyObject *)result;
+ return result;
}
/******************************************************************************
* *
-* Paramètres : debugger = instance existante GLib. *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments accompagnant l'appel. *
* *
-* Description : Crée un nouvel objet Python de type 'BinaryDebugger'. *
+* Description : Lit une valeur de 32 bits à une adresse arbitraire. *
* *
-* Retour : Instance Python mise en place. *
+* Retour : Valeur lue ou None. *
* *
* Remarques : - *
* *
******************************************************************************/
-PyObject *py_binary_debugger_from_c(GBinaryDebugger *debugger)
+static PyObject *py_binary_debugger_read_memory_u32(PyObject *self, PyObject *args)
{
- PyObject *module; /* Module d'appartenance */
- PyTypeObject *type; /* Type Python correspondant */
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ int ret; /* Bilan de lecture des args. */
+ vmpa2t addr; /* Position interne associée */
+ uint32_t value; /* Valeur lue en mémoire */
+ bool status; /* Bilan de l'opération */
- module = PyImport_ImportModule("pychrysalide.debug");
- type = (PyTypeObject*)PyObject_GetAttrString(module, "BinaryDebugger");
- Py_DECREF(module);
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
+ if (!ret) return NULL;
+
+ status = g_binary_debugger_read_memory_u32(debugger, get_virt_addr(&addr), &value);
- pychrysalide_set_instance_data(G_OBJECT(debugger), type);
+ if (status)
+ result = PyLong_FromUnsignedLongLong(value);
- return pygobject_new(G_OBJECT(debugger));
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ return result;
}
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments accompagnant l'appel. *
+* *
+* Description : Lit une valeur de 64 bits à une adresse arbitraire. *
+* *
+* Retour : Valeur lue ou None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_read_memory_u64(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ int ret; /* Bilan de lecture des args. */
+ vmpa2t addr; /* Position interne associée */
+ uint64_t value; /* Valeur lue en mémoire */
+ bool status; /* Bilan de l'opération */
+
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
+ if (!ret) return NULL;
+ status = g_binary_debugger_read_memory_u64(debugger, get_virt_addr(&addr), &value);
+
+ if (status)
+ result = PyLong_FromUnsignedLongLong(value);
+
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ return result;
+
+}
/******************************************************************************
* *
-* Paramètres : self = classe représentant un débogueur. *
-* args = arguments fournis à l'appel. *
+* Paramètres : self = instance de débogueur à consulter. *
+* args = arguments accompagnant l'appel. *
* *
-* Description : Fournit les identifiants de tous les threads actifs. *
+* Description : Liste l'ensemble des registres appartenant à un groupe. *
* *
-* Retour : Object Python représentant le résultat de l'opération. *
+* Retour : Liste de noms à libérer de la mémoire après utilisation. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_binary_debugger_list_all_threads(PyObject *self, PyObject *args)
+static PyObject *py_binary_debugger_get_register_names(PyObject *self, PyObject *args)
{
- PyObject *result; /* Trouvailles à retourner */
- GBinaryDebugger *debugger; /* Version native */
- char **names; /* Noms associés aux threads */
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ const char *group; /* Nom du registre à manipuler */
+ int ret; /* Bilan de lecture des args. */
+ char **list; /* Liste de noms de registre */
size_t count; /* Taille de cette liste */
- pid_t *threads; /* Liste des threads actifs */
size_t i; /* Boucle de parcours */
- PyObject *thread; /* Détails sur un thread donné */
debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ ret = PyArg_ParseTuple(args, "|s", &group);
+ if (!ret) return NULL;
- threads = g_binary_debugger_list_all_threads(debugger, &names, &count);
+ list = g_binary_debugger_get_register_names(debugger, group, &count);
result = PyTuple_New(count);
for (i = 0; i < count; i++)
{
- thread = PyTuple_New(2);
- PyTuple_SetItem(result, i, thread);
+ PyTuple_SetItem(result, i, PyUnicode_FromString(list[i]));
+ free(list[i]);
+ }
+
+ if (list != NULL)
+ free(list);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = instance de débogueur à consulter. *
+* args = arguments accompagnant l'appel. *
+* *
+* Description : Indique la taille associée à un registre donné. *
+* *
+* Retour : Taille en bits, ou 0 si le registre n'a pas été trouvé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_get_register_size(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ char *reg; /* Nom du registre à manipuler */
+ int ret; /* Bilan de lecture des args. */
+ unsigned int size; /* Taille associée au registre */
+
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ ret = PyArg_ParseTuple(args, "s", &reg);
+ if (!ret) return NULL;
+
+ size = g_binary_debugger_get_register_size(debugger, reg);
+
+ result = PyLong_FromUnsignedLong(size);
+
+ return result;
+
+}
+
- PyTuple_SetItem(thread, 0, PyLong_FromLong(threads[i]));
- PyTuple_SetItem(thread, 1, PyString_FromString(names[i]));
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments accompagnant l'appel. *
+* *
+* Description : Lit une valeur de 8 bits à partir d'un registre. *
+* *
+* Retour : Valeur lue ou None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- free(names[i]);
+static PyObject *py_binary_debugger_read_register_u8(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ char *reg; /* Nom du registre à manipuler */
+ int ret; /* Bilan de lecture des args. */
+ uint8_t value; /* Valeur lue en mémoire */
+ bool status; /* Bilan de l'opération */
+
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ ret = PyArg_ParseTuple(args, "s", &reg);
+ if (!ret) return NULL;
+ status = g_binary_debugger_read_register_u8(debugger, reg, &value);
+
+ if (status)
+ result = PyLong_FromUnsignedLongLong(value);
+
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
}
- if (names != NULL)
- free(names);
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments accompagnant l'appel. *
+* *
+* Description : Lit une valeur de 16 bits à partir d'un registre. *
+* *
+* Retour : Valeur lue ou None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_read_register_u16(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ char *reg; /* Nom du registre à manipuler */
+ int ret; /* Bilan de lecture des args. */
+ uint16_t value; /* Valeur lue en mémoire */
+ bool status; /* Bilan de l'opération */
+
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
- if (threads != NULL)
- free(threads);
+ ret = PyArg_ParseTuple(args, "s", &reg);
+ if (!ret) return NULL;
+
+ status = g_binary_debugger_read_register_u16(debugger, reg, &value);
+
+ if (status)
+ result = PyLong_FromUnsignedLongLong(value);
+
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
return result;
@@ -165,47 +526,374 @@ static PyObject *py_binary_debugger_list_all_threads(PyObject *self, PyObject *a
/******************************************************************************
* *
-* Paramètres : self = classe représentant un débogueur. *
-* args = arguments fournis à l'appel. *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments accompagnant l'appel. *
* *
-* Description : Fournit la pile d'exécution courante via un débogueur. *
+* Description : Lit une valeur de 32 bits à partir d'un registre. *
* *
-* Retour : Object Python représentant le résultat de l'opération. *
+* Retour : Valeur lue ou None. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_binary_debugger_get_frames_stack(PyObject *self, PyObject *args)
+static PyObject *py_binary_debugger_read_register_u32(PyObject *self, PyObject *args)
{
- PyObject *result; /* Trouvailles à retourner */
- GBinaryDebugger *debugger; /* Version native */
- unsigned long thread; /* Identifiant du thread visé */
- size_t count; /* Taille de cette liste */
- dbg_frame_t *frames; /* Frames courantes trouvées */
- size_t i; /* Boucle de parcours */
- PyObject *frame; /* Détails sur une frame */
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ char *reg; /* Nom du registre à manipuler */
+ int ret; /* Bilan de lecture des args. */
+ uint32_t value; /* Valeur lue en mémoire */
+ bool status; /* Bilan de l'opération */
debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
- if (!PyArg_ParseTuple(args, "k", &thread))
- Py_RETURN_NONE;
+ ret = PyArg_ParseTuple(args, "s", &reg);
+ if (!ret) return NULL;
- frames = g_binary_debugger_get_frames_stack(debugger, thread, &count);
+ status = g_binary_debugger_read_register_u32(debugger, reg, &value);
- result = PyTuple_New(count);
+ if (status)
+ result = PyLong_FromUnsignedLongLong(value);
- for (i = 0; i < count; i++)
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments accompagnant l'appel. *
+* *
+* Description : Lit une valeur de 64 bits à partir d'un registre. *
+* *
+* Retour : Valeur lue ou None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_read_register_u64(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ char *reg; /* Nom du registre à manipuler */
+ int ret; /* Bilan de lecture des args. */
+ uint64_t value; /* Valeur lue en mémoire */
+ bool status; /* Bilan de l'opération */
+
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ ret = PyArg_ParseTuple(args, "s", &reg);
+ if (!ret) return NULL;
+
+ status = g_binary_debugger_read_register_u64(debugger, reg, &value);
+
+ if (status)
+ result = PyLong_FromUnsignedLongLong(value);
+
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments accompagnant l'appel. *
+* *
+* Description : Ecrit une valeur de 8 bits dans un registre. *
+* *
+* Retour : Valeur lue ou None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_write_register_u8(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ char *reg; /* Nom du registre à manipuler */
+ int ret; /* Bilan de lecture des args. */
+ uint8_t value; /* Valeur lue en mémoire */
+ bool status; /* Bilan de l'opération */
+
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ ret = PyArg_ParseTuple(args, "sB", &reg, &value);
+ if (!ret) return NULL;
+
+ status = g_binary_debugger_write_register_u8(debugger, reg, &value);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments accompagnant l'appel. *
+* *
+* Description : Ecrit une valeur de 16 bits dans un registre. *
+* *
+* Retour : Valeur lue ou None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_write_register_u16(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ char *reg; /* Nom du registre à manipuler */
+ int ret; /* Bilan de lecture des args. */
+ uint16_t value; /* Valeur lue en mémoire */
+ bool status; /* Bilan de l'opération */
+
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ ret = PyArg_ParseTuple(args, "sH", &reg, &value);
+ if (!ret) return NULL;
+
+ status = g_binary_debugger_write_register_u16(debugger, reg, &value);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments accompagnant l'appel. *
+* *
+* Description : Ecrit une valeur de 32 bits dans un registre. *
+* *
+* Retour : Valeur lue ou None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_write_register_u32(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ char *reg; /* Nom du registre à manipuler */
+ int ret; /* Bilan de lecture des args. */
+ uint32_t value; /* Valeur lue en mémoire */
+ bool status; /* Bilan de l'opération */
+
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ ret = PyArg_ParseTuple(args, "sI", &reg, &value);
+ if (!ret) return NULL;
+
+ status = g_binary_debugger_write_register_u32(debugger, reg, &value);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments accompagnant l'appel. *
+* *
+* Description : Ecrit une valeur de 64 bits dans un registre. *
+* *
+* Retour : Valeur lue ou None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_write_register_u64(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ char *reg; /* Nom du registre à manipuler */
+ int ret; /* Bilan de lecture des args. */
+ uint64_t value; /* Valeur lue en mémoire */
+ bool status; /* Bilan de l'opération */
+
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ ret = PyArg_ParseTuple(args, "sK", &reg, &value);
+ if (!ret) return NULL;
+
+ status = g_binary_debugger_write_register_u64(debugger, reg, &value);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments accompagnant l'appel. *
+* *
+* Description : Remonte la pile d'appels jusqu'au point courant. *
+* *
+* Retour : Pile d'appels sous forme de liste ou None en cas d'erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_get_call_stack(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ virt_t *callstack; /* Pile d'appels obtenue */
+ size_t size; /* Hauteur de cette pile */
+ bool status; /* Bilan de l'opération */
+ size_t i; /* Boucle de parcours */
+
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ status = g_binary_debugger_get_call_stack(debugger, &callstack, &size);
+
+ if (!status)
{
- frame = PyTuple_New(1);
- PyTuple_SetItem(result, i, frame);
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ else
+ {
+ result = PyTuple_New(size);
+
+ for (i = 0; i < size; i++)
+ PyTuple_SetItem(result, i, PyLong_FromUnsignedLongLong(callstack[i]));
- PyTuple_SetItem(frame, 0, PyLong_FromUnsignedLongLong(frames[i].addr));
+ if (callstack != NULL)
+ free(callstack);
}
- if (frames != NULL)
- free(frames);
+ return result;
+
+}
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments accompagnant l'appel. *
+* *
+* Description : Ajoute un point d'arrêt basique en mémoire. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_add_mem_bp(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ vmpa2t addr; /* Position interne associée */
+ int ret; /* Bilan de lecture des args. */
+ bool status; /* Bilan de l'opération */
+
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
+ if (!ret) return NULL;
+
+ status = g_binary_debugger_add_memory_breakpoint(debugger, get_virt_addr(&addr));
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments accompagnant l'appel. *
+* *
+* Description : Retire un point d'arrêt basique en mémoire. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_delete_mem_bp(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ vmpa2t addr; /* Position interne associée */
+ int ret; /* Bilan de lecture des args. */
+ bool status; /* Bilan de l'opération */
+
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
+ if (!ret) return NULL;
+
+ status = g_binary_debugger_delete_memory_breakpoint(debugger, get_virt_addr(&addr));
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
return result;
@@ -215,66 +903,283 @@ static PyObject *py_binary_debugger_get_frames_stack(PyObject *self, PyObject *a
+
+
+
/******************************************************************************
* *
-* Paramètres : module = module dont la définition est à compléter. *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments non utilisés ici. *
* *
-* Description : Ajoute l'objet 'pychrysalide.debug.BinaryDebugger' au module.*
+* Description : Redémarre le processus de débogage. *
* *
-* Retour : - *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool register_python_binary_debugger(PyObject *module)
+static PyObject *py_binary_debugger_restart(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ bool status; /* Bilan de l'opération */
+
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ status = g_binary_debugger_restart(debugger);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments non utilisés ici. *
+* *
+* Description : Remet en marche le débogueur courant. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_resume(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ bool status; /* Bilan de l'opération */
+
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ status = g_binary_debugger_resume(debugger);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = contenu binaire à manipuler. *
+* args = arguments non utilisés ici. *
+* *
+* Description : Relance l'exécution pour une seule instruction. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_stepi(PyObject *self, PyObject *args)
{
- PyObject *pygobj_mod; /* Module Python-GObject */
- int ret; /* Bilan d'un appel */
+ PyObject *result; /* Instance à retourner */
+ GBinaryDebugger *debugger; /* Version GLib du format */
+ bool status; /* Bilan de l'opération */
+
+ debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+ assert(debugger != NULL);
+
+ status = g_binary_debugger_stepi(debugger, false);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit un accès à une définition de type à diffuser. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyTypeObject *get_python_binary_debugger_type(void)
+{
static PyMethodDef py_binary_debugger_methods[] = {
{
- "list_all_threads", (PyCFunction)py_binary_debugger_list_all_threads,
+ "list_all_threads", py_binary_debugger_list_all_threads,
METH_NOARGS,
- "List all current active threads."
+ "list_all_threads($self, /)\n--\n\nList all current active threads."
+ },
+ {
+ "read_mem_u8", py_binary_debugger_read_memory_u8,
+ METH_VARARGS,
+ "read_mem_u8($self, addr, /)\n--\n\nRead a 8-bit value from a given address."
},
{
- "get_frames_stack", (PyCFunction)py_binary_debugger_get_frames_stack,
+ "read_mem_u16", py_binary_debugger_read_memory_u16,
METH_VARARGS,
- "Provide the current callstack using a debugger."
+ "read_mem_u16($self, addr, /)\n--\n\nRead a 16-bit value from a given address."
},
+ {
+ "read_mem_u32", py_binary_debugger_read_memory_u32,
+ METH_VARARGS,
+ "read_mem_u32($self, addr, /)\n--\n\nRead a 32-bit value from a given address."
+ },
+ {
+ "read_mem_u64", py_binary_debugger_read_memory_u64,
+ METH_VARARGS,
+ "read_mem_u64($self, addr, /)\n--\n\nRead a 64-bit value from a given address."
+ },
+ {
+ "get_reg_names", py_binary_debugger_get_register_names,
+ METH_VARARGS,
+ "get_reg_names($self, [grp]/)\n--\n\nGet the names of all registers belonging to an optional group."
+ },
+ {
+ "get_reg_size", py_binary_debugger_get_register_size,
+ METH_VARARGS,
+ "get_reg_size($self, name, /)\n--\n\nGet the size of a given register."
+ },
+ {
+ "read_reg_u8", py_binary_debugger_read_register_u8,
+ METH_VARARGS,
+ "read_reg_u8($self, reg, /)\n--\n\nRead a 8-bit value from a named register."
+ },
+ {
+ "read_reg_u16", py_binary_debugger_read_register_u16,
+ METH_VARARGS,
+ "read_reg_u16($self, reg, /)\n--\n\nRead a 16-bit value from a named register."
+ },
+ {
+ "read_reg_u32", py_binary_debugger_read_register_u32,
+ METH_VARARGS,
+ "read_reg_u32($self, reg, /)\n--\n\nRead a 32-bit value from a named register."
+ },
+ {
+ "read_reg_u64", py_binary_debugger_read_register_u64,
+ METH_VARARGS,
+ "read_reg_u64($self, reg, /)\n--\n\nRead a 64-bit value from a named register."
+ },
+ {
+ "write_reg_u8", py_binary_debugger_write_register_u8,
+ METH_VARARGS,
+ "write_reg_u8($self, reg, val, /)\n--\n\nWrite a 8-bit value into a named register."
+ },
+ {
+ "write_reg_u16", py_binary_debugger_write_register_u16,
+ METH_VARARGS,
+ "write_reg_u16($self, reg, val, /)\n--\n\nWrite a 16-bit value into a named register."
+ },
+ {
+ "write_reg_u32", py_binary_debugger_write_register_u32,
+ METH_VARARGS,
+ "write_reg_u32($self, reg, val, /)\n--\n\nWrite a 32-bit value into a named register."
+ },
+ {
+ "write_reg_u64", py_binary_debugger_write_register_u64,
+ METH_VARARGS,
+ "write_reg_u64($self, reg, val, /)\n--\n\nWrite a 64-bit value into a named register."
+ },
+ {
+ "get_call_stack", py_binary_debugger_get_call_stack,
+ METH_NOARGS,
+ "get_call_stack($self, /)\n--\n\nGet the current call stack."
+ },
+ {
+ "add_mem_bp", py_binary_debugger_add_mem_bp,
+ METH_VARARGS,
+ "add_mem_bp($self, addr, /)\n--\n\nInsert a memory breakpoint at a given address."
+ },
+ {
+ "delete_mem_bp", py_binary_debugger_delete_mem_bp,
+ METH_VARARGS,
+ "delete_mem_bp($self, addr, /)\n--\n\nRemove a memory breakpoint at a given address."
+ },
+ {
+ "restart", py_binary_debugger_restart,
+ METH_NOARGS,
+ "restart($self, /)\n--\n\nRestart the current debugging session."
+ },
+ {
+ "resume", py_binary_debugger_resume,
+ METH_NOARGS,
+ "resume($self, /)\n--\n\nResume the current debugging session."
+ },
+ {
+ "stepi", py_binary_debugger_stepi,
+ METH_NOARGS,
+ "stepi($self, /)\n--\n\nExecute one machine instruction, then stop and return to the debugger."
+ },
+ { NULL }
+ };
+
+ static PyGetSetDef py_binary_debugger_getseters[] = {
{ NULL }
};
static PyTypeObject py_binary_debugger_type = {
- PyObject_HEAD_INIT(NULL)
+ PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.debug.BinaryDebugger",
- .tp_basicsize = sizeof(PyGObject),
+ .tp_name = "pychrysalide.analysis.BinaryDebugger",
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "PyChrysalide binary debugger",
+ .tp_doc = "PyChrysalide loaded binary",
.tp_methods = py_binary_debugger_methods,
- .tp_new = (newfunc)py_binary_debugger_new
+ .tp_getset = py_binary_debugger_getseters
};
- pygobj_mod = PyImport_ImportModule("gobject");
- if (pygobj_mod == NULL) return false;
+ return &py_binary_debugger_type;
- py_binary_debugger_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "GObject");
- Py_DECREF(pygobj_mod);
+}
- if (PyType_Ready(&py_binary_debugger_type) < 0)
- return false;
- Py_INCREF(&py_binary_debugger_type);
- ret = PyModule_AddObject(module, "BinaryDebugger", (PyObject *)&py_binary_debugger_type);
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.....BinaryDebugger'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_python_binary_debugger(PyObject *module)
+{
+ PyTypeObject *py_binary_debugger_type; /* Type Python 'BinaryDebugger'*/
+ PyObject *dict; /* Dictionnaire du module */
+
+ py_binary_debugger_type = get_python_binary_debugger_type();
+
+ dict = PyModule_GetDict(module);
+
+ if (!register_class_for_pygobject(dict, G_TYPE_BINARY_DEBUGGER, py_binary_debugger_type, &PyGObject_Type))
+ return false;
- return (ret == 0);
+ return true;
}
-#endif
diff --git a/plugins/pychrysa/debug/debugger.h b/plugins/pychrysa/debug/debugger.h
index f2e4e46..97f91ac 100644
--- a/plugins/pychrysa/debug/debugger.h
+++ b/plugins/pychrysa/debug/debugger.h
@@ -22,24 +22,21 @@
*/
-#ifndef _PLUGINS_PYOIDA_DEBUG_DEBUGGER_H
-#define _PLUGINS_PYOIDA_DEBUG_DEBUGGER_H
+#ifndef _PLUGINS_PYCHRYSALIDE_DEBUG_DEBUGGER_H
+#define _PLUGINS_PYCHRYSALIDE_DEBUG_DEBUGGER_H
#include <Python.h>
#include <stdbool.h>
-#if 0
-#include <debug/debugger.h>
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_binary_debugger_type(void);
-/* Crée un nouvel objet Python de type 'BinaryDebugger'. */
-PyObject *py_binary_debugger_from_c(GBinaryDebugger *debugger);
-
-/* Ajoute l'objet 'pychrysalide.debug.BinaryDebugger' au module. */
+/* Prend en charge l'objet 'pychrysalide.debug.BinaryDebugger'. */
bool register_python_binary_debugger(PyObject *);
-#endif
-#endif /* _PLUGINS_PYOIDA_DEBUG_DEBUGGER_H */
+
+#endif /* _PLUGINS_PYCHRYSALIDE_DEBUG_DEBUGGER_H */
diff --git a/plugins/pychrysa/debug/gdbrsp/Makefile.am b/plugins/pychrysa/debug/gdbrsp/Makefile.am
new file mode 100644
index 0000000..cf7b78a
--- /dev/null
+++ b/plugins/pychrysa/debug/gdbrsp/Makefile.am
@@ -0,0 +1,15 @@
+
+noinst_LTLIBRARIES = libpychrysadebuggdbrsp.la
+
+libpychrysadebuggdbrsp_la_SOURCES = \
+ gdb.h gdb.c \
+ module.h module.c
+
+
+libpychrysadebuggdbrsp_la_LDFLAGS =
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+ -I../../../../src
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
diff --git a/plugins/pychrysa/debug/gdbrsp/gdb.c b/plugins/pychrysa/debug/gdbrsp/gdb.c
new file mode 100644
index 0000000..cbbf66b
--- /dev/null
+++ b/plugins/pychrysa/debug/gdbrsp/gdb.c
@@ -0,0 +1,165 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gdb.c - équivalent Python du fichier "debug/gdbrsp/gdb.c"
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "gdb.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+
+
+#include <debug/gdbrsp/gdb.h>
+
+
+#include "../debugger.h"
+#include "../../helpers.h"
+#include "../../analysis/binary.h"
+
+
+/* Crée un nouvel objet Python de type 'GdbDebugger'. */
+static PyObject *py_gdb_debugger_new(PyTypeObject *, PyObject *, PyObject *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type de l'objet à instancier. *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
+* *
+* Description : Crée un nouvel objet Python de type 'GdbDebugger'. *
+* *
+* Retour : Instance Python mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_gdb_debugger_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *result; /* Instance à retourner */
+ PyObject *binary_obj; /* Objet pour le binaire lié */
+ const char *server; /* Nom du serveur à contacter */
+ unsigned short port; /* Port de connexion */
+ int ret; /* Bilan de lecture des args. */
+ GLoadedBinary *binary; /* Binaire chargé en mémoire */
+ GBinaryDebugger *debugger; /* Création GLib à transmettre */
+
+ ret = PyArg_ParseTuple(args, "OsH", &binary_obj, &server, &port);
+ if (!ret) return NULL;
+
+ ret = PyObject_IsInstance(binary_obj, (PyObject *)get_python_loaded_binary_type());
+ if (!ret)
+ {
+ PyErr_SetString(PyExc_TypeError, _("The first argument must be an instance of LoadedBinary."));
+ return NULL;
+ }
+
+ binary = G_LOADED_BINARY(pygobject_get(binary_obj));
+
+ debugger = g_gdb_debugger_new(binary, server, port);
+
+ result = pygobject_new(G_OBJECT(debugger));
+
+ g_object_unref(debugger);
+
+ return (PyObject *)result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit un accès à une définition de type à diffuser. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyTypeObject *get_python_gdb_debugger_type(void)
+{
+ static PyMethodDef py_gdb_debugger_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_gdb_debugger_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_gdb_debugger_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.debug.gdbrsp.GdbDebugger",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+
+ .tp_doc = "PyChrysalide GDB debugger",
+
+ .tp_methods = py_gdb_debugger_methods,
+ .tp_getset = py_gdb_debugger_getseters,
+ .tp_new = (newfunc)py_gdb_debugger_new
+
+ };
+
+ return &py_gdb_debugger_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide....gdbrsp.GdbDebugger'.*
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_python_gdb_debugger(PyObject *module)
+{
+ PyTypeObject *py_gdb_debugger_type; /* Type Python 'GdbDebugger' */
+ PyObject *dict; /* Dictionnaire du module */
+
+ py_gdb_debugger_type = get_python_gdb_debugger_type();
+
+ dict = PyModule_GetDict(module);
+
+ if (!register_class_for_pygobject(dict, G_TYPE_GDB_DEBUGGER,
+ py_gdb_debugger_type, get_python_binary_debugger_type()))
+ return false;
+
+ return true;
+
+}
diff --git a/plugins/pychrysa/debug/gdbrsp/gdb.h b/plugins/pychrysa/debug/gdbrsp/gdb.h
new file mode 100644
index 0000000..c3d1330
--- /dev/null
+++ b/plugins/pychrysa/debug/gdbrsp/gdb.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gdb.h - prototypes pour l'équivalent Python du fichier "debug/gdbrsp/gdb.h"
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSA_DEBUG_GDBRSP_DEBUGGER_H
+#define _PLUGINS_PYCHRYSA_DEBUG_GDBRSP_DEBUGGER_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_gdb_debugger_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.debug.gdbrsp.GdbDebugger'. */
+bool register_python_gdb_debugger(PyObject *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSA_DEBUG_GDBRSP_DEBUGGER_H */
diff --git a/plugins/pychrysa/debug/gdbrsp/module.c b/plugins/pychrysa/debug/gdbrsp/module.c
new file mode 100644
index 0000000..6e7896c
--- /dev/null
+++ b/plugins/pychrysa/debug/gdbrsp/module.c
@@ -0,0 +1,86 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire gdbrsp en tant que module
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "module.h"
+
+
+#include "gdb.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Ajoute le module 'debug.gdbrsp' au module Python. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool add_debug_gdbrsp_module_to_python_module(PyObject *super)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *module; /* Sous-module mis en place */
+ int ret; /* Bilan d'un appel */
+
+ static PyModuleDef py_chrysalide_gdbrsp_module = {
+
+ .m_base = PyModuleDef_HEAD_INIT,
+
+ .m_name = "pychrysalide.debug.gdbrsp",
+ .m_doc = "Python module for Chrysalide.debug.gdbrsp",
+
+ .m_size = -1,
+
+ };
+
+ result = false;
+
+ module = PyModule_Create(&py_chrysalide_gdbrsp_module);
+ if (module == NULL) return false;
+
+ ret = PyState_AddModule(super, &py_chrysalide_gdbrsp_module);
+ if (ret != 0) goto loading_failed;
+
+ ret = _PyImport_FixupBuiltin(module, "pychrysalide.debug.gdbrsp");
+ if (ret != 0) goto loading_failed;
+
+ Py_INCREF(module);
+ ret = PyModule_AddObject(super, "gdbrsp", module);
+ if (ret != 0) goto loading_failed;
+
+ result = true;
+
+ result &= register_python_gdb_debugger(module);
+
+ loading_failed:
+
+ assert(result);
+
+ return result;
+
+}
diff --git a/plugins/pychrysa/debug/gdbrsp/module.h b/plugins/pychrysa/debug/gdbrsp/module.h
new file mode 100644
index 0000000..78e62b0
--- /dev/null
+++ b/plugins/pychrysa/debug/gdbrsp/module.h
@@ -0,0 +1,39 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire gdbrsp en tant que module
+ *
+ * Copyright (C) 2012-2016 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSA_DEBUG_GDBRSP_MODULE_H
+#define _PLUGINS_PYCHRYSA_DEBUG_GDBRSP_MODULE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'debug.gdbrsp' au module Python. */
+bool add_debug_gdbrsp_module_to_python_module(PyObject *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSA_DEBUG_GDBRSP_MODULE_H */
diff --git a/plugins/pychrysa/debug/module.c b/plugins/pychrysa/debug/module.c
index f4b1ff3..db33a13 100644
--- a/plugins/pychrysa/debug/module.c
+++ b/plugins/pychrysa/debug/module.c
@@ -26,6 +26,7 @@
#include "debugger.h"
+#include "gdbrsp/module.h"
@@ -43,23 +44,45 @@
bool add_debug_module_to_python_module(PyObject *super)
{
- bool result;
- PyObject *module;
+ bool result; /* Bilan à retourner */
+ PyObject *module; /* Sous-module mis en place */
int ret; /* Bilan d'un appel */
- static PyMethodDef py_debug_methods[] = {
- { NULL }
+ static PyModuleDef py_chrysalide_debug_module = {
+
+ .m_base = PyModuleDef_HEAD_INIT,
+
+ .m_name = "pychrysalide.debug",
+ .m_doc = "Python module for Chrysalide.debug",
+
+ .m_size = -1,
+
};
- module = Py_InitModule("pyoida.debug", py_debug_methods);
+ result = false;
+
+ module = PyModule_Create(&py_chrysalide_debug_module);
if (module == NULL) return false;
+ ret = PyState_AddModule(super, &py_chrysalide_debug_module);
+ if (ret != 0) goto loading_failed;
+
+ ret = _PyImport_FixupBuiltin(module, "pychrysalide.debug");
+ if (ret != 0) goto loading_failed;
+
Py_INCREF(module);
- ret = PyModule_AddObject(super, "pyoida.debug", module);
+ ret = PyModule_AddObject(super, "debug", module);
+ if (ret != 0) goto loading_failed;
+
+ result = true;
+
+ result &= register_python_binary_debugger(module);
+
+ result &= add_debug_gdbrsp_module_to_python_module(module);
- result = (ret == 0);
+ loading_failed:
- //result &= register_python_binary_debugger(module);
+ assert(result);
return result;
diff --git a/plugins/pychrysa/debug/module.h b/plugins/pychrysa/debug/module.h
index 9c17b75..bbd1971 100644
--- a/plugins/pychrysa/debug/module.h
+++ b/plugins/pychrysa/debug/module.h
@@ -22,8 +22,8 @@
*/
-#ifndef _PLUGINS_PYOIDA_DEBUG_MODULE_H
-#define _PLUGINS_PYOIDA_DEBUG_MODULE_H
+#ifndef _PLUGINS_PYCHRYSA_DEBUG_MODULE_H
+#define _PLUGINS_PYCHRYSA_DEBUG_MODULE_H
#include <Python.h>
@@ -36,4 +36,4 @@ bool add_debug_module_to_python_module(PyObject *);
-#endif /* _PLUGINS_PYOIDA_DEBUG_MODULE_H */
+#endif /* _PLUGINS_PYCHRYSA_DEBUG_MODULE_H */
diff --git a/plugins/pychrysa/format/Makefile.am b/plugins/pychrysa/format/Makefile.am
index 5733e39..bef87ca 100644
--- a/plugins/pychrysa/format/Makefile.am
+++ b/plugins/pychrysa/format/Makefile.am
@@ -11,7 +11,6 @@ libpychrysaformat_la_LIBADD = \
dex/libpychrysaformatdex.la \
elf/libpychrysaformatelf.la
-
libpychrysaformat_la_LDFLAGS =
diff --git a/plugins/pychrysa/format/elf/elf.c b/plugins/pychrysa/format/elf/elf.c
index f8c067f..102c60d 100644
--- a/plugins/pychrysa/format/elf/elf.c
+++ b/plugins/pychrysa/format/elf/elf.c
@@ -198,7 +198,7 @@ bool register_python_elf_format(PyObject *module)
dict = PyModule_GetDict(module);
if (!register_class_for_pygobject(dict, G_TYPE_ELF_FORMAT,
- py_elf_format_type, get_python_executable_format_type()))
+ py_elf_format_type, get_python_executable_format_type()))
return false;
return true;
diff --git a/plugins/pychrysa/format/symbol.c b/plugins/pychrysa/format/symbol.c
index 44707d1..101b694 100644
--- a/plugins/pychrysa/format/symbol.c
+++ b/plugins/pychrysa/format/symbol.c
@@ -384,7 +384,14 @@ static PyObject *py_binary_symbol_get_label(PyObject *self, void *closure)
symbol = G_BIN_SYMBOL(pygobject_get(self));
label = g_binary_symbol_get_label(symbol);
- result = PyUnicode_FromString(label);
+ if (label != NULL)
+ result = PyUnicode_FromString(label);
+
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
return result;
diff --git a/plugins/pychrysa/pychrysa.c b/plugins/pychrysa/pychrysa.c
index 60d200d..45e32b4 100644
--- a/plugins/pychrysa/pychrysa.c
+++ b/plugins/pychrysa/pychrysa.c
@@ -46,6 +46,7 @@
#include "arch/module.h"
#include "common/module.h"
#include "core/module.h"
+#include "debug/module.h"
#include "format/module.h"
#include "glibext/module.h"
#include "gtkext/module.h"
@@ -391,6 +392,7 @@ PyMODINIT_FUNC PyInit_pychrysalide(void)
status &= add_arch_module_to_python_module(result);
status &= add_common_module_to_python_module(result);
status &= add_core_module_to_python_module(result);
+ status &= add_debug_module_to_python_module(result);
status &= add_format_module_to_python_module(result);
status &= add_glibext_module_to_python_module(result);
status &= add_gtkext_module_to_python_module(result);