diff options
Diffstat (limited to 'src/common')
-rwxr-xr-x | src/common/Makefile.am | 1 | ||||
-rwxr-xr-x | src/common/endianness.c | 34 | ||||
-rwxr-xr-x | src/common/endianness.h | 5 | ||||
-rw-r--r-- | src/common/leb128.c | 111 | ||||
-rw-r--r-- | src/common/leb128.h | 49 |
5 files changed, 199 insertions, 1 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 7aa255e..f8e4f20 100755 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -6,6 +6,7 @@ libcommon_la_SOURCES = \ endianness.h endianness.c \ environment.h environment.c \ extstr.h extstr.c \ + leb128.h leb128.c \ macros.h \ xml.h xml.c diff --git a/src/common/endianness.c b/src/common/endianness.c index 32bb65a..5c9b183 100755 --- a/src/common/endianness.c +++ b/src/common/endianness.c @@ -25,8 +25,42 @@ +/****************************************************************************** +* * +* 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. * +* low = position éventuelle des 4 bits visés. [OUT] * +* endian = ordre des bits dans la source. * +* * +* Description : Lit un nombre non signé sur 4 bits. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_u4(uint8_t *target, const bin_t *data, off_t *pos, off_t len, bool *low, SourceEndian endian) +{ + if ((len - *pos) < 1) return false; + + if (*low) + { + *target = data[*pos] & 0x0f; + *low = false; + } + else + { + *target = (data[*pos] & 0xf0) >> 4; + *low = true; + *pos += 1; + } + return true; +} /****************************************************************************** diff --git a/src/common/endianness.h b/src/common/endianness.h index f9d421e..f729ac5 100755 --- a/src/common/endianness.h +++ b/src/common/endianness.h @@ -26,7 +26,6 @@ #include <stdbool.h> -#include <sys/types.h> #include "../arch/archbase.h" @@ -43,6 +42,9 @@ typedef enum _SourceEndian } SourceEndian; +/* Lit un nombre non signé sur 4 bits. */ +bool read_u4(uint8_t *, const bin_t *, off_t *, off_t, bool *, SourceEndian); + /* Lit un nombre non signé sur un octet. */ bool read_u8(uint8_t *, const bin_t *, off_t *, off_t, SourceEndian); @@ -56,6 +58,7 @@ bool read_u32(uint32_t *, const bin_t *, off_t *, off_t, SourceEndian); bool read_u64(uint64_t *, const bin_t *, off_t *, off_t, SourceEndian); +#define read_s4(target, data, pos, len, low, endian) read_u4((uint8_t *)target, data, pos, len, low, endian) #define read_s8(target, data, pos, len, endian) read_u8((uint8_t *)target, data, pos, len, endian) #define read_s16(target, data, pos, len, endian) read_u16((uint16_t *)target, data, pos, len, endian) #define read_s32(target, data, pos, len, endian) read_u32((uint32_t *)target, data, pos, len, endian) diff --git a/src/common/leb128.c b/src/common/leb128.c new file mode 100644 index 0000000..4a03797 --- /dev/null +++ b/src/common/leb128.c @@ -0,0 +1,111 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * leb128.c - support des valeurs encodées au format LEB128. + * + * 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/>. + */ + + +#include "leb128.h" + + + +/****************************************************************************** +* * +* 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. * +* * +* Description : Lit un nombre non signé encodé au format LEB128. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_uleb128(uleb128_t *target, const bin_t *data, off_t *pos, off_t len) +{ + int shift; /* Décallage à appliquer */ + off_t i; /* Boucle de parcours */ + + shift = 0; + *target = 0; + + for (i = 0; i < 8; i++) + { + /* On évite les débordements... */ + if (*pos >= len) return false; + + *target |= (data[*pos] & 0x7f) << shift; + + shift += 7; + (*pos)++; + + if ((data[*pos - 1] & 0x80) == 0x00) break; + + } + + return (i < 8); + +} + + +/****************************************************************************** +* * +* 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. * +* * +* Description : Lit un nombre signé encodé au format LEB128. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_leb128(leb128_t *target, const bin_t *data, off_t *pos, off_t len) +{ + int shift; /* Décallage à appliquer */ + off_t i; /* Boucle de parcours */ + + shift = 0; + *target = 0; + + for (i = 0; i < 8; i++) + { + /* On évite les débordements... */ + if (*pos >= len) return false; + + *target |= (data[*pos] & 0x7f) << shift; + + shift += 7; + + if ((data[(*pos)++] & 0x80) == 0x00) break; + + } + + if (shift < (8 * sizeof(int64_t)) && (data[*pos - 1] & 0x40) == 0x40) + *target |= - (1 << shift); + + return (i < 8); + +} diff --git a/src/common/leb128.h b/src/common/leb128.h new file mode 100644 index 0000000..0364cf7 --- /dev/null +++ b/src/common/leb128.h @@ -0,0 +1,49 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * leb128.h - prototypes pour le support des valeurs encodées au format LEB128. + * + * 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_LEB128_H +#define _COMMON_LEB128_H + + +#include <stdbool.h> + + +#include "../arch/archbase.h" + + + +/* Nouveaux types */ +typedef uint64_t uleb128_t; +typedef int64_t leb128_t; + + + +/* Lit un nombre non signé encodé au format LEB128. */ +bool read_uleb128(uleb128_t *, const bin_t *, off_t *, off_t); + +/* Lit un nombre signé encodé au format LEB128. */ +bool read_leb128(leb128_t *, const bin_t *, off_t *, off_t); + + + +#endif /* _COMMON_LEB128_H */ |