Merge remote-tracking branch 'origin/GP-968_ghizard_PDB_CLI_quieting_and_fix_filebytes_parsing--SQUASHED'

This commit is contained in:
ghidra1 2021-05-18 21:28:11 -04:00
commit 1753252922
5 changed files with 112 additions and 17 deletions

View File

@ -24,6 +24,62 @@ import ghidra.util.DataConverter;
import ghidra.util.task.TaskMonitor;
public interface OptionalHeader extends StructConverter {
/**
* ASLR with 64 bit address space.
*/
public final static int IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020;
/**
* The DLL can be relocated at load time.
*/
public final static int IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040;
/**
* Code integrity checks are forced.
*/
public final static int IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 0x0080;
/**
* The image is compatible with data execution prevention (DEP)
*/
public final static int IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100;
/**
* The image is isolation aware, but should not be isolated.
*/
public final static int IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200;
/**
* The image does not use structured exception handling (SEH).
*/
public final static int IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400;
/**
* Do not bind the image.
*/
public final static int IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800;
/**
* Image should execute in an AppContainer.
*/
public final static int IMAGE_DLLCHARACTERISTICS_APPCONTAINER = 0x1000;
/**
* A WDM driver.
*/
public final static int IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000;
/**
* Image supports Control Flow Guard.
*/
public final static int IMAGE_DLLCHARACTERISTICS_GUARD_CF = 0x4000;
/**
* The image is terminal server aware.
*/
public final static int IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000;
/**
* The count of data directories in the optional header.
*/
@ -262,7 +318,7 @@ public interface OptionalHeader extends StructConverter {
public void setSizeOfInitializedData(long size);
/**
* Returns the size of all sections with the uninitialized
* Returns the size of all sections with the uninitialized
* data attributes.
* @return the size of all sections with the uninitialized data attributes
*/
@ -307,10 +363,10 @@ public interface OptionalHeader extends StructConverter {
/**
* Writes this optional header to the specified random access file.
*
*
* @param raf the random access file
* @param dc the data converter
*
*
* @throws IOException
*/
public void writeHeader(RandomAccessFile raf, DataConverter dc) throws IOException;

View File

@ -168,11 +168,13 @@ public class ManagedProcedureSymbolApplier extends MsSymbolApplier {
@Override
void apply() throws PdbException, CancelledException {
boolean result = applyTo(applicator.getCancelOnlyWrappingMonitor());
if (result == false) {
throw new PdbException(this.getClass().getSimpleName() + ": failure at " + address +
" applying " + getName());
}
// TODO. Investigate more. This is not working for at least one CLI dll in that we are
// not getting correct addresses. There is no omap and the one section is unnamed.
// boolean result = applyTo(applicator.getCancelOnlyWrappingMonitor());
// if (result == false) {
// throw new PdbException(this.getClass().getSimpleName() + ": failure at " + address +
// " applying " + getName());
// }
}
boolean applyTo(TaskMonitor monitor) throws PdbException, CancelledException {
@ -291,6 +293,8 @@ public class ManagedProcedureSymbolApplier extends MsSymbolApplier {
}
// Rest presumes procedureSymbol.
long token = procedureSymbol.getToken();
// TODO: once GP-328 is merged, use static methods to get table and row.
// CliIndexUtils.getTableIdUnencoded(token) and .getRowIdUnencoded(token).
int table = (int) (token >> 24) & 0xff;
int row = (int) (token & 0xffffff);

View File

@ -99,7 +99,7 @@ public class PdbAddressManager {
/**
* Returns the Address for the given symbol. If the {@link PdbApplicatorOptions}
* Address Remap option is turned on is turned on, it will attempt to map the address to a
* new address in the current program.
* new address in the current program.
* @param symbol The {@link AddressMsSymbol}
* @return The Address, which can be {@code Address.NO_ADDRESS} if invalid or
* {@code Address.EXTERNAL_ADDRESS} if the address is external to the program.
@ -111,7 +111,7 @@ public class PdbAddressManager {
/**
* Returns the Address for the given section and offset. If the {@link PdbApplicatorOptions}
* Address Remap option is turned on is turned on, it will attempt to map the address to a
* new address in the current program.
* new address in the current program.
* @param segment The segment
* @param offset The offset
* @return The Address, which can be {@code Address.NO_ADDRESS} if invalid or
@ -128,7 +128,7 @@ public class PdbAddressManager {
/**
* Returns the Address for the given section and offset. If the {@link PdbApplicatorOptions}
* Address Remap option is turned on is turned on, it will attempt to map the address to a
* new address in the current program.
* new address in the current program.
* @param symbol The {@link AddressMsSymbol}
* @return The Address, which can be {@code Address.NO_ADDRESS} if invalid or
* {@code Address.EXTERNAL_ADDRESS} if the address is external to the program.
@ -298,7 +298,7 @@ public class PdbAddressManager {
// // Set section/segment 0 to image base. (should be what is header), but what is its size?
// // TODO... made up size for now... is there something else? We could put null instead.
// // For now, the method that reads this information might report EXTERNAL instead of
// // trying to use this.
// // trying to use this.
// long segmentZeroLength = 0x7fffffff;
// allSegmentsInfo.add(new SegmentInfo(imageBase, segmentZeroLength));
// PdbDebugInfo dbi = applicator.getPdb().getDebugInfo();

View File

@ -928,6 +928,16 @@ public class PdbApplicator {
//==============================================================================================
// CLI-Managed infor methods.
//==============================================================================================
// Currently in CLI, but could move.
boolean isDll() {
return pdbCliManagedInfoManager.isDll();
}
// Currently in CLI, but could move.
boolean isAslr() {
return pdbCliManagedInfoManager.isAslr();
}
CliAbstractTableRow getCliTableRow(int tableNum, int rowNum) throws PdbException {
return pdbCliManagedInfoManager.getCliTableRow(tableNum, rowNum);
}

View File

@ -16,11 +16,12 @@
package ghidra.app.util.pdb.pdbapplicator;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import generic.continues.GenericFactory;
import ghidra.app.util.bin.ByteProvider;
import ghidra.app.util.bin.MemoryByteProvider;
import ghidra.app.util.bin.FileBytesProvider;
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
import ghidra.app.util.bin.format.pe.*;
import ghidra.app.util.bin.format.pe.PortableExecutable.SectionLayout;
@ -28,6 +29,7 @@ import ghidra.app.util.bin.format.pe.cli.streams.CliStreamMetadata;
import ghidra.app.util.bin.format.pe.cli.tables.CliAbstractTable;
import ghidra.app.util.bin.format.pe.cli.tables.CliAbstractTableRow;
import ghidra.app.util.importer.MessageLogContinuesFactory;
import ghidra.program.database.mem.FileBytes;
import ghidra.program.model.listing.Program;
/**
@ -37,6 +39,11 @@ public class PdbCliInfoManager {
private CliStreamMetadata metadataStream;
// TODO: May move these out from this class to a higher level. Would mean passing in
// the appropriate header to this constructor if we want to reuse that code.
private boolean isDll = false;
private boolean isAslr = false;
/**
* Manager of CLI-related tables that we might need access to for PDB processing.
* @param applicator {@link PdbApplicator} for which this class is working.
@ -46,7 +53,15 @@ public class PdbCliInfoManager {
metadataStream = getCliStreamMetadata(applicator);
}
public CliAbstractTableRow getCliTableRow(int tableNum, int rowNum) throws PdbException {
boolean isDll() {
return isDll;
}
boolean isAslr() {
return isAslr;
}
CliAbstractTableRow getCliTableRow(int tableNum, int rowNum) throws PdbException {
if (metadataStream == null) {
throw new PdbException("CliStreamMetadata is null");
}
@ -63,18 +78,28 @@ public class PdbCliInfoManager {
return null;
}
ByteProvider provider = new MemoryByteProvider(program.getMemory(), program.getImageBase());
List<FileBytes> allFileBytes = program.getMemory().getAllFileBytes();
FileBytes fileBytes = allFileBytes.get(0); // Should be that of main imported file
ByteProvider provider = new FileBytesProvider(fileBytes);
PortableExecutable pe = null;
try {
GenericFactory factory = MessageLogContinuesFactory.create(applicator.getMessageLog());
pe = PortableExecutable.createPortableExecutable(factory, provider,
SectionLayout.MEMORY, true, true);
pe = PortableExecutable.createPortableExecutable(factory, provider, SectionLayout.FILE,
true, true);
NTHeader ntHeader = pe.getNTHeader();
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;
COMDescriptorDataDirectory comDir =
(COMDescriptorDataDirectory) dataDirectory[OptionalHeader.IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR];
ImageCor20Header header = comDir.getHeader();
if (header == null) {
return null;
}
return header.getMetadata().getMetadataRoot().getMetadataStream();
}
catch (Exception e) {