Вот такие штуки меня раздражают:
unsigned long objdump_address()
{
FILE *command = popen("objdump -d /bin/su|grep '<exit@plt>' ........
if (!command) {
perror("[-] popen");
return 0;
}
char result[32];
fgets(result, 32, command);
pclose(command);
return strtoul(result, NULL, 16);
}
Можно заменить на вот такую жуть ;-)
uint64_t get_elf_symbol(char *filename)
{
uint64_t ret = 0;
int h = open(filename, 0);
if (h < 0)
return 0;
int l = lseek(h, 0, 2);
if (l <= sizeof(Elf64_Ehdr))
goto _error_close;
uint8_t *m = mmap(NULL, l, PROT_READ, MAP_SHARED, h, 0);
if (m == MAP_FAILED)
goto _error_close;
if (*(uint64_t*)m != 0x00010102464c457f)
goto _error_unmap;
Elf64_Ehdr *ehdr = (Elf64_Ehdr*)m;
if ((ehdr->e_phoff + ehdr->e_phnum * sizeof(Elf64_Phdr)) > l)
goto _error_unmap;
if ((ehdr->e_shoff + ehdr->e_shnum * sizeof(Elf64_Shdr)) > l)
goto _error_unmap;
if (ehdr->e_shstrndx > ehdr->e_shnum)
goto _error_unmap;
Elf64_Shdr *shdr = (Elf64_Shdr*)(m + ehdr->e_shoff);
char *strtab = (char*)(m + shdr[ehdr->e_shstrndx].sh_offset);
Elf64_Rel *rel = NULL, *r;
Elf64_Sym *sym = NULL;
char *str = NULL, *plt = NULL;
int i, plt_size = 0, rel_size = 0, rel_sz = 16;
uint64_t plt_addr = 0;
for (i = 0; i < ehdr->e_shnum; i++) {
char *sname = shdr[i].sh_name + strtab;
int stype = shdr[i].sh_type;
if ((stype == SHT_REL || stype == SHT_RELA) && strstr(sname, ".plt")) {
rel = (Elf64_Rel*)(m + shdr[i].sh_offset);
rel_size = shdr[i].sh_size;
if (shdr[i].sh_type == SHT_RELA)
rel_sz = 24;
}
if (stype == SHT_DYNSYM) {
sym = (Elf64_Sym*)(m + shdr[i].sh_offset);
str = (char*)(m + shdr[shdr[i].sh_link].sh_offset);
}
if (!strcmp(sname, ".plt")) {
plt = (char*)(m + shdr[i].sh_offset);
plt_size = shdr[i].sh_size;
plt_addr = shdr[i].sh_addr;
}
}
if (rel == NULL || sym == NULL || str == NULL || plt == NULL)
goto _error_unmap;
#define C(x, y) ((char*)x - (char*)y)
for (r = rel; C(r, rel) < rel_size; r = (Elf64_Rel*)(C(r, 0) + rel_sz))
if (! strcmp("exit", sym[ELF64_R_SYM(r->r_info)].st_name + str))
for (i = 16; i < plt_size; i += 16)
if (*((uint32_t*)(plt + i + 7)) == C(r, rel) / rel_sz) {
ret = i + plt_addr;
goto _error_unmap;
}
#undef C
_error_unmap:
munmap(m, l);
_error_close:
close(h);
return ret;
}
И там еще есть неприятность с блокирующим recv, но это уже совсем другая история.
|