elfmaster / libelfmaster

Secure ELF parsing/loading library for forensics reconstruction of malware, and robust reverse engineering tools
http://www.bitlackeys.org
410 stars 64 forks source link

Unitialized field for struct elf_segment *segment in elf_segment_by_index() #32

Closed sad0p closed 1 year ago

sad0p commented 1 year ago
bool
elf_segment_by_index(struct elfobj *obj, uint64_t index, struct elf_segment *segment)
{

    switch(elf_class(obj)) {
    case elfclass32:
        if (index >= obj->ehdr32->e_phnum)
            return false;
        segment->type = obj->phdr32[index].p_type;
        segment->flags = obj->phdr32[index].p_flags;
        segment->offset = obj->phdr32[index].p_offset;
        segment->vaddr = obj->phdr32[index].p_vaddr;
        segment->paddr = obj->phdr32[index].p_paddr;
        segment->filesz = obj->phdr32[index].p_filesz;
        segment->memsz = obj->phdr32[index].p_memsz;
        segment->align = obj->phdr32[index].p_align;
        break;
    case elfclass64:
        if (index >= obj->ehdr64->e_phnum)
            return false;
        segment->type = obj->phdr64[index].p_type;
        segment->flags = obj->phdr64[index].p_flags;
        segment->offset = obj->phdr64[index].p_offset;
        segment->vaddr = obj->phdr64[index].p_vaddr;
        segment->paddr = obj->phdr64[index].p_paddr;
        segment->filesz = obj->phdr64[index].p_filesz;
        segment->memsz = obj->phdr64[index].p_memsz;
        segment->align = obj->phdr64[index].p_align;
        break;
    default:
        return false;
    }
    return true;
}```

```C
struct elf_segment {
    uint32_t type;
    uint32_t flags;
    uint64_t offset;
    uint64_t paddr;
    uint64_t vaddr;
    uint64_t filesz;
    uint64_t memsz;
    uint64_t align;
    unsigned int index;
};

Results in undefine behavior when accessing segment.index in the local instance of stuct elf_segment segment.

[sad0p@Arch-Deliberate tmp]$ ./elfmaster_test2 /bin/ls
0x6 && index => 0x2e42c0
0x3 && index => 0x2e42c0
0x1 && index => 0x2e42c0
0x1 && index => 0x2e42c0
0x1 && index => 0x2e42c0
0x1 && index => 0x2e42c0
0x2 && index => 0x2e42c0
0x4 && index => 0x2e42c0
0x4 && index => 0x2e42c0
0x6474e553 && index => 0x2e42c0
0x6474e550 && index => 0x2e42c0
0x6474e551 && index => 0x2e42c0
0x6474e552 && index => 0x2e42c0
[sad0p@Arch-Deliberate tmp]$ cat elfmaster_test2.c
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <elf.h>
#include <sys/types.h>
#include <search.h>
#include <sys/time.h>
#include "libelfmaster.h"

#define ERROR -1

int main(int argc, char **argv) {
    elfobj_t obj;
    elf_error_t error;
    struct elf_segment segment; 

    if (!elf_open_object(argv[1], &obj, ELF_LOAD_F_FORENSICS,&error)) {
        printf("%s\n", elf_error_msg(&error));
        exit(ERROR);
    }

    int i = 0;
    while(elf_segment_by_index(&obj, i, &segment)) {
        printf("0x%x && index => 0x%x\n", segment.type, segment.index); 
        i++;
    }

    elf_close_object(&obj);
    return 0;
}

[sad0p@Arch-Deliberate tmp]$ readelf -l /bin/ls

Elf file type is DYN (Position-Independent Executable file)
Entry point 0x5eb0
There are 13 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
                 0x00000000000002d8 0x00000000000002d8  R      0x8
  INTERP         0x0000000000000318 0x0000000000000318 0x0000000000000318
                 0x000000000000001c 0x000000000000001c  R      0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000003520 0x0000000000003520  R      0x1000
  LOAD           0x0000000000004000 0x0000000000004000 0x0000000000004000
                 0x0000000000013991 0x0000000000013991  R E    0x1000
  LOAD           0x0000000000018000 0x0000000000018000 0x0000000000018000
                 0x00000000000075e8 0x00000000000075e8  R      0x1000
  LOAD           0x000000000001ffb0 0x0000000000020fb0 0x0000000000020fb0
                 0x00000000000012c8 0x00000000000025b0  RW     0x1000
  DYNAMIC        0x0000000000020a98 0x0000000000021a98 0x0000000000021a98
                 0x00000000000001c0 0x00000000000001c0  RW     0x8
  NOTE           0x0000000000000338 0x0000000000000338 0x0000000000000338
                 0x0000000000000050 0x0000000000000050  R      0x8
  NOTE           0x0000000000000388 0x0000000000000388 0x0000000000000388
                 0x0000000000000044 0x0000000000000044  R      0x4
  GNU_PROPERTY   0x0000000000000338 0x0000000000000338 0x0000000000000338
                 0x0000000000000050 0x0000000000000050  R      0x8
  GNU_EH_FRAME   0x000000000001ce14 0x000000000001ce14 0x000000000001ce14
                 0x00000000000005c4 0x00000000000005c4  R      0x4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10
  GNU_RELRO      0x000000000001ffb0 0x0000000000020fb0 0x0000000000020fb0
                 0x0000000000001050 0x0000000000001050  R      0x1

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .note.gnu.property .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn 
   03     .init .text .fini 
   04     .rodata .eh_frame_hdr .eh_frame 
   05     .init_array .fini_array .data.rel.ro .dynamic .got .data .bss 
   06     .dynamic 
   07     .note.gnu.property 
   08     .note.gnu.build-id .note.ABI-tag 
   09     .note.gnu.property 
   10     .eh_frame_hdr 
   11     
   12     .init_array .fini_array .data.rel.ro .dynamic .got 
[sad0p@Arch-Deliberate tmp]$