C 如何使用包含浮点的CE的给定地址进行阅读/写入



我目前正在为游戏培训师创作传送功能。我找到了包含浮子的正确静态地址:

带有偏移的地址的图片

此地址指向我的X坐标。现在,我正在尝试使用读/写入过程更改我的X坐标(float(。但是无论我做什么,它都无法使用(我在更改正常INT方面没有问题(。我想用我之前选择的浮子替换值。

有人可以给我一个详细的例子,我该怎么做?

预先感谢您

1(获取过程基础地址 - 获取过程的基础地址hprocess是处理方法,将其传递OpenProcess返回值(https://msdn.microsoft.com/en-us/library/windows/desktop/mss684320(v = vs.85(.aspx .aspx(

2(将"传送"偏移添加到基础地址

3(将给定的值写入进程的内存

HANDLE hProcess = openProcess(processId); //you also need to pass desired mode, use read & write
DWORD dwBaseAddress = getBaseAddress(hProcess): 
DWORD dwPositionAddress = dwBaseAddress + POSITION_OFFSET; 
float newPosition = 123.5;
WriteProcessMemory(hProcess, dwPositionAddress, &newPosition, sizeof(float));

您需要检查错误,这只是伪代码,可以让您了解您需要做什么,还请确保您以Admin的速度运行教练并可以访问Game的内存

您必须阅读指针,并添加指针将其相对偏移到传送地址。

您可以使用 writeProcessMemory((直接写入过程内存, readProcessMemory((从内存中读取。

但是,如果您正在阅读两三个级别指针,它将成为麻烦的方法。

您可以使用 gtlibc g ame t 用于C/C 的Rainer Libray。GTLIBC游戏教练库

或者您可以使用memore.dll游戏黑客库作为c#。memory.dll

内部进行

ReadProcessMemory和WriteProcessMemory将相对简单,但是更好的选择是将DLL注入目标过程中的速度和简单性。您可以使用*手动尊重,也可以执行首选方法并设置具有适当尺寸的类,因此您不必以相同的方式处理偏移。查看reclass.net以自动化此。

class unk3{
public:
    char pad_001[0x10];
    float location;
}
class unk2{
public:
    unk3* m_unk3;
}
class unk1{
public:
    char pad_001[0x78];
    unk2* m_unk2;
}

然后在您的静态偏移处声明一个实例,然后像您自己的内存一样读/写入/写入。

unk1* p_unk1 = (unk1*)(uintptr_t*)(OFFSET);
p_unk1->m_unk2->m_unk3->location = 300f;

使用rpm

如果您想进入外部,则需要首先打开该过程的手柄。

void attach(LPCSTR WindowName) {
    HWND hWindow = FindWindowA(NULL, WindowName); 
    if (hWindow)
    {
        GetWindowThreadProcessId(hWindow, &Proc_ID); 
        hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION/*PROCESS_ALL_ACCESS*/, FALSE, Proc_ID); 
        HANDLE hModule = INVALID_HANDLE_VALUE; 
        MODULEENTRY32 ePoint; 
        hModule = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, Proc_ID); 
        ePoint.dwSize = sizeof(MODULEENTRY32); 
        Module32First(hModule, &ePoint);
        base = (DWORD*)ePoint.modBaseAddr; 
        CloseHandle(hModule);
    }
}

然后,我建议您设置模板为您进行阅读/写作。

template <class T>
T read(DWORD_PTR Address){
    T buffer;
    ReadProcessMemory(this->hProcess, (LPCVOID)Address, &buffer, sizeof(buffer), NULL);
    return buffer;
}

然后几乎是写作的方法。然后执行将是:

DWORD_PTR p_unk1 = mem.read<DWORD_PTR>(OFFSET);
DWORD_PTR p_unk2 = mem.read<DWORD_PTR>(p_unk1 + 0x78);
DWORD_PTR p_unk3 = mem.read<DWORD_PTR>(p_unk2);
float location = mem.read<float>(p_unk3 + 0x10);

外部效率

而不仅仅是读书sizeof(dword_ptr(并阅读班级中的每个元素,如果您做这样的事情,则更好:

class unk3{
public:
    char pad_001[0x10];
    float location;
}
class unk2{
public:
    DWORD_PTR m_unk3;
}
class unk1{
public:
    char pad_001[0x78];
    DWORD_PTR m_unk2;
}

用dword_ptr

替换每个类*

然后用

执行它
unk1 p_unk1 = mem.read<unk1>(OFFSET);
unk2 p_unk2 = mem.read<unk2>(p_unk1.m_unk2);
unk3 p_unk3 = mem.read<unk3>(p_unk2.m_unk3);
float location = p_unk3.Location;

对于那些想知道的人,以这种方式写作:

mem.write<float>(p_unk2 + offsetof(unk3, location), value);

总结

在内部这样做的好处要好得多,麻烦减少。注意您的问题,WriteProcessMemory只是推入字节,它不在乎类型。当INT和Floats用Little Endian的编码不同时,您可能会将整数的地址作为缓冲区的编写。确保将其声明为浮点,或者更好地使用模板。甚至更好,只需写一个dll:(

最新更新