summaryrefslogtreecommitdiff
path: root/plugins/gdbrsp/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/gdbrsp/utils.c')
-rw-r--r--plugins/gdbrsp/utils.c354
1 files changed, 354 insertions, 0 deletions
diff --git a/plugins/gdbrsp/utils.c b/plugins/gdbrsp/utils.c
new file mode 100644
index 0000000..1088e51
--- /dev/null
+++ b/plugins/gdbrsp/utils.c
@@ -0,0 +1,354 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * utils.h - fonctions qui simplifient la vie dans les interactions avec un serveur GDB
+ *
+ * Copyright (C) 2016 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 "utils.h"
+
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <sys/param.h>
+#include <sys/types.h>
+
+
+
+/******************************************************************************
+* *
+* Paramètres : data = données à inspecter. *
+* len = quantité de ces données. *
+* *
+* Description : Indique si les données correspondent à un code d'erreur. *
+* *
+* Retour : Bilan de l'analyse. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool is_error_code(const char *data, size_t len)
+{
+ bool result; /* Bilan à retourner */
+
+ result = (len == 3);
+
+ if (result)
+ result = (data[0] == 'E' && isdigit(data[1]) && isdigit(data[2]));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = données à analyser. *
+* size = taille de ces données. *
+* byte = statut de sortie d'un programme. [OUT] *
+* *
+* Description : Relit une valeur sur 8 bits et deux lettres. *
+* *
+* Retour : Bilan de la lecture. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_fixed_byte(const char *data, size_t len, uint8_t *byte)
+{
+ bool result; /* Bilan à retourner */
+ const char *iter; /* Boucle de parcours #1 */
+ size_t i; /* Boucle de parcours #2 */
+ uint8_t nibble; /* Valeur affichée */
+
+ result = true;
+
+ len = MIN(2, len);
+
+ for (i = 0, iter = data; i < len; i++, iter++)
+ {
+ switch (*iter)
+ {
+ case '0' ... '9':
+ nibble = *iter - '0';
+ break;
+
+ case 'a' ... 'f':
+ nibble = *iter - 'a' + 10;
+ break;
+
+ case 'A' ... 'F':
+ nibble = *iter - 'A' + 10;
+ break;
+
+ default:
+ result = false;
+ break;
+
+ }
+
+ if (!result)
+ break;
+
+ if (i == 0)
+ *byte = (nibble << 4);
+ else
+ *byte |= nibble;
+
+ }
+
+ if (result)
+ result = (i == 2);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : hex = tampon d'origine assez grand. *
+* size = taille de la valeur à considérer pour les travaux. *
+* value = valeur sur XX bits à transcrire. [OUT] *
+* *
+* Description : Traduit en valeur sur XX bits une forme textuelle. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool hex_to_any_u(const char *hex, size_t size, ...)
+{
+ bool result; /* Bilan à retourner */
+ va_list ap; /* Gestion de l'inconnue */
+ uint8_t *value8; /* Valeur sur 8 bits */
+ uint16_t *value16; /* Valeur sur 16 bits */
+ uint32_t *value32; /* Valeur sur 32 bits */
+ uint64_t *value64; /* Valeur sur 64 bits */
+ uint8_t *iter; /* Boucle de parcours #1 */
+ size_t i; /* Boucle de parcours #2 */
+ char nibble; /* Valeur à afficher */
+
+ result = false;
+
+ /* Récupération de la destination */
+
+ va_start(ap, size);
+
+ switch (size)
+ {
+ case 1:
+ value8 = va_arg(ap, uint8_t *);
+ iter = value8;
+ break;
+
+ case 2:
+ value16 = va_arg(ap, uint16_t *);
+ iter = (uint8_t *)value16;
+ break;
+
+ case 4:
+ value32 = va_arg(ap, uint32_t *);
+ iter = (uint8_t *)value32;
+ break;
+
+ case 8:
+ value64 = va_arg(ap, uint64_t *);
+ iter = (uint8_t *)value64;
+ break;
+
+ default:
+ goto done;
+ break;
+
+ }
+
+ /* Lecture de la valeur */
+
+ for (i = 0; i < size; i++, iter++)
+ {
+ *iter = 0;
+
+ nibble = hex[i * 2];
+
+ switch (nibble)
+ {
+ case '0' ... '9':
+ *iter = (nibble - '0') << 4;
+ break;
+
+ case 'a' ... 'f':
+ *iter = (nibble - 'a' + 0xa) << 4;
+ break;
+
+ case 'A' ... 'F':
+ *iter = (nibble - 'A' + 0xa) << 4;
+ break;
+
+ default:
+ goto done;
+ break;
+
+ }
+
+ nibble = hex[i * 2 + 1];
+
+ switch (nibble)
+ {
+ case '0' ... '9':
+ *iter |= (nibble - '0');
+ break;
+
+ case 'a' ... 'f':
+ *iter |= (nibble - 'a' + 0xa);
+ break;
+
+ case 'A' ... 'F':
+ *iter |= (nibble - 'A' + 0xa);
+ break;
+
+ default:
+ goto done;
+ break;
+
+ }
+
+ }
+
+ result = (i == size);
+
+ done:
+
+ va_end(ap);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : size = taille de la valeur à considérer pour les travaux. *
+* hex = tampon de destination assez grand. *
+* value = valeur sur XX bits à transcrire. [OUT] *
+* *
+* Description : Traduit une valeur sur XX bits en forme textuelle. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool any_u_to_hex(size_t size, char hex[17], ...)
+{
+ bool result; /* Bilan à retourner */
+ va_list ap; /* Gestion de l'inconnue */
+ uint8_t *value8; /* Valeur sur 8 bits */
+ uint16_t *value16; /* Valeur sur 16 bits */
+ uint32_t *value32; /* Valeur sur 32 bits */
+ uint64_t *value64; /* Valeur sur 64 bits */
+ size_t i; /* Boucle de parcours #1 */
+ const uint8_t *iter; /* Boucle de parcours #2 */
+ uint8_t nibble; /* Valeur à retenir */
+
+ result = true;
+
+ /* Récupération de la destination */
+
+ va_start(ap, hex);
+
+ switch (size)
+ {
+ case 1:
+ value8 = va_arg(ap, uint8_t *);
+ iter = (const uint8_t *)value8;
+ break;
+
+ case 2:
+ value16 = va_arg(ap, uint16_t *);
+ iter = (const uint8_t *)value16;
+ break;
+
+ case 4:
+ value32 = va_arg(ap, uint32_t *);
+ iter = (const uint8_t *)value32;
+ break;
+
+ case 8:
+ value64 = va_arg(ap, uint64_t *);
+ iter = (const uint8_t *)value64;
+ break;
+
+ default:
+ result = false;
+ goto done;
+ break;
+
+ }
+
+ /* Lecture de la valeur */
+
+ for (i = 0; i < size; i++, iter++)
+ {
+ nibble = (*iter & 0xf0) >> 4;
+
+ switch (nibble)
+ {
+ case 0x0 ... 0x9:
+ hex[i * 2] = '0' + nibble;
+ break;
+
+ case 0xa ... 0xf:
+ hex[i * 2] = 'A' + nibble - 0xa;
+ break;
+
+ }
+
+ nibble = (*iter & 0x0f);
+
+ switch (nibble)
+ {
+ case 0x0 ... 0x9:
+ hex[i * 2 + 1] = '0' + nibble;
+ break;
+
+ case 0xa ... 0xf:
+ hex[i * 2 + 1] = 'A' + nibble - 0xa;
+ break;
+
+ }
+
+ }
+
+ hex[size * 2] = '\0';
+
+ done:
+
+ va_end(ap);
+
+ return result;
+
+}