GP-2072 added CallotherCensusScript

This commit is contained in:
James 2022-05-26 16:05:48 +00:00
parent 2474de38d0
commit a540cbe0f0
2 changed files with 95 additions and 5 deletions

View File

@ -0,0 +1,89 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Produces a list of instructions whose pcode contains a CALLOTHER pcode op. The list is
// sorted by number of occurrences of an instruction. When run headlessly, the list is displayed
// each time a program is processed and the counts are cumulative.
// @category sleigh
import java.util.HashMap;
import java.util.Map;
import ghidra.app.script.GhidraScript;
import ghidra.program.model.listing.Instruction;
import ghidra.program.model.listing.InstructionIterator;
import ghidra.program.model.pcode.PcodeOp;
public class CallotherCensusScript extends GhidraScript {
public static Map<String, CountAndLocationInfo> instCountMap = new HashMap<>();
@Override
protected void run() throws Exception {
if (currentProgram == null) {
popup("This script requires an active current program.");
return;
}
if (!isRunningHeadless()) {
instCountMap.clear();
}
InstructionIterator instIter = currentProgram.getListing().getInstructions(true);
while (instIter.hasNext()) {
monitor.checkCanceled();
Instruction inst = instIter.next();
for (PcodeOp op : inst.getPcode()) {
if (op.getOpcode() == PcodeOp.CALLOTHER) {
String mnemonic = inst.getMnemonicString();
CountAndLocationInfo countInfo = instCountMap.computeIfAbsent(mnemonic,
s -> new CountAndLocationInfo(s,
currentProgram.getDomainFile().getPathname() + " " +
inst.getAddress()));
countInfo.incrementCount();
}
}
}
instCountMap.values().stream().sorted().forEach(x -> printf("%s\n", x.toString()));
}
class CountAndLocationInfo implements Comparable<CountAndLocationInfo> {
private String mnemonic;
private String firstOccurrence;
private Integer count;
public CountAndLocationInfo(String mnemonic, String firstOccurrence) {
this.mnemonic = mnemonic;
this.firstOccurrence = firstOccurrence;
count = 0;
}
public void incrementCount() {
count += 1;
}
@Override
public String toString() {
return mnemonic + " " + count.toString() + " " + firstOccurrence;
}
@Override
public int compareTo(CountAndLocationInfo o) {
return -Integer.compare(count, o.count);
}
}
}

View File

@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Generate WARNING Bookmarks CallOther PcodeOp's within an instructions Pcode.
// This is useful to find PsuedoOps that need to be implemented to yield better
// Generate WARNING Bookmarks at instructions whose pcode contains a CALLOTHER op.
// This is useful to find PseudoOps that need to be implemented to yield better
// emulation or decompilation.
// @category sleigh
@ -63,8 +63,9 @@ public class MarkCallOtherPcode extends GhidraScript {
}
private void markCallOtherPcode(Instruction instr, PcodeOp op) {
currentProgram.getBookmarkManager().setBookmark(instr.getAddress(), BookmarkType.WARNING,
"CallOther PcodeOp",
currentProgram.getLanguage().getUserDefinedOpName((int) op.getInput(0).getOffset()));
currentProgram.getBookmarkManager()
.setBookmark(instr.getAddress(), BookmarkType.WARNING, "CallOther PcodeOp",
currentProgram.getLanguage()
.getUserDefinedOpName((int) op.getInput(0).getOffset()));
}
}