//TODO write a description for this script //@author //@category _NEW_ //@keybinding //@menupath //@toolbar bomb import java.util.List; import java.util.regex.Pattern; import ghidra.app.script.GhidraScript; import ghidra.program.model.listing.Function; public class SetCallingConventionBulk extends GhidraScript { public void run() throws Exception { String callingConvention = BulkUtils.askForCallingConvention(this); Pattern pattern = BulkUtils.askForRegex(this, "entire function name"); List matchingFunctions = BulkUtils.getFunctionsByRegex(this, pattern); int skipped = BulkUtils.removeFunctionsByCallingConvention(matchingFunctions, callingConvention); int numOfMatches = matchingFunctions.size(); // only abort if there are no matches AND no matches have been skipped, so the users understands why there are no matches if(numOfMatches == 0 && skipped == 0){ println("Abort: no matches found"); return; } String title = "Set calling convention of " + matchingFunctions.size() + " function(s) to " + callingConvention; boolean confirmed = BulkUtils.showFunctionConfirmationDialog(matchingFunctions, title, skipped, "Number of matches skipped (calling convention already matches): %d"); if (!confirmed) { println("Abort: negative confirmation"); return; } int success = 0; int fail = 0; for (Function func : matchingFunctions) { try { func.setCallingConvention(callingConvention); success++; } catch (Exception e) { println("Failed to update function " + func.getName() + " at " + func.getEntryPoint() + " - " + e.getMessage()); fail++; } } BulkUtils.printDoneMessage(this, success, fail); } }