Class RMGUtils


  • public class RMGUtils
    extends Object
    The RMGUtils class defines static helper functions that do not really fit into other categories. Like it is always the case with such classes, it is quite overblown and may be separated in future. Most of the functions in it are concerned about dynamic class creation via javassist. But over the time many other utilities were included within this class.
    Author:
    Tobias Neitzel (@qtc_de)
    • Constructor Summary

      Constructors 
      Constructor Description
      RMGUtils()  
    • Method Summary

      All Methods Static Methods Concrete Methods 
      Modifier and Type Method Description
      static MethodArguments applyParameterTypes​(javassist.CtMethod method, Object[] parameterArray)
      During regular RMI calls, method arguments are usually passed as Object array as methods are invoked using a Proxy mechanism.
      static String bytesToHex​(byte[] in)
      Converts a byte array into a hex string.
      static boolean createdByReadString​(String msg)
      Determines whether a ClassCastException was created by readString because of an non-String type being passed to a call that expected String.
      static Object createObjectInputFilter​(String pattern)
      Provides a Java8+ compatible way to create an ObjectInputFilter using reflection.
      static void createTypesFromList​(List<String> types)
      Takes a list of strings that represent Java class names and replaces array and vararg definitions within of it.
      static void createTypesFromSignature​(String signature)
      Just a helper function that combines getTypesFromSignature and createTypesFrom list.
      static Class<?> ctClassToClass​(javassist.CtClass type)
      Convert a CtClass back to an ordinary Class object.
      static void disableWarning()
      This code was copied from the following link and is just used to disable the annoying reflection warnings: https://stackoverflow.com/questions/46454995/how-to-hide-warning-illegal-reflective-access-in-java-9-without-jvm-argument
      static boolean dynamicallyCreated​(String className)
      Checks whether the specified class name was generated dynamically by RMGUtils.
      static void enableCodebase()
      Sets the useCodebaseOnly setting to false and configures the CodebaseCollector class as the RMIClassLoaderSpi.
      static void enableCodebaseCollector()
      Since version 3.4.0 of remote-method-guesser, the CodebaseCollectorClass has the additional purpose of creating unknown remote classes at runtime.
      static void exit()
      Just a wrapper around System.exit(1) that prints an information before quitting.
      static String expandPath​(String path)
      Expand a leading ~/ with the users home directory.
      static ObjID extractObjID​(Remote remote)
      Extracts the ObjID value from an instance of Remote.
      static ObjID extractObjID​(sun.rmi.server.UnicastRef uref)
      Extracts the ObjID value from a UnicastRef.
      static RemoteRef extractRef​(Remote instance)
      Extracts the underlying RemoteRef within an instance of Remote.
      static Object getArgument​(Class type)
      Takes a Class object and returns a valid instance for the corresponding class.
      static Object getArgument​(javassist.CtClass type)
      Takes a CtClass object and returns a valid instance for the corresponding class.
      static Object[] getArgumentArray​(Method method)
      Construct an argument array for the specified method.
      static Object[] getArgumentArray​(javassist.CtMethod method)
      Construct an argument array for the specified method.
      static boolean getBooleanOption​(String opt, String[] args)
      Primitive argument parser for finding a single boolean value option on the command line.
      static String getCast​(javassist.CtClass type)
      Takes a CtClass and returns a string that can be used within Java code to cast an object to the type of the specified CtClass.
      static String getClass​(InvalidClassException e)
      Parse the class name from an InvalidClassException.
      static String getInterfaceName​(Remote remoteObject)
      Determines the className of an object that implements Remote.
      static ObjID getObjIDByComponent​(RMIComponent component)
      Returns the ObjID for the user specified RMI component,
      static String getOption​(String opt, String[] args)
      Primitive argument parser for finding a single string value option on the command line.
      static int getPrimitiveSize​(javassist.CtClass[] types)
      Takes an array of types and returns the amount of bytes before the first non primitive type.
      static String getSampleArgument​(javassist.CtClass type, String argName)
      This function is used to generate method argument strings that are used in samples.
      static long getSerialVersionUID​(InvalidClassException e)
      Parse the SerialVersionUID of the foreign class from an an InvalidClassException.
      static String getSimpleSignature​(javassist.CtMethod method)
      Returns a human readable method signature of a CtMethod.
      static List<String> getTypesFromSignature​(String signature)
      This function is a pretty primitive way to obtain the different Java classes (types) that are contained within a method signature.
      static String getTypeString​(javassist.CtClass type)
      Another function that is required when creating samples for legacy stubs.
      static byte[] hexToBytes​(String s)
      Converts a hex string into a byte array.
      static void init()
      The init function has to be called before the javassist library can be utilized via RMGUtils.
      static void injectObjectInputFilter​(sun.rmi.server.UnicastServerRef uref, Object filter)
      Inject an ObjectInputFilter into a UnicastServerRef.
      static boolean isAssignableFrom​(javassist.CtClass thisCtClass, String targetClassName)
      This code was copied from the org.hibernate.bytecode.enhance.internal.javassist package, that is licensed under LGPL version 2.1 or later.
      static Class makeActivatableRef()
      Create required classes for the activation system.
      static Class makeInterface​(String className)
      Creates the specified class dynamically as an interface.
      static Class makeLegacyStub​(String className, long serialVersionUID)
      This function is basically like the makeInterface function, but for the legacy RMI stub mechanism.
      static javassist.CtMethod makeMethod​(String signature)
      Creates a method from a signature string.
      static Class makeRandomClass()
      Dynamically creates a class with random class name.
      static Class makeSerializableClass​(String className, long serialVersionUID)
      Dynamically creates a serializable class that can be used within RMI calls.
      static Class makeSocketFactory​(String className, long serialVersionUID)
      Dynamically create a socket factory class that implements RMIClientSocketFactory.
      static ObjID parseObjID​(String objIdString)
      Parses an ObjID from a String.
      static void printObjID​(ObjID objID)
      Print information contained in an ObjID to stdout.
      static void setCodebase​(String serverAddress)
      Enables a user specified codebase within the MaliciousOutputStream.
      static String[] splitListener​(String listener)
      Helper function that is called to split a string that contains a listener definition (host:port).
      static <T> List<Set<T>> splitSet​(Set<T> original, int count)
      Divide a Set into n separate Sets, where n is the number specified within the count argument.
    • Constructor Detail

      • RMGUtils

        public RMGUtils()
    • Method Detail

      • init

        public static void init()
        The init function has to be called before the javassist library can be utilized via RMGUtils. It initializes the class pool and creates CtClass objects for the Remote, RemoteStub and Serializable classes. Furthermore, it creates a Dummy interface that is used for method creation. All this stuff is stored within static variables and can be used by RMGUtils after initialization.
      • makeInterface

        public static Class makeInterface​(String className)
                                   throws javassist.CannotCompileException
        Creates the specified class dynamically as an interface. The interfaces created by this function always extend the Remote class and contain the rmgInvokeObject and rmgInvokePrimitive functions. These functions are used during method guessing, as described in the MethodGuesser class documentation. If the specified class already exists, the class is resolved via Class.forName and is then just returned. This case can occur when multiple bound names use the same RemoteObject class.
        Parameters:
        className - full qualified name of the class to create
        Returns:
        created Class instance
        Throws:
        javassist.CannotCompileException - can be thrown when e.g. the class name is invalid
      • makeLegacyStub

        public static Class makeLegacyStub​(String className,
                                           long serialVersionUID)
                                    throws javassist.CannotCompileException,
                                           javassist.NotFoundException
        This function is basically like the makeInterface function, but for the legacy RMI stub mechanism. First, it also creates an interface class that contains the methods rmgInvokeObject and rmgInvokePrimitive. However, the interface class is not created with the actual specified class name, but with the name 'className + "Interface"'. The actual specified class name is then created as a regular class that extends the RemoteStub class. Furthermore, this class is configured to implement the previously created interface. Interestingly, it is not required to provide implementations for the interface methods when using javassist. However, what needs to be done is adding a serialVersionUID that allows deserialization of the RMI RemoteStubs. In previous versions of remote-method-guesser, this value was set to 2L per default, as this is also the default value when legacy RMI stubs are compiled via rmic. However, edge cases were observed where legacy RMI stubs were compiled with a different serialVersionUID, which caused exceptions in remote-method-guesser. Therefore, the serialVersionUID can now be dynamically supplied. After everything is setup, the function returns the class object that extends RemoteStub.
        Parameters:
        className - full qualified class name to create the stub object for
        serialVersionUID - the serialVersionUID to use for the new class
        Returns:
        dynamically created stub Class object
        Throws:
        javassist.CannotCompileException - may be thrown when the specified class name is invalid
        javassist.NotFoundException - should never be thrown in practice
      • makeRandomClass

        public static Class makeRandomClass()
                                     throws javassist.CannotCompileException
        Dynamically creates a class with random class name. The class implements the Serializable interface and can therefore be used during RMI calls. Random classes are used as canaries during method attacks. The MethodAttacker sends gadgets always as an array of Object. The first item within this arrays is the actual payload object, while the second one is a canary (random class). When the RMI server complains about not knowing the random class name, one can be sure that the previous class was successfully loaded. Furthermore, this also makes sure that even during method attacks, server side calls will not be dispatched due to missing classes.
        Returns:
        Class object of a serializable class with random class name.
        Throws:
        javassist.CannotCompileException - should never be thrown in practice
      • makeSerializableClass

        public static Class makeSerializableClass​(String className,
                                                  long serialVersionUID)
                                           throws javassist.CannotCompileException
        Dynamically creates a serializable class that can be used within RMI calls. This function is used to perform codebase attacks, where a serializable class with user controlled class name needs to be sent to the remote RMI server.
        Parameters:
        className - name of the serializable class to generate
        serialVersionUID - the serialVersionUID to use for the new class
        Returns:
        Class object of a serializable class with specified class name
        Throws:
        javassist.CannotCompileException - may be thrown if the specified class name is invalid
      • makeActivatableRef

        public static Class makeActivatableRef()
                                        throws javassist.CannotCompileException
        Create required classes for the activation system. This function is called when the server contains an ActivatableRef. It checks whether the class exists within the currently running JVM and creates it otherwise.
        Returns:
        Class object for ActivatableRef
        Throws:
        javassist.CannotCompileException - internal error
      • makeSocketFactory

        public static Class makeSocketFactory​(String className,
                                              long serialVersionUID)
                                       throws javassist.CannotCompileException
        Dynamically create a socket factory class that implements RMIClientSocketFactory. This function is used when the RMI server uses a custom socket factory class. In this case, remote-method-guesser attempts to connect with it's default LoopbackSslSocketFactory or LoopbackSocketFactory (depending on the value of the settings --ssl, --socket-factory-ssl and --socket-factory-plain) which works if the custom socket factory provided by the server is not too different. To achieve this, remote-method-guesser just clones LoopbackSslSocketFactory or LoopbackSocketFactory and assigns it a new name. As in the case of Stub classes with unusual serialVersionUIDs, the serialVersionUID is determined error based. The factory is first created using a default serialVersionUID. This should cause an exception revealing the actual serialVersionUID. This is then used to recreate the class. Check the CodebaseCollector class documentation for more information.
        Parameters:
        className - name for the SocketFactoryClass
        serialVersionUID - for the SocketFactoryClass
        Returns:
        socket factory class that implements RMIClientSocketFactory
        Throws:
        javassist.CannotCompileException - internal error
      • makeMethod

        public static javassist.CtMethod makeMethod​(String signature)
                                             throws javassist.CannotCompileException
        Creates a method from a signature string. Methods need to be assigned to a class, therefore the static dummyClass is used that is created during the initialization of RMGUtils. The class relationship of the created method is not really important, as the method is mainly used to compute the method hash and to obtain the argument types.
        Parameters:
        signature - method signature as String
        Returns:
        CtMethod compiled from the signature
        Throws:
        javassist.CannotCompileException - is thrown when signature is invalid
      • getTypesFromSignature

        public static List<String> getTypesFromSignature​(String signature)
        This function is a pretty primitive way to obtain the different Java classes (types) that are contained within a method signature. This is required, as javassist needs all classes contained in a method definition to be present before the compilation. Therefore, we need to create dummy implementations for each class that is not already on the class path.
        Parameters:
        signature - method signature to collect the types from
        Returns:
        List of types that were identified
      • createTypesFromList

        public static void createTypesFromList​(List<String> types)
                                        throws javassist.CannotCompileException
        Takes a list of strings that represent Java class names and replaces array and vararg definitions within of it. When it tries to lookup each full qualified class name within the list. If the class is found, just continues. If the class is not found, it dynamically creates the class using javassist.
        Parameters:
        types - list of Java class names
        Throws:
        javassist.CannotCompileException - may be thrown when encountering invalid class names
      • createTypesFromSignature

        public static void createTypesFromSignature​(String signature)
                                             throws javassist.CannotCompileException
        Just a helper function that combines getTypesFromSignature and createTypesFrom list. This function should be called before a method signature is compiled, as it makes sure that all required classes are on the class path.
        Parameters:
        signature - method signature to create types for
        Throws:
        javassist.CannotCompileException - may be thrown when specifying invalid signatures
      • getArgument

        public static Object getArgument​(Class type)
        Takes a Class object and returns a valid instance for the corresponding class. For primitive types, preconfigured default values will be returned. Non primitive types create always a null instance.
        Parameters:
        type - Class to create the instance for
        Returns:
        instance depending on the value of type
      • getArgumentArray

        public static Object[] getArgumentArray​(Method method)
        Construct an argument array for the specified method. Returns an array of Objects, each being an instance of the type that is expected by the method.
        Parameters:
        method - Method to create the argument array for
        Returns:
        argument array that can be used to invoke the method
      • getArgument

        public static Object getArgument​(javassist.CtClass type)
        Takes a CtClass object and returns a valid instance for the corresponding class. For primitive types, preconfigured default values will be returned. Non primitive types create always a null instance.
        Parameters:
        type - Class to create the instance for
        Returns:
        instance depending on the value of type
      • getArgumentArray

        public static Object[] getArgumentArray​(javassist.CtMethod method)
                                         throws javassist.NotFoundException
        Construct an argument array for the specified method. Returns an array of Objects, each being an instance of the type that is expected by the method.
        Parameters:
        method - CtMethod to create the argument array for
        Returns:
        argument array that can be used to invoke the method
        Throws:
        javassist.NotFoundException - internal error
      • getSampleArgument

        public static String getSampleArgument​(javassist.CtClass type,
                                               String argName)
        This function is used to generate method argument strings that are used in samples. Actually, it is only required for legacy stub samples, as the call arguments need to be packed manually for stubs. This means, that the Object array needs to be manually constructed. When one of the argument types is a primitive like e.g. int, you cannot put it into an Object array without wrapping it into an Integer. Therefore, this function replaces primitives by their corresponding Object compatible representations. During ordinary RMI calls, this is done automatically by using the Proxy object, which also wraps primitive types into their corresponding Object compatible representations before passing them to the invoke method. However, as legacy stubs aren't invoked via a Proxy, we have to implement the wrapping ourselves.
        Parameters:
        type - the type of the argument in question
        argName - the name of the argument in question
        Returns:
        string that can be used for the argument within the Object array
      • getTypeString

        public static String getTypeString​(javassist.CtClass type)
        Another function that is required when creating samples for legacy stubs. It takes a CtClass and returns a string that can be used to represent the corresponding class within of Java code. When CtClass is e.g. int, the return string would be "Integer.TYPE". This function is required to generate the reflection lookups within of legacy samples. Legacy samples use reflection to get access to the interface methods and need to know the argument types in order to lookup methods. The strings returned by this function can just be used during this lookup operation.
        Parameters:
        type - argument type to create a class string for
        Returns:
        class string for the specified type
      • getCast

        public static String getCast​(javassist.CtClass type)
        Takes a CtClass and returns a string that can be used within Java code to cast an object to the type of the specified CtClass. This is another function required for creating legacy stubs. Legacy stubs use the invoke method of UnicastRemoteRef directly, which just returns an Object as result of the RMI call. However, as the actual stub method most of the time asks for a different return type, it is required to cast the result to the appropriate type. To get the correct string for this cast, this function is used.
        Parameters:
        type - type to generate the cast string for
        Returns:
        cast string for the specified type
      • exit

        public static void exit()
        Just a wrapper around System.exit(1) that prints an information before quitting.
      • enableCodebase

        public static void enableCodebase()
        Sets the useCodebaseOnly setting to false and configures the CodebaseCollector class as the RMIClassLoaderSpi. This is required to get access to server side exposed codebases, which is one of the things that rmg reports during its enum action. Setting useCodebaseOnly to false is generally dangerous, as it could potentially allow remote class loading. It tells the RMI runtime that you are interested in server side codebases and want to load unknown classes from an URL that may be specified by the server. Therefore, this setting can easily lead to remote code execution. In the case of remote-method-guesser, a remote class loading attack is prevented by two mechanisms: 1. Remote class loading is not allowed when no SecurityManager is defined. As rmg does not create a SecurityManager on its own, the code is in principle not vulnerable. Furthermore, even when the user specifies a SecurityManager manually, it would still require a security policy that allows class loading from the server side specified codebase. If you manually enable a SecurityManager with such a policy, it isn't really rmg's fault. 2. remote-method-guesser replaces the RMIClassLoaderSpi class with a custom implementation. RMIClassLoaderSpi is normally used to resolve unknown classes during RMI calls. It obtains the unknown class name and a reference to the codebase of the server that exposes the class. Within rmg, the codebase reference is simply collected and returned back to the user. Afterwards, it is set to null before continuing with the usual RMI functionality. This way, even when a codebase is used by the server, the client side RMI call should never notice anything of it.
      • enableCodebaseCollector

        public static void enableCodebaseCollector()
        Since version 3.4.0 of remote-method-guesser, the CodebaseCollectorClass has the additional purpose of creating unknown remote classes at runtime. This behavior needs to be always enabled, independently of the useCodebaseOnly property.
      • disableWarning

        public static void disableWarning()
        This code was copied from the following link and is just used to disable the annoying reflection warnings: https://stackoverflow.com/questions/46454995/how-to-hide-warning-illegal-reflective-access-in-java-9-without-jvm-argument
      • getSimpleSignature

        public static String getSimpleSignature​(javassist.CtMethod method)
        Returns a human readable method signature of a CtMethod. Builtin methods only return the signature in a non well formatted format. This function is used to display known remote methods as the result of a guessing operation.
        Parameters:
        method - CtMethod to create the signature for
        Returns:
        human readable method signature as String
      • applyParameterTypes

        public static MethodArguments applyParameterTypes​(javassist.CtMethod method,
                                                          Object[] parameterArray)
                                                   throws javassist.NotFoundException
        During regular RMI calls, method arguments are usually passed as Object array as methods are invoked using a Proxy mechanism. However, on the network layer argument types need to be marshalled according to the expected type from the method signature. E.g. an argument value might be an Integer, but is expected by the method as int. Therefore, passing an Object array alone is not sufficient to correctly write the method arguments to the output stream. This function takes the remote method that is going to be invoked and an Object array of parameters to use for the call. It then creates a MethodArguments object, that contains Pairs that store the desired object value together with their corresponding type that is expected by the remote method.
        Parameters:
        method - CtMethod that is going to be invoked
        parameterArray - array of arguments to use for the call
        Returns:
        MethodArguments - basically a list of Object value -> Type pairs
        Throws:
        javassist.NotFoundException - internal error
      • splitListener

        public static String[] splitListener​(String listener)
        Helper function that is called to split a string that contains a listener definition (host:port). The main benefit of this function is, that it implements basic error handling.
        Parameters:
        listener - listener definition as string
        Returns:
        split listener [host, port]
      • setCodebase

        public static void setCodebase​(String serverAddress)
        Enables a user specified codebase within the MaliciousOutputStream. If the user specified address does not start with a protocol definition, 'http' is prefixed by default. Furthermore, if no typical java extension was specified, a slash is added to the end of the URL.
        Parameters:
        serverAddress - user specified codebase address.
      • isAssignableFrom

        public static boolean isAssignableFrom​(javassist.CtClass thisCtClass,
                                               String targetClassName)
        This code was copied from the org.hibernate.bytecode.enhance.internal.javassist package, that is licensed under LGPL version 2.1 or later. According to the GPL compatibility matrix, it is fine to include the code in a GPLv3 licensed project and to convey the license to GPLv3. (https://www.gnu.org/licenses/gpl-faq.en.html#AllCompatibility) The code is used to implement isAssignableFrom for CtClasses. It checks whether thisCtClass is the same as, extends or implements targetClassName. Or in other words: It checks whether targetClassName is the same as, or is a superclass or superinterface of the class or interface represented by the thisCtClass parameter.
        Parameters:
        thisCtClass - class in question
        targetClassName - name of the class to compare against
        Returns:
        true if targetClassName is the same as, or is a superclass or superinterface of thisCtClass
      • splitSet

        public static <T> List<Set<T>> splitSet​(Set<T> original,
                                                int count)
        Divide a Set into n separate Sets, where n is the number specified within the count argument. Basically copied from: https://stackoverflow.com/questions/16449644/how-can-i-take-a-java-set-of-size-x-and-break-into-x-y-sets
        Type Parameters:
        T - inner type of the set
        Parameters:
        original - Set that should be divided
        count - Number of Sets to divide into
        Returns:
        List of n separate sets, where n is equal to count
      • getPrimitiveSize

        public static int getPrimitiveSize​(javassist.CtClass[] types)
        Takes an array of types and returns the amount of bytes before the first non primitive type. If all types are primitive, it returns -1.
        Parameters:
        types - Array of types
        Returns:
        bytes before the first non primitive type. If all types are primitive, returns -1
      • bytesToHex

        public static String bytesToHex​(byte[] in)
        Converts a byte array into a hex string. Copied from: https://stackoverflow.com/questions/15429257/how-to-convert-byte-array-to-hexstring-in-java
        Parameters:
        in - byte array to convert
        Returns:
        hex string representing the byte array
      • hexToBytes

        public static byte[] hexToBytes​(String s)
        Converts a hex string into a byte array. Copied from: https://stackoverflow.com/questions/140131/convert-a-string-representation-of-a-hex-dump-to-a-byte-array-using-java
        Parameters:
        s - Hex string to convert from
        Returns:
        byte array representation of the hex data
      • dynamicallyCreated

        public static boolean dynamicallyCreated​(String className)
        Checks whether the specified class name was generated dynamically by RMGUtils.
        Parameters:
        className - class to check for
        Returns:
        true if it was generated dynamically
      • extractRef

        public static RemoteRef extractRef​(Remote instance)
                                    throws IllegalArgumentException,
                                           IllegalAccessException
        Extracts the underlying RemoteRef within an instance of Remote. The RemoteRef contains information regarding the actual TCP endpoint and the ObjID that is used within the call.
        Parameters:
        instance - An Instance of Remote - Usually obtained by the RMI lookup method
        Returns:
        underlying RemoteRef that is used by the Remote instance
        Throws:
        IllegalArgumentException - if reflective access fails
        IllegalAccessException - if reflective access fails
      • parseObjID

        public static ObjID parseObjID​(String objIdString)
        Parses an ObjID from a String. In previous versions of rmg, only well known ObjIDs were supported, as it was only possible to specify the ObjNum property of an ObjID. For non well known RemoteObjects, an UID is required too. This function accepts now both inputs. You can just specify a number like 1, 2 or 3 to target one of the well known RMI components or a full ObjID string to target a different RemoteObject. Full ObjID strings can be obtained by rmg's enum action and look usually like this: [196e60b8:17ac2551248:-7ffc, -7934078052539650836]
        Parameters:
        objIdString - Either a plain number or an ObjID value formatted as String
        Returns:
        ObjID object constructed from the specified input string
      • getInterfaceName

        public static String getInterfaceName​(Remote remoteObject)
        Determines the className of an object that implements Remote. If the specified object is a Proxy, the function returns the first implemented interface name that is not java.rmi.Remote.
        Parameters:
        remoteObject - Object to obtain the class from
        Returns:
        Class name of the implementor or one of its interfaces in case of a Proxy
      • printObjID

        public static void printObjID​(ObjID objID)
        Print information contained in an ObjID to stdout.
        Parameters:
        objID - ObjID value to print information from
      • getObjIDByComponent

        public static ObjID getObjIDByComponent​(RMIComponent component)
        Returns the ObjID for the user specified RMI component,
        Parameters:
        component - the well known RMI component to return the Object ID for
        Returns:
        ObjID for the user specified RMI component.
      • createdByReadString

        public static boolean createdByReadString​(String msg)
        Determines whether a ClassCastException was created by readString because of an non-String type being passed to a call that expected String.
        Parameters:
        msg - Message of the ClassCastException
        Returns:
        true if created by readString
      • getClass

        public static String getClass​(InvalidClassException e)
        Parse the class name from an InvalidClassException.
        Parameters:
        e - the InvalidClassException
        Returns:
        the class name of the invalid class
      • getSerialVersionUID

        public static long getSerialVersionUID​(InvalidClassException e)
        Parse the SerialVersionUID of the foreign class from an an InvalidClassException.
        Parameters:
        e - the InvalidClassException
        Returns:
        the serialVersionUID of the foreign class
      • ctClassToClass

        public static Class<?> ctClassToClass​(javassist.CtClass type)
                                       throws ClassNotFoundException,
                                              javassist.NotFoundException
        Convert a CtClass back to an ordinary Class object. This method is intended to be called for classes that are known to already exist within the JVM. No compilation is triggered but the Class object is simply obtained by Class.forName (including handling for all the edge cases).
        Parameters:
        type - the CtClass that should be converted back to a Class object
        Returns:
        Class associated to the specified CtClass
        Throws:
        ClassNotFoundException - internal error
        javassist.NotFoundException - internal error
      • getOption

        public static String getOption​(String opt,
                                       String[] args)
        Primitive argument parser for finding a single string value option on the command line.
        Parameters:
        opt - option name to find
        args - command line
        Returns:
        the value of the specified option
      • getBooleanOption

        public static boolean getBooleanOption​(String opt,
                                               String[] args)
        Primitive argument parser for finding a single boolean value option on the command line.
        Parameters:
        opt - option name to find
        args - command line
        Returns:
        true if option was found
      • expandPath

        public static String expandPath​(String path)
        Expand a leading ~/ with the users home directory.
        Parameters:
        path - input path
        Returns:
        expanded path