Class HeadlessScript


  • public abstract class HeadlessScript
    extends GhidraScript
    This class is analogous to GhidraScript, except that is only meant to be used with the HeadlessAnalyzer. That is, if a user writes a script that extends HeadlessScript, it should only be run in the Headless environment.
    • Constructor Detail

      • HeadlessScript

        public HeadlessScript()
    • Method Detail

      • storeHeadlessValue

        public void storeHeadlessValue​(java.lang.String key,
                                       java.lang.Object value)
                                throws ImproperUseException
        Stores a key/value pair in the HeadlessAnalyzer instance for later use.

        This method, along with the 'getStoredHeadlessValue' method, is useful for debugging and testing the Headless Analyzer (when the user has directly instantiated the HeadlessAnalyzer instead of running it from analyzeHeadless.sh or analyzeHeadless.bat). This method is intended to allow a HeadlessScript to store variables that reflect the current state of processing (at the time the script is being run). Storing variables in the HeadlessAnalyzer instance may be the only way to access the state of processing during cases when the user is forced to run in -readOnly mode, or if there is a value that is only accessible at the scripts stage.

        Parameters:
        key - storage key in String form
        value - value to store
        Throws:
        ImproperUseException - if not in headless mode or headless instance not set
        See Also:
        getStoredHeadlessValue(String), headlessStorageContainsKey(String)
      • getStoredHeadlessValue

        public java.lang.Object getStoredHeadlessValue​(java.lang.String key)
                                                throws ImproperUseException
        Get stored value by key from the HeadlessAnalyzer instance.

        This method, along with the 'storedHeadlessValue' method, is useful for debugging and testing the Headless Analyzer (when the user has directly instantiated the HeadlessAnalyzer instead of running it from analyzeHeadless.sh or analyzeHeadless.bat). This method is intended to allow a HeadlessScript to store variables that reflect the current state of processing (at the time the script is being run). Storing variables in the HeadlessAnalyzer instance may be the only way to access the state of processing during cases when the user is forced to run in -readOnly mode, or if there is a value that is only accessible at the scripts stage.

        Parameters:
        key - key to retrieve the desired stored value
        Returns:
        stored Object, or null if none exists for that key
        Throws:
        ImproperUseException - if not in headless mode or headless instance not set
        See Also:
        storeHeadlessValue(String, Object), headlessStorageContainsKey(String)
      • setHeadlessContinuationOption

        public void setHeadlessContinuationOption​(HeadlessScript.HeadlessContinuationOption option)
        Sets the continuation option for this script

        The continuation option specifies whether to continue or abort follow-on processing, and whether to delete or keep the current program.

        Parameters:
        option - HeadlessContinuationOption set by this script
        See Also:
        getHeadlessContinuationOption()
      • getHeadlessContinuationOption

        public HeadlessScript.HeadlessContinuationOption getHeadlessContinuationOption()
        Returns the continuation option for the current script (if one has not been set in this script, the option defaults to CONTINUE).

        The continuation option specifies whether to continue or abort follow-on processing, and whether to delete or keep the current program.

        Returns:
        the current HeadlessContinuationOption
        See Also:
        setHeadlessContinuationOption(HeadlessContinuationOption)
      • enableHeadlessAnalysis

        public void enableHeadlessAnalysis​(boolean b)
                                    throws ImproperUseException
        Enables or disables analysis according to the passed-in boolean value.

        A script that calls this method should run as a 'preScript', since preScripts execute before analysis would typically run. Running the script as a 'postScript' is ineffective, since the stage at which analysis would have happened has already passed.

        This change will persist throughout the current HeadlessAnalyzer session, unless changed again (in other words, once analysis is enabled via script for one program, it will also be enabled for future programs in the current session, unless changed).

        Parameters:
        b - true to enable analysis, false to disable analysis
        Throws:
        ImproperUseException - if not in headless mode or headless instance not set
        See Also:
        isHeadlessAnalysisEnabled()
      • isHeadlessAnalysisEnabled

        public boolean isHeadlessAnalysisEnabled()
                                          throws ImproperUseException
        Returns whether analysis is currently enabled or disabled in the HeadlessAnalyzer.
        Returns:
        whether analysis has been enabled or not
        Throws:
        ImproperUseException - if not in headless mode or headless instance not set
        See Also:
        enableHeadlessAnalysis(boolean)
      • isImporting

        public boolean isImporting()
                            throws ImproperUseException
        Returns whether the headless analyzer is currently set to -import mode or not (if not, it is in -process mode). The use of -import mode implies that binaries are actively being imported into the project (with optional scripts/analysis). The use of -process mode implies that existing project files are being processed (using scripts and/or analysis).
        Returns:
        whether we are in -import mode or not
        Throws:
        ImproperUseException - if not in headless mode or headless instance not set
      • setHeadlessImportDirectory

        public void setHeadlessImportDirectory​(java.lang.String importDir)
                                        throws ImproperUseException,
                                               java.io.IOException,
                                               InvalidNameException
        Changes the path in the Ghidra project where imported files are saved. The passed-in path is assumed to be relative to the project root. For example, if the directory structure for the Ghidra project looks like this:
                        MyGhidraProject:
                          /dir1
                            /innerDir1
                            /innerDir2
         
        Then the following usage would ensure that any files imported after this call would be saved in the MyGhidraProject:/dir1/innerDir2 folder.
                        setHeadlessImportDirectory("dir1/innerDir2");
         
        In contrast, the following usages would add new folders to the Ghidra project and save the imported files into the newly-created path:
                        setHeadlessImportDirectory("innerDir2/my/folder");
         
        changes the directory structure to:
                        MyGhidraProject:
                          /dir1
                            /innerDir1
                            /innerDir2
                              /my
                                /folder
         
        and:
                        setHeadlessImportDirectory("newDir/saveHere");
         
        changes the directory structure to:
                        MyGhidraProject:
                          /dir1
                            /innerDir1
                                /innerDir2
                          /newDir
                            /saveHere
         
        As in the examples above, if the desired folder does not already exist, it is created.

        A change in the import save folder will persist throughout the current HeadlessAnalyzer session, unless changed again (in other words, once the import directory has been changed, it will remain the 'save' directory for import files in the current session, unless changed).

        To revert back to the default import location (that which was specified via command line), pass the null object as the argument to this method, as below:

                        setHeadlessImportDirectory(null);       // Sets import save directory to default
         
        If a file with the same name already exists in the desired location, it will only be overwritten if "-overwrite" is true.

        This method is only applicable when using the HeadlessAnalyzer -import mode and is ineffective in -process mode.

        Parameters:
        importDir - the absolute path (relative to root) where inputs will be saved
        Throws:
        ImproperUseException - if not in headless mode or headless instance not set
        java.io.IOException - if there are issues creating the folder
        InvalidNameException - if folder name is invalid
      • analysisTimeoutOccurred

        public boolean analysisTimeoutOccurred()
                                        throws ImproperUseException
        Returns whether analysis for the current program has timed out.

        Analysis will time out only in the case where:

        1. the users has set an analysis timeout period using the -analysisTimeoutPerFile parameter
        2. analysis is enabled and has completed
        3. the current script is being run as a postScript (since postScripts run after analysis)
        Returns:
        whether analysis timeout occurred
        Throws:
        ImproperUseException - if not in headless mode or headless instance not set
      • runScript

        public void runScript​(java.lang.String scriptName,
                              java.lang.String[] scriptArguments,
                              GhidraState scriptState)
                       throws java.lang.Exception
        Description copied from class: GhidraScript
        Runs a script by name with the given arguments using the given state.

        It attempts to locate the script in the directories defined in GhidraScriptUtil.getScriptDirectories().

        The script being run uses the given GhidraState (e.g., script variables) Any changes to the state by the script being run will be reflected in the given state object. If the given object is the current state, the this scripts state may be changed by the called script.

        Overrides:
        runScript in class GhidraScript
        Parameters:
        scriptName - the name of the script to run
        scriptArguments - the arguments to pass to the script
        scriptState - the Ghidra state
        Throws:
        java.lang.IllegalArgumentException - if the script does not exist
        java.lang.Exception - if any exceptions occur while running the script
        See Also:
        GhidraScript.runScriptPreserveMyState(String), GhidraScript.runScript(String)
      • cleanup

        public void cleanup​(boolean success)
        Description copied from class: GhidraScript
        A callback for scripts to perform any needed cleanup after the script is finished
        Overrides:
        cleanup in class GhidraScript
        Parameters:
        success - true if the script was successful