Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在C+中编辑操作码、写入内存或编辑字节+;?_C++_Pointers_Reverse Engineering_Memory Editing - Fatal编程技术网

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

C++ 如何在C+中编辑操作码、写入内存或编辑字节+;?,c++,pointers,reverse-engineering,memory-editing,C++,Pointers,Reverse Engineering,Memory Editing,我正在编辑一款名为“攻击立方体”的游戏,可在以下网址找到: 我不知道该如何描述它,所以我制作了一个我这样做的视频: 请注意,我的弹药在编辑之前就已经放下了。编辑后,弹药保持不变。基本上,在0x45B75F,我需要插入两个NOP 我在互联网上发现了以下内容: 一, 所以我试着做: BYTE NewBytes[] = { 0x90, 0x90 }; *(PBYTE)0x45B75F[0] = NewBytes; 但我得到了这个错误:错误C2109:下标需要数组或指针类型 二, 我宁愿不使用memc

我正在编辑一款名为“攻击立方体”的游戏,可在以下网址找到:

我不知道该如何描述它,所以我制作了一个我这样做的视频:

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

我在互联网上发现了以下内容:

一,

所以我试着做:

BYTE NewBytes[] = { 0x90, 0x90 };
*(PBYTE)0x45B75F[0] = NewBytes;
但我得到了这个错误:
错误C2109:下标需要数组或指针类型

二,

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

三,

同样,我不想使用一种方法

四,

以上给出了以下错误:

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
五,

这会导致崩溃。

1。 你在这里两次取消引用。你想要的是:

*((BYTE *) (0x45B75F + 0)) = NewBytes[0];
*((BYTE *) (0x45B75F + 1)) = NewBytes[1];
覆盖代码时,需要确保执行时没有运行要覆盖的代码。否则,您可能会引入竞争条件,在这种情况下,您会在短时间内意外引入无效或不需要的指令。您可以研究执行二进制重写的原子操作(如果适用)

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

code[0] = byte0;
code[1] = byte1;
etc.
三,。 为什么要避免使用此功能?我不熟悉windows,但这似乎是写入另一个进程内存的标准方式

四,。
uint8_t
stdint.h
C99标准库标题中定义;你必须把它包括在内。未声明的
code
错误是前一个
uint8\t
错误的副作用

五,。 这并非不合理。您正在将一个
NOP
注入到一个假定的定义良好的地址中,而不考虑要覆盖什么。举个简单的例子:

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

这可能不起作用的另一个原因是,调试器(在您的例子中是OllyDbg)通常(至少在Mac和Linux上)以与本机运行进程时操作系统不同的方式布置正在调试的进程的地址空间。这意味着类似于
0x45B75F
的地址在调试器中可能有意义,但在尝试对本机进程的内存进行操作时可能没有意义


这可能不起作用的第三个原因是,对内存的写入(没有来自您的更多信息)似乎在您进程的内存上运行,而不是在另一个进程的内存上运行(除非您正试图这样做)。如果内存地址被映射,它可能仍然无法写入(由于页面保护)。

我正在使用DLL注入,因此我正在游戏进程的内存中写入。你会推荐五种方法中的哪一种?我之所以想避免使用memcpy或WriteProcessMemory,是因为我想了解内存是如何被编辑的。可以通过在调试器中减去两个地址来实现这一点:下一个指令地址和要覆盖的指令地址。然后找到一种方法来编写这么多的NOP(例如memcpy)。然后找到一个可靠的方法来找到你需要写作的地方。例如,如果要覆盖的指令位于二进制文件开头的偏移量X处,则使用工具获取二进制文件文本部分的基址,添加X,然后在该点进行覆盖。
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
*(char*)0x45B75F = 0x90;
*((BYTE *) (0x45B75F + 0)) = NewBytes[0];
*((BYTE *) (0x45B75F + 1)) = NewBytes[1];
code[0] = byte0;
code[1] = byte1;
etc.