C++ 如何使用来自 CE 的包含浮点数的给定地址来执行 read/writeprocess?
C++ How can i do read/writeprocess with a given address from CE that contains a float?
我目前正在为游戏训练师开发传送功能。我找到了包含浮点数的正确静态地址:
picture of addresses with offsets
这个地址指向我的 X 坐标。现在我正在尝试使用 read/write processmemory 更改我的 X 坐标(浮点数)。但是无论我做什么都行不通(我对更改普通整数没有任何问题)。我想用我之前选择的浮点数替换该值。
有人可以给我一个详细的例子吗?
提前致谢
1) 获取进程基址 - Getting base address of a process
hprocess 是句柄,将 openprocess 返回值传递给那里 (https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx)
2) 将'teleport'偏移量添加到基址
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));
你需要检查错误,这只是伪代码,让你知道你需要做什么,还要确保你 运行 你的培训师是管理员并且可以访问游戏内存
您必须读取指针并添加指针的相对偏移量才能到达传送地址。
您可以使用 WriteProcessMemory() 直接写入进程内存,并使用 ReadProcessMemory() 从内存读取。
但是,如果您正在阅读 二三 级指针,这样做会变得很麻烦。
所以我建议使用 Game Trainer 或内存破解库 轻松地 read/write 指针。
你可以使用 GTLibc Game Trainer libray for C/C ++。
GTLibc Game trainer library
或者您可以使用 Memory.dll 用于 C# 的游戏黑客库。
Memory.dll
改为在内部进行
Readprocessmemory 和 writeprocessmemory 会相对简单,但更好的选择是将 DLL 注入目标进程以提高速度和简单性。您可以使用 *
手动遵从,或者执行首选方法并设置具有适当大小的 classes,这样您就不必以相同的方式处理偏移量。查看 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;
}
然后在您的静态偏移量处声明一个实例,并且read/write像它是您自己的内存一样。
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);
}
}
那么我建议设置模板来为您完成 reading/writing。
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 中的每个元素,不如这样做更好:
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;
}
将每个 class* 替换为 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 只是推送字节,它不关心类型。当整数和浮点数使用小端字节序进行不同编码时,您可能将整数的地址作为要写入的缓冲区传递。确保将其声明为浮点数,或者更好的是,使用模板。或者更好的是,只写一个 dll :)
我目前正在为游戏训练师开发传送功能。我找到了包含浮点数的正确静态地址:
picture of addresses with offsets
这个地址指向我的 X 坐标。现在我正在尝试使用 read/write processmemory 更改我的 X 坐标(浮点数)。但是无论我做什么都行不通(我对更改普通整数没有任何问题)。我想用我之前选择的浮点数替换该值。
有人可以给我一个详细的例子吗?
提前致谢
1) 获取进程基址 - Getting base address of a process hprocess 是句柄,将 openprocess 返回值传递给那里 (https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx)
2) 将'teleport'偏移量添加到基址
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));
你需要检查错误,这只是伪代码,让你知道你需要做什么,还要确保你 运行 你的培训师是管理员并且可以访问游戏内存
您必须读取指针并添加指针的相对偏移量才能到达传送地址。
您可以使用 WriteProcessMemory() 直接写入进程内存,并使用 ReadProcessMemory() 从内存读取。
但是,如果您正在阅读 二三 级指针,这样做会变得很麻烦。
所以我建议使用 Game Trainer 或内存破解库 轻松地 read/write 指针。
你可以使用 GTLibc Game Trainer libray for C/C ++。 GTLibc Game trainer library
或者您可以使用 Memory.dll 用于 C# 的游戏黑客库。 Memory.dll
改为在内部进行
Readprocessmemory 和 writeprocessmemory 会相对简单,但更好的选择是将 DLL 注入目标进程以提高速度和简单性。您可以使用 *
手动遵从,或者执行首选方法并设置具有适当大小的 classes,这样您就不必以相同的方式处理偏移量。查看 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;
}
然后在您的静态偏移量处声明一个实例,并且read/write像它是您自己的内存一样。
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);
}
}
那么我建议设置模板来为您完成 reading/writing。
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 中的每个元素,不如这样做更好:
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;
}
将每个 class* 替换为 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 只是推送字节,它不关心类型。当整数和浮点数使用小端字节序进行不同编码时,您可能将整数的地址作为要写入的缓冲区传递。确保将其声明为浮点数,或者更好的是,使用模板。或者更好的是,只写一个 dll :)