static int find_matching_file (struct dl_phdr_info *info, size_t size, void *data) { struct file_match *match = data; /* This code is modeled from Gfind_proc_info-lsb.c:callback() from libunwind */ long n; const ElfW(Phdr) *phdr; ElfW(Addr) load_base = info->dlpi_addr; phdr = info->dlpi_phdr; for (n = info->dlpi_phnum; --n >= 0; phdr++) { if (phdr->p_type == PT_LOAD) { ElfW(Addr) vaddr = phdr->p_vaddr + load_base; if (match->address >= vaddr && match->address < vaddr + phdr->p_memsz) { /* we found a match */ match->file = info->dlpi_name; match->base = info->dlpi_addr; return 1; } } } return 0; }
static void _dl_unprotect_relro (struct link_map *l) { ElfW(Addr) start = ((l->l_addr + l->l_relro_addr) & ~(GLRO(dl_pagesize) - 1)); ElfW(Addr) end = ((l->l_addr + l->l_relro_addr + l->l_relro_size) & ~(GLRO(dl_pagesize) - 1)); if (start != end) __mprotect ((void *) start, end - start, PROT_READ | PROT_WRITE); }
void _dl_protect_relro (struct elf_resolve *l) { ElfW(Addr) base = (ElfW(Addr)) DL_RELOC_ADDR(l->loadaddr, l->relro_addr); ElfW(Addr) start = (base & PAGE_ALIGN); ElfW(Addr) end = ((base + l->relro_size) & PAGE_ALIGN); _dl_if_debug_dprint("RELRO protecting %s: start:%x, end:%x\n", l->libname, start, end); if (start != end && _dl_mprotect ((void *) start, end - start, PROT_READ) < 0) { _dl_dprintf(2, "%s: cannot apply additional memory protection after relocation", l->libname); _dl_exit(0); } }
bool CrashInfo::GetDSOInfo() { Phdr* phdrAddr = reinterpret_cast<Phdr*>(m_auxvValues[AT_PHDR]); int phnum = m_auxvValues[AT_PHNUM]; assert(m_auxvValues[AT_PHENT] == sizeof(Phdr)); if (phnum <= 0 || phdrAddr == nullptr) { return false; } TRACE("DSO: phdr %p phnum %d\n", phdrAddr, phnum); // Search for the program PT_DYNAMIC header ElfW(Dyn)* dynamicAddr = nullptr; for (int i = 0; i < phnum; i++, phdrAddr++) { Phdr ph; if (!ReadMemory(phdrAddr, &ph, sizeof(ph))) { return false; } TRACE("DSO: phdr %p type %d (%x) vaddr %016lx memsz %016lx offset %016lx\n", phdrAddr, ph.p_type, ph.p_type, ph.p_vaddr, ph.p_memsz, ph.p_offset); if (ph.p_type == PT_DYNAMIC) { dynamicAddr = reinterpret_cast<ElfW(Dyn)*>(ph.p_vaddr); } else if (ph.p_type == PT_GNU_EH_FRAME)
static const char * elf_platform (void) { int fd; fd = open ("/proc/self/auxv", O_RDONLY); if (fd != -1) { char buf[1024]; ElfW(auxv_t) *av; ssize_t n; n = read (fd, buf, sizeof (buf)); close (fd); if (n > 0) { for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av) switch (av->a_type) { case AT_PLATFORM: return (const char *) av->a_un.a_val; default: break; } } }
void attribute_hidden _dl_tlsdesc_lazy_resolver_fixup (struct tlsdesc volatile *td, Elf32_Addr *got) { struct link_map *l = (struct link_map *)got[1]; lookup_t result; unsigned long value; if (_dl_tlsdesc_resolve_early_return_p (td, (void*)(D_PTR (l, l_info[ADDRIDX (DT_TLSDESC_PLT)]) + l->l_addr))) return; if (td->argument.value & 0x80000000) { /* A global symbol, this is the symbol index. */ /* The code below was borrowed from _dl_fixup(). */ const Elf_Symndx symndx = td->argument.value ^ 0x80000000; const ElfW(Sym) *const symtab = (const void *) D_PTR (l, l_info[DT_SYMTAB]); const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]); const ElfW(Sym) *sym = &symtab[symndx]; /* Look up the target symbol. If the normal lookup rules are not used don't look in the global scope. */ if (ELFW(ST_BIND) (sym->st_info) != STB_LOCAL && __builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0) { const struct r_found_version *version = NULL; if (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) { const ElfW(Half) *vernum = (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]); ElfW(Half) ndx = vernum[symndx] & 0x7fff; version = &l->l_versions[ndx]; if (version->hash == 0) version = NULL; } result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, l->l_scope, version, ELF_RTYPE_CLASS_PLT, DL_LOOKUP_ADD_DEPENDENCY, NULL); if (sym) value = sym->st_value; else { td->entry = _dl_tlsdesc_undefweak; goto done; } } else { /* We already found the symbol. The module (and therefore its load address) is also known. */ result = l; value = sym->st_value; } }
static int find_dynamic_entry_addr(Process *proc, void *pvAddr, int d_tag, void **addr) { int i = 0, done = 0; ElfW(Dyn) entry; debug(DEBUG_FUNCTION, "find_dynamic_entry()"); if (addr == NULL || pvAddr == NULL || d_tag < 0 || d_tag > DT_NUM) { return -1; } while ((!done) && (i < ELF_MAX_SEGMENTS) && (sizeof(entry) == umovebytes(proc, pvAddr, &entry, sizeof(entry))) && (entry.d_tag != DT_NULL)) { if (entry.d_tag == d_tag) { done = 1; *addr = (void *)entry.d_un.d_val; } pvAddr += sizeof(entry); i++; } if (done) { debug(2, "found address: 0x%p in dtag %d\n", *addr, d_tag); return 0; } else { debug(2, "Couldn't address for dtag!\n"); return -1; } }
static void hook_libdl_cb(void *data) { struct cb_data *hook_data = data; const char *lib_name = NULL; ElfW(Addr) addr; struct ltelf *lte = NULL; debug(DEBUG_FUNCTION, "add_library_cb"); if (!data) { debug(2, "No callback data"); return; } lib_name = hook_data->lib_name; addr = hook_data->addr; lte = hook_data->lte; if (library_num < MAX_LIBRARIES) { lte[library_num].base_addr = addr; library[library_num++] = strdup(lib_name); } else { fprintf (stderr, "MAX LIBS REACHED\n"); exit(EXIT_FAILURE); } }
static telf_status headerfs_release_ident(void *obj_hdl) { telf_obj *obj = obj_hdl; telf_status ret; telf_default_content *content = NULL; ElfW(Ehdr) *ehdr = obj->ctx->ehdr; DEBUG("name:%s data=%p", obj->name, obj->data); content = obj->data; if (content) { int i; for (i = 0; i < EI_NIDENT; i++) { char tmp[3] = { content->buf[2*i], content->buf[2*i+1], 0 }; ehdr->e_ident[i] = (uint8_t) strtoul(tmp, NULL, 16); } } ret = ELF_SUCCESS; return ret; }
void __libc_init_AT_SECURE(KernelArgumentBlock& args) { __libc_auxv = args.auxv; // Check that the kernel provided a value for AT_SECURE. bool found_AT_SECURE = false; for (ElfW(auxv_t)* v = __libc_auxv; v->a_type != AT_NULL; ++v) { if (v->a_type == AT_SECURE) { found_AT_SECURE = true; break; } } if (!found_AT_SECURE) __early_abort(__LINE__); if (getauxval(AT_SECURE)) { // If this is a setuid/setgid program, close the security hole described in // https://www.freebsd.org/security/advisories/FreeBSD-SA-02:23.stdio.asc __nullify_closed_stdio(); __sanitize_environment_variables(args.envp); } // Now the environment has been sanitized, make it available. environ = args.envp; __initialize_personality(); }
static telf_status symentryfs_read_info(void *obj_hdl, char **bufp, size_t *buf_lenp) { telf_obj *obj = obj_hdl; char *symname = NULL; char *buf = NULL; size_t buf_len = 0; telf_status ret; FILE *out = NULL; ElfW(Sym) *sym = obj->parent->data; /* default value */ symname = "NONAME"; if (sym->st_name) { symname = ((ELF_SECTION_SYMTAB == obj->parent->type) ? elf_getsymname : elf_getdsymname)(obj->ctx, sym); if (! symname || ! *symname) symname = "UNRESOLVED"; } out = open_memstream(&buf, &buf_len); if (! out) { ERR("open_memstream: %s", strerror(errno)); ret = ELF_ENOMEM; goto end; } fprintf(out, "value: %p\n" "size: %zu\n" "type: %s\n" "bind: %s\n" "name: %s\n", (void *) sym->st_value, sym->st_size, sym_type_to_str(sym), sym_bind_to_str(sym), symname); ret = ELF_SUCCESS; end: if (out) fclose(out); if (bufp) *bufp = buf; else free(buf); if (buf_lenp) *buf_lenp = buf_len; return ret; }
extern "C" unsigned long int getauxval(unsigned long int type) { for (ElfW(auxv_t)* v = __libc_auxv; v->a_type != AT_NULL; ++v) { if (v->a_type == type) { return v->a_un.a_val; } } return 0; }
_dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry) { ELF_RELOC *this_reloc; char *strtab; ElfW(Sym) *symtab; int symtab_index; char *rel_addr; struct elf_resolve *new_tpnt; char *new_addr; struct funcdesc_value funcval; struct funcdesc_value volatile *got_entry; char *symname; rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL]; this_reloc = (ELF_RELOC *)(intptr_t)(rel_addr + reloc_entry); symtab_index = ELF_R_SYM(this_reloc->r_info); symtab = (Elf32_Sym *) tpnt->dynamic_info[DT_SYMTAB]; strtab = (char *) tpnt->dynamic_info[DT_STRTAB]; symname= strtab + symtab[symtab_index].st_name; /* Address of GOT entry fix up */ got_entry = (struct funcdesc_value *) DL_RELOC_ADDR(tpnt->loadaddr, this_reloc->r_offset); /* Get the address to be used to fill in the GOT entry. */ new_addr = _dl_lookup_hash(symname, tpnt->symbol_scope, NULL, 0, &new_tpnt); if (!new_addr) { new_addr = _dl_lookup_hash(symname, NULL, NULL, 0, &new_tpnt); if (!new_addr) { _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname); _dl_exit(1); } } funcval.entry_point = new_addr; funcval.got_value = new_tpnt->loadaddr.got_value; #if defined (__SUPPORT_LD_DEBUG__) if (_dl_debug_bindings) { _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname); if (_dl_debug_detail) _dl_dprintf(_dl_debug_file, "\n\tpatched (%x,%x) ==> (%x,%x) @ %x\n", got_entry->entry_point, got_entry->got_value, funcval.entry_point, funcval.got_value, got_entry); } if (1 || !_dl_debug_nofixups) { *got_entry = funcval; } #else *got_entry = funcval; #endif return got_entry; }
// Returns elf_header.e_type if the file pointed by fd is an ELF binary. static int FileGetElfType(const int fd) { ElfW(Ehdr) elf_header; if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) { return -1; } if (memcmp(elf_header.e_ident, ELFMAG, SELFMAG) != 0) { return -1; } return elf_header.e_type; }
int main(int argc, char *argv[]){ long i; ElfW(Addr) a_type; ElfW(Addr) a_val; if(argc == 1){ printf("No arguments specified.\n\n"); print_help(); return 0; } for(i = 1; i < argc; i++){ if(!strcasecmp("--help", argv[i]) || !strcasecmp("-help", argv[i])){ print_help(); return 0; } if(!strcasecmp("--info", argv[i]) || !strcasecmp("-info", argv[i])){ print_info(); return 0; } if(!strcasecmp("--list", argv[i]) || !strcasecmp("-list", argv[i])){ print_list(); return 0; } if(!strcasecmp("--hwcap", argv[i]) || !strcasecmp("-hwcap", argv[i])){ print_hwcap(); return 0; } } for(i = 1; i < argc; i++){ a_type = translate_a_type(argv[i]); a_val = query_auxv(a_type); #ifdef __powerpc64__ printf("%lu\n", a_val); #else printf("%u\n", a_val); #endif } return 0; }
static telf_status headerfs_release_entrypoint(void *obj_hdl) { telf_obj *obj = obj_hdl; telf_status ret; telf_default_content *content = NULL; DEBUG("name:%s data=%p", obj->name, obj->data); content = obj->data; if (content) { ElfW(Addr) addr = (ElfW(Addr)) strtoull(content->buf, NULL, 0); DEBUG("new entry point: %p", (void *) addr); obj->ctx->ehdr->e_entry = addr; } ret = ELF_SUCCESS; return ret; }
int init_elf_headers(HIJACK *hijack) { hijack->ehdr.raw = read_data(hijack, (unsigned long)(hijack->baseaddr), sizeof(ElfW(Ehdr))); if (!(hijack->ehdr.raw)) return -1; hijack->phdr.raw = read_data(hijack, ((unsigned long)(hijack->baseaddr) + hijack->ehdr.ehdr->e_phoff), hijack->ehdr.ehdr->e_phentsize * hijack->ehdr.ehdr->e_phnum); if (!(hijack->phdr.raw)) return -1; return 0; }
/* * This is the entry point for the linker wrapper, which finds * the real linker, then bootstraps into it. */ extern "C" ElfW(Addr) __linker_init(void* raw_args) { KernelArgumentBlock args(raw_args); static uintptr_t linker_offset = reinterpret_cast<uintptr_t>(&linker_code_start); static uintptr_t linktime_addr = reinterpret_cast<uintptr_t>(&linktime_addr); ElfW(Addr) my_addr = reinterpret_cast<uintptr_t>(&linktime_addr) - linktime_addr; // Set AT_ENTRY to the proper entry point for (ElfW(auxv_t)* v = args.auxv; v->a_type != AT_NULL; ++v) { if (v->a_type == AT_BASE) { v->a_un.a_val = my_addr + linker_offset; } if (v->a_type == AT_ENTRY) { v->a_un.a_val = my_addr + reinterpret_cast<uintptr_t>(&original_start); } } // Return address of linker entry point -- may need to ensure that raw_args // was saved. return my_addr + linker_offset + reinterpret_cast<uintptr_t>(&linker_entry); }
int iconv_real_init( void ) { static pthread_mutex_t iconv_real_lock = PTHREAD_MUTEX_INITIALIZER; static int iconv_real_initialized = 0; static int iconv_real_status = -1; struct link_map *map = _r_debug.r_map; if (iconv_real_initialized) { return iconv_real_status; } pthread_mutex_lock(&iconv_real_lock); if (!map) { goto out; } for (; map; map = map->l_next) { if (!strstr(map->l_name, "/libc.so")) { continue; } ElfW(Dyn) *dyn; ElfW(Sym) *symtab = NULL; char const *strtab = NULL; unsigned int symnum = 0; for (dyn = map->l_ld; dyn->d_tag != DT_NULL; ++dyn) { if (dyn->d_tag == DT_SYMTAB) { symtab = (ElfW(Sym) *)OFFSET(map, dyn->d_un.d_ptr); } else if (dyn->d_tag == DT_STRTAB) { strtab = (char const *)OFFSET(map, dyn->d_un.d_ptr); } else if (dyn->d_tag == DT_HASH) { symnum = ((unsigned int *)OFFSET(map, dyn->d_un.d_ptr))[1]; } }
void dynLibImplLinux::GetImportAndExportData( const char* dllName ) { if( std::string(dllName).empty()) { return; } Elf* mainElf; struct link_map* mainLm; std::string csPath_o; OpenDynamicLibrary( dllName, mainElf, mainLm, csPath_o ); if ( mainLm == NULL ) { return; } Elf_Scn* section = 0; ElfW(Shdr) *shdr; FindSection( mainElf, SHT_DYNAMIC, section, shdr ); std::list<std::string> dependencies; ExtractDynSymbols( mainElf, section, shdr, STT_NOTYPE, dependencies ); std::list<std::string>::iterator it; for(it = dependencies.begin( ); it != dependencies.end( ) ; it++) { AddString( it->c_str() ); if ( GetDllEntry( it->c_str() ) == NULL ) { DLL_ENTRY stImpExport; std::string csPath_o; if ( GetExportData( it->c_str(), stImpExport.ArrayExport, csPath_o ) ) { stImpExport.m_bIsStable = true; stImpExport.m_csFullPath = csPath_o; // Add data to static internal map MakeUpper( *it ); m_DataEntry[ *it ] = stImpExport; } } DeleteString( it->c_str() ); } dlclose( mainLm ); }
/* Returns 0 if everything is ok, != 0 in case of error. */ int process_elf_file (const char *file_name, const char *lib, int *flag, unsigned int *osversion, char **soname, void *file_contents, size_t file_length) { union { Elf64_Ehdr *eh64; Elf32_Ehdr *eh32; ElfW(Ehdr) *eh; } elf_header; int ret; elf_header.eh = file_contents; if (elf_header.eh->e_ident [EI_CLASS] == ELFCLASS32) { ret = process_elf32_file (file_name, lib, flag, osversion, soname, file_contents, file_length); if (!ret) { Elf32_Word flags = elf_header.eh32->e_flags; int nan2008 = (flags & EF_MIPS_NAN2008) != 0; /* n32 libraries are always libc.so.6+, o32 only if 2008 NaN. */ if ((flags & EF_MIPS_ABI2) != 0) *flag = (nan2008 ? FLAG_MIPS64_LIBN32_NAN2008 : FLAG_MIPS64_LIBN32) | FLAG_ELF_LIBC6; else if (nan2008) *flag = FLAG_MIPS_LIB32_NAN2008 | FLAG_ELF_LIBC6; } } else { ret = process_elf64_file (file_name, lib, flag, osversion, soname, file_contents, file_length); /* n64 libraries are always libc.so.6+. */ if (!ret) { Elf64_Word flags = elf_header.eh64->e_flags; int nan2008 = (flags & EF_MIPS_NAN2008) != 0; *flag = (nan2008 ? FLAG_MIPS64_LIBN64_NAN2008 : FLAG_MIPS64_LIBN64) | FLAG_ELF_LIBC6; } } return ret; }
internal_function _dl_vdso_vsym (const char *name, const struct r_found_version *vers) { #ifndef __ZRT_SO struct link_map *map = GLRO (dl_sysinfo_map); void *value = NULL; if (map != NULL) { /* Use a WEAK REF so we don't error out if the symbol is not found. */ ElfW (Sym) wsym; memset (&wsym, 0, sizeof (ElfW (Sym))); wsym.st_info = (unsigned char) ELFW (ST_INFO (STB_WEAK, STT_NOTYPE)); /* Search the scope of the vdso map. */ const ElfW (Sym) *ref = &wsym; lookup_t result = GLRO (dl_lookup_symbol_x) (name, map, &ref, map->l_local_scope, vers, 0, 0, NULL); if (ref != NULL) value = DL_SYMBOL_ADDRESS (result, ref); }
unsigned la_objopen(struct link_map *map, Lmid_t lmid, uintptr_t *cookie) { #ifdef GLGRAB_APPLY_ELF_HACK ElfW(Dyn) *last, *pltrelsz = NULL; for (last = map->l_ld; last->d_tag != DT_NULL; ++last) { if (last->d_tag == DT_PLTRELSZ) pltrelsz = last; } if (pltrelsz == NULL) { pltrelsz = last++; last->d_tag = DT_NULL; pltrelsz->d_tag = DT_PLTRELSZ; pltrelsz->d_un.d_val = 0; ElfW(Dyn) **p = &map->l_ld + 1; while (*p < map->l_ld || *p > last) ++p; p[DT_PLTRELSZ - map->l_ld->d_tag] = pltrelsz; } #endif return LA_FLG_BINDTO | LA_FLG_BINDFROM; }
void *get_func_end(void *func) { int r; Dl_info dl_info; ElfW(Sym) *elf_info; r = dladdr1(func, &dl_info, (void **) &elf_info, RTLD_DL_SYMENT); if (r == 0) return NULL; if (elf_info == NULL) return NULL; if (dl_info.dli_saddr == NULL) return NULL; return ((unsigned char *) func) + elf_info->st_size; }
unsigned long int __getauxval (unsigned long int type) { ElfW(auxv_t) *p; if (type == AT_HWCAP) return GLRO(dl_hwcap); else if (type == AT_HWCAP2) return GLRO(dl_hwcap2); for (p = GLRO(dl_auxv); p->a_type != AT_NULL; p++) if (p->a_type == type) return p->a_un.a_val; __set_errno (ENOENT); return 0; }
void* dlsym(void* handle, const char* symbol) { ScopedPthreadMutexLocker locker(&g_dl_mutex); #if !defined(__LP64__) if (handle == NULL) { __bionic_format_dlerror("dlsym library handle is null", NULL); return NULL; } #endif if (symbol == NULL) { __bionic_format_dlerror("dlsym symbol name is null", NULL); return NULL; } soinfo* found = NULL; ElfW(Sym)* sym = NULL; if (handle == RTLD_DEFAULT) { sym = dlsym_linear_lookup(symbol, &found, NULL); } else if (handle == RTLD_NEXT) { void* caller_addr = __builtin_return_address(0); soinfo* si = find_containing_library(caller_addr); sym = NULL; if (si && si->next) { sym = dlsym_linear_lookup(symbol, &found, si->next); } } else { found = reinterpret_cast<soinfo*>(handle); sym = dlsym_handle_lookup(found, symbol); } if (sym != NULL) { unsigned bind = ELF_ST_BIND(sym->st_info); if ((bind == STB_GLOBAL || bind == STB_WEAK) && sym->st_shndx != 0) { return reinterpret_cast<void*>(sym->st_value + found->load_bias); } __bionic_format_dlerror("symbol found but not global", symbol); return NULL; } else { __bionic_format_dlerror("undefined symbol", symbol); return NULL; } }
void attribute_hidden _dl_tlsdesc_resolve_rela_fixup (struct tlsdesc *td, struct link_map *l) { const ElfW(Rela) *reloc = atomic_load_relaxed (&td->arg); /* After GL(dl_load_lock) is grabbed only one caller can see td->entry in initial state in _dl_tlsdesc_resolve_early_return_p, other concurrent callers will return and retry calling td->entry. The updated td->entry synchronizes with the single writer so all read accesses here can use relaxed order. */ if (_dl_tlsdesc_resolve_early_return_p (td, (void*)(D_PTR (l, l_info[ADDRIDX (DT_TLSDESC_PLT)]) + l->l_addr))) return; /* The code below was borrowed from _dl_fixup(), except for checking for STB_LOCAL. */ const ElfW(Sym) *const symtab = (const void *) D_PTR (l, l_info[DT_SYMTAB]); const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]); const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)]; lookup_t result; /* Look up the target symbol. If the normal lookup rules are not used don't look in the global scope. */ if (ELFW(ST_BIND) (sym->st_info) != STB_LOCAL && __builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0) { const struct r_found_version *version = NULL; if (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) { const ElfW(Half) *vernum = (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]); ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)] & 0x7fff; version = &l->l_versions[ndx]; if (version->hash == 0) version = NULL; } result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, l->l_scope, version, ELF_RTYPE_CLASS_PLT, DL_LOOKUP_ADD_DEPENDENCY, NULL); } else {
/* Find the list of shared objects */ static struct link_map * loaded (void) { ElfW(Dyn) *d; if (&_DYNAMIC == 0) /* statically linked */ return 0; for (d = _DYNAMIC; d->d_tag != DT_NULL; ++d) if (d->d_tag == DT_DEBUG) { struct r_debug *r = (void *) d->d_un.d_ptr; return r->r_map; } return 0; /* ld broken */ }
unsigned long find_pltgot(HIJACK *hijack) { unsigned int i; ElfW(Dyn) *dyn=NULL; SetError(hijack, ERROR_NONE); if (IsFlagSet(hijack, F_DEBUG)) fprintf(stderr, "[*] Attempting to find PLT/GOT\n"); for (i=0; i<hijack->ehdr.ehdr->e_phnum; i++) { if (hijack->phdr.phdr[i].p_type == PT_DYNAMIC) { dyn = (ElfW(Dyn) *)read_data(hijack, (unsigned long)(hijack->phdr.phdr[i].p_vaddr), hijack->phdr.phdr[i].p_memsz); break; } }
void get_proc_tables (proc_tables * ptabs) { #ifdef HAVE_ELF_H # if (defined(HAVE_ELF32_DYN_D_TAG) || defined(HAVE_ELF64_DYN_D_TAG)) && HAVE_DECL_ELFW ElfW (Dyn) * dyn; memset (ptabs, 0x00, sizeof (proc_tables)); for (dyn = _DYNAMIC; dyn != NULL && dyn->d_tag != DT_NULL; ++dyn) switch (dyn->d_tag) { /* symbols */ case DT_SYMTAB: ptabs->symbols = (Elf32_Sym *) dyn->d_un.d_ptr; break; case DT_HASH: ptabs->sym_hash = (Elf32_Word *) dyn->d_un.d_ptr; break; case DT_SYMENT: ptabs->sym_ent_size = dyn->d_un.d_val; break; /* strings */ case DT_STRTAB: ptabs->strings = (char *)dyn->d_un.d_ptr; break; case DT_STRSZ: ptabs->str_tabl_size = dyn->d_un.d_val; break; /* debug info */ case DT_DEBUG: # ifdef HAVE_LINK_H ptabs->debug = (struct r_debug *)dyn->d_un.d_ptr; # endif break; /* GOT/PLT */ case DT_PLTGOT: ptabs->pltgot = (void *)dyn->d_un.d_ptr; break; } if (ptabs->sym_hash != NULL) ptabs->sym_ent_num = *(ptabs->sym_hash + 1); # endif #endif /* HAVE_ELF_H */ }