summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-09-11 21:25:13 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-09-11 21:25:13 (GMT)
commit83faef9c8f78b20cb031af686f763cfb215cf9d7 (patch)
treeea95f741855044f4473573726804c6c2bcac5db1
parent3e1347d378e7ff0e21fb53b61e0317b8dfe52fc9 (diff)
Reactivated bookmarks for disassembled code.
-rw-r--r--plugins/pychrysalide/analysis/db/constants.c38
-rw-r--r--plugins/pychrysalide/analysis/db/constants.h3
-rw-r--r--plugins/pychrysalide/analysis/db/item.c137
-rw-r--r--plugins/pychrysalide/analysis/db/items/bookmark.c7
-rw-r--r--src/analysis/db/collection.c10
-rw-r--r--src/analysis/db/item-int.h9
-rw-r--r--src/analysis/db/item.c68
-rw-r--r--src/analysis/db/item.h18
-rw-r--r--src/analysis/db/items/bookmark.c71
-rw-r--r--src/analysis/db/misc/rlestr.c13
-rw-r--r--src/arch/vmpa.c24
-rw-r--r--src/glibext/gbuffercache.h5
12 files changed, 356 insertions, 47 deletions
diff --git a/plugins/pychrysalide/analysis/db/constants.c b/plugins/pychrysalide/analysis/db/constants.c
index 9685ba6..fb30c7e 100644
--- a/plugins/pychrysalide/analysis/db/constants.c
+++ b/plugins/pychrysalide/analysis/db/constants.c
@@ -25,6 +25,7 @@
#include "constants.h"
+#include <analysis/db/item.h>
#include <analysis/db/server.h>
@@ -36,6 +37,43 @@
* *
* Paramètres : type = type dont le dictionnaire est à compléter. *
* *
+* Description : Définit les constantes pour les éléments de base de données. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool define_db_item_constants(PyTypeObject *type)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *values; /* Groupe de valeurs à établir */
+
+ values = PyDict_New();
+
+ result = add_const_to_group(values, "NONE", DIF_NONE);
+ if (result) result = add_const_to_group(values, "ERASER", DIF_ERASER);
+
+ if (!result)
+ {
+ Py_DECREF(values);
+ goto exit;
+ }
+
+ result = attach_constants_group(type, true, "DbItemFlags", values, "Properties of a database item.");
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type dont le dictionnaire est à compléter. *
+* *
* Description : Définit les constantes pour les serveurs de données. *
* *
* Retour : true en cas de succès de l'opération, false sinon. *
diff --git a/plugins/pychrysalide/analysis/db/constants.h b/plugins/pychrysalide/analysis/db/constants.h
index a2fc49e..cb7edf4 100644
--- a/plugins/pychrysalide/analysis/db/constants.h
+++ b/plugins/pychrysalide/analysis/db/constants.h
@@ -31,6 +31,9 @@
+/* Définit les constantes pour les éléments de base de données. */
+bool define_db_item_constants(PyTypeObject *);
+
/* Définit les constantes pour les serveurs de données. */
bool define_hub_server_constants(PyTypeObject *);
diff --git a/plugins/pychrysalide/analysis/db/item.c b/plugins/pychrysalide/analysis/db/item.c
index 981e0c0..bbaa21b 100644
--- a/plugins/pychrysalide/analysis/db/item.c
+++ b/plugins/pychrysalide/analysis/db/item.c
@@ -32,17 +32,109 @@
#include <analysis/db/item.h>
+#include "constants.h"
#include "../../access.h"
#include "../../helpers.h"
+/* Ajoute une propriété à un élément de base de données. */
+static PyObject *py_db_item_add_flag(PyObject *, PyObject *);
+
+/* Retire une propriété à un élément de base de données. */
+static PyObject *py_db_item_remove_flag(PyObject *, PyObject *);
+
/* Indique si l'élément contient des données à oublier ou non. */
static PyObject *py_db_item_get_volatile(PyObject *, void *);
/* Définit si l'élément contient des données à oublier ou non. */
static int py_db_item_set_volatile(PyObject *, PyObject *, void *);
+/* Indique les propriétés particulières appliquées à l'élément. */
+static PyObject *py_db_item_get_flags(PyObject *, void *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = serveur à manipuler. *
+* args = arguments d'appel non utilisés ici. *
+* *
+* Description : Ajoute une propriété à un élément de base de données. *
+* *
+* Retour : None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_db_item_add_flag(PyObject *self, PyObject *args)
+{
+ unsigned int flag; /* Propriété à traiter */
+ int ret; /* Bilan de lecture des args. */
+ GDbItem *item; /* Elément à manipuler */
+
+#define DB_ITEM_ADD_FLAG_METHOD PYTHON_METHOD_DEF \
+( \
+ add_flag, "$self, flag, /", \
+ METH_VARARGS, py_db_item, \
+ "Add a property to a database item." \
+ "\n" \
+ "This property is one of the values listed in the" \
+ " of pychrysalide.analysis.db.DbItem.DbItemFlags enumeration." \
+)
+
+ ret = PyArg_ParseTuple(args, "I", &flag);
+ if (!ret) return NULL;
+
+ item = G_DB_ITEM(pygobject_get(self));
+
+ g_db_item_add_flag(item, flag);
+
+ Py_RETURN_NONE;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = serveur à manipuler. *
+* args = arguments d'appel non utilisés ici. *
+* *
+* Description : Retire une propriété à un élément de base de données. *
+* *
+* Retour : None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_db_item_remove_flag(PyObject *self, PyObject *args)
+{
+ unsigned int flag; /* Propriété à traiter */
+ int ret; /* Bilan de lecture des args. */
+ GDbItem *item; /* Elément à manipuler */
+
+#define DB_ITEM_REMOVE_FLAG_METHOD PYTHON_METHOD_DEF \
+( \
+ remove_flag, "$self, flag, /", \
+ METH_VARARGS, py_db_item, \
+ "Remove a property from a database item." \
+ "\n" \
+ "This property is one of the values listed in the" \
+ " of pychrysalide.analysis.db.DbItem.DbItemFlags enumeration." \
+)
+
+ ret = PyArg_ParseTuple(args, "I", &flag);
+ if (!ret) return NULL;
+
+ item = G_DB_ITEM(pygobject_get(self));
+
+ g_db_item_remove_flag(item, flag);
+
+ Py_RETURN_NONE;
+
+}
/******************************************************************************
@@ -107,6 +199,43 @@ static int py_db_item_set_volatile(PyObject *self, PyObject *value, void *closur
/******************************************************************************
* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Indique les propriétés particulières appliquées à l'élément. *
+* *
+* Retour : Propriétés actives de l'élément. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_db_item_get_flags(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GDbItem *item; /* Elément à consulter */
+ DbItemFlags flags; /* Propriétés de l'élément */
+
+#define DB_ITEM_FLAGS_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ flags, py_db_item, \
+ "Properties of the database item, provided as a mask" \
+ " of pychrysalide.analysis.db.DbItem.DbItemFlags values." \
+)
+
+ item = G_DB_ITEM(pygobject_get(self));
+
+ flags = g_db_item_get_flags(item);
+
+ result = cast_with_constants_group(get_python_db_item_type(), "DbItemFlags", flags);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : - *
* *
* Description : Fournit un accès à une définition de type à diffuser. *
@@ -120,17 +249,18 @@ static int py_db_item_set_volatile(PyObject *self, PyObject *value, void *closur
PyTypeObject *get_python_db_item_type(void)
{
static PyMethodDef py_db_item_methods[] = {
+ DB_ITEM_ADD_FLAG_METHOD,
+ DB_ITEM_REMOVE_FLAG_METHOD,
{ NULL }
};
static PyGetSetDef py_db_item_getseters[] = {
-
{
"volatile", py_db_item_get_volatile, py_db_item_set_volatile,
"Define if a Database item can be forgotten.", NULL
},
+ DB_ITEM_FLAGS_ATTRIB,
{ NULL }
-
};
static PyTypeObject py_db_item_type = {
@@ -183,6 +313,9 @@ bool ensure_python_db_item_is_registered(void)
if (!register_class_for_pygobject(dict, G_TYPE_DB_ITEM, type, &PyGObject_Type))
return false;
+ if (!define_db_item_constants(type))
+ return false;
+
}
return true;
diff --git a/plugins/pychrysalide/analysis/db/items/bookmark.c b/plugins/pychrysalide/analysis/db/items/bookmark.c
index 8a33357..783efa6 100644
--- a/plugins/pychrysalide/analysis/db/items/bookmark.c
+++ b/plugins/pychrysalide/analysis/db/items/bookmark.c
@@ -147,7 +147,12 @@ static int py_db_bookmark_init(PyObject *self, PyObject *args, PyObject *kwds)
" DbBookmark(addr, comment=None)" \
"\n" \
"Where addr is a location of type pychrysalide.arch.vmpa and" \
- " comment is a string or None."
+ " comment is a string or None.\n" \
+ "\n" \
+ "An empty comment is not enough to delete a bookmark for a given address;" \
+ " the *ERASER* flag from the pychrysalide.analysis.db.DbItem.DbItemFlags" \
+ " enumeration must be explicitly add to the item by a call to the" \
+ " pychrysalide.analysis.db.DbItem.add_flag() function."
result = -1;
diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c
index cdc91aa..0f4e771 100644
--- a/src/analysis/db/collection.c
+++ b/src/analysis/db/collection.c
@@ -375,14 +375,10 @@ bool g_db_collection_unpack(GDbCollection *collec, packed_buffer *pbuf, sqlite3
if (result)
{
if (collec->binary != NULL && g_db_item_is_active(item))
- result = g_db_item_apply(item, collec->binary);
+ g_db_item_apply(item, collec->binary);
- if (result && db != NULL)
- result = g_db_collection_store_item(collec, item, db);
-
- /* En cas d'erreur, il faut retirer l'élément */
- if (!result)
- _g_db_collection_remove_item(collec, item, true, false);
+ if (db != NULL)
+ g_db_collection_store_item(collec, item, db);
}
diff --git a/src/analysis/db/item-int.h b/src/analysis/db/item-int.h
index 3a5f47d..923ea3a 100644
--- a/src/analysis/db/item-int.h
+++ b/src/analysis/db/item-int.h
@@ -71,8 +71,17 @@ struct _GDbItem
char *label; /* Représentation humaine */
+ union
+ {
+ DbItemFlags flags; /* Propriétés de l'élément */
+ gint atomic_flags; /* Accès atomique */
+
+ };
+
bool is_volatile; /* Pas besoin de sauvegarde ? */
+ bool broken; /* Changement applicable ? */
+
};
/* Base d'un élément pour collection générique (classe) */
diff --git a/src/analysis/db/item.c b/src/analysis/db/item.c
index 2bbc683..c59ef64 100644
--- a/src/analysis/db/item.c
+++ b/src/analysis/db/item.c
@@ -596,6 +596,74 @@ bool g_db_item_is_volatile(const GDbItem *item)
}
+/******************************************************************************
+* *
+* Paramètres : item = base d'éléments à mettre à jour. *
+* flag = type de propriété à traiter. *
+* *
+* Description : Ajoute une propriété à un élément de base de données. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_db_item_add_flag(GDbItem *item, DbItemFlags flag)
+{
+ g_atomic_int_add(&item->atomic_flags, flag);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = base d'éléments à mettre à jour. *
+* flag = type de propriété à traiter. *
+* *
+* Description : Retire une propriété à un élément de base de données. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_db_item_remove_flag(GDbItem *item, DbItemFlags flag)
+{
+ gint mask; /* Masque à appliquer */
+
+ mask = flag;
+ mask = ~mask;
+
+ g_atomic_int_and(&item->atomic_flags, mask);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = base d'éléments à consulter. *
+* *
+* Description : Indique les propriétés particulières appliquées à l'élément. *
+* *
+* Retour : Propriétés actives de l'élément. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+DbItemFlags g_db_item_get_flags(const GDbItem *item)
+{
+ DbItemFlags result; /* Fanions à retourner */
+
+ result = g_atomic_int_get(&item->atomic_flags);
+
+ return result;
+
+}
+
+
/* ---------------------------------------------------------------------------------- */
/* MANIPULATIONS AVEC UNE BASE DE DONNEES */
diff --git a/src/analysis/db/item.h b/src/analysis/db/item.h
index 6644507..3444b73 100644
--- a/src/analysis/db/item.h
+++ b/src/analysis/db/item.h
@@ -40,6 +40,15 @@
typedef struct _GLoadedBinary GLoadedBinary;
+/* Propriétés particulières pour un élément */
+typedef enum _DbItemFlags
+{
+ DIF_NONE = (0 << 0), /* Propriétés par défaut */
+ DIF_ERASER = (1 << 0), /* Suppression de l'effet */
+
+} DbItemFlags;
+
+
#define G_TYPE_DB_ITEM g_db_item_get_type()
#define G_DB_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_db_item_get_type(), GDbItem))
#define G_IS_DB_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_db_item_get_type()))
@@ -103,6 +112,15 @@ void g_db_item_set_volatile(GDbItem *, bool);
/* Indique si l'élément contient des données à oublier ou non. */
bool g_db_item_is_volatile(const GDbItem *);
+/* Ajoute une propriété à un élément de base de données. */
+void g_db_item_add_flag(GDbItem *, DbItemFlags);
+
+/* Retire une propriété à un élément de base de données. */
+void g_db_item_remove_flag(GDbItem *, DbItemFlags);
+
+/* Indique les propriétés particulières appliquées à l'élément. */
+DbItemFlags g_db_item_get_flags(const GDbItem *);
+
/* --------------------- MANIPULATIONS AVEC UNE BASE DE DONNEES --------------------- */
diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c
index 266b04c..819528d 100644
--- a/src/analysis/db/items/bookmark.c
+++ b/src/analysis/db/items/bookmark.c
@@ -34,6 +34,7 @@
#include "../collection-int.h"
#include "../item-int.h"
+#include "../../../glibext/gbinarycursor.h"
@@ -206,6 +207,9 @@ static void g_db_bookmark_class_init(GDbBookmarkClass *klass)
static void g_db_bookmark_init(GDbBookmark *bookmark)
{
+ init_vmpa(&bookmark->addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
+
+ init_dynamic_rle_string(&bookmark->comment, NULL);
}
@@ -440,37 +444,60 @@ static void g_db_bookmark_build_label(GDbBookmark *bookmark)
static bool g_db_bookmark_run(GDbBookmark *bookmark, GLoadedBinary *binary, bool *prev, bool set)
{
- return false;
-#if 0
bool result; /* Bilan à faire remonter */
- GCodeBuffer *buffer; /* Tampon de lignes à traiter */
+ GBufferCache *cache; /* Tampon d'impression colorée */
+ GLineCursor *cursor; /* Emplacement dans un tampon */
+ size_t index; /* Indice de ligne à traiter */
GBufferLine *line; /* Ligne de tampon à marquer */
- result = true;
+ result = false;
+
+ cache = g_loaded_binary_get_disassembled_cache(binary);
+ if (cache == NULL) goto exit;
+
+ g_buffer_cache_lock(cache);
+
+ /* Recherche de la ligne concernée */
+
+ cursor = g_binary_cursor_new();
+ g_binary_cursor_update(G_BINARY_CURSOR(cursor), &bookmark->addr);
- buffer = g_loaded_binary_get_disassembled_buffer(binary);
+ index = g_buffer_cache_find_index_by_cursor(cache, cursor, true);
- line = g_code_buffer_find_line_by_addr(buffer, &bookmark->addr, BLF_HAS_CODE, NULL);
- if (line == NULL)
+ g_object_unref(G_OBJECT(cursor));
+
+ line = g_buffer_cache_find_line_by_index(cache, index);
+
+ /* Application du changement */
+
+ result = (line != NULL);
+
+ if (result)
{
- result = false;
- goto exit;
- }
+ *prev = g_buffer_line_get_flags(line) & BLF_BOOKMARK;
- *prev = g_buffer_line_get_flags(line) & BLF_BOOKMARK;
+ if (set)
+ g_buffer_line_add_flag(line, BLF_BOOKMARK);
- if (set)
- g_buffer_line_add_flag(line, BLF_BOOKMARK);
+ else
+ g_buffer_line_remove_flag(line, BLF_BOOKMARK);
- else
- g_buffer_line_remove_flag(line, BLF_BOOKMARK);
+ g_object_unref(G_OBJECT(line));
+
+ g_buffer_cache_throw_update_at_index(cache, index);
+
+ }
- g_object_unref(G_OBJECT(line));
+ /* Sortie */
+
+ g_buffer_cache_unlock(cache);
+
+ g_object_unref(G_OBJECT(cache));
exit:
return result;
-#endif
+
}
@@ -490,8 +517,11 @@ static bool g_db_bookmark_run(GDbBookmark *bookmark, GLoadedBinary *binary, bool
static bool g_db_bookmark_apply(GDbBookmark *bookmark, GLoadedBinary *binary)
{
bool result; /* Bilan à faire remonter */
+ DbItemFlags flags; /* Propriétés de l'élément */
- result = g_db_bookmark_run(bookmark, binary, &bookmark->prev_state, true);
+ flags = g_db_item_get_flags(G_DB_ITEM(bookmark));
+
+ result = g_db_bookmark_run(bookmark, binary, &bookmark->prev_state, (flags & DIF_ERASER) == 0);
return result;
@@ -514,9 +544,12 @@ static bool g_db_bookmark_apply(GDbBookmark *bookmark, GLoadedBinary *binary)
static bool g_db_bookmark_cancel(GDbBookmark *bookmark, GLoadedBinary *binary)
{
bool result; /* Bilan à faire remonter */
+ DbItemFlags flags; /* Propriétés de l'élément */
+
+ flags = g_db_item_get_flags(G_DB_ITEM(bookmark));
if (!bookmark->prev_state)
- result = g_db_bookmark_run(bookmark, binary, (bool []) { 0 }, false);
+ result = g_db_bookmark_run(bookmark, binary, (bool []) { 0 }, (flags & DIF_ERASER) != 0);
else
result = true;
diff --git a/src/analysis/db/misc/rlestr.c b/src/analysis/db/misc/rlestr.c
index f26c146..0fe182b 100644
--- a/src/analysis/db/misc/rlestr.c
+++ b/src/analysis/db/misc/rlestr.c
@@ -105,6 +105,9 @@ void init_static_rle_string(rle_string *str, const char *data)
void dup_into_rle_string(rle_string *str, const char *data)
{
+ if (str->data != NULL)
+ unset_rle_string(str);
+
if (data != NULL)
{
str->data = strdup(data);
@@ -144,6 +147,11 @@ void set_dynamic_rle_string(rle_string *str, char *data)
str->length = strlen(data);
str->dynamic = true;
}
+ else
+ {
+ str->data = NULL;
+ str->length = 0;
+ }
}
@@ -172,6 +180,11 @@ void set_static_rle_string(rle_string *str, const char *data)
str->length = strlen(data);
str->dynamic = false;
}
+ else
+ {
+ str->data = NULL;
+ str->length = 0;
+ }
}
diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c
index a2a3ba5..70ea52b 100644
--- a/src/arch/vmpa.c
+++ b/src/arch/vmpa.c
@@ -813,36 +813,24 @@ bool store_vmpa(const vmpa2t *addr, const char *base, bound_value **values, size
asprintf(&value->name, "%s%sphys", base != NULL ? base : "", base != NULL ? "_" : "");
value->built_name = true;
+ value->type = SQLITE_INT64;
+
value->has_value = (addr != NULL);
if (value->has_value)
- {
- if (addr->physical != VMPA_NO_PHYSICAL)
- {
- value->type = SQLITE_INT64;
- value->integer64 = addr->physical;
- }
- else
- value->type = SQLITE_NULL;
- }
+ value->integer64 = addr->physical;
value = &(*values)[*count - 1];
asprintf(&value->name, "%s%svirt", base != NULL ? base : "", base != NULL ? "_" : "");
value->built_name = true;
+ value->type = SQLITE_INT64;
+
value->has_value = (addr != NULL);
if (value->has_value)
- {
- if (addr->virtual != VMPA_NO_VIRTUAL)
- {
- value->type = SQLITE_INT64;
- value->integer64 = addr->virtual;
- }
- else
- value->type = SQLITE_NULL;
- }
+ value->integer64 = addr->virtual;
return true;
diff --git a/src/glibext/gbuffercache.h b/src/glibext/gbuffercache.h
index 8059357..0086b38 100644
--- a/src/glibext/gbuffercache.h
+++ b/src/glibext/gbuffercache.h
@@ -99,6 +99,11 @@ void g_buffer_cache_get_line_cursor(const GBufferCache *, size_t, gint, GLineCur
/* Détermine l'ensemble des propriétés attachées à une ligne. */
BufferLineFlags g_buffer_cache_get_line_flags(const GBufferCache *, size_t);
+#define g_buffer_cache_lock(c)
+#define g_buffer_cache_unlock(c)
+
+#define g_buffer_cache_throw_update_at_index(c, i) // check locked
+
/* Retrouve une ligne au sein d'un tampon avec un indice. */
GBufferLine *g_buffer_cache_find_line_by_index(const GBufferCache *, size_t);