我尝试编写一个程序,将一个空的(作为第一步)phdr结构插入到任何elf二进制文件中,所以我编码如下:
cat add_phdr.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <elf.h>
#include <sys/mman.h>
#include <stddef.h>
static void calc_dyntables(void **ehdr_ptr, size_t bound_size)
{
void *ptr = *ehdr_ptr;
Elf32_Ehdr *Elf32_ptr = NULL;
Elf32_ptr = (Elf32_Ehdr *)ptr;
Elf32_Phdr *elf32_phdr = NULL;
int n, found = 0;
n = Elf32_ptr->e_phnum;
elf32_phdr = ptr + Elf32_ptr->e_phoff;
while (n--) {
if (elf32_phdr->p_type == PT_DYNAMIC) {
found = 1;
break;
}
elf32_phdr++;
}
if (found) {
/* printf("=== PT_DYNAMIC: offset: 0x%x, size: 0x%x\n", */
/* elf32_phdr->p_offset, elf32_phdr->p_filesz); */
/* printf("sizeof(Elf32_Dyn): %d\n", sizeof(Elf32_Dyn)); */
}
else
return;
/* list all of dynamic sections */
found = 0;
Elf32_Dyn *dyn_entry = ptr + elf32_phdr->p_offset;
while (dyn_entry->d_tag != DT_NULL) {
switch (dyn_entry->d_tag) {
case 0x6ffffef5:
dyn_entry->d_un.d_ptr += bound_size;
break;
case 0x6ffffff0:
dyn_entry->d_un.d_ptr += bound_size;
break;
case 0x6ffffffe:
dyn_entry->d_un.d_ptr += bound_size;
break;
case 0x0000000c:
dyn_entry->d_un.d_ptr += bound_size;
break;
case 0x0000000d:
dyn_entry->d_un.d_ptr += bound_size;
break;
case 0x00000019:
dyn_entry->d_un.d_ptr += bound_size;
break;
case 0x0000001a:
dyn_entry->d_un.d_ptr += bound_size;
break;
case 0x00000005:
dyn_entry->d_un.d_ptr += bound_size;
break;
case 0x00000006:
dyn_entry->d_un.d_ptr += bound_size;
break;
case 0x00000003:
dyn_entry->d_un.d_ptr += bound_size;
break;
case 0x00000017:
dyn_entry->d_un.d_ptr += bound_size;
break;
case 0x00000011:
dyn_entry->d_un.d_ptr += bound_size;
break;
default:
break;
}
/* printf("== tag: 0x%x, value: 0x%x\n", dyn_entry->d_tag, */
/* dyn_entry->d_un.d_val); */
dyn_entry++;
}
}
static int write_phdr(int fd_dst, void *ptr, size_t filesize)
{
/* ptr for Ehdr */
Elf32_Ehdr *Elf32_ptr = NULL;
Elf32_ptr = (Elf32_Ehdr *)ptr;
/* ptr for Phdr */
Elf32_Phdr *elf32_phdr = NULL;
/* ptr for Shdr */
Elf32_Shdr *elf32_shdr = NULL;
int n;
/*
* We must find the phdr array's border, then recalcuate
* the offset of phdrs & shdrs which's offset beyond the
* offset of border.
*/
off_t old_phdr_border = Elf32_ptr->e_phoff + Elf32_ptr->e_phentsize * Elf32_ptr->e_phnum;
printf("=== border 0x%x\n", (unsigned int) (0x8048000 + old_phdr_border));
off_t phdr_size = Elf32_ptr->e_phentsize;
/* recalcuate the hash table address */
calc_dyntables(&ptr, phdr_size);
/* pdhr */
n = Elf32_ptr->e_phnum;
elf32_phdr = ptr + Elf32_ptr->e_phoff;
/* recalculate phdr offset */
while (n-- > 0) {
if (elf32_phdr->p_offset >= old_phdr_border) {
elf32_phdr->p_offset += phdr_size;
elf32_phdr->p_vaddr += phdr_size;
elf32_phdr->p_paddr += phdr_size;
}
else {
if ((elf32_phdr->p_offset + elf32_phdr->p_filesz) >= old_phdr_border) {
elf32_phdr->p_filesz += phdr_size;
elf32_phdr->p_memsz += phdr_size;
}
}
elf32_phdr++;
}
/* recalculate shdr offset */
n = Elf32_ptr->e_shnum;
elf32_shdr = ptr + Elf32_ptr->e_shoff;
while (n-- > 0) {
if (elf32_shdr->sh_offset >= old_phdr_border) {
elf32_shdr->sh_offset += phdr_size;
elf32_shdr->sh_addr += phdr_size;
}
else {
if ((elf32_shdr->sh_offset + elf32_shdr->sh_size) >= old_phdr_border) {
elf32_shdr->sh_size += phdr_size;
}
}
elf32_shdr++;
}
Elf32_ptr->e_shoff += phdr_size;
Elf32_Phdr *new_ptr = malloc(sizeof(Elf32_Phdr));
if (new_ptr == NULL)
return -1;
Elf32_ptr->e_phnum += 1;
/* recalculate the entry */
if (Elf32_ptr->e_entry > old_phdr_border)
Elf32_ptr->e_entry += phdr_size;
write(fd_dst, ptr, old_phdr_border);
memset(new_ptr, 0, sizeof(Elf32_Phdr));
new_ptr->p_type = PT_NULL;
new_ptr->p_offset = 0xffff;
new_ptr->p_vaddr = 0xffff;
new_ptr->p_paddr = 0xffff;
new_ptr->p_filesz = 0x1111;
new_ptr->p_memsz = 0;
new_ptr->p_flags = PF_R;
new_ptr->p_align = 0x4;
write(fd_dst, new_ptr, phdr_size);
write(fd_dst, ptr + old_phdr_border, filesize - old_phdr_border);
free(new_ptr);
return 0;
}
/*
* this version of write_phdr will apend phdr to
* the tail of file, so it wont move any sections
* or offset, we just need change the entry address.
*/
static int write_phdr2(int fd_dst, void *ptr, size_t filesize)
{
/* ptr for Ehdr */
Elf32_Ehdr *Elf32_ptr = NULL;
Elf32_ptr = (Elf32_Ehdr *)ptr;
/* ptr for Phdr */
// Elf32_Phdr *elf32_phdr = NULL;
Elf32_Phdr *new_ptr = malloc(sizeof(Elf32_Phdr));
if (new_ptr == NULL)
return -1;
off_t phdr_size = Elf32_ptr->e_phentsize;
/* recalculate the entry */
// Elf32_ptr->e_entry += phdr_size;
write(fd_dst, ptr, filesize);
/* append the phdr to the tail of file */
memset(new_ptr, 0, sizeof(Elf32_Phdr));
new_ptr->p_type = PT_NULL;
new_ptr->p_offset = 0xffff;
new_ptr->p_vaddr = 0xffff;
new_ptr->p_paddr = 0xffff;
new_ptr->p_filesz = 0;
new_ptr->p_memsz = 0;
new_ptr->p_flags = PF_R;
new_ptr->p_align = 0x4;
write(fd_dst, new_ptr, phdr_size);
free(new_ptr);
return 0;
}
/*
* we'll add a new phdr to the binary file
*/
int main(int argc, char *argv[])
{
int fd_src, fd_dst;
//size_t len = 0;
size_t filesize = 0;
void *ptr = NULL; /* ptr to binary file which mapped in memory */
if (argc != 3) {
printf("Usage: %s [ src bin ] [ dst bin ]...\n", argv[0]);
exit(EXIT_FAILURE);
}
/*
* we'll calculate the file size then map to memory
*/
fd_src = open(argv[1], O_RDONLY);
if (fd_src < 0) {
printf("Failed to open %s!\n", argv[1]);
exit(EXIT_FAILURE);
}
fd_dst = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0755);
if (fd_dst < 0) {
printf("Failed to open %s!\n", argv[2]);
exit(EXIT_FAILURE);
}
/* get file size with lseek SEEK_END */
filesize = lseek(fd_src, 0, SEEK_END);
if (filesize < 0) {
perror("lseek failed!");
close(fd_src);
exit(EXIT_FAILURE);
}
ptr = mmap(0, filesize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd_src, 0);
if (ptr < 0) {
perror("mmap failed!");
close(fd_src);
exit(EXIT_FAILURE);
}
if (1)
write_phdr(fd_dst, ptr, filesize);
if (0)
write_phdr2(fd_dst, ptr, filesize);
/* copy the modified file to dst */
/* do the clean work */
munmap(ptr, filesize);
close(fd_src);
close(fd_dst);
return EXIT_SUCCESS;
}
然后是Makefile:
cat Makefile
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
LDFLAGS = -m elf_i386
CFLAGS = -m32 -Wall -fPIE
TARGETS = elf_parser show_addr without_libc add_phdr read_elf hello
all: $(TARGETS)
elf_parser:elf_parser.c
$(CC) $(CFLAGS) -o $@ $<
show_addr:show_addr.c
$(CC) $(CFLAGS) -o $@ $<
without_libc:without_libc.c
$(CC) $(CFLAGS) -nostdlib -o $@ $<
add_phdr:add_phdr.c
$(CC) $(CFLAGS) -o $@ $<
hello:hello.c
$(CC) $(CFLAGS) -o $@ $<
read_elf:read_elf.o
$(LD) $(LDFLAGS) -o $@ $<
read_elf.o:read_elf.asm
nasm -f elf32 -o $@ $<
clean:
rm -rf $(TARGETS)
rm -rf *.o
好的,还有很多其他代码包含asm代码,我只列出了read_elf.asm和hello.c作为比较: cat read_elf.asm:
global _start
_start:
call main
xor eax, eax
inc eax
xor ebx, ebx
int 0x80
main:
call funA
ret
funA:
call funB
ret
funB:
call funC
ret
funC:
push byte 4
pop eax
xor ebx, ebx
inc ebx
mov ecx, 0x08048001
push byte 3
pop edx
int 0x80
ret
cat hello.c:
int main()
{
return 10;
}
接下来,让我们编译代码,然后运行add_phdr program:
./add_phdr read_elf test
然后运行测试,它运行良好,但是当我尝试修补hello程序时如下:
./add_phdr hello hello_test
./hello_test
我明白了:
Inconsistency detected by ld.so: dl-lookup.c: 876: _dl_setup_hash: Assertion `(bitmask_nwords & (bitmask_nwords - 1)) == 0' failed!
我不能再跑了! 那么任何提示?
更新
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <elf.h>
#include <sys/mman.h>
#include <stddef.h>
static void calc_symtab(void **ehdr_ptr, size_t bound_size)
{
void *ptr = *ehdr_ptr;
Elf32_Shdr *shdr_ptr = NULL;
Elf32_Ehdr *Elf32_ptr = (Elf32_Ehdr *)ptr;
int n = Elf32_ptr->e_shnum;
char *shstrtab = NULL;
/*
* first of all, let's get the shstrtab, we'll get
* the name of each section with it
*/
shdr_ptr = (Elf32_Shdr *)(ptr + Elf32_ptr->e_shoff);
while (n--) {
if (shdr_ptr->sh_type == SHT_STRTAB) {
shstrtab = (char *)(ptr + shdr_ptr->sh_offset);
if (!strcmp(&shstrtab[shdr_ptr->sh_name], ".shstrtab"))
break;
}
shdr_ptr++;
}
/* list all of sections */
shdr_ptr = (Elf32_Shdr *)(ptr + Elf32_ptr->e_shoff);
n = Elf32_ptr->e_shnum;
while (n--) {
if (shdr_ptr->sh_type == SHT_SYMTAB) {
int n2 = (shdr_ptr->sh_size / sizeof(Elf32_Sym));
Elf32_Sym *sym = (Elf32_Sym *)(ptr + shdr_ptr->sh_offset);
while (n2--) {
if (sym->st_value > 0)
sym->st_value += bound_size;
sym++;
}
}
shdr_ptr++;
}
}
static void calc_dynsym(void **ehdr_ptr, size_t bound_size)
{
void *ptr = *ehdr_ptr;
Elf32_Shdr *shdr_ptr = NULL;
Elf32_Ehdr *Elf32_ptr = (Elf32_Ehdr *)ptr;
int n = Elf32_ptr->e_shnum;
char *shstrtab = NULL;
/*
* first of all, let's get the shstrtab, we'll get
* the name of each section with it
*/
shdr_ptr = (Elf32_Shdr *)(ptr + Elf32_ptr->e_shoff);
while (n--) {
if (shdr_ptr->sh_type == SHT_STRTAB) {
shstrtab = (char *)(ptr + shdr_ptr->sh_offset);
if (!strcmp(&shstrtab[shdr_ptr->sh_name], ".shstrtab"))
break;
}
shdr_ptr++;
}
/* list all of sections */
shdr_ptr = (Elf32_Shdr *)(ptr + Elf32_ptr->e_shoff);
n = Elf32_ptr->e_shnum;
while (n--) {
if (shdr_ptr->sh_type == SHT_DYNSYM) {
int n2 = (shdr_ptr->sh_size / sizeof(Elf32_Sym));
Elf32_Sym *sym = (Elf32_Sym *)(ptr + shdr_ptr->sh_offset);
while (n2--) {
if (sym->st_value > 0)
sym->st_value += bound_size;
sym++;
}
}
shdr_ptr++;
}
}
static void calc_relocs(void **ehdr_ptr, size_t bound_size)
{
void *ptr = *ehdr_ptr;
Elf32_Shdr *shdr_ptr = NULL;
Elf32_Ehdr *Elf32_ptr = (Elf32_Ehdr *)ptr;
int n = Elf32_ptr->e_shnum;
char *shstrtab = NULL;
/*
* first of all, let's get the shstrtab, we'll get
* the name of each section with it
*/
shdr_ptr = (Elf32_Shdr *)(ptr + Elf32_ptr->e_shoff);
while (n--) {
if (shdr_ptr->sh_type == SHT_STRTAB) {
shstrtab = (char *)(ptr + shdr_ptr->sh_offset);
if (!strcmp(&shstrtab[shdr_ptr->sh_name], ".shstrtab"))
break;
}
shdr_ptr++;
}
/* list all of sections */
shdr_ptr = (Elf32_Shdr *)(ptr + Elf32_ptr->e_shoff);
n = Elf32_ptr->e_shnum;
while (n--) {
if (shdr_ptr->sh_type == SHT_REL || shdr_ptr->sh_type == SHT_RELA) {
int n2 = (shdr_ptr->sh_size / sizeof(Elf32_Rel));
Elf32_Rel *rel = (Elf32_Rel *)(ptr + shdr_ptr->sh_offset);
while (n2--) {
rel->r_offset += bound_size;
rel++;
}
}
shdr_ptr++;
}
}
static void calc_dyntables(void **ehdr_ptr, size_t bound_size)
{
void *ptr = *ehdr_ptr;
Elf32_Ehdr *Elf32_ptr = NULL;
Elf32_ptr = (Elf32_Ehdr *)ptr;
Elf32_Phdr *elf32_phdr = NULL;
int n, found = 0;
n = Elf32_ptr->e_phnum;
elf32_phdr = ptr + Elf32_ptr->e_phoff;
while (n--) {
if (elf32_phdr->p_type == PT_DYNAMIC) {
found = 1;
break;
}
elf32_phdr++;
}
if (found) {
/* printf("=== PT_DYNAMIC: offset: 0x%x, size: 0x%x\n", */
/* elf32_phdr->p_offset, elf32_phdr->p_filesz); */
/* printf("sizeof(Elf32_Dyn): %d\n", sizeof(Elf32_Dyn)); */
}
else
return;
/* list all of dynamic sections */
found = 0;
Elf32_Dyn *dyn_entry = ptr + elf32_phdr->p_offset;
while (dyn_entry->d_tag != DT_NULL) {
switch (dyn_entry->d_tag) {
case DT_GNU_HASH:
dyn_entry->d_un.d_ptr += bound_size;
break;
case DT_VERSYM:
dyn_entry->d_un.d_ptr += bound_size;
break;
case DT_VERNEED:
dyn_entry->d_un.d_ptr += bound_size;
break;
case DT_INIT:
dyn_entry->d_un.d_ptr += bound_size;
break;
case DT_FINI:
dyn_entry->d_un.d_ptr += bound_size;
break;
case DT_INIT_ARRAY:
dyn_entry->d_un.d_ptr += bound_size;
break;
case DT_FINI_ARRAY:
dyn_entry->d_un.d_ptr += bound_size;
break;
case DT_STRTAB:
dyn_entry->d_un.d_ptr += bound_size;
break;
case DT_SYMTAB:
dyn_entry->d_un.d_ptr += bound_size;
break;
case DT_PLTGOT:
dyn_entry->d_un.d_ptr += bound_size;
break;
case DT_JMPREL:
dyn_entry->d_un.d_ptr += bound_size;
break;
case DT_REL:
dyn_entry->d_un.d_ptr += bound_size;
break;
default:
break;
}
/* printf("== tag: 0x%x, value: 0x%x\n", dyn_entry->d_tag, */
/* dyn_entry->d_un.d_val); */
dyn_entry++;
}
}
static int write_phdr(int fd_dst, void *ptr, size_t filesize)
{
/* ptr for Ehdr */
Elf32_Ehdr *Elf32_ptr = NULL;
Elf32_ptr = (Elf32_Ehdr *)ptr;
/* ptr for Phdr */
Elf32_Phdr *elf32_phdr = NULL;
/* ptr for Shdr */
Elf32_Shdr *elf32_shdr = NULL;
int n;
/*
* We must find the phdr array's border, then recalcuate
* the offset of phdrs & shdrs which's offset beyond the
* offset of border.
*/
off_t old_phdr_border = Elf32_ptr->e_phoff + Elf32_ptr->e_phentsize * Elf32_ptr->e_phnum;
printf("=== border 0x%x\n", (unsigned int) (0x8048000 + old_phdr_border));
off_t phdr_size = Elf32_ptr->e_phentsize;
/* recalcuate the hash table address */
calc_dyntables(&ptr, phdr_size);
calc_relocs(&ptr, phdr_size);
calc_symtab(&ptr, phdr_size);
calc_dynsym(&ptr, phdr_size);
/* pdhr */
n = Elf32_ptr->e_phnum;
elf32_phdr = ptr + Elf32_ptr->e_phoff;
/* recalculate phdr offset */
while (n-- > 0) {
if (elf32_phdr->p_offset >= old_phdr_border) {
elf32_phdr->p_offset += phdr_size;
elf32_phdr->p_vaddr += phdr_size;
elf32_phdr->p_paddr += phdr_size;
}
else {
if ((elf32_phdr->p_offset + elf32_phdr->p_filesz) >= old_phdr_border) {
elf32_phdr->p_filesz += phdr_size;
elf32_phdr->p_memsz += phdr_size;
}
}
elf32_phdr++;
}
/* recalculate shdr offset */
n = Elf32_ptr->e_shnum;
elf32_shdr = ptr + Elf32_ptr->e_shoff;
while (n-- > 0) {
if (elf32_shdr->sh_offset >= old_phdr_border) {
elf32_shdr->sh_offset += phdr_size;
if (elf32_shdr->sh_addr > 0)
elf32_shdr->sh_addr += phdr_size;
}
else {
if ((elf32_shdr->sh_offset + elf32_shdr->sh_size) >= old_phdr_border) {
elf32_shdr->sh_size += phdr_size;
}
}
elf32_shdr++;
}
Elf32_ptr->e_shoff += phdr_size;
Elf32_Phdr *new_ptr = malloc(sizeof(Elf32_Phdr));
if (new_ptr == NULL)
return -1;
Elf32_ptr->e_phnum += 1;
/* recalculate the entry */
if (Elf32_ptr->e_entry >= old_phdr_border)
Elf32_ptr->e_entry += phdr_size;
write(fd_dst, ptr, old_phdr_border);
memset(new_ptr, 0, sizeof(Elf32_Phdr));
new_ptr->p_type = PT_NULL;
new_ptr->p_offset = 0xffff;
new_ptr->p_vaddr = 0xffff;
new_ptr->p_paddr = 0xffff;
new_ptr->p_filesz = 0x1111;
new_ptr->p_memsz = 0;
new_ptr->p_flags = PF_R;
new_ptr->p_align = 0x4;
write(fd_dst, new_ptr, phdr_size);
write(fd_dst, ptr + old_phdr_border, filesize - old_phdr_border);
free(new_ptr);
return 0;
}
/*
* this version of write_phdr will apend phdr to
* the tail of file, so it wont move any sections
* or offset, we just need change the entry address.
*/
static int write_phdr2(int fd_dst, void *ptr, size_t filesize)
{
/* ptr for Ehdr */
Elf32_Ehdr *Elf32_ptr = NULL;
Elf32_ptr = (Elf32_Ehdr *)ptr;
/* ptr for Phdr */
// Elf32_Phdr *elf32_phdr = NULL;
Elf32_Phdr *new_ptr = malloc(sizeof(Elf32_Phdr));
if (new_ptr == NULL)
return -1;
off_t phdr_size = Elf32_ptr->e_phentsize;
/* recalculate the entry */
// Elf32_ptr->e_entry += phdr_size;
write(fd_dst, ptr, filesize);
/* append the phdr to the tail of file */
memset(new_ptr, 0, sizeof(Elf32_Phdr));
new_ptr->p_type = PT_NULL;
new_ptr->p_offset = 0xffff;
new_ptr->p_vaddr = 0xffff;
new_ptr->p_paddr = 0xffff;
new_ptr->p_filesz = 0;
new_ptr->p_memsz = 0;
new_ptr->p_flags = PF_R;
new_ptr->p_align = 0x4;
write(fd_dst, new_ptr, phdr_size);
free(new_ptr);
return 0;
}
/*
* we'll add a new phdr to the binary file
*/
int main(int argc, char *argv[])
{
int fd_src, fd_dst;
//size_t len = 0;
size_t filesize = 0;
void *ptr = NULL; /* ptr to binary file which mapped in memory */
if (argc != 3) {
printf("Usage: %s [ src bin ] [ dst bin ]...\n", argv[0]);
exit(EXIT_FAILURE);
}
/*
* we'll calculate the file size then map to memory
*/
fd_src = open(argv[1], O_RDONLY);
if (fd_src < 0) {
printf("Failed to open %s!\n", argv[1]);
exit(EXIT_FAILURE);
}
fd_dst = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0755);
if (fd_dst < 0) {
printf("Failed to open %s!\n", argv[2]);
exit(EXIT_FAILURE);
}
/* get file size with lseek SEEK_END */
filesize = lseek(fd_src, 0, SEEK_END);
if (filesize < 0) {
perror("lseek failed!");
close(fd_src);
exit(EXIT_FAILURE);
}
ptr = mmap(0, filesize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd_src, 0);
if (ptr < 0) {
perror("mmap failed!");
close(fd_src);
exit(EXIT_FAILURE);
}
if (1)
write_phdr(fd_dst, ptr, filesize);
if (0)
write_phdr2(fd_dst, ptr, filesize);
/* copy the modified file to dst */
/* do the clean work */
munmap(ptr, filesize);
close(fd_src);
close(fd_dst);
return EXIT_SUCCESS;
}
答案 0 :(得分:2)
所以提示?
ELF格式里面有很多指针,如果你移动数据(就像你的程序一样),你必须调整所有这些指针以指向新的位置/偏移量(你的程序)没有做到。)
ELF实际上并不是为您尝试执行的后链接处理而设计的。
您的立即问题是hello
包含DT_HASH
或DT_GNU_HASH
(或两者),仍然指向{{1}的旧偏移量}或.hash
部分,但你已经移动了位,因此旧的偏移量不再包含运行时加载程序期望在那里找到的有效哈希表。
运行
.gnu.hash
应该证明确实如此。
修改强>:
for exe in hello hello_test; do readelf -d $exe | grep HASH readelf -WS $exe | grep hash done
不要那样做:它使您的代码无法阅读和理解。这样做:
case 0x6ffffef5:
dyn_entry->d_un.d_ptr += bound_size;
break;
由于您有12个这样的案例,我拒绝将它们映射回其符号名称。
无论如何,我的回答是:你没有在某处更新某些指针,这会导致你的ELF自我不一致,这会让动态加载器不满意。
如果您真的想要坚持这个方向,请安装glibc调试符号,并像这样调试加载器:
#include <elf.h>
...
case DT_GNU_HASH:
dyn_entry->d_un.d_ptr += bound_size;
break;
这应该允许您识别哪个指针无法更新。
答案 1 :(得分:0)
您是否使用“readelf”查看了新的可执行文件?
我自己会检查phdr是否(已经)在文件的末尾(phoff + phentsize * phnum == file_size)。如果不是,我只需将phdr表的副本附加到文件的末尾,并修改elf标题中的phoff成员。
然后我可以在文件的末尾添加phdr部分(我不必移动部分)。
原始phdr表将保留在文件中但处于非活动状态。