#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>//声明快照函数的头文件
DWORD g_arList[1024]; //地址列表
int g_nListCnt=0; //有效地址个数
HANDLE g_hProcess; //目标进程句柄
bool CompareAPage(DWORD dwBaseAddr,DWORD dwValue)
{
//读取一页内存
BYTE arBytes[4096];
if(!::ReadProcessMemory(g_hProcess,(LPVOID*)dwBaseAddr,&arBytes,4096,NULL))
return FALSE; //此页不可读
//在这1页内存中查找
DWORD *pdw;
int i=0;
for(i=0;i<(int)4*1024-3;++i)
{
pdw = (DWORD*)&arBytes[i];
//if(pdw[0] == dwValue)//等于要查找的值?
if(pdw[0] == dwValue)
{
if(g_nListCnt>=1024)
return FALSE;
//添加到全局变量中
g_arList[g_nListCnt++] = dwBaseAddr+i;
}
}
return TRUE;
}
BOOL FindFirst(DWORD dwValue)
{
const DWORD dwOneGB = 1024*1024*1024; //1GB
const DWORD dwOnePage = 4*1024; //4KB
if(g_hProcess == NULL)
return FALSE;
//查看操作系统类型,以决定开始地址
DWORD dwBase;
OSVERSIONINFO vi = { sizeof(vi)};
::GetVersionEx(&vi);
if(vi.dwPlatformId ==VER_PLATFORM_WIN32_WINDOWS)
dwBase = 4*1024*1024; //Windows 98 系列,4MB
else
dwBase = 64*1024; //Windows NT 系列,64KB
//在开始地址到2GB的地址控件进行查找
for(;dwBase<2*dwOneGB;dwBase+=dwOnePage)
{
//比较1页大小的内存
CompareAPage(dwBase,dwValue);
}
return TRUE;
}
BOOL FindNext(DWORD dwValue)
{
//保存m_arList数组中有效地址的个数,初始化新的m_nListCnt值
int nOrgCnt = g_nListCnt;
g_nListCnt = 0;
//在m_arList数组记录的地址处查找
BOOL bRet = FALSE ;//假设失败
DWORD dwReadValue;
int i=0;
for(i=0;i<nOrgCnt;++i)
{
if(::ReadProcessMemory(g_hProcess,(LPVOID *)g_arList[i],
&dwReadValue,sizeof(DWORD),NULL))
{
if(dwReadValue == dwValue)
{
g_arList[g_nListCnt++] = g_arList[i];
bRet = TRUE;
}
}
}
return bRet;
}
void ShowList()
{
int i=0;
for(i=0;i<g_nListCnt;++i)
{
printf("%08lX \n",g_arList[i]);
}
}
BOOL WriteMemory(DWORD dwAddr, DWORD dwValue)
{
return ::WriteProcessMemory(g_hProcess, (LPVOID)dwAddr, &dwValue, sizeof(DWORD), NULL);
}
int main(int argc,char *argv[])
{
//启动testor进程
char szFileName[] = "Testor\\Debug\\Testor.exe" ;
STARTUPINFO si = {sizeof(si)};
PROCESS_INFORMATION pi;
::CreateProcess(NULL,szFileName,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,
NULL,NULL,&si,&pi);
//关闭线程句柄,既然我们不使用它
::CloseHandle(pi.hThread);
g_hProcess = pi.hProcess;
//输入要修改的值
int iVal;
printf("Input val= ");
scanf("%d",&iVal);
//进行第一次查找
FindFirst(iVal);
//打印出搜索的结果
ShowList();
while(g_nListCnt>1)
{
printf("Input val= ");
scanf("%d",&iVal);
//进行下次查找
FindNext(iVal);
//打印出搜索的结果
ShowList();
}
// 取得新值
printf(" New value = ");
scanf("%d", &iVal);
// 写入新值
if(WriteMemory(g_arList[0], iVal))
printf(" Write data success \n");
::CloseHandle(g_hProcess);
return 0;
}
测试程序代码如下:
#include <stdio.h>
int g_nNum;
int main(int argc,char *argv[])
{
int i = 198;
g_nNum = 1003;
while(1)
{
printf("i=%d , add=%08lX ;g_nNum=%d , add=%08lX ; \n",++i,&i,--g_nNum,&g_nNum);
getchar();
}
return 0;
}