wxhelper/script/ghidra_script/NamedScript.java

200 lines
7.2 KiB
Java
Raw Normal View History

2024-08-19 22:58:06 +08:00
import java.util.ArrayList;
2024-07-24 22:47:58 +08:00
import java.util.Iterator;
2024-08-19 22:58:06 +08:00
import java.util.List;
import docking.widgets.filter.ContainsTextFilterFactory;
import docking.widgets.filter.TextFilter;
2024-07-24 22:47:58 +08:00
import ghidra.app.decompiler.DecompInterface;
import ghidra.app.decompiler.DecompileOptions;
import ghidra.app.decompiler.DecompileResults;
import ghidra.app.script.GhidraScript;
2024-08-19 22:58:06 +08:00
import ghidra.feature.fid.hash.FidHashQuad;
import ghidra.feature.fid.service.FidService;
2024-07-24 22:47:58 +08:00
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressFactory;
2024-08-19 22:58:06 +08:00
import ghidra.program.model.address.AddressSet;
import ghidra.program.model.address.AddressSetView;
2024-07-24 22:47:58 +08:00
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;
2024-08-19 22:58:06 +08:00
import ghidra.program.model.mem.MemoryAccessException;
2024-07-24 22:47:58 +08:00
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;
2024-08-19 22:58:06 +08:00
import ghidra.program.util.string.FoundString;
import ghidra.util.exception.CancelledException;
2024-07-24 22:47:58 +08:00
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.InvalidInputException;
public class NamedScript extends GhidraScript {
2024-08-19 22:58:06 +08:00
long wxlog_full_hash = 0xf9f7e7c3081f5aa3L;
long wxlog_spec_hash = 0x9e71b418c749e4faL;
FidService service;
2024-07-24 22:47:58 +08:00
@Override
protected void run() throws Exception {
2024-08-19 22:58:06 +08:00
service = new FidService();
Address selectAddress = askAddress("填写手动确认的wxlog地址", "wxlog地址或者任意值进行搜索");
2024-07-24 22:47:58 +08:00
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;
2024-08-19 22:58:06 +08:00
2024-07-24 22:47:58 +08:00
Function logFunction = functionManager.getFunctionAt(funcAddress);
2024-07-31 18:02:39 +08:00
2024-08-19 22:58:06 +08:00
if (null == logFunction) {
logFunction = findLogFunc();
if (null == logFunction) {
printerr("未能成功自动匹配wxlog函数,请手动查找后填写正确地址 ");
return;
}
}
2024-07-24 22:47:58 +08:00
ReferenceIterator referenceIterator = referenceManager.getReferencesTo(logFunction.getEntryPoint());
2024-08-19 22:58:06 +08:00
while (referenceIterator.hasNext()) {
2024-07-31 18:02:39 +08:00
monitor.checkCancelled();
Reference next = referenceIterator.next();
Address fromAddress = next.getFromAddress();
println("lookup address: " + fromAddress.toString());
2024-08-19 22:58:06 +08:00
handle(fromAddress, functionManager, decompiler, space, listing, selectAddress);
2024-07-31 18:02:39 +08:00
println("caller address: " + fromAddress.toString());
2024-07-24 22:47:58 +08:00
}
2024-08-19 22:58:06 +08:00
}
private Function findLogFunc() throws MemoryAccessException, CancelledException {
2024-07-31 18:02:39 +08:00
2024-08-19 22:58:06 +08:00
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;
2024-07-24 22:47:58 +08:00
}
private void handle(Address address, FunctionManager functionManager, DecompInterface decompiler,
2024-08-19 22:58:06 +08:00
AddressSpace space, Listing listing, Address selectAddress) {
2024-07-24 22:47:58 +08:00
Function functionContaining = functionManager.getFunctionContaining(address);
if (null == functionContaining) {
2024-07-31 18:02:39 +08:00
println("no found function: " + address.toString());
2024-07-24 22:47:58 +08:00
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();
}
}
}
}
}
}
}
}
}