summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rwxr-xr-xsrc/common/Makefile.am1
-rw-r--r--src/common/cpp.h45
-rwxr-xr-xsrc/common/endianness.c197
-rwxr-xr-xsrc/common/endianness.h12
4 files changed, 255 insertions, 0 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index f8e4f20..c883e02 100755
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -2,6 +2,7 @@
lib_LTLIBRARIES = libcommon.la
libcommon_la_SOURCES = \
+ cpp.h \
dllist.h dllist.c \
endianness.h endianness.c \
environment.h environment.c \
diff --git a/src/common/cpp.h b/src/common/cpp.h
new file mode 100644
index 0000000..b5e09c0
--- /dev/null
+++ b/src/common/cpp.h
@@ -0,0 +1,45 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * cpp.h - prototypes pour avoir à disposition un langage C plus plus mieux
+ *
+ * Copyright (C) 2010 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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 _COMMON_CPP_H
+#define _COMMON_CPP_H
+
+
+#include <limits.h>
+#include <string.h>
+
+
+
+/**
+ * Détermine la taille de la plus longue chaîne de caractères
+ * correspondant à un type donné.
+ */
+
+#define XSTR(e) STR(e)
+#define STR(e) #e
+
+#define SIZE_T_MAXLEN strlen(XSTR(LONG_MAX))
+
+
+
+#endif /* _COMMON_CPP_H */
diff --git a/src/common/endianness.c b/src/common/endianness.c
index 5a14e1c..0b7e192 100755
--- a/src/common/endianness.c
+++ b/src/common/endianness.c
@@ -24,6 +24,9 @@
#include "endianness.h"
+#include <stdarg.h>
+
+
/******************************************************************************
* *
@@ -318,3 +321,197 @@ bool read_u64(uint64_t *target, const bin_t *data, off_t *pos, off_t len, Source
return true;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : target = lieu d'enregistrement de la lecture. [OUT] *
+* data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* endian = ordre des bits dans la source. *
+* *
+* Description : Lit un nombre hexadécimal non signé sur deux octets. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool strtou8(uint8_t *target, const char *data, size_t *pos, size_t len, SourceEndian endian)
+{
+ size_t i; /* Boucle de parcours */
+
+ if (*pos < 0) return false;
+ if ((len - *pos) < 2) return false;
+
+ *target = 0;
+
+ for (i = 0; i < 2; i++)
+ switch (data[*pos + i])
+ {
+ case '0' ... '9':
+ *target |= ((data[*pos + i] - '0') << (4 * (1 - i)));
+ break;
+
+ case 'A' ... 'F':
+ *target |= ((data[*pos + i] + 10 - 'A') << (4 * (1 - i)));
+ break;
+
+ case 'a' ... 'f':
+ *target |= ((data[*pos + i] + 10 - 'a') << (4 * (1 - i)));
+ break;
+
+ }
+
+ *pos += 2;
+
+ return true;
+
+}
+
+
+
+/******************************************************************************
+* *
+* Paramètres : n = nombre d'octets constituant le nombre à lire. *
+* data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* endian = ordre des bits dans la source. *
+* ... = lieu d'enregistrement de la lecture. [OUT] *
+* *
+* Description : Lit un nombre hexadécimal non signé sur n octets. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool _strtoun(uint8_t n, const char *data, size_t *pos, size_t len, SourceEndian endian, ...)
+{
+ bool result; /* Bilan à renvoyer */
+ va_list ap; /* Arguments variables */
+ uint8_t *target8; /* Enregistrement sur 8 bits */
+ uint16_t *target16; /* Enregistrement sur 16 bits */
+ uint32_t *target32; /* Enregistrement sur 32 bits */
+ uint64_t *target64; /* Enregistrement sur 64 bits */
+ uint8_t i; /* Boucle de parcours #1 */
+ size_t j; /* Boucle de parcours #2 */
+ uint8_t tmp; /* Valeur temporaire de 8 bits */
+
+ if (*pos < 0) return false;
+ if ((len - *pos) < (n * 2)) return false;
+
+ /* Récupération de la destination */
+
+ va_start(ap, endian);
+
+ switch (n)
+ {
+ case 1:
+ target8 = va_arg(ap, uint8_t *);
+ *target8 = 0;
+ target64 = (uint64_t *)target8;
+ break;
+ case 2:
+ target16 = va_arg(ap, uint16_t *);
+ *target16 = 0;
+ target64 = (uint64_t *)target16;
+ break;
+ case 4:
+ target32 = va_arg(ap, uint32_t *);
+ *target32 = 0;
+ target64 = (uint64_t *)target32;
+ break;
+ case 8:
+ target64 = va_arg(ap, uint64_t *);
+ *target64 = 0ull;
+ break;
+ default:
+ va_end(ap);
+ return false;
+ break;
+ }
+
+ va_end(ap);
+
+ /* Lecture des données */
+
+ result = true;
+
+ for (i = 0; i < n && result; i++)
+ {
+ tmp = 0;
+
+ for (j = 0; j < 2 && result; j++)
+ switch (data[*pos + j])
+ {
+ case '0' ... '9':
+ tmp |= ((data[*pos + j] - '0') << (4 * (1 - j)));
+ break;
+
+ case 'A' ... 'F':
+ tmp |= ((data[*pos + j] + 10 - 'A') << (4 * (1 - j)));
+ break;
+
+ case 'a' ... 'f':
+ tmp |= ((data[*pos + j] + 10 - 'a') << (4 * (1 - j)));
+ break;
+
+ default:
+ printf(" string :: '%s'\n", &data[*pos + j]);
+ result = false;
+ break;
+
+ }
+
+ *pos += 2;
+
+ switch (endian)
+ {
+ case SRE_LITTLE:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+ *target64 |= ((uint64_t)tmp) << (8 * i);
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+ *target64 |= ((uint64_t)tmp) << (8 * (n - 1 - i));
+
+#else
+
+# error "TODO : PDP !"
+
+#endif
+
+ break;
+
+ case SRE_BIG:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+ *target64 |= ((uint64_t)tmp) << (8 * (n - 1 - i));
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+ *target64 |= ((uint64_t)tmp) << (8 * i);
+
+#else
+
+# error "TODO : PDP !"
+
+#endif
+
+ break;
+
+ }
+
+ }
+
+ return result;
+
+}
diff --git a/src/common/endianness.h b/src/common/endianness.h
index f729ac5..0664d6a 100755
--- a/src/common/endianness.h
+++ b/src/common/endianness.h
@@ -65,5 +65,17 @@ bool read_u64(uint64_t *, const bin_t *, off_t *, off_t, SourceEndian);
#define read_s64(target, data, pos, len, endian) read_u64((uint64_t *)target, data, pos, len, endian)
+/* Lit un nombre hexadécimal non signé sur deux octets. */
+bool strtou8(uint8_t *, const char *, size_t *, size_t, SourceEndian);
+
+
+
+/* Lit un nombre hexadécimal non signé sur n octets. */
+bool _strtoun(uint8_t, const char *, size_t *, size_t, SourceEndian, ...);
+
+
+#define strtou32(target, data, pos, len, endian) _strtoun(4, data, pos, len, endian, target)
+
+
#endif /* _COMMON_ENDIANNESS_H */