请教几个问题:准备做个单机游戏的内存修改器,发现没法找到程序内存基址,求助!通过网络查找,拼凑出如下代码:

莫名其妙的人参果 2017-05-17 06:31:35
#include<iostream>  
#include<windows.h>
#include<TlHelp32.h>
#include<stdio.h>
using namespace std;

DWORD changeAsm(HANDLE mproc, DWORD pid);
DWORD huoqu(LPCWSTR procName);
DWORD huoqujizhi(LPCWSTR procName);
DWORD GetBaseAddr(DWORD pid);
int main()
{
LPCWSTR procName = L"QQ.exe"; //进程名
do{
DWORD jizhi;
DWORD pid;
pid = huoqu(procName);//获取游戏进程id
jizhi = huoqujizhi(procName);
if (jizhi != NULL){
printf("\n%ls进程基址= 0x%08X",procName, jizhi);

printf("\n%ls确认PID %u (0x %08X )\n", procName, pid, pid);
}

system("pause");
} while (1);
return 0;
}

DWORD huoqujizhi(LPCWSTR procName)
{
DWORD jizhi;
DWORD pid;
pid = huoqu(procName);//获取游戏进程id
if (!pid)
{
printf(" 无法进程,程序是否打开?\n");
return NULL;
}
HANDLE mProc = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if (mProc == NULL)
{
printf(" 无法获取进程权限\n");
return NULL;
}
//jizhi = GetBaseAddr(pid);

jizhi = changeAsm(mProc,pid);
return jizhi;

}

DWORD huoqu(LPCWSTR procName)
{
DWORD FAN = NULL;

PROCESSENTRY32 pe32;
//在使用这个结构前,先设置它的大小
pe32.dwSize = sizeof(pe32);
//给系统内所有的进程拍个快照

HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
printf(" 无法创建进程列表\n");
return NULL;
}
//遍历进程快照,轮流显示每个进程的信息
BOOL bMore = ::Process32First(hProcessSnap, &pe32);
while (bMore)
{

if (lstrcmpi(procName, pe32.szExeFile) == 0)
{

FAN = pe32.th32ProcessID;
break;
}
bMore = ::Process32Next(hProcessSnap, &pe32);
}

::CloseHandle(hProcessSnap);
return FAN;


}
//简单更改sub为add
DWORD changeAsm(HANDLE mproc, DWORD pid)
{
DWORD addressOfChange;//这个因为会变,所有遍历内存中的模块
HANDLE phSnapshot;
MODULEENTRY32 me32;//存放快照信息的结构体

phSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);//创建进程快照
if (phSnapshot == INVALID_HANDLE_VALUE)
{
printf(" 无法创建进程\n");
return NULL;
}
//使用之前先设置大小
me32.dwSize = sizeof(MODULEENTRY32);
if (!Module32First(phSnapshot, &me32))
{
printf(" 无法读取进程\n");
return NULL;
}
do
{
if (me32.th32ProcessID == pid)
{
addressOfChange = (DWORD)me32.modBaseAddr;

break;
}
} while (Module32Next(phSnapshot, &me32));

BYTE oldByte[8];
DWORD dwNum = 0;
if (!ReadProcessMemory(mproc, &addressOfChange, &oldByte, 8, &dwNum))
{
printf(" 无法读取内存\n");
return addressOfChange;
}
else{

printf(" 0x%08X\n", addressOfChange);
printf(" 0x%08X\n", oldByte);

return addressOfChange;
}
}
DWORD GetBaseAddr(DWORD pid)
{
HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
if (hModuleSnap == INVALID_HANDLE_VALUE)
{
MessageBox(NULL, L"创建进程失败", L"!", MB_OK);
}
MODULEENTRY32 me;
me.dwSize = sizeof(MODULEENTRY32);
Module32First(hModuleSnap, &me);
DWORD dwBaseAddr;
dwBaseAddr = (DWORD)me.modBaseAddr;
CloseHandle(hModuleSnap);
return dwBaseAddr;
}



以上代码是网络各处收集加以我的个人理解拼凑起来的...
多次测试后,PID能正确获取,这个没问题,但是获取之后的内存基址我无法确定是否正确(我觉得是错误的,因为我读取了该处内的值,然后用CE扫描不到.....)这里俩个问题:
1:获得的这个东西到底是不是指定程序的内存基址?
2:如果是,为什么我用CE扫不到这个值?如果不是...那我理解为基址到底是个什么东西?....
接着的问题:
3:以上代码ReadProcessMemory时候大半时间无法读取到,但是多次运行还是可以读取成功一回,请问这是什么原因?
4:我对修改器的理解是,找到游戏程序内存基址,然后找到数据的地址,算出偏移。以后修改器就直接改:基址+偏移的值。就达到目的了... 这个看法对么?
...全文
2248 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
baidu_38811692 2017-11-10
  • 打赏
  • 举报
回复
楼主,最后有用什么方法找到基址了吗
  • 打赏
  • 举报
回复
引用 6 楼 zhao4zhong1 的回复:
百度搜相关关键字。
嗯 .
  • 打赏
  • 举报
回复
引用 2 楼 u010611736 的回复:
http://www.cheatengine.org/downloads.php
刚刚下载了源代码... 64解压出错...只能用6.2,但是无法通过编译..好像是汇编那块出错了...然后还少一个头文件.... 你知道我要的那部分在哪里么....我还在一页页一行行猜....
赵4老师 2017-05-18
  • 打赏
  • 举报
回复
引用 2 楼 u010611736 的回复:
http://www.cheatengine.org/downloads.php
你这个头像和帖子内容是绝配呀!
walkereklaw 2017-05-18
  • 打赏
  • 举报
回复
http://www.cheatengine.org/downloads.php
赵4老师 2017-05-18
  • 打赏
  • 举报
回复
Cheat Engine不知道是不是开源的。
赵4老师 2017-05-18
  • 打赏
  • 举报
回复
百度搜相关关键字。
zwfgdlc 2017-05-18
  • 打赏
  • 举报
回复
ReadProcessMemory()之前先用VirtualQueryEx确定内存是否可读

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