监控自身进程指定内存块是否被读写(防CE)

无意当中看到的一种监控读写的方法,写了个DEMO留档

// WsWatch.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Psapi.h>
#pragma comment(lib, "psapi.lib")
#ifndef PAGE_SIZE
#define PAGE_SIZE 0x1000
#endif
#define NtCurrentProcess() ((HANDLE)-1)
#define PAGE_ALIGN(Va) ((PVOID)((ULONG_PTR)(Va) & ~(PAGE_SIZE - 1)))

#define INITIAL_RECORD_SIZE 1000

bool GetProcessDataFromThread(_In_ DWORD ThreadId, _Out_ DWORD& ProcessId, _Out_writes_z_(MAX_PATH) wchar_t ProcessPath[MAX_PATH])
{
	bool status = false;

	ProcessId = 0;
	ProcessPath[0] = NULL;
	HANDLE Thread = OpenThread(THREAD_QUERY_LIMITED_INFORMATION, FALSE, ThreadId);
	if (Thread)
	{
		ProcessId = GetProcessIdOfThread(Thread);
		if (ProcessId)
		{
			HANDLE Process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ProcessId);
			if (Process)
			{
				status = (GetModuleFileNameExW(Process, NULL, ProcessPath, MAX_PATH) != 0);
				CloseHandle(Process);
			}
		}
		CloseHandle(Thread);
	}
	return status;
}


int check_ce()
{
	int status = -1;

	PBYTE AllocatedBuffer = NULL;
	PPSAPI_WS_WATCH_INFORMATION_EX WatchInfoEx = NULL;

	const DWORD CurrentProcessId = GetCurrentProcessId();
	printf("[+] PID: %lu\n", CurrentProcessId);


#if defined(_M_IX86)
	// Can't run on Wow64 (32-bit on 64-bit OS).
	BOOL Wow64Process = FALSE;
	if (IsWow64Process(NtCurrentProcess(), &Wow64Process) && Wow64Process)
	{
		fprintf(stderr, "[-] ERROR: This process cannot be run under Wow64.\n");
		goto Cleanup;
	}
#endif

	// Initiate monitoring of the working set for this process.
	if (!InitializeProcessForWsWatch(NtCurrentProcess()))
	{
		fprintf(stderr, "[-] ERROR: Failed to initialize process for working set watch. InitializeProcessForWsWatch failed with error: %lu.\n", GetLastError());
		goto Cleanup;
	}
	AllocatedBuffer = (PBYTE)VirtualAlloc(NULL, PAGE_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	if (!AllocatedBuffer)
	{
		fprintf(stderr, "[-] ERROR: Failed to allocate %u bytes for page faulting test buffer.\n", PAGE_SIZE);
		goto Cleanup;
	}

	printf("[+] Allocated buffer at 0x%p.\n", AllocatedBuffer);

	DWORD WatchInfoSize = (sizeof(PSAPI_WS_WATCH_INFORMATION_EX) * INITIAL_RECORD_SIZE);
	WatchInfoEx = (PPSAPI_WS_WATCH_INFORMATION_EX)malloc(WatchInfoSize);
	if (!WatchInfoEx)
	{
		fprintf(stderr, "[-] ERROR: Failed to allocate %lu bytes.\n", WatchInfoSize);
		goto Cleanup;
	}

	while (TRUE)
	{
		memset(WatchInfoEx, 0, WatchInfoSize);

		if (!GetWsChangesEx(NtCurrentProcess(), WatchInfoEx, &WatchInfoSize))
		{
			DWORD ErrorCode = GetLastError();

			// This really isn't an error. This just means that no new pages
			// have been mapped into our process' VA since the last time
			// we called GetWsChangesEx.
			if (ErrorCode == ERROR_NO_MORE_ITEMS)
			{
				// Wait a little bit before trying again.
				Sleep(1);
				continue;
			}

			// Any other error code is bad.
			if (ErrorCode != ERROR_INSUFFICIENT_BUFFER)
			{
				fprintf(stderr, "[-] ERROR: GetWsChangesEx failed with error: %lu.\n", ErrorCode);
				goto Cleanup;
			}

			// If we get this far, we need to increase the buffer size. 
			WatchInfoSize *= 2;

			free(WatchInfoEx);
			WatchInfoEx = (PPSAPI_WS_WATCH_INFORMATION_EX)malloc(WatchInfoSize);

			if (!WatchInfoEx)
			{
				fprintf(stderr, "[-] ERROR: Failed to allocate %lu bytes.\n", WatchInfoSize);
				goto Cleanup;
			}

			continue;
		}

		bool bFound = false;
		for (size_t i = 0;; ++i)
		{
			PPSAPI_WS_WATCH_INFORMATION_EX info = &WatchInfoEx[i];


			if (info->BasicInfo.FaultingPc == NULL)
				break;

			PVOID FaultingPageVa = PAGE_ALIGN(info->BasicInfo.FaultingVa);
			if (FaultingPageVa == AllocatedBuffer)
			{
				printf("[+] 0x%p (0x%p) was mapped by 0x%p (TID: %lu).\n", FaultingPageVa, info->BasicInfo.FaultingVa, info->BasicInfo.FaultingPc, (DWORD)info->FaultingThreadId);

				DWORD ProcessId;
				wchar_t ProcessPath[MAX_PATH];

				if (GetProcessDataFromThread((DWORD)info->FaultingThreadId, ProcessId, ProcessPath))
					printf("\t--> %S (PID: %lu).\n", ProcessPath, ProcessId);


				bFound = true;
				break;
			}
		}

		if (bFound)
		{
			status = 1;
			break;
		}
	}

Cleanup:
	// 'free' the 'malloc's.
	if (WatchInfoEx)
	{
		free(WatchInfoEx);
		WatchInfoEx = NULL;
	}

	if (AllocatedBuffer)
	{
		VirtualFree(AllocatedBuffer, 0, MEM_RELEASE);
		AllocatedBuffer = NULL;
	}

	return status;
}

int main()
{
	printf("Base = %llX\r\n",(UINT64)GetModuleHandle("WsWatch.exe"));
	while (1) {
		if (check_ce() > 0) printf("Find CE\r\n");
		Sleep(100);
	}
    return 0;
}


  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值