mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-27 14:31:29 +08:00
GP-714: Adding PeLoader option to show/hide debug line numbers
This commit is contained in:
+60
-8
@@ -17,12 +17,15 @@ package ghidra.app.util.opinion;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import ghidra.app.util.Option;
|
||||||
|
import ghidra.app.util.bin.ByteProvider;
|
||||||
import ghidra.app.util.bin.format.pdb.PdbInfoCodeView;
|
import ghidra.app.util.bin.format.pdb.PdbInfoCodeView;
|
||||||
import ghidra.app.util.bin.format.pdb.PdbInfoDotNet;
|
import ghidra.app.util.bin.format.pdb.PdbInfoDotNet;
|
||||||
import ghidra.app.util.bin.format.pe.*;
|
import ghidra.app.util.bin.format.pe.*;
|
||||||
import ghidra.app.util.bin.format.pe.debug.*;
|
import ghidra.app.util.bin.format.pe.debug.*;
|
||||||
import ghidra.app.util.demangler.DemangledObject;
|
import ghidra.app.util.demangler.DemangledObject;
|
||||||
import ghidra.app.util.demangler.DemanglerUtil;
|
import ghidra.app.util.demangler.DemanglerUtil;
|
||||||
|
import ghidra.framework.model.DomainObject;
|
||||||
import ghidra.framework.options.Options;
|
import ghidra.framework.options.Options;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.data.DWordDataType;
|
import ghidra.program.model.data.DWordDataType;
|
||||||
@@ -36,11 +39,54 @@ import ghidra.util.exception.InvalidInputException;
|
|||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
abstract class AbstractPeDebugLoader extends AbstractOrdinalSupportLoader {
|
abstract class AbstractPeDebugLoader extends AbstractOrdinalSupportLoader {
|
||||||
|
|
||||||
|
/** Loader option to display line numbers */
|
||||||
|
public static final String SHOW_LINE_NUMBERS_OPTION_NAME = "Show Debug Line Number Comments";
|
||||||
|
static final boolean SHOW_LINE_NUMBERS_OPTION_DEFAULT = false;
|
||||||
|
|
||||||
private HashMap<Address, StringBuffer> plateCommentMap = new HashMap<>();
|
private HashMap<Address, StringBuffer> plateCommentMap = new HashMap<>();
|
||||||
private HashMap<Address, StringBuffer> preCommentMap = new HashMap<>();
|
private HashMap<Address, StringBuffer> preCommentMap = new HashMap<>();
|
||||||
private HashMap<Address, StringBuffer> postCommentMap = new HashMap<>();
|
private HashMap<Address, StringBuffer> postCommentMap = new HashMap<>();
|
||||||
private HashMap<Address, StringBuffer> eolCommentMap = new HashMap<>();
|
private HashMap<Address, StringBuffer> eolCommentMap = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Option> getDefaultOptions(ByteProvider provider, LoadSpec loadSpec,
|
||||||
|
DomainObject domainObject, boolean loadIntoProgram) {
|
||||||
|
List<Option> list =
|
||||||
|
super.getDefaultOptions(provider, loadSpec, domainObject, loadIntoProgram);
|
||||||
|
list.add(new Option(SHOW_LINE_NUMBERS_OPTION_NAME, SHOW_LINE_NUMBERS_OPTION_DEFAULT,
|
||||||
|
Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-showDebugLineNumbers"));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String validateOptions(ByteProvider provider, LoadSpec loadSpec, List<Option> options,
|
||||||
|
Program program) {
|
||||||
|
if (options != null) {
|
||||||
|
for (Option option : options) {
|
||||||
|
String name = option.getName();
|
||||||
|
if (name.equals(SHOW_LINE_NUMBERS_OPTION_NAME)) {
|
||||||
|
if (!Boolean.class.isAssignableFrom(option.getValueClass())) {
|
||||||
|
return "Invalid type for option: " + name + " - " + option.getValueClass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.validateOptions(provider, loadSpec, options, program);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldShowDebugLineNumbers(List<Option> options) {
|
||||||
|
if (options != null) {
|
||||||
|
for (Option option : options) {
|
||||||
|
String optName = option.getName();
|
||||||
|
if (optName.equals(SHOW_LINE_NUMBERS_OPTION_NAME)) {
|
||||||
|
return (Boolean) option.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SHOW_LINE_NUMBERS_OPTION_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
protected void processComments(Listing listing, TaskMonitor monitor) {
|
protected void processComments(Listing listing, TaskMonitor monitor) {
|
||||||
List<HashMap<Address, StringBuffer>> maps = new ArrayList<>();
|
List<HashMap<Address, StringBuffer>> maps = new ArrayList<>();
|
||||||
maps.add(plateCommentMap);
|
maps.add(plateCommentMap);
|
||||||
@@ -81,7 +127,8 @@ abstract class AbstractPeDebugLoader extends AbstractOrdinalSupportLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void processDebug(DebugDirectoryParser parser, NTHeader ntHeader,
|
protected void processDebug(DebugDirectoryParser parser, NTHeader ntHeader,
|
||||||
Map<SectionHeader, Address> sectionToAddress, Program program, TaskMonitor monitor) {
|
Map<SectionHeader, Address> sectionToAddress, Program program, List<Option> options,
|
||||||
|
TaskMonitor monitor) {
|
||||||
|
|
||||||
if (parser == null) {
|
if (parser == null) {
|
||||||
return;
|
return;
|
||||||
@@ -95,15 +142,16 @@ abstract class AbstractPeDebugLoader extends AbstractOrdinalSupportLoader {
|
|||||||
|
|
||||||
monitor.setMessage("Processing code view debug...");
|
monitor.setMessage("Processing code view debug...");
|
||||||
processDebugCodeView(parser.getDebugCodeView(), ntHeader, sectionToAddress, program,
|
processDebugCodeView(parser.getDebugCodeView(), ntHeader, sectionToAddress, program,
|
||||||
monitor);
|
options, monitor);
|
||||||
|
|
||||||
monitor.setMessage("Processing coff debug...");
|
monitor.setMessage("Processing coff debug...");
|
||||||
processDebugCOFF(parser.getDebugCOFFSymbolsHeader(), ntHeader, sectionToAddress, program,
|
processDebugCOFF(parser.getDebugCOFFSymbolsHeader(), ntHeader, sectionToAddress, program,
|
||||||
monitor);
|
options, monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processDebugCodeView(DebugCodeView dcv, NTHeader ntHeader,
|
private void processDebugCodeView(DebugCodeView dcv, NTHeader ntHeader,
|
||||||
Map<SectionHeader, Address> sectionToAddress, Program program, TaskMonitor monitor) {
|
Map<SectionHeader, Address> sectionToAddress, Program program, List<Option> options,
|
||||||
|
TaskMonitor monitor) {
|
||||||
|
|
||||||
if (dcv == null) {
|
if (dcv == null) {
|
||||||
return;
|
return;
|
||||||
@@ -136,7 +184,7 @@ abstract class AbstractPeDebugLoader extends AbstractOrdinalSupportLoader {
|
|||||||
for (OMFSrcModuleFile file : files) {
|
for (OMFSrcModuleFile file : files) {
|
||||||
processFiles(file, segs[segIndex++], fileHeader, sectionToAddress, monitor);
|
processFiles(file, segs[segIndex++], fileHeader, sectionToAddress, monitor);
|
||||||
processLineNumbers(fileHeader, sectionToAddress, file.getOMFSrcModuleLines(),
|
processLineNumbers(fileHeader, sectionToAddress, file.getOMFSrcModuleLines(),
|
||||||
monitor);
|
options, monitor);
|
||||||
|
|
||||||
if (monitor.isCancelled()) {
|
if (monitor.isCancelled()) {
|
||||||
return;
|
return;
|
||||||
@@ -258,7 +306,10 @@ abstract class AbstractPeDebugLoader extends AbstractOrdinalSupportLoader {
|
|||||||
|
|
||||||
private void processLineNumbers(FileHeader fileHeader,
|
private void processLineNumbers(FileHeader fileHeader,
|
||||||
Map<SectionHeader, Address> sectionToAddress, OMFSrcModuleLine[] lines,
|
Map<SectionHeader, Address> sectionToAddress, OMFSrcModuleLine[] lines,
|
||||||
TaskMonitor monitor) {//TODO revisit this method for accuracy
|
List<Option> options, TaskMonitor monitor) {//TODO revisit this method for accuracy
|
||||||
|
if (!shouldShowDebugLineNumbers(options)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (OMFSrcModuleLine line : lines) {
|
for (OMFSrcModuleLine line : lines) {
|
||||||
if (monitor.isCancelled()) {
|
if (monitor.isCancelled()) {
|
||||||
return;
|
return;
|
||||||
@@ -288,7 +339,8 @@ abstract class AbstractPeDebugLoader extends AbstractOrdinalSupportLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void processDebugCOFF(DebugCOFFSymbolsHeader dcsh, NTHeader ntHeader,
|
private void processDebugCOFF(DebugCOFFSymbolsHeader dcsh, NTHeader ntHeader,
|
||||||
Map<SectionHeader, Address> sectionToAddress, Program program, TaskMonitor monitor) {
|
Map<SectionHeader, Address> sectionToAddress, Program program, List<Option> options,
|
||||||
|
TaskMonitor monitor) {
|
||||||
if (dcsh == null) {
|
if (dcsh == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -313,7 +365,7 @@ abstract class AbstractPeDebugLoader extends AbstractOrdinalSupportLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DebugCOFFLineNumber[] lineNumbers = dcsh.getLineNumbers();
|
DebugCOFFLineNumber[] lineNumbers = dcsh.getLineNumbers();
|
||||||
if (lineNumbers != null) {
|
if (shouldShowDebugLineNumbers(options) && lineNumbers != null) {
|
||||||
for (DebugCOFFLineNumber lineNumber : lineNumbers) {
|
for (DebugCOFFLineNumber lineNumber : lineNumbers) {
|
||||||
if (monitor.isCancelled()) {
|
if (monitor.isCancelled()) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public class DbgLoader extends AbstractPeDebugLoader {
|
|||||||
sectionToAddress.put(sectionHeader,
|
sectionToAddress.put(sectionHeader,
|
||||||
imageBase.add(sectionHeader.getVirtualAddress()));
|
imageBase.add(sectionHeader.getVirtualAddress()));
|
||||||
}
|
}
|
||||||
processDebug(debug.getParser(), parentPE.getNTHeader(), sectionToAddress, prog,
|
processDebug(debug.getParser(), parentPE.getNTHeader(), sectionToAddress, prog, options,
|
||||||
monitor);
|
monitor);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ public class PeLoader extends AbstractPeDebugLoader {
|
|||||||
processImports(optionalHeader, program, monitor, log);
|
processImports(optionalHeader, program, monitor, log);
|
||||||
processDelayImports(optionalHeader, program, monitor, log);
|
processDelayImports(optionalHeader, program, monitor, log);
|
||||||
processRelocations(optionalHeader, program, monitor, log);
|
processRelocations(optionalHeader, program, monitor, log);
|
||||||
processDebug(optionalHeader, ntHeader, sectionToAddress, program, monitor);
|
processDebug(optionalHeader, ntHeader, sectionToAddress, program, options, monitor);
|
||||||
processProperties(optionalHeader, program, monitor);
|
processProperties(optionalHeader, program, monitor);
|
||||||
processComments(program.getListing(), monitor);
|
processComments(program.getListing(), monitor);
|
||||||
processSymbols(ntHeader, sectionToAddress, program, monitor, log);
|
processSymbols(ntHeader, sectionToAddress, program, monitor, log);
|
||||||
@@ -818,7 +818,8 @@ public class PeLoader extends AbstractPeDebugLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void processDebug(OptionalHeader optionalHeader, NTHeader ntHeader,
|
private void processDebug(OptionalHeader optionalHeader, NTHeader ntHeader,
|
||||||
Map<SectionHeader, Address> sectionToAddress, Program program, TaskMonitor monitor) {
|
Map<SectionHeader, Address> sectionToAddress, Program program, List<Option> options,
|
||||||
|
TaskMonitor monitor) {
|
||||||
if (monitor.isCancelled()) {
|
if (monitor.isCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -840,7 +841,7 @@ public class PeLoader extends AbstractPeDebugLoader {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
processDebug(parser, ntHeader, sectionToAddress, program, monitor);
|
processDebug(parser, ntHeader, sectionToAddress, program, options, monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -612,7 +612,8 @@ The Headless Analyzer uses the command-line parameters discussed below. See <a h
|
|||||||
<LI><typewriter>-loader-libraryLoadDepth <depth></typewriter></LI>
|
<LI><typewriter>-loader-libraryLoadDepth <depth></typewriter></LI>
|
||||||
<LI><typewriter>-loader-libraryDestinationFolder <project path></typewriter></LI>
|
<LI><typewriter>-loader-libraryDestinationFolder <project path></typewriter></LI>
|
||||||
<LI><typewriter>-loader-ordinalLookup <true|false></typewriter></LI>
|
<LI><typewriter>-loader-ordinalLookup <true|false></typewriter></LI>
|
||||||
<LI><typewriter>-loader-parseCliHeaders <true|false></typewriter></LI>
|
<LI><typewriter>-loader-parseCliHeaders <true|false></typewriter></LI>
|
||||||
|
<LI><typewriter>-loader-showDebugLineNumbers <true|false></typewriter></LI>
|
||||||
</UL>
|
</UL>
|
||||||
<LI><typewriter>-loader MachoLoader<typewriter></LI>
|
<LI><typewriter>-loader MachoLoader<typewriter></LI>
|
||||||
<UL>
|
<UL>
|
||||||
|
|||||||
Reference in New Issue
Block a user