| 43 | } |
| 44 | |
| 45 | void *fake_dlopen(const char *libpath, int flags) { |
| 46 | FILE *maps; |
| 47 | char buff[256]; |
| 48 | struct ctx *ctx = 0; |
| 49 | off_t load_addr, size; |
| 50 | int k, fd = -1, found = 0; |
| 51 | intptr_t shoff; |
| 52 | Elf_Ehdr *elf = (Elf_Ehdr *) MAP_FAILED; |
| 53 | |
| 54 | |
| 55 | maps = fopen("/proc/self/maps", "r"); |
| 56 | if (!maps) goto err_exit; |
| 57 | |
| 58 | while (!found && fgets(buff, sizeof(buff), maps)) |
| 59 | if (strstr(buff, "r-xp") && strstr(buff, libpath)) found = 1; |
| 60 | |
| 61 | fclose(maps); |
| 62 | |
| 63 | if (!found) goto err_exit; |
| 64 | |
| 65 | if (sscanf(buff, "%lx", &load_addr) != 1) |
| 66 | goto err_exit; |
| 67 | |
| 68 | /* Now, mmap the same library once again */ |
| 69 | |
| 70 | fd = open(libpath, O_RDONLY); |
| 71 | if (fd < 0) goto err_exit; |
| 72 | |
| 73 | size = lseek(fd, 0, SEEK_END); |
| 74 | if (size <= 0) goto err_exit; |
| 75 | |
| 76 | elf = (Elf_Ehdr *) mmap(0, size, PROT_READ, MAP_SHARED, fd, 0); |
| 77 | close(fd); |
| 78 | fd = -1; |
| 79 | |
| 80 | if (elf == MAP_FAILED) goto err_exit; |
| 81 | |
| 82 | ctx = (struct ctx *) calloc(1, sizeof(struct ctx)); |
| 83 | if (!ctx) goto err_exit; |
| 84 | |
| 85 | ctx->load_addr = (intptr_t) load_addr; |
| 86 | shoff = (intptr_t) elf + elf->e_shoff; |
| 87 | |
| 88 | for (k = 0; k < elf->e_shnum; k++, shoff += elf->e_shentsize) { |
| 89 | |
| 90 | Elf_Shdr *sh = (Elf_Shdr *) shoff; |
| 91 | switch (sh->sh_type) { |
| 92 | |
| 93 | case SHT_DYNSYM: |
| 94 | /* .dynsym */ |
| 95 | ctx->dynsym = malloc(sh->sh_size); |
| 96 | if (!ctx->dynsym) goto err_exit; |
| 97 | memcpy(ctx->dynsym, (const void *) ((intptr_t) elf + sh->sh_offset), sh->sh_size); |
| 98 | ctx->nsyms = (sh->sh_size / sizeof(Elf_Sym)); |
| 99 | break; |
| 100 | |
| 101 | case SHT_STRTAB: |
| 102 | if (ctx->dynstr) break; /* .dynstr is guaranteed to be the first STRTAB */ |
nothing calls this directly
no test coverage detected