Beispiel #1
0
/* Get the machine type */
static r_binfmt_arch_e pe_get_machine(r_binfmt_s *bin) {
  IMAGE_COFF_HEADER *coff;
  WORD arch;

  coff = pe_get_coff(bin);

  arch = pe_get_arch(bin);

  if(arch != PE32 && arch != PE64)
    return R_BINFMT_ARCH_UNDEF;

  switch(coff->Machine) {
  case PE_MACHINE_I386:
    return R_BINFMT_ARCH_X86;
  case PE_MACHINE_IA64:
  case PE_MACHINE_AMD64:
    return R_BINFMT_ARCH_X86_64;
  default:
    return R_BINFMT_ARCH_UNDEF;
  }

  return R_BINFMT_ARCH_UNDEF;
}
Beispiel #2
0
int main(int argc, char *argv[])
{
	PE_FILE pe;
	FILE *fp = NULL;
	DWORD ep, stub_offset;
	int callbacks;
	double entropy;
//	unsigned int num_sections;

	if (argc < 2)
	{
		usage();
		exit(1);
	}

	parse_options(argc, argv); // opcoes

	if ((fp = fopen(argv[argc-1], "rb")) == NULL)
		EXIT_ERROR("file not found or unreadable");

	pe_init(&pe, fp); // inicializa o struct pe

	if (!is_pe(&pe))
		EXIT_ERROR("not a valid PE file");

	// File entropy
	entropy = calculate_entropy_file(&pe);

	if(entropy < 7.0)
		snprintf(value, MAX_MSG, "normal (%f)", entropy);
	else
		snprintf(value, MAX_MSG, "packed (%f)", entropy);
	output("file entropy", value);
        memset(&value, 0, sizeof(value));

	if (!pe_get_optional(&pe))
		return 1;

  	ep = (pe.optional_ptr->_32 ? pe.optional_ptr->_32->AddressOfEntryPoint :
	(pe.optional_ptr->_64 ? pe.optional_ptr->_64->AddressOfEntryPoint : 0));

	// fake ep
	if (ep == 0)
		snprintf(value, MAX_MSG, "null");
	else if (pe_check_fake_entrypoint(&pe, &ep))
		if (config.verbose)
			snprintf(value, MAX_MSG, "fake - va: %#x - raw: %#"PRIx64, ep, rva2ofs(&pe, ep));
		else
			snprintf(value, MAX_MSG, "fake");
	else
		if (config.verbose)
			snprintf(value, MAX_MSG, "normal - va: %#x - raw: %#"PRIx64, ep, rva2ofs(&pe, ep));
		else
			snprintf(value, MAX_MSG, "normal");

	output("entrypoint", value);

	// dos stub
	memset(&value, 0, sizeof(value));
	if (!normal_dos_stub(&pe, &stub_offset))
	{
		if (config.verbose)
			snprintf(value, MAX_MSG, "suspicious - raw: %#x", stub_offset);
		else
			snprintf(value, MAX_MSG, "suspicious");
	}
	else
		snprintf(value, MAX_MSG, "normal");

	output("DOS stub", value);

	// tls callbacks
	callbacks = pe_get_tls_callbacks(&pe);

	if (callbacks == 0)
		snprintf(value, MAX_MSG, "not found");
	else if (callbacks == -1)
		snprintf(value, MAX_MSG, "found - no functions");
	else if (callbacks >0)
		snprintf(value, MAX_MSG, "found - %d function(s)", callbacks);

	output("TLS directory", value);
	memset(&value, 0, sizeof(value));

	// section analysis
	print_strange_sections(&pe);

	// no imagebase
	if (!normal_imagebase(&pe))
	{
		if (config.verbose)
			snprintf(value, MAX_MSG, "suspicious - %#"PRIx64, pe.imagebase);
		else
			snprintf(value, MAX_MSG, "suspicious");
	}
	else
	{
		if (config.verbose)
			snprintf(value, MAX_MSG, "normal - %#"PRIx64, pe.imagebase);
		else
			snprintf(value, MAX_MSG, "normal");
	}
	output("imagebase", value);

	// invalid timestamp
	IMAGE_COFF_HEADER coff;

	if (!pe_get_coff(&pe, &coff))
		EXIT_ERROR("unable to read coff header");

	print_timestamp(&coff.TimeDateStamp);

	pe_deinit(&pe);

	return 0;
}
Beispiel #3
0
int main(int argc, char *argv[])
{
	PE_FILE pe;
	FILE *fp = NULL;
	
	if (argc < 2)
	{
		usage();
		exit(1);
	}

	parse_options(argc, argv); // opcoes

	if ((fp = fopen(argv[argc-1], "rb")) == NULL)
		EXIT_ERROR("file not found or unreadable");

	pe_init(&pe, fp); // inicializa o struct pe

	if (!is_pe(&pe))
		EXIT_ERROR("not a valid PE file");

	// dos header
	if (config.dos || config.all_headers || config.all)
	{
		IMAGE_DOS_HEADER dos;

		if (pe_get_dos(&pe, &dos))
			print_dos_header(&dos);
		else { EXIT_ERROR("unable to read DOS header"); }
	}

	// coff/file header
	if (config.coff || config.all_headers || config.all)
	{
		IMAGE_COFF_HEADER coff;

		if (pe_get_coff(&pe, &coff))
			print_coff_header(&coff);
		else { EXIT_ERROR("unable to read COFF file header"); }
	}

	// optional header
	if (config.opt || config.all_headers || config.all)
	{
		if (pe_get_optional(&pe))
			print_optional_header(&pe);
		else { EXIT_ERROR("unable to read Optional (Image) file header"); }
	}

	// directories
	if (config.dirs || config.all)
	{
		if (pe_get_directories(&pe))
			print_directories(&pe);
		else { EXIT_ERROR("unable to read the Directories entry from Optional header"); }
	}
	
	// imports
	if (config.imports || config.all)
	{
		if (pe_get_directories(&pe))
			print_imports(&pe);
		else { EXIT_ERROR("unable to read the Directories entry from Optional header"); }
	}	

	// exports
	if (config.exports || config.all)
	{
		if (pe_get_directories(&pe))
			print_exports(&pe);
		else
			{ EXIT_ERROR("unable to read directories from optional header"); }
	}

	// sections
	if (config.all_sections || config.all)
	{
		if (pe_get_sections(&pe))
			print_sections(&pe);
		else { EXIT_ERROR("unable to read sections"); }
	}

	// free
	pe_deinit(&pe);
	return 0;
}
Beispiel #4
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;
}