summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog26
-rw-r--r--plugins/pychrysa/analysis/content.c7
-rw-r--r--src/analysis/binary.c8
-rw-r--r--src/analysis/content-int.h6
-rw-r--r--src/analysis/content.c29
-rw-r--r--src/analysis/content.h2
-rw-r--r--src/analysis/contents/file.c35
-rw-r--r--src/analysis/contents/restricted.c42
-rw-r--r--src/analysis/disass/disassembler.c2
-rw-r--r--src/analysis/project.c2
-rw-r--r--tests/analysis/contents/checksum.py67
11 files changed, 181 insertions, 45 deletions
diff --git a/ChangeLog b/ChangeLog
index 25f0b0e..0ccf59b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+16-07-28 Cyrille Bagard <nocbos@gmail.com>
+
+ * plugins/pychrysa/analysis/content.c:
+ Update code.
+
+ * src/analysis/binary.c:
+ Typo.
+
+ * src/analysis/content-int.h:
+ * src/analysis/content.c:
+ Centralize the checksum computing of binary contents.
+
+ * src/analysis/content.h:
+ Typo.
+
+ * src/analysis/contents/file.c:
+ * src/analysis/contents/restricted.c:
+ Centralize the checksum computing of binary contents.
+
+ * src/analysis/disass/disassembler.c:
+ * src/analysis/project.c:
+ Typo.
+
+ * tests/analysis/contents/checksum.py:
+ New entry: verify checksums in the test suite.
+
16-07-23 Cyrille Bagard <nocbos@gmail.com>
* plugins/pychrysa/analysis/routine.c:
diff --git a/plugins/pychrysa/analysis/content.c b/plugins/pychrysa/analysis/content.c
index 00265e3..d3da2b1 100644
--- a/plugins/pychrysa/analysis/content.c
+++ b/plugins/pychrysa/analysis/content.c
@@ -82,12 +82,9 @@ static PyObject *py_binary_content_get_checksum(PyObject *self, PyObject *args)
content = G_BIN_CONTENT(pygobject_get(self));
- //checksum = g_binary_content_get_cheksum(content);
+ checksum = g_binary_content_get_checksum(content);
- printf("YEAH\n");
- fflush(NULL);
-
- result = PyUnicode_FromString("checksum");
+ result = PyUnicode_FromString(checksum);
return result;
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 20410f2..75c6e14 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -525,7 +525,7 @@ bool g_loaded_binary_save(const GLoadedBinary *binary, xmlDocPtr xdoc, xmlXPathC
access = stradd(access, "/Main");
content = g_binary_format_get_content(G_BIN_FORMAT(binary->format));
- hash = g_binary_content_get_cheksum(content);
+ hash = g_binary_content_get_checksum(content);
g_object_unref(G_OBJECT(content));
result = add_content_to_node(xdoc, context, access, hash);
@@ -541,7 +541,7 @@ bool g_loaded_binary_save(const GLoadedBinary *binary, xmlDocPtr xdoc, xmlXPathC
debug = g_exe_format_get_debug_info(binary->format, i);
content = g_binary_format_get_content(G_BIN_FORMAT(debug));
- hash = g_binary_content_get_cheksum(content);
+ hash = g_binary_content_get_checksum(content);
g_object_unref(G_OBJECT(content));
g_object_unref(G_OBJECT(debug));
@@ -1038,7 +1038,7 @@ static bool g_loaded_binary_connect_internal(GLoadedBinary *binary)
/* Détermination de l'identifiant */
content = g_binary_format_get_content(G_BIN_FORMAT(binary->format));
- checksum = g_binary_content_get_cheksum(content);
+ checksum = g_binary_content_get_checksum(content);
g_object_unref(G_OBJECT(content));
/* Tentative de connexion */
@@ -1114,7 +1114,7 @@ static bool g_loaded_binary_connect_remote(GLoadedBinary *binary)
/* Détermination de l'identifiant */
content = g_binary_format_get_content(G_BIN_FORMAT(binary->format));
- checksum = g_binary_content_get_cheksum(content);
+ checksum = g_binary_content_get_checksum(content);
g_object_unref(G_OBJECT(content));
/* Tentative de connexion */
diff --git a/src/analysis/content-int.h b/src/analysis/content-int.h
index d9f9ef9..24cea81 100644
--- a/src/analysis/content-int.h
+++ b/src/analysis/content-int.h
@@ -35,8 +35,8 @@ typedef const char * (* describe_content_fc) (const GBinContent *, bool);
/* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */
typedef bool (* save_content_fc) (const GBinContent *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *);
-/* Fournit une empreinte unique (SHA256) pour les données. */
-typedef const gchar * (* get_checksum_fc) (GBinContent *);
+/* Calcule une empreinte unique (SHA256) pour les données. */
+typedef void (* compute_checksum_fc) (GBinContent *, GChecksum *);
/* Détermine le nombre d'octets lisibles. */
typedef phys_t (* compute_size_fc) (const GBinContent *);
@@ -78,7 +78,7 @@ struct _GBinContentIface
save_content_fc save; /* Sauvegarde du contenu */
- get_checksum_fc get_checksum; /* Calcul de l'empreinte */
+ compute_checksum_fc compute_checksum; /* Calcul de l'empreinte */
compute_size_fc compute_size; /* Calcul de la taille totale */
diff --git a/src/analysis/content.c b/src/analysis/content.c
index 01c9c99..4b4645f 100644
--- a/src/analysis/content.c
+++ b/src/analysis/content.c
@@ -24,9 +24,13 @@
#include "content.h"
+#include <assert.h>
#include <string.h>
+#include <i18n.h>
+
+
#include "content-int.h"
#include "contents/file.h"
@@ -155,13 +159,32 @@ bool g_binary_content_save(const GBinContent *content, xmlDocPtr xdoc, xmlXPathC
* *
******************************************************************************/
-const gchar *g_binary_content_get_cheksum(GBinContent *content)
+const gchar *g_binary_content_get_checksum(GBinContent *content)
{
+ const gchar *result; /* Empreinte à retourner */
+ GChecksum *checksum; /* Calcul de l'empreinte */
GBinContentIface *iface; /* Interface utilisée */
- iface = G_BIN_CONTENT_GET_IFACE(content);
+ checksum = g_object_get_data(G_OBJECT(content), "checksum");
+
+ if (checksum == NULL)
+ {
+ checksum = g_checksum_new(G_CHECKSUM_SHA256);
+ assert(checksum != NULL);
+
+ g_checksum_reset(checksum);
+
+ iface = G_BIN_CONTENT_GET_IFACE(content);
- return iface->get_checksum(content);
+ iface->compute_checksum(content, checksum);
+
+ g_object_set_data_full(G_OBJECT(content), "checksum", checksum, (GDestroyNotify)g_checksum_free);
+
+ }
+
+ result = g_checksum_get_string(checksum);
+
+ return result;
}
diff --git a/src/analysis/content.h b/src/analysis/content.h
index 1a61cb7..f1e5bbf 100644
--- a/src/analysis/content.h
+++ b/src/analysis/content.h
@@ -64,7 +64,7 @@ const char *g_binary_content_describe(const GBinContent *, bool);
bool g_binary_content_save(const GBinContent *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *);
/* Fournit une empreinte unique (SHA256) pour les données. */
-const gchar *g_binary_content_get_cheksum(GBinContent *);
+const gchar *g_binary_content_get_checksum(GBinContent *);
/* Détermine le nombre d'octets lisibles. */
phys_t g_binary_content_compute_size(const GBinContent *);
diff --git a/src/analysis/contents/file.c b/src/analysis/contents/file.c
index 8416348..95cfd5d 100644
--- a/src/analysis/contents/file.c
+++ b/src/analysis/contents/file.c
@@ -24,7 +24,6 @@
#include "file.h"
-#include <assert.h>
#include <fcntl.h>
#include <malloc.h>
#include <string.h>
@@ -49,9 +48,6 @@ struct _GFileContent
bin_t *data; /* Contenu binaire représenté */
mrange_t range; /* Couverture du binaire */
- GChecksum *checksum; /* Calcul de l'empreinte */
- bool cs_computed; /* Calcul effectué ? */
-
};
/* Contenu de données binaires issues d'un fichier (classe) */
@@ -84,7 +80,7 @@ static const char *g_file_content_describe(const GFileContent *, bool);
static bool g_file_content_save(const GFileContent *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *);
/* Fournit une empreinte unique (SHA256) pour les données. */
-static const gchar *g_file_content_get_checksum(GFileContent *);
+static void g_file_content_compute_checksum(GFileContent *, GChecksum *);
/* Détermine le nombre d'octets lisibles. */
static phys_t g_file_content_compute_size(const GFileContent *);
@@ -161,10 +157,6 @@ static void g_file_content_class_init(GFileContentClass *klass)
static void g_file_content_init(GFileContent *content)
{
- content->checksum = g_checksum_new(G_CHECKSUM_SHA256);
- assert(content->checksum != NULL);
-
- content->cs_computed = false;
}
@@ -187,7 +179,7 @@ static void g_file_content_interface_init(GBinContentInterface *iface)
iface->save = (save_content_fc)g_file_content_save;
- iface->get_checksum = (get_checksum_fc)g_file_content_get_checksum;
+ iface->compute_checksum = (compute_checksum_fc)g_file_content_compute_checksum;
iface->compute_size = (compute_size_fc)g_file_content_compute_size;
@@ -220,8 +212,6 @@ static void g_file_content_interface_init(GBinContentInterface *iface)
static void g_file_content_dispose(GFileContent *content)
{
- g_checksum_free(content->checksum);
-
G_OBJECT_CLASS(g_file_content_parent_class)->dispose(G_OBJECT(content));
}
@@ -444,29 +434,20 @@ static bool g_file_content_save(const GFileContent *content, xmlDocPtr xdoc, xml
/******************************************************************************
* *
-* Paramètres : content = contenu binaire à venir lire. *
+* Paramètres : content = contenu binaire à venir lire. *
+* checksum = empreinte de zone mémoire à compléter. *
* *
-* Description : Fournit une empreinte unique (SHA256) pour les données. *
+* Description : Calcule une empreinte unique (SHA256) pour les données. *
* *
-* Retour : Chaîne représentant l'empreinte du contenu binaire. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static const gchar *g_file_content_get_checksum(GFileContent *content)
+static void g_file_content_compute_checksum(GFileContent *content, GChecksum *checksum)
{
- if (!content->cs_computed)
- {
- g_checksum_reset(content->checksum);
-
- g_checksum_update(content->checksum, content->data, get_mrange_length(&content->range));
-
- content->cs_computed = true;
-
- }
-
- return g_checksum_get_string(content->checksum);
+ g_checksum_update(checksum, content->data, get_mrange_length(&content->range));
}
diff --git a/src/analysis/contents/restricted.c b/src/analysis/contents/restricted.c
index a8f1763..e342242 100644
--- a/src/analysis/contents/restricted.c
+++ b/src/analysis/contents/restricted.c
@@ -66,6 +66,9 @@ static void g_restricted_content_dispose(GRestrictedContent *);
/* Procède à la libération totale de la mémoire. */
static void g_restricted_content_finalize(GRestrictedContent *);
+/* Calcule une empreinte unique (SHA256) pour les données. */
+static void g_restricted_content_compute_checksum(GRestrictedContent *, GChecksum *);
+
/* Donne accès à une portion des données représentées. */
static const bin_t *g_restricted_content_get_raw_access(const GRestrictedContent *, vmpa2t *, phys_t);
@@ -156,6 +159,8 @@ static void g_restricted_content_init(GRestrictedContent *content)
static void g_restricted_content_interface_init(GBinContentInterface *iface)
{
+ iface->compute_checksum = (compute_checksum_fc)g_restricted_content_compute_checksum;
+
iface->get_raw_access = (get_raw_access_fc)g_restricted_content_get_raw_access;
iface->read_raw = (read_raw_fc)g_restricted_content_read_raw;
@@ -242,6 +247,43 @@ GBinContent *g_restricted_content_new(GBinContent *content, const mrange_t *rang
/******************************************************************************
* *
+* Paramètres : content = contenu binaire à venir lire. *
+* checksum = empreinte de zone mémoire à compléter. *
+* *
+* Description : Calcule une empreinte unique (SHA256) pour les données. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_restricted_content_compute_checksum(GRestrictedContent *content, GChecksum *checksum)
+{
+ vmpa2t start; /* Point de départ */
+ phys_t i; /* Boucle de parcours */
+ vmpa2t iter; /* Tête de lecture */
+ const bin_t *byte; /* Octet de données à intégrer */
+
+ copy_vmpa(&start, get_mrange_addr(&content->range));
+
+ for (i = 0; i < get_mrange_length(&content->range); i++)
+ {
+ copy_vmpa(&iter, &start);
+ advance_vmpa(&iter, i);
+
+ byte = g_binary_content_get_raw_access(G_BIN_CONTENT(content->internal), &iter, 1);
+
+ if (byte != NULL)
+ g_checksum_update(checksum, byte, 1);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : content = contenu binaire à venir lire. *
* addr = position de la tête de lecture. *
* length = quantité d'octets à lire. *
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index 1499064..7c16dd1 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -691,7 +691,7 @@ void disassemble_binary(GLoadedBinary *binary, GArchInstruction **instrs, GCodeB
format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
content = g_binary_format_get_content(format);
- checksum = g_binary_content_get_cheksum(content);
+ checksum = g_binary_content_get_checksum(content);
g_object_unref(G_OBJECT(content));
build_disass_prologue(*buffer, g_binary_content_describe(content, true), checksum);
diff --git a/src/analysis/project.c b/src/analysis/project.c
index 1a73e74..bf78a49 100644
--- a/src/analysis/project.c
+++ b/src/analysis/project.c
@@ -528,7 +528,7 @@ GBinContent *g_study_project_find_binary_content_by_hash(GStudyProject *project,
for (i = 0; i < project->contents_count && result == NULL; i++)
{
iter = project->contents[i].content;
- other = g_binary_content_get_cheksum(iter);
+ other = g_binary_content_get_checksum(iter);
if (strcmp(hash, other) == 0)
{
diff --git a/tests/analysis/contents/checksum.py b/tests/analysis/contents/checksum.py
new file mode 100644
index 0000000..ba09a3f
--- /dev/null
+++ b/tests/analysis/contents/checksum.py
@@ -0,0 +1,67 @@
+#!/usr/bin/python3-dbg
+# -*- coding: utf-8 -*-
+
+
+# Tests validant le bon calcul d'empreintes.
+
+
+from chrysacase import ChrysalideTestCase
+from pychrysalide.analysis.contents import FileContent, RestrictedContent
+from pychrysalide.arch import vmpa, mrange
+import hashlib
+import tempfile
+
+
+class TestRestrictedContent(ChrysalideTestCase):
+ """TestCase for analysis.contents.RestrictedContent."""
+
+ @classmethod
+ def setUpClass(cls):
+
+ super(TestRestrictedContent, cls).setUpClass()
+
+ cls._out = tempfile.NamedTemporaryFile()
+
+ cls._out.write(b'AAAABBBBCCCCDDDD')
+
+ cls._out.flush()
+
+ cls.log('Using temporary file "%s"' % cls._out.name)
+
+
+ @classmethod
+ def tearDownClass(cls):
+
+ super(TestRestrictedContent, cls).tearDownClass()
+
+ cls.log('Delete file "%s"' % cls._out.name)
+
+ cls._out.close()
+
+
+ def testFullChecksum(self):
+ """Check checksum of full content."""
+
+ fcnt = FileContent(self._out.name)
+ self.assertIsNotNone(fcnt)
+
+ expected = hashlib.sha256(b'AAAABBBBCCCCDDDD').hexdigest()
+
+ self.assertEqual(fcnt.get_checksum(), expected)
+
+
+ def testPartialChecksum(self):
+ """Check checksum of restricted content."""
+
+ fcnt = FileContent(self._out.name)
+ self.assertIsNotNone(fcnt)
+
+ start = vmpa(4, vmpa.VMPA_NO_VIRTUAL)
+ covered = mrange(start, 4) # 'BBBB'
+
+ rcnt = RestrictedContent(fcnt, covered)
+ self.assertIsNotNone(rcnt)
+
+ expected = hashlib.sha256(b'BBBB').hexdigest()
+
+ self.assertEqual(rcnt.get_checksum(), expected)