summaryrefslogtreecommitdiff
path: root/plugins/bhash/rich.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/bhash/rich.c')
-rw-r--r--plugins/bhash/rich.c181
1 files changed, 181 insertions, 0 deletions
diff --git a/plugins/bhash/rich.c b/plugins/bhash/rich.c
new file mode 100644
index 0000000..b5bed4e
--- /dev/null
+++ b/plugins/bhash/rich.c
@@ -0,0 +1,181 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * rich.c - calculs d'empreintes relatifs aux en-têtes PE enrichis
+ *
+ * Copyright (C) 2020 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "rich.h"
+
+
+#include <format/known.h>
+#include <plugins/pe/rich.h>
+
+
+
+/******************************************************************************
+* *
+* Paramètres : format = format en place à consulter. *
+* csum = empreinte à déterminer. [OUT] *
+* *
+* Description : Calcule la valeur pour empreinte d'en-tête PE enrichi. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool compute_pe_rich_header_checksum(const GPeFormat *format, uint32_t *csum)
+{
+ bool result; /* Bilan à retourner */
+ mrange_t area; /* Zone couverte par l'en-tête */
+ GBinContent *content; /* Contenu à parcourir */
+ vmpa2t start; /* Position de départ */
+ phys_t offset; /* Position du début d'en-tête */
+ const bin_t *data; /* Données brutes à analyser */
+ phys_t i; /* Boucle de parcours #0 */
+ comp_id_t *ids; /* Identifiants à traiter */
+ size_t count; /* Quantité de ces identifiants*/
+ size_t k; /* Boucle de parcours #1 */
+
+ result = g_pe_format_get_rich_header_area(format, &area);
+
+ if (!result)
+ *csum = 0;
+
+ else
+ {
+
+#define rol32(word, shift) \
+ ((uint32_t)word) << (shift & 31) | ((uint32_t)word) >> (32 - (shift & 31))
+
+ /* Première source de calculs */
+
+ content = g_known_format_get_content(G_KNOWN_FORMAT(format));
+
+ g_binary_content_compute_start_pos(content, &start);
+
+ offset = get_phy_addr(get_mrange_addr(&area)) - get_phy_addr(&start);
+
+ *csum = offset;
+
+ data = g_binary_content_get_raw_access(content, &start, offset);
+ if (data == NULL)
+ {
+ g_object_unref(G_OBJECT(content));
+ result = false;
+ goto exit;
+ }
+
+ for (i = 0; i < offset; i++)
+ {
+ /* Saut du champ e_lfanew, non initialisé lors de la construction */
+ if (0x3c <= i && i < 0x40)
+ continue;
+
+ *csum += rol32(data[i], i);
+
+ }
+
+ g_object_unref(G_OBJECT(content));
+
+ /* Seconde source de calculs */
+
+ ids = g_pe_format_get_comp_ids(format, &count);
+
+ for (k = 0; k < count; k++)
+ *csum += rol32((ids[k].prod_id << 16) | ids[k].minor_cv, ids[k].count);
+
+ if (ids != NULL)
+ free(ids);
+
+ }
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = format en place à consulter. *
+* pv = forme d'empreinte à construire. *
+* *
+* Description : Calcule l'empreinte des informations d'en-tête PE enrichi. *
+* *
+* Retour : Empreinte MD5 calculée ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+char *compute_pe_rich_header_hash(const GPeFormat *format, bool pv)
+{
+ char *result; /* Empreinte à retourner */
+ comp_id_t *ids; /* Identifiants à traiter */
+ size_t count; /* Quantité de ces identifiants*/
+ GChecksum *checksum; /* Preneur d'empreinte */
+ size_t i; /* Boucle de parcours */
+ uint32_t value; /* Valeur à prendre en compte */
+
+ ids = g_pe_format_get_comp_ids(format, &count);
+
+ if (ids == NULL)
+ result = NULL;
+
+ else
+ {
+ checksum = g_checksum_new(G_CHECKSUM_MD5);
+
+ if (!pv)
+ {
+ g_checksum_update(checksum, "DanS", 4);
+ g_checksum_update(checksum, "\x00\x00\x00\x00", 4);
+ }
+
+ for (i = 0; i < count; i++)
+ {
+ if (pv && i == 0)
+ continue;
+
+ value = (ids[i].prod_id << 16) | ids[i].minor_cv;
+ g_checksum_update(checksum, (char *)&value, sizeof(value));
+
+ if (!pv)
+ {
+ value = ids[i].count;
+ g_checksum_update(checksum, (char *)&value, sizeof(value));
+ }
+
+ }
+
+ result = strdup(g_checksum_get_string(checksum));
+
+ g_checksum_free(checksum);
+
+ free(ids);
+
+ }
+
+ return result;
+
+}