【问题标题】:Can you modify Java's (more specifically javaw's) memory externally during runtime?您可以在运行时在外部修改 Java(更具体地说是 javaw)的内存吗?
【发布时间】:2017-08-13 04:46:40
【问题描述】:

我一直在尝试为 java 中的游戏编写客户端代码(老实说:Minecraft)。但这不仅适用于 Minecraft,它通常适用于 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.

程序正确执行,“Write”函数返回它已成功写入内存地址,但没有成功(因为游戏没有更新;Cheat Engine 界面也没有更新)。这只发生在我尝试修改 JVM 进程时。例如:如果我要在“记事本”进程中编辑一些文本,它会正确编辑,并且程序会显示更改,以及在作弊引擎中。

更进一步,JVM进程甚至不允许作弊引擎修改内存地址;它会立即重置它。所以问题仍然存在:JVM 中是否有防止其内存被外部修改的机制?

【问题讨论】:

    标签: c# jvm


    【解决方案1】:

    是的,如果用户有足够的权限(即管理员),您可以修改 Java 进程的内存。这基本上是操作系统的能力; JVM 不做(也不能做)任何事情来防止这种情况发生。

    此外,JVM 甚至可以协助进行此类修改。有public API 将代理附加到正在运行的JVM 进程;然后代理可以使用标准的JNIJVM TI 接口来访问加载的类、修改对象字段、调用任意Java 方法等。

    我不能说为什么 Cheat Engine 在你的情况下不起作用 - 这可能是引擎的问题 - 但有很多可能的原因导致这种情况发生。

    例如,您尝试修改的值缓存在寄存器中,而不是从内存中读取。每当值更改(在寄存器中)时,它可能会被写回内存,这就是为什么您会看到值 'reset'

    还要注意,Java 对象在内存中不一定具有固定地址。垃圾收集器可能会跨堆移动对象,这使得作弊引擎的工作变得更加困难。

    在运行时“修补”Java 应用程序的正确方法是使用标准 API,如 JNI / JVM TI / Instrumentation API,它们可以处理非 Java 实用程序无法处理的所有情况。

    【讨论】:

      猜你喜欢
      • 2017-08-13
      • 1970-01-01
      • 2011-01-25
      • 1970-01-01
      • 2014-01-05
      • 1970-01-01
      • 2015-09-30
      • 2010-09-19
      • 1970-01-01
      相关资源
      最近更新 更多