2

I've been trying to code a client for a game in java (I'll be honest: Minecraft). But this does not only apply to Minecraft, it applies generally to the java virtual machine architecture, or so I presume. Basically, I'm using Cheat Engine to find memory addresses, and I've found the address that seems to correspond to the health value of the player.

The problem is: it is impossible to modify it, and so the question is: Am I doing something wrong, or is there a mechanism that restricts the modification of memory in the JVM?

To give you a little background: I'm using C# to read/write memory from and to processes. The way I achieve this is by using external functions provided by kernel.dll (more information about it here: https://stackoverflow.com/a/4623200/6817922). I also have a function that simplifies the writing task:

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)
}

However, when I run the program with code as such:

Write(0xCDD9BEA0, new byte[] { 20 }); // 0xCDD9BEA0 is the memory address of health.

the program executes correctly and the function 'Write' returns that it had written to the memory address successfully, yet it didn't (because the game did not update; nor did the Cheat Engine interface). And this only occurs when I try to modify a JVM process. For example: if I were to edit some text in the process "notepad", it would edit it correctly, and the program would show the changes, as well as in Cheat Engine.

To go a bit further, the JVM process would not even allow Cheat Engine to modify the memory address; it would just reset it immediately. So the question still stands: Is there a mechanism in the JVM that prevents its memory from being modified externally?

1 Answers1

1

Yes, you can modify memory of a Java process if a user has enough priviliges (i.e. Administrator). This is basically the OS capability; JVM does not do (and it cannot do) anything to prevent from this.

Furthermore, JVM can even assist with such modifications. There is public API to attach an agent to a running JVM process; then the agent can use standard JNI and JVM TI interfaces to access loaded classes, modify object fields, call arbitrary Java methods etc.

I can't say why Cheat Engine does not work in your case - this is likely the problem of the engine - but there is a number of possible reasons why this can happen.

For example, the value you try to modify is cached in a register and is not read from memory. Whenever the value changes (in a register) it is probably written back to the memory, and that's why you see the value 'reset'.

Also note that Java objects do not necessarily have a fixed address in memory. Garbage Collector may move objects across heap, and this makes the job of Cheat Engine harder.

The right way to 'patch' Java application in runtime would be to use standard APIs like JNI / JVM TI / Instrumentation API, that handle all the cases that non-Java utilities can't.

apangin
  • 92,924
  • 10
  • 193
  • 247