int module_frob_arch_sections(Elf32_Ehdr *hdr, Elf32_Shdr *sechdrs, char *secstrings, struct module *me) { unsigned int i; /* Find .plt and .init.plt sections */ for (i = 0; i < hdr->e_shnum; i++) { if (strcmp(secstrings + sechdrs[i].sh_name, ".init.plt") == 0) me->arch.init_plt_section = i; else if (strcmp(secstrings + sechdrs[i].sh_name, ".plt") == 0) me->arch.core_plt_section = i; } if (!me->arch.core_plt_section || !me->arch.init_plt_section) { printk("Module doesn't contain .plt or .init.plt sections.\n"); return -ENOEXEC; } /* Override their sizes */ sechdrs[me->arch.core_plt_section].sh_size = get_plt_size(hdr, sechdrs, secstrings, 0); sechdrs[me->arch.init_plt_section].sh_size = get_plt_size(hdr, sechdrs, secstrings, 1); return 0; }
addr_t get_plt_by_entry_call( asmelf_t * aelf ) { /* XXX: only works if the first call of the entrypoint is * to a plt function */ char * start; addr_t start_addr; Elf32_Ehdr * ehdr; if( ! aelf || ! aelf->elf ) error_ret("null arg", -1 ); if( aelf->plt ) return( aelf->plt ); if( ! ( ehdr = get_ehdr( aelf->elf ) ) ) error_ret("can't get ehdr",-1); start_addr = ehdr->e_entry; if( ! ( start = data_at_addr( aelf->elf , start_addr ) ) ) error_ret("can't entry point get data", -1 ); /* 1: get our first call */ offset_t offset = 0; size_t nread; x86_insn_t insn; addr_t dst; addr_t pltaddr; do { nread=x86_disasm( start , 36+offset , start_addr , offset , &insn ); if( nread <= 0 ) error_ret("can't disassemble",-1); offset += nread; /* found our first plt call */ if( insn.type == insn_call ){ dst = op_resolve( &insn.operands[op_dest] , &insn ); break; } } while( offset < 256 ); if( offset >= 256 ) error_ret("can't find call",-1); if( crunch_plt_entry( aelf , dst, 0 , &pltaddr , 0 ) < 0 ) error_ret("can't get plt from plt code", -1 ); if( get_plt_size( aelf ) < 0 ) error_ret("can't get size",-1); return(( aelf->plt = pltaddr )); }