java - How to replace boolean field with a constant value using ASM -



java - How to replace boolean field with a constant value using ASM -

i want transform field of class constant. i'm using asm 5.0.3.

here test class have:

public class bytecodeutilstest { @beforeclass public static void beforeclass(){ string replacefieldclassname = "com.mypackage.classwithfieldtoreplacewithconstant"; string replacefieldclassnameaspath = replacefieldclassname.replace('.', '/') + ".class"; // standard code redefine class (inspired asm faq http://asm.ow2.org/doc/faq.html, sec. 5) classloader contextclassloader = thread.currentthread().getcontextclassloader(); inputstream stream = contextclassloader.getresourceasstream(replacefieldclassnameaspath); byte[] classbytes; seek { classbytes = ioutils.tobytearray(stream); // here interesting part byte[] patchedclassbytes = bytecodeutils.patch(classbytes, "_fieldtoreplace", true); reflection.invoke(contextclassloader, "defineclass", class.class, new class[]{string.class, byte[].class, int.class, int.class}, new object[]{replacefieldclassname, patchedclassbytes, 0, patchedclassbytes.length}); } grab (ioexception e) { throw new runtimeexception(e); } } @test public void testfieldreplace(){ assert.asserttrue(new classwithfieldtoreplacewithconstant().getfieldtoreplace()); assert.asserttrue(new classwithfieldtoreplacewithconstant()._fieldtoreplace); } }

here test class update:

public class classwithfieldtoreplacewithconstant { boolean _fieldtoreplace; public boolean getfieldtoreplace() { homecoming _fieldtoreplace; } }

and here patcher:

public class bytecodeutils { public static byte[] patch(byte[] bytecode, final string fieldtoreplace, final boolean value) { classreader classreader = new classreader(bytecode); final classwriter classwriter = new classwriter(classreader, 0); classvisitor classvisitor = new classvisitor(opcodes.asm4, classwriter) { @override public methodvisitor visitmethod(int access, string name, string desc, string signature, string[] exceptions) { homecoming new methodvisitor(opcodes.asm4, super.visitmethod(access, name, desc, signature, exceptions)) { @override public void visitfieldinsn(int opcode, string owner, string name, string desc) { if (opcode == opcodes.getfield && name.equals(fieldtoreplace)) { mv.visitinsn(opcodes.pop); mv.visitinsn(value ? opcodes.iconst_1 : opcodes.iconst_0); } else { super.visitfieldinsn(opcode, owner, name, desc); } } }; } }; classreader.accept(classvisitor, 0); homecoming classwriter.tobytearray(); } }

the problem test fails @ sec assert. if utilize getter, returns trueas expected, if read field straight returns false. that's quite unexpected considering fact getter yields invokevirtual instruction , field read yields getfield updated invocation of visitinsn method.

what doing wrong , how create direct field access homecoming true?

for sec assert work need patch bytecodeutilstest, not classwithfieldtoreplacewithconstant, since bytecode instruction read field sec case in bytecodeutilstest#testfieldreplace method.

getter case works fine since instruction read field within getter body, i.e, within classwithfieldtoreplacewithconstant class.

if in real scenario field private, code should fine (since there no access field outside of class field declared in). otherwise, have patch every class reads or writes field.

java

Comments

Popular posts from this blog

php - Edges appear in image after resizing -

ios8 - iOS custom keyboard - preserve state between appearances -

Delphi change the assembly code of a running process -