API函数写控制台修改内存(最Low)
左边程序修改右边程序内存,通过API函数先读内存取得g_nNum(右边程序全局变量),然后修改;
先贴右边程序代码
#include <stdio.h>
int g_nNum; // 全局变量测试
int main(int argc, char* argv[])
{
int i=198; // 局部变量测试
g_nNum=1003;
while(1){
//输出每个变量的值和地址
printf("i=%d,addr=0x%0x; g_nNum=%d,addr=0x%0x\n",++i,&i,--g_nNum,&g_nNum);
getchar();
}
return 0;
}
左边程序代码
// MemRepair.cpp : Defines the entry point for the console application.//
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
BOOL FindFirst(DWORD dwValue); // 在目标进程空间进行第一次查找
BOOL FindNext(DWORD dwValue); // 在目标进程空间进行第2,3,4....此查找
BOOL CompareAPage(DWORD dwBaseAddr,DWORD dwValue); // 查找一页4KB的内存 符合存入地址列表
void ShowList(); //打印搜索到的地址
BOOL WriteMemory(DWORD dwAddr,DWORD dwValue);
DWORD g_arList[1024]; // 地址列表
int g_nListCnt; // 有效地址的个数
HANDLE g_hProcess; // 目标进程句柄
int main(int argc, char* argv[])
{
// 启动MemRepairTestor进程
char szFileName[]="..\\MemRepairTestor\\debug\\MemRepairTestor.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;
}
BOOL CompareAPage(DWORD dwBaseAddr,DWORD dwValue)
{
// 读取1页内存
BYTE arBytes[4096];
if(!::ReadProcessMemory(g_hProcess,(LPVOID)dwBaseAddr,arBytes,4096,NULL))
return FALSE; // 此页不可读
// 在这1页内存中查找
DWORD* pdw;
for(int i=0;i<(int)4*1024-3;i++){
pdw=(DWORD*)&arBytes[i];
if(pdw[0]==dwValue){ // 等于要查找的值
if(g_nListCnt>=1024)
return FALSE;
// 添加到全局变量中
g_arList[g_nListCnt++]=dwBaseAddr+i;
}
}
}
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; //Window98系列,4MB
else
dwBase=64*1024; //WindowNT系列,64KB
// 在开始地址到2GB的地址空间进行查找
for(;dwBase<2*dwOneGB;dwBase+=dwOnePage){
// 比较1页大小的内存
CompareAPage(dwBase,dwValue);
}
return TRUE;
}
void ShowList()
{
for(int i=0;i<g_nListCnt;i++){
printf("0x%0x\n",g_arList[i]);
}
}
BOOL FindNext(DWORD dwValue)
{
// 保存m_arList数组中有效地址的个数,初始化新的m_nListCnt值
int nOrgCnt=g_nListCnt;
g_nListCnt=0;
// 在m_arList数组记录的地址处查找
BOOL bRet=FALSE; //假设失败
DWORD dwReadValue;
for(int 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;
}
BOOL WriteMemory(DWORD dwAddr,DWORD dwValue)
{
return ::WriteProcessMemory(g_hProcess,(LPVOID)dwAddr,&dwValue,sizeof(DWORD),NULL);
}