Неверный адрес 0x71db7cb5e0 передан бесплатно: значение не выделено

получение ошибки ниже после вызова функции free() для filepaths (free(filePaths[i]);) сразу после запуска приложения Android с minSDK=22 или выше. На minSDK=21 все ок

Неверный адрес 0x71db7cb5e0 передан бесплатно: значение не выделено Я просто хочу знать, что произойдет с Android с minSDK = 22 или выше. Распределение памяти отличается?

static inline void parse_proc_maps_to_fetch_path(char **filepaths);
JNIEXPORT jboolean JNICALL Java_io_github_inflationx_calligraphy_Calligraphy_CalligraphyInterceptor_detectFrida(JNIEnv *env, jobject obj) {

    char *filePaths[NUM_LIBS];

    globalEnv = env;
    parse_proc_maps_to_fetch_path(filePaths);
    __android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "Libc[%x][%x][%x][%x][%x][%x]", __NR_openat,
                        __NR_lseek, __NR_read, __NR_close, __NR_readlinkat, __NR_nanosleep);
    for (int i = 0; i < NUM_LIBS; i++) {
        fetch_checksum_of_library(filePaths[i], &elfSectionArr[i]);
        if (filePaths[i] != NULL)
            free(filePaths[i]);
    }
    bool result = false;
    pthread_t t;
    pthread_create(&t, NULL, (void *) detect_frida_loop, &result);
    return result;
}
__attribute__((always_inline))
static inline void parse_proc_maps_to_fetch_path(char **filepaths) {
    int fd = 0;
    char map[MAX_LINE];
    int counter = 0;
    if ((fd = my_openat(AT_FDCWD, PROC_MAPS, O_RDONLY | O_CLOEXEC, 0)) != 0) {

        while ((read_one_line(fd, map, MAX_LINE)) > 0) {
            for (int i = 0; i < NUM_LIBS; i++) {
                if (my_strstr(map, libstocheck[i]) != NULL) {
                    char tmp[MAX_LENGTH] = "";
                    char path[MAX_LENGTH] = "";
                    char buf[5] = "";
                    sscanf(map, "%s %s %s %s %s %s", tmp, buf, tmp, tmp, tmp, path);
                    if (buf[2] == 'x') {
                        size_t size = my_strlen(path) + 1;
                        filepaths[i] = malloc(size);
                        my_strlcpy(filepaths[i], path, size);
                        counter++;
                    }
                }
            }
            if (counter == NUM_LIBS)
                break;
        }
        my_close(fd);
    }
}
globalEnv = env;? Вы не можете кэшировать значение JNIEnv *env.
Andrew Henle 27.04.2024 14:21

globalEnv не используется

nima 27.04.2024 14:23

предоставленный код — единственное использование (чтение и запись) filepaths

nima 27.04.2024 14:24

Может быть, это и не связано, но что такое my_openat? Что он вернет в случае неудачи? Оно возвращается -1? Затем вы продолжите и будете использовать (неверный) дескриптор файла -1. Поскольку в этом случае чтение из файла завершится неудачно, вы завершите функцию со всеми элементами filepaths, которые не инициализированы и имеют неопределенные значения.

Some programmer dude 27.04.2024 14:28

Что касается вышеупомянутой проблемы, что произойдет, если не все элементы filepaths инициализированы? Если циклы заканчиваются раньше counter == NUM_LIBS?

Some programmer dude 27.04.2024 14:31

поставив логи после filepaths[i] = malloc(size);, я понял, что вызывается функция malloc.

nima 27.04.2024 14:35

@nima Для всех элементов?

Some programmer dude 27.04.2024 14:39
(fd = my_openat(AT_FDCWD, PROC_MAPS, O_RDONLY | O_CLOEXEC, 0)) != 0 тоже неправильно. Во-первых, не впихивайте это в if — это ужасный способ написать код, который будет идиоматическим, когда код вводился на перфокартах, а свинец помещался в бензин. Во-вторых: 0 является допустимым дескриптором файла, поэтому его нельзя использовать для обозначения ошибки.
Andrew Henle 27.04.2024 15:10
1
8
85
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В Java_io_github_inflationx_calligraphy_Calligraphy_CalligraphyInterceptor_detectFrida вы определяете filePaths, оставляя значения в массиве неинициализированными:

char *filePaths[NUM_LIBS];

В parse_proc_maps_to_fetch_path вы присваиваете значения filepaths[i] только в том случае, если какое-то условие истинно, в противном случае эти элементы остаются неинициализированными.

Кажется, вы предполагаете, что элементы filePaths будут NULL по умолчанию, чего нельзя сказать о локальной переменной в функции. Элементы filePaths не имеют определенных значений.

Чтобы исправить это, вы можете инициализировать filePaths:

char *filePaths[NUM_LIBS] = { 0 };

В качестве альтернативы вы можете структурировать parse_proc_maps_to_fetch_path таким образом, чтобы всем элементам filePaths всегда присваивались значения (NULL, когда вы не присваиваете указатель на значимую строку). Это может быть лучшим вариантом, если parse_proc_maps_to_fetch_path предназначен для «создания» массива целиком.

Другие вопросы по теме