Пример #1
0
static void *
read_file_to_jni_array_impl(const char *filename)
{
    char *buffer = NULL;
    size_t size = 0;

    if (apk_read_file(global.apklib_handle, filename, &buffer, &size) == APK_OK) {
        if(!global.use_dvm)
        {
            struct dummy_array *array = NULL;
            array = malloc(sizeof(*array));
            if (array == NULL)
                return NULL;
            array->data = buffer;
            array->length = size;
            array->element_size = 1;

            return array;
        }
        else
        {
            const struct JNINativeInterface *env = global._env->functions;
            jarray *array = env->NewByteArray(ENV((&global)), size);
            jbyte *elements = env->GetByteArrayElements(ENV((&global)), array, 0);
            memcpy(elements, buffer, size);
            free(buffer);
            env->ReleaseByteArrayElements(ENV((&global)), array, elements, JNI_ABORT);

            return array;
        }
    }

    return NULL;
}
Пример #2
0
static void *
read_file_to_jni_array_impl(const char *filename)
{
    struct dummy_array *array = NULL;
    char *buffer = NULL;
    size_t size = 0;

    if (apk_read_file(global.apklib_handle, filename, &buffer, &size) == APK_OK) {
        array = malloc(sizeof(*array));
        if (array == NULL)
            return NULL;
        array->data = buffer;
        array->length = size;
        array->element_size = 1;
    }

    return array;
}
Пример #3
0
static int
read_file_impl(const char *filename, char **buffer, size_t *size)
{
    return (apk_read_file(global.apklib_handle,
                filename, buffer, size) == APK_OK);
}
Пример #4
0
enum ApkResult
apk_read_resources(AndroidApk *apk, struct ResourceStrings *rstrings)
{
    char *buf, *p, *p2, *p_end;
    char *values, *keys;
    struct ResTable_header *res_table_h;
    struct ResTable_package *res_table_package;
    struct ResChunk_header *chunk;
    struct ResStringPool_header *value_pool, *key_pool;
    struct ResTable_type *res_table;
    struct ResTable_entry *entry;
    struct Res_value *value;
    int *value_index, *key_index;
    size_t rstr_i, rstr_alloc;
    enum ApkResult ret;
    size_t size;

    assert(apk != NULL && rstrings != NULL);

    ret = apk_read_file(apk, "resources.arsc", &buf, &size);
    if (ret != APK_OK) {
        fprintf(stderr, "missing/bad resources.arsc\n");
        return ret;
    }

    rstrings->count = rstr_i = 0;
    rstrings->app_name = NULL;
    rstrings->game_name = NULL;
    rstr_alloc = 32;
    rstrings->entries = malloc(rstr_alloc * sizeof(rstrings->entries[0]));
    if (rstrings->entries == NULL) {
        ret = APK_ERROR;
        goto out;
    }

    p = buf;
    res_table_h = (void *)p;
    assert(res_table_h->header.type == RES_TABLE_TYPE);
    p += res_table_h->header.headerSize;

    value_pool = (void *)p;
    assert(value_pool->header.type == RES_STRING_POOL_TYPE);
    value_index = (int *)(p + value_pool->header.headerSize);
    values = p + value_pool->stringsStart;
    p += value_pool->header.size;

    res_table_package = (void *)p;
    assert(res_table_package->header.type == RES_TABLE_PACKAGE_TYPE);
    key_pool = (void *)(p + res_table_package->keyStrings);

    p = (void *)key_pool;
    assert(key_pool->header.type == RES_STRING_POOL_TYPE);
    key_index = (int *)(p + key_pool->header.headerSize);
    keys = p + key_pool->stringsStart;
    p += key_pool->header.size;

    /* handle all ResTable chunks */
    for (; p < buf + size; p += chunk->size) {
        chunk = (void *)p;
        if (chunk->type != RES_TABLE_TYPE_TYPE)
            continue;

        res_table = (void *)p;
        p2 = p + res_table->entriesStart;
        /* res_table->entryCount is unreliable? */
        p_end = p + chunk->size;
        for (; p2 < p_end; p2 += entry->size + value->size) {
            entry = (void *)p2;
            value = (void *)(p2 + entry->size);
            if (entry->flags & ~FLAG_PUBLIC) {
                // printf("flags %x\n", entry->flags);
                break;
            }
            if (value->dataType != TYPE_STRING) {
                //printf("  type %x\n", value->dataType);
                // TODO: at least TYPE_INT_BOOLEAN might be useful
                continue;
            }
            if (entry->key.index >= key_pool->stringCount) {
                fprintf(stderr, "key index out of range: %u >= %u\n",
                        entry->key.index, key_pool->stringCount);
                break;
            }
            if (value->data >= value_pool->stringCount) {
                fprintf(stderr, "value index out of range: %u >= %u\n",
                        value->data, value_pool->stringCount);
                break;
            }
            rstrings->entries[rstr_i].key = apk_get_res_string(
                                                keys + key_index[entry->key.index], key_pool->flags & UTF8_FLAG);
            rstrings->entries[rstr_i].value = apk_get_res_string(
                                                  values + value_index[value->data], value_pool->flags & UTF8_FLAG);
            if (rstrings->app_name==NULL && strcmp(rstrings->entries[rstr_i].key, "app_name") == 0)
                rstrings->app_name = rstrings->entries[rstr_i].value;
            if (rstrings->game_name==NULL && strcmp(rstrings->entries[rstr_i].key, "game_name") == 0)
                rstrings->game_name = rstrings->entries[rstr_i].value;

            rstr_i++;
            if (rstr_i >= rstr_alloc) {
                rstr_alloc *= 2;
                rstrings->entries = realloc(rstrings->entries,
                                            rstr_alloc * sizeof(rstrings->entries[0]));
                if (rstrings->entries == NULL)
                    goto out;
            }
        }
    }
    rstrings->count = rstr_i;

out:
    free(buf);
    return ret;
}