Skip to content

Commit

Permalink
Merge branch 'GP-1104_ghizard_Fix_PDB_CLI_processing_bug' into patch
Browse files Browse the repository at this point in the history
  • Loading branch information
ghidra1 committed Jul 8, 2021
2 parents 7fde6c7 + fd2b5da commit 3c1e51d
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,23 @@ void pdbLogAndInfoMessage(Object originator, String message) {
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.
Expand Down Expand Up @@ -928,6 +945,7 @@ void addMemorySectionRefinement(PeCoffSectionMsSymbol symbol) {
//==============================================================================================
// CLI-Managed infor methods.
//==============================================================================================

// Currently in CLI, but could move.
boolean isDll() {
return pdbCliManagedInfoManager.isDll();
Expand All @@ -938,6 +956,15 @@ boolean isAslr() {
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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
*/
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
Expand All @@ -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");
}
Expand All @@ -72,47 +96,67 @@ CliAbstractTableRow getCliTableRow(int tableNum, int rowNum) throws PdbException
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;
DataDirectory[] dataDirectory = optionalHeader.getDataDirectories();
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");
}
}
}
}

0 comments on commit 3c1e51d

Please sign in to comment.