Candidate release of source code.

This commit is contained in:
Dan 2019-03-26 13:45:32 -04:00
parent db81e6b3b0
commit 79d8f164f8
12449 changed files with 2800756 additions and 16 deletions

View file

@ -0,0 +1,98 @@
/* ###
* 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.
*/
// An example of how to create Version Tracking session, run some correlators to find matching
// data and and then save the session.
//@category Examples.Version Tracking
import java.util.Iterator;
import java.util.List;
import ghidra.app.script.GhidraScript;
import ghidra.feature.vt.api.db.VTSessionDB;
import ghidra.feature.vt.api.main.VTSession;
import ghidra.feature.vt.gui.actions.AutoVersionTrackingCommand;
import ghidra.feature.vt.gui.plugin.*;
import ghidra.framework.model.DomainFolder;
import ghidra.framework.plugintool.Plugin;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.listing.Program;
public class AutoVersionTrackingScript extends GhidraScript {
@Override
public void run() throws Exception {
DomainFolder folder =
askProjectFolder("Please choose a folder for your Version Tracking session.");
String name = askString("Please enter a Version Tracking session name", "Session Name");
Program sourceProgram;
Program destinationProgram;
boolean isCurrentProgramSourceProg = askYesNo("Current Program Source Program?",
"Is the current program your source program?");
if (isCurrentProgramSourceProg) {
sourceProgram = currentProgram;
destinationProgram = askProgram("Please select the destination (new) program");
}
else {
destinationProgram = currentProgram;
sourceProgram = askProgram("Please select the source (existing annotated) program");
}
// Need to end the script transaction or it interferes with vt things that need locks
end(true);
VTSession session =
VTSessionDB.createVTSession(name, sourceProgram, destinationProgram, this);
folder.createFile(name, session, monitor);
PluginTool tool = state.getTool();
VTPlugin vtPlugin = getPlugin(tool, VTPlugin.class);
if (vtPlugin == null) {
tool.addPlugin(VTPlugin.class.getName());
vtPlugin = getPlugin(tool, VTPlugin.class);
}
VTController controller = new VTControllerImpl(vtPlugin);
//String description = "AutoVTScript";
AutoVersionTrackingCommand autoVTcmd =
new AutoVersionTrackingCommand(controller, session, 1.0, 10.0);
controller.getTool().executeBackgroundCommand(autoVTcmd, session);
//destinationProgram.save(description, monitor);
//session.save(description, monitor);
//session.release(this);
}
public static <T extends Plugin> T getPlugin(PluginTool tool, Class<T> c) {
List<Plugin> list = tool.getManagedPlugins();
Iterator<Plugin> it = list.iterator();
while (it.hasNext()) {
Plugin p = it.next();
if (p.getClass() == c) {
return c.cast(p);
}
}
return null;
}
}

View file

