void dot_so_finder(char *filename) {

    int file_fd;

    char *file_map;
    char *ptr;
    char *prev;
    off_t size;
    struct stat file_stat;

    file_fd = open(filename, O_RDONLY);

    fstat(file_fd, &file_stat);

    file_map = mmap(0, file_stat.st_size, PROT_READ, MAP_PRIVATE, file_fd, 0);

    ptr = file_map;
    prev = ptr;
    size = file_stat.st_size;

    while ((ptr = memmem(ptr, size, lib_ending, strlen(lib_ending))) != NULL) {

        if (ptr >= file_map + file_stat.st_size)
            break;

        if (char_is_valid(ptr - 1))
            get_full_lib_name(ptr);

        size -= ptr - prev;
        prev = ptr;

        ptr++; /* Advance pointer one character to ensure we don't keep looping
                  over the same ".so" instance over and over again */
    }

    munmap(file_map, file_stat.st_size);
    close(file_fd);
}
Example #2
0
File: str.c Project: amikoren/tnapy
int charset_is_valid(char *s)
{
    for (; s && *s && char_is_valid(*s); s++);
    return !s || !*s;
}
void get_full_lib_name(char *found_lib) {

    char *ptr, *peek;

    char full_name[256] = {0};

    long len;
    int num_chars;
    int i;

    ptr = found_lib;
    peek = ptr - 1;

    /* if there's a false-positive in finding matching ".so", but it isn't ever referencing
     * a library, it's probably just instructions that slipped through the cracks. In this case
     * we will rewind the pointer that's searching for "lib" or "egl" MAX_LIB_NAME (default 50)
     * times, in which we will bail out citing that it was probably a false-positive
     */
    for (num_chars = 0; num_chars <= MAX_LIB_NAME; num_chars++) {
        if (!strncmp(ptr, egl_beginning, strlen(egl_beginning)) || !strncmp(ptr, lib_beginning, strlen(lib_beginning))) {
            peek = ptr - 1;
            /* the peek below would fall victim to a file which is looking directly for
             * "/system/lib/lib_whatever.so", because it would now point to lib/lib_whatever.so
             * which is not what what we want, so take the first pick if the peek character is '/'
             */
            if (*peek == '/') {
                for (i = 0; blob_directories[i]; i++) {
                    if (!strncmp(peek, blob_directories[i], strlen(blob_directories[i]))) {
                        peek += strlen(blob_directories[i]);
                        ptr = peek;
                        break;
                    }
                }
                break;
            }
            /* some libraries are called "libmmcamera_wavelet_lib.so", in which the pointer will
             * rewind to the first "lib" and then will pass it over to the check_emulator_for_lib
             * method, which will in turn bark about a missing "lib.so", so we will rewind the pointer
             * some extra times until it encounters an invalid character using the char_is_valid
             * function and if it ends up finding another instance of "lib", picks that *that* one, not
             * the original one, so we will get the entire library name of "libmmcamera_wavelet_lib.so"
             * and not just "lib.so" which would have been chosen if not for the peek.
             */
            while (char_is_valid(peek) && *peek--) {
                if (!strncmp(peek, lib_beginning, strlen(lib_beginning))) {
#ifdef DEBUG
                    printf("Possible lib_lib.so! %s\n", peek);
#endif
                    ptr = peek;
                }
            }
            break;
        }
        if (num_chars == MAX_LIB_NAME) {
#ifdef DEBUG
            printf("Character limit exceeded! Full string was:\n");
            for (num_chars = 0; num_chars < MAX_LIB_NAME + strlen(lib_beginning); num_chars++) {
                printf("%c", *ptr);
                ptr++;
            }
            printf("\n");
#endif
            return;
        }
        ptr--;
        peek--;
    }
    len = (long)(found_lib + strlen(lib_beginning)) - (long)ptr;
    strncpy(full_name, ptr, len);

    check_emulator_for_lib(full_name);
}