Merge remote-tracking branch 'origin/patch'

This commit is contained in:
ghidra1
2021-07-08 13:19:45 -04:00
3 changed files with 120 additions and 19 deletions
@@ -7,6 +7,36 @@
<BODY>
<H1 align="center">Ghidra 10.0.1 Change History (July 2021)</H1>
<blockquote><p><u>New Features</u></p>
<ul>
<li><I>Decompiler</I>. The Decompiler now supports conversion (hex, dec, bin, oct, char) and equate actions directly on constant tokens in the Decompiler window. To the extent possible, these actions also affect matching scalar operands in the listing. (GP-1053, Issue #21)</li>
</ul>
</blockquote>
<blockquote><p><u>Improvements</u></p>
<ul>
<li><I>Basic Infrastructure</I>. Ghidra now gracefully fails to launch when its path contains an exclamation point. (GP-1057, Issue #1817)</li>
<li><I>FileSystems</I>. Can now handle multi-level Ext4 extent nodes when reading a file. (GP-1070)</li>
</ul>
</blockquote>
<blockquote><p><u>Bugs</u></p>
<ul>
<li><I>Build</I>. No longer building and distributing the Debugger native test binaries. (GP-1080, Issue #3160, #3177)</li>
<li><I>Debugger</I>. Corrected potential deadlock condition within Debugger which could occur under some circumstances during a breakpoint or while stepping. (GP-1072)</li>
<li><I>Decompiler</I>. Fixed a bug in the Decompiler causing <code>Overriding symbol with different type size</code> exceptions. (GP-1041)</li>
<li><I>Exporter</I>. PE and ELF exporters no longer error out when processing non-file-backed relocations. (GP-1091)</li>
<li><I>FileSystems</I>. Corrected problem mounting Ext4 file systems when the container file is larger than the file system. (GP-1067)</li>
<li><I>Importer:ELF</I>. Corrected ELF relocation error reporting, including error bookmarks, when relocation handler extension is missing. (GP-1097)</li>
<li><I>Jython</I>. Added <code>__file__ attribute</code> support in Jython scripts. (GP-1099, Issue #3181)</li>
<li><I>PDB</I>. Fixed bug that prevented constructor signatures from being created properly. (GP-1086)</li>
<li><I>PDB</I>. Fixed bug in PDB CLI processing that could kill analysis for binaries imported with older versions of Ghidra. (GP-1104)</li>
<li><I>Processors</I>. Added ELF Relocation handler for SuperH processors. Only a few common relocation types have been added. (GP-1090)</li>
<li><I>Scripting</I>. Fixed a potential NullPointerException that could occur when trying to run a script that doesn't exist. (GP-1074, Issue #2742)</li>
<li><I>Scripting</I>. Improved graphing of class hierarchy in RecoverClassesFromRTTIScript and the GraphClassesScript to handle duplicate class names, class namespace delimiters, and to make better vertex descriptions. (GP-1095)</li>
<li><I>Scripting</I>. Fixed a flaw in the RecoverClassesFromRTTIScript that was not using PDB information to create data member names in class data structures. (GP-1101)</li>
</ul>
</blockquote>
<H1 align="center">Ghidra 10.0 Change History (June 2021)</H1>
<blockquote><p><u>New Features</u></p>
<ul>
@@ -439,6 +439,23 @@ public class PdbApplicator {
Msg.info(originator, message);
}
/**
* Puts error message to {@link PdbLog} and to Msg.error() which will
* also log a stack trace if exception is specified.
* @param originator a Logger instance, "this", or YourClass.class
* @param message the error message to display/log
* @param exc exception whose stack trace should be reported or null
*/
void pdbLogAndErrorMessage(Object originator, String message, Exception exc) {
PdbLog.message(message);
if (exc != null) {
Msg.error(originator, message);
}
else {
Msg.error(originator, message, exc);
}
}
/**
* Returns the {@link TaskMonitor} to available for this analyzer.
* @return the monitor.
@@ -928,6 +945,7 @@ public class PdbApplicator {
//==============================================================================================
// CLI-Managed infor methods.
//==============================================================================================
// Currently in CLI, but could move.
boolean isDll() {
return pdbCliManagedInfoManager.isDll();
@@ -938,6 +956,15 @@ public class PdbApplicator {
return pdbCliManagedInfoManager.isAslr();
}
/**
* Get CLI metadata for specified tableNum and rowNum within the CLI
* metadata stream.
* @param tableNum CLI metadata stream table index
* @param rowNum table row number
* @return CLI metadata or null if specified tableNum not found
* @throws PdbException if CLI metadata stream is not found in program file bytes
* @throws IndexOutOfBoundsException if specified rowNum is invalid
*/
CliAbstractTableRow getCliTableRow(int tableNum, int rowNum) throws PdbException {
return pdbCliManagedInfoManager.getCliTableRow(tableNum, rowNum);
}
@@ -37,6 +37,9 @@ import ghidra.program.model.listing.Program;
*/
public class PdbCliInfoManager {
private PdbApplicator applicator;
private boolean initComplete = false;
private CliStreamMetadata metadataStream;
// TODO: May move these out from this class to a higher level. Would mean passing in
@@ -46,22 +49,43 @@ public class PdbCliInfoManager {
/**
* Manager of CLI-related tables that we might need access to for PDB processing.
* @param applicator {@link PdbApplicator} for which this class is working.
* @param applicator {@link PdbApplicator} for which this class is working (used for logging purposes only).
*/
PdbCliInfoManager(PdbApplicator applicator) {
Objects.requireNonNull(applicator, "applicator may not be null");
metadataStream = getCliStreamMetadata(applicator);
this.applicator = applicator;
}
private synchronized void initialize() {
if (initComplete) {
return;
}
initComplete = true;
metadataStream = getCliStreamMetadata();
}
boolean isDll() {
initialize();
return isDll;
}
boolean isAslr() {
initialize();
return isAslr;
}
CliAbstractTableRow getCliTableRow(int tableNum, int rowNum) throws PdbException {
/**
* Get CLI metadata for specified tableNum and rowNum within the CLI
* metadata stream.
* @param tableNum CLI metadata stream table index
* @param rowNum table row number
* @return CLI metadata or null if specified tableNum not found
* @throws PdbException if CLI metadata stream is not found in program file bytes
* @throws IndexOutOfBoundsException if specified rowNum is invalid
*/
CliAbstractTableRow getCliTableRow(int tableNum, int rowNum)
throws PdbException, IndexOutOfBoundsException {
initialize();
if (metadataStream == null) {
throw new PdbException("CliStreamMetadata is null");
}
@@ -72,21 +96,34 @@ public class PdbCliInfoManager {
return table.getRow(rowNum);
}
private CliStreamMetadata getCliStreamMetadata(PdbApplicator applicator) {
/**
* Get CLI stream metadata
* @return CLI stream metadata or null if not found or error occured
*/
private CliStreamMetadata getCliStreamMetadata() {
Program program = applicator.getProgram();
if (program == null) {
return null;
}
List<FileBytes> allFileBytes = program.getMemory().getAllFileBytes();
if (allFileBytes.isEmpty()) {
applicator.pdbLogAndErrorMessage(this,
"Unable to retrieve CliStreamMetadata: no FileBytes", null);
return null;
}
FileBytes fileBytes = allFileBytes.get(0); // Should be that of main imported file
ByteProvider provider = new FileBytesProvider(fileBytes);
PortableExecutable pe = null;
ByteProvider provider = new FileBytesProvider(fileBytes); // close not required
try {
GenericFactory factory = MessageLogContinuesFactory.create(applicator.getMessageLog());
pe = PortableExecutable.createPortableExecutable(factory, provider, SectionLayout.FILE,
true, true);
NTHeader ntHeader = pe.getNTHeader();
PortableExecutable pe = PortableExecutable.createPortableExecutable(factory, provider,
SectionLayout.FILE, true, true);
NTHeader ntHeader = pe.getNTHeader(); // will be null if header parse fails
if (ntHeader == null) {
applicator.pdbLogAndErrorMessage(this,
"Unable to retrieve CliStreamMetadata: NTHeader file bytes not found", null);
return null;
}
OptionalHeader optionalHeader = ntHeader.getOptionalHeader();
int characteristics = ntHeader.getFileHeader().getCharacteristics();
isDll = (characteristics & FileHeader.IMAGE_FILE_DLL) == FileHeader.IMAGE_FILE_DLL;
@@ -94,25 +131,32 @@ public class PdbCliInfoManager {
int optionalHeaderCharaceristics = optionalHeader.getDllCharacteristics();
isAslr = (optionalHeaderCharaceristics &
OptionalHeader.IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA) == OptionalHeader.IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA;
if (OptionalHeader.IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR >= dataDirectory.length) {
applicator.pdbLogAndErrorMessage(this,
"Unable to retrieve CliStreamMetadata: Bad index (" +
OptionalHeader.IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR +
") for COMDescriptorDataDirectory in DataDirectory array of size " +
dataDirectory.length,
null);
return null;
}
COMDescriptorDataDirectory comDir =
(COMDescriptorDataDirectory) dataDirectory[OptionalHeader.IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR];
ImageCor20Header header = comDir.getHeader();
if (header == null) {
applicator.pdbLogAndErrorMessage(this,
"Unable to retrieve CliStreamMetadata: no COMDir header", null);
return null;
}
return header.getMetadata().getMetadataRoot().getMetadataStream();
}
catch (Exception e) {
applicator.pdbLogAndInfoMessage(this, "Unable to retrieve CliStreamMetadata");
catch (RuntimeException | IOException e) {
// We do not know what can go wrong. Some of the header parsing might have issues,
// and we'd rather log the error and limp on by with whatever other processing we can
// do than to fail here.
applicator.pdbLogAndErrorMessage(this,
"Unable to retrieve CliStreamMetadata: " + e.getMessage(), e);
return null;
}
finally {
try {
provider.close();
}
catch (IOException ioe) {
applicator.pdbLogAndInfoMessage(this, "Problem closing ByteProvider");
}
}
}
}