めいくりぷとのブログ

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

高速でプロセスのメモリを調べる。

	std::vector<SCAN_MEMORY_INFO> vScanMemory;

	MEMORY_BASIC_INFORMATION mbi;
	HANDLE	hProcess;
	PBYTE	pbStartAddress, pbEndAddress;
	SIZE_T	nBufferSize, nNumberOfBytesRead;
	int		nScanValue;

	hProcess = pIDEngine->GetAttachedProcess();
	if (hProcess == INVALID_HANDLE_VALUE)
		return;

	pbStartAddress		= (PBYTE)0x00000000;
	pbEndAddress		= (PBYTE)0x7FFFFFFF;
	nScanValue		= 10000; // scan value
	nNumberOfBytesRead	= 0;

#ifdef _DEBUG
	auto start = clock();
	std::cout << "scan value = " << nScanValue << "\n";
#endif

	while (pbStartAddress < pbEndAddress)
	{
		nBufferSize = VirtualQueryEx(hProcess, (LPCVOID)pbStartAddress, &mbi, sizeof(MEMORY_BASIC_INFORMATION));

		if (!nBufferSize)
		{
			pbStartAddress += 0x1000;
			continue;
		}

		if (mbi.State == MEM_COMMIT && mbi.Protect == PAGE_READWRITE)
		{
			PBYTE pbScanStart, pbScanEnd;
			PVOID pBuffer;
			SCAN_MEMORY_INFO memInfo;

			pBuffer = VirtualAlloc(NULL, mbi.RegionSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

			if (pBuffer != NULL)
			{
				if (ReadProcessMemory(hProcess, (LPCVOID)mbi.BaseAddress, pBuffer, mbi.RegionSize, &nNumberOfBytesRead))
				{
					pbScanStart = 	PBYTE(pBuffer);
					pbScanEnd = 	PBYTE(pBuffer) + nNumberOfBytesRead;

					// Set base address of module.
					memInfo.BaseAddress = PBYTE(mbi.BaseAddress);

					while (pbScanStart < pbScanEnd)
					{
						// 4 bytes scan
						if (*(DWORD*)pbScanStart == nScanValue)
						{
							memInfo.RelativeAddress = 	pbScanStart - PBYTE(pBuffer);
							memInfo.AbsoluteAddress = 	pbScanStart - PBYTE(pBuffer) + PBYTE(mbi.BaseAddress);
							vScanMemory.push_back(memInfo);
						}

						pbScanStart += 4;
					}

					VirtualFree(pBuffer, 0, MEM_RELEASE);
				}
			}
		}

		pbStartAddress += mbi.RegionSize;
	}

#ifdef _DEBUG
	auto end = clock();
	std::cout << "found = " << vScanMemory.size() << "\n";
	std::cout << "scan time = " << (double)(end - start) << "ms.\n";
#endif

	// add list
	for (auto memInfo : vScanMemory)
	{
		this->m_pFoundAddressTableModel->AddItem(ValueType4Bytes, nScanValue, &memInfo);
	}

x86/x64のプロセス両方に対応させる場合は、pbStartAddress, pbEndAddress, pbScanStart, pbScanEndを PBYTE(4バイト)から8バイトの型に変更すればok