Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"base_seg" variable is incorrect #5

Open
Hackerl opened this issue Nov 21, 2020 · 1 comment
Open

"base_seg" variable is incorrect #5

Hackerl opened this issue Nov 21, 2020 · 1 comment

Comments

@Hackerl
Copy link

Hackerl commented Nov 21, 2020

for(int i=0; i<ehdr->e_phnum; i++)
{
    phdr = (elf_phdr *)(elf_buf + ehdr->e_phoff + i * ehdr->e_phentsize);
    // printf("> seg[%d] load: %d addr 0x%llx size 0x%llx\n", i, phdr->p_type == PT_LOAD, phdr->p_vaddr, phdr->p_memsz);
    if(phdr->p_type == PT_LOAD && load_segment(elf_buf, ehdr, phdr, base_off))
        return -1;
    if(!base_seg)
        base_seg = phdr->p_vaddr;
    base_next = phdr->p_vaddr + phdr->p_memsz > base_next ? phdr->p_vaddr + phdr->p_memsz : base_next;
}

ALIGN_PAGE_DOWN(base_seg);

if(ehdr->e_type == ET_DYN)
    base_seg += base_off;
// printf("> program base: 0x%llx\n", base_seg);

Now the code to get the base address is written like this, get the non-zero offset of any segment (phdr->p_vaddr). But when I compile the program with the "-static-pie" option, the section information is as follows.

  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x00000000000e6965 0x00000000000e6965  R E    0x200000
  LOAD           0x00000000000e7188 0x00000000002e7188 0x00000000002e7188
                 0x0000000000007360 0x000000000000b550  RW     0x200000
  DYNAMIC        0x00000000000ed8e8 0x00000000002ed8e8 0x00000000002ed8e8
                 0x0000000000000170 0x0000000000000170  RW     0x8
  TLS            0x00000000000e7188 0x00000000002e7188 0x00000000002e7188
                 0x0000000000000000 0x0000000000000010  R      0x8
  GNU_EH_FRAME   0x00000000000bb650 0x00000000000bb650 0x00000000000bb650
                 0x000000000000697c 0x000000000000697c  R      0x4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10
  GNU_RELRO      0x00000000000e7188 0x00000000002e7188 0x00000000002e7188
                 0x0000000000006e78 0x0000000000006e78  R      0x1

You can see that the first segment is LOAD, but its virtual address is 0, then the program is judging that "if (!base_seg)" will enter the branch, so the final value of "base_seg" is "2e7188", the second Load segment Virtual address.
"base_seg" should take the virtual address of the first LOAD segment, whether it is zero or not.

int base_set = 0;

for(int i=0; i<ehdr->e_phnum; i++)
{
    phdr = (elf_phdr *)(elf_buf + ehdr->e_phoff + i * ehdr->e_phentsize);
    // printf("> seg[%d] load: %d addr 0x%llx size 0x%llx\n", i, phdr->p_type == PT_LOAD, phdr->p_vaddr, phdr->p_memsz);
    if(phdr->p_type == PT_LOAD)
    {
        if(!base_set)
        {
            base_set = 1;
            base_seg = phdr->p_vaddr;
        }

        if (load_segment(elf_buf, ehdr, phdr, base_off))
            return -1;
    }

    base_next = phdr->p_vaddr + phdr->p_memsz > base_next ? phdr->p_vaddr + phdr->p_memsz : base_next;
}
@ixty
Copy link
Owner

ixty commented Nov 27, 2020

nice catch :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants