2017-08-13 4 views
2

J'ai essayé de coder un client pour un jeu en Java (je vais être honnête: Minecraft). Mais cela ne s'applique pas seulement à Minecraft, il s'applique généralement à l'architecture de machine virtuelle Java, ou je présume. Fondamentalement, j'utilise Cheat Engine pour trouver des adresses de mémoire, et j'ai trouvé l'adresse qui semble correspondre à la valeur de santé du joueur. Le problème est: il est impossible de le modifier, et donc la question est: est-ce que je fais quelque chose de mal, ou y a-t-il un mécanisme qui limite la modification de la mémoire dans la JVM?Pouvez-vous modifier la mémoire de Java (plus spécifiquement javaw) en externe pendant l'exécution?

Pour vous donner un peu d'arrière-plan: J'utilise C# pour lire/écrire de la mémoire depuis et vers les processus. La façon dont j'y parviens est en utilisant les fonctions externes fournies par kernel.dll (plus d'informations à ce sujet ici: https://stackoverflow.com/a/4623200/6817922). J'ai aussi une fonction qui simplifie la tâche d'écriture:

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

Cependant, quand je lance le programme avec le code en tant que tel:

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

le programme se termine correctement et la fonction « » Write renvoie que avait écrit à l'adresse de mémoire avec succès, mais il n'a pas (parce que le jeu n'a pas mis à jour, ni l'interface Cheat Engine). Et cela ne se produit que lorsque j'essaie de modifier un processus JVM. Par exemple: si je devais éditer du texte dans le processus "notepad", il le modifierait correctement, et le programme montrerait les changements, ainsi que dans Cheat Engine. Pour aller un peu plus loin, le processus JVM n'autoriserait même pas Cheat Engine à modifier l'adresse de la mémoire; il serait juste réinitialisé immédiatement. La question est donc toujours la suivante: y a-t-il un mécanisme dans la JVM qui empêche la modification externe de la mémoire?

Répondre

1

Oui, vous pouvez modifier la mémoire d'un processus Java si un utilisateur dispose de privilèges suffisants (administrateur). C'est essentiellement la capacité du système d'exploitation; La JVM ne fait rien (et ne peut rien faire) pour empêcher cela.

En outre, JVM peut même aider avec de telles modifications. Il existe public API pour attacher un agent à un processus JVM en cours d'exécution; alors l'agent peut utiliser des interfaces standard JNI et JVM TI pour accéder aux classes chargées, modifier les champs d'objet, appeler des méthodes Java arbitraires, etc.

Je ne peux pas dire pourquoi Cheat Engine ne fonctionne pas dans votre cas - il est probable que le problème de la le moteur - mais il y a un certain nombre de raisons possibles pour lesquelles cela peut arriver. Par exemple, la valeur que vous essayez de modifier est mise en cache dans un registre et n'est pas lue dans la mémoire. Par exemple, la valeur que vous essayez de modifier est mise en cache dans un registre. Chaque fois que la valeur change (dans un registre), elle est probablement réécrite dans la mémoire, et c'est pourquoi vous voyez la valeur 'réinitialiser'.

Notez également que les objets Java n'ont pas nécessairement d'adresse fixe en mémoire. Garbage Collector peut déplacer des objets à travers le tas, ce qui rend le travail de Cheat Engine plus difficile. La meilleure façon de «patcher» une application Java en cours d'exécution serait d'utiliser des API standard comme JNI/JVM TI/Instrumentation API, qui gèrent tous les cas que les utilitaires non-Java ne peuvent pas.