wxhelper/script/ghidra_script/FindMarsScript.java
2024-09-05 22:15:37 +08:00

387 lines
14 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// find mars
//@author ttttupup
//@category _NEW_
//@keybinding
//@menupath
//@toolbar
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import docking.widgets.filter.ContainsTextFilterFactory;
import docking.widgets.filter.TextFilter;
import ghidra.app.decompiler.DecompInterface;
import ghidra.app.decompiler.DecompileOptions;
import ghidra.app.decompiler.DecompileResults;
import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressFactory;
import ghidra.program.model.address.AddressIterator;
import ghidra.program.model.address.AddressSet;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.block.BasicBlockModel;
import ghidra.program.model.block.CodeBlock;
import ghidra.program.model.listing.CodeUnit;
import ghidra.program.model.listing.Data;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.FunctionManager;
import ghidra.program.model.listing.Instruction;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.pcode.HighFunction;
import ghidra.program.model.pcode.PcodeBlockBasic;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.program.model.pcode.PcodeOpAST;
import ghidra.program.model.pcode.Varnode;
import ghidra.program.model.symbol.Reference;
import ghidra.program.model.symbol.ReferenceIterator;
import ghidra.program.model.symbol.ReferenceManager;
import ghidra.program.model.symbol.SourceType;
import ghidra.program.util.string.FoundString;
import ghidra.sleigh.grammar.SleighParser.stringorident_return;
import ghidra.util.StringUtilities;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.InvalidInputException;
public class FindMarsScript extends GhidraScript {
DecompInterface decompiler = new DecompInterface();
BasicBlockModel basicBlockModel;
@Override
protected void run() throws Exception {
DecompileOptions decompileOptions = new DecompileOptions();
decompiler.setOptions(decompileOptions);
decompiler.openProgram(currentProgram);
basicBlockModel = new BasicBlockModel(currentProgram);
Address findXScopeTracer = findXScopeTracer();
// Address findXScopeTracer = currentProgram.getAddressFactory().getAddress("0x183d04d10");
if (null != findXScopeTracer) {
ReferenceIterator referenceIterator = currentProgram.getReferenceManager()
.getReferencesTo(findXScopeTracer);
while (referenceIterator.hasNext()) {
monitor.checkCancelled();
Reference next = referenceIterator.next();
Address fromAddress = next.getFromAddress();
Function functionContaining = currentProgram.getFunctionManager().getFunctionContaining(fromAddress);
if (null == functionContaining) {
println("no found function: " + fromAddress.toString());
continue;
}
DecompileResults res = decompiler.decompileFunction(functionContaining, 20, null);
if (!res.decompileCompleted()) {
println("decompile error: " + res.getErrorMessage());
continue;
}
HighFunction highFunction = res.getHighFunction();
Iterator<PcodeOpAST> pcodeOps = highFunction.getPcodeOps();
while (pcodeOps.hasNext()) {
monitor.checkCancelled();
PcodeOpAST opAST = pcodeOps.next();
int opcode = opAST.getOpcode();
if (PcodeOp.CALL == opcode || PcodeOp.CALLIND == opcode || PcodeOp.CALLOTHER == opcode) {
Varnode input0 = opAST.getInput(0);
boolean contains = input0.contains(findXScopeTracer);
if (contains) {
Varnode input3 = opAST.getInput(3);
Varnode input4 = opAST.getInput(4);
if (input4 == null || input3 == null) {
continue;
}
String namespaceString = "";
String funcNameString = "";
if (input3.isUnique()) {
namespaceString = getUniqueValue(input3);
} else if (input3.isConstant()) {
namespaceString = getConstact(input3);
}
if (input4.isUnique()) {
funcNameString = getUniqueValue(input4);
} else if (input4.isConstant()) {
funcNameString = getConstact(input4);
}
if (StringUtilities.isAllBlank(namespaceString)
|| StringUtilities.isAllBlank(funcNameString)) {
continue;
}
String name = namespaceString.replace(" ", "") + "::" + funcNameString.replace(" ", "");
println("find function :" + name);
functionContaining.setName(name, SourceType.USER_DEFINED);
currentProgram.getListing().setComment(functionContaining.getEntryPoint(),
CodeUnit.EOL_COMMENT, "mars scipt auto define: " + name);
}
}
}
}
}
}
private String getConstact(Varnode input3) {
Address address2 = input3.getAddress();
Address address3 = currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(address2.getOffset());
Data dataAt2 = getDataAt(address3);
if (null != dataAt2) {
if (dataAt2.hasStringValue()) {
return dataAt2.getValue().toString();
}
}
return null;
}
private void easy(Address findXScopeTracer) throws CancelledException {
if (null != findXScopeTracer) {
ReferenceIterator referenceIterator = currentProgram.getReferenceManager()
.getReferencesTo(findXScopeTracer);
while (referenceIterator.hasNext()) {
monitor.checkCancelled();
Reference next = referenceIterator.next();
Address fromAddress = next.getFromAddress();
Instruction instructionAt = currentProgram.getListing().getInstructionAt(fromAddress);
if (null != instructionAt) {
PcodeOp[] pcode = instructionAt.getPcode();
if (null != pcode) {
for (PcodeOp pcodeOp : pcode) {
if (pcodeOp.getOpcode() == PcodeOp.CALL) {
Varnode namespace = pcodeOp.getInput(3);
Varnode funcName = pcodeOp.getInput(4);
if (null != namespace) {
if (namespace.isConstant()) {
long offset = namespace.getAddress().getOffset();
Address address = currentProgram.getAddressFactory().getDefaultAddressSpace()
.getAddress(offset);
Data dataAt = currentProgram.getListing().getDataAt(address);
if (null != dataAt) {
if (dataAt.hasStringValue()) {
dataAt.getValue().toString();
}
}
}
}
if (null != funcName) {
if (funcName.isConstant()) {
long offset = funcName.getAddress().getOffset();
Address address = currentProgram.getAddressFactory().getDefaultAddressSpace()
.getAddress(offset);
Data dataAt = currentProgram.getListing().getDataAt(address);
if (null != dataAt) {
if (dataAt.hasStringValue()) {
dataAt.getValue().toString();
}
}
}
}
}
}
}
println("caller address: " + fromAddress.toString());
}
}
}
}
private void find() throws Exception {
Function findXLogger = findXLogger();
if (null != findXLogger) {
if (findXLogger.isThunk()) {
currentProgram.getFunctionManager().createFunction("XLogger::operator()", findXLogger.getEntryPoint(),
findXLogger.getBody(), findXLogger.getSignatureSource());
} else {
findXLogger.setName("XLogger::operator()", SourceType.USER_DEFINED);
currentProgram.getListing().setComment(findXLogger.getEntryPoint(), CodeUnit.EOL_COMMENT,
"rename function: XLogger::operator()");
ReferenceIterator referenceIterator = currentProgram.getReferenceManager()
.getReferencesTo(findXLogger.getEntryPoint());
while (referenceIterator.hasNext()) {
monitor.checkCancelled();
Reference next = referenceIterator.next();
Address fromAddress = next.getFromAddress();
println("caller address: " + fromAddress.toString());
handle(fromAddress, findXLogger.getEntryPoint());
}
}
}
}
private Address findXScopeTracer() throws Exception {
List<FoundString> list = findStrings(null, 5, 1, true, false);
ContainsTextFilterFactory factory = new ContainsTextFilterFactory(false, true);
TextFilter textFilter = factory.getTextFilter("mars::comm::DNS::GetHostByName");
for (FoundString foundString : list) {
monitor.checkCancelled();
String string = foundString.getString(currentProgram.getMemory());
if (textFilter.matches(string)) {
Address address = foundString.getAddress();
println("=====text addr :" + address.toString());
ReferenceIterator referencesTo = currentProgram.getReferenceManager().getReferencesTo(address);
while (referencesTo.hasNext()) {
Reference ref = referencesTo.next();
Address textAddress = ref.getFromAddress();
Function func = currentProgram.getFunctionManager().getFunctionContaining(textAddress);
if (null == func) {
continue;
}
CodeBlock[] codeBlocksContaining = basicBlockModel.getCodeBlocksContaining(textAddress, monitor);
for (CodeBlock codeBlock : codeBlocksContaining) {
AddressIterator addressIterator = codeBlock.getAddresses(true);
while (addressIterator.hasNext()) {
Address next = addressIterator.next();
CodeUnit codeUnitAt = currentProgram.getListing().getCodeUnitAt(next);
if (null != codeUnitAt) {
if (codeUnitAt.getMnemonicString().equals("CALL")) {
Instruction instructionAt = currentProgram.getListing().getInstructionAt(next);
PcodeOp[] pcode = instructionAt.getPcode();
PcodeOp pcodeOp = pcode[pcode.length - 1];
Varnode input = pcodeOp.getInput(0);
Address address2 = input.getAddress();
println("===== XScopeTracer::XScopeTracer addr :" + address2.toString());
Function functionAt = currentProgram.getFunctionManager().getFunctionAt(address2);
if (null != functionAt) {
functionAt.setName("XScopeTracer::XScopeTracer", SourceType.USER_DEFINED);
currentProgram.getListing().setComment(functionAt.getEntryPoint(),
CodeUnit.EOL_COMMENT, "scipt auto define: XScopeTracer::XScopeTracer");
} else {
createFunction(address2, "XScopeTracer::XScopeTracer");
currentProgram.getListing().setComment(address2, CodeUnit.EOL_COMMENT,
"scipt auto create: XScopeTracer::XScopeTracer");
}
return address2;
}
}
}
}
}
}
}
return null;
}
private void handle(Address address, Address calleeAddress) throws CancelledException {
Function functionContaining = currentProgram.getFunctionManager().getFunctionContaining(address);
if (null == functionContaining) {
println("no found function: " + address.toString());
return;
}
DecompileResults res = decompiler.decompileFunction(functionContaining, 20, null);
if (!res.decompileCompleted()) {
println("decompile error: " + res.getErrorMessage());
return;
}
HighFunction highFunction = res.getHighFunction();
ArrayList<PcodeBlockBasic> basicBlocks = highFunction.getBasicBlocks();
for (PcodeBlockBasic pcodeBlockBasic : basicBlocks) {
monitor.checkCancelled();
boolean contains = pcodeBlockBasic.contains(address);
if (contains) {
Iterator<PcodeOp> iterator = pcodeBlockBasic.getIterator();
for (; iterator.hasNext();) {
monitor.checkCancelled();
PcodeOp next = iterator.next();
if (next.getOpcode() == PcodeOp.CALL) {
if (next.getNumInputs() > 4) {
Varnode input3 = next.getInput(3);
if (null != input3) {
if (input3.isUnique()) {
String uniqueValue = getUniqueValue(input3);
if (null != uniqueValue) {
println(uniqueValue);
}
}
}
}
}
}
}
}
}
private String getUniqueValue(Varnode input3) {
PcodeOp def = input3.getDef();
Varnode[] inputs = def.getInputs();
if (null != inputs && inputs.length > 0) {
if (inputs[0].isConstant()) {
Address address2 = inputs[0].getAddress();
Address address3 = currentProgram.getAddressFactory().getDefaultAddressSpace()
.getAddress(address2.getOffset());
Data dataAt2 = currentProgram.getListing().getDataAt(address3);
if (null != dataAt2) {
if (dataAt2.hasStringValue()) {
return dataAt2.getValue().toString();
}
}
}
}
return null;
}
private Function findXLogger() throws MemoryAccessException, CancelledException {
FunctionManager functionManager = currentProgram.getFunctionManager();
ReferenceManager referenceManager = currentProgram.getReferenceManager();
AddressFactory factory = currentProgram.getAddressFactory();
AddressSpace[] addressSpaces = factory.getAddressSpaces();
AddressSetView initializedMemory = currentProgram.getMemory().getLoadedAndInitializedAddressSet();
AddressSet searchSet = initializedMemory.intersect(new AddressSet(initializedMemory));
List<FoundString> findStrings = new ArrayList<>();
println("初次查询速度较慢,请耐心等待。");
for (AddressSpace space : addressSpaces) {
if (monitor.isCancelled()) {
break;
}
AddressSet intersecting = searchSet.intersectRange(space.getMinAddress(), space.getMaxAddress());
findStrings.addAll(findStrings(null, 10, 1, true, true));
}
if (null != findStrings && findStrings.size() > 0) {
ContainsTextFilterFactory containsTextFilterFactory = new ContainsTextFilterFactory(false, true);
TextFilter textFilter = containsTextFilterFactory
.getTextFilter("XLogger& XLogger::operator()(const char* _format, ...)");
for (FoundString foundString : findStrings) {
if (monitor.isCancelled()) {
break;
}
String string = foundString.getString(currentProgram.getMemory());
if (textFilter.matches(string)) {
Address address = foundString.getAddress();
println(address.toString());
ReferenceIterator referencesTo = referenceManager.getReferencesTo(address);
while (referencesTo.hasNext()) {
if (monitor.isCancelled()) {
break;
}
Reference ref = referencesTo.next();
Address xLoggerAddr = ref.getFromAddress();
Function targetFunction = functionManager.getFunctionContaining(xLoggerAddr);
if (null == targetFunction) {
continue;
}
println("XLogger::operator() " + targetFunction.getEntryPoint().toString());
return targetFunction;
}
}
}
}
return null;
}
}