wxhelper/script/ghidra_script/NamedScript.java
2024-08-19 22:58:06 +08:00

200 lines
7.2 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.

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.feature.fid.hash.FidHashQuad;
import ghidra.feature.fid.service.FidService;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressFactory;
import ghidra.program.model.address.AddressSet;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.address.AddressSpace;
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.Listing;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.pcode.HighFunction;
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.util.exception.CancelledException;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.InvalidInputException;
public class NamedScript extends GhidraScript {
long wxlog_full_hash = 0xf9f7e7c3081f5aa3L;
long wxlog_spec_hash = 0x9e71b418c749e4faL;
FidService service;
@Override
protected void run() throws Exception {
service = new FidService();
Address selectAddress = askAddress("填写手动确认的wxlog地址", "wxlog地址或者任意值进行搜索");
Listing listing = currentProgram.getListing();
FunctionManager functionManager = currentProgram.getFunctionManager();
ReferenceManager referenceManager = currentProgram.getReferenceManager();
AddressFactory addressFactory = currentProgram.getAddressFactory();
AddressSpace space = addressFactory.getDefaultAddressSpace();
DecompInterface decompiler = new DecompInterface();
DecompileOptions decompileOptions = new DecompileOptions();
decompiler.setOptions(decompileOptions);
decompiler.openProgram(currentProgram);
Address funcAddress = selectAddress;
Function logFunction = functionManager.getFunctionAt(funcAddress);
if (null == logFunction) {
logFunction = findLogFunc();
if (null == logFunction) {
printerr("未能成功自动匹配wxlog函数,请手动查找后填写正确地址 ");
return;
}
}
ReferenceIterator referenceIterator = referenceManager.getReferencesTo(logFunction.getEntryPoint());
while (referenceIterator.hasNext()) {
monitor.checkCancelled();
Reference next = referenceIterator.next();
Address fromAddress = next.getFromAddress();
println("lookup address: " + fromAddress.toString());
handle(fromAddress, functionManager, decompiler, space, listing, selectAddress);
println("caller address: " + fromAddress.toString());
}
}
private Function findLogFunc() 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("(%d-%d-%d:%d:%02d:%02d:%03d %05d)-%s/%s:");
for (FoundString foundString : findStrings) {
if (monitor.isCancelled()) {
break;
}
String string = foundString.getString(currentProgram.getMemory());
if (textFilter.matches(string)) {
Address address = foundString.getAddress();
ReferenceIterator referencesTo = referenceManager.getReferencesTo(address);
while (referencesTo.hasNext()) {
if (monitor.isCancelled()) {
break;
}
Reference ref = referencesTo.next();
Address wxlogAddr = ref.getFromAddress();
Function targetFunction = functionManager.getFunctionContaining(wxlogAddr);
if (null == targetFunction) {
continue;
}
FidHashQuad hashQuad = service.hashFunction(targetFunction);
if (hashQuad.getFullHash() == wxlog_full_hash
&& hashQuad.getSpecificHash() == wxlog_spec_hash) {
return targetFunction;
}
}
}
}
}
return null;
}
private void handle(Address address, FunctionManager functionManager, DecompInterface decompiler,
AddressSpace space, Listing listing, Address selectAddress) {
Function functionContaining = functionManager.getFunctionContaining(address);
if (null == functionContaining) {
println("no found function: " + address.toString());
return;
}
DecompileResults res = decompiler.decompileFunction(functionContaining, 20, null);
if (!res.decompileCompleted()) {
println("Symbol " + res.getErrorMessage());
return;
}
HighFunction highFunction = res.getHighFunction();
Iterator<PcodeOpAST> pcodeOps = highFunction.getPcodeOps();
while (pcodeOps.hasNext()) {
PcodeOpAST next = pcodeOps.next();
int opcode = next.getOpcode();
if (PcodeOp.CALL == opcode || PcodeOp.CALLIND == opcode || PcodeOp.CALLOTHER == opcode) {
Varnode input0 = next.getInput(0);
boolean contains = input0.contains(selectAddress);
if (contains) {
Varnode input4 = next.getInput(4);
if (input4 == null) {
continue;
}
PcodeOp def4 = input4.getDef();
if (null != def4) {
Address param4Address = null;
if (def4.getOpcode() == PcodeOp.COPY) {
Varnode vn0 = def4.getInput(0);
param4Address = space.getAddress(vn0.getAddress().getOffset());
Data dataAt = listing.getDataAt(param4Address);
if (dataAt.hasStringValue()) {
Object value = dataAt.getValue();
String funcStr = value.toString();
println("func:" + funcStr);
try {
functionContaining.setName(funcStr, SourceType.USER_DEFINED);
listing.setComment(functionContaining.getEntryPoint(), CodeUnit.EOL_COMMENT,
"auto define:" + funcStr);
} catch (DuplicateNameException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidInputException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
}
}
}