前置知识:5.模仿CheatEngine实现锁血无敌功能(封装它的代码)
封装功能.cpp文件
#include "封装功能.h"
GAMECheat::GAMECheat(unsigned pid, unsigned _baseAdr, unsigned _readTime)
{
readTime = _readTime;
baseAdr = _baseAdr;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
}
bool GAMECheat::ReadData(unsigned readTick)
{
if(!readTick) return false;
lastRead = readTick;
return ReadProcessMemory(hProcess, (LPCVOID)baseAdr,this, sizeof(JianXiaGameRole), 0);
}
JianXiaGameRole& GAMECheat::Data(bool IsCheckTime)
{
if (!IsCheckTime)return _data;
unsigned dTickNow = GetTickCount();
if ((dTickNow - lastRead) > readTime)ReadData(dTickNow);
return _data;
}
void GAMECheat::SetData(void* dataAdr, void* buffer, SIZE_T length)
{
LPVOID destAdr = (LPVOID)((unsigned)dataAdr - (unsigned)this + baseAdr);
WriteProcessMemory(hProcess, destAdr, buffer, length, 0);
}
封装功能.h文件
#pragma once
#include <Windows.h>
struct JianXiaGameRole
{
int unknown1[4];
int hp;
int maxHp;
int tiLi;
int maxTiLi;
int mp;
int maxMp;
int gongJiLi;
int fangYu;
int shenFa;
int dengJi;
int unknown2;
int jingYan;
int shengJi;
int yiDongSuDu;
int unknown3;
int mianXiang;
int unknown4[2];
int xZuoBiao;
int yZuoBiao;
int unknown5[36];
char name[0x20];
};
class GAMECheat {
public:
// 通过构造函数初始化需要的数据,pid是进程id、_baseAdr是游戏中人物属性结构的首地址、_readTime读取内存的间隔时间
GAMECheat(unsigned pid, unsigned _baseAdr, unsigned _readTime =100);
// IsCheckTime为true会读取内存,false不读取内存目的提升效率
JianXiaGameRole& Data(bool IsCheckTime=false);
// 给进程写数据,也就是设置人物属性的值
void SetData(void * dataAdr, void*buffer, SIZE_T length);
private:
// 这个_data必须要放在第一个,如果不放在第一个我们就无法用this来表示 JianXiaGameRole 结构了那样就要多写点代码
JianXiaGameRole _data;
bool ReadData(unsigned readTick);
HANDLE hProcess;
unsigned baseAdr;
unsigned lastRead;
unsigned readTime;
};
main代码:
#include "封装功能.h"
#include <iostream>
#define P(data,x) &data, &x,sizeof(x)
int main() {
unsigned pid;
std::cout << "请输入游戏进程ID:";
std::cin >> pid;
GAMECheat gcheat(pid, 0x4CEF08);
std::cout << "角色名称:" << gcheat.Data(1).name << std::endl;
std::cout << "血量:" << gcheat.Data().hp << std::endl;
int hp = 0;
gcheat.SetData(P(gcheat.Data().hp, hp));
system("pause");
}