无意当中看到的一种监控读写的方法,写了个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;
}
版权声明:本文为yoie01原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。