Package javapayload.builder

Source Code of javapayload.builder.ClassBuilder

/*
* Java Payloads.
*
* Copyright (c) 2010, Michael 'mihi' Schierl
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright notice,
*   this list of conditions and the following disclaimer.
*  
* - Redistributions in binary form must reproduce the above copyright
*   notice, this list of conditions and the following disclaimer in the
*   documentation and/or other materials provided with the distribution.
*  
* - Neither name of the copyright holders nor the names of its
*   contributors may be used to endorse or promote products derived from
*   this software without specific prior written permission.
*  
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND THE CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package javapayload.builder;

import java.io.FileOutputStream;
import java.io.InputStream;

import javapayload.stager.Stager;

import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodAdapter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class ClassBuilder extends Stager {

  protected static void buildClass(final String classname, final String stager, Class loaderClass, final String embeddedArgs) throws Exception {

    final ClassWriter cw = new ClassWriter(0);

    class MyMethodVisitor extends MethodAdapter {
      private final String newClassName;

      public MyMethodVisitor(MethodVisitor mv, String newClassName) {
        super(mv);
        this.newClassName = newClassName;
      }

      private String cleanType(String type) {
        if (type.startsWith("javapayload/")) {
          type = newClassName;
        }
        return type;
      }

      public void visitFieldInsn(int opcode, String owner, String name, String desc) {
        super.visitFieldInsn(opcode, cleanType(owner), name, desc);
      }

      public void visitMethodInsn(int opcode, String owner, String name, String desc) {
        super.visitMethodInsn(opcode, cleanType(owner), name, desc);
      }

      public void visitTypeInsn(int opcode, String type) {
        super.visitTypeInsn(opcode, cleanType(type));
      }
    }
    final ClassVisitor stagerVisitor = new ClassAdapter(cw) {

      public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
        super.visit(version, access, classname, signature, "java/lang/ClassLoader", interfaces);
      }

      public void visitEnd() {
        // not the end!
      }

      public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
        // strip constructors
        if (name.equals("<init>")) {
          return null;
        }
        return new MyMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions), classname);
      }
    };
    visitClass(Class.forName("javapayload.stager." + stager), stagerVisitor, cw);
    final ClassVisitor stagerBaseVisitor = new ClassAdapter(cw) {

      public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
        // not the beginning!
      }

      public void visitEnd() {
        // not the end!
      }

      public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
        // strip abstract bootstrap method
        if (name.equals("bootstrap") && (access & Opcodes.ACC_ABSTRACT) != 0) {
          return null;
        }
        return new MyMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions), classname);
      }
    };
    visitClass(Stager.class, stagerBaseVisitor, cw);
    final ClassVisitor loaderVisitor = new ClassAdapter(cw) {
      public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
        // not the beginning!
      }

      public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
        if (embeddedArgs != null && name.equals("EMBEDDED_ARGS")) {
          // create EMBEDDED_ARGS field
          return super.visitField(access, name, desc, signature, embeddedArgs);
        }
        // do not copy other fields
        return null;
      }

      public void visitInnerClass(String name, String outerName, String innerName, int access) {
        // do not copy inner classes
      }

      public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
        if (name.equals("mainToEmbed")) {
          return new MyMethodVisitor(super.visitMethod(access, "main", desc, signature, exceptions), classname);
        } else {
          return null;
        }
      }

      public void visitOuterClass(String owner, String name, String desc) {
        // do not copy outer classes
      }
    };
    visitClass(loaderClass, loaderVisitor, cw);
    final byte[] newBytecode = cw.toByteArray();
    final FileOutputStream fos = new FileOutputStream(classname + ".class");
    fos.write(newBytecode);
    fos.close();
  }

  public static void main(String[] args) throws Exception {
    if (args.length != 1 && args.length != 2) {
      System.out.println("Usage: java javapayload.builder.ClassBuilder <stager> [classname]");
      return;
    }
    final String stager = args[0];
    String classname = stager + "Class";
    if (args.length == 2) {
      classname = args[1];
    }

    buildClass(classname, stager, ClassBuilder.class, null);
  }

  public static void mainToEmbed(String[] args) throws Exception {
    new ClassBuilder().bootstrap(args);
  }

  private static void visitClass(Class clazz, ClassVisitor stagerVisitor, ClassWriter cw) throws Exception {
    final InputStream is = ClassBuilder.class.getResourceAsStream("/" + clazz.getName().replace('.', '/') + ".class");
    final ClassReader cr = new ClassReader(is);
    cr.accept(stagerVisitor, ClassReader.SKIP_DEBUG);
    is.close();
  }

  public void bootstrap(String[] parameters) throws Exception {
    throw new Exception("Never used!");
  }
}
TOP

Related Classes of javapayload.builder.ClassBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.