java - modify local variable using ASM -
i need use asm find local variable inside method, is:
string var4 = "hello!"; i have created 3 classes. 1 transformation, 1 extends classvisitor, , 1 extends methodvisitor, so:
transformer entry point (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 + " not we're looking for!"); return b; } } classvisior extender (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 extender (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(){ } } as can see, visitcode() method empty. understand method bytecode manipulation supposed happen.
i saw methodvisitor has
mv.visitlocalvariable(string name, string desc, string signature, label start, label end, int index); method, have no idea how use label class correctly.
my transformer read file, , change variable contents of file. using asm, how do that?
edit: bytecode thing want change says: ldc "hello!" (java.lang.string)
and want change to:
ldc "goodbye!" (java.lang.string)
you shouldn’t try bytecode transformations without fundamental understanding of how java bytecode works. primary source information the java® virtual machine specification. starter, may read §3 “compiling java virtual machine” learn, how language constructs map byte code instructions.
the important thing, have understand intended kind of transformation, is, there no local variables (the way know java language) on byte code level. there room number of local variables in stack frame, addressed numerical index. method visitlocalvariable, have discovered in asm api called, if class file has been compiled debugging information included.
if gets called, tell local variable name , index maps. label arguments tell scope of variable outside of scope, index might used different variable. if write code using way of learning particular index of variable, have keep in mind, code work class containing debugging hints.
so on byte code level, there no formal declaration of variable var4, assignment of string "hello" particular variable implicitly creates variable if didn’t exist. assignment implemented on byte code level 2 instructions, ldc "hello", followed astore n, n index of local variable. actually, ldc bears index constant pool holding string, asm takes care of , invoke visitldcinsn("hello") when encountering instruction.
so may search 2 instruction sequence, implies have find out right index first (e.g. using debugging information, if present). or, if string "hello" expected appear @ single assignment, waiting occurrence of visitldcinsn("hello") , replacing different constant string simplest form of replacement.
Comments
Post a Comment