GP-4085 Improved AutoVersionTrackingScript script to accomodate new

versioned session capability.  Added script to enable adding of vt
session to version control. Added help for shared project use of
VTSession.
This commit is contained in:
ghidra007 2024-02-21 23:47:13 +00:00 committed by ghidra1
parent c3386b72a2
commit a5a4da216e
6 changed files with 233 additions and 61 deletions

View file

@ -14,7 +14,7 @@
</HEAD>
<BODY>
<H1>Project Repository</H1>
<H1><A name="ProjectRepository"></A>Project Repository</H1>
<P>Ghidra supports the concept of a <I>project repository</I> such that files in the repository
can be <I>versioned</I>.&nbsp; <A name="Versioning"></A>Versioning allows you to track file

View file

@ -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|

View file

@ -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.");
}
}

View file

@ -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
//
// <ghidra_install>/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:
//
// <ghidra_install>/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.");
}
}
/**

View file

@ -401,6 +401,56 @@
version tracking session.</P>
</BLOCKQUOTE>
<H2><A name="Open_Existing_Session"></A>Open an Existing Session</H2>
<BLOCKQUOTE>
<P>To open an existing session you can do one of the following:</P>
<UL>
<LI>Double click a an existing Session in the Project Manager window. Sessions can be
identified by the <IMG border="0" src="images/start-here.png"> icon next to their names.</LI>
<LI>Drag an existing Session onto a running tool.</LI>
<LI>Choose File->Open Session... from an open Version Tracking tool and select a Version Tracking Session.</LI>
</BLOCKQUOTE>
<H2><A name="Versioning_Sessions"></A>Sessions in Project Repositories</H2>
<BLOCKQUOTE>
<P>Sessions can be versioned using Ghidra's
<A href="help/topics/VersionControl/project_repository.htm#ProjectRepository">Project Repository</A>
mechanism mostly in the same way programs or data archives can be with some
qualifications:</P>
<UL>
<LI>Most shared project actions work for Sessions as they normally do, such as <b>Add to
Version Control</b>, <b>Check In</b>, <b>History</b>, ... </LI>
<LI>When checking out a Session you must choose exclusive checkout because there is no
way to merge two Sessions that have been edited. Exclusive checkout will prevent others
from making changes to the session until an Undo Checkout is performed.</LI>
<LI>In order for others to check out a Session that another user has added to source
control, the two programs used in creating the session must be first added to source
control. NOTE: The exact two programs used when creating the Session (not copies of the
programs) must be the ones added.</LI>
<LI>When opening a versioned session in the active project the user may be prompted to perform a checkout if not currently checked-out.</LI>
<LI>Opening a versioned session must have an exclusive checkout or it will fail on open. In addition, only a session within the active project may be opened (i.e., not a viewed project or URL-based access). </LI>
<LI>NOTE: A session and its two programs must reside within the same project.</LI>
</UL>
</BLOCKQUOTE>
</BLOCKQUOTE><!-- Main content blockquote -->
<P class="providedbyplugin">Provided by: <I>Version Tracking Plugin</I></P>

Binary file not shown.

After

Width:  |  Height:  |  Size: 932 B