mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-02 07:48:16 +08:00
Merge remote-tracking branch 'origin/GP-899_ghizard_PDB_initial_managed_code_work--SQUASHED'
This commit is contained in:
+5
-6
@@ -255,10 +255,9 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer {
|
|||||||
|
|
||||||
PdbProgramAttributes programAttributes = new PdbProgramAttributes(program);
|
PdbProgramAttributes programAttributes = new PdbProgramAttributes(program);
|
||||||
if (programAttributes.isPdbLoaded()) {
|
if (programAttributes.isPdbLoaded()) {
|
||||||
Msg.info(this, "Skipping PDB analysis since it has previouslu run.");
|
Msg.info(this, "Skipping PDB analysis since it has previously run.");
|
||||||
Msg.info(this,
|
Msg.info(this, ">> Clear 'PDB Loaded' program property or use Load PDB action if " +
|
||||||
">> Clear 'PDB Loaded' program property or use Load PDB action if " +
|
"additional PDB processing required.");
|
||||||
"additional PDB processing required.");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,8 +360,8 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer {
|
|||||||
options.registerOption(OPTION_NAME_FORCELOAD_FILE, OptionType.FILE_TYPE,
|
options.registerOption(OPTION_NAME_FORCELOAD_FILE, OptionType.FILE_TYPE,
|
||||||
DEFAULT_FORCE_LOAD_FILE, null, OPTION_DESCRIPTION_FORCELOAD_FILE);
|
DEFAULT_FORCE_LOAD_FILE, null, OPTION_DESCRIPTION_FORCELOAD_FILE);
|
||||||
}
|
}
|
||||||
options.registerOption(OPTION_NAME_SYMBOLPATH, OptionType.FILE_TYPE,
|
options.registerOption(OPTION_NAME_SYMBOLPATH, OptionType.FILE_TYPE, symbolsRepositoryDir,
|
||||||
symbolsRepositoryDir, null, OPTION_DESCRIPTION_SYMBOLPATH);
|
null, OPTION_DESCRIPTION_SYMBOLPATH);
|
||||||
options.registerOption(OPTION_NAME_INCLUDE_PE_PDB_PATH, includePeSpecifiedPdbPath, null,
|
options.registerOption(OPTION_NAME_INCLUDE_PE_PDB_PATH, includePeSpecifiedPdbPath, null,
|
||||||
OPTION_DESCRIPTION_INCLUDE_PE_PDB_PATH);
|
OPTION_DESCRIPTION_INCLUDE_PE_PDB_PATH);
|
||||||
|
|
||||||
|
|||||||
-2
@@ -919,8 +919,6 @@ public class PdbReaderMetrics {
|
|||||||
// Not sure what to do here. What are records in this range?
|
// Not sure what to do here. What are records in this range?
|
||||||
// Worse is when it was originally a TYPE with high bit set. Why would it
|
// Worse is when it was originally a TYPE with high bit set. Why would it
|
||||||
// just not be given a non-set high bit if primitive.
|
// just not be given a non-set high bit if primitive.
|
||||||
int a = 1;
|
|
||||||
a = a + 1;
|
|
||||||
//witnessPrimitive(recordNumber.getNumber());
|
//witnessPrimitive(recordNumber.getNumber());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
+101
-1
@@ -23,7 +23,8 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.*;
|
|||||||
* Note: we do not necessarily understand each of these symbol type classes. Refer to the
|
* Note: we do not necessarily understand each of these symbol type classes. Refer to the
|
||||||
* base class for more information.
|
* base class for more information.
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractManagedProcedureMsSymbol extends AbstractMsSymbol {
|
public abstract class AbstractManagedProcedureMsSymbol extends AbstractMsSymbol
|
||||||
|
implements AddressMsSymbol, NameMsSymbol {
|
||||||
|
|
||||||
protected long parentPointer;
|
protected long parentPointer;
|
||||||
protected long endPointer;
|
protected long endPointer;
|
||||||
@@ -79,4 +80,103 @@ public abstract class AbstractManagedProcedureMsSymbol extends AbstractMsSymbol
|
|||||||
builder.append(String.format(" Return Reg: %s\n", registerContainingReturnValue));
|
builder.append(String.format(" Return Reg: %s\n", registerContainingReturnValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the parent pointer.
|
||||||
|
* @return Parent pointer.
|
||||||
|
*/
|
||||||
|
public long getParentPointer() {
|
||||||
|
return parentPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the end pointer.
|
||||||
|
* @return End pointer.
|
||||||
|
*/
|
||||||
|
public long getEndPointer() {
|
||||||
|
return endPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the next pointer.
|
||||||
|
* @return next pointer.
|
||||||
|
*/
|
||||||
|
public long getNextPointer() {
|
||||||
|
return nextPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the procedure length.
|
||||||
|
* @return Length.
|
||||||
|
*/
|
||||||
|
public long getProcedureLength() {
|
||||||
|
return procedureLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the debug start offset.
|
||||||
|
* @return Debug start offset.
|
||||||
|
*/
|
||||||
|
public long getDebugStartOffset() {
|
||||||
|
return debugStartOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the debug end offset.
|
||||||
|
* @return Debug end offset.
|
||||||
|
*/
|
||||||
|
public long getDebugEndOffset() {
|
||||||
|
return debugEndOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the offset.
|
||||||
|
* @return Offset.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long getOffset() {
|
||||||
|
return symbolOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the segment.
|
||||||
|
* @return Segment.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getSegment() {
|
||||||
|
return symbolSegment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link ProcedureFlags}.
|
||||||
|
* @return Procedure flags.
|
||||||
|
*/
|
||||||
|
public ProcedureFlags getFlags() {
|
||||||
|
return procedureFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the procedure name.
|
||||||
|
* @return Name.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the token.
|
||||||
|
* @return token.
|
||||||
|
*/
|
||||||
|
public long getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the register containing the return value
|
||||||
|
* @return the register.
|
||||||
|
*/
|
||||||
|
public RegisterName getReturnRegister() {
|
||||||
|
return registerContainingReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-1
@@ -58,10 +58,20 @@ public class BlockSymbolApplier extends MsSymbolApplier {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
void manageBlockNesting(MsSymbolApplier applierParam) {
|
void manageBlockNesting(MsSymbolApplier applierParam) {
|
||||||
|
Address address = applicator.getAddress(symbol);
|
||||||
if (applierParam instanceof FunctionSymbolApplier) {
|
if (applierParam instanceof FunctionSymbolApplier) {
|
||||||
FunctionSymbolApplier functionSymbolApplier = (FunctionSymbolApplier) applierParam;
|
FunctionSymbolApplier functionSymbolApplier = (FunctionSymbolApplier) applierParam;
|
||||||
Address address = applicator.getAddress(symbol);
|
|
||||||
functionSymbolApplier.beginBlock(address, symbol.getName(), symbol.getLength());
|
functionSymbolApplier.beginBlock(address, symbol.getName(), symbol.getLength());
|
||||||
}
|
}
|
||||||
|
else if (applierParam instanceof SeparatedCodeSymbolApplier) {
|
||||||
|
SeparatedCodeSymbolApplier separatedCodeSymbolApplier =
|
||||||
|
(SeparatedCodeSymbolApplier) applierParam;
|
||||||
|
separatedCodeSymbolApplier.beginBlock(address);
|
||||||
|
}
|
||||||
|
else if (applierParam instanceof ManagedProcedureSymbolApplier) {
|
||||||
|
ManagedProcedureSymbolApplier procedureSymbolApplier =
|
||||||
|
(ManagedProcedureSymbolApplier) applierParam;
|
||||||
|
procedureSymbolApplier.beginBlock(address, symbol.getName(), symbol.getLength());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-16
@@ -583,8 +583,7 @@ public class CppCompositeType {
|
|||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectOrientedClassLayout getLayout(
|
public ObjectOrientedClassLayout getLayout(ObjectOrientedClassLayout layoutOptions) {
|
||||||
ObjectOrientedClassLayout layoutOptions) {
|
|
||||||
if (classLayout == null) {
|
if (classLayout == null) {
|
||||||
classLayout = determineClassLayout(layoutOptions);
|
classLayout = determineClassLayout(layoutOptions);
|
||||||
}
|
}
|
||||||
@@ -644,8 +643,8 @@ public class CppCompositeType {
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------
|
||||||
//----------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------
|
||||||
public void createVbtBasedLayout(ObjectOrientedClassLayout layoutOptions,
|
public void createVbtBasedLayout(ObjectOrientedClassLayout layoutOptions, VbtManager vbtManager,
|
||||||
VbtManager vbtManager, TaskMonitor monitor) throws PdbException, CancelledException {
|
TaskMonitor monitor) throws PdbException, CancelledException {
|
||||||
CategoryPath cn;
|
CategoryPath cn;
|
||||||
hasDirect = false;
|
hasDirect = false;
|
||||||
switch (getLayout(layoutOptions)) {
|
switch (getLayout(layoutOptions)) {
|
||||||
@@ -699,8 +698,7 @@ public class CppCompositeType {
|
|||||||
}
|
}
|
||||||
directClassLength = getCompositeLength(directDataType);
|
directClassLength = getCompositeLength(directDataType);
|
||||||
}
|
}
|
||||||
if (getLayout(
|
if (getLayout(layoutOptions) == ObjectOrientedClassLayout.SIMPLE_COMPLEX) {
|
||||||
layoutOptions) == ObjectOrientedClassLayout.SIMPLE_COMPLEX) {
|
|
||||||
// Not using the dummy/direct type (only used it to get the
|
// Not using the dummy/direct type (only used it to get the
|
||||||
// directClassLength), so remove it and add the members to the main
|
// directClassLength), so remove it and add the members to the main
|
||||||
// type instead.
|
// type instead.
|
||||||
@@ -836,8 +834,7 @@ public class CppCompositeType {
|
|||||||
}
|
}
|
||||||
directClassLength = getCompositeLength(directDataType);
|
directClassLength = getCompositeLength(directDataType);
|
||||||
}
|
}
|
||||||
if (getLayout(
|
if (getLayout(layoutOptions) == ObjectOrientedClassLayout.SIMPLE_COMPLEX) {
|
||||||
layoutOptions) == ObjectOrientedClassLayout.SIMPLE_COMPLEX) {
|
|
||||||
// Not using the dummy/direct type (only used it to get the
|
// Not using the dummy/direct type (only used it to get the
|
||||||
// directClassLength), so remove it and add the members to the main
|
// directClassLength), so remove it and add the members to the main
|
||||||
// type instead.
|
// type instead.
|
||||||
@@ -947,8 +944,6 @@ public class CppCompositeType {
|
|||||||
throws PdbException {
|
throws PdbException {
|
||||||
if (placeholderVirtualBaseTables.size() > 1) {
|
if (placeholderVirtualBaseTables.size() > 1) {
|
||||||
// study this.
|
// study this.
|
||||||
int a = 1;
|
|
||||||
a = a + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean allVbtFound = true;
|
boolean allVbtFound = true;
|
||||||
@@ -957,8 +952,6 @@ public class CppCompositeType {
|
|||||||
PlaceholderVirtualBaseTable table = tableEntry.getValue();
|
PlaceholderVirtualBaseTable table = tableEntry.getValue();
|
||||||
if (!table.validateOffset()) {
|
if (!table.validateOffset()) {
|
||||||
// TODO study this.
|
// TODO study this.
|
||||||
int a = 1;
|
|
||||||
a = a + 1;
|
|
||||||
}
|
}
|
||||||
DataType vbptr = getVbptrDataType(dtm, vbtManager, table);
|
DataType vbptr = getVbptrDataType(dtm, vbtManager, table);
|
||||||
allVbtFound &=
|
allVbtFound &=
|
||||||
@@ -1352,8 +1345,7 @@ public class CppCompositeType {
|
|||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectOrientedClassLayout getLayoutMode(
|
ObjectOrientedClassLayout getLayoutMode(ObjectOrientedClassLayout layoutOptions) {
|
||||||
ObjectOrientedClassLayout layoutOptions) {
|
|
||||||
return baseClassType.getLayout(layoutOptions);
|
return baseClassType.getLayout(layoutOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1430,8 +1422,7 @@ public class CppCompositeType {
|
|||||||
|
|
||||||
Structure getLayout() {
|
Structure getLayout() {
|
||||||
if (layout == null) {
|
if (layout == null) {
|
||||||
int a = 1;
|
// consider what to do here...
|
||||||
a = a + 1;
|
|
||||||
}
|
}
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -69,5 +69,10 @@ public class EndSymbolApplier extends MsSymbolApplier {
|
|||||||
(SeparatedCodeSymbolApplier) applierParam;
|
(SeparatedCodeSymbolApplier) applierParam;
|
||||||
separatedCodeSymbolApplier.endBlock();
|
separatedCodeSymbolApplier.endBlock();
|
||||||
}
|
}
|
||||||
|
else if (applierParam instanceof ManagedProcedureSymbolApplier) {
|
||||||
|
ManagedProcedureSymbolApplier procedureSymbolApplier =
|
||||||
|
(ManagedProcedureSymbolApplier) applierParam;
|
||||||
|
procedureSymbolApplier.endBlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-4
@@ -129,8 +129,7 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
|||||||
|
|
||||||
// MsProperty property = type.getMsProperty();
|
// MsProperty property = type.getMsProperty();
|
||||||
// if (property.isForwardReference()) {
|
// if (property.isForwardReference()) {
|
||||||
// int a = 1;
|
// // investigate this
|
||||||
// a = a + 1;
|
|
||||||
// }
|
// }
|
||||||
//// RecordNumber underlyingRecordNumber = type.getUnderlyingRecordNumber();
|
//// RecordNumber underlyingRecordNumber = type.getUnderlyingRecordNumber();
|
||||||
//// underlyingApplier = applicator.getApplier(underlyingRecordNumber);
|
//// underlyingApplier = applicator.getApplier(underlyingRecordNumber);
|
||||||
@@ -227,8 +226,7 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
|||||||
// RecordNumber underlyingRecordNumber = type.getUnderlyingRecordNumber();
|
// RecordNumber underlyingRecordNumber = type.getUnderlyingRecordNumber();
|
||||||
// MsProperty property = type.getMsProperty();
|
// MsProperty property = type.getMsProperty();
|
||||||
// if (property.isForwardReference()) {
|
// if (property.isForwardReference()) {
|
||||||
// int a = 1;
|
// // investigate this
|
||||||
// a = a + 1;
|
|
||||||
// }
|
// }
|
||||||
// underlyingApplier = applicator.getApplier(underlyingRecordNumber);
|
// underlyingApplier = applicator.getApplier(underlyingRecordNumber);
|
||||||
//
|
//
|
||||||
|
|||||||
+506
File diff suppressed because it is too large
Load Diff
+23
-3
@@ -15,9 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.app.util.pdb.pdbapplicator;
|
package ghidra.app.util.pdb.pdbapplicator;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
import ghidra.app.cmd.label.SetLabelPrimaryCmd;
|
import ghidra.app.cmd.label.SetLabelPrimaryCmd;
|
||||||
import ghidra.app.util.NamespaceUtils;
|
import ghidra.app.util.NamespaceUtils;
|
||||||
@@ -26,6 +25,7 @@ import ghidra.app.util.bin.format.pdb.PdbParserConstants;
|
|||||||
import ghidra.app.util.bin.format.pdb2.pdbreader.*;
|
import ghidra.app.util.bin.format.pdb2.pdbreader.*;
|
||||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.*;
|
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.*;
|
||||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
|
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
|
||||||
|
import ghidra.app.util.bin.format.pe.cli.tables.CliAbstractTableRow;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.app.util.pdb.PdbCategories;
|
import ghidra.app.util.pdb.PdbCategories;
|
||||||
import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator;
|
import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator;
|
||||||
@@ -123,6 +123,8 @@ public class PdbApplicator {
|
|||||||
private PdbAddressManager pdbAddressManager;
|
private PdbAddressManager pdbAddressManager;
|
||||||
private List<SymbolGroup> symbolGroups;
|
private List<SymbolGroup> symbolGroups;
|
||||||
|
|
||||||
|
private PdbCliInfoManager pdbCliManagedInfoManager;
|
||||||
|
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
// If we have symbols and memory with VBTs in them, then a better VbtManager is created.
|
// If we have symbols and memory with VBTs in them, then a better VbtManager is created.
|
||||||
VbtManager vbtManager;
|
VbtManager vbtManager;
|
||||||
@@ -309,6 +311,9 @@ public class PdbApplicator {
|
|||||||
pdbApplicatorMetrics = new PdbApplicatorMetrics();
|
pdbApplicatorMetrics = new PdbApplicatorMetrics();
|
||||||
|
|
||||||
pdbAddressManager = new PdbAddressManager(this, imageBase);
|
pdbAddressManager = new PdbAddressManager(this, imageBase);
|
||||||
|
|
||||||
|
pdbCliManagedInfoManager = new PdbCliInfoManager(this);
|
||||||
|
|
||||||
symbolGroups = createSymbolGroups();
|
symbolGroups = createSymbolGroups();
|
||||||
|
|
||||||
categoryUtils = setPdbCatogoryUtils(pdbFilename);
|
categoryUtils = setPdbCatogoryUtils(pdbFilename);
|
||||||
@@ -414,6 +419,14 @@ public class PdbApplicator {
|
|||||||
log.appendMsg(message);
|
log.appendMsg(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the MessageLog.
|
||||||
|
* @return the MessageLog
|
||||||
|
*/
|
||||||
|
MessageLog getMessageLog() {
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Puts message to {@link PdbLog} and to Msg.info()
|
* Puts message to {@link PdbLog} and to Msg.info()
|
||||||
* @param originator a Logger instance, "this", or YourClass.class
|
* @param originator a Logger instance, "this", or YourClass.class
|
||||||
@@ -910,6 +923,13 @@ public class PdbApplicator {
|
|||||||
pdbAddressManager.addMemorySectionRefinement(symbol);
|
pdbAddressManager.addMemorySectionRefinement(symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==============================================================================================
|
||||||
|
// CLI-Managed infor methods.
|
||||||
|
//==============================================================================================
|
||||||
|
CliAbstractTableRow getCliTableRow(int tableNum, int rowNum) throws PdbException {
|
||||||
|
return pdbCliManagedInfoManager.getCliTableRow(tableNum, rowNum);
|
||||||
|
}
|
||||||
|
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
// Virtual-Base-Table-related methods.
|
// Virtual-Base-Table-related methods.
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
@@ -1140,7 +1160,7 @@ public class PdbApplicator {
|
|||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
appendLogMsg("Not processing linker symbols because linker module not found");
|
pdbLogAndInfoMessage(this, "Not processing linker symbols because linker module not found");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+93
@@ -0,0 +1,93 @@
|
|||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.app.util.pdb.pdbapplicator;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
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.format.pdb2.pdbreader.PdbException;
|
||||||
|
import ghidra.app.util.bin.format.pe.*;
|
||||||
|
import ghidra.app.util.bin.format.pe.PortableExecutable.SectionLayout;
|
||||||
|
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.model.listing.Program;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages CLI-Managed information, the bounds of which we do not yet know.
|
||||||
|
*/
|
||||||
|
public class PdbCliInfoManager {
|
||||||
|
|
||||||
|
private CliStreamMetadata metadataStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manager of CLI-related tables that we might need access to for PDB processing.
|
||||||
|
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||||
|
*/
|
||||||
|
PdbCliInfoManager(PdbApplicator applicator) {
|
||||||
|
Objects.requireNonNull(applicator, "applicator may not be null");
|
||||||
|
metadataStream = getCliStreamMetadata(applicator);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CliAbstractTableRow getCliTableRow(int tableNum, int rowNum) throws PdbException {
|
||||||
|
if (metadataStream == null) {
|
||||||
|
throw new PdbException("CliStreamMetadata is null");
|
||||||
|
}
|
||||||
|
CliAbstractTable table = metadataStream.getTable(tableNum);
|
||||||
|
if (table == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return table.getRow(rowNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CliStreamMetadata getCliStreamMetadata(PdbApplicator applicator) {
|
||||||
|
Program program = applicator.getProgram();
|
||||||
|
if (program == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteProvider provider = new MemoryByteProvider(program.getMemory(), program.getImageBase());
|
||||||
|
PortableExecutable pe = null;
|
||||||
|
try {
|
||||||
|
GenericFactory factory = MessageLogContinuesFactory.create(applicator.getMessageLog());
|
||||||
|
pe = PortableExecutable.createPortableExecutable(factory, provider,
|
||||||
|
SectionLayout.MEMORY, true, true);
|
||||||
|
NTHeader ntHeader = pe.getNTHeader();
|
||||||
|
OptionalHeader optionalHeader = ntHeader.getOptionalHeader();
|
||||||
|
DataDirectory[] dataDirectory = optionalHeader.getDataDirectories();
|
||||||
|
COMDescriptorDataDirectory comDir =
|
||||||
|
(COMDescriptorDataDirectory) dataDirectory[OptionalHeader.IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR];
|
||||||
|
ImageCor20Header header = comDir.getHeader();
|
||||||
|
return header.getMetadata().getMetadataRoot().getMetadataStream();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
applicator.pdbLogAndInfoMessage(this, "Unable to retrieve CliStreamMetadata");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
provider.close();
|
||||||
|
}
|
||||||
|
catch (IOException ioe) {
|
||||||
|
applicator.pdbLogAndInfoMessage(this, "Problem closing ByteProvider");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
-30
@@ -44,10 +44,16 @@ public class PdbResearch {
|
|||||||
private static Set<Integer> developerDebugOrderIndexNumbers;
|
private static Set<Integer> developerDebugOrderIndexNumbers;
|
||||||
|
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
|
// This method exists so we can place breakpoints on call locations to it wherever we
|
||||||
|
// would like to break during debugging.
|
||||||
|
private static void doNothingSetBreakPointHere() {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is used to populate debugIndexNumbers set that gets used by
|
* This method is used to populate debugIndexNumbers set that gets used by
|
||||||
* {@link #checkBreak(int recordNumber)} in which we set a breakpoint on {@code int a = 1;} to
|
* {@link #checkBreak(int recordNumber)} in which we set a breakpoint on
|
||||||
* then allow us to debug into other code.
|
* {@code #doNothingSetBreakPointHere();} to then allow us to debug into other code.
|
||||||
*/
|
*/
|
||||||
static void initBreakPointRecordNumbers() {
|
static void initBreakPointRecordNumbers() {
|
||||||
debugIndexNumbers = new TreeSet<>();
|
debugIndexNumbers = new TreeSet<>();
|
||||||
@@ -304,8 +310,8 @@ public class PdbResearch {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Developmental method for breakpoints. TODO: will delete this from production.
|
* Developmental method for breakpoints. TODO: will delete this from production.
|
||||||
* Set breakpoint on {@code int a = 1;}
|
* Set breakpoint on {@code #doNothingSetBreakPointHere();}
|
||||||
* @param recordNumber the record number tha is being processed (set negative to ignore)
|
* @param recordNumber the record number that is being processed (set negative to ignore)
|
||||||
* <p>
|
* <p>
|
||||||
* This code is useful for developer debugging because the PDB is records-based and we often
|
* This code is useful for developer debugging because the PDB is records-based and we often
|
||||||
* need to set breakpoints elsewhere, determine what RecordNumber we are interested in, and
|
* need to set breakpoints elsewhere, determine what RecordNumber we are interested in, and
|
||||||
@@ -315,8 +321,7 @@ public class PdbResearch {
|
|||||||
*/
|
*/
|
||||||
static void checkBreak(int recordNumber) {
|
static void checkBreak(int recordNumber) {
|
||||||
if (debugIndexNumbers.contains(recordNumber)) {
|
if (debugIndexNumbers.contains(recordNumber)) {
|
||||||
int a = 1;
|
doNothingSetBreakPointHere();
|
||||||
a = a + 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,16 +336,13 @@ public class PdbResearch {
|
|||||||
String nn = applier.getMsType().getName();
|
String nn = applier.getMsType().getName();
|
||||||
if ("std::__1::__map_value_compare<std::__1::basic_string<char>,std::__1::__value_type<std::__1::basic_string<char>,std::__1::basic_string<wchar_t> >,std::__1::less<void>,1>".equals(
|
if ("std::__1::__map_value_compare<std::__1::basic_string<char>,std::__1::__value_type<std::__1::basic_string<char>,std::__1::basic_string<wchar_t> >,std::__1::less<void>,1>".equals(
|
||||||
nn)) {
|
nn)) {
|
||||||
int a = 1;
|
doNothingSetBreakPointHere();
|
||||||
a = a + 1;
|
|
||||||
}
|
}
|
||||||
if ("class std::__1::__iostream_category".equals(nn)) {
|
if ("class std::__1::__iostream_category".equals(nn)) {
|
||||||
int a = 1;
|
doNothingSetBreakPointHere();
|
||||||
a = a + 1;
|
|
||||||
}
|
}
|
||||||
if ("std::__1::__do_message".equals(nn)) {
|
if ("std::__1::__do_message".equals(nn)) {
|
||||||
int a = 1;
|
doNothingSetBreakPointHere();
|
||||||
a = a + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//checkBreak(recordNumber);
|
//checkBreak(recordNumber);
|
||||||
@@ -445,9 +447,10 @@ public class PdbResearch {
|
|||||||
}
|
}
|
||||||
else if (applier instanceof ReferenceSymbolApplier) {
|
else if (applier instanceof ReferenceSymbolApplier) {
|
||||||
ReferenceSymbolApplier refSymbolApplier = (ReferenceSymbolApplier) applier;
|
ReferenceSymbolApplier refSymbolApplier = (ReferenceSymbolApplier) applier;
|
||||||
SymbolGroup refSymbolGroup = refSymbolApplier.getInitializedReferencedSymbolGroup();
|
AbstractMsSymbolIterator refIter =
|
||||||
|
refSymbolApplier.getInitializedReferencedSymbolGroupIterator();
|
||||||
// recursion
|
// recursion
|
||||||
childWalkSym(applicator, refSymbolGroup.getModuleNumber(), refSymbolGroup.iterator());
|
childWalkSym(applicator, refIter.getModuleNumber(), refIter);
|
||||||
}
|
}
|
||||||
else if (applier instanceof DataSymbolApplier) {
|
else if (applier instanceof DataSymbolApplier) {
|
||||||
DataSymbolApplier dataSymbolApplier = (DataSymbolApplier) applier;
|
DataSymbolApplier dataSymbolApplier = (DataSymbolApplier) applier;
|
||||||
@@ -464,19 +467,16 @@ public class PdbResearch {
|
|||||||
// ConstantSymbolApplier constantSymbolApplier = (ConstantSymbolApplier) applier;
|
// ConstantSymbolApplier constantSymbolApplier = (ConstantSymbolApplier) applier;
|
||||||
// }
|
// }
|
||||||
else {
|
else {
|
||||||
int a = 1;
|
doNothingSetBreakPointHere();
|
||||||
a = a + 1;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
static private boolean childWalkType(int moduleNumber, MsTypeApplier applier) {
|
static private boolean childWalkType(int moduleNumber, MsTypeApplier applier) {
|
||||||
int b = 1;
|
doNothingSetBreakPointHere();
|
||||||
b = b + 1;
|
|
||||||
if (applier instanceof AbstractFunctionTypeApplier) {
|
if (applier instanceof AbstractFunctionTypeApplier) {
|
||||||
int a = 1;
|
doNothingSetBreakPointHere();
|
||||||
a = a + 1;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -861,21 +861,18 @@ public class PdbResearch {
|
|||||||
p = compType.getMsProperty();
|
p = compType.getMsProperty();
|
||||||
isForwardReference = p.isForwardReference();
|
isForwardReference = p.isForwardReference();
|
||||||
if (c == 0 && !isForwardReference) {
|
if (c == 0 && !isForwardReference) {
|
||||||
int a = 1;
|
doNothingSetBreakPointHere();
|
||||||
a = a + 1;
|
|
||||||
// For PDBs that we have looked at, if count is zero
|
// For PDBs that we have looked at, if count is zero
|
||||||
// for a forward reference, then the field list record number is zero;
|
// for a forward reference, then the field list record number is zero;
|
||||||
// if count is zero for a definition, then, the field list record
|
// if count is zero for a definition, then, the field list record
|
||||||
// number refers to an actual field list.
|
// number refers to an actual field list.
|
||||||
// So... seems we can trust forward reference and ignore count.
|
// So... seems we can trust forward reference and ignore count.
|
||||||
if (compType.getFieldDescriptorListRecordNumber() == RecordNumber.NO_TYPE) {
|
if (compType.getFieldDescriptorListRecordNumber() == RecordNumber.NO_TYPE) {
|
||||||
int b = 1;
|
doNothingSetBreakPointHere();
|
||||||
b = b + 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (c != 0 && isForwardReference) {
|
else if (c != 0 && isForwardReference) {
|
||||||
int a = 1;
|
doNothingSetBreakPointHere();
|
||||||
a = a + 1;
|
|
||||||
}
|
}
|
||||||
// ps = c + (p.isForwardReference() ? "fwdref" : "");
|
// ps = c + (p.isForwardReference() ? "fwdref" : "");
|
||||||
}
|
}
|
||||||
@@ -916,13 +913,11 @@ public class PdbResearch {
|
|||||||
// list. So... seems we can trust forward reference and
|
// list. So... seems we can trust forward reference and
|
||||||
// ignore count.
|
// ignore count.
|
||||||
if (compType.getFieldDescriptorListRecordNumber() == RecordNumber.NO_TYPE) {
|
if (compType.getFieldDescriptorListRecordNumber() == RecordNumber.NO_TYPE) {
|
||||||
int a = 1;
|
doNothingSetBreakPointHere();
|
||||||
a = a + 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (c != 0 && isForwardReference) {
|
else if (c != 0 && isForwardReference) {
|
||||||
int a = 1;
|
doNothingSetBreakPointHere();
|
||||||
a = a + 1;
|
|
||||||
}
|
}
|
||||||
// ps = c + (p.isForwardReference() ? "fwdref" : "");
|
// ps = c + (p.isForwardReference() ? "fwdref" : "");
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -135,8 +135,7 @@ public class PdbVbtManager extends VbtManager {
|
|||||||
vbtByAddress.put(address, vbt);
|
vbtByAddress.put(address, vbt);
|
||||||
}
|
}
|
||||||
if (!(vbt instanceof PdbVirtualBaseTable)) {
|
if (!(vbt instanceof PdbVirtualBaseTable)) {
|
||||||
int a = 1;
|
// investigate this
|
||||||
a = a + 1;
|
|
||||||
}
|
}
|
||||||
return (PdbVirtualBaseTable) vbt;
|
return (PdbVirtualBaseTable) vbt;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -52,15 +52,15 @@ public class ReferenceSymbolApplier extends MsSymbolApplier {
|
|||||||
@Override
|
@Override
|
||||||
void apply() throws CancelledException, PdbException {
|
void apply() throws CancelledException, PdbException {
|
||||||
// Potential recursive call via applicator.procSym().
|
// Potential recursive call via applicator.procSym().
|
||||||
AbstractMsSymbolIterator refIter = getInitializedReferencedSymbolGroup().iterator();
|
AbstractMsSymbolIterator refIter = getInitializedReferencedSymbolGroupIterator();
|
||||||
applicator.procSym(refIter);
|
applicator.procSym(refIter);
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolGroup getInitializedReferencedSymbolGroup() {
|
AbstractMsSymbolIterator getInitializedReferencedSymbolGroupIterator() {
|
||||||
SymbolGroup refSymbolGroup = getReferencedSymbolGroup();
|
SymbolGroup refSymbolGroup = getReferencedSymbolGroup();
|
||||||
AbstractMsSymbolIterator refIter = refSymbolGroup.iterator();
|
AbstractMsSymbolIterator refIter = refSymbolGroup.iterator();
|
||||||
refIter.initGetByOffset(getOffsetInReferencedSymbolGroup());
|
refIter.initGetByOffset(getOffsetInReferencedSymbolGroup());
|
||||||
return refSymbolGroup;
|
return refIter;
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolGroup getReferencedSymbolGroup() {
|
SymbolGroup getReferencedSymbolGroup() {
|
||||||
|
|||||||
+2
-4
@@ -129,17 +129,15 @@ public class SeparatedCodeSymbolApplier extends MsSymbolApplier {
|
|||||||
return (symbolBlockNestingLevel > 0) && iter.hasNext();
|
return (symbolBlockNestingLevel > 0) && iter.hasNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
int endBlock() {
|
void endBlock() {
|
||||||
if (--symbolBlockNestingLevel < 0) {
|
if (--symbolBlockNestingLevel < 0) {
|
||||||
applicator.appendLogMsg("Block Nesting went negative at " + specifiedAddress);
|
applicator.appendLogMsg("Block Nesting went negative at " + specifiedAddress);
|
||||||
}
|
}
|
||||||
return symbolBlockNestingLevel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int beginBlock(Address startAddress) {
|
void beginBlock(Address startAddress) {
|
||||||
currentBlockAddress = startAddress;
|
currentBlockAddress = startAddress;
|
||||||
++symbolBlockNestingLevel;
|
++symbolBlockNestingLevel;
|
||||||
return symbolBlockNestingLevel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-12
@@ -282,12 +282,12 @@ public class SymbolApplierFactory {
|
|||||||
// case AnnotationMsSymbol.PDB_ID:
|
// case AnnotationMsSymbol.PDB_ID:
|
||||||
// symbol = new AnnotationMsSymbol(pdb, reader);
|
// symbol = new AnnotationMsSymbol(pdb, reader);
|
||||||
// break;
|
// break;
|
||||||
// case GlobalManagedProcedureStMsSymbol.PDB_ID:
|
case GlobalManagedProcedureStMsSymbol.PDB_ID:
|
||||||
// symbol = new GlobalManagedProcedureStMsSymbol(pdb, reader);
|
applier = new ManagedProcedureSymbolApplier(applicator, iter);
|
||||||
// break;
|
break;
|
||||||
// case LocalManagedProcedureStMsSymbol.PDB_ID:
|
case LocalManagedProcedureStMsSymbol.PDB_ID:
|
||||||
// symbol = new LocalManagedProcedureStMsSymbol(pdb, reader);
|
applier = new ManagedProcedureSymbolApplier(applicator, iter);
|
||||||
// break;
|
break;
|
||||||
// case Reserved1MsSymbol.PDB_ID:
|
// case Reserved1MsSymbol.PDB_ID:
|
||||||
// symbol = new Reserved1MsSymbol(pdb, reader);
|
// symbol = new Reserved1MsSymbol(pdb, reader);
|
||||||
// break;
|
// break;
|
||||||
@@ -455,12 +455,12 @@ public class SymbolApplierFactory {
|
|||||||
case TokenReferenceToManagedProcedureMsSymbol.PDB_ID:
|
case TokenReferenceToManagedProcedureMsSymbol.PDB_ID:
|
||||||
applier = new ReferenceSymbolApplier(applicator, iter);
|
applier = new ReferenceSymbolApplier(applicator, iter);
|
||||||
break;
|
break;
|
||||||
// case GlobalManagedProcedureMsSymbol.PDB_ID:
|
case GlobalManagedProcedureMsSymbol.PDB_ID:
|
||||||
// symbol = new GlobalManagedProcedureMsSymbol(pdb, reader);
|
applier = new ManagedProcedureSymbolApplier(applicator, iter);
|
||||||
// break;
|
break;
|
||||||
// case LocalManagedProcedureMsSymbol.PDB_ID:
|
case LocalManagedProcedureMsSymbol.PDB_ID:
|
||||||
// symbol = new LocalManagedProcedureMsSymbol(pdb, reader);
|
applier = new ManagedProcedureSymbolApplier(applicator, iter);
|
||||||
// break;
|
break;
|
||||||
case TrampolineMsSymbol.PDB_ID:
|
case TrampolineMsSymbol.PDB_ID:
|
||||||
applier = new TrampolineSymbolApplier(applicator, iter);
|
applier = new TrampolineSymbolApplier(applicator, iter);
|
||||||
break;
|
break;
|
||||||
|
|||||||
+10
-10
@@ -150,17 +150,17 @@ public class SymbolGroup {
|
|||||||
*/
|
*/
|
||||||
class AbstractMsSymbolIterator implements Iterator<AbstractMsSymbol> {
|
class AbstractMsSymbolIterator implements Iterator<AbstractMsSymbol> {
|
||||||
|
|
||||||
private int currentIndex;
|
private int nextIndex;
|
||||||
private long currentOffset;
|
private long currentOffset;
|
||||||
|
|
||||||
public AbstractMsSymbolIterator() {
|
public AbstractMsSymbolIterator() {
|
||||||
currentIndex = 0;
|
nextIndex = 0;
|
||||||
currentOffset = 0L;
|
currentOffset = -1L;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
if (currentIndex == offsets.size()) {
|
if (nextIndex == offsets.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -175,10 +175,10 @@ public class SymbolGroup {
|
|||||||
* @throws NoSuchElementException if there are no more elements
|
* @throws NoSuchElementException if there are no more elements
|
||||||
*/
|
*/
|
||||||
public AbstractMsSymbol peek() throws NoSuchElementException {
|
public AbstractMsSymbol peek() throws NoSuchElementException {
|
||||||
if (currentIndex == offsets.size()) {
|
if (nextIndex == offsets.size()) {
|
||||||
throw new NoSuchElementException("none left");
|
throw new NoSuchElementException("none left");
|
||||||
}
|
}
|
||||||
long temporaryOffset = offsets.get(currentIndex);
|
long temporaryOffset = offsets.get(nextIndex);
|
||||||
AbstractMsSymbol symbol = symbolsByOffset.get(temporaryOffset);
|
AbstractMsSymbol symbol = symbolsByOffset.get(temporaryOffset);
|
||||||
if (symbol == null) {
|
if (symbol == null) {
|
||||||
throw new NoSuchElementException("No symbol");
|
throw new NoSuchElementException("No symbol");
|
||||||
@@ -188,10 +188,10 @@ public class SymbolGroup {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractMsSymbol next() {
|
public AbstractMsSymbol next() {
|
||||||
if (currentIndex == offsets.size()) {
|
if (nextIndex == offsets.size()) {
|
||||||
throw new NoSuchElementException("none left");
|
throw new NoSuchElementException("none left");
|
||||||
}
|
}
|
||||||
currentOffset = offsets.get(currentIndex++);
|
currentOffset = offsets.get(nextIndex++);
|
||||||
return symbolsByOffset.get(currentOffset);
|
return symbolsByOffset.get(currentOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +211,7 @@ public class SymbolGroup {
|
|||||||
* @see #hasNext()
|
* @see #hasNext()
|
||||||
*/
|
*/
|
||||||
void initGet() {
|
void initGet() {
|
||||||
currentIndex = 0;
|
nextIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -224,7 +224,7 @@ public class SymbolGroup {
|
|||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
currentIndex = index;
|
nextIndex = index;
|
||||||
currentOffset = offset;
|
currentOffset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user