asm rsps client hacking pt 3

Upload: evan-zaruba

Post on 02-Jun-2018

221 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/10/2019 Asm Rsps Client Hacking Pt 3

    1/4

    Welcome back!

    If you have been following these tutorials up to this part, I'm going to take itfor granted that you are still motivated to learn some more!

    If you haven't seen Part 1 or Part 2, I strongly recommend that you read them!

    -> Link to Part One-> Link to Part Two

    3.1 - Recap

    Last tutorial, I have somewhat explained how adapters work and I've also gave abrief introduction on how classes are transformed. If you haven't noticed already, the AddGetterAdapter that we have worked on DOES have a flaw. I'll get to that later.

    Remember how I mentioned in Part One that there will definitely be learning "gaps". This is the one of the parts of the tutorial that I will create these "gaps". Why? Because you will use what you have learned to create content for yourself.

    If you haven't read the ASM guide already, I strongly recommend that you read atleast the Core API (see Part 2 for a link).

    3.2 - AddInterfaceAdapter Introduction

    Recall in the last tutorial that we created an AddGetterAdapter to insert our accessor methods. Notice how something was missing?

    We need an interface to provide access to these methods!

    It's not like reflection; we can't just plainly do something as simple as "#setAccessible(true)". Now we need to "link" the accessor method via the interface that we inject.

    So create a new class, call it AddInterfaceAdapter and set it up like we've setup the AddGetterAdapter. Do it without looking at the following spoiler! When you're done, it should look something like the following:

    Spoiler

    After this, you will need one more parameter argument in the constructor. Can you guess what it is (it's pretty obvious)? Add it in.

    Spoiler

    Obviously, the variable name will differ.

    Guess what? You're nearly done making this adapter (what?!?!?!?).

    The only method that we need to worry about in the ClassVisitor class is visit.Why? It's because that's where the interfaces are "visited" with the ClassWriterthat you would be using (will get to that soon).

  • 8/10/2019 Asm Rsps Client Hacking Pt 3

    2/4

    3.3 - AddInterfaceAdapter Continued

    So we need to grab all of the "current" interfaces of the class (from the information passed as a ClassVisitor; in this case, a ClassWriter). Then, all we needto do is to add the one interface that we want to add as a String in its fully qualified name.

    For example, if I had an interface called Accessor, in the package "com.dna.asm.accessors", its fully qualified name is the same thing, but it has slashes ('/')instead of dots. So therefore, it translates to "com/dna/asm/accessors". Sincethe interface is called "Accessor", you obviously need to indicate that as well.So it should then be "com/dna/asm/accessors/Accessor". Makes sense?

    So coming back on topic, let's continue.

    You may use an ArrayList to store the fully qualified names of the interfaces asStrings. All you need to do is to add yours in.

    Lets also make the adapter so it can accept the qualified names of more than oneinterface so we don't need to keep reusing this Adapter for other getters.

    It should now look like this:

    import org.objectweb.asm.ClassVisitor;

    import org.objectweb.asm.Opcodes;import java.util.ArrayList;/*** Adds an interface to a given class via a ClassVisitor (ClassWriter).* @author trDna*/

    public class AddInterfaceAdapter extends ClassVisitor implements Opcodes {private String[] interfacesToAdd;

    public AddInterfaceAdapter(final ClassVisitor cv, final String... interfacesToAdd){

    super(ASM4, cv);

    this.interfacesToAdd = interfacesToAdd;}@Overridepublic void visit(int version, int access, java.lang.String name, java.lang.String signature, java.lang.String superName, java.lang.String[] interfaces){

    ArrayList interfaceList = new ArrayList();if(interfaces != null){

    for(String i : interfaces){interfaceList.add(i);

    }} for(String i : interfacesToAdd){

    interfaceList.add(i);}

    cv.visit(version, access, name, signature, superName, interfaceList.toArray(new String[interfaceList.size()]));}}Since the visit() method is a void method, it does not return anything. We wantthe ClassVisitor (a ClassWriter) to consume our modified method. So we need to "manually" call the visit method in the ClassVisitor that has been passed throughthe constructor.

    The ClassVisitor (a ClassWriter) consumes whatever values that are passed throug

  • 8/10/2019 Asm Rsps Client Hacking Pt 3

    3/4

    h its parameters. This gives us the effect that we want!

    Now, you have completed your AddInterface adapter!

    3.3 - Useful subclasses of ClassVisitor

    If you haven't read the ASM guide by Eric Bruneton, then you probably have no idea how any of the useful subclasses that ASM provides function.

    -> A ClassReader parses a given class file as a stream of bytes. It also calledthe corresponding visit___ methods on the ClassVisitor passed through its acceptmethod (will explain that later).

    It's known as the event producer because it calls these ClassVisitor methods (usually, the ClassVisitor is a ClassWriter or an adapter); which ultimately creates these events.

    -> A ClassWriter consumes and builds classes in binary form. It also produces any compiled class to a byte array.

    This is known as an event consumer because it acts like a "retriever" when the ClassReader acting on it calls the visit___ methods of the ClassWriter (or any ot

    her ClassVisitor, such as adapters).

    -> A ClassVisitor "trusts" all of these methods to another ClassVisitor instance(such as a ClassWriter).

    Remember how we used adapters as our "tool" to add things? It's because the ClassVisitor acts as a special filter. You can easily guess that if a custom ClassVisitor (like an adapter) can add things, it can also remove things as well.

    For example, in our AddInterface adapter, if passed a null value to the visit method of the ClassVisitor passed through the constructor, then the interfaces of

    the class parsed will be removed. This is because in ASM, you are almost reconstructing the classes.

    --------------------------------------------------------------------------------------------------------------------------------------------------

    In the interest of time, here's something to do or to think about before proceeding to the next part:

    How would you create a method in your AbstractClassTransform called addGetter that functions?Remember that you need to read from a JAR to obtain the class in binary format!

    Here is a start (note that it's not the complete code):

    The following can be cleaned up, but for learning purposes, I think it's fine:

    private static String clazz;private static String theJar; // JarFile dir goes here.private static JarFile jf;private static JarEntry entry;private static ClassReader cr = null;

  • 8/10/2019 Asm Rsps Client Hacking Pt 3

    4/4

    private ClassWriter cw = null; private ClassVisitor interfaceAdder = null; // AddInterfaceAdapterprivate ClassVisitor adder = null; // AddGetterAdapterprivate ClassVisitor combinedAdapter = null; //Mixture of all adapters

    public abstract void runTransform();

    public void setup(final String theJar, final String clazz){this.theJar = theJar;this.clazz = clazz;

    }public void start(){

    try{jf = new JarFile(theJar);entry = new JarEntry(clazz);Enumeration en = jf.entries();cr = new ClassReader(jf.getInputStream(entry));cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter

    .COMPUTE_FRAMES);cr.accept(cw, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES)

    ;}catch (Exception ex){

    ex.printStackTrace();}

    }---------------------------------------------------------------------------------------------------------------------------------------------------

    This is all I have time for, and hopefully I write up Part 4 soon (within a week, probably), where we can immediately start working on the AbstractClassTransform.

    I will explain every step to create the AbstractClassTransform in the next part,so don't be afraid to attempt to make it!

    You can find my examples repository here if you wish to move ahead:

    https://github.com/t.../master/com/dna