예제 #1
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;
}
예제 #2
0
static r_binfmt_arch_e r_binfmt_macho64_getarch(r_binfmt_s *bin) {
  r_binfmt_macho64_header_s *hdr;
  u32 cpu;

  hdr = (r_binfmt_macho64_header_s*)(bin->mapped);
  cpu = r_binfmt_get_int32((byte_t*)&hdr->h_cpu, bin->endian);

  if(cpu == R_BINFMT_MACHO_CPU_X86_64)
    return R_BINFMT_ARCH_X86_64;

  return R_BINFMT_ARCH_UNDEF;
}
예제 #3
0
/* Load the ELF binary in the bin->mlist */
static void elf64_load_mlist(r_binfmt_s *bin) {
  Elf64_Ehdr *ehdr = (Elf64_Ehdr*)bin->mapped;
  Elf64_Phdr *phdr;
  int i;
  uint64_t flags;
  uint64_t p_vaddr, p_offset, p_filesz;
  uint32_t p_type, p_flags;
  uint16_t e_phnum;

  bin->mlist = r_binfmt_mlist_new();

  phdr = (Elf64_Phdr*)(bin->mapped + r_binfmt_get_int64((byte_t*)&ehdr->e_phoff, bin->endian));

  e_phnum = r_binfmt_get_int16((byte_t*)&ehdr->e_phnum, bin->endian);

  for(i = 0; i < e_phnum; i++) {
    p_type = r_binfmt_get_int32((byte_t*)&phdr[i].p_type, bin->endian);
    p_flags = r_binfmt_get_int32((byte_t*)&phdr[i].p_flags, bin->endian);
    p_vaddr = r_binfmt_get_int64((byte_t*)&phdr[i].p_vaddr, bin->endian);
    p_offset = r_binfmt_get_int64((byte_t*)&phdr[i].p_offset, bin->endian);
    p_filesz = r_binfmt_get_int64((byte_t*)&phdr[i].p_filesz, bin->endian);

    if(p_type == PT_LOAD) {

      flags = 0;
      if(p_flags & PF_X)
	flags |= R_BINFMT_MEM_FLAG_PROT_X;
      if(p_flags & PF_R)
	flags |= R_BINFMT_MEM_FLAG_PROT_R;
      if(p_flags & PF_W)
	flags |= R_BINFMT_MEM_FLAG_PROT_W;

      r_binfmt_mlist_add(bin->mlist,
			p_vaddr,
			bin->mapped + p_offset,
			p_filesz,
			flags);
    }
  }
}
예제 #4
0
static void r_binfmt_macho64_load_mlist(r_binfmt_s *bin) {
  r_binfmt_macho64_header_s *hdr;
  r_binfmt_macho_cmd_s *cmd;
  u32 i, cmd_num, type, off;

  bin->mlist = r_binfmt_mlist_new();

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


  off = 0;
  for(i = 0; i < cmd_num; i++) {
    cmd = (r_binfmt_macho_cmd_s*)(bin->mapped + sizeof(*hdr) + off);
    type = r_binfmt_get_int32((byte_t*)&cmd->type, bin->endian);
    if(type == R_BINFMT_MACHO_CMD_TYPE_SEGMENT64) {
      r_binfmt_macho64_load_segment(bin, (r_binfmt_macho64_segment_s*)cmd);
    }

    off += r_binfmt_get_int32((byte_t*)&cmd->size, bin->endian);
  }
}
예제 #5
0
/* Check if NX bit is enabled */
static r_binfmt_nx_e r_binfmt_elf64_check_nx(r_binfmt_s *bin) {
  Elf64_Ehdr *ehdr = (Elf64_Ehdr*)(bin->mapped);
  Elf64_Phdr *phdr;
  u32 i, p_type;
  u16 e_phnum;

  phdr = (Elf64_Phdr*)(bin->mapped + r_binfmt_get_int64((byte_t*)&ehdr->e_phoff, bin->endian));

  e_phnum = r_binfmt_get_int16((byte_t*)&ehdr->e_phnum, bin->endian);

  for(i = 0; i < e_phnum; i++) {
    p_type = r_binfmt_get_int32((byte_t*)&phdr[i].p_type, bin->endian);
    if(p_type == PT_GNU_STACK)
      return R_BINFMT_NX_ENABLED;
  }
  return R_BINFMT_NX_DISABLED;
}
예제 #6
0
static void r_binfmt_macho32_load_segments(r_binfmt_s *bin) {
  r_binfmt_macho32_header_s *hdr;
  r_binfmt_macho_cmd_s *cmd;
  u32 i, cmd_num, type, off;

  hdr = (r_binfmt_macho32_header_s*)(bin->mapped);
  R_BINFMT_GET_INT(cmd_num, hdr->h_cmd_num, bin->endian);


  off = 0;
  for(i = 0; i < cmd_num; i++) {
    cmd = (r_binfmt_macho_cmd_s*)(bin->mapped + sizeof(r_binfmt_macho32_header_s) + off);
    R_BINFMT_GET_INT(type, cmd->type, bin->endian);
    if(type == R_BINFMT_MACHO_CMD_TYPE_SEGMENT) {
      r_binfmt_macho32_load_segment(bin, (r_binfmt_macho32_segment_s*)cmd);
    }

    off += r_binfmt_get_int32((byte_t*)&cmd->size, bin->endian);
  }
}
예제 #7
0
static void r_binfmt_macho64_load_segment(r_binfmt_s *bin, r_binfmt_macho64_segment_s *seg) {
  u64 vaddr, filesz, fileoff;
  u32 flags, initprot;

  vaddr    = r_binfmt_get_int64((byte_t*)&seg->vm_addr, bin->endian);
  filesz   = r_binfmt_get_int64((byte_t*)&seg->file_size, bin->endian);
  fileoff  = r_binfmt_get_int64((byte_t*)&seg->file_off, bin->endian);
  initprot = r_binfmt_get_int32((byte_t*)&seg->init_prot, bin->endian);

  flags = 0;
  if(initprot & R_BINFMT_MACHO_PROT_R)
    flags |= R_BINFMT_MEM_FLAG_PROT_R;
  if(initprot & R_BINFMT_MACHO_PROT_W)
    flags |= R_BINFMT_MEM_FLAG_PROT_W;
  if(initprot & R_BINFMT_MACHO_PROT_X)
    flags |= R_BINFMT_MEM_FLAG_PROT_X;

  r_binfmt_mlist_add(bin->mlist,
		     vaddr,
		     bin->mapped + fileoff,
		     filesz,
		     flags);
}