修改代码行

时间:2016-01-04 20:33:35

标签: java bytecode javassist

对于我正在做的项目,我需要使用javassist对外部jar文件中的方法进行字节码操作。这工作正常,除了我有一个源代码错误,我无法看出问题是什么。所以我创建了一个Exception变量,捕获了异常,并打印了消息和堆栈跟踪元素,如下所示:

StackTraceElement[] e = randomexception.getStackTrace();
System.out.println(randomexception.getMessage());
    for(int i = 0; i < e.length; i++){
        StackTraceElement ste = e[i];
        String s = ste.toString();
        System.out.println(s);
    }

我收到了这个错误:

cannot find java.net.SocketAddress
javassist.CtBehavior.insertAt(CtBehavior.java:1210)
RainbowBansTransAgent.Transformationer.transform(Transformationer.java:26)
RainbowBansTransAgent.Transformationer.transform(Transformationer.java:68)
sun.instrument.TransformerManager.transform(Unknown Source)
sun.instrument.InstrumentationImpl.transform(Unknown Source)
sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
sun.instrument.InstrumentationImpl.retransformClasses(Unknown Source)
RainbowBansTransAgent.TransAgent.premain(TransAgent.java:106)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
sun.instrument.InstrumentationImpl.loadClassAndStartAgent(Unknown Source)
sun.instrument.InstrumentationImpl.loadClassAndCallPremain(Unknown Source)

但是我的源代码根本没有调用SocketAddress类。我在内部编辑代码的方法确实如此,但我没有编辑该方法,所以我认为没有理由不这样做。

方法是:

checkIfShouldDisconnect(SocketAddress address)

我尝试使用ClassLoader.loadClass方法加载java.net.SocketAddress类。我也尝试将源代码放在括号中。我看了一下javassist的限制,但我的代码看起来很好。我将堆栈跟踪追溯到用于构造CannotCompileEception的NotFoundException。

我将在下面附上我的代码:

TransAgent.java

package RainbowBansTransAgent;

import java.io.File;
import java.io.IOException;
import java.lang.instrument.Instrumentation;
import java.util.ArrayList;
import java.util.jar.JarFile;

import javassist.ClassPool;
import javassist.NotFoundException;

public class TransAgent{

    public static TransAgent ta;
    public static ClassPool coldwater = new ClassPool();
    public static File dir = new File("RainbowBans");
    public static ArrayList<Long> ln = new ArrayList<Long>();
    public static Exception randomexception;

    public static void main(String[] args){
        System.out.println("JarFile looking at: " + getRainbowPath() + "Rainbow.jar");
        if(BooleanKeys.premain) System.out.println("Premain agent loaded"); 
        else{
            System.out.println("Premain agent not loaded!");
            ln.add(16185131914L);
            BooleanKeys.error = true;
        }
        if(BooleanKeys.transformer_loaded) System.out.println("Transformation agent loaded!");
        else{
            System.out.println("Transformation agent not loaded!");
            ln.add(16185131914L);
            BooleanKeys.error = true;
        }
        if(BooleanKeys.returns_line && BooleanKeys.returned_bytes) System.out.println("Transformation worked successfully");
        else if (BooleanKeys.returned_bytes && (NumberKeys.line_Inserted_At != 409)) System.out.println("Transformation worked successfully, but code inserted at the wrong line");
        else if (BooleanKeys.error){
            System.out.println("There was an error in the transformation! Please report the following:");
            System.out.println("Error codes: ");
                for (int i = 0; i < ln.size(); i++){
                    System.out.println(ln.get(i));
                }
            if(ln.contains(14152061521144L)){
                System.out.println("This indicates that the joebkt.PlayerList class could not be located!");        
            }else if (ln.contains(69125L)){
                if(BooleanKeys.IOFromEntry){
                    System.out.println("This indicates the Rainbow.jar could not be found! Stack trace:");
                    StackTraceElement[] e = randomexception.getStackTrace();
                        for(int i = 0; i < e.length; i++){
                            StackTraceElement ste = e[i];
                            String s = ste.toString();
                            System.out.println(s);
                    }
                }else{
                    System.out.println("This indicates that there was an error returning the inserted bytecode to the joebkt.PlayerList class!");
                }
            }else if (ln.contains(16185131914L)){
                System.out.println("This indicates that the transformation stopped either at the premain or the transformation agent!");
            }else if (ln.contains(31513169125L)){
                System.out.println("This indicates an error in adding the code into the joebkt.PLayerList class! Stack trace:");
                StackTraceElement[] e = randomexception.getStackTrace();
                System.out.println(randomexception.getMessage());
                    for(int i = 0; i < e.length; i++){
                        StackTraceElement ste = e[i];
                        String s = ste.toString();
                        System.out.println(s);
                }
            }else if (ln.contains(31211919161208L)){
                System.out.println("This indicates an error with javassist getting to Rainbow.jar!");
            }else if (ln.contains(131549625L)){
                System.out.println("This indicates the joebkt.PlayerList class could not be retransformed!");
            }else if(ln.contains(514201825L)){
                System.out.println("This indicates that the JarEntry for the joebkt.PlayerList class could not be made!");
            }
            else{
                System.out.println("Error code misspelt! Please report");
            }
        }else if (BooleanKeys.frozen){
            System.out.println("The class cannot be edited!");  
        }else if (BooleanKeys.found_class){
            System.out.println("At least the class was found. But there were errors in the process.");
        }else{
            System.out.println("NO IDEA WHAT HAPPENED!!!");
        }
        BooleanKeys.premain = false;
    }
    public TransAgent(){
        ta = this;
    }

