summaryrefslogtreecommitdiffhomepage
path: root/src/process/ntapi_tt_get_runtime_data.c
blob: 71662b4da85b96c4b1056b3ec78bd5cb399901e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/********************************************************/
/*  ntapi: Native API core library                      */
/*  Copyright (C) 2013--2016  Z. Gilboa                 */
/*  Released under GPLv2 and GPLv3; see COPYING.NTAPI.  */
/********************************************************/

#include <psxtypes/psxtypes.h>
#include <ntapi/nt_memory.h>
#include <ntapi/nt_process.h>
#include <ntapi/ntapi.h>
#include "ntapi_impl.h"

#if (__SIZEOF_POINTER__ == 4)
static wchar16_t runtime_arg[12] = {
	' ','-','r',' ',
	'i','n','t','e','g','r','a','l'};
#elif (__SIZEOF_POINTER__ == 8)
static wchar16_t runtime_arg[20] = {
	' ','-','r',' ',
	'i','n','t','e','g','r','a','l',
	'-','r','u','n','t','i','m','e'};
#endif

int32_t __stdcall __ntapi_tt_get_runtime_data(
	__out		nt_runtime_data **	rtdata,
	__in		wchar16_t **		wargv)
{
	int32_t				status;
	nt_process_parameters *		process_params;
	wchar16_t *			addrarg;
	uintptr_t			address;
	uintptr_t			buffer;
	nt_runtime_data *		prtdata;
	ntapi_internals *		__internals;

	/* init */
	__internals = __ntapi_internals();

	/* once? */
	if (__internals->rtdata) {
		*rtdata = __internals->rtdata;
		return NT_STATUS_SUCCESS;
	}

	if (!(wargv = wargv ? wargv : __internals->ntapi_img_sec_bss->argv_envp_array))
		return NT_STATUS_INVALID_PARAMETER;

	if (!wargv[1] || !wargv[2])
		return NT_STATUS_MORE_PROCESSING_REQUIRED;

	/* integral process? */
	addrarg = ((wargv[1][0] == '-') && (wargv[1][1] == 'r') && (wargv[1][2] == 0))
		? wargv[2] : 0;

	/* top-level framework process? */
	if (!addrarg || wargv[3])
		return NT_STATUS_MORE_PROCESSING_REQUIRED;

	/* obtain pointer to data block */
	if ((status = __ntapi->tt_hex_utf16_to_uintptr(
			addrarg,&address)))
		return status;

	/* invalid pointer? */
	if (address & 0xFFF)
		return NT_STATUS_MORE_PROCESSING_REQUIRED;

	/* address is aligned at page boundary */
	if ((status = __ntapi->zw_read_virtual_memory(
			NT_CURRENT_PROCESS_HANDLE,
			(void *)address,
			(char *)&buffer,
			sizeof(buffer),
			0)))
		return status;

	/* abi */
	prtdata = (nt_runtime_data *)address;

	if (__ntapi->tt_guid_compare(&prtdata->abi,&(nt_guid)NT_PROCESS_GUID_RTDATA))
		return NT_STATUS_MORE_PROCESSING_REQUIRED;

	/* update state */
	prtdata->flags |= NT_RUNTIME_DATA_INTEGRAL_PROCESS;

	/* avoid confusion :-) */
	process_params = ((nt_peb *)pe_get_peb_address())->process_params;

	__ntapi->tt_memcpy_utf16(
		(wchar16_t *)pe_va_from_rva(
			process_params->command_line.buffer,
			process_params->command_line.strlen - sizeof(runtime_arg)),
		runtime_arg,
		sizeof(runtime_arg));

	*rtdata = prtdata;

	return NT_STATUS_SUCCESS;
}