###內存修改器
修改指定進程名字中的內存
####單線程版本
#include <Windows.h>
#include <stdio.h>
#include <vector>
// 第一次查找
void FirstFind(HANDLE hProcess, BYTE *pBuffer, DWORD dwPageSize, DWORD dwVal, std::vector<DWORD> &vecAddr)
{
DWORD dwOneGB = 1024 * 1024 * 1024;
for (DWORD dwBaseAddr = 0; dwBaseAddr < dwOneGB*2; dwBaseAddr += dwPageSize)
{
// 讀取一頁大小的內存空間
if (ReadProcessMemory(hProcess, (LPCVOID)dwBaseAddr, pBuffer, dwPageSize, nullptr))
{
// 從一頁地址中查找相等的值,並記錄
DWORD *pdw = nullptr;
for (DWORD i = 0; i < dwPageSize - 3; ++i)
{
pdw = (DWORD *)&pBuffer[i];
if (pdw[0] == dwVal)
{
vecAddr.push_back(dwBaseAddr + i);
}
}
}
}
}
// 下一次查找
void NextFind(HANDLE hProcess, DWORD dwPageSize, DWORD dwVal, std::vector<DWORD> &vecAddr)
{
DWORD dwCount = 0;
DWORD dwSize = vecAddr.size();
DWORD dwReadVal = 0;
for (DWORD i=0; i<dwSize; ++i)
{
if (ReadProcessMemory(hProcess, (LPCVOID)vecAddr[i], &dwReadVal, sizeof(DWORD), nullptr))
{
if (dwReadVal == dwVal)
{
vecAddr[dwCount++] = vecAddr[i];
}
}
}
vecAddr.resize(dwCount);
}
int main()
{
do
{
// 查找窗口
printf("Please input the process name:");
char strProcessName[MAXBYTE] = { 0 };
gets_s(strProcessName, MAXBYTE);
HWND hWnd = FindWindowA(nullptr, strProcessName);
//HWND hWnd = FindWindowW(nullptr, L"Plants vs. Zombies 1.2.0.1073 RELEASE");
if (hWnd == nullptr)
{
printf("the handle of window do not found!");
break;
}
// 根據窗口句柄查找進程ID
DWORD dwProcessId = 0;
GetWindowThreadProcessId(hWnd, &dwProcessId);
if (dwProcessId == NULL)
{
printf("process Id do not found!");
break;
}
// 打開進程
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (hProcess == nullptr)
{
printf("open the process failed!");
break;
}
// 在讀取內存的時候,最好以頁的大小爲單位,這樣可以提高讀取效率,獲取頁面大小
SYSTEM_INFO system_info = { 0 };
GetSystemInfo(&system_info);
DWORD dwPageSize = system_info.dwPageSize;
// 判斷是否是32位程序運行在64位操作系統下面,以便於確定起始地址,如果是的話,輸出值爲TRUE,其餘情況都爲FALSE
// 在這裏無論是32位系統還是64位系統,它們的起始地址都是0x10000,所以起始地址就固定了,但是對於結束地址,這裏就
// 按照32位查找了,因爲64位的太大了,所以暫時沒有必要判斷多少位系統
//BOOL bWow64 = FALSE;
//IsWow64Process(hProcess, &bWow64);
//if (bWow64)
//{
//
//}
BYTE *pByte = new BYTE[dwPageSize];
memset(pByte, 0, dwPageSize * sizeof(BYTE));
// 定義一個vector
std::vector<DWORD> vecAddr;
DWORD dwVal = 0;
printf("The value to find:");
scanf_s("%d", &dwVal);
DWORD dwPrevTime = GetTickCount();
FirstFind(hProcess, pByte, dwPageSize, dwVal, vecAddr);
printf("The first find used time:%d ms\r\n", GetTickCount() - dwPrevTime);
while (vecAddr.size() > 1)
{
printf("The value to find:");
scanf_s("%d", &dwVal);
NextFind(hProcess, dwPageSize, dwVal, vecAddr);
}
printf("The value to modify:");
scanf_s("%d", &dwVal);
WriteProcessMemory(hProcess, (LPVOID)vecAddr[0], &dwVal, sizeof(DWORD), nullptr);
}
while (false);
system("pause");
return 0;
}
####多線程版本
#include <Windows.h>
#include <stdio.h>
#include <vector>
#include <process.h>
typedef struct _tagParam
{
DWORD dwPageSize;
DWORD dwStartAddr;
DWORD dwEndAddr;
DWORD dwFindVal;
HANDLE hProcess;
std::vector<DWORD> vecAddr;
}Param;
unsigned int __stdcall ThreadFunc(void *lParam)
{
Param *pParam = (Param *)lParam;
BYTE *pByte = new BYTE[pParam->dwPageSize];
for (DWORD dwStartAddr=pParam->dwStartAddr; dwStartAddr<pParam->dwEndAddr; dwStartAddr+=pParam->dwPageSize)
{
if (ReadProcessMemory(pParam->hProcess, (LPCVOID)dwStartAddr, pByte, pParam->dwPageSize, nullptr))
{
DWORD *pDword = nullptr;
for (DWORD i=0; i<pParam->dwPageSize-3; ++i)
{
pDword = (DWORD *)&pByte[i];
if (pDword[0] == pParam->dwFindVal)
{
pParam->vecAddr.push_back(dwStartAddr + i);
}
}
}
}
delete[] pByte;
return 0;
}
// 第一次查找
void FirstFind(HANDLE hProcess, BYTE *pBuffer, DWORD dwPageSize, DWORD dwVal, std::vector<DWORD> &vecAddr)
{
DWORD dwOneGB = 1024 * 1024 * 1024;
for (DWORD dwBaseAddr = 0; dwBaseAddr < dwOneGB*2; dwBaseAddr += dwPageSize)
{
// 讀取一頁大小的內存空間
if (ReadProcessMemory(hProcess, (LPCVOID)dwBaseAddr, pBuffer, dwPageSize, nullptr))
{
// 從一頁地址中查找相等的值,並記錄
DWORD *pdw = nullptr;
for (DWORD i = 0; i < dwPageSize - 3; ++i)
{
pdw = (DWORD *)&pBuffer[i];
if (pdw[0] == dwVal)
{
vecAddr.push_back(dwBaseAddr + i);
}
}
}
}
}
// 下一次查找
void NextFind(HANDLE hProcess, DWORD dwPageSize, DWORD dwVal, std::vector<DWORD> &vecAddr)
{
DWORD dwCount = 0;
DWORD dwSize = vecAddr.size();
DWORD dwReadVal = 0;
for (DWORD i=0; i<dwSize; ++i)
{
if (ReadProcessMemory(hProcess, (LPCVOID)vecAddr[i], &dwReadVal, sizeof(DWORD), nullptr))
{
if (dwReadVal == dwVal)
{
vecAddr[dwCount++] = vecAddr[i];
}
}
}
vecAddr.resize(dwCount);
}
int main()
{
do
{
// 查找窗口
printf("Please input the process name:");
char strProcessName[MAXBYTE] = { 0 };
gets_s(strProcessName, MAXBYTE);
HWND hWnd = FindWindowA(nullptr, strProcessName);
//HWND hWnd = FindWindowW(nullptr, L"Plants vs. Zombies 1.2.0.1073 RELEASE");
if (hWnd == nullptr)
{
printf("the handle of window do not found!");
break;
}
// 根據窗口句柄查找進程ID
DWORD dwProcessId = 0;
GetWindowThreadProcessId(hWnd, &dwProcessId);
if (dwProcessId == NULL)
{
printf("process Id do not found!");
break;
}
// 打開進程
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (hProcess == nullptr)
{
printf("open the process failed!");
break;
}
// 在讀取內存的時候,最好以頁的大小爲單位,這樣可以提高讀取效率,獲取頁面大小
SYSTEM_INFO system_info = { 0 };
GetSystemInfo(&system_info);
DWORD dwThreadCount = system_info.dwNumberOfProcessors;
BYTE *pByte = new BYTE[system_info.dwPageSize];
memset(pByte, 0, system_info.dwPageSize * sizeof(BYTE));
// 定義一個vector
std::vector<DWORD> vecAddr;
DWORD dwVal = 0;
printf("The value to find:");
scanf_s("%d", &dwVal);
DWORD dwPrevTime = GetTickCount();
//FirstFind(hProcess, pByte, dwPageSize, dwVal, vecAddr);
DWORD dwStartAddr = 0;
DWORD dwOneGB = 1024 * 1024 * 1024;
DWORD dwSizePerThread = 16 * 1024 * 1024; // 每個線程讀取16MB的空間
HANDLE *hThreads = new HANDLE[system_info.dwNumberOfProcessors];
Param *pParams = new Param[system_info.dwNumberOfProcessors];
for (DWORD i = 0; i < system_info.dwNumberOfProcessors; ++i)
{
pParams[i].dwStartAddr = dwStartAddr;
dwStartAddr += dwSizePerThread;
pParams[i].dwEndAddr = dwStartAddr;
pParams[i].hProcess = hProcess;
pParams[i].dwPageSize = system_info.dwPageSize;
pParams[i].dwFindVal = dwVal;
pParams[i].vecAddr.clear();
hThreads[i] = (HANDLE)_beginthreadex(nullptr, 0, ThreadFunc, &pParams[i], 0, nullptr);
}
for (; dwStartAddr<dwOneGB*2; )
{
DWORD dwRet = WaitForMultipleObjects(system_info.dwNumberOfProcessors, hThreads, FALSE, INFINITE);
pParams[dwRet].dwStartAddr = dwStartAddr;
dwStartAddr += dwSizePerThread;
pParams[dwRet].dwEndAddr = dwStartAddr;
for (DWORD i=0; i<pParams[dwRet].vecAddr.size(); ++i)
{
vecAddr.push_back(pParams[dwRet].vecAddr[i]);
}
pParams[dwRet].vecAddr.clear();
hThreads[dwRet] = (HANDLE)_beginthreadex(nullptr, 0, ThreadFunc, &pParams[dwRet], 0, nullptr);
}
WaitForMultipleObjects(system_info.dwNumberOfProcessors, hThreads, TRUE, INFINITE);
printf("The first find used time:%d ms\r\n", GetTickCount() - dwPrevTime);
while (vecAddr.size() > 1)
{
printf("The value to find:");
scanf_s("%d", &dwVal);
NextFind(hProcess, system_info.dwPageSize, dwVal, vecAddr);
}
printf("The value to modify:");
scanf_s("%d", &dwVal);
WriteProcessMemory(hProcess, (LPVOID)vecAddr[0], &dwVal, sizeof(DWORD), nullptr);
delete[] pByte;
}
while (false);
system("pause");
return 0;
}