Blame src/reader/pe_read_coff_header.c

e2e2c2
/***************************************************************/
e2e2c2
/*  perk: PE Resource Kit                                      */
ced38a
/*  Copyright (C) 2015--2017  Z. Gilboa                        */
e2e2c2
/*  Released under GPLv2 and GPLv3; see COPYING.PERK.          */
e2e2c2
/***************************************************************/
e2e2c2
c0fbae
#include <string.h>
c0fbae
c0fbae
#include <perk/perk.h>
01439f
#include "perk_endian_impl.h"
413f56
#include "perk_reader_impl.h"
c0fbae
822ef0
int pe_read_coff_header(const struct pe_raw_coff_image_hdr * p, struct pe_meta_coff_file_hdr * m)
c0fbae
{
da15f0
	if ((p->cfh_signature[0] != 'P') || (p->cfh_signature[1] != 'E')
da15f0
			|| p->cfh_signature[2] || p->cfh_signature[3])
ff121d
		return PERK_ERR_BAD_COFF_HEADER;
c0fbae
da15f0
	m->cfh_signature[0] = p->cfh_signature[0];
da15f0
	m->cfh_signature[1] = p->cfh_signature[1];
da15f0
	m->cfh_signature[2] = p->cfh_signature[2];
da15f0
	m->cfh_signature[3] = p->cfh_signature[3];
c0fbae
da15f0
	m->cfh_machine		= pe_read_short(p->cfh_machine);
da15f0
	m->cfh_num_of_sections	= pe_read_short(p->cfh_num_of_sections);
c0fbae
da15f0
	m->cfh_time_date_stamp	= pe_read_long(p->cfh_time_date_stamp);
da15f0
	m->cfh_ptr_to_sym_tbl	= pe_read_long(p->cfh_ptr_to_sym_tbl);
da15f0
	m->cfh_num_of_syms	= pe_read_long(p->cfh_num_of_syms);
c0fbae
da15f0
	m->cfh_size_of_opt_hdr	= pe_read_short(p->cfh_size_of_opt_hdr);
da15f0
	m->cfh_characteristics	= pe_read_short(p->cfh_characteristics);
c0fbae
c0fbae
	return 0;
b5f7f5
}
6b694b
6b694b
#define   PE_IMAGE_FILE_CHARACTERISTICS (\
6b694b
          PE_IMAGE_FILE_RELOCS_STRIPPED   \
6b694b
	| PE_IMAGE_FILE_EXECUTABLE_IMAGE   \
6b694b
	| PE_IMAGE_FILE_LINE_NUMS_STRIPPED  \
6b694b
	| PE_IMAGE_FILE_LOCAL_SYMS_STRIPPED  \
6b694b
	| PE_IMAGE_FILE_AGGRESSIVE_WS_TRIM    \
6b694b
	| PE_IMAGE_FILE_LARGE_ADDRESS_AWARE    \
6b694b
	| PE_IMAGE_FILE_RESERVED_CHARACTERISTIC \
6b694b
	| PE_IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP  \
6b694b
	| PE_IMAGE_FILE_BYTES_REVERSED_LO        \
6b694b
	| PE_IMAGE_FILE_32BIT_MACHINE           \
6b694b
	| PE_IMAGE_FILE_DEBUG_STRIPPED         \
6b694b
	| PE_IMAGE_FILE_NET_RUN_FROM_SWAP     \
6b694b
	| PE_IMAGE_FILE_SYSTEM               \
6b694b
	| PE_IMAGE_FILE_DLL                 \
6b694b
	| PE_IMAGE_FILE_UP_SYSTEM_ONLY     \
6b694b
	| PE_IMAGE_FILE_BYTES_REVERSED_HI)
6b694b
6b694b
int pe_read_object_header(const struct pe_raw_coff_object_hdr * p, struct pe_meta_coff_file_hdr * m)
6b694b
{
6b694b
	if (pe_read_short(p->cfh_size_of_opt_hdr))
6b694b
		return PERK_ERR_BAD_COFF_HEADER;
6b694b
6b694b
	if (pe_read_short(p->cfh_characteristics) & ~PE_IMAGE_FILE_CHARACTERISTICS)
6b694b
		return PERK_ERR_BAD_COFF_HEADER;
6b694b
6b694b
	switch (pe_read_short(p->cfh_machine)) {
6b694b
		case PE_IMAGE_FILE_MACHINE_I386:
6b694b
		case PE_IMAGE_FILE_MACHINE_R4000:
6b694b
		case PE_IMAGE_FILE_MACHINE_WCEMIPSV2:
6b694b
		case PE_IMAGE_FILE_MACHINE_SH3:
6b694b
		case PE_IMAGE_FILE_MACHINE_SH3DSP:
6b694b
		case PE_IMAGE_FILE_MACHINE_SH4:
6b694b
		case PE_IMAGE_FILE_MACHINE_SH5:
6b694b
		case PE_IMAGE_FILE_MACHINE_ARM:
6b694b
		case PE_IMAGE_FILE_MACHINE_THUMB:
6b694b
		case PE_IMAGE_FILE_MACHINE_ARMV7:
6b694b
		case PE_IMAGE_FILE_MACHINE_AM33:
6b694b
		case PE_IMAGE_FILE_MACHINE_POWERPC:
6b694b
		case PE_IMAGE_FILE_MACHINE_POWERPCFP:
6b694b
		case PE_IMAGE_FILE_MACHINE_IA64:
6b694b
		case PE_IMAGE_FILE_MACHINE_MIPS16:
6b694b
		case PE_IMAGE_FILE_MACHINE_MIPSFPU:
6b694b
		case PE_IMAGE_FILE_MACHINE_MIPSFPU16:
6b694b
		case PE_IMAGE_FILE_MACHINE_EBC:
6b694b
		case PE_IMAGE_FILE_MACHINE_AMD64:
6b694b
		case PE_IMAGE_FILE_MACHINE_M32R:
6b694b
			break;
6b694b
6b694b
		default:
6b694b
			return PERK_ERR_BAD_COFF_HEADER;
6b694b
	}
6b694b
6b694b
	m->cfh_signature[0] = 0;
6b694b
	m->cfh_signature[1] = 0;
6b694b
	m->cfh_signature[2] = 0;
6b694b
	m->cfh_signature[3] = 0;
6b694b
6b694b
	m->cfh_machine		= pe_read_short(p->cfh_machine);
6b694b
	m->cfh_num_of_sections	= pe_read_short(p->cfh_num_of_sections);
6b694b
6b694b
	m->cfh_time_date_stamp	= pe_read_long(p->cfh_time_date_stamp);
6b694b
	m->cfh_ptr_to_sym_tbl	= pe_read_long(p->cfh_ptr_to_sym_tbl);
6b694b
	m->cfh_num_of_syms	= pe_read_long(p->cfh_num_of_syms);
6b694b
6b694b
	m->cfh_size_of_opt_hdr	= pe_read_short(p->cfh_size_of_opt_hdr);
6b694b
	m->cfh_characteristics	= pe_read_short(p->cfh_characteristics);
6b694b
6b694b
	return 0;
6b694b
}