diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2023-10-09 22:49:59 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2023-10-09 22:49:59 (GMT) |
commit | 7c6fe94c90d320813d0d78a9dbef707696f31505 (patch) | |
tree | 912b5c51469c02e6ef680c0c60739787ccff4891 /src/analysis | |
parent | cb05b99a8c451ff80d88f988e2654c794b0f3750 (diff) |
Support some last missing features from Kaitai: bit fields, instance search order and stream EOF.
Diffstat (limited to 'src/analysis')
-rw-r--r-- | src/analysis/content.c | 88 | ||||
-rw-r--r-- | src/analysis/content.h | 3 |
2 files changed, 91 insertions, 0 deletions
diff --git a/src/analysis/content.c b/src/analysis/content.c index 0560d73..e12237f 100644 --- a/src/analysis/content.c +++ b/src/analysis/content.c @@ -474,6 +474,94 @@ bool g_binary_content_read_raw(const GBinContent *content, vmpa2t *addr, phys_t /****************************************************************************** * * * Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture complète. * +* size = quantité de bits à lire. * +* endian = ordre des bits dans la source. * +* val = lieu d'enregistrement de la lecture. [OUT] * +* * +* Description : Lit un nombre non signé sur deux octets. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_content_read_bits(const GBinContent *content, ext_vmpa_t *addr, uint8_t size, SourceEndian endian, uint64_t *val) +{ + bool result; /* Bilan de lecture à renvoyer */ + vmpa2t pos; /* Tête de lecture courante */ + uint8_t data; /* Données à parcourir */ + uint8_t i; /* Boucle de parcours */ + uint8_t remaining; /* Nombre de bits disponibles */ + uint64_t bit; /* Nouveau bit à intégrer */ + + assert(addr->consumed_extra_bits < 8); + assert(size <= 64); + + if (addr->consumed_extra_bits >= 8 || size > 64) + return false; + + copy_vmpa(&pos, &addr->base); + + result = g_binary_content_read_u8(content, &pos, &data); + if (!result) goto exit; + + remaining = 8 - addr->consumed_extra_bits; + + *val = 0; + + for (i = 0; i < size; i++) + { + if (remaining == 0) + { + result = g_binary_content_read_u8(content, &pos, &data); + if (!result) goto exit; + + remaining = 8; + + } + + bit = (data >> (remaining - 1)) & 0x1; + + remaining--; + + switch (endian) + { + case SRE_LITTLE: + *val |= (bit << i); + break; + + case SRE_BIG: + *val |= (bit << (size - i - 1)); + break; + + default: + assert(false); + result = false; + break; + + } + + } + + if (result) + { + advance_vmpa(&addr->base, get_phy_addr(&pos) - get_phy_addr(&addr->base) - 1); + addr->consumed_extra_bits = 8 - remaining; + + } + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * * addr = position de la tête de lecture. * * low = position éventuelle des 4 bits visés. [OUT] * * val = lieu d'enregistrement de la lecture. [OUT] * diff --git a/src/analysis/content.h b/src/analysis/content.h index 5279890..ee79a9c 100644 --- a/src/analysis/content.h +++ b/src/analysis/content.h @@ -87,6 +87,9 @@ const bin_t *g_binary_content_get_raw_access(const GBinContent *, vmpa2t *, phys /* Fournit une portion des données représentées. */ bool g_binary_content_read_raw(const GBinContent *, vmpa2t *, phys_t, bin_t *); +/* Lit un nombre non signé sur deux octets. */ +bool g_binary_content_read_bits(const GBinContent *, ext_vmpa_t *, uint8_t, SourceEndian, uint64_t *); + /* Lit un nombre non signé sur quatre bits. */ bool g_binary_content_read_u4(const GBinContent *, vmpa2t *, bool *, uint8_t *); |