/* ### * 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. */ // Shows how to run a script on all of the programs within the current project. // NOTE: Script will only process unversioned and checked-out files. //@category Examples import java.io.IOException; import ghidra.app.script.GhidraScript; import ghidra.app.script.GhidraState; import ghidra.framework.model.*; import ghidra.program.database.ProgramContentHandler; import ghidra.program.model.listing.Program; import ghidra.util.exception.CancelledException; import ghidra.util.exception.VersionException; public class CallAnotherScriptForAllPrograms extends GhidraScript { // The script referenced in the following line should be replaced with the script to be called private static String SUBSCRIPT_NAME = "AddCommentToProgramScript.java"; @Override public void run() throws Exception { if (currentProgram != null) { popup("This script should be run from a tool with no open programs"); return; } Project project = state.getProject(); ProjectData projectData = project.getProjectData(); DomainFolder rootFolder = projectData.getRootFolder(); recurseProjectFolder(rootFolder); } private void recurseProjectFolder(DomainFolder domainFolder) throws CancelledException, IOException { DomainFile[] files = domainFolder.getFiles(); for (DomainFile domainFile : files) { processDomainFile(domainFile); } DomainFolder[] folders = domainFolder.getFolders(); for (DomainFolder folder : folders) { recurseProjectFolder(folder); } } private void processDomainFile(DomainFile domainFile) throws CancelledException, IOException { // Do not follow folder-links or consider program links. Using content type // to filter is best way to control this. If program links should be considered // "Program.class.isAssignableFrom(domainFile.getDomainObjectClass())" // should be used. if (!ProgramContentHandler.PROGRAM_CONTENT_TYPE.equals(domainFile.getContentType())) { return; // skip non-Program files } if (domainFile.isVersioned() && !domainFile.isCheckedOut()) { println("WARNING! Skipping versioned file - not checked-out: " + domainFile.getPathname()); return; } Program program = null; try { program = (Program) domainFile.getDomainObject(this, true /*upgrade*/, false /*don't recover*/, monitor); processProgram(program); } catch (VersionException e) { println("ERROR! Failed to process file due to upgrade issue: " + domainFile.getPathname()); } finally { if (program != null) { program.release(this); } } } private void processProgram(Program program) throws CancelledException, IOException { /* Do you program work here */ println("Processing: " + program.getDomainFile().getPathname()); monitor.setMessage("Processing: " + program.getDomainFile().getName()); int id = program.startTransaction("Batch Script Transaction"); try { GhidraState newState = new GhidraState(state.getTool(), state.getProject(), program, null, null, null); runScript(SUBSCRIPT_NAME, newState); } catch (Exception e) { printerr("ERROR! Exception occurred while processing file: " + program.getDomainFile().getPathname()); printerr(" " + e.getMessage()); e.printStackTrace(); return; } finally { program.endTransaction(id, true); } // ...save any changes program.save("Changes made by script: " + SUBSCRIPT_NAME, monitor); } }