• S'inscrire
    • Se connecter
    • Recherche
    • Récent
    • Mots-clés
    • Populaire
    • Utilisateurs
    • Groupes

    Résolu ASM INVOKE et obfuscation

    1.7.x
    1.7.10
    2
    9
    1594
    Charger plus de messages
    • Du plus ancien au plus récent
    • Du plus récent au plus ancien
    • Les plus votés
    Répondre
    • Répondre à l'aide d'un nouveau sujet
    Se connecter pour répondre
    Ce sujet a été supprimé. Seuls les utilisateurs avec les droits d'administration peuvent le voir.
    • MasterCat
      MasterCat dernière édition par

      Bonjour,

      Je vais poster mon premier “casse tête” 😄

      Contexte:

      • Je développe actuellement un coremod dans lequel j’utilise pas mal d’ASM
      • Minecraft version: 1.7.10
      • Forge build: 1.7.10-10.13.4.1614-1.7.10
      • Java: 1.8.0_66
      • Le mod est server side only

      J’utilise l’ASM pour modifier la partie handshake et login des joueurs pour gérer plusieurs protocole dont celui de l’ip forwarding de bungeecord.
      Je procède toujours de la même façon, dans une méthode donné, je rajouter un appel via INVOKESTATIC par exemple pour appeler une fonction static de mes class qui vont modifier le fonctionnement de la fonction.

      Jusque la, pas de soucis, en environnement de dev tout marche nikel, le probleme surviens quand je veux distribuer le mod, et le tester en “production”.
      Mon injection fonctionne nikel, ma fonction ajouté est bien appelé, mais par exemple si à l’intérieur je veux utiliser un ChatComponentText pour “kick” le joueur avec un message d’erreur, je revoit une java.lang.NoClassDefFoundError sur net/minecraft/util/IChatComponent.

      Du coup ma fonctionne marche nikel si j’enlève la partie message derreur, mais ça me gêne pas mal, j’aimerai comprendre comment corriger ça.

      Je peux faire un code allégé pour montrer mon problème si besoin

      1 réponse Dernière réponse Répondre Citer 0
      • robin4002
        robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par

        Salut,
        Possible d’avoir le crash complet ?

        1 réponse Dernière réponse Répondre Citer 0
        • MasterCat
          MasterCat dernière édition par

          @‘robin4002’:

          Salut,
          Possible d’avoir le crash complet ?

          Bien sur, mais je suis pas sur que ça vas t’aider 😄

          A problem occurred running the Server launcher.[16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: java.lang.reflect.InvocationTargetException
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at java.lang.reflect.Method.invoke(Unknown Source)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at cpw.mods.fml.relauncher.ServerLaunchWrapper.run(ServerLaunchWrapper.java:43)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at cpw.mods.fml.relauncher.ServerLaunchWrapper.main(ServerLaunchWrapper.java:12)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: Caused by: java.lang.NoClassDefFoundError: net/minecraft/util/IChatComponent
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at fr.littlebigcraft.asm.MasterClassTransformer.<clinit>(MasterClassTransformer.java:53)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at java.lang.reflect.Constructor.newInstance(Unknown Source)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at java.lang.Class.newInstance(Unknown Source)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at net.minecraft.launchwrapper.LaunchClassLoader.registerTransformer(LaunchClassLoader.java:88)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at cpw.mods.fml.relauncher.CoreModManager$FMLPluginWrapper.injectIntoClassLoader(CoreModManager.java:108)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at net.minecraft.launchwrapper.Launch.launch(Launch.java:115)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   … 6 more
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: Caused by: java.lang.ClassNotFoundException: net.minecraft.util.IChatComponent
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:191)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at java.lang.ClassLoader.loadClass(Unknown Source)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at java.lang.ClassLoader.loadClass(Unknown Source)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   … 16 more
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: Caused by: java.lang.NullPointerException
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:182)
          [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   … 18 more
          
          ```</clinit>
          1 réponse Dernière réponse Répondre Citer 0
          • robin4002
            robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par

            En effet.
            Je m’attendais à voir dans le deuxième ClassNotFoundException un détail, dès fois il indique que le byte code de la classe en question est invalide par exemple.

            Mais là ce n’est pas le cas, donc c’est juste qu’il ne trouve pas la classe comme si elle n’était pas là …

            Le mod est sur un serveur forge ou cauldron ?

            Maintenant je comprends pourquoi tu parlais de problème tordu x)

            ÉDIT : tu pourrai aussi envoyer le code de la classe MasterClassTransformer ?

            1 réponse Dernière réponse Répondre Citer 0
            • MasterCat
              MasterCat dernière édition par

              @‘robin4002’:

              Maintenant je comprends pourquoi tu parlais de problème tordu x)

              J’avais prévenu 😉

              Le serveur est pure forge, pour mes test j’utilise un serveur forge de la version 1.7.10-10.13.4.1614-1.7.10 sans aucun autre mod, avec comme seul librairy ajouté le connector mySQL (mais pas utilisé pour cette partie du code).

              Concernant les bytecode je pense avoir plutôt bien géré cette partie la, car en environnement deobfuscate ça marche nikel, et en obfuscate ça marche si j’envoie pas ce fichu ChatConponant au joueur; mais si j’affiche un bête message dans la console il apparait bien :s

              PS: concernant

              [16:03:59] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]:   at fr.littlebigcraft.asm.MasterClassTransformer.<clinit>(MasterClassTransformer.java:53)
              

              Je fait un simple ajout dans une liste d’un objet qui soccupe de modifier le bytcode

              cTransformerList.add(new NetHandlerHandshakeTCPTransformer());
              

              et la class NetHandlerHandshakeTCPTransformer n’a pas de constructeur définit</clinit>

              1 réponse Dernière réponse Répondre Citer 0
              • MasterCat
                MasterCat dernière édition par

                Alors je vais envoyer seulement les partie utile, car le code est plutôt long 😄

                private static final List <iclassnodetransformer>cTransformerList = new ArrayList<iclassnodetransformer>();
                
                […]
                
                static {
                   cTransformerList.add(new C00HandshakeTransformer());
                   cTransformerList.add(new NetworkManagerTransformer());
                   cTransformerList.add(new NetHandlerHandshakeTCPTransformer()); // la ligne 53
                   cTransformerList.add(new NetHandlerLoginServerTransformer());
                }
                
                […]
                
                @Override
                public byte[] transform(String name, String transformedName, byte[] bytes) {
                
                   if (bytes == null)
                       return null;
                
                   for (IClassNodeTransformer ct : cTransformerList) {
                    if (transformedName.equals(ct.getClassName())) {
                    boolean isObfuscate = !name.equals(transformedName);
                           ClassNode classNode = new ClassNode();
                           ClassReader classReader = new ClassReader(bytes);
                           classReader.accept(classNode, 0);
                
                           ct.transform(classNode, isObfuscate);
                
                           ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
                           classNode.accept(classWriter);
                           bytes = classWriter.toByteArray();
                    break;
                    }
                   }
                
                   return bytes;
                }
                
                […]
                

                Edit: la partie transform de la class NetHandlerHandshakeTCPTransformer

                @Override
                public void        transform(ClassNode classNode, boolean isObfuscate) {
                    final String    targetMethod        = isObfuscate ? "a" : "processHandshake";
                    final String    targetMethodDesc    = isObfuscate ? "(Ljp;)V" : "(Lnet/minecraft/network/handshake/client/C00Handshake;)V";
                
                    for (MethodNode m : classNode.methods) {
                        if ((m.name.equals(targetMethod) && (m.desc.equals(targetMethodDesc)))) {
                               CatLog.info("Injection du NetHandlerHandshakeTCP: processHandshake");
                
                               InsnList    newBlock    = new InsnList();
                
                               newBlock.add(new VarInsnNode(ALOAD, 1));
                               newBlock.add(new VarInsnNode(ALOAD, 0));
                
                               if (isObfuscate)
                                   newBlock.add(new FieldInsnNode(GETFIELD, "nl", "b", "Lej;"));
                               else
                                   newBlock.add(new FieldInsnNode(GETFIELD, "net/minecraft/server/network/NetHandlerHandshakeTCP", "field_147386_b", "Lnet/minecraft/network/NetworkManager;"));
                
                            final String    methodDesc        = isObfuscate ? "(Ljp;Lej;)V" : "(Lnet/minecraft/network/handshake/client/C00Handshake;Lnet/minecraft/network/NetworkManager;)V";
                
                               newBlock.add(new MethodInsnNode(INVOKESTATIC, "fr/littlebigcraft/transformers/NetHandlerHandshakeTCPTransformer", "onProcessHandshakeStart", methodDesc, false));
                
                               m.instructions.insert(newBlock);
                
                               break;
                        }
                    }
                }
                ```</iclassnodetransformer></iclassnodetransformer>
                1 réponse Dernière réponse Répondre Citer 0
                • robin4002
                  robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par

                  Et du-coup j’imagine que net.minecraft.util.IChatComponent est utilisé quelque part dans la classe NetHandlerHandshakeTCPTransformer ?

                  Ce qui cause surement problème c’est donc la façon dont le jeu en prod fonctionne.

                  En dev c’est très simple comme tous passe les noms proposés par les mappings (=nom mcp).
                  Un prod c’est plus complexe, de base le code est comme fourni par mojang (100% obf, donc avec des classes nommées a, aa, etc … et des fonctions/fields du même nom = nom notch). Lors du lancement, le byte code passe par un transformer qui fait donne un nom correcte aux classes et nomme les field et fonction en field_xxxx et func_xxx (=nom srg).
                  Le transformer des différents coremod est surement appliqué au même moment ou avant.
                  Du-coup au moment où ton mod cherche “net.minecraft.util.IChatComponent”, il devrait plutôt chercher “fj”

                  Donc faudrait soit get la classe fj par réflexion, soit faire en sorte qu’elle soit chargé plus tard.

                  1 réponse Dernière réponse Répondre Citer 0
                  • MasterCat
                    MasterCat dernière édition par

                    En gros j’ai une autre method static dans cette class comme ca:

                    public static void    onProcessHandshakeStart(C00Handshake packetIn, NetworkManager networkManager) {
                    

                    et c’est la dedans que j’utilise le ChatConponent
                    Elle est appelé via ASM comme ceci:

                    final String    methodDesc        = isObfuscate ? "(Ljp;Lej;)V" : "(Lnet/minecraft/network/handshake/client/C00Handshake;Lnet/minecraft/network/NetworkManager;)V";
                    
                    newBlock.add(new MethodInsnNode(INVOKESTATIC, "fr/littlebigcraft/transformers/NetHandlerHandshakeTCPTransformer", "onProcessHandshakeStart", methodDesc, false));
                    
                    

                    C’est pas grave si j’ai pas de solution, je vais rajouter le code de ma fonction entièrement en bytecode, comme ca aucun prob dobfuscation car je pourrai le gérer manuellement.

                    1 réponse Dernière réponse Répondre Citer 0
                    • MasterCat
                      MasterCat dernière édition par

                      Problème résolu en réglant l’autre problème mystérieux,

                      Merci pour ta patience.

                      1 réponse Dernière réponse Répondre Citer 0
                      • 1 / 1
                      • Premier message
                        Dernier message
                      Design by Woryk
                      Contact / Mentions Légales

                      MINECRAFT FORGE FRANCE © 2018

                      Powered by NodeBB