Package javapayload.handler.stager

Source Code of javapayload.handler.stager.JDWPTunnel$InputInterceptHandler

/*
* 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.handler.stager;

import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.List;

import javapayload.handler.stage.StageHandler;

import com.sun.jdi.ArrayReference;
import com.sun.jdi.ByteValue;
import com.sun.jdi.ClassType;
import com.sun.jdi.LocalVariable;
import com.sun.jdi.Location;
import com.sun.jdi.Method;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.event.BreakpointEvent;
import com.sun.jdi.event.Event;
import com.sun.jdi.event.EventIterator;
import com.sun.jdi.event.EventSet;
import com.sun.jdi.request.BreakpointRequest;
import com.sun.jdi.request.EventRequest;

public class JDWPTunnel extends StagerHandler implements Runnable {

  private ClassType communicationClass;
  private WrappedPipedOutputStream pipedOut;
  private PipedInputStream pipedIn;
  private PrintStream errorStream;
 
  protected void handle(StageHandler stageHandler, String[] parameters, PrintStream errorStream, Object extraArg) throws Exception {
    this.errorStream = errorStream;
    if (extraArg == null || !(extraArg instanceof ClassType))
      throw new IllegalArgumentException("No JDWP communication class found");
    communicationClass = (ClassType) extraArg;
    VirtualMachine vm = communicationClass.virtualMachine();
    if (vm.eventRequestManager().stepRequests().size() > 0) {
      throw new RuntimeException("Some threads are currently stepping");
    }
    if (vm.eventRequestManager().breakpointRequests().size() > 0) {
      throw new RuntimeException("There are some breakpoints set");
    }
    PipedOutputStream pos = new PipedOutputStream();
    pipedOut = new WrappedPipedOutputStream(pos);
    pipedIn = new PipedInputStream();
   
    new Thread(this).start();
    stageHandler.handle(new WrappedPipedOutputStream(new PipedOutputStream(pipedIn)), new PipedInputStream(pos), parameters);
  }
 
  public void run() {
    VirtualMachine vm = communicationClass.virtualMachine();
    try {
      Location interceptIn = ((Method)communicationClass.methodsByName("interceptIn").get(0)).locationOfCodeIndex(2);
      Location interceptOut = ((Method)communicationClass.methodsByName("interceptOut").get(0)).locationOfCodeIndex(2);
      BreakpointRequest req =  vm.eventRequestManager().createBreakpointRequest(interceptIn);
      req.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
      req.setEnabled(true);
      req = vm.eventRequestManager().createBreakpointRequest(interceptOut);
      req.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
      req.setEnabled(true);
      final com.sun.jdi.event.EventQueue q = vm.eventQueue();
      boolean done = false;
      errorStream.println("== Handling I/O events...");
      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();
          if (!done && e instanceof BreakpointEvent) {
            final BreakpointEvent be = (BreakpointEvent) e;
            final Location loc = be.location();
            final ThreadReference tr = be.thread()
            if (loc.equals(interceptIn)) {
              LocalVariable result = (LocalVariable) loc.method().variablesByName("result").get(0);
              LocalVariable buffer = (LocalVariable) loc.method().arguments().get(0);
              ArrayReference buf = (ArrayReference) tr.frame(0).getValue(buffer);
              new InputInterceptHandler(tr, buf, result).start();
            } else if (loc.equals(interceptOut)) {
              LocalVariable result = (LocalVariable) loc.method().variablesByName("result").get(0);
              LocalVariable data = (LocalVariable) loc.method().arguments().get(0);
              ArrayReference buf = (ArrayReference) tr.frame(0).getValue(data);
              List values = buf.getValues();
              byte[] temp = new byte[buf.length()];
              for (int i = 0; i < temp.length; i++) {
                temp[i] = ((ByteValue)values.get(i)).byteValue();
              }
              pipedOut.write(temp);
              pipedOut.flush();
              if (temp.length == 0) {
                pipedOut.close();
                pipedIn.close();
                done = true;
              }
              tr.frame(0).setValue(result, vm.mirrorOf(true));
              tr.resume();
            } else {
              throw new RuntimeException("Unknown location: "+loc);
           
          } else {
            System.out.println("== Unknown event received: " + e.toString());
            es.resume();
          }
        }
      }
    }
    catch(Throwable t) {
      t.printStackTrace(errorStream);
    }
    vm.dispose();
  }
 
  protected boolean needHandleBeforeStart() { return false; }
 
  public class InputInterceptHandler extends Thread {
   
    private final ThreadReference thread;
    private final ArrayReference buffer;
    private final LocalVariable result;

    public InputInterceptHandler(ThreadReference thread, ArrayReference buffer, LocalVariable result) {
      this.thread = thread;
      this.buffer = buffer;
      this.result = result;
      setDaemon(true);
    }
   
    public void run() {
      try {
        byte[] temp = new byte[buffer.length()];
        int len = pipedIn.read(temp);
        if (len > 0) {
          ByteValue[] bytes = new ByteValue[len];
          for (int i = 0; i < bytes.length; i++) {
            bytes[i] = thread.virtualMachine().mirrorOf(temp[i]);
          }
          buffer.setValues(0, Arrays.asList(bytes), 0, len);
        }
        thread.frame(0).setValue(result, thread.virtualMachine().mirrorOf(len));
        thread.resume();
      } catch (Throwable t) {
        t.printStackTrace(errorStream);
      }
    }
  }
}
TOP

Related Classes of javapayload.handler.stager.JDWPTunnel$InputInterceptHandler

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.