diff options
Diffstat (limited to 'src/common')
-rwxr-xr-x | src/common/Makefile.am | 1 | ||||
-rw-r--r-- | src/common/cpp.h | 45 | ||||
-rwxr-xr-x | src/common/endianness.c | 197 | ||||
-rwxr-xr-x | src/common/endianness.h | 12 |
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 */ |