Pregunta

How do I modify specific sections of bytecode to add things in?

What I mean by this is that I know what class, and what method (or field), and what line number I want to modify, but I want to know how I would actually go about modifying the bytecode at a specific line / field of a class.

Say I have a class, GammaController

public class GammaController {
    private int gamma = 60;

    public int getScreenGamma() {
        return gamma;
    }

    public void setScreenGamma(int gamma) {
        this.gamma = gamma;
    }
}

But I want to change GammaController.setScreenGamma() to not allow values above 100, without editing the file. I know that the method is at line 8 (we'll ignore packages for now), and a check for above 100 would have to go at line 9, moving the part of the method doing the setting down 1 line.

Let's say I also know the bytecode that will do the check. What I want to do is run an application targeting a jar containing GammaController.class, and have the application modify the class with the bytecode that checks the value to make sure it isn't over 100. How would I go about doing this?

¿Fue útil?

Solución 2

You need to use ASM 2.0 or 3.0/4.0 (depending on your Java version). To do what I think you want to do, you'll need to use a ClassVisitor and modify some values (via VisitField etc.). You will then need to reload the class.

This is nontrivial, but the ASM people provide some very verbose documentation. Happy hacking.

Otros consejos

AspectJ (or any AOP library) could be of some use here. It allows you to define pointcuts, such as when a particular method is called (or when a field is defined among other things). You can then apply advice, which is something you do before/after the join point (the join point is where the pointcut was applied).

For example,

Apply advice that validates that the gamma value is < 100 whenever that method is called. If the value is invalid, throw an exception. If it is valid, continue as normal.

If you really want to modify individual lines of code that don't fall into the categories of what pointcuts can handle, you can use the ASM libraries as suggested by @DavidTitarenco

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top