前段日子因为学习内存把王艳平老师的书看了一遍综合了其他书籍,简单学习做了一个内存修改器,下面是我觉得比较重要的知识,从书上抠了下来
代码:
类的形式写的代码:
// HelloGame.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include"HelloGame.h"
Game::Game(DWORD ProcessID)
{
m_GameCount = 0;
IsOK = TRUE;
ToAimProcessHandle = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,
FALSE, ProcessID);
}
Game::~Game()
{
if (ToAimProcessHandle!=NULL)
{
CloseHandle(ToAimProcessHandle);
ToAimProcessHandle = NULL;
}
}
BOOL Game::CompareAPage(DWORD BaseAddress, DWORD Value)//搜索内存
{
BYTE PageBytes[4096];
BOOL IsOK;
IsOK = ReadProcessMemory(ToAimProcessHandle, (LPVOID)BaseAddress, PageBytes, 4096, NULL);
if (IsOK == FALSE)
{
return NULL;
}
DWORD *Buffer;
for (int i = 0; i < 4 * 1024 - 3; i++)
{
Buffer = (DWORD*)&PageBytes[i];//这样才是地址的地址
if (Buffer[0] == Value)
{
m_AddressList[m_GameCount++] = BaseAddress + i;//不懂??
}
}
return TRUE;
}
BOOL Game:: FindFirst(DWORD Value)
{
const DWORD OneGB = 1024 * 1024 * 1024; // 1GB
const DWORD OnePage = 4 * 1024; // 4KB
if (ToAimProcessHandle == NULL)
return FALSE;
// 查看操作系统类型,以决定开始地址
DWORD BaseAddress;
OSVERSIONINFO vi = { sizeof(vi) };
::GetVersionEx(&vi);
if (vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
BaseAddress = 4 * 1024 * 1024; // Windows 98系列,4MB
else
BaseAddress = 640 * 1024; // Windows NT系列,64KB
// 在开始地址到2GB的地址空间进行查找
for (; BaseAddress < 2 * OneGB; BaseAddress += OnePage)
{
// 比较1页大小的内存
CompareAPage(BaseAddress, Value);
}
IsOK = FALSE;
return TRUE;
}
BOOL Game::FindNext(DWORD Value)
{/*第二次不是从原先进程内存中查找所以直接是进行一个计数而已*/
// 保存m_arList数组中有效地址的个数,初始化新的m_nListCnt值
int Count = m_GameCount;//有效个数
m_GameCount = 0;
// 在m_arList数组记录的地址处查找
BOOL IsOK = FALSE; // 假设失败
DWORD ReadValue;
for (int i = 0; i<Count; i++)
{
if (::ReadProcessMemory(ToAimProcessHandle, (LPVOID)m_AddressList[i], &ReadValue, sizeof(DWORD), NULL))
{
if (ReadValue == Value)
{
m_AddressList[m_GameCount++] = m_AddressList[i];
IsOK = TRUE;
}
}
}
return TRUE;
}
BOOL Game::WriteMemory(DWORD Address, DWORD Value)
{
return WriteProcessMemory(ToAimProcessHandle, (LPVOID)Address, (LPCVOID)Value, sizeof(Value), NULL);
}
main函数中的代码:
#include"HelloGame.h"
#include<Windows.h>
#include<iostream>
using namespace std;
Game GamePlay;
DWORD m_AddressList[4096];
ULONG GameListCount;
HANDLE ProcessHandle;
int main()
{
WCHAR FileName[] = L"..\\debug\\02testor.exe";
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
BOOL IsOK=CreateProcess(NULL, FileName, NULL, NULL, FALSE,
CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
if (IsOK == FALSE)
{
return NULL;
}
// 关闭线程句柄,既然我们不使用它
::CloseHandle(pi.hThread);
GamePlay.ToAimProcessHandle = pi.hProcess;
int ChangeValue;
printf("输入改变的值");
scanf("%d", &ChangeValue);
GamePlay.FindFirst(ChangeValue);
GamePlay.ShowData();
while (GamePlay.m_GameCount > 1)
{
printf("二次查询:%d\r\n");
scanf("%d", &ChangeValue);
// 进行下次搜索
GamePlay.FindNext(ChangeValue);
// 显示搜索结果
GamePlay.ShowData();
}
}