我需要使用ASM找到一個方法,這是內部的局部變量修改局部變量:使用ASM
String var4 = "hello!";
我已經創建了三個班。一個沒有轉變,一個延伸ClassVisitor,以及一個擴展MethodVisitor中,像這樣:
變壓器入口點(Transformationer.java)
package RainbowBansTransAgent;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import org.objectweb.asm.*;
public class Transformationer implements ClassFileTransformer {
public byte[] transform(String arg1, byte[] arg2){
ClassReader cr = new ClassReader(arg2);
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES);
cr.accept(cw, 0);
return cw.toByteArray();
}
@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, arg4);
if(b !=null){
BooleanKeys.returned_bytes = true;
}
}
}
else System.out.println("Class name " + realName + " is not what we're looking for!");
return b;
}
}
ClassVisior擴展(RBClassVisitor.java)
package RainbowBansTransAgent;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class RBClassVisitor extends ClassVisitor{
public RBClassVisitor() {
super(Opcodes.ASM5);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature,
exceptions);
return new RBMethodVisitor(mv);
}
}
MethodVisitor中擴展(RBMethodVisitor.java)
package RainbowBansTransAgent;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class RBMethodVisitor extends MethodVisitor {
MethodVisitor mv;
public RBMethodVisitor(MethodVisitor mv) {
super(Opcodes.ASM5, mv);
this.mv = mv;
}
public void visitLineNumber(int line, Label start){
if(line == 409){
mv.visitCode();
}
}
public void visitCode(){
}
}
正如你所看到的,我的visitCode()方法是空的。我知道這是字節碼操作應該發生的方法。
我看到MethodVisitor中有
mv.visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index);
的方法,但我不知道如何正確使用標籤類。
我的變壓器將讀取一個文件,並將變量更改爲文件的內容。使用ASM,我該怎麼做?
編輯:我想要改變的東西的字節碼說: ldc「hello!」 (java.lang.String中)
,我想將它更改爲: 「再見」
LDC (java.lang.String)
您是否嘗試過查看javac爲您嘗試轉換的方法生成的字節碼,並瞭解其如何工作?這應該讓你更好地理解如何解決這個問題。 (提示:如果您需要更改用於初始化局部變量的字符串,則根本不需要visitLocalVarialble()方法,但您需要了解常量池的用途以及如何使用它。) – yole
您的發佈代碼提醒我關於[this](http://assets.amuniversal.com/4a53f3006d5901301d7d001dd8b71c47)。但是,不僅所有這些發佈的代碼都缺少相關部分,即您嘗試*實際執行某些操作*,您也未能解釋此代碼應該執行的操作。 – Holger
缺少的代碼應該改變一個變量等於什麼。例如'String var4 =「hello!」;'將變成'String var4 =「goodbye!」;' – JD9999