Blame src/process/ntapi_tt_map_image_as_data.c

dd89bb
/********************************************************/
dd89bb
/*  ntapi: Native API core library                      */
dd89bb
/*  Copyright (C) 2013,2014,2015  Z. Gilboa             */
dd89bb
/*  Released under GPLv2 and GPLv3; see COPYING.NTAPI.  */
dd89bb
/********************************************************/
dd89bb
dd89bb
#include <psxtypes/psxtypes.h>
dd89bb
#include <pemagine/pemagine.h>
dd89bb
#include <ntapi/nt_section.h>
dd89bb
#include <ntapi/nt_process.h>
dd89bb
#include <ntapi/ntapi.h>
dd89bb
#include "ntapi_impl.h"
dd89bb
dd89bb
static nt_sqos const sqos = {
dd89bb
	sizeof(sqos),
dd89bb
	NT_SECURITY_IMPERSONATION,
dd89bb
	NT_SECURITY_TRACKING_DYNAMIC,
dd89bb
	1};
dd89bb
dd89bb
static int32_t __tt_exec_unmap_image(nt_executable_image * image, void * base, int32_t status)
dd89bb
{
dd89bb
	int32_t ret;
dd89bb
dd89bb
	if (base)
dd89bb
		if ((ret = __ntapi->zw_unmap_view_of_section(
dd89bb
				NT_CURRENT_PROCESS_HANDLE,
dd89bb
				base)))
dd89bb
			return ret;
dd89bb
dd89bb
	if (image->hsection)
dd89bb
		if ((ret = __ntapi->zw_close(image->hsection)))
dd89bb
			return ret;
dd89bb
dd89bb
	return status;
dd89bb
}
dd89bb
dd89bb
int32_t	__stdcall __ntapi_tt_exec_unmap_image(nt_executable_image * image)
dd89bb
{
dd89bb
	return __tt_exec_unmap_image(image,image->addr,0);
dd89bb
}
dd89bb
dd89bb
dd89bb
int32_t __stdcall __ntapi_tt_exec_map_image_as_data(nt_executable_image * image)
dd89bb
{
dd89bb
	int32_t				status;
dd89bb
	uint16_t *			pi16;
dd89bb
	uint32_t *			pi32;
dd89bb
	nt_sec_size			sec_size;
dd89bb
	size_t				view_size;
dd89bb
	void *				base;
dd89bb
	void *				hsection;
dd89bb
dd89bb
	struct pe_image_dos_hdr *	dos;
dd89bb
	struct pe_coff_file_hdr *	coff;
dd89bb
	union  pe_opt_hdr *		opt;
dd89bb
	struct pe_sec_hdr *		sec;
dd89bb
dd89bb
	nt_oa oa = {sizeof(oa),
dd89bb
		    0,0,0,0,(nt_sqos *)&sqos};
dd89bb
dd89bb
	base = 0;
dd89bb
	sec_size.quad = 0;
dd89bb
	view_size = image->size;
dd89bb
dd89bb
	if ((status = __ntapi->zw_create_section(
dd89bb
			&hsection,
dd89bb
			NT_SECTION_MAP_READ,
dd89bb
			&oa,
dd89bb
			&sec_size,
dd89bb
			NT_PAGE_READONLY,
dd89bb
			NT_SEC_RESERVE,image->hfile)))
dd89bb
		return status;
dd89bb
dd89bb
	if ((status = __ntapi->zw_map_view_of_section(
dd89bb
			hsection,
dd89bb
			NT_CURRENT_PROCESS_HANDLE,
dd89bb
			&base,
dd89bb
			0,0,0,
dd89bb
			&view_size,
dd89bb
			NT_VIEW_UNMAP,0,
dd89bb
			NT_PAGE_READONLY)))
dd89bb
		return __tt_exec_unmap_image(
dd89bb
			image,base,status);
dd89bb
dd89bb
	if (!(dos = pe_get_image_dos_hdr_addr(base)))
dd89bb
		return 0;
dd89bb
dd89bb
	pi32 = (uint32_t *)dos->dos_lfanew;
dd89bb
	if ((*pi32 + sizeof(*coff)) > view_size)
dd89bb
		return __tt_exec_unmap_image(
dd89bb
			image,base,NT_STATUS_INVALID_IMAGE_FORMAT);
dd89bb
dd89bb
	if (!(coff = pe_get_image_coff_hdr_addr(base)))
dd89bb
		return 0;
dd89bb
dd89bb
	if (!(opt = pe_get_image_opt_hdr_addr(base)))
dd89bb
		return 0;
dd89bb
dd89bb
	sec  = pe_get_image_section_tbl_addr(base);
dd89bb
	pi16 = (uint16_t *)coff->num_of_sections;
dd89bb
	if (((size_t)sec-(size_t)base + *pi16 * sizeof(*sec)) > view_size)
dd89bb
		return __tt_exec_unmap_image(
dd89bb
			image,base,NT_STATUS_INVALID_IMAGE_FORMAT);
dd89bb
dd89bb
	/* subsystem: same offset (pe32, pe32+) */
dd89bb
	pi16 = (uint16_t *)opt;
dd89bb
	image->magic = *pi16;
dd89bb
dd89bb
	pi16 = (uint16_t *)opt->opt_hdr_32.subsystem;
dd89bb
	image->subsystem = *pi16;
dd89bb
dd89bb
	pi16 = (uint16_t *)coff->characteristics;
dd89bb
	image->characteristics = *pi16;
dd89bb
dd89bb
	image->hsection = hsection;
dd89bb
	image->addr = base;
dd89bb
	image->size = view_size;
dd89bb
dd89bb
	return status;
dd89bb
}