diff options
Diffstat (limited to 'src/analysis')
20 files changed, 1324 insertions, 64 deletions
diff --git a/src/analysis/scan/core.c b/src/analysis/scan/core.c index da3cf00..6316a53 100644 --- a/src/analysis/scan/core.c +++ b/src/analysis/scan/core.c @@ -46,13 +46,14 @@ #include "patterns/modifiers/hex.h" #include "patterns/modifiers/plain.h" #include "patterns/modifiers/rev.h" +#include "patterns/modifiers/xor.h" /* Liste des modificateurs disponibles */ typedef struct _available_modifier_t { - char *name; /* Désignation humaine */ + sized_string_t name; /* Désignation humaine */ GScanTokenModifier *instance; /* Mécanisme correspondant */ } available_modifier_t; @@ -76,18 +77,19 @@ static size_t __modifiers_count = 0; bool register_scan_token_modifier(GScanTokenModifier *modifier) { bool result; /* Bilan à retourner */ - char *name; /* Nom donné au modificateur */ + sized_string_t name; /* Nom donné au modificateur */ GScanTokenModifier *found; /* Alternative présente */ available_modifier_t *last; /* Emplacement disponible */ - name = g_scan_token_modifier_get_name(modifier); + name.data = g_scan_token_modifier_get_name(modifier); + name.len = strlen(name.data); - found = find_scan_token_modifiers_for_name(name); + found = find_scan_token_modifiers_for_name(&name); result = (found == NULL); if (!result) - free(name); + exit_szstr(&name); else { @@ -137,6 +139,7 @@ bool load_all_known_scan_token_modifiers(void) if (result) result = REGISTER_SCAN_MODIFIER(g_scan_hex_modifier_new()); if (result) result = REGISTER_SCAN_MODIFIER(g_scan_plain_modifier_new()); if (result) result = REGISTER_SCAN_MODIFIER(g_scan_reverse_modifier_new()); + if (result) result = REGISTER_SCAN_MODIFIER(g_scan_xor_modifier_new()); return result; @@ -160,7 +163,10 @@ void unload_all_scan_token_modifiers(void) size_t i; /* Boucle de parcours */ for (i = 0; i < __modifiers_count; i++) + { + exit_szstr(&__modifiers[i].name); g_object_unref(G_OBJECT(__modifiers[i].instance)); + } if (__modifiers != NULL) free(__modifiers); @@ -180,7 +186,7 @@ void unload_all_scan_token_modifiers(void) * * ******************************************************************************/ -GScanTokenModifier *find_scan_token_modifiers_for_name(const char *name) +GScanTokenModifier *find_scan_token_modifiers_for_name(const sized_string_t *name) { GScanTokenModifier *result; /* Instance à renvoyer */ size_t i; /* Boucle de parcours */ @@ -192,7 +198,10 @@ GScanTokenModifier *find_scan_token_modifiers_for_name(const char *name) { registered = __modifiers + i; - if (strcmp(registered->name, name) == 0) + if (registered->name.len != name->len) + continue; + + if (strncmp(registered->name.data, name->data, name->len) == 0) { result = registered->instance; g_object_ref(G_OBJECT(result)); diff --git a/src/analysis/scan/core.h b/src/analysis/scan/core.h index 86a47da..8a18a75 100644 --- a/src/analysis/scan/core.h +++ b/src/analysis/scan/core.h @@ -40,7 +40,7 @@ bool load_all_known_scan_token_modifiers(void); void unload_all_scan_token_modifiers(void); /* Fournit le modificateur correspondant à un nom. */ -GScanTokenModifier *find_scan_token_modifiers_for_name(const char *); +GScanTokenModifier *find_scan_token_modifiers_for_name(const sized_string_t *); /* Inscrit les principales fonctions dans l'espace racine. */ bool populate_main_scan_namespace(GScanNamespace *); diff --git a/src/analysis/scan/grammar.y b/src/analysis/scan/grammar.y index 741b394..c63dda7 100644 --- a/src/analysis/scan/grammar.y +++ b/src/analysis/scan/grammar.y @@ -40,6 +40,7 @@ typedef void *yyscan_t; #include "exprs/setcounter.h" #include "exprs/relational.h" #include "exprs/strop.h" +#include "patterns/customizer.h" #include "patterns/modifier.h" #include "patterns/modifiers/list.h" #include "patterns/tokens/hex.h" @@ -80,6 +81,7 @@ typedef void *yyscan_t; GSearchPattern *pattern; /* Nouveau motif à considérer */ GScanTokenModifier *modifier; /* Modificateur pour texte */ + modifier_arg_t mod_arg; /* Argument pour modificateur */ ScanPlainNodeFlags str_flags; /* Fanions pour texte */ @@ -255,6 +257,8 @@ YY_DECL; %type <modifier> chained_modifiers %type <modifier> mod_stage %type <modifier> modifier +%type <modifier> modifier_args +%type <mod_arg> modifier_arg %type <str_flags> str_flags @@ -512,9 +516,9 @@ YY_DECL; { $$ = $1; } - | chained_modifiers + | "(" chained_modifiers ")" { - $$ = $1; + $$ = $2; } ; @@ -550,7 +554,7 @@ YY_DECL; modifier : NAME { - $$ = find_scan_token_modifiers_for_name($1.data); + $$ = find_scan_token_modifiers_for_name(&$1); if ($$ == NULL) { char *_msg; @@ -567,9 +571,71 @@ YY_DECL; YYERROR; } } - | "(" chained_modifiers ")" + | NAME "(" modifier_args ")" { - $$ = $2; + GScanTokenModifier *_mod; + bool _status; + + $$ = $3; + + _mod = find_scan_token_modifiers_for_name(&$1); + if (_mod == NULL) + { + char *_msg; + int _ret; + + _ret = asprintf(&_msg, _("Unknown modifier: \"%.*s\""), (int)$1.len, $1.data); + + if (_ret != -1) + { + raise_error(_msg); + free(_msg); + } + + g_object_unref(G_OBJECT($$)); + + YYERROR; + } + + _status = g_scan_token_customizer_attach_modifier(G_SCAN_TOKEN_CUSTOMIZER($$), _mod); + if (!_status) + { + char *_msg; + int _ret; + + _ret = asprintf(&_msg, + _("Unsupported argument for modifier: \"%.*s\""), + (int)$1.len, $1.data); + if (_ret != -1) + { + raise_error(_msg); + free(_msg); + } + + g_object_unref(G_OBJECT($$)); + + YYERROR; + } + + } + ; + + + modifier_args : modifier_arg + { + $$ = g_scan_token_customizer_new(&$1); + } + | modifier_args "," modifier_arg + { + $$ = $1; + g_scan_token_customizer_add_extra_arg(G_SCAN_TOKEN_CUSTOMIZER($$), &$3); + } + ; + + modifier_arg : PLAIN_TEXT + { + $$.type = MAT_STRING; + $$.value.string = $1; } ; diff --git a/src/analysis/scan/patterns/Makefile.am b/src/analysis/scan/patterns/Makefile.am index c3d0994..c520321 100644 --- a/src/analysis/scan/patterns/Makefile.am +++ b/src/analysis/scan/patterns/Makefile.am @@ -5,6 +5,9 @@ noinst_LTLIBRARIES = libanalysisscanpatterns.la libanalysisscanpatterns_la_SOURCES = \ backend-int.h \ backend.h backend.c \ + customizer-int.h \ + customizer.h customizer.c \ + modarg.h \ modifier-int.h \ modifier.h modifier.c \ token-int.h \ diff --git a/src/analysis/scan/patterns/customizer-int.h b/src/analysis/scan/patterns/customizer-int.h new file mode 100644 index 0000000..9d49ab6 --- /dev/null +++ b/src/analysis/scan/patterns/customizer-int.h @@ -0,0 +1,58 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * customizer-int.h - prototypes internes pour la 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_SCAN_CUSTOMIZER_INT_H +#define _ANALYSIS_SCAN_CUSTOMIZER_INT_H + + +#include "customizer.h" +#include "modifier-int.h" + + + +/* Encadrement de transformation paramétrée d'une séquence d'octets (instance) */ +struct _GScanTokenCustomizer +{ + GScanTokenModifier parent; /* A laisser en premier */ + + GScanTokenModifier *effective; /* Modificateur effectif */ + + modifier_arg_t *args; /* Paramètres de transformation*/ + size_t count; /* Quantité de ces paramètres */ + +}; + +/* Encadrement de transformation paramétrée d'une séquence d'octets (classe) */ +struct _GScanTokenCustomizerClass +{ + GScanTokenModifierClass parent; /* A laisser en premier */ + +}; + + +/* Met en place un encadrement de transformation de motifs. */ +bool g_scan_token_customizer_create(GScanTokenCustomizer *, const modifier_arg_t *); + + + +#endif /* _ANALYSIS_SCAN_CUSTOMIZER_INT_H */ diff --git a/src/analysis/scan/patterns/customizer.c b/src/analysis/scan/patterns/customizer.c new file mode 100644 index 0000000..59065aa --- /dev/null +++ b/src/analysis/scan/patterns/customizer.c @@ -0,0 +1,374 @@ + +/* 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 <http://www.gnu.org/licenses/>. + */ + + +#include "customizer.h" + + +#include <malloc.h> + + +#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équence 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 */ + 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; + + new = (*dest) + *dcount; + + *dcount += extra_count; + *dest = realloc(*dest, *dcount * sizeof(sized_binary_t)); + + 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; + +} diff --git a/src/analysis/scan/patterns/customizer.h b/src/analysis/scan/patterns/customizer.h new file mode 100644 index 0000000..845d9ff --- /dev/null +++ b/src/analysis/scan/patterns/customizer.h @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * customizer.h - prototypes pour la 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_SCAN_CUSTOMIZER_H +#define _ANALYSIS_SCAN_CUSTOMIZER_H + + +#include <glib-object.h> +#include <stdbool.h> + + +#include "modifier.h" + + + +#define G_TYPE_SCAN_TOKEN_CUSTOMIZER g_scan_token_customizer_get_type() +#define G_SCAN_TOKEN_CUSTOMIZER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_TOKEN_CUSTOMIZER, GScanTokenCustomizer)) +#define G_IS_SCAN_TOKEN_CUSTOMIZER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_TOKEN_CUSTOMIZER)) +#define G_SCAN_TOKEN_CUSTOMIZER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_TOKEN_CUSTOMIZER, GScanTokenCustomizerClass)) +#define G_IS_SCAN_TOKEN_CUSTOMIZER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_TOKEN_CUSTOMIZER)) +#define G_SCAN_TOKEN_CUSTOMIZER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_TOKEN_CUSTOMIZER, GScanTokenCustomizerClass)) + + +/* Encadrement de transformation paramétrée d'une séquence d'octets (instance) */ +typedef struct _GScanTokenCustomizer GScanTokenCustomizer; + +/* Encadrement de transformation paramétrée d'une séquence d'octets (classe) */ +typedef struct _GScanTokenCustomizerClass GScanTokenCustomizerClass; + + +/* Indique le type défini pour une transformation personnalisée d'une séquence d'octets. */ +GType g_scan_token_customizer_get_type(void); + +/* Construit un encadrement de transformation de motifs. */ +GScanTokenModifier *g_scan_token_customizer_new(const modifier_arg_t *); + +/* Ajoute un argument à l'encadrement de transformation. */ +void g_scan_token_customizer_add_extra_arg(GScanTokenCustomizer *, const modifier_arg_t *); + +/* Définit le transformateur effectif pour les motifs. */ +bool g_scan_token_customizer_attach_modifier(GScanTokenCustomizer *, GScanTokenModifier *); + + + +#endif /* _ANALYSIS_SCAN_CUSTOMIZER_H */ diff --git a/src/analysis/scan/patterns/modarg.h b/src/analysis/scan/patterns/modarg.h new file mode 100644 index 0000000..d96e137 --- /dev/null +++ b/src/analysis/scan/patterns/modarg.h @@ -0,0 +1,91 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * modarg.h - prototypes pour la conservation d'arguments pour modificateurs + * + * 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_SCAN_MODARG_H +#define _ANALYSIS_SCAN_MODARG_H + + +#include <stdbool.h> + + +#include "../../../common/szstr.h" + + + +/* Types d'arguments pris en charge */ +typedef enum _ModifierArgType +{ + MAT_BOOLEAN, /* Valeur booléenne */ + MAT_SIGNED_INTEGER, /* Nombre entier 64 bits #1 */ + MAT_UNSIGNED_INTEGER, /* Nombre entier 64 bits #2 */ + MAT_STRING, /* Chaîne de caractères */ + MAT_RANGE, /* Séquence d'entiers */ + +} ModifierArgType; + +/* Argument pour modificateur de motif */ +typedef struct _modifier_arg_t +{ + ModifierArgType type; /* Type de valeur portée */ + + union + { + bool boolean; /* Valeur booléenne */ + long long s_integer; /* Valeur entière 64 bits */ + unsigned long long u_integer; /* Valeur entière 64 bits */ + sized_string_t string; /* Chaîne de caractères */ + + struct + { + long long start; /* Point de départ */ + long long end; /* Point d'arrivée */ + + } range; + + } value; + +} modifier_arg_t; + + +#define exit_mod_arg(a) \ + do \ + { \ + if ((a)->type == MAT_STRING) \ + exit_szstr(&(a)->value.string); \ + } \ + while (0) + +#define copy_mod_arg(d, s) \ + do \ + { \ + (d)->type = (s)->type; \ + if ((s)->type == MAT_STRING) \ + szstrdup(&(d)->value.string, &(s)->value.string); \ + else \ + *(d) = *(s); \ + } \ + while (0) + + + +#endif /* _ANALYSIS_SCAN_MODARG_H */ diff --git a/src/analysis/scan/patterns/modifier-int.h b/src/analysis/scan/patterns/modifier-int.h index 246c139..e1de2d8 100644 --- a/src/analysis/scan/patterns/modifier-int.h +++ b/src/analysis/scan/patterns/modifier-int.h @@ -33,7 +33,13 @@ typedef char * (* get_scan_modifier_name_fc) (const GScanTokenModifier *); /* Transforme une séquence d'octets pour motif de recherche. */ -typedef bool (* transform_scan_token_fc) (const GScanTokenModifier *, const sized_binary_t *, sized_binary_t **, size_t *); +typedef bool (* transform_scan_token_fc) (const GScanTokenModifier *, const sized_binary_t *, size_t, sized_binary_t **, size_t *); + +/* Détermine si un argument est bien toléré par un modificateur. */ +typedef bool (* can_token_modifier_handle_arg) (const GScanTokenModifier *, const modifier_arg_t *); + +/* Transforme une séquence d'octets pour motif de recherche. */ +typedef bool (* transform_scan_token_with_fc) (const GScanTokenModifier *, const sized_binary_t *, size_t, const modifier_arg_t *, sized_binary_t **, size_t *); /* Transformation d'une séquence d'octets en une ou plusieurs autres formes (instance) */ @@ -51,6 +57,8 @@ struct _GScanTokenModifierClass get_scan_modifier_name_fc get_name; /* Fourniture du nom d'appel */ transform_scan_token_fc transform; /* Opération de transformation */ + can_token_modifier_handle_arg can_handle; /* Support d'argument donné */ + transform_scan_token_with_fc transform_with; /* Opération encadrée */ }; diff --git a/src/analysis/scan/patterns/modifier.c b/src/analysis/scan/patterns/modifier.c index 77d8bfd..4f041b1 100644 --- a/src/analysis/scan/patterns/modifier.c +++ b/src/analysis/scan/patterns/modifier.c @@ -156,8 +156,9 @@ char *g_scan_token_modifier_get_name(const GScanTokenModifier *modifier) * * * Paramètres : modifier = modificateur à solliciter. * * src = séquence d'octets à traiter. * +* scount = quantité de ces séquences. * * dest = nouvelle(s) séquence(s) d'octets obtenue(s) [OUT] * -* count = quantité de ces séquences. * +* dcount = quantité de ces séquences. * * * * Description : Transforme une séquence d'octets pour motif de recherche. * * * @@ -167,14 +168,83 @@ char *g_scan_token_modifier_get_name(const GScanTokenModifier *modifier) * * ******************************************************************************/ -bool g_scan_token_modifier_transform(const GScanTokenModifier *modifier, const sized_binary_t *src, sized_binary_t **dest, size_t *count) +bool g_scan_token_modifier_transform(const GScanTokenModifier *modifier, const sized_binary_t *src, size_t scount, sized_binary_t **dest, size_t *dcount) { bool result; /* Bilan d'opération à renvoyer*/ GScanTokenModifierClass *class; /* Classe à activer */ class = G_SCAN_TOKEN_MODIFIER_GET_CLASS(modifier); - result = class->transform(modifier, src, dest, count); + result = class->transform(modifier, src, scount, dest, dcount); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : modifier = modificateur à solliciter. * +* arg = argument de personnalisation. * +* * +* Description : Détermine si un argument est bien toléré par un modificateur.* +* * +* Retour : Bilan de la consultation : support ou non. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_scan_token_modifier_can_handle_arg(const GScanTokenModifier *modifier, const modifier_arg_t *arg) +{ + bool result; /* Bilan d'opération à renvoyer*/ + GScanTokenModifierClass *class; /* Classe à activer */ + + class = G_SCAN_TOKEN_MODIFIER_GET_CLASS(modifier); + + if (class->can_handle == NULL) + result = false; + else + result = class->can_handle(modifier, arg); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : modifier = modificateur à solliciter. * +* src = séquence d'octets à traiter. * +* scount = quantité de ces séquences. * +* arg = argument de personnalisation. * +* 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 : - * +* * +******************************************************************************/ + +bool g_scan_token_modifier_transform_with_arg(const GScanTokenModifier *modifier, const sized_binary_t *src, size_t scount, const modifier_arg_t *arg, sized_binary_t **dest, size_t *dcount) +{ + bool result; /* Bilan d'opération à renvoyer*/ + GScanTokenModifierClass *class; /* Classe à activer */ + + result = false; + + if (!g_scan_token_modifier_can_handle_arg(modifier, arg)) + goto exit; + + class = G_SCAN_TOKEN_MODIFIER_GET_CLASS(modifier); + + if (class->transform_with != NULL) + result = class->transform_with(modifier, src, scount, arg, dest, dcount); + + exit: return result; diff --git a/src/analysis/scan/patterns/modifier.h b/src/analysis/scan/patterns/modifier.h index a195ca8..ce2589a 100644 --- a/src/analysis/scan/patterns/modifier.h +++ b/src/analysis/scan/patterns/modifier.h @@ -29,6 +29,8 @@ #include <stdbool.h> + +#include "modarg.h" #include "../../../common/szstr.h" @@ -55,7 +57,13 @@ GType g_scan_token_modifier_get_type(void); char *g_scan_token_modifier_get_name(const GScanTokenModifier *); /* Transforme une séquence d'octets pour motif de recherche. */ -bool g_scan_token_modifier_transform(const GScanTokenModifier *, const sized_binary_t *, sized_binary_t **, size_t *); +bool g_scan_token_modifier_transform(const GScanTokenModifier *, const sized_binary_t *, size_t, sized_binary_t **, size_t *); + +/* Détermine si un argument est bien toléré par un modificateur. */ +bool g_scan_token_modifier_can_handle_arg(const GScanTokenModifier *, const modifier_arg_t *); + +/* Transforme une séquence d'octets pour motif de recherche. */ +bool g_scan_token_modifier_transform_with_arg(const GScanTokenModifier *, const sized_binary_t *, size_t, const modifier_arg_t *, sized_binary_t **, size_t *); diff --git a/src/analysis/scan/patterns/modifiers/Makefile.am b/src/analysis/scan/patterns/modifiers/Makefile.am index fe5263c..f66393e 100644 --- a/src/analysis/scan/patterns/modifiers/Makefile.am +++ b/src/analysis/scan/patterns/modifiers/Makefile.am @@ -7,7 +7,8 @@ libanalysisscanpatternsmodifiers_la_SOURCES = \ list-int.h \ list.h list.c \ plain.h plain.c \ - rev.h rev.c + rev.h rev.c \ + xor.h xor.c libanalysisscanpatternsmodifiers_la_CFLAGS = $(LIBGOBJ_CFLAGS) diff --git a/src/analysis/scan/patterns/modifiers/hex.c b/src/analysis/scan/patterns/modifiers/hex.c index cf1583c..da992df 100644 --- a/src/analysis/scan/patterns/modifiers/hex.c +++ b/src/analysis/scan/patterns/modifiers/hex.c @@ -56,7 +56,7 @@ static void g_scan_hex_modifier_finalize(GScanHexModifier *); static char *g_scan_hex_modifier_get_name(const GScanHexModifier *); /* Transforme une séquence d'octets pour motif de recherche. */ -static bool g_scan_hex_modifier_transform(const GScanHexModifier *, const sized_binary_t *, sized_binary_t **, size_t *); +static bool g_scan_hex_modifier_transform(const GScanHexModifier *, const sized_binary_t *, size_t, sized_binary_t **, size_t *); @@ -212,8 +212,9 @@ static char *g_scan_hex_modifier_get_name(const GScanHexModifier *modifier) * * * Paramètres : modifier = modificateur à solliciter. * * src = séquence d'octets à traiter. * +* scount = quantité de ces séquences. * * dest = nouvelle(s) séquence(s) d'octets obtenue(s) [OUT] * -* count = quantité de ces séquences. * +* dcount = quantité de ces séquences. * * * * Description : Transforme une séquence d'octets pour motif de recherche. * * * @@ -223,28 +224,36 @@ static char *g_scan_hex_modifier_get_name(const GScanHexModifier *modifier) * * ******************************************************************************/ -static bool g_scan_hex_modifier_transform(const GScanHexModifier *modifier, const sized_binary_t *src, sized_binary_t **dest, size_t *count) +static bool g_scan_hex_modifier_transform(const GScanHexModifier *modifier, const sized_binary_t *src, size_t scount, sized_binary_t **dest, size_t *dcount) { bool result; /* Bilan d'opération à renvoyer*/ sized_binary_t *binary; /* Raccourci vers le stockage */ - size_t i; /* Boucle de parcours */ + size_t i; /* Boucle de parcours #1 */ + const sized_binary_t *_src; /* SOurce courante */ + size_t k; /* Boucle de parcours #2 */ static char *alphabet = "0123456789abcdef"; result = true; - *dest = malloc(1 * sizeof(sized_binary_t)); - *count = 1; + *dcount = scount; + *dest = malloc(*dcount * sizeof(sized_binary_t)); binary = &(*dest)[0]; - binary->len = src->len * 2; - binary->data = malloc(binary->len); - - for (i = 0; i < src->len; i++) + for (i = 0; i < scount; i++, binary++) { - binary->data[i * 2 + 0] = alphabet[src->data[i] >> 4]; - binary->data[i * 2 + 1] = alphabet[src->data[i] & 0xf]; + _src = src + i; + + binary->len = _src->len * 2; + binary->data = malloc(binary->len); + + for (k = 0; k < _src->len; k++) + { + binary->data[k * 2 + 0] = alphabet[_src->data[k] >> 4]; + binary->data[k * 2 + 1] = alphabet[_src->data[k] & 0xf]; + } + } return result; diff --git a/src/analysis/scan/patterns/modifiers/list.c b/src/analysis/scan/patterns/modifiers/list.c index 141fa54..5bf0faa 100644 --- a/src/analysis/scan/patterns/modifiers/list.c +++ b/src/analysis/scan/patterns/modifiers/list.c @@ -56,7 +56,7 @@ static void g_scan_modifier_list_finalize(GScanModifierList *); static char *g_scan_modifier_list_get_name(const GScanModifierList *); /* Transforme une séquence d'octets pour motif de recherche. */ -static bool g_scan_modifier_list_transform(const GScanModifierList *, const sized_binary_t *, sized_binary_t **, size_t *); +static bool g_scan_modifier_list_transform(const GScanModifierList *, const sized_binary_t *, size_t, sized_binary_t **, size_t *); @@ -345,8 +345,9 @@ static char *g_scan_modifier_list_get_name(const GScanModifierList *modifier) * * * Paramètres : modifier = modificateur à solliciter. * * src = séquence d'octets à traiter. * +* scount = quantité de ces séquences. * * dest = nouvelle(s) séquence(s) d'octets obtenue(s) [OUT] * -* count = quantité de ces séquences. * +* dcount = quantité de ces séquences. * * * * Description : Transforme une séquence d'octets pour motif de recherche. * * * @@ -356,7 +357,7 @@ static char *g_scan_modifier_list_get_name(const GScanModifierList *modifier) * * ******************************************************************************/ -static bool g_scan_modifier_list_transform(const GScanModifierList *modifier, const sized_binary_t *src, sized_binary_t **dest, size_t *count) +static bool g_scan_modifier_list_transform(const GScanModifierList *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 */ @@ -366,17 +367,17 @@ static bool g_scan_modifier_list_transform(const GScanModifierList *modifier, co size_t k; /* Boucle de parcours #2 */ *dest = NULL; - *count = 0; + *dcount = 0; for (i = 0; i < modifier->count; i++) { - result = g_scan_token_modifier_transform(modifier->modifiers[i], src, &extra, &extra_count); + result = g_scan_token_modifier_transform(modifier->modifiers[i], src, scount, &extra, &extra_count); if (!result) goto exit; - new = (*dest) + *count; + new = (*dest) + *dcount; - *count += extra_count; - *dest = realloc(*dest, *count * sizeof(sized_binary_t)); + *dcount += extra_count; + *dest = realloc(*dest, *dcount * sizeof(sized_binary_t)); for (k = 0; k < extra_count; k++, new++) copy_szstr(*new, extra[k]); @@ -389,14 +390,14 @@ static bool g_scan_modifier_list_transform(const GScanModifierList *modifier, co if (!result) { - for (i = 0; i < *count; i++) + for (i = 0; i < *dcount; i++) exit_szstr(dest[i]); if (*dest != NULL) free(*dest); *dest = NULL; - *count = 0; + *dcount = 0; } diff --git a/src/analysis/scan/patterns/modifiers/plain.c b/src/analysis/scan/patterns/modifiers/plain.c index 5837d46..485bb23 100644 --- a/src/analysis/scan/patterns/modifiers/plain.c +++ b/src/analysis/scan/patterns/modifiers/plain.c @@ -56,7 +56,7 @@ static void g_scan_plain_modifier_finalize(GScanPlainModifier *); static char *g_scan_plain_modifier_get_name(const GScanPlainModifier *); /* Transforme une séquence d'octets pour motif de recherche. */ -static bool g_scan_plain_modifier_transform(const GScanPlainModifier *, const sized_binary_t *, sized_binary_t **, size_t *); +static bool g_scan_plain_modifier_transform(const GScanPlainModifier *, const sized_binary_t *, size_t, sized_binary_t **, size_t *); @@ -212,8 +212,9 @@ static char *g_scan_plain_modifier_get_name(const GScanPlainModifier *modifier) * * * Paramètres : modifier = modificateur à solliciter. * * src = séquence d'octets à traiter. * +* scount = quantité de ces séquences. * * dest = nouvelle(s) séquence(s) d'octets obtenue(s) [OUT] * -* count = quantité de ces séquences. * +* dcount = quantité de ces séquences. * * * * Description : Transforme une séquence d'octets pour motif de recherche. * * * @@ -223,22 +224,30 @@ static char *g_scan_plain_modifier_get_name(const GScanPlainModifier *modifier) * * ******************************************************************************/ -static bool g_scan_plain_modifier_transform(const GScanPlainModifier *modifier, const sized_binary_t *src, sized_binary_t **dest, size_t *count) +static bool g_scan_plain_modifier_transform(const GScanPlainModifier *modifier, const sized_binary_t *src, size_t scount, sized_binary_t **dest, size_t *dcount) { bool result; /* Bilan d'opération à renvoyer*/ sized_binary_t *binary; /* Raccourci vers le stockage */ + size_t i; /* Boucle de parcours */ + const sized_binary_t *_src; /* SOurce courante */ result = true; - *dest = malloc(1 * sizeof(sized_binary_t)); - *count = 1; + *dcount = scount; + *dest = malloc(*dcount * sizeof(sized_binary_t)); binary = &(*dest)[0]; - binary->len = src->len; - binary->data = malloc(binary->len); + for (i = 0; i < scount; i++, binary++) + { + _src = src + i; - memcpy(binary->data, src->data, src->len); + binary->len = _src->len; + binary->data = malloc(binary->len); + + memcpy(binary->data, _src->data, _src->len); + + } return result; diff --git a/src/analysis/scan/patterns/modifiers/rev.c b/src/analysis/scan/patterns/modifiers/rev.c index d22b549..8b931bd 100644 --- a/src/analysis/scan/patterns/modifiers/rev.c +++ b/src/analysis/scan/patterns/modifiers/rev.c @@ -56,7 +56,7 @@ static void g_scan_reverse_modifier_finalize(GScanReverseModifier *); static char *g_scan_reverse_modifier_get_name(const GScanReverseModifier *); /* Transforme une séquence d'octets pour motif de recherche. */ -static bool g_scan_reverse_modifier_transform(const GScanReverseModifier *, const sized_binary_t *, sized_binary_t **, size_t *); +static bool g_scan_reverse_modifier_transform(const GScanReverseModifier *, const sized_binary_t *, size_t, sized_binary_t **, size_t *); @@ -212,8 +212,9 @@ static char *g_scan_reverse_modifier_get_name(const GScanReverseModifier *modifi * * * Paramètres : modifier = modificateur à solliciter. * * src = séquence d'octets à traiter. * +* scount = quantité de ces séquences. * * dest = nouvelle(s) séquence(s) d'octets obtenue(s) [OUT] * -* count = quantité de ces séquences. * +* dcount = quantité de ces séquences. * * * * Description : Transforme une séquence d'octets pour motif de recherche. * * * @@ -223,24 +224,32 @@ static char *g_scan_reverse_modifier_get_name(const GScanReverseModifier *modifi * * ******************************************************************************/ -static bool g_scan_reverse_modifier_transform(const GScanReverseModifier *modifier, const sized_binary_t *src, sized_binary_t **dest, size_t *count) +static bool g_scan_reverse_modifier_transform(const GScanReverseModifier *modifier, const sized_binary_t *src, size_t scount, sized_binary_t **dest, size_t *dcount) { bool result; /* Bilan d'opération à renvoyer*/ sized_binary_t *binary; /* Raccourci vers le stockage */ - size_t i; /* Boucle de parcours */ + size_t i; /* Boucle de parcours #1 */ + const sized_binary_t *_src; /* SOurce courante */ + size_t k; /* Boucle de parcours #2 */ result = true; - *dest = malloc(1 * sizeof(sized_binary_t)); - *count = 1; + *dcount = scount; + *dest = malloc(*dcount * sizeof(sized_binary_t)); binary = &(*dest)[0]; - binary->len = src->len; - binary->data = malloc(binary->len); + for (i = 0; i < scount; i++, binary++) + { + _src = src + i; - for (i = 0; i < src->len; i++) - binary->data[src->len - i - 1] = src->data[i]; + binary->len = _src->len; + binary->data = malloc(binary->len); + + for (k = 0; k < _src->len; k++) + binary->data[_src->len - k - 1] = _src->data[k]; + + } return result; diff --git a/src/analysis/scan/patterns/modifiers/xor.c b/src/analysis/scan/patterns/modifiers/xor.c new file mode 100644 index 0000000..65194ab --- /dev/null +++ b/src/analysis/scan/patterns/modifiers/xor.c @@ -0,0 +1,395 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * xor.c - transormation via opération XOR + * + * 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 <http://www.gnu.org/licenses/>. + */ + + +#include "xor.h" + + +#include <assert.h> +#include <malloc.h> +#include <stdint.h> +#include <string.h> + + +#include "../modifier-int.h" + + + +/* ----------------------- RECHERCHE D'UN MOTIF DE TEXTE BRUT ----------------------- */ + + +/* Initialise la classe des transmissions via opération XOR. */ +static void g_scan_xor_modifier_class_init(GScanXorModifierClass *klass); + +/* Initialise une instance de transmission via opération XOR. */ +static void g_scan_xor_modifier_init(GScanXorModifier *); + +/* Supprime toutes les références externes. */ +static void g_scan_xor_modifier_dispose(GScanXorModifier *); + +/* Procède à la libération totale de la mémoire. */ +static void g_scan_xor_modifier_finalize(GScanXorModifier *); + + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Fournit le nom d'appel d'un modificateur pour motif. */ +static char *g_scan_xor_modifier_get_name(const GScanXorModifier *); + +/* Transforme une séquence d'octets pour motif de recherche. */ +static bool g_scan_xor_modifier_transform(const GScanXorModifier *, const sized_binary_t *, size_t, sized_binary_t **, size_t *); + +/* Détermine si un argument est bien toléré par un modificateur. */ +static bool g_scan_xor_modifier_can_handle_arg(const GScanXorModifier *, const modifier_arg_t *); + +/* Transforme une séquence d'octets pour motif de recherche. */ +static bool g_scan_xor_modifier_transform_with_arg(const GScanXorModifier *, const sized_binary_t *, size_t, const modifier_arg_t *, sized_binary_t **, size_t *); + + + +/* ---------------------------------------------------------------------------------- */ +/* RECHERCHE D'UN MOTIF DE TEXTE BRUT */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour une transormation via une opération XOR. */ +G_DEFINE_TYPE(GScanXorModifier, g_scan_xor_modifier, G_TYPE_SCAN_TOKEN_MODIFIER); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des transmissions via opération XOR. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_scan_xor_modifier_class_init(GScanXorModifierClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GScanTokenModifierClass *modifier; /* Version de classe parente */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_xor_modifier_dispose; + object->finalize = (GObjectFinalizeFunc)g_scan_xor_modifier_finalize; + + modifier = G_SCAN_TOKEN_MODIFIER_CLASS(klass); + + modifier->get_name = (get_scan_modifier_name_fc)g_scan_xor_modifier_get_name; + + modifier->transform = (transform_scan_token_fc)g_scan_xor_modifier_transform; + modifier->can_handle = (can_token_modifier_handle_arg)g_scan_xor_modifier_can_handle_arg; + modifier->transform_with = (transform_scan_token_with_fc)g_scan_xor_modifier_transform_with_arg; + +} + + +/****************************************************************************** +* * +* Paramètres : modifier = instance à initialiser. * +* * +* Description : Initialise une instance de transmission via opération XOR. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_scan_xor_modifier_init(GScanXorModifier *modifier) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : modifier = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_scan_xor_modifier_dispose(GScanXorModifier *modifier) +{ + G_OBJECT_CLASS(g_scan_xor_modifier_parent_class)->dispose(G_OBJECT(modifier)); + +} + + +/****************************************************************************** +* * +* Paramètres : modifier = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_scan_xor_modifier_finalize(GScanXorModifier *modifier) +{ + G_OBJECT_CLASS(g_scan_xor_modifier_parent_class)->finalize(G_OBJECT(modifier)); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Construit un modificateur livrant des octets traités par XOR.* +* * +* Retour : Mécanisme mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GScanTokenModifier *g_scan_xor_modifier_new(void) +{ + GScanTokenModifier *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_SCAN_XOR_MODIFIER, NULL); + + 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_xor_modifier_get_name(const GScanXorModifier *modifier) +{ + char *result; /* Désignation à retourner */ + + result = strdup("xor"); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : modifier = modificateur à solliciter. * +* src = séquence 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_xor_modifier_transform(const GScanXorModifier *modifier, const sized_binary_t *src, size_t scount, sized_binary_t **dest, size_t *dcount) +{ + bool result; /* Bilan d'opération à renvoyer*/ + sized_binary_t *binary; /* Raccourci vers le stockage */ + size_t i; /* Boucle de parcours #1 */ + const sized_binary_t *_src; /* SOurce courante */ + long long x; /* Boucle de parcours #2 */ + size_t k; /* Boucle de parcours #3 */ + + result = true; + + *dcount = scount * 256; + *dest = malloc(*dcount * sizeof(sized_binary_t)); + + binary = &(*dest)[0]; + + for (i = 0; i < scount; i++) + { + _src = src + i; + + for (x = 0; x <= 0xff; x++, binary++) + { + binary->len = _src->len; + binary->data = malloc(binary->len); + + for (k = 0; k < _src->len; k++) + binary->data[k] = _src->data[k] ^ x; + + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : modifier = modificateur à solliciter. * +* arg = argument de personnalisation. * +* * +* Description : Détermine si un argument est bien toléré par un modificateur.* +* * +* Retour : Bilan de la consultation : support ou non. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_scan_xor_modifier_can_handle_arg(const GScanXorModifier *modifier, const modifier_arg_t *arg) +{ + bool result; /* Bilan d'opération à renvoyer*/ + + switch (arg->type) + { + case MAT_UNSIGNED_INTEGER: + result = (arg->value.u_integer <= UINT8_MAX); + break; + + case MAT_RANGE: + result = (INT8_MIN <= arg->value.range.start && arg->value.range.end <= INT8_MAX); + break; + + default: + result = false; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : modifier = modificateur à solliciter. * +* src = séquence d'octets à traiter. * +* scount = quantité de ces séquences. * +* arg = argument de personnalisation. * +* 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_xor_modifier_transform_with_arg(const GScanXorModifier *modifier, const sized_binary_t *src, size_t scount, const modifier_arg_t *arg, sized_binary_t **dest, size_t *dcount) +{ + bool result; /* Bilan d'opération à renvoyer*/ + sized_binary_t *binary; /* Raccourci vers le stockage */ + size_t i; /* Boucle de parcours #1 */ + const sized_binary_t *_src; /* SOurce courante */ + long long x; /* Boucle de parcours #2 */ + size_t k; /* Boucle de parcours #3 */ + + result = true; + + switch (arg->type) + { + case MAT_UNSIGNED_INTEGER: + + *dcount = scount; + *dest = malloc(*dcount * sizeof(sized_binary_t)); + + binary = &(*dest)[0]; + + for (i = 0; i < scount; i++) + { + _src = src + i; + + binary->len = _src->len; + binary->data = malloc(binary->len); + + for (k = 0; k < _src->len; k++) + binary->data[k] = _src->data[k] ^ arg->value.u_integer; + + } + + break; + + case MAT_RANGE: + + *dcount = scount * (arg->value.range.end - arg->value.range.start + 1); + *dest = malloc(*dcount * sizeof(sized_binary_t)); + + binary = &(*dest)[0]; + + for (i = 0; i < scount; i++) + { + _src = src + i; + + for (x = arg->value.range.start; x <= arg->value.range.end; x++, binary++) + { + binary->len = _src->len; + binary->data = malloc(binary->len); + + for (k = 0; k < _src->len; k++) + binary->data[k] = _src->data[k] ^ x; + + } + + } + + break; + + default: + assert(false); + result = false; + + } + + return result; + +} diff --git a/src/analysis/scan/patterns/modifiers/xor.h b/src/analysis/scan/patterns/modifiers/xor.h new file mode 100644 index 0000000..1a3e7e6 --- /dev/null +++ b/src/analysis/scan/patterns/modifiers/xor.h @@ -0,0 +1,58 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * xor.h - prototypes pour la transormation via opération XOR + * + * 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_SCAN_PATTERNS_MODIFIERS_XOR_H +#define _ANALYSIS_SCAN_PATTERNS_MODIFIERS_XOR_H + + +#include <glib-object.h> + + +#include "../modifier.h" + + + +#define G_TYPE_SCAN_XOR_MODIFIER g_scan_xor_modifier_get_type() +#define G_SCAN_XOR_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_XOR_MODIFIER, GScanXorModifier)) +#define G_IS_SCAN_XOR_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_XOR_MODIFIER)) +#define G_SCAN_XOR_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_XOR_MODIFIER, GScanXorModifierClass)) +#define G_IS_SCAN_XOR_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_XOR_MODIFIER)) +#define G_SCAN_XOR_MODIFIER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_XOR_MODIFIER, GScanXorModifierClass)) + + +/* Transormation via inversement d'une séquence d'octets (instance) */ +typedef GScanTokenModifier GScanXorModifier; + +/* Transormation via inversement d'une séquence d'octets (classe) */ +typedef GScanTokenModifierClass GScanXorModifierClass; + + +/* Indique le type défini pour une transormation via une opération XOR. */ +GType g_scan_xor_modifier_get_type(void); + +/* Construit un modificateur livrant des octets traités par XOR. */ +GScanTokenModifier *g_scan_xor_modifier_new(void); + + + +#endif /* _ANALYSIS_SCAN_PATTERNS_MODIFIERS_XOR_H */ diff --git a/src/analysis/scan/patterns/tokens/nodes/plain.c b/src/analysis/scan/patterns/tokens/nodes/plain.c index 5a7f976..5d89cf8 100644 --- a/src/analysis/scan/patterns/tokens/nodes/plain.c +++ b/src/analysis/scan/patterns/tokens/nodes/plain.c @@ -344,7 +344,7 @@ static bool g_scan_token_node_plain_enroll(GScanTokenNodePlain *node, GScanConte } else - result = g_scan_token_modifier_transform(node->modifier, &node->orig, &node->raw, &node->count); + result = g_scan_token_modifier_transform(node->modifier, &node->orig, 1, &node->raw, &node->count); if (!result) goto exit; diff --git a/src/analysis/scan/tokens.l b/src/analysis/scan/tokens.l index b284128..6633975 100644 --- a/src/analysis/scan/tokens.l +++ b/src/analysis/scan/tokens.l @@ -607,6 +607,32 @@ bytes_fuzzy_id [\*A-Za-z_][\*A-Za-z0-9_]* } + +<bytes>[A-Za-z_][A-Za-z0-9_]* { + yylval->sized_cstring.data = yytext; + yylval->sized_cstring.len = yyleng; + return NAME; + } + + + <bytes>"(" { return PAREN_O; } + + <bytes>")" { return PAREN_C; } + + <bytes>"," { return COMMA; } + + +<bytes>\"{str_not_escaped}+\" { + yylval->sized_cstring.data = yytext + 1; + yylval->sized_cstring.len = yyleng - 2; + + return PLAIN_TEXT; + } + + + + + %{ /* Définition de motif en hexadécimal */ %} <bytes_value>"{" { @@ -885,9 +911,9 @@ bytes_fuzzy_id [\*A-Za-z_][\*A-Za-z0-9_]* <condition>"/" { return DIV; } <condition>"%" { return MOD; } -<bytes,condition>"(" { return PAREN_O; } -<bytes,condition>")" { return PAREN_C; } -<bytes,condition>"," { return COMMA; } +<condition>"(" { return PAREN_O; } +<condition>")" { return PAREN_C; } +<condition>"," { return COMMA; } <condition>"[" { return HOOK_O; } @@ -946,7 +972,7 @@ bytes_fuzzy_id [\*A-Za-z_][\*A-Za-z0-9_]* -<bytes,condition>[A-Za-z_][A-Za-z0-9_]* { +<condition>[A-Za-z_][A-Za-z0-9_]* { yylval->sized_cstring.data = yytext; yylval->sized_cstring.len = yyleng; return NAME; |