gpt4 book ai didi

c++ - 如何在 C++ 中编辑操作码或写入内存或编辑字节?

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:50:43 31 4
gpt4 key购买 nike

我正在内存编辑一个名为 Assault Cube 的游戏,可以在以下位置找到:http://assault.cubers.net/

我不确定如何描述它,所以我制作了一段视频:www.youtube.com/watch?v=SS1swxQIbDI

请注意,我的弹药在编辑之前就没电了。编辑后,弹药保持不变。基本上,在 0x45B75F,我需要插入两个 NOP。

我在网上找到了以下内容:

1.

BYTE NewBytes[] = { 0xXX, 0xXX, 0xXX, 0xXX, 0xXX };
*(PBYTE)0xXXXXXXXX[0] = NewBytes;

所以我尝试这样做:

BYTE NewBytes[] = { 0x90, 0x90 };
*(PBYTE)0x45B75F[0] = NewBytes;

但是我得到这个错误:error C2109: subscript requires array or pointer type

2.

DWORD origProtect;
VirtualProtect( ( void* )0x77D142CF, 5, PAGE_EXECUTE_READWRITE, &origProtect );
memcpy( ( void* )0x77D142CF, "\x8B\xFF\x55\x8B\xEC", 5 );
VirtualProtect( ( void* )0x77D142CF, 5, origProtect, NULL );

我宁愿不使用 memcpy 或任何方法。

3.

char val = 0x48;
BOOL success = WriteProcessMemory(target, 0x10134CE0, &val, 1, NULL);

同样,我宁愿不使用方法。

4.

uint8_t* code = (uint8_t*)0x45B75F;
*code = 0x90;

上面给出了这些错误:

error C2065: 'uint8_t' : undeclared identifier
error C2065: 'code' : undeclared identifier
error C2065: 'uint8_t' : undeclared identifier
error C2059: syntax error : ')'
error C2065: 'code' : undeclared identifier

5.

*(char*)0x45B75F = 0x90;

这会导致崩溃。

最佳答案

1.你在这里双重取消引用。你想要的是:

*((BYTE *) (0x45B75F + 0)) = NewBytes[0];
*((BYTE *) (0x45B75F + 1)) = NewBytes[1];

覆盖代码时,您需要确保执行的不是您要覆盖的代码。否则,您可能会引入竞争条件,在这种情况下,您会在短时间内不小心引入无效或不需要的指令。您可能会研究用于执行二进制重写的原子操作(如果适用)。

2。您对此处 memcpy 的厌恶似乎值得怀疑。编译器可能会将 memcpy 优化为双字 - MOV,然后是单字节 MOV。您可以通过将 5 个字节编码为一个 32 位整数和一个字节来强制解决此问题。或者,您可以连续写入 5 次内存,编译器可能会自动组合它们。例如:

code[0] = byte0;
code[1] = byte1;
etc.

3。为什么要避免使用此功能?我不熟悉 Windows,但这似乎是写入另一个进程内存的标准方法。

4.uint8_t定义在stdint.h C99标准库头文件中;你必须包括它。关于 code 未声明的错误是前一个 uint8_t 错误的副作用。

5.这不无道理。您将 NOP 注入(inject)到假定的定义明确的地址中,而不管您要覆盖什么。以这个简单的例子为例:

假设我在内存中有一条指令调用I1,它占用两个字节:[I1_0, I1_1]。现在,您正在做的可能是用 NOP 覆盖其中一个字节,而不考虑周围的字节是否仍将作为指令有效,例如[0x90, I1_1][I1_0, 0x90]。如果单独的 I1_0I1_1 是无效的操作码序列,那么程序当然会崩溃!

这可能不起作用的另一个原因是调试器(在您的情况下为 OllyDbg)以不同于操作系统的方式布置被调试进程的地址空间是很常见的(至少在 Mac 和 Linux 上)将在 native 运行进程时。这意味着像 0x45B75F 这样的地址在调试器中可能有意义,但在尝试对 native 进程的内存进行操作时却毫无意义。

这可能不起作用的第三个原因是写入内存(没有你的更多信息)似乎是在你进程的内存上运行而不是另一个进程的内存(除非那是你试图做)。即使该内存地址已映射,它仍然可能无法写入(由于页面保护)。

关于c++ - 如何在 C++ 中编辑操作码或写入内存或编辑字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16259499/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com