mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-2016 addressing code review suggestions
GP-2016_short_wide_character_format_strings
This commit is contained in:
parent
37a8ffb492
commit
c6f174dffb
2 changed files with 52 additions and 49 deletions
|
@ -99,8 +99,7 @@ public class FormatStringAnalyzer extends AbstractAnalyzer {
|
|||
return true;
|
||||
}
|
||||
|
||||
private void run(AddressSetView selection, TaskMonitor monitor)
|
||||
throws CancelledException {
|
||||
private void run(AddressSetView selection, TaskMonitor monitor) throws CancelledException {
|
||||
|
||||
DefinedDataIterator dataIterator = DefinedDataIterator.definedStrings(currentProgram);
|
||||
Map<Address, Data> stringsByAddress = new HashMap<>();
|
||||
|
@ -114,7 +113,8 @@ public class FormatStringAnalyzer extends AbstractAnalyzer {
|
|||
|
||||
FunctionIterator functionIterator = currentProgram.getListing().getFunctions(true);
|
||||
FunctionIterator externalIterator = currentProgram.getListing().getExternalFunctions();
|
||||
Iterator<Function> programFunctionIterator = IteratorUtils.chainedIterator(functionIterator,externalIterator);
|
||||
Iterator<Function> programFunctionIterator =
|
||||
IteratorUtils.chainedIterator(functionIterator, externalIterator);
|
||||
Map<String, List<DataType>> namesToParameters = new HashMap<>();
|
||||
|
||||
Map<String, DataType> namesToReturn = new HashMap<>();
|
||||
|
@ -124,22 +124,21 @@ public class FormatStringAnalyzer extends AbstractAnalyzer {
|
|||
// Find variadic function names and their parameter data types
|
||||
for (Function function : IteratorUtils.asIterable(programFunctionIterator)) {
|
||||
String name = function.getName().strip();
|
||||
if (usesVariadicFormatString(function)) {
|
||||
for (String variadicSubstring : VARIADIC_SUBSTRINGS) {
|
||||
if (name.contains(variadicSubstring)) {
|
||||
variadicFunctionNames.add(name);
|
||||
namesToParameters.put(name, getParameters(function));
|
||||
namesToReturn.put(name, function.getReturnType());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (usesVariadicFormatString(function)) {
|
||||
for (String variadicSubstring : VARIADIC_SUBSTRINGS) {
|
||||
if (name.contains(variadicSubstring)) {
|
||||
variadicFunctionNames.add(name);
|
||||
namesToParameters.put(name, getParameters(function));
|
||||
namesToReturn.put(name, function.getReturnType());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
monitor.checkCanceled();
|
||||
}
|
||||
|
||||
Iterator<Function> functionsToSearchIterator = selection != null
|
||||
? currentProgram.getFunctionManager()
|
||||
.getFunctionsOverlapping(selection)
|
||||
? currentProgram.getFunctionManager().getFunctionsOverlapping(selection)
|
||||
: currentProgram.getFunctionManager().getFunctionsNoStubs(true);
|
||||
|
||||
// Find functions that call variadic functions
|
||||
|
@ -157,14 +156,11 @@ public class FormatStringAnalyzer extends AbstractAnalyzer {
|
|||
}
|
||||
|
||||
decompile(currentProgram, monitor, stringsByAddress, variadicFunctionNames,
|
||||
namesToParameters,
|
||||
namesToReturn,
|
||||
toDecompile);
|
||||
namesToParameters, namesToReturn, toDecompile);
|
||||
}
|
||||
|
||||
private void decompile(Program program, TaskMonitor monitor,
|
||||
Map<Address, Data> stringsByAddress,
|
||||
Set<String> variadicFunctionNames,
|
||||
Map<Address, Data> stringsByAddress, Set<String> variadicFunctionNames,
|
||||
Map<String, List<DataType>> namesToParameters, Map<String, DataType> namesToReturn,
|
||||
Set<Function> toDecompile) {
|
||||
|
||||
|
@ -187,11 +183,9 @@ public class FormatStringAnalyzer extends AbstractAnalyzer {
|
|||
}
|
||||
|
||||
private DecompilerCallback<Void> initDecompilerCallback(Program program,
|
||||
Map<Address, Data> stringsByAddress,
|
||||
Set<String> variadicFuncNames, Map<String, List<DataType>> namesToParameters,
|
||||
Map<String, DataType> namesToReturn) {
|
||||
return new DecompilerCallback<>(program,
|
||||
new VariadicSignatureDecompileConfigurer()) {
|
||||
Map<Address, Data> stringsByAddress, Set<String> variadicFuncNames,
|
||||
Map<String, List<DataType>> namesToParameters, Map<String, DataType> namesToReturn) {
|
||||
return new DecompilerCallback<>(program, new VariadicSignatureDecompileConfigurer()) {
|
||||
@Override
|
||||
public Void process(DecompileResults results, TaskMonitor tMonitor) throws Exception {
|
||||
if (results == null) {
|
||||
|
@ -211,8 +205,8 @@ public class FormatStringAnalyzer extends AbstractAnalyzer {
|
|||
pcodeOpASTs.add(pcodeAST);
|
||||
}
|
||||
}
|
||||
List<FunctionCallData> functionCallDataList = pcodeParser.parseFunctionForCallData(
|
||||
pcodeOpASTs, stringsByAddress, variadicFuncNames);
|
||||
List<FunctionCallData> functionCallDataList = pcodeParser
|
||||
.parseFunctionForCallData(pcodeOpASTs, stringsByAddress, variadicFuncNames);
|
||||
if (functionCallDataList != null && functionCallDataList.size() > 0) {
|
||||
overrideCallList(program, function, functionCallDataList, namesToParameters,
|
||||
namesToReturn);
|
||||
|
@ -256,7 +250,7 @@ public class FormatStringAnalyzer extends AbstractAnalyzer {
|
|||
// DecompInterface allows for control of decompilation processes
|
||||
@Override
|
||||
public void configure(DecompInterface decompiler) {
|
||||
decompiler.toggleCCode(true); // Produce C code
|
||||
decompiler.toggleCCode(false); //only need syntax tree
|
||||
decompiler.toggleSyntaxTree(true); // Produce syntax tree
|
||||
decompiler.openProgram(currentProgram);
|
||||
decompiler.setSimplificationStyle("normalize");
|
||||
|
@ -266,8 +260,7 @@ public class FormatStringAnalyzer extends AbstractAnalyzer {
|
|||
}
|
||||
}
|
||||
|
||||
private ParameterDefinition[] parseParameters(Function function,
|
||||
Address address,
|
||||
private ParameterDefinition[] parseParameters(Function function, Address address,
|
||||
String callFunctionName, String formatString,
|
||||
Map<String, List<DataType>> namesToParameters) {
|
||||
|
||||
|
@ -347,8 +340,7 @@ public class FormatStringAnalyzer extends AbstractAnalyzer {
|
|||
|
||||
private void overrideFunctionCall(Program program, Function function, Address address,
|
||||
String callFunctionName, String formatString,
|
||||
Map<String, List<DataType>> namesToParameters,
|
||||
Map<String, DataType> namesToReturn) {
|
||||
Map<String, List<DataType>> namesToParameters, Map<String, DataType> namesToReturn) {
|
||||
if (formatString == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -361,14 +353,14 @@ public class FormatStringAnalyzer extends AbstractAnalyzer {
|
|||
try {
|
||||
if (createBookmarksEnabled) {
|
||||
BookmarkManager bookmark = program.getBookmarkManager();
|
||||
bookmark.setBookmark(address, BookmarkType.ANALYSIS,
|
||||
"Function Signature Override",
|
||||
bookmark.setBookmark(address, BookmarkType.ANALYSIS, "Function Signature Override",
|
||||
"Override for call to function " + callFunctionName);
|
||||
}
|
||||
HighFunctionDBUtil.writeOverride(function, address, functionSignature);
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
Msg.error(this, "Error: invalid input given to writeOverride()", e);
|
||||
Msg.warn(this,
|
||||
"Error applying override to " + address.toString() + ": " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,12 +19,12 @@ import java.util.*;
|
|||
|
||||
import ghidra.docking.settings.SettingsImpl;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.StringDataInstance;
|
||||
import ghidra.program.model.data.StringDataType;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.mem.MemoryBufferImpl;
|
||||
import ghidra.program.model.pcode.PcodeOpAST;
|
||||
import ghidra.program.model.pcode.Varnode;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
|
||||
/**
|
||||
* Class for parsing functions' Pcode representations and finding variadic
|
||||
|
@ -84,7 +84,7 @@ public class PcodeFunctionParser {
|
|||
boolean hasDefinedFormatString = searchForVariadicCallData(ast,
|
||||
addressToCandidateData, functionCallDataList, functionName);
|
||||
if (!hasDefinedFormatString) {
|
||||
searchForHiddenFormatStrings(ast, functionCallDataList, functionName);
|
||||
searchForHiddenFormatStrings(ast, functionCallDataList, function);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -116,20 +116,28 @@ public class PcodeFunctionParser {
|
|||
// If addrToCandidateData doesn't have format String data for this call
|
||||
// and we are calling a variadic function, parse the String to determine
|
||||
// whether it's a format String.
|
||||
private void searchForHiddenFormatStrings(PcodeOpAST ast,
|
||||
List<FunctionCallData> functionCallDataList, String functionName) {
|
||||
private void searchForHiddenFormatStrings(PcodeOpAST callOp,
|
||||
List<FunctionCallData> functionCallDataList, Function function) {
|
||||
|
||||
Varnode[] inputs = ast.getInputs();
|
||||
// Initialize i = 1 to skip first input
|
||||
Varnode[] inputs = callOp.getInputs();
|
||||
// Initialize i = 1 to skip first input, which is the call target
|
||||
for (int i = 1; i < inputs.length; ++i) {
|
||||
Varnode v = inputs[i];
|
||||
String formatStringCandidate = findFormatString(v.getAddress());
|
||||
Parameter param = function.getParameter(i - 1);
|
||||
if (param == null || param.getSource().equals(SourceType.DEFAULT)) {
|
||||
continue;
|
||||
}
|
||||
DataType type = param.getDataType();
|
||||
if ((type == null) || !(type instanceof Pointer)) {
|
||||
continue;
|
||||
}
|
||||
String formatStringCandidate = findFormatString(v.getAddress(), (Pointer) type);
|
||||
if (formatStringCandidate == null) {
|
||||
continue;
|
||||
}
|
||||
if (formatStringCandidate.contains("%")) {
|
||||
functionCallDataList.add(new FunctionCallData(ast.getSeqnum().getTarget(),
|
||||
functionName, formatStringCandidate));
|
||||
functionCallDataList.add(new FunctionCallData(callOp.getSeqnum().getTarget(),
|
||||
function.getName(), formatStringCandidate));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -145,9 +153,10 @@ public class PcodeFunctionParser {
|
|||
* Looks at bytes at given address and converts to format String
|
||||
*
|
||||
* @param address Address of format String
|
||||
* @param pointer Pointer "type" of string
|
||||
* @return format String
|
||||
*/
|
||||
private String findFormatString(Address address) {
|
||||
private String findFormatString(Address address, Pointer pointer) {
|
||||
|
||||
if (!address.getAddressSpace().isConstantSpace()) {
|
||||
return null;
|
||||
|
@ -159,9 +168,11 @@ public class PcodeFunctionParser {
|
|||
MemoryBufferImpl memoryBuffer =
|
||||
new MemoryBufferImpl(this.program.getMemory(), ramSpaceAddress);
|
||||
|
||||
StringDataInstance stringDataInstance = StringDataInstance
|
||||
.getStringDataInstance(new StringDataType(), memoryBuffer, SettingsImpl.NO_SETTINGS,
|
||||
BUFFER_LENGTH);
|
||||
DataType charType = pointer.getDataType();
|
||||
//StringDataInstace.getStringDataInstance checks that charType is appropriate
|
||||
//and returns StringDataInstace.NULL_INSTANCE if not
|
||||
StringDataInstance stringDataInstance = StringDataInstance.getStringDataInstance(charType,
|
||||
memoryBuffer, SettingsImpl.NO_SETTINGS, BUFFER_LENGTH);
|
||||
String stringValue = stringDataInstance.getStringValue();
|
||||
if (stringValue == null) {
|
||||
return null;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue