summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2021-10-24 22:13:40 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2021-10-24 22:15:59 (GMT)
commit55faf115708f8448c1dbbb1798ac115e8021e45f (patch)
tree995059fb5d651b29ebc457c7c11396eba53867ec
parentda03e81474f8e5271c61cb88cb56bb1f9e2b3cfd (diff)
Use the loaded content class hints in the DB archives.
-rw-r--r--plugins/pychrysalide/analysis/db/analyst.c17
-rw-r--r--src/analysis/binary.c4
-rw-r--r--src/analysis/db/analyst.c48
-rw-r--r--src/analysis/db/analyst.h3
-rw-r--r--src/analysis/db/cdb.c27
-rw-r--r--src/analysis/db/cdb.h6
-rw-r--r--src/analysis/db/server.c32
7 files changed, 102 insertions, 35 deletions
diff --git a/plugins/pychrysalide/analysis/db/analyst.c b/plugins/pychrysalide/analysis/db/analyst.c
index bb9af30..289db31 100644
--- a/plugins/pychrysalide/analysis/db/analyst.c
+++ b/plugins/pychrysalide/analysis/db/analyst.c
@@ -37,6 +37,7 @@
#include "client.h"
#include "collection.h"
#include "../content.h"
+#include "../loaded.h"
#include "../../access.h"
#include "../../helpers.h"
#include "../../struct.h"
@@ -95,7 +96,9 @@ static PyObject *py_analyst_client_get_current_snapshot(PyObject *, void *);
static PyObject *py_analyst_client_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *result; /* Instance à retourner */
+ GLoadedContent *loaded; /* Contenu local déjà chargé */
const char *hash; /* Empreinte du binaire visé */
+ const char *class; /* Nature du contenu analysé */
PyObject *list; /* Liste Python de collections */
int ret; /* Bilan de lecture des args. */
Py_ssize_t length; /* Nombre d'éléments collectés */
@@ -113,11 +116,15 @@ static PyObject *py_analyst_client_new(PyTypeObject *type, PyObject *args, PyObj
"\n" \
"Instances can be created using the following constructor:\n" \
"\n" \
- " AnalystClient(hash, list)" \
+ " AnalystClient(hash, class, list, loaded=None)" \
"\n" \
- "Where hash is a SHA256 fingerprint of the studied binary and list is a list of" \
+ "Where *hash* is a SHA256 fingerprint of the studied binary, *class* refers to" \
+ " the nature description of the loaded content (as provided from" \
+ " pychrysalide.analysis.LoadedContent.content_class), *list* is a list of" \
" pychrysalide.analysis.db.DbCollection instances ; this kind of list can be" \
" retrived with the pychrysalide.analysis.LoadedBinary.collections attribute." \
+ " The *loaded* object is an optional local already loaded content which has to" \
+ " be a pychrysalide.analysis.LoadedContent instance or *None*." \
"\n" \
"AnalystClient instances emit the following signals:\n" \
"* 'snapshots-updated'\n" \
@@ -131,7 +138,9 @@ static PyObject *py_analyst_client_new(PyTypeObject *type, PyObject *args, PyObj
" Handlers are expected to have only one argument: the client managing the" \
" snapshots."
- ret = PyArg_ParseTuple(args, "sO", &hash, &list);
+ loaded = NULL;
+
+ ret = PyArg_ParseTuple(args, "ssO|O&", &hash, &class, &list, convert_to_loaded_content, &loaded);
if (!ret) return NULL;
if (!PySequence_Check(list))
@@ -164,7 +173,7 @@ static PyObject *py_analyst_client_new(PyTypeObject *type, PyObject *args, PyObj
}
- client = g_analyst_client_new(hash, collections);
+ client = g_analyst_client_new(hash, class, collections, loaded);
if (client != NULL)
{
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 5d604be..9c3b3b9 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -609,7 +609,7 @@ static bool g_loaded_binary_connect_internal(GLoadedBinary *binary)
/* Tentative de connexion */
- binary->client = g_analyst_client_new(checksum, binary->collections);
+ binary->client = g_analyst_client_new(checksum, "NULL", binary->collections, NULL);
result = g_hub_client_start_internal(G_HUB_CLIENT(binary->client));
@@ -646,7 +646,7 @@ static bool g_loaded_binary_connect_remote(GLoadedBinary *binary)
/* Tentative de connexion */
- binary->client = g_analyst_client_new(checksum, binary->collections);
+ binary->client = g_analyst_client_new(checksum, "NULL", binary->collections, NULL);
result = g_hub_client_start_remote(G_HUB_CLIENT(binary->client),
binary->remote_host, binary->remote_port, true);
diff --git a/src/analysis/db/analyst.c b/src/analysis/db/analyst.c
index 49585c2..ab12cc1 100644
--- a/src/analysis/db/analyst.c
+++ b/src/analysis/db/analyst.c
@@ -40,7 +40,10 @@ struct _GAnalystClient
{
GHubClient parent; /* A laisser en premier */
- char *hash; /* Empreinte du binaire lié */
+ char *cnt_hash; /* Empreinte du binaire lié */
+ char *cnt_class; /* Interprétation du contenu */
+
+ GLoadedContent *loaded; /* Contenu chargé */
GList *collections; /* Collections d'un binaire */
bool can_get_updates; /* Réception de maj possibles ?*/
@@ -159,7 +162,10 @@ static void g_analyst_client_class_init(GAnalystClientClass *klass)
static void g_analyst_client_init(GAnalystClient *client)
{
- client->hash = NULL;
+ client->cnt_hash = NULL;
+ client->cnt_class = NULL;
+
+ client->loaded = NULL;
client->collections = NULL;
client->can_get_updates = false;
@@ -195,6 +201,8 @@ static void g_analyst_client_dispose(GAnalystClient *client)
g_mutex_clear(&client->snap_lock);
+ g_clear_object(&client->loaded);
+
G_OBJECT_CLASS(g_analyst_client_parent_class)->dispose(G_OBJECT(client));
}
@@ -216,8 +224,11 @@ static void g_analyst_client_finalize(GAnalystClient *client)
{
size_t i; /* Boucle de parcours */
- if (client->hash != NULL)
- free(client->hash);
+ if (client->cnt_hash != NULL)
+ free(client->cnt_hash);
+
+ if (client->cnt_class != NULL)
+ free(client->cnt_class);
if (client->snapshots != NULL)
{
@@ -236,7 +247,9 @@ static void g_analyst_client_finalize(GAnalystClient *client)
/******************************************************************************
* *
* Paramètres : hash = empreinte d'un binaire en cours d'analyse. *
+* class = nature de l'interprétation de ce contenu. *
* collections = ensemble de collections existantes. *
+* loaded = éventuel élément local préchargé. *
* *
* Description : Prépare un client pour une connexion à une BD. *
* *
@@ -246,13 +259,18 @@ static void g_analyst_client_finalize(GAnalystClient *client)
* *
******************************************************************************/
-GAnalystClient *g_analyst_client_new(const char *hash, GList *collections)
+GAnalystClient *g_analyst_client_new(const char *hash, const char *class, GList *collections, GLoadedContent *loaded)
{
GAnalystClient *result; /* Adresse à retourner */
result = g_object_new(G_TYPE_ANALYST_CLIENT, NULL);
- result->hash = strdup(hash);
+ result->cnt_hash = strdup(hash);
+ result->cnt_class = strdup(class);
+
+ result->loaded = loaded;
+ if (loaded != NULL) g_object_ref(G_OBJECT(loaded));
+
result->collections = collections;
return result;
@@ -278,7 +296,13 @@ static bool g_analyst_client_complete_hello(GAnalystClient *client, packed_buffe
bool result; /* Bilan à retourner */
rle_string str; /* Chaîne à communiquer */
- init_static_rle_string(&str, client->hash);
+ init_static_rle_string(&str, client->cnt_hash);
+
+ result = pack_rle_string(&str, pbuf);
+
+ exit_rle_string(&str);
+
+ init_static_rle_string(&str, client->cnt_class);
result = pack_rle_string(&str, pbuf);
@@ -414,10 +438,10 @@ static void *g_analyst_client_update(GAnalystClient *client)
error = tmp32;
if (error == DBE_NONE)
- log_variadic_message(LMT_INFO, _("Archive saved for binary '%s'"), client->hash);
+ log_variadic_message(LMT_INFO, _("Archive saved for binary '%s'"), client->cnt_hash);
else
log_variadic_message(LMT_ERROR, _("Failed to save the archive for binary '%s'"),
- client->hash);
+ client->cnt_hash);
break;
@@ -669,10 +693,10 @@ bool g_analyst_client_send_content(GAnalystClient *client, GBinContent *content)
hash = g_binary_content_get_checksum(content);
- if (strcmp(hash, client->hash) != 0)
+ if (strcmp(hash, client->cnt_hash) != 0)
{
log_variadic_message(LMT_ERROR, _("Provided ontent does not match client content (hash: '%s')"),
- client->hash);
+ client->cnt_hash);
goto exit;
}
@@ -680,7 +704,7 @@ bool g_analyst_client_send_content(GAnalystClient *client, GBinContent *content)
init_packed_buffer(&cnt_pbuf);
- storage = g_object_storage_new(client->hash);
+ storage = g_object_storage_new(client->cnt_hash);
result = g_object_storage_store_object(storage, "contents", G_SERIALIZABLE_OBJECT(content), &pos);
if (!result) goto exit_with_failure;
diff --git a/src/analysis/db/analyst.h b/src/analysis/db/analyst.h
index 7b11f53..9f7b32b 100644
--- a/src/analysis/db/analyst.h
+++ b/src/analysis/db/analyst.h
@@ -34,6 +34,7 @@
#include "collection.h"
#include "misc/snapshot.h"
#include "../content.h"
+#include "../loaded.h"
@@ -56,7 +57,7 @@ typedef struct _GAnalystClientClass GAnalystClientClass;
GType g_analyst_client_get_type(void);
/* Prépare un client pour une connexion à une BD. */
-GAnalystClient *g_analyst_client_new(const char *, GList *);
+GAnalystClient *g_analyst_client_new(const char *, const char *, GList *, GLoadedContent *);
/* Envoie un contenu binaire pour conservation côté serveur. */
bool g_analyst_client_send_content(GAnalystClient *, GBinContent *);
diff --git a/src/analysis/db/cdb.c b/src/analysis/db/cdb.c
index 62de6a7..08410c4 100644
--- a/src/analysis/db/cdb.c
+++ b/src/analysis/db/cdb.c
@@ -80,6 +80,7 @@ struct _GCdbArchive
GServerBackend parent; /* A laisser en premier */
rle_string hash; /* Empreinte cryptographique */
+ rle_string class; /* Nature du contenu analysé */
char *filename; /* Chemin d'accès à l'archive */
char *tmpdir; /* Répertoire de travail */
@@ -235,6 +236,7 @@ static void g_cdb_archive_class_init(GCdbArchiveClass *klass)
static void g_cdb_archive_init(GCdbArchive *archive)
{
setup_empty_rle_string(&archive->hash);
+ setup_empty_rle_string(&archive->class);
archive->filename = NULL;
archive->tmpdir = NULL;
@@ -315,6 +317,7 @@ static void g_cdb_archive_finalize(GCdbArchive *archive)
if (archive->filename != NULL)
free(archive->filename);
+ exit_rle_string(&archive->class);
exit_rle_string(&archive->hash);
G_OBJECT_CLASS(g_cdb_archive_parent_class)->finalize(G_OBJECT(archive));
@@ -327,6 +330,7 @@ static void g_cdb_archive_finalize(GCdbArchive *archive)
* Paramètres : basedir = répertoire de stockage des enregistrements. *
* tmpdir = répertoire de travail temporaire. *
* hash = empreinte du binaire à représenter. *
+* class = nature du contenu analysé associé. *
* error = indication éventuelle en cas d'échec. [OUT] *
* *
* Description : Définit ou ouvre une archive d'éléments utilisateur. *
@@ -338,7 +342,7 @@ static void g_cdb_archive_finalize(GCdbArchive *archive)
* *
******************************************************************************/
-GCdbArchive *g_cdb_archive_new(const char *basedir, const char *tmpdir, const rle_string *hash, DBError *error)
+GCdbArchive *g_cdb_archive_new(const char *basedir, const char *tmpdir, const rle_string *hash, const rle_string *class, DBError *error)
{
GCdbArchive *result; /* Adresse à retourner */
int ret; /* Retour d'un appel */
@@ -347,13 +351,16 @@ GCdbArchive *g_cdb_archive_new(const char *basedir, const char *tmpdir, const rl
result = g_object_new(G_TYPE_CDB_ARCHIVE, NULL);
dup_into_rle_string(&result->hash, get_rle_string(hash));
+ dup_into_rle_string(&result->class, get_rle_string(class));
*error = DBE_SYS_ERROR;
/* Chemin de l'archive */
result->filename = strdup(basedir);
- result->filename = stradd(result->filename, hash->data);
+ result->filename = stradd(result->filename, get_rle_string(hash));
+ result->filename = stradd(result->filename, "-");
+ result->filename = stradd(result->filename, get_rle_string(class));
result->filename = stradd(result->filename, ".cdb.tar.xz");
if (!mkpath(result->filename))
@@ -679,18 +686,26 @@ DBError g_cdb_archive_write(const GCdbArchive *archive)
* *
* Paramètres : archive = informations quant à l'archive à consulter. *
* hash = empreinte extérieure à comparer. *
+* class = nature du contenu analysé. *
* *
-* Description : Détermine si une empreinte correspond à celle d'une archive. *
+* Description : Détermine l'archive correspond à une cible recherchée. *
* *
-* Retour : Résultat de la comparaison : -1, 0 ou 1. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-int g_cdb_archive_compare_hash(const GCdbArchive *archive, const rle_string *hash)
+bool g_cdb_archive_compare_is_suitable_for(const GCdbArchive *archive, const rle_string *hash, const rle_string *class)
{
- return cmp_rle_string(&archive->hash, hash);
+ bool result; /* Bilan à retourner */
+
+ result = (cmp_rle_string(&archive->hash, hash) == 0);
+
+ if (result)
+ result = (cmp_rle_string(&archive->class, class) == 0);
+
+ return result;
}
diff --git a/src/analysis/db/cdb.h b/src/analysis/db/cdb.h
index b2c3fc3..7a557f2 100644
--- a/src/analysis/db/cdb.h
+++ b/src/analysis/db/cdb.h
@@ -54,7 +54,7 @@ typedef struct _GCdbArchiveClass GCdbArchiveClass;
GType g_cdb_archive_get_type(void);
/* Prépare un client pour une connexion à une BD. */
-GCdbArchive *g_cdb_archive_new(const char *, const char *, const rle_string *, DBError *);
+GCdbArchive *g_cdb_archive_new(const char *, const char *, const rle_string *, const rle_string *, DBError *);
/* Construit un chemin pour un fichier propre à l'archive. */
char *g_cdb_archive_get_tmp_filename(const GCdbArchive *, const char *);
@@ -62,8 +62,8 @@ char *g_cdb_archive_get_tmp_filename(const GCdbArchive *, const char *);
/* Enregistre une archive avec tous les éléments à conserver. */
DBError g_cdb_archive_write(const GCdbArchive *);
-/* Détermine si une empreinte correspond à celle d'une archive. */
-int g_cdb_archive_compare_hash(const GCdbArchive *, const rle_string *);
+/* Détermine l'archive correspond à une cible recherchée. */
+bool g_cdb_archive_compare_is_suitable_for(const GCdbArchive *, const rle_string *, const rle_string *);
diff --git a/src/analysis/db/server.c b/src/analysis/db/server.c
index b08962c..5c6fd18 100644
--- a/src/analysis/db/server.c
+++ b/src/analysis/db/server.c
@@ -1028,7 +1028,7 @@ static GServerBackend *g_hub_server_handle_admin(GHubServer *server, packed_buff
if (has_more_data_in_packed_buffer(in_pbuf))
{
- log_variadic_message(LMT_ERROR, _("The client from '%s' provided to much data!"), peer_name);
+ log_variadic_message(LMT_ERROR, _("The client from '%s' provided too much data!"), peer_name);
result = NULL;
@@ -1074,6 +1074,7 @@ static GServerBackend *g_hub_server_handle_analyst(GHubServer *server, packed_bu
{
GCdbArchive *result; /* Support de suivi à retourner*/
rle_string hash; /* Empreinte du binaire visé */
+ rle_string class; /* Nature du contenu visé */
bool status; /* Bilan d'une opération */
GList *iter; /* Boucle de parcours */
GCdbArchive *archive; /* Destinataire final du client*/
@@ -1097,13 +1098,26 @@ static GServerBackend *g_hub_server_handle_analyst(GHubServer *server, packed_bu
if (is_rle_string_empty(&hash))
{
log_variadic_message(LMT_ERROR, _("The submitted binary hash from '%s' is empty!"), peer_name);
- goto wrong_receiving;
+ goto wrong_receiving_0;
+ }
+
+ status = unpack_rle_string(&class, in_pbuf);
+ if (!status)
+ {
+ log_variadic_message(LMT_ERROR, _("Error while getting the content class from '%s'..."), peer_name);
+ goto wrong_receiving_0;
+ }
+
+ if (is_rle_string_empty(&class))
+ {
+ log_variadic_message(LMT_ERROR, _("The submitted content class from '%s' is empty!"), peer_name);
+ goto wrong_receiving_1;
}
if (has_more_data_in_packed_buffer(in_pbuf))
{
- log_variadic_message(LMT_ERROR, _("The client from '%s' provided to much data!"), peer_name);
- goto wrong_receiving;
+ log_variadic_message(LMT_ERROR, _("The client from '%s' provided too much data!"), peer_name);
+ goto wrong_receiving_1;
}
/* Recherche d'un support existant adapté */
@@ -1114,7 +1128,7 @@ static GServerBackend *g_hub_server_handle_analyst(GHubServer *server, packed_bu
{
archive = G_CDB_ARCHIVE(iter->data);
- if (g_cdb_archive_compare_hash(archive, &hash) == 0)
+ if (g_cdb_archive_compare_is_suitable_for(archive, &hash, &class))
break;
}
@@ -1137,7 +1151,7 @@ static GServerBackend *g_hub_server_handle_analyst(GHubServer *server, packed_bu
tmpdir = strdup(server->working);
tmpdir = stradd(tmpdir, "tmp" G_DIR_SEPARATOR_S);
- result = g_cdb_archive_new(basedir, tmpdir, &hash, error);
+ result = g_cdb_archive_new(basedir, tmpdir, &hash, &class, error);
free(tmpdir);
free(basedir);
@@ -1146,7 +1160,11 @@ static GServerBackend *g_hub_server_handle_analyst(GHubServer *server, packed_bu
}
- wrong_receiving:
+ wrong_receiving_1:
+
+ exit_rle_string(&class);
+
+ wrong_receiving_0:
exit_rle_string(&hash);