#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:我对修改器的理解是,找到游戏程序内存基址,然后找到数据的地址,算出偏移。以后修改器就直接改:基址+偏移的值。就达到目的了... 这个看法对么?
8 个解决方案
#1
Cheat Engine不知道是不是开源的。
#2
http://www.cheatengine.org/downloads.php
#3
你这个头像和帖子内容是绝配呀!
#4
刚刚下载了源代码... 64解压出错...只能用6.2,但是无法通过编译..好像是汇编那块出错了...然后还少一个头文件....
你知道我要的那部分在哪里么....我还在一页页一行行猜....
#5
ReadProcessMemory()之前先用VirtualQueryEx确定内存是否可读
#6
百度搜相关关键字。
#7
嗯 .
#8
楼主,最后有用什么方法找到基址了吗
#1
Cheat Engine不知道是不是开源的。
#2
http://www.cheatengine.org/downloads.php
#3
你这个头像和帖子内容是绝配呀!
#4
刚刚下载了源代码... 64解压出错...只能用6.2,但是无法通过编译..好像是汇编那块出错了...然后还少一个头文件....
你知道我要的那部分在哪里么....我还在一页页一行行猜....
#5
ReadProcessMemory()之前先用VirtualQueryEx确定内存是否可读
#6
百度搜相关关键字。
#7
嗯 .
#8
楼主,最后有用什么方法找到基址了吗