mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-10 14:11:59 +00:00
Merge branch 'GP-1104_ghizard_Fix_PDB_CLI_processing_bug' into patch
This commit is contained in:
commit
3c1e51d0c0
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user