Merge remote-tracking branch 'origin/GT-2753_Dan_PR-331_cblichmann_AddSHA256ToProgramAPI'

This commit is contained in:
ghidravore 2019-04-12 12:20:20 -04:00
commit ca7d169d62
5 changed files with 81 additions and 26 deletions

View File

@ -39,8 +39,7 @@ import ghidra.program.model.symbol.*;
import ghidra.program.model.util.AddressLabelInfo; import ghidra.program.model.util.AddressLabelInfo;
import ghidra.program.util.DefaultLanguageService; import ghidra.program.util.DefaultLanguageService;
import ghidra.program.util.GhidraProgramUtilities; import ghidra.program.util.GhidraProgramUtilities;
import ghidra.util.InvalidNameException; import ghidra.util.*;
import ghidra.util.MD5Utilities;
import ghidra.util.exception.*; import ghidra.util.exception.*;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
@ -111,8 +110,8 @@ public abstract class AbstractProgramLoader implements Loader {
return results; return results;
} }
List<Program> programs = loadProgram(provider, name, folder, loadSpec, options, messageLog, List<Program> programs =
consumer, monitor); loadProgram(provider, name, folder, loadSpec, options, messageLog, consumer, monitor);
boolean success = false; boolean success = false;
try { try {
@ -285,6 +284,8 @@ public abstract class AbstractProgramLoader implements Loader {
} }
String md5 = computeBinaryMD5(provider); String md5 = computeBinaryMD5(provider);
prog.setExecutableMD5(md5); prog.setExecutableMD5(md5);
String sha256 = computeBinarySHA256(provider);
prog.setExecutableSHA256(sha256);
if (shouldSetImageBase(prog, imageBase)) { if (shouldSetImageBase(prog, imageBase)) {
try { try {
@ -465,6 +466,12 @@ public abstract class AbstractProgramLoader implements Loader {
} }
} }
private String computeBinarySHA256(ByteProvider provider) throws IOException {
try (InputStream in = provider.getInputStream(0)) {
return HashUtilities.getHash(HashUtilities.SHA256_ALGORITHM, in);
}
}
private boolean shouldSetImageBase(Program prog, Address imageBase) { private boolean shouldSetImageBase(Program prog, Address imageBase) {
if (imageBase == null || imageBase instanceof SegmentedAddress) { if (imageBase == null || imageBase instanceof SegmentedAddress) {
return false; return false;

View File

@ -128,6 +128,7 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
private static final String EXECUTABLE_PATH = "Executable Location"; private static final String EXECUTABLE_PATH = "Executable Location";
private static final String EXECUTABLE_FORMAT = "Executable Format"; private static final String EXECUTABLE_FORMAT = "Executable Format";
private static final String EXECUTABLE_MD5 = "Executable MD5"; private static final String EXECUTABLE_MD5 = "Executable MD5";
private static final String EXECUTABLE_SHA256 = "Executable SHA256";
private static final String TABLE_NAME = "Program"; private static final String TABLE_NAME = "Program";
private static final String EXECUTE_PATH = "Execute Path"; private static final String EXECUTE_PATH = "Execute Path";
private static final String EXECUTE_FORMAT = "Execute Format"; private static final String EXECUTE_FORMAT = "Execute Format";
@ -716,7 +717,6 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
} }
/** /**
*
* @see ghidra.program.model.listing.Program#setExecutableFormat(java.lang.String) * @see ghidra.program.model.listing.Program#setExecutableFormat(java.lang.String)
*/ */
@Override @Override
@ -742,7 +742,6 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
} }
/** /**
*
* @see ghidra.program.model.listing.Program#setExecutableMD5(java.lang.String) * @see ghidra.program.model.listing.Program#setExecutableMD5(java.lang.String)
*/ */
@Override @Override
@ -752,6 +751,31 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
changed = true; changed = true;
} }
/**
* @see ghidra.program.model.listing.Program#getExecutableSHA256()
*/
@Override
public String getExecutableSHA256() {
String format = null;
try {
Options pl = getOptions(PROGRAM_INFO);
format = pl.getString(EXECUTABLE_SHA256, (String) null);
}
catch (Exception e) {
}
return format == null ? UNKNOWN : format;
}
/**
* @see ghidra.program.model.listing.Program#setExecutableSHA256(java.lang.String)
*/
@Override
public void setExecutableSHA256(String sha256) {
Options pl = getOptions(PROGRAM_INFO);
pl.setString(EXECUTABLE_SHA256, sha256);
changed = true;
}
/** /**
* @see ghidra.program.model.listing.Program#getCreationDate() * @see ghidra.program.model.listing.Program#getCreationDate()
*/ */

View File

