/* Chrysalide - Outil d'analyse de fichiers binaires * customizer.c - modification paramétrée d'une séquence d'octets * * Copyright (C) 2023 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 Foobar. If not, see . */ #include "customizer.h" #include #include "customizer-int.h" /* --------------------- TRANSFORMATION PERSONNALISEE DE MOTIFS --------------------- */ /* Initialise la classe des transformations paramétrée. */ static void g_scan_token_customizer_class_init(GScanTokenCustomizerClass *); /* Initialise une instance de transformation paramétrée. */ static void g_scan_token_customizer_init(GScanTokenCustomizer *); /* Supprime toutes les références externes. */ static void g_scan_token_customizer_dispose(GScanTokenCustomizer *); /* Procède à la libération totale de la mémoire. */ static void g_scan_token_customizer_finalize(GScanTokenCustomizer *); /* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ /* Fournit le nom d'appel d'un modificateur pour motif. */ static char *g_scan_token_customizer_get_name(const GScanTokenCustomizer *); /* Transforme une séquence d'octets pour motif de recherche. */ static bool g_scan_token_customizer_transform(const GScanTokenCustomizer *, const sized_binary_t *, size_t, sized_binary_t **, size_t *); /* ---------------------------------------------------------------------------------- */ /* TRANSFORMATION PERSONNALISEE DE MOTIFS */ /* ---------------------------------------------------------------------------------- */ /* Indique le type défini pour une transformation personnalisée d'une séquence d'octets. */ G_DEFINE_TYPE(GScanTokenCustomizer, g_scan_token_customizer, G_TYPE_SCAN_TOKEN_MODIFIER); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe des transformations paramétrée. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_scan_token_customizer_class_init(GScanTokenCustomizerClass *klass) { GObjectClass *object; /* Autre version de la classe */ GScanTokenModifierClass *modifier; /* Version de classe parente */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_token_customizer_dispose; object->finalize = (GObjectFinalizeFunc)g_scan_token_customizer_finalize; modifier = G_SCAN_TOKEN_MODIFIER_CLASS(klass); modifier->get_name = (get_scan_modifier_name_fc)g_scan_token_customizer_get_name; modifier->transform = (transform_scan_token_fc)g_scan_token_customizer_transform; } /****************************************************************************** * * * Paramètres : customizer = instance à initialiser. * * * * Description : Initialise une instance de transformation paramétrée. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_scan_token_customizer_init(GScanTokenCustomizer *customizer) { customizer->effective = NULL; customizer->args = NULL; customizer->count = 0; } /****************************************************************************** * * * Paramètres : customizer = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_scan_token_customizer_dispose(GScanTokenCustomizer *customizer) { g_clear_object(&customizer->effective); G_OBJECT_CLASS(g_scan_token_customizer_parent_class)->dispose(G_OBJECT(customizer)); } /****************************************************************************** * * * Paramètres : customizer = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_scan_token_customizer_finalize(GScanTokenCustomizer *customizer) { size_t i; /* Boucle de parcours */ for (i = 0; i < customizer->count; i++) exit_mod_arg(&customizer->args[i]); if (customizer->args != NULL) free(customizer->args); G_OBJECT_CLASS(g_scan_token_customizer_parent_class)->finalize(G_OBJECT(customizer)); } /****************************************************************************** * * * Paramètres : arg = premier argument pour personnaliser l'opération. * * * * Description : Construit un encadrement de transformation de motifs. * * * * Retour : Mécanisme mis en place. * * * * Remarques : - * * * ******************************************************************************/ GScanTokenModifier *g_scan_token_customizer_new(const modifier_arg_t *arg) { GScanTokenModifier *result; /* Structure à retourner */ result = g_object_new(G_TYPE_SCAN_TOKEN_CUSTOMIZER, NULL); if (!g_scan_token_customizer_create(G_SCAN_TOKEN_CUSTOMIZER(result), arg)) g_clear_object(&result); return result; } /****************************************************************************** * * * Paramètres : customizer = encadrement de motif à initialiser pleinement. * * arg = premier argument pour personnaliser l'opération.* * * * Description : Met en place un encadrement de transformation de motifs. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool g_scan_token_customizer_create(GScanTokenCustomizer *customizer, const modifier_arg_t *arg) { g_scan_token_customizer_add_extra_arg(customizer, arg); return true; } /****************************************************************************** * * * Paramètres : customizer = encadrement de motif à compléter. * * arg = nouvel argument pour personnaliser l'opération. * * * * Description : Ajoute un argument à l'encadrement de transformation. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_scan_token_customizer_add_extra_arg(GScanTokenCustomizer *customizer, const modifier_arg_t *arg) { customizer->args = realloc(customizer->args, ++customizer->count * sizeof(modifier_arg_t)); copy_mod_arg(&customizer->args[customizer->count - 1], arg); } /****************************************************************************** * * * Paramètres : customizer = encadrement de motif à compléter. * * modifier = modificateur de motifs à employer en sous-main. * * * * Description : Définit le transformateur effectif pour les motifs. * * * * Retour : true si le motificateur accepte les arguments courants. * * * * Remarques : - * * * ******************************************************************************/ bool g_scan_token_customizer_attach_modifier(GScanTokenCustomizer *customizer, GScanTokenModifier *modifier) { bool result; /* Validation à retourner */ size_t i; /* Boucle de parcours */ result = true; for (i = 0; i < customizer->count && result; i++) result = g_scan_token_modifier_can_handle_arg(modifier, &customizer->args[i]); if (!result) goto exit; customizer->effective = modifier; g_object_ref(G_OBJECT(modifier)); exit: return result; } /* ---------------------------------------------------------------------------------- */ /* IMPLEMENTATION DES FONCTIONS DE CLASSE */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * Paramètres : modifier = modificateur à consulter. * * * * Description : Fournit le nom d'appel d'un modificateur pour motif. * * * * Retour : Désignation humaine. * * * * Remarques : - * * * ******************************************************************************/ static char *g_scan_token_customizer_get_name(const GScanTokenCustomizer *modifier) { char *result; /* Désignation à retourner */ if (modifier->effective == NULL) result = NULL; else result = g_scan_token_modifier_get_name(modifier->effective); return result; } /****************************************************************************** * * * Paramètres : modifier = modificateur à solliciter. * * src = séquences d'octets à traiter. * * scount = quantité de ces séquences. * * dest = nouvelle(s) séquence(s) d'octets obtenue(s) [OUT] * * dcount = quantité de ces séquences. * * * * Description : Transforme une séquence d'octets pour motif de recherche. * * * * Retour : Bilan de l'opération : succès ou échec. * * * * Remarques : - * * * ******************************************************************************/ static bool g_scan_token_customizer_transform(const GScanTokenCustomizer *modifier, const sized_binary_t *src, size_t scount, sized_binary_t **dest, size_t *dcount) { bool result; /* Bilan d'opération à renvoyer*/ size_t i; /* Boucle de parcours #1 */ sized_binary_t *extra; /* Motifs supplémentaires */ size_t extra_count; /* Quantité de ces motifs */ size_t old_dcount; /* Mémorisation avant avancées */ sized_binary_t *new; /* Nouvel emplacement libre */ size_t k; /* Boucle de parcours #2 */ *dest = NULL; *dcount = 0; for (i = 0; i < modifier->count; i++) { result = g_scan_token_modifier_transform_with_arg(modifier->effective, src, scount, &modifier->args[i], &extra, &extra_count); if (!result) goto exit; old_dcount = *dcount; *dcount += extra_count; *dest = realloc(*dest, *dcount * sizeof(sized_binary_t)); new = (*dest) + old_dcount; for (k = 0; k < extra_count; k++, new++) copy_szstr(*new, extra[k]); free(extra); } exit: if (!result) { for (i = 0; i < *dcount; i++) exit_szstr(dest[i]); if (*dest != NULL) free(*dest); *dest = NULL; *dcount = 0; } return result; }