summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/dex/dex-int.c63
1 files changed, 61 insertions, 2 deletions
diff --git a/plugins/dex/dex-int.c b/plugins/dex/dex-int.c
index 287ec7a..843db32 100644
--- a/plugins/dex/dex-int.c
+++ b/plugins/dex/dex-int.c
@@ -32,6 +32,7 @@
#include <common/endianness.h>
+#include <common/utf8.h>
#include <plugins/dalvik/pseudo/identifiers.h>
@@ -160,6 +161,14 @@ bool read_dex_string_data_item(const GDexFormat *format, vmpa2t *pos, vmpa2t *in
{
bool result; /* Bilan à retourner */
GBinContent *content; /* Contenu binaire à lire */
+ size_t consumed; /* Taille effective des données*/
+ phys_t fullsize; /* Taille complète du contenu */
+ vmpa2t old; /* Sauvegarde de position */
+ uleb128_t i; /* Boucle de parcours */
+ phys_t maxsize; /* Taille maximale d'une unité */
+ const bin_t *tmp; /* Zone de parcours temporaire */
+ size_t used; /* Quantié d'octets consommés */
+ unichar_t ch; /* Unité de code MUTF-8 */
content = G_BIN_FORMAT(format)->content;
@@ -170,8 +179,58 @@ bool read_dex_string_data_item(const GDexFormat *format, vmpa2t *pos, vmpa2t *in
if (inter != NULL)
copy_vmpa(inter, pos);
- str_data->data = g_binary_content_get_raw_access(content, pos, str_data->utf16_size);
- result = (str_data->data != NULL);
+ consumed = 0;
+
+ fullsize = g_binary_content_compute_size(content);
+
+ copy_vmpa(&old, pos);
+
+ for (i = 0; i < (str_data->utf16_size + 1) && result; i++)
+ {
+ if (i > 0)
+ {
+ copy_vmpa(pos, &old);
+ advance_vmpa(pos, consumed);
+ }
+
+ /**
+ * Théoriquement, les 4 octets maximaux pour l'encodage ne sont pas
+ * forcément tous disponibles...
+ *
+ * Il est alors possible d'obtenir une erreur pour un caractère
+ * légitime d'un octet.
+ *
+ * On borne donc la taille de la prochaine unité MUTF-8.
+ */
+
+ maxsize = fullsize - get_phy_addr(pos);
+
+ if (maxsize > 4)
+ maxsize = 4;
+
+ tmp = g_binary_content_get_raw_access(content, pos, maxsize);
+
+ ch = decode_utf8_char(tmp, maxsize, &used);
+
+ if (IS_UTF8_ERROR(ch))
+ result = false;
+
+ else
+ consumed += used;
+
+ if (i == str_data->utf16_size)
+ result = (ch == 0x0);
+
+ }
+
+ copy_vmpa(pos, &old);
+
+ if (result)
+ {
+ str_data->data = g_binary_content_get_raw_access(content, pos, consumed);
+ result = (str_data->data != NULL);
+ }
+
}
return result;