Пример #1
0
void r_binfmt_elf32_load_symtab(r_binfmt_s *bin, r_binfmt_elf32_s *elf) {
  Elf32_Word i, sh_type, sh_size;
  Elf32_Off sh_offset;

  R_BINFMT_ASSERT(elf->ehdr != NULL);
  R_BINFMT_ASSERT(elf->shdr != NULL);


  for(i = 0; i < elf->shdr_entries; i++) {
    R_BINFMT_GET_INT(sh_type, elf->shdr[i].sh_type, bin->endian);

    if(sh_type == SHT_SYMTAB) {
      R_BINFMT_GET_INT(sh_size, elf->shdr[i].sh_size, bin->endian);

      R_BINFMT_ASSERT((sh_size % sizeof(Elf32_Sym)) == 0);

      R_BINFMT_GET_INT(sh_offset, elf->shdr[i].sh_offset, bin->endian);

      R_BINFMT_ASSERT(r_utils_add32(NULL, sh_offset, sh_size) &&
                      sh_offset + sh_size <= bin->mapped_size);

      elf->symtab = (Elf32_Sym*)(bin->mapped + sh_offset);
      elf->symtab_entries = sh_size / sizeof(Elf32_Sym);
      break;
    }
  }
}
Пример #2
0
/* Fill bin->sections structure */
static void r_binfmt_elf32_load_sections(r_binfmt_s *bin, r_binfmt_elf32_s *elf) {
  r_binfmt_section_s *section;
  Elf32_Word sh_name, sh_size, i;
  Elf32_Off strndx_off;
  Elf32_Addr sh_addr;
  Elf32_Half e_shstrndx;

  R_BINFMT_ASSERT(elf->ehdr != NULL);
  R_BINFMT_ASSERT(elf->shdr != NULL);

  R_BINFMT_GET_INT(e_shstrndx, elf->ehdr->e_shstrndx, bin->endian);
  R_BINFMT_ASSERT(e_shstrndx < elf->shdr_entries);

  R_BINFMT_GET_INT(strndx_off, elf->shdr[e_shstrndx].sh_offset, bin->endian);

  for(i = 0; i < elf->shdr_entries; i++) {
    R_BINFMT_GET_INT(sh_addr, elf->shdr[i].sh_addr, bin->endian);
    R_BINFMT_GET_INT(sh_size, elf->shdr[i].sh_size, bin->endian);
    R_BINFMT_GET_INT(sh_name, elf->shdr[i].sh_name, bin->endian);

    R_BINFMT_ASSERT(r_utils_add32(NULL, strndx_off, sh_name) &&
                    strndx_off + sh_name <= bin->mapped_size);

    section = r_binfmt_section_new();
    section->addr = sh_addr;
    section->size = sh_size;
    section->name = r_binfmt_elf32_get_name(bin, elf, e_shstrndx, sh_name);

    r_utils_linklist_push(&bin->sections, section);
  }
}
Пример #3
0
/* Check evil or malformed files */
static int r_binfmt_macho64_check(r_binfmt_s *bin) {
  r_binfmt_macho64_header_s *hdr;
  r_binfmt_macho_cmd_s *cmd;
  u32 tmp, i, cmd_num, cmd_size, off, type;

  /* Already checked in r_binfmt_machoXX_is(),
     but if the check is removed in the future, the
     r_binfmt_machoXX_check() function must handle this case */
  if(bin->mapped_size < sizeof(*hdr))
    return 0;

  hdr = (r_binfmt_macho64_header_s*)(bin->mapped);

  cmd_num = r_binfmt_get_int32((byte_t*)&hdr->h_cmd_num, bin->endian);

  /* Check each command */
  off = 0;
  for(i = 0; i < cmd_num; i++) {

    /* Check if off+sizeof(*hdr)+sizeof(*cmd) isn't greater than
       bin->mapped_size */
    if(!r_utils_add32(&tmp, sizeof(*hdr)+sizeof(*cmd), off))
      return 0;
    if(bin->mapped_size < tmp)
      return 0;

    cmd = (r_binfmt_macho_cmd_s*)(bin->mapped + off + sizeof(*hdr));

    /* Now check command */
    type = r_binfmt_get_int32((byte_t*)&cmd->type, bin->endian);
    if(type == R_BINFMT_MACHO_CMD_TYPE_SEGMENT64) {
      if(!r_binfmt_macho64_check_segment(bin, (r_binfmt_macho64_segment_s*)cmd))
	return 0;
    }

    cmd_size = r_binfmt_get_int32((byte_t*)&cmd->size, bin->endian);
    if(!cmd_size)
      return 0;
    if(!r_utils_add32(&off, off, cmd_size))
      return 0;
  }

  return 1;
}
Пример #4
0
/* Check the fields of the machoXX segment */
static int r_binfmt_macho32_check_segment(r_binfmt_s *bin, r_binfmt_macho32_segment_s *seg) {
  u32 filesz, fileoff;
  u32 off;

  off = ((byte_t*)seg) - bin->mapped;

  if(!r_utils_add32(NULL, off, sizeof(*seg)))
    return 0;

  if(bin->mapped_size < off + sizeof(*seg))
    return 0;

  R_BINFMT_GET_INT(filesz, seg->file_size, bin->endian);
  R_BINFMT_GET_INT(fileoff, seg->file_off, bin->endian);

  if(!r_utils_add32(&off, fileoff, filesz))
    return 0;

  if(bin->mapped_size < off)
    return 0;

  return 1;
}
Пример #5
0
static const char* r_binfmt_elf32_get_name(r_binfmt_s *bin, r_binfmt_elf32_s *elf, Elf32_Half section_id, Elf32_Word name) {
  Elf32_Off sh_offset;
  Elf32_Word sh_size;

  R_BINFMT_GET_INT(sh_offset, elf->shdr[section_id].sh_offset, bin->endian);
  R_BINFMT_GET_INT(sh_size, elf->shdr[section_id].sh_size, bin->endian);

  R_BINFMT_ASSERT_RET("", r_utils_add32(NULL, sh_offset, sh_size) &&
                      sh_offset + sh_size <= bin->mapped_size);

  R_BINFMT_ASSERT_RET("", name < sh_size);

  return (const char*)(bin->mapped + sh_offset + name);
}
Пример #6
0
void r_binfmt_elf32_load_shdr(r_binfmt_s *bin, r_binfmt_elf32_s *elf) {
  Elf32_Off e_shoff;
  Elf32_Half e_shnum;

  R_BINFMT_ASSERT(elf->ehdr != NULL);

  R_BINFMT_GET_INT(e_shoff, elf->ehdr->e_shoff, bin->endian);
  R_BINFMT_ASSERT(e_shoff < bin->mapped_size);

  R_BINFMT_GET_INT(e_shnum, elf->ehdr->e_shnum, bin->endian);

  R_BINFMT_ASSERT(r_utils_add32(NULL, e_shnum*sizeof(Elf32_Shdr), e_shoff) &&
                  e_shnum*sizeof(Elf32_Shdr) + e_shoff <= bin->mapped_size);

  elf->shdr = (Elf32_Shdr*)(bin->mapped + e_shoff);
  elf->shdr_entries = e_shnum;
}
Пример #7
0
/* Fill bin->segments structure */
static void r_binfmt_elf32_load_segments(r_binfmt_s *bin, r_binfmt_elf32_s *elf) {
  r_binfmt_segment_s *seg;
  Elf32_Word i, p_type, p_flags, p_filesz;
  Elf32_Off p_offset;
  Elf32_Addr p_vaddr;
  Elf32_Half e_phnum;

  R_BINFMT_ASSERT(elf->ehdr != NULL);
  R_BINFMT_ASSERT(elf->phdr != NULL);

  R_BINFMT_GET_INT(e_phnum, elf->ehdr->e_phnum, bin->endian);

  for(i = 0; i < e_phnum; i++) {
    R_BINFMT_GET_INT(p_type, elf->phdr[i].p_type, bin->endian);
    R_BINFMT_GET_INT(p_flags, elf->phdr[i].p_flags, bin->endian);
    R_BINFMT_GET_INT(p_vaddr, elf->phdr[i].p_vaddr, bin->endian);
    R_BINFMT_GET_INT(p_offset, elf->phdr[i].p_offset, bin->endian);
    R_BINFMT_GET_INT(p_filesz, elf->phdr[i].p_filesz, bin->endian);

    R_BINFMT_ASSERT(r_utils_add32(NULL, p_offset, p_filesz) &&
                    p_offset + p_filesz <= bin->mapped_size);

    if(p_type == PT_LOAD) {
      seg = r_binfmt_segment_new();

      seg->flags = 0;
      if(p_flags & PF_X)
        seg->flags |= R_BINFMT_SEGMENT_FLAG_PROT_X;
      if(p_flags & PF_R)
        seg->flags |= R_BINFMT_SEGMENT_FLAG_PROT_R;
      if(p_flags & PF_W)
        seg->flags |= R_BINFMT_SEGMENT_FLAG_PROT_W;

      seg->addr = p_vaddr;
      seg->length = p_filesz;
      seg->start = bin->mapped + p_offset;

      r_utils_linklist_push(&bin->segments, seg);
    }
  }
}
Пример #8
0
static void r_binfmt_elf32_load_syms_dyntab(r_binfmt_s *bin, r_binfmt_elf32_s *elf) {
  r_binfmt_sym_s *sym;
  Elf32_Half sh_link, st_name;
  Elf32_Off link_off;
  Elf32_Word i, sh_type;

  R_BINFMT_ASSERT(elf->ehdr != NULL);
  R_BINFMT_ASSERT(elf->shdr != NULL);
  R_BINFMT_ASSERT(elf->dynsym != NULL);

  sh_link = 0xFFFF;
  for(i = 0; i < elf->shdr_entries; i++) {
    R_BINFMT_GET_INT(sh_type, elf->shdr[i].sh_type, bin->endian);

    if(sh_type == SHT_DYNSYM) {
      R_BINFMT_GET_INT(sh_link, elf->shdr[i].sh_link, bin->endian);
      R_BINFMT_ASSERT(sh_link < elf->shdr_entries);
      break;
    }
  }

  if(sh_link == 0xFFFF)
    return;

  for(i = 0; i < elf->dynsym_entries; i++) {
    R_BINFMT_GET_INT(st_name, elf->dynsym[i].st_name, bin->endian);
    R_BINFMT_GET_INT(link_off, elf->shdr[sh_link].sh_offset, bin->endian);

    R_BINFMT_ASSERT(r_utils_add32(NULL, link_off, st_name) &&
                    link_off + st_name <= bin->mapped_size);

    sym = r_binfmt_sym_new();
    sym->name = r_binfmt_elf32_get_name(bin, elf, sh_link, st_name);
    sym->addr = elf->dynsym[i].st_value;
    r_utils_arraylist_push(&bin->syms, sym);
  }
}
Пример #9
0
static int r_binfmt_pe_check(r_binfmt_s *bin) {
  IMAGE_DOS_HEADER *dos;
  IMAGE_COFF_HEADER *coff;
  IMAGE_SECTION_HEADER *shdr;
  DWORD addr_optional, addr_sections, numberOfRvaAndSizes;
  WORD arch;
  size_t size_optional;
  u32 tmp, i;

  /********************/
  /* Check DOS header */
  /********************/
  if(bin->mapped_size < sizeof(*dos))
    return 0;

  dos = (IMAGE_DOS_HEADER*)(bin->mapped);

  /*********************/
  /* Check COFF header */
  /*********************/
  if(bin->mapped_size < (DWORD)dos->e_lfanew)
    return 0;

  /* COFF+magic+arch */
  if(!r_utils_add32(&tmp, 8+sizeof(*coff), dos->e_lfanew))
    return 0;

  if(bin->mapped_size < tmp)
    return 0;

  coff = pe_get_coff(bin);

  /**************************/
  /* Check optionnal header */
  /**************************/
  arch = pe_get_arch(bin);

  switch(arch) {
  case PE32:
    size_optional = sizeof(IMAGE_OPTIONAL_HEADER_32);
    break;
  case PE64:
    size_optional = sizeof(IMAGE_OPTIONAL_HEADER_64);
    break;
  default:
    return 0;
  }

  if(!r_utils_add32(&tmp, 4+sizeof(*coff)+dos->e_lfanew, size_optional))
    return 0;

  if(bin->mapped_size < tmp)
    return 0;

  addr_optional = pe_get_addr_coff(bin) + sizeof(*coff);

  /******************/
  /* Check sections */
  /******************/
  switch(arch) {
  case PE32:
    numberOfRvaAndSizes = ((IMAGE_OPTIONAL_HEADER_32*)(bin->mapped + addr_optional))->NumberOfRvaAndSizes;
    break;
  case PE64:
    numberOfRvaAndSizes = ((IMAGE_OPTIONAL_HEADER_32*)(bin->mapped + addr_optional))->NumberOfRvaAndSizes;
    break;
  default:
    return 0;
  }

  if(!r_utils_mul32(&addr_sections, numberOfRvaAndSizes, sizeof(IMAGE_DATA_DIRECTORY)))
    return 0;

  if(bin->mapped_size < addr_sections)
    return 0;

  if(!r_utils_mul32(&tmp, sizeof(IMAGE_SECTION_HEADER), coff->NumberOfSections))
    return 0;

  if(!r_utils_add32(&tmp, tmp, addr_sections))
    return 0;

  if(bin->mapped_size < tmp)
    return 0;

  shdr = (IMAGE_SECTION_HEADER*)(bin->mapped + pe_get_addr_sections(bin));

  for(i = 0; i < coff->NumberOfSections; i++) {

    if(!r_utils_add32(&tmp, shdr[i].PointerToRawData, shdr[i].SizeOfRawData))
      return 0;
    if(bin->mapped_size < tmp)
      return 0;
  }

  return 1;
}