我一直试图用java编写一个客户端的代码(老实说:我的世界)。但这不仅适用于“我的世界”,也适用于java虚拟机体系结构,或者我认为是这样的。基本上,我使用欺骗引擎来查找内存地址,并且找到了似乎与播放器的健康值相对应的地址。
问题是:不可能修改它,所以问题是:我做错了什么,还是有一种机制限制JVM中内存的修改?
给您一些背景:我正在使用C#从进程读取/写入内存。实现这一目标的方法是使用kernel.dll提供的外部函数(更多关于它的信息:https://stackoverflow.com/a/4623200/6817922)。我还有一个函数可以简化写作任务:
public static bool Write(IntPtr address, byte[] value)
{
if(ProcessToEdit == null) // If the process is not valid: return with no attempt to edit
{
return false;
}
int bytesWritten = 0;
// Writes the byte[] value to a specified address
return WriteProcessMemory(ProcessPointer, address, value, (uint)value.LongLength, out bytesWritten)
}但是,当我以这样的代码运行程序时:
Write(0xCDD9BEA0, new byte[] { 20 }); // 0xCDD9BEA0 is the memory address of health.程序正确执行,函数“写”返回它成功写入内存地址的函数,但没有(因为游戏没有更新;欺骗引擎接口也没有)。只有当我试图修改JVM进程时,才会发生这种情况。例如:如果我要编辑进程“记事本”中的一些文本,它将正确地编辑它,程序将显示更改,以及在欺骗引擎中。
更进一步说,JVM进程甚至不允许欺骗引擎修改内存地址;它将立即重置它。因此,问题仍然存在: JVM中是否有一种机制可以防止外部修改其内存?
发布于 2017-08-13 13:08:11
是的,如果用户有足够的私密性(即管理员),您可以修改Java进程的内存。这基本上是操作系统的能力;JVM不做(也不能做)任何事情来防止这种情况发生。
此外,JVM甚至可以帮助进行这样的修改。有公共API将代理附加到正在运行的JVM进程;然后代理可以使用标准的JNI和JVM TI接口来访问加载的类、修改对象字段、调用任意的Java方法等等。
我不能说为什么在您的情况下欺骗引擎不工作-这很可能是引擎的问题-但有许多可能的原因,这可能会发生。
例如,试图修改的值被缓存在寄存器中,而不是从内存中读取。每当值发生变化(在寄存器中),它可能会被写回内存,这就是为什么您看到的值‘重置’。
还请注意,Java对象不一定在内存中有固定地址。垃圾收集器可能会在堆中移动对象,这使得欺骗引擎的工作更加困难。
在运行时对Java应用程序进行“修补”的正确方法是使用标准API,如JNI / JVM TI / Instrumentation,这些API可以处理所有非Java实用程序无法处理的情况。
https://stackoverflow.com/questions/45657170
复制相似问题