@ -102,7 +102,7 @@ public interface Program extends DataTypeManagerDomainObject {
public SymbolTable getSymbolTable(); public SymbolTable getSymbolTable();
/** /**
* Returns the external manager. * Returns the external manager.
*/ */
public ExternalManager getExternalManager(); public ExternalManager getExternalManager();
@ -190,6 +190,18 @@ public interface Program extends DataTypeManagerDomainObject {
*/ */
public void setExecutableMD5(String md5); public void setExecutableMD5(String md5);
/**
* Sets the value corresponding to the original binary file SHA256 hash.
* @param sha256 SHA256 binary file hash
*/
public void setExecutableSHA256(String sha256);
/**
* Returns a value corresponding to the original binary file SHA256 hash.
* May be null if program source did not correspond to a binary file.
*/
public String getExecutableSHA256();
/** /**
* Returns the creation date of this program. * Returns the creation date of this program.
* If the program was created before this property * If the program was created before this property
@ -343,8 +355,8 @@ public interface Program extends DataTypeManagerDomainObject {
* This will never be thrown if commit is false. * This will never be thrown if commit is false.
* @throws IllegalStateException if the program state is not suitable for setting the image base. * @throws IllegalStateException if the program state is not suitable for setting the image base.
*/ */
public void setImageBase(Address base, boolean commit) throws AddressOverflowException, public void setImageBase(Address base, boolean commit)
LockException, IllegalStateException; throws AddressOverflowException, LockException, IllegalStateException;
/** /**
* Restores the last committed image base. * Restores the last committed image base.
@ -365,8 +377,8 @@ public interface Program extends DataTypeManagerDomainObject {
* @throws LockException if the program is shared and not checked out exclusively. * @throws LockException if the program is shared and not checked out exclusively.
*/ */
public void setLanguage(Language language, CompilerSpecID compilerSpecID, public void setLanguage(Language language, CompilerSpecID compilerSpecID,
boolean forceRedisassembly, TaskMonitor monitor) throws IllegalStateException, boolean forceRedisassembly, TaskMonitor monitor)
IncompatibleLanguageException, LockException; throws IllegalStateException, IncompatibleLanguageException, LockException;
/** /**
* Returns the global namespace for this program * Returns the global namespace for this program

View File

@ -15,6 +15,10 @@
*/ */
package ghidra.program.model; package ghidra.program.model;
import java.io.File;
import java.io.IOException;
import java.util.*;
import ghidra.framework.model.*; import ghidra.framework.model.*;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
import ghidra.framework.store.LockException; import ghidra.framework.store.LockException;
@ -34,10 +38,6 @@ import ghidra.util.exception.CancelledException;
import ghidra.util.exception.DuplicateNameException; import ghidra.util.exception.DuplicateNameException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
import java.io.File;
import java.io.IOException;
import java.util.*;
public class ProgramTestDouble implements Program { public class ProgramTestDouble implements Program {
@Override @Override
@ -111,8 +111,8 @@ public class ProgramTestDouble implements Program {
} }
@Override @Override
public void saveToPackedFile(File outputFile, TaskMonitor monitor) throws IOException, public void saveToPackedFile(File outputFile, TaskMonitor monitor)
CancelledException { throws IOException, CancelledException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@ -406,6 +406,16 @@ public class ProgramTestDouble implements Program {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public String getExecutableSHA256() {
throw new UnsupportedOperationException();
}
@Override
public void setExecutableSHA256(String sha256) {
throw new UnsupportedOperationException();
}
@Override @Override
public Date getCreationDate() { public Date getCreationDate() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
@ -507,8 +517,8 @@ public class ProgramTestDouble implements Program {
} }
@Override @Override
public void setImageBase(Address base, boolean commit) throws AddressOverflowException, public void setImageBase(Address base, boolean commit)
LockException, IllegalStateException { throws AddressOverflowException, LockException, IllegalStateException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@ -519,8 +529,8 @@ public class ProgramTestDouble implements Program {
@Override @Override
public void setLanguage(Language language, CompilerSpecID compilerSpecID, public void setLanguage(Language language, CompilerSpecID compilerSpecID,
boolean forceRedisassembly, TaskMonitor monitor) throws IllegalStateException, boolean forceRedisassembly, TaskMonitor monitor)
IncompatibleLanguageException, LockException { throws IllegalStateException, IncompatibleLanguageException, LockException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }

View File

@ -786,7 +786,7 @@ public class ServerTestUtil {
funcAddr += 2; funcAddr += 2;
} }
setProgramMd5(program); setProgramHashes(program);
ContentHandler contentHandler = DomainObjectAdapter.getContentHandler(program); ContentHandler contentHandler = DomainObjectAdapter.getContentHandler(program);
long checkoutId = contentHandler.createFile(repoFilesystem, null, folderPath, name, long checkoutId = contentHandler.createFile(repoFilesystem, null, folderPath, name,
@ -856,15 +856,17 @@ public class ServerTestUtil {
} }
/** /**
* Sets a dummy MD5 value for the given program. * Sets dummy hash values for the given program.
* *
* @param program the current program * @param program the current program
*/ */
private static void setProgramMd5(Program program) { private static void setProgramHashes(Program program) {
int id = program.startTransaction("setmd5"); int id = program.startTransaction("sethashes");
try { try {
String md5 = RandomStringUtils.randomNumeric(32); String md5 = RandomStringUtils.randomNumeric(32);
program.setExecutableMD5(md5); program.setExecutableMD5(md5);
String sha256 = RandomStringUtils.randomNumeric(64);
program.setExecutableSHA256(sha256);
} }
finally { finally {
program.endTransaction(id, true); program.endTransaction(id, true);