Windows程序设计

API函数写控制台修改内存(最Low)

2018-03-13  本文已影响0人  半数的年

左边程序修改右边程序内存,通过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);

}

上一篇下一篇

猜你喜欢

热点阅读