めいくりぷとのブログ

技術的なことをまったりと。

プロセス検出と最小化とそのBypass

プロセス検出&最小化

// ProcessMinimizer.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"

#include <Windows.h>
#include <winternl.h>
#include <ntstatus.h>
#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")
#pragma comment(lib, "ntdll.lib")

EXTERN_C
NTSTATUS 
WINAPI 
NtQuerySystemInformation(
	_In_      SYSTEM_INFORMATION_CLASS SystemInformationClass,
	_Inout_   PVOID                    SystemInformation,
	_In_      ULONG                    SystemInformationLength,
	_Out_opt_ PULONG                   ReturnLength
	);

_Success_(return != NULL)
HWND
WINAPI
GetWindowHandle(
	_In_  DWORD dwProcessId
	)
{
	HWND hWnd = GetTopWindow(NULL);

	do
	{
		if (GetWindowLong(hWnd, GWL_HWNDPARENT) != 0 || !IsWindowVisible(hWnd))
			continue;
	
		DWORD dwTemp = 0;
		GetWindowThreadProcessId(hWnd, &dwTemp);
		if (dwProcessId == dwTemp)
			return hWnd;
	
	} while ((hWnd = GetNextWindow(hWnd, GW_HWNDNEXT)) != NULL);

	return NULL;
}

_Success_(NT_SUCCESS(return))
NTSTATUS
NTAPI
ProcessMinimizer(
	)
{
	NTSTATUS ntStatus;
	SIZE_T nLength;
	PVOID pBuffer;
	SYSTEM_PROCESS_INFORMATION *pProcessInformation;

	ntStatus = NtQuerySystemInformation(SystemProcessInformation, NULL, sizeof(SYSTEM_PROCESS_INFORMATION), &nLength);
	if (ntStatus == STATUS_INFO_LENGTH_MISMATCH)
		pBuffer = VirtualAlloc(NULL, nLength, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

	if (reinterpret_cast<PVOID*>(pBuffer) != NULL)
	{
		ntStatus = NtQuerySystemInformation(SystemProcessInformation, pBuffer, nLength, NULL);
		if (NT_SUCCESS(ntStatus))
		{
			pProcessInformation = reinterpret_cast<SYSTEM_PROCESS_INFORMATION*>(pBuffer);
			while (pProcessInformation != NULL
				&& pProcessInformation->NextEntryOffset > 0)
			{				
				DWORD dwProcessId = reinterpret_cast<DWORD>(pProcessInformation->UniqueProcessId);
				if (dwProcessId != GetCurrentProcessId())
				{
					HWND hWnd = GetWindowHandle(dwProcessId);
					HANDLE hProcess;
					WCHAR szFileName[MAX_PATH];

					if (hWnd != NULL)
					{
						PostMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, NULL);

						hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
						if (hProcess != INVALID_HANDLE_VALUE)
						{
							GetModuleFileNameEx(hProcess, NULL, szFileName, MAX_PATH);
							_tprintf(L"Minimize ProcessID: %08X ProcessName: %s\n", dwProcessId, szFileName);
						}
						else
						{
							_tprintf(L"Minimize ProcessID: %08X ProcessName: Unknown\n", dwProcessId);
						}
					}
				}

				pProcessInformation = reinterpret_cast<SYSTEM_PROCESS_INFORMATION*>(
					reinterpret_cast<PBYTE>(pProcessInformation) + pProcessInformation->NextEntryOffset);
			}			
		}

                VirtualFree(pBuffer, 0, MEM_RELEASE);
	}

	return ntStatus;
}

int main()
{
	ProcessMinimizer();

	getchar();

    return 0;
}

Bypass

BOOL Detour_NtQuerySystemInformation()
{
	static decltype(&NtQuerySystemInformation) _NtQuerySystemInformation = NtQuerySystemInformation;

	decltype(&NtQuerySystemInformation) NtQuerySystemInformation_Hook = [](
		_In_      SYSTEM_INFORMATION_CLASS SystemInformationClass,
		_Inout_   PVOID                    SystemInformation,
		_In_      ULONG                    SystemInformationLength,
		_Out_opt_ PULONG                   ReturnLength) -> NTSTATUS
	{
		NTSTATUS ntStatus;

		ntStatus = _NtQuerySystemInformation(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
		if (NT_SUCCESS(ntStatus))
			if (SystemInformationClass == SystemProcessInformation)
				PSYSTEM_PROCESS_INFORMATION(SystemInformation)->NextEntryOffset = 0;

		return ntStatus;
	};

	return DetourFunction(TRUE, reinterpret_cast<LPVOID*>(&_NtQuerySystemInformation), NtQuerySystemInformation_Hook);
}