    public static void agentmain(String args, Instrumentation inst){
        premain(args, inst);
    }

    public static void premain(String agentArgs, Instrumentation inst) {
        try {
            inst.appendToSystemClassLoaderSearch(new JarFile(getRainbowPath() + "Rainbow.jar", true));
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        BooleanKeys.premain = true; 
        try {
            inst.addTransformer(new Transformationer(), true);
            coldwater.insertClassPath(getRainbowPath() + "Rainbow.jar");
            Class<?> classs = Class.forName("joebkt.PlayerList", false, joebkt.PlayerList.class.getClassLoader());
            Class<?>[] classes = {classs};
            inst.retransformClasses(classes);
            BooleanKeys.premain_done = true;
        } catch (NotFoundException e) {
            BooleanKeys.error = true;
            ln.add(31211919161208L);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public static String getRainbowPath() {
        return new File(".").getAbsoluteFile().getParent() + File.separator;
    }
}
class BooleanKeys{
    public static boolean premain = false;
    public static boolean transformer_loaded = false;
    public static boolean entry = false;
    public static boolean premain_done = false;
    public static boolean returns_line = false;
    public static boolean error = false;
    public static boolean frozen = false;
    public static boolean found_class = false;
    public static boolean returned_bytes = false;
    public static boolean IOFromEntry = false;
}

class NumberKeys{
    public static int line_Inserted_At = 0;
}    

Transformationer.java

package RainbowBansTransAgent;

import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;

import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
import joebkt.PlayerList;

public class Transformationer implements ClassFileTransformer {

    public byte[] transform(String arg1){
        try {
            ClassLoader.getSystemClassLoader().loadClass("java.net.SocketAddress");
            CtClass cc = TransAgent.coldwater.get(arg1);
            if(cc.isFrozen()){
                BooleanKeys.frozen = true;
                return null;
            }else{
                cc.getClassFile().setMajorVersion(javassist.bytecode.ClassFile.JAVA_4);
                CtMethod m = cc.getDeclaredMethod("checkIfShouldDisconnect");
                int n = m.insertAt(409, true, "{java.lang.String var4 = var5.d();}");
                if(n == 409){
                    BooleanKeys.returns_line = true;
                    NumberKeys.line_Inserted_At = 409;
                }else{
                    BooleanKeys.returns_line = false;
                    NumberKeys.line_Inserted_At = n;
                }
                System.out.println("Code inserted at line " + n);
                Class<PlayerList> cls = joebkt.PlayerList.class;
                cls.getClassLoader().loadClass(arg1);
                return cc.toBytecode();
            }
        } catch (IOException e) {
            BooleanKeys.error = true;
            TransAgent.ln.add(69125L);
        } catch (CannotCompileException e) {
            BooleanKeys.error = true;
            TransAgent.ln.add(31513169125L);
            TransAgent.randomexception = e;
        } catch (ClassNotFoundException e) {
            BooleanKeys.error = true;
            TransAgent.ln.add(14152061521144L);
        } catch (NotFoundException e) {
            BooleanKeys.error = true;
            TransAgent.ln.add(14152061521144L);
        }
        return null;
    }

    @Override
    public byte[] transform(ClassLoader arg0, String className, Class<?> arg2,
            ProtectionDomain arg3, byte[] arg4)
                    throws IllegalClassFormatException {
        BooleanKeys.transformer_loaded = true;
        byte[] b = null;
        String realName = className.replaceAll("/", ".");
        if(realName.equals("joebkt.PlayerList")){
            if(BooleanKeys.returned_bytes){
                return null;
            }else{
                BooleanKeys.found_class = true;
                b =  transform(realName);
                if(b !=null){
                    BooleanKeys.returned_bytes = true;
                }
            }
        }
        else System.out.println("Class name " + realName + " is not what we're looking for!");
        return b;
    }

}    

TransAgent是从另一个JAR文件的ProcessBuilder加载的。

我的问题是,我的源代码有什么错误,我该如何解决?

0 个答案:

没有答案