Пример #1
0
int main(int argc, char *argv[])
{
	PE_FILE pe;
	FILE *dbfile = NULL, *fp = NULL;
	QWORD ep_offset, pesize;
	char value[MAX_MSG];
	unsigned char *pe_data;

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

	memset(&config, 0, sizeof(config));
	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 (!ispe(&pe))
		EXIT_ERROR("invalid PE file");

	if (!pe_get_optional(&pe))
		EXIT_ERROR("unable to read optional header");

   if (!(ep_offset = rva2ofs(&pe, pe.entrypoint)))
		EXIT_ERROR("unable to get entrypoint offset");
	
	pesize = pe_get_size(&pe);
	pe_data = (unsigned char *) xmalloc(pesize);
	
	//if (fseek(pe.handle, ep, SEEK_SET))
		//EXIT_ERROR("unable to seek to entrypoint offset");
	
	if (!fread(pe_data, pesize, 1, pe.handle))
		EXIT_ERROR("unable to read entrypoint data");
	
	if (!loaddb(&dbfile))
		fprintf(stderr, "warning: without valid database file, %s will search in generic mode only\n", PROGRAM);
	
	// packer by signature
	if (compare_signature(pe_data, ep_offset, dbfile, value));
	// generic detection
	else if (generic_packer(&pe, ep_offset))
		snprintf(value, MAX_MSG, "generic");
	else
		snprintf(value, MAX_MSG, "no packer found");
	
	free(pe_data);
	output("packer", value);

	if (dbfile)
		fclose(dbfile);
	pe_deinit(&pe);
	
	return 0;
}
Пример #2
0
int main(int argc, char *argv[])
{
	PE_FILE pe;
	FILE *fp, *datafile, *outfile;
	IMAGE_SECTION_HEADER section;
	unsigned long data_size, hole_size = 0;
	unsigned char *buff;

	fp = datafile = outfile = NULL;
	if (argc < 4)
	{
		usage();
		exit(1);
	}

	parse_options(argc, argv); // opcoes
	
	//if (!(outfile = fopen(argv[argc-1], "w")))
	//	EXIT_ERROR("unable to write outfile");

	if (!(fp = fopen(argv[argc-2], "r+b")))
		EXIT_ERROR("PE file not found or unreadable");

	if (!(datafile = fopen(datafile_path, "rb")))
		EXIT_ERROR("datafile not found or unreadable");

	pe_init(&pe, fp);

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

	// switch method
	if (!find_section(&pe, &section, true))
		EXIT_ERROR("no code sections found");

	hole_size = get_hole(&pe, &section);

	if (!hole_size)
		EXIT_ERROR("no holes found");

	printf("hole size: %ld\n", hole_size);
	printf("hole addr: %ld\n", ftell(pe.handle));

	// <pev> </pev>

	fseek(datafile, 0L, SEEK_END);
	data_size = ftell(datafile);
	if (data_size + 11> hole_size)
		EXIT_ERROR("not enough space");

	rewind(datafile);
	buff = xmalloc(data_size);
	fread(buff, sizeof(buff), 1, datafile);

	//'fwrite(buff, sizeof(buff), 1, pe.handle);
	free(buff);
	
	fclose(fp); fclose(outfile); fclose(datafile);
	return 0;
}
Пример #3
0
int main(int argc, char *argv[])
{
	PE_FILE pe;
	FILE *fp = NULL;
	unsigned long rva = 0;

	parse_options(argc, argv); // opcoes

	if (argc != 3)
	{
		usage();
		exit(1);
	}

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

	rva = (unsigned long) strtol(argv[1], NULL, 0);

	if (!rva)
		EXIT_ERROR("invalid RVA");


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

	if (!ispe(&pe))
		EXIT_ERROR("not a valid PE file");
		
	printf("%#"PRIx64"\n", rva2ofs(&pe, rva));
	// libera a memoria
	pe_deinit(&pe);
	
	return 1;
}
Пример #4
0
int main(int argc, char *argv[])
{
	FILE *fp;
	PE_FILE pe;
	unsigned char *data;
	size_t pesize = 0;

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

	parse_options(argc, argv);

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

	pe_init(&pe, fp);
	fseek(pe.handle, 0, SEEK_END);
	pesize = ftell(pe.handle);
	rewind(pe.handle);
	data = (unsigned char *) xmalloc(pesize + 1);
	fread(data, pesize, 1, pe.handle);

	if (config.md5 || config.all)
	{
		char md5_sum[(MD5_DIGEST_LENGTH*2) + 1];

		calc_md5(data, pesize, md5_sum);
		output("md5", md5_sum);
	}

	if (config.sha1 || config.all)
	{
		char sha1_sum[((SHA_DIGEST_LENGTH*2)+1)];

		calc_sha1(data, pesize, sha1_sum);
		output("sha-1", sha1_sum);
	}


	if (config.sha256 || config.all)
	{
		char sha256_sum[((SHA256_DIGEST_LENGTH*2)+1)];

		calc_sha256(data, pesize, sha256_sum);
		output("sha-256", sha256_sum);
	}

	pe_deinit(&pe);
	free(data);
	return 0;
}
Пример #5
0
int main(int argc, char *argv[])
{
	PE_FILE pe;
	FILE *fp = NULL;
	WORD dllchar = 0;
	char field[MAX_MSG];
	
	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");

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

	if (pe.architecture == PE32)
		dllchar = pe.optional_ptr->_32->DllCharacteristics;
	else if (pe.architecture == PE64)
		dllchar = pe.optional_ptr->_64->DllCharacteristics;
	else
		return 1;

	// aslr
	snprintf(field, MAX_MSG, "ASLR");	
	output(field, (dllchar & 0x40) ? "yes" : "no");

	// dep/nx
	snprintf(field, MAX_MSG, "DEP/NX");	
	output(field, (dllchar & 0x100) ? "yes" : "no");

	// seh
	snprintf(field, MAX_MSG, "SEH");	
	output(field, (dllchar & 0x400) ? "no" : "yes");

	// stack cookies
	snprintf(field, MAX_MSG, "Stack cookies (EXPERIMENTAL)");
	output(field, stack_cookies(&pe) ? "yes" : "no");
	
	// libera a memoria
	pe_deinit(&pe);
	
	return 0;
}
Пример #6
0
static int dw_iter_by_addr(struct ps_prochandle *P, const char *object_name, int which,
                           int mask, proc_sym_f *func, void *cd)
{
    int fd = 0, ret = -1, i, index = 0;
    Pe_object *pe;
    proc_mod_t *mod = findmodulebyname(P, object_name);

    fd = _open(mod->fullname, _O_RDONLY|_O_BINARY, 0);

    if (fd == -1 )
        return -1;

    if  ((pe = pe_init(fd)) != NULL) {
        IMAGE_SYMBOL *Sym = pe_getsymarr(pe, &index);
        char name[MAX_SYM_NAME];

        if (Sym == NULL)
            goto end;
        ret = 0;
        for (i = 0; i < index; i++) {
            GElf_Sym symp;
            char *n = NULL;

            if (ISFCN(Sym[i].Type) == 0)
                continue;
            symp.st_name = 0;
            symp.st_other = 0;
            symp.st_info = GELF_ST_INFO((STB_GLOBAL), (STT_FUNC));
            symp.st_shndx = 1;
            symp.st_value = Sym[i].Value+mod->imgbase+pe_getsecva(pe, Sym[i].SectionNumber);
            /* If size is zero libdtrace will reject the probe.Allow creation of entry probe */
            symp.st_size = 1;
            if (pe_getsymname(pe, &Sym[i], name, MAX_SYM_NAME) == NULL)
                continue;

            if (pe_getarch(pe) == PE_ARCH_I386)
                func(cd, &symp, &name[1]);
            else
                func(cd, &symp, name);
        }
    }
end:
    if (pe != NULL)
        pe_end(pe);
    if (fd != -1)
        close(fd);
    return ret;
}
Пример #7
0
static int is64bitmodule(PVOID base, char *s)
{
    int fd = _open(s, _O_RDONLY|_O_BINARY, 0);
    Pe_object *pe;

    if (fd != -1 && (pe = pe_init(fd)) != NULL) {
        int type = pe_getarch(pe);
        pe_end(pe);
        close(fd);
        if ( type == PE_ARCH_AMD64)
            return 1;
        else
            return 0;
    }

}
Пример #8
0
static int dw_lookup_by_name(struct ps_prochandle *P, const char *oname, const char *sname, GElf_Sym *symp)
{
    IMAGE_SYMBOL Sym;
    int ret = -1, fd;
    Pe_object *pe;
    proc_mod_t *mod;

    mod = findmodulebyname(P, oname);
    if (mod == NULL)
        return -1;

    fd = _open(mod->fullname, _O_RDONLY|_O_BINARY, 0);

    if (fd != -1 && (pe = pe_init(fd)) != NULL) {
        char s[MAX_SYM_NAME];

        if (pe_getarch(pe) == PE_ARCH_I386) {
            s[0] = '_';
            strcpy(&s[1], sname);
        } else {
            strcpy(s, sname);
        }

        if (pe_getsymbyname(pe, s, &Sym) != NULL) {
            symp->st_name = 0;
            symp->st_other = 0;
            if (ISFCN(Sym.Type)) {
                symp->st_info = GELF_ST_INFO((STB_GLOBAL), (STT_FUNC));
                symp->st_shndx = 1;
            } else {
                symp->st_info = GELF_ST_INFO((STB_GLOBAL), (STT_NOTYPE));
                symp->st_shndx = SHN_UNDEF;
            }
            symp->st_value = Sym.Value + mod->imgbase + pe_getsecva(pe, Sym.SectionNumber);
            /* If size is zero libdtrace will reject the function. Allow creation of entry probe */
            symp->st_size = 1;
            ret = 0;
        }
    }

    if (pe != NULL)
        pe_end(pe);
    if (fd != -1)
        close(fd);

    return ret;
}
Пример #9
0
void init_thread(void* param1, void* param2)
{
    ahci_init();
    //ahci_test();
    fat_init();
    pe_init();

    //LoadSysModule("sys/test.sys");
    //for(int i=0; i <16; i++)
	process_create("sys/init.exe");

    while(1)
    {
        mdelay(2000);
        printk("1");
    }
}
Пример #10
0
static int dw_lookup_by_addr(struct ps_prochandle *P, uintptr_t addr, char *buf, size_t size, GElf_Sym *symp)
{
    proc_mod_t *mod = NULL;
    int fd, ret = -1, index, i;
    Pe_object *pe;

    mod = findmodulebyaddr(P, addr);
    if (mod == NULL)
        return -1;

    fd = _open(mod->fullname, _O_RDONLY|_O_BINARY, 0);

    if (fd == -1 )
        return -1;

    if ((pe = pe_init(fd)) != NULL) {
        IMAGE_SYMBOL *Sym = pe_getsymarr(pe, &index);
        char name[MAX_SYM_NAME];

        int secno, addr1, mark = -1, prev = 0, va;

        if (Sym == NULL)
            goto end;

        if ((secno = pe_getsecnofromaddr(pe, addr - mod->imgbase))== 0)
            goto end;

        va = pe_getsecva(pe, secno);
        addr1 = addr - (mod->imgbase + va);
        if (addr1 <= 0)
            goto end;
        for (i = 0; i < index; i++) {
            if (ISFCN(Sym[i].Type) == 0 || Sym[i].SectionNumber != secno)
                continue;
            if (addr1 == Sym[i].Value) {
                mark = i;
                break;
            } else if (addr1 > Sym[i].Value) {
                if (prev < Sym[i].Value) {
                    prev = Sym[i].Value;
                    mark = i;
                }
            }
        }
        if (mark >= 0) {
            symp->st_name = 0;
            symp->st_other = 0;
            symp->st_info = GELF_ST_INFO((STB_GLOBAL), (STT_FUNC));
            symp->st_shndx = 1;
            symp->st_value = Sym[mark].Value + mod->imgbase
                             + pe_getsecva(pe, Sym[mark].SectionNumber);
            /* If size is zero libdtrace will reject the function. Allow creation of entry probe */
            symp->st_size = 1;

            if (pe_getsymname(pe, &Sym[mark], name, MAX_SYM_NAME) == NULL)
                goto end;
            if (pe_getarch(pe) == PE_ARCH_I386) {
                strncpy(buf, &name[1], size);
            } else {
                strncpy(buf, name, size);
            }

            ret = 0;
        }
    }
end:
    if (pe != NULL)
        pe_end(pe);
    if (fd != -1)
        close(fd);

    return ret;
}
Пример #11
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;
}
Пример #12
0
/* Convert ELF object to Portable Executable (PE). */
void
create_pe(struct elfcopy *ecp, int ifd, int ofd)
{
	Elf *e;
	Elf_Scn *scn;
	Elf_Data *d;
	GElf_Ehdr eh;
	GElf_Shdr sh;
	PE *pe;
	PE_Scn *ps;
	PE_SecHdr psh;
	PE_CoffHdr pch;
	PE_OptHdr poh;
	PE_Object po;
	PE_Buffer *pb;
	const char *name;
	size_t indx;
	int elferr;

	if (ecp->otf == ETF_EFI || ecp->oem == EM_X86_64)
		po = PE_O_PE32P;
	else
		po = PE_O_PE32;

	if ((e = elf_begin(ifd, ELF_C_READ, NULL)) == NULL)
		errx(EXIT_FAILURE, "elf_begin() failed: %s",
		    elf_errmsg(-1));

	if (gelf_getehdr(e, &eh) == NULL)
		errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
		    elf_errmsg(-1));

	if (elf_getshstrndx(ecp->ein, &indx) == 0)
		errx(EXIT_FAILURE, "elf_getshstrndx() failed: %s",
		    elf_errmsg(-1));

	if ((pe = pe_init(ofd, PE_C_WRITE, po)) == NULL)
		err(EXIT_FAILURE, "pe_init() failed");

	/* Setup PE COFF header. */
	memset(&pch, 0, sizeof(pch));
	switch (ecp->oem) {
	case EM_386:
		pch.ch_machine = IMAGE_FILE_MACHINE_I386;
		break;
	case EM_X86_64:
		pch.ch_machine = IMAGE_FILE_MACHINE_AMD64;
		break;
	default:
		pch.ch_machine = IMAGE_FILE_MACHINE_UNKNOWN;
		break;
	}
	pch.ch_timestamp = (uint32_t) time(NULL);
	if (pe_update_coff_header(pe, &pch) < 0)
		err(EXIT_FAILURE, "pe_update_coff_header() failed");

	/* Setup PE optional header. */
	memset(&poh, 0, sizeof(poh));
	if (ecp->otf == ETF_EFI)
		poh.oh_subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION;
	poh.oh_entry = (uint32_t) eh.e_entry;

	/*
	 * Default section alignment and file alignment. (Here the
	 * section alignment is set to the default page size of the
	 * archs supported. We should use different section alignment
	 * for some arch. (e.g. IA64)
	 */
	poh.oh_secalign = 0x1000;
	poh.oh_filealign = 0x200;

	/* Copy sections. */
	scn = NULL;
	while ((scn = elf_nextscn(e, scn)) != NULL) {

		/*
		 * Read in ELF section.
		 */

		if (gelf_getshdr(scn, &sh) == NULL) {
			warnx("gelf_getshdr() failed: %s", elf_errmsg(-1));
			(void) elf_errno();
			continue;
		}
		if ((name = elf_strptr(ecp->ein, indx, sh.sh_name)) ==
		    NULL) {
			warnx("elf_strptr() failed: %s", elf_errmsg(-1));
			(void) elf_errno();
			continue;
		}

		/* Skip sections unneeded. */
		if (strcmp(name, ".shstrtab") == 0 ||
		    strcmp(name, ".symtab") == 0 ||
		    strcmp(name, ".strtab") == 0)
			continue;

		if ((d = elf_getdata(scn, NULL)) == NULL) {
			warnx("elf_getdata() failed: %s", elf_errmsg(-1));
			(void) elf_errno();
			continue;
		}

		if (strcmp(name, ".text") == 0) {
			poh.oh_textbase = (uint32_t) sh.sh_addr;
			poh.oh_textsize = (uint32_t) roundup(sh.sh_size,
			    poh.oh_filealign);
		} else {
			if (po == PE_O_PE32 && strcmp(name, ".data") == 0)
				poh.oh_database = sh.sh_addr;
			if (sh.sh_type == SHT_NOBITS)
				poh.oh_bsssize += (uint32_t)
				    roundup(sh.sh_size, poh.oh_filealign);
			else if (sh.sh_flags & SHF_ALLOC)
				poh.oh_datasize += (uint32_t)
				    roundup(sh.sh_size, poh.oh_filealign);
		}

		/*
		 * Create PE/COFF section.
		 */

		if ((ps = pe_newscn(pe)) == NULL) {
			warn("pe_newscn() failed");
			continue;
		}

		/*
		 * Setup PE/COFF section header. The section name is not
		 * NUL-terminated if its length happens to be 8. Long
		 * section name should be truncated for PE image according
		 * to the PE/COFF specification.
		 */
		memset(&psh, 0, sizeof(psh));
		strncpy(psh.sh_name, name, sizeof(psh.sh_name));
		psh.sh_addr = sh.sh_addr;
		psh.sh_virtsize = sh.sh_size;
		if (sh.sh_type != SHT_NOBITS)
			psh.sh_rawsize = roundup(sh.sh_size, poh.oh_filealign);
		else
			psh.sh_char |= IMAGE_SCN_CNT_UNINITIALIZED_DATA;

		/*
		 * Translate ELF section flags to PE/COFF section flags.
		 */
		psh.sh_char |= IMAGE_SCN_MEM_READ;
		if (sh.sh_flags & SHF_WRITE)
			psh.sh_char |= IMAGE_SCN_MEM_WRITE;
		if (sh.sh_flags & SHF_EXECINSTR)
			psh.sh_char |= IMAGE_SCN_MEM_EXECUTE |
			    IMAGE_SCN_CNT_CODE;
		if ((sh.sh_flags & SHF_ALLOC) && (psh.sh_char & 0xF0) == 0)
			psh.sh_char |= IMAGE_SCN_CNT_INITIALIZED_DATA;

		/* Mark relocation section "discardable". */
		if (strcmp(name, ".reloc") == 0)
			psh.sh_char |= IMAGE_SCN_MEM_DISCARDABLE;

		if (pe_update_section_header(ps, &psh) < 0) {
			warn("pe_update_section_header() failed");
			continue;
		}

		/* Copy section content. */
		if ((pb = pe_newbuffer(ps)) == NULL) {
			warn("pe_newbuffer() failed");
			continue;
		}
		pb->pb_align = 1;
		pb->pb_off = 0;
		pb->pb_size = roundup(sh.sh_size, poh.oh_filealign);
		if ((pb->pb_buf = calloc(1, pb->pb_size)) == NULL) {
			warn("calloc failed");
			continue;
		}
		memcpy(pb->pb_buf, d->d_buf, sh.sh_size);
	}
	elferr = elf_errno();
	if (elferr != 0)
		warnx("elf_nextscn() failed: %s", elf_errmsg(elferr));

	/* Update PE optional header. */
	if (pe_update_opt_header(pe, &poh) < 0)
		err(EXIT_FAILURE, "pe_update_opt_header() failed");

	/* Write out PE/COFF object. */
	if (pe_update(pe) < 0)
		err(EXIT_FAILURE, "pe_update() failed");

	pe_finish(pe);
	elf_end(e);
}
Пример #13
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;
}