前置知识: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");
}
05-24 21:19