@ -0,0 +1,174 @@
/* ###
* 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.
*/
// An example of how to create Version Tracking session, run some correlators to find matching
// data and and then save the session.
//@category Examples.Version Tracking
import ghidra.app.script.GhidraScript;
import ghidra.feature.vt.api.correlator.program.*;
import ghidra.feature.vt.api.db.VTSessionDB;
import ghidra.feature.vt.api.main.*;
import ghidra.feature.vt.api.markuptype.*;
import ghidra.feature.vt.api.util.*;
import ghidra.framework.model.DomainFolder;
import ghidra.framework.options.ToolOptions;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.address.AddressSet;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.listing.Program;
import ghidra.util.exception.CancelledException;
import java.util.Collection;
import java.util.List;
public class CreateAppliedExactMatchingSessionScript extends GhidraScript {
@Override
public void run() throws Exception {
DomainFolder folder =
askProjectFolder("Please choose a folder for the session domain object");
String name = askString("Please enter a Version Tracking session name", "Session Name");
Program sourceProgram = askProgram("Please select the source (existing annotated) program");
Program destinationProgram = askProgram("Please select the destination (new) program");
VTSession session =
VTSessionDB.createVTSession(name, sourceProgram, destinationProgram, this);
// it seems clunky to have to create this separately, but I'm not sure how else to do it
folder.createFile(name, session, monitor);
String description = "CreateAppliedExactMatchingSession";
int sessionTransaction = session.startTransaction(description);
try {
PluginTool serviceProvider = state.getTool();
VTAssociationManager manager = session.getAssociationManager();
// should we have convenience methods in VTCorrelator that don't
// take address sets, thus implying the entire address space should be used?
AddressSetView sourceAddressSet = sourceProgram.getMemory().getLoadedAndInitializedAddressSet();
AddressSetView destinationAddressSet =
destinationProgram.getMemory().getLoadedAndInitializedAddressSet();
VTProgramCorrelatorFactory factory;
factory = new ExactDataMatchProgramCorrelatorFactory();
correlateAndPossiblyApply(sourceProgram, destinationProgram, session, serviceProvider,
manager, sourceAddressSet, destinationAddressSet, factory);
factory = new ExactMatchBytesProgramCorrelatorFactory();
correlateAndPossiblyApply(sourceProgram, destinationProgram, session, serviceProvider,
manager, sourceAddressSet, destinationAddressSet, factory);
factory = new ExactMatchInstructionsProgramCorrelatorFactory();
correlateAndPossiblyApply(sourceProgram, destinationProgram, session, serviceProvider,
manager, sourceAddressSet, destinationAddressSet, factory);
}
finally {
try {
session.endTransaction(sessionTransaction, true);
destinationProgram.save(description, monitor);
session.save(description, monitor);
}
finally {
session.release(this);
}
}
}
private void correlateAndPossiblyApply(Program sourceProgram, Program destinationProgram,
VTSession session, PluginTool serviceProvider, VTAssociationManager manager,
AddressSetView sourceAddressSet, AddressSetView destinationAddressSet,
VTProgramCorrelatorFactory factory) throws CancelledException,
VTAssociationStatusException {
AddressSetView restrictedSourceAddresses =
excludeAcceptedMatches(session, sourceAddressSet, true);
AddressSetView restrictedDestinationAddresses =
excludeAcceptedMatches(session, destinationAddressSet, false);
VTOptions options = factory.createDefaultOptions();
VTProgramCorrelator correlator =
factory.createCorrelator(serviceProvider, sourceProgram, restrictedSourceAddresses,
destinationProgram, restrictedDestinationAddresses, options);
VTMatchSet results = correlator.correlate(session, monitor);
applyMatches(manager, results.getMatches());
}
private void applyMatches(VTAssociationManager manager, Collection<VTMatch> matches)
throws VTAssociationStatusException, CancelledException {
for (VTMatch match : matches) {
VTAssociation association = match.getAssociation();
association.setAccepted();
Collection<VTMarkupItem> markupItems = association.getMarkupItems(monitor);
for (VTMarkupItem vtMarkupItem : markupItems) {
maybeApplyMarkup(association, vtMarkupItem);
}
}
}
private void maybeApplyMarkup(VTAssociation association, VTMarkupItem vtMarkupItem) {
//
// Note: We use 'null' for options here, which signals to use the default apply
// operation. To configure apply options, see GhidraVersionTrackingScript.
//
ToolOptions options = null;
VTMarkupType markupType = vtMarkupItem.getMarkupType();
if (markupType == FunctionNameMarkupType.INSTANCE) {
try {
vtMarkupItem.apply(VTMarkupItemApplyActionType.REPLACE, options);
}
catch (VersionTrackingApplyException e) {
printerr("could not transfer function name " +
vtMarkupItem.getSourceValue().getDisplayString());
}
}
else if (markupType == LabelMarkupType.INSTANCE &&
association.getType() == VTAssociationType.DATA) {
try {
vtMarkupItem.apply(VTMarkupItemApplyActionType.REPLACE, options);
}
catch (VersionTrackingApplyException e) {
printerr("could not transfer data name " +
vtMarkupItem.getSourceValue().getDisplayString());
}
}
}
private AddressSet excludeAcceptedMatches(VTSession session, AddressSetView addrSetView,
boolean source) {
AddressSet addrSet = new AddressSet(addrSetView);
if (session == null) {
return addrSet;
}
List<VTMatchSet> matchSets = session.getMatchSets();
for (VTMatchSet matchSet : matchSets) {
Collection<VTMatch> matches = matchSet.getMatches();
for (VTMatch match : matches) {
VTAssociationStatus status = match.getAssociation().getStatus();
if (status == VTAssociationStatus.ACCEPTED) {
AddressSetView matchAddresses = VTMatchUtil.getMatchAddresses(match, source);
addrSet.delete(matchAddresses);
}
}
}
return addrSet;
}
}

View file

@ -0,0 +1,84 @@
/* ###
* 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.
*/
// An example of how to use Version Tracking to find matching and non-matching functions between
// two different versions of the same program.
//@category Examples.Version Tracking
import java.util.Collection;
import java.util.Set;
import ghidra.feature.vt.GhidraVersionTrackingScript;
import ghidra.feature.vt.api.main.VTMatch;
import ghidra.framework.model.Project;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program;
import ghidra.util.Msg;
public class FindChangedFunctionsScript extends GhidraVersionTrackingScript {
@Override
protected void run() throws Exception {
Project project = state.getProject();
if (project == null) {
throw new RuntimeException("No project open");
}
// Prompt the user to load the two programs that will be analyzed.
// This will only allow you to select programs from the currently-open
// project in Ghidra, so import them if you haven't already.
Program p1 = askProgram("Program1_Version1");
Program p2 = askProgram("Program1_Version2");
// Make sure the selected programs are not open and locked by Ghidra. If so,
// warn the user.
if (areProgramsLocked(p1, p2)) {
Msg.showError(this, null, "Program is locked!", "One of the programs you selected is locked by Ghidra. Please correct and try again.");
return;
}
// Create a new VT session
createVersionTrackingSession("new session", p1, p2);
runCorrelator("Exact Function Instructions Match");
Set<String> functionNames = getSourceFunctions();
Collection<VTMatch> matches = getMatchesFromLastRunCorrelator();
for (VTMatch vtMatch : matches) {
Function function = getSourceFunction(vtMatch);
functionNames.remove(function.getName());
println("Found exact match for " + function.getName());
}
for (String functionName : functionNames) {
println("Did not find exact match for: " + functionName);
}
}
/**
* Returns true if one of the programs is locked.
* <p>
* Note: calling {@link Program#isLocked()} does not work here; we must
* check to see if one of the programs is the currently-open program.
*
* @param p1 the first program
* @param p2 the second program
* @return true if either program is locked
*/
private boolean areProgramsLocked(Program p1, Program p2) {
return p1 == currentProgram || p2 == currentProgram;
}
}

View file

@ -0,0 +1,67 @@
/* ###
* 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.
*/
// An example of how to open an existing Version Tracking session, manipulate some data and then
// save the session.
//@category Examples.Version Tracking
import java.util.Collection;
import java.util.List;
import ghidra.feature.vt.GhidraVersionTrackingScript;
import ghidra.feature.vt.api.main.*;
public class OpenVersionTrackingSessionScript extends GhidraVersionTrackingScript {
@Override
protected void run() throws Exception {
openVersionTrackingSession("/VT__WallaceSrc__WallaceVersion2.exe");
acceptMatchesWithGoodConfidence();
saveVersionTrackingSession();
}
private void acceptMatchesWithGoodConfidence() throws Exception {
println("Working on session: " + vtSession);
List<VTMatchSet> matchSets = vtSession.getMatchSets();
for (VTMatchSet matchSet : matchSets) {
println("Match set contains " + matchSet.getMatchCount() + " matches");
//
// Do some work here - this example is an arbitrary accepting of matches that pass an
// arbitrary confidence level
//
double arbitraryValue = 10.0D;
Collection<VTMatch> matches = matchSet.getMatches();
for (VTMatch match : matches) {
VTAssociation association = match.getAssociation();
if (association.getStatus() != VTAssociationStatus.AVAILABLE) {
continue;
}
VTScore confidenceScore = match.getConfidenceScore();
if (confidenceScore.getScore() > arbitraryValue) {
println("\taccepting: " + match);
association.setAccepted();
}
else {
association.setRejected();
println("\trejecting: " + match);
}
}
}
}
}

View file

@ -0,0 +1,146 @@
/* ###
* 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.
*/
// An example of how to use an existing Version Tracking session to iterate over accepted matches
// to manipulate function prototypes.
//@category Examples.Version Tracking
import ghidra.app.script.GhidraScript;
import ghidra.app.script.ImproperUseException;
import ghidra.feature.vt.api.db.VTSessionDB;
import ghidra.feature.vt.api.main.*;
import ghidra.framework.model.DomainFile;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address;
import ghidra.program.model.lang.Language;
import ghidra.program.model.lang.LanguageDescription;
import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.SourceType;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.InvalidInputException;
import java.util.List;
public class OverrideFunctionPrototypesOnAcceptedMatchesScript extends GhidraScript {
@Override
protected void run() throws Exception {
DomainFile vtFile = askDomainFile("Select VT Session");
openVTSessionAndDoWork(vtFile);
}
private void openVTSessionAndDoWork(DomainFile domainFile) {
DomainObject vtDomainObject = null;
try {
vtDomainObject = domainFile.getDomainObject(this, false, false, monitor);
doWork((VTSessionDB) vtDomainObject);
}
catch (ClassCastException e) {
printerr("That domain object (" + domainFile.getName() + ") is not a VT session");
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (vtDomainObject != null) {
vtDomainObject.release(this);
}
}
}
private void doWork(VTSessionDB session) throws InvalidInputException, DuplicateNameException,
ImproperUseException {
println("Working on session: " + session);
Program sourceProg = session.getSourceProgram();
Program destProg = session.getDestinationProgram();
int transID = -1;
boolean allIsGood = false;
try {
transID = destProg.startTransaction("OverrideFunctionPrototypes");
Language sourceLanguage = sourceProg.getLanguage();
Language destLanguage = destProg.getLanguage();
LanguageDescription sourceDesc = sourceLanguage.getLanguageDescription();
LanguageDescription destDesc = destLanguage.getLanguageDescription();
if (!(sourceDesc.getProcessor().equals(destDesc.getProcessor()) &&
sourceDesc.getEndian() == destDesc.getEndian() && sourceDesc.getSize() == destDesc.getSize())) {
boolean yes =
askYesNo("Warning: possibly incompatible source/dest architectures",
"Source and destination programs might have different architectures. Continue?");
if (!yes) {
return;
}
}
FunctionManager sourceFuncMgr = sourceProg.getFunctionManager();
FunctionManager destFuncMgr = destProg.getFunctionManager();
VTAssociationManager associationManager = session.getAssociationManager();
List<VTAssociation> associations = associationManager.getAssociations();
for (VTAssociation association : associations) {
if (association.getType() == VTAssociationType.FUNCTION &&
association.getStatus() == VTAssociationStatus.ACCEPTED) {
Address srcAddr = association.getSourceAddress();
Address destAddr = association.getDestinationAddress();
Function sourceFunc = sourceFuncMgr.getFunctionAt(srcAddr);
if (sourceFunc == null) {
continue;
}
Function destFunc = destFuncMgr.getFunctionAt(destAddr);
if (destFunc == null) {
continue;
}
transfer(sourceFunc, destFunc);
}
}
allIsGood = true;
}
finally {
if (transID != -1) {
destProg.endTransaction(transID, allIsGood);
}
}
}
@SuppressWarnings("deprecation")
private void transfer(Function sourceFunc, Function destFunc) throws InvalidInputException,
DuplicateNameException {
// FIXME: this is just a skeleton, I am dumb, failed all of RE, etc.
// please make this do what you really want
destFunc.setReturnType(sourceFunc.getReturnType(), sourceFunc.getSignatureSource());
destFunc.setName(sourceFunc.getName(), SourceType.USER_DEFINED);
destFunc.setCallingConvention(sourceFunc.getCallingConventionName());
int parameterCount = destFunc.getParameterCount();
for (int ii = parameterCount - 1; ii >= 0; --ii) {
// TODO: Fix deprecated method call
destFunc.removeParameter(ii);
}
parameterCount = sourceFunc.getParameterCount();
for (int ii = 0; ii < parameterCount; ++ii) {
Parameter parameter = sourceFunc.getParameter(ii);
// TODO: Fix deprecated method call
destFunc.addParameter(parameter, SourceType.USER_DEFINED);
}
}
}