|
23 | 23 | import com.google.security.zynamics.BinExport.BinExport2; |
24 | 24 | import com.google.security.zynamics.BinExport.BinExport2.Builder; |
25 | 25 | import ghidra.app.nav.NavigationUtils; |
| 26 | +import ghidra.program.database.function.OverlappingFunctionException; |
26 | 27 | import ghidra.program.database.symbol.EquateDB; |
27 | 28 | import ghidra.program.model.address.Address; |
28 | 29 | import ghidra.program.model.address.AddressSetView; |
|
58 | 59 | import ghidra.program.model.symbol.Symbol; |
59 | 60 | import ghidra.program.model.symbol.SymbolUtilities; |
60 | 61 | import ghidra.program.util.DefinedDataIterator; |
| 62 | +import ghidra.util.UndefinedFunction; |
61 | 63 | import ghidra.util.exception.CancelledException; |
| 64 | +import ghidra.util.exception.InvalidInputException; |
62 | 65 | import ghidra.util.task.TaskMonitor; |
63 | 66 | import java.io.File; |
64 | 67 | import java.util.ArrayList; |
@@ -744,6 +747,41 @@ private void buildBasicBlocks( |
744 | 747 | } |
745 | 748 | } |
746 | 749 |
|
| 750 | + private void promoteUndefinedFunctions() throws CancelledException { |
| 751 | + FunctionManager funcManager = program.getFunctionManager(); |
| 752 | + |
| 753 | + for (var bbIter = bbModel.getCodeBlocks(monitor); bbIter.hasNext(); ) { |
| 754 | + CodeBlock bb = bbIter.next(); |
| 755 | + Address bbEntryPoint = bb.getFirstStartAddress(); |
| 756 | + // If a function is already defined or external, no need to promote it. |
| 757 | + Function func = funcManager.getFunctionContaining(bbEntryPoint); |
| 758 | + if (func != null && func.isExternal()) { |
| 759 | + continue; |
| 760 | + } |
| 761 | + UndefinedFunction undefinedFunction = |
| 762 | + UndefinedFunction.findFunction(program, bbEntryPoint, monitor); |
| 763 | + if (undefinedFunction != null) { |
| 764 | + try { |
| 765 | + Function newFunc = |
| 766 | + funcManager.createFunction( |
| 767 | + undefinedFunction.getName(), |
| 768 | + undefinedFunction.getEntryPoint(), |
| 769 | + undefinedFunction.getBody(), |
| 770 | + undefinedFunction.getSignatureSource()); |
| 771 | + if (newFunc != null) { |
| 772 | + monitor.setMessage( |
| 773 | + String.format("Created undefined function at %x", getMappedAddress(bbEntryPoint))); |
| 774 | + System.out.printf("newUndefinedFunction: %x%n", getMappedAddress(bbEntryPoint)); |
| 775 | + } |
| 776 | + } catch (InvalidInputException | OverlappingFunctionException e) { |
| 777 | + monitor.setMessage( |
| 778 | + String.format( |
| 779 | + "Failed to create undefined function at %x", getMappedAddress(bbEntryPoint))); |
| 780 | + } |
| 781 | + } |
| 782 | + } |
| 783 | + } |
| 784 | + |
747 | 785 | private void buildFlowGraphs(Map<Long, Integer> basicBlockIndices) throws CancelledException { |
748 | 786 | FunctionManager funcManager = program.getFunctionManager(); |
749 | 787 | monitor.setIndeterminate(false); |
@@ -1146,6 +1184,7 @@ public BinExport2 build(TaskMonitor taskMonitor) throws CancelledException { |
1146 | 1184 | buildStrings(instructionIndices); |
1147 | 1185 | buildDataReferences(instructionIndices); |
1148 | 1186 |
|
| 1187 | + promoteUndefinedFunctions(); |
1149 | 1188 | monitor.setMessage("Exporting flow graphs"); |
1150 | 1189 | buildFlowGraphs(basicBlockIndices); |
1151 | 1190 | monitor.setMessage("Exporting call graph"); |
|
0 commit comments