diff --git a/Ghidra/Features/Base/src/main/help/help/topics/VersionControl/project_repository.htm b/Ghidra/Features/Base/src/main/help/help/topics/VersionControl/project_repository.htm index d3e5d0c5dd..4cb185cee3 100644 --- a/Ghidra/Features/Base/src/main/help/help/topics/VersionControl/project_repository.htm +++ b/Ghidra/Features/Base/src/main/help/help/topics/VersionControl/project_repository.htm @@ -14,7 +14,7 @@ -

Project Repository

+

Project Repository

Ghidra supports the concept of a project repository such that files in the repository can be versionedVersioning allows you to track file diff --git a/Ghidra/Features/VersionTracking/certification.manifest b/Ghidra/Features/VersionTracking/certification.manifest index fe6191d51e..3e8f42116b 100644 --- a/Ghidra/Features/VersionTracking/certification.manifest +++ b/Ghidra/Features/VersionTracking/certification.manifest @@ -56,6 +56,7 @@ src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingTool.png|| src/main/help/help/topics/VersionTrackingPlugin/images/accepted_fully_applied.png||GHIDRA||reviewed||END| src/main/help/help/topics/VersionTrackingPlugin/images/accepted_fully_considered.png||GHIDRA||reviewed||END| src/main/help/help/topics/VersionTrackingPlugin/images/accepted_warning.png||GHIDRA||reviewed||END| +src/main/help/help/topics/VersionTrackingPlugin/images/start-here.png||Tango Icons - Public Domain|||tango icon set|END| src/main/help/help/topics/VersionTrackingPlugin/providers/VT_Apply_Options.html||GHIDRA||||END| src/main/help/help/topics/VersionTrackingPlugin/providers/VT_Functions_Table.html||GHIDRA||||END| src/main/help/help/topics/VersionTrackingPlugin/providers/VT_Implied_Matches_Table.html||GHIDRA||||END| diff --git a/Ghidra/Features/VersionTracking/ghidra_scripts/AddVTSessionToVersionControl.java b/Ghidra/Features/VersionTracking/ghidra_scripts/AddVTSessionToVersionControl.java new file mode 100644 index 0000000000..7b1f1dc021 --- /dev/null +++ b/Ghidra/Features/VersionTracking/ghidra_scripts/AddVTSessionToVersionControl.java @@ -0,0 +1,70 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//Script that enables user to add an existing Version Tracking Session to version control. This +//is meant to to be used when project is a shared project and when running in headless mode +//since it is simple add a VTSession to version control from the project manager when running in +//GUI mode. +//@category Version Tracking +import ghidra.app.script.GhidraScript; +import ghidra.features.base.values.GhidraValuesMap; +import ghidra.framework.model.DomainFile; +import ghidra.util.MessageType; + +public class AddVTSessionToVersionControl extends GhidraScript { + + @Override + public void run() throws Exception { + + GhidraValuesMap startupValues = new GhidraValuesMap(); + + startupValues.defineProjectFile("Select Version Tracking Session", "/"); + startupValues.defineString("Enter commit message", "Commiting session to version control"); + + startupValues.setValidator((valueMap, status) -> { + + if (!valueMap.hasValue("Select Version Tracking Session")) { + status.setStatusText("Must select a Version Tracking Session!", MessageType.ERROR); + return false; + } + + if (!valueMap.hasValue("Enter commit message")) { + status.setStatusText("Must enter a commit message!", MessageType.ERROR); + return false; + } + return true; + }); + + startupValues = askValues( + "Enter Version Tracking Session info for adding to source control:", "", startupValues); + + DomainFile sessionDF = startupValues.getProjectFile("Select Version Tracking Session"); + String commitMsg = startupValues.getString("Enter commit message"); + + if (sessionDF.isVersioned()) { + println("Chosen session is already in version control"); + return; + } + + // add session to version control and do not keep checkout out + sessionDF.addToVersionControl(commitMsg, false, monitor); + + println(sessionDF.getName() + " was successfully added to version control."); + + } + + + +} diff --git a/Ghidra/Features/VersionTracking/ghidra_scripts/AutoVersionTrackingScript.java b/Ghidra/Features/VersionTracking/ghidra_scripts/AutoVersionTrackingScript.java index 3daa33f5d6..e53d1162a0 100644 --- a/Ghidra/Features/VersionTracking/ghidra_scripts/AutoVersionTrackingScript.java +++ b/Ghidra/Features/VersionTracking/ghidra_scripts/AutoVersionTrackingScript.java @@ -14,37 +14,77 @@ * limitations under the License. */ -// A script that runs Auto Version Tracking given the options set in one of the following ways: +// A script that runs Auto Version Tracking such that the current program in the tool is the +// destination program and the user is prompted to choose the source program. The user must also +// choose a name for a new Version Tracking Session. The script cannot run using an existing session. +// There are many options that can be set in one of the following ways: // 1. If script is run from the CodeBrowser, the GUI options are set in a pop up dialog by user. -// 2. If script is run in headless mode either the defaults provided by the script are used or the -// user can specify a script to be run that sets the options. See example script +// 2. If script is run in headless mode either the default options provided by the script are used +// or the user can specify a script to be run that sets the options. See example script // SetAutoVersionTrackingOptionsScript that can be copied and updated to reflect the users // desired options. // -// NOTE: This is an example to show how run this script in headless mode +// HEADLESS MODE NON-SHARED PROJECT: +// +// This is an example to show how run this script in headless mode against a local non-shared +// project // // /support/analyzeHeadless.bat/sh c:/MyGhidraProjectFolder -// MyProjectName/OptionalFolderContainingProgram -process Program1.exe -postScript +// MyProjectName/OptionalFolderContainingDestProgram -process DestinationProgram.exe -postScript // MyOptionsSetupScript -postScript AutoVersionTrackingScript.java "/FolderContainingSession" -// "MySessionName" true "/OptionalFolderContainingProgram/Program2.exe" +// "MySessionName" "/OptionalFolderContainingSourceProgram/SourceProgram.exe" // -// -// NOTE: The first program will be analyzed for you if it is not already analyzed (and if you -// do not include the -noanalysis option) as it is part of the typical analyzeHeadless run. -// The second program must be analyzed prior to running the script as the headless analyzer -// itself knows nothing about the file other than as a given option name. This is true in -// both GUI and headless mode. -// -// NOTE: The second to last parameter is to identify whether the first listed program -// is the source program or not. True means first program is source program and second -// program is destination program. False means second program is source program and first -// program is destination program. This is important if you want the correct markup to be -// applied from the source to destination program. +// NOTE: The destination program will be analyzed for you if it is not already analyzed (and if +// you do not include the -noanalysis option) as it is part of the typical analyzeHeadless +// run. The source program must be analyzed prior to running the script as the headless +// analyzer itself knows nothing about the file other than as a given option name. This is +// true in both GUI and headless mode. // // NOTE: The options setup script is optional. It is only necessary if users want to change the -// default options. To use it make a copy of the example one and save to a new script. You -// You may need to add the -scriptPath to the headless run so it will find your script. +// other default options that are not settable on the headless command line. To use an +// options script, make a copy of the example one (SetAutoVersionTrackingOptionsScript) +// and save it with a new script file name. Then use the -postScript headless argument to +// run the options script before the second -postScript argument to run the +// AutoVersionTrackingScript. Depending on where you save your script, you might also need +// to add the -scriptPath to the headless run so it will find your script. // +// SHARED PROJECT MODE FROM GUI +// +// From the GUI, this script can run on local project files contained in the shared project or +// those that have been added to source control. If the destination program has been added to +// version control but is not checked out, the user will be prompted to checkout the file. +// If the file is not checked-out the script will not proceed. User is responsible for checking +// in changes to the destination file made by the script if they want the changes added. After +// the script is run, if user wants to add the session to version control they can. +// +// SHARED PROJECT MODE FROM HEADLESS MODE: +// +// If running this script in headless mode on a shared project, both source and destination +// programs must have already been added to version control before running the script or the +// script will not be able to locate the programs because the only programs visible to it will +// be those in the shared repository project. +// +// The headless shared project run will be different from the non-shared project in terms of how +// to tell it where the project location is. Instead of specifying a project location and +// project name, the user must instead specify the Ghidra Server repository URL. +// +// Also, there are necessary extra arguments to the headless run in order to connect to the +// server and commit the destination program changes to the server. +// +// This is an example command line for running this script in headless shared project mode: +// +// /support/analyzeHeadless.bat/sh +// ghidra://localhost:13100/MyProjectName/OptionalFolderContainingDestProgram -process +// DestinationProgram.exe -postScript MyOptionsSetupScript -postScript +// AutoVersionTrackingScript.java "/FolderContainingSession" +// "MySessionName" "/OptionalFolderContainingSourceProgram/SourceProgram.exe" +// optionalAddSessionToVersionControl -connect username -p -commit "my commit msg" +// +// NOTE: The Destination program being processed in the shared project headless run must not be +// checked out by anyone prior to the run. The headless script expects the file to be in version +// control but not checked out. The headless script will check it out, run the given scripts +// against it then check in any changes with the given commit message. +// //@category Version Tracking import ghidra.app.script.GhidraScript; import ghidra.feature.vt.api.db.VTSessionDB; @@ -63,29 +103,29 @@ import ghidra.util.task.TaskLauncher; public class AutoVersionTrackingScript extends GhidraScript { - private Program sourceProgram; - private Program destinationProgram; - - @Override - public void cleanup(boolean success) { - if (sourceProgram != null && sourceProgram.isUsedBy(this)) { - sourceProgram.release(this); - } - if (destinationProgram != null && destinationProgram.isUsedBy(this)) { - destinationProgram.release(this); - } - super.cleanup(success); - } + private static final int NUM_ARGS = 3; @Override public void run() throws Exception { + + if(currentProgram == null) { + println("Please open the destination program."); + return; + } + + Program destinationProgram = currentProgram; + + if (!destinationProgram.canSave()) { + println("VT Session destination program " + destinationProgram.getName() + + " is read-only which prevents its use."); + return; + } GhidraValuesMap startupValues = new GhidraValuesMap(); startupValues.defineProjectFolder("Version Tracking Session Folder", "/"); startupValues.defineString("Version Tracking Session Name"); - startupValues.defineBoolean("Check if current program is the Source Program", true); - startupValues.defineProgram("Please select the other program"); + startupValues.defineProjectFile("Please select the SOURCE program", "/"); startupValues.setValidator((valueMap, status) -> { @@ -108,43 +148,38 @@ public class AutoVersionTrackingScript extends GhidraScript { return false; } - if (!valueMap.hasValue("Please select the other program")) { - status.setStatusText("Must choose second program!", MessageType.ERROR); + if (!valueMap.hasValue("Please select the SOURCE program")) { + status.setStatusText("Must choose a SOURCE program!", MessageType.ERROR); return false; } return true; }); startupValues = askValues("Enter Auto Version Tracking Information", - "Changing these options will not change the corresponding tool options", startupValues); + "The currently opened program is assumed to be the DESTINATION program.", + startupValues); DomainFolder folder = startupValues.getProjectFolder("Version Tracking Session Folder"); String name = startupValues.getString("Version Tracking Session Name"); - boolean isCurrentProgramSourceProg = - startupValues.getBoolean("Check if current program is the Source Program"); // setting auto upgrade to isHeadless, will cause headless uses to auto upgrade, but in - // Gui mode, will prompt before upgrading. + // GUI mode, will prompt before upgrading. boolean autoUpgradeIfNeeded = isRunningHeadless(); - Program otherProgram = startupValues.getProgram("Please select the other program", this, - state.getTool(), autoUpgradeIfNeeded); + + DomainFile sourceProgramDF = + startupValues.getProjectFile("Please select the SOURCE program"); + if (!Program.class.isAssignableFrom(sourceProgramDF.getDomainObjectClass())) { + println(sourceProgramDF.getContentType() + " file " + sourceProgramDF.getName() + + " may not be specified as the SOURCE Program."); + return; + } + + Program sourceProgram = (Program) sourceProgramDF.getDomainObject(this, autoUpgradeIfNeeded, + false, monitor); VTSession session = null; try { - if (isCurrentProgramSourceProg) { - sourceProgram = currentProgram; - destinationProgram = otherProgram; - } - else { - destinationProgram = currentProgram; - sourceProgram = otherProgram; - } - - if (sourceProgram == null || destinationProgram == null) { - return; - } - // Need to end the script transaction or it interferes with vt things that need locks end(true); @@ -170,7 +205,7 @@ public class AutoVersionTrackingScript extends GhidraScript { // See SetAutoVersionTrackingOptionsScript.java as an example GhidraValuesMap stateOptionsMap = (GhidraValuesMap) state.getEnvironmentVar("autoVTOptionsMap"); - if (optionsMap != null) { + if (stateOptionsMap != null) { optionsMap = stateOptionsMap; } @@ -183,19 +218,35 @@ public class AutoVersionTrackingScript extends GhidraScript { TaskLauncher.launch(autoVtTask); // Save destination program and session changes - otherProgram.save("Updated with Auto Version Tracking", monitor); + destinationProgram.save("Updated with Auto Version Tracking", monitor); session.save(); println(autoVtTask.getStatusMsg()); } + catch (CancelledException e) { + // let finally clean up + return; + } finally { - if (otherProgram != null) { - otherProgram.release(this); + if (sourceProgram != null) { + sourceProgram.release(this); } if (session != null) { session.release(this); + } } + + // try adding to version control if it is a transient project (ie headless operating against + // a shared project repository + if (state.getProject().getProjectLocator().isTransient()) { + + session.getDomainFile() + .addToVersionControl("Added new session + " + session.getName(), false, + monitor); + println("Added session " + session.getName() + " to version control."); + } + } /** diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/VT_Wizard.html b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/VT_Wizard.html index a4debe9092..3c0638379d 100644 --- a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/VT_Wizard.html +++ b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/VT_Wizard.html @@ -401,6 +401,56 @@ version tracking session.

+

Open an Existing Session

+ +
+ +

To open an existing session you can do one of the following:

+ +
+ +

Sessions in Project Repositories

+ +
+ +

Sessions can be versioned using Ghidra's + Project Repository + mechanism mostly in the same way programs or data archives can be with some + qualifications:

+ + + +
+ +

Provided by: Version Tracking Plugin

diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/start-here.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/start-here.png new file mode 100644 index 0000000000..fc9b0497fe Binary files /dev/null and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/start-here.png differ