Skip to content

Commit d765288

Browse files
committed
FunctionID: Add AddSingleFunction.java Ghidra script
1 parent 2333ab6 commit d765288

File tree

2 files changed

+117
-2
lines changed

2 files changed

+117
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
2+
/* ###
3+
* IP: GHIDRA
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
//Adds the function at the current address to the chosen FID library.
18+
//@category FunctionID
19+
20+
import java.util.List;
21+
22+
import ghidra.app.script.GhidraScript;
23+
import ghidra.feature.fid.db.*;
24+
import ghidra.feature.fid.hash.FidHashQuad;
25+
import ghidra.feature.fid.service.FidService;
26+
import ghidra.feature.fid.service.FidServiceLibraryIngest;
27+
import ghidra.framework.model.DomainFile;
28+
import ghidra.program.model.lang.CompilerSpec;
29+
import ghidra.program.model.lang.Language;
30+
import ghidra.program.model.lang.LanguageID;
31+
import ghidra.program.model.listing.Function;
32+
import ghidra.program.model.listing.FunctionManager;
33+
34+
public class AddSingleFunction extends GhidraScript {
35+
36+
private FidDB fidDb = null;
37+
38+
@Override
39+
protected void run() throws Exception {
40+
41+
if (currentProgram == null) {
42+
printerr("No current program");
43+
return;
44+
}
45+
if (currentAddress == null) {
46+
printerr("No current address (?)");
47+
return;
48+
}
49+
FunctionManager functionManager = currentProgram.getFunctionManager();
50+
Function function = functionManager.getFunctionContaining(currentAddress);
51+
if (function == null) {
52+
printerr("No current function");
53+
return;
54+
}
55+
56+
FidService service = new FidService();
57+
FidHashQuad hashFunction = service.hashFunction(function);
58+
if (hashFunction == null) {
59+
printerr("Function too small");
60+
return;
61+
}
62+
63+
FidFileManager fidFileManager = FidFileManager.getInstance();
64+
List<FidFile> userFid = fidFileManager.getUserAddedFiles();
65+
if (userFid.isEmpty()) {
66+
printerr("No available FID DB");
67+
return;
68+
}
69+
FidFile fidFile =
70+
askChoice("FID database", "Choose FID database", userFid, userFid.get(0));
71+
try {
72+
fidDb = fidFile.getFidDB(true);
73+
74+
List<LibraryRecord> libraries = fidDb.getAllLibraries();
75+
LibraryRecord library;
76+
if (libraries == null || libraries.isEmpty()) {
77+
println("No libraries found. Creating one...");
78+
79+
String libraryFamilyName =
80+
askString("Library Family Name", "Choose Library Family Name");
81+
String libraryVersion = askString("Library Version", "Choose Library Version");
82+
String libraryVariant = askString("Library Variant", "Choose Library Variant");
83+
LanguageID languageId = currentProgram.getLanguageID();
84+
Language language = currentProgram.getLanguage();
85+
CompilerSpec compilerSpec = currentProgram.getCompilerSpec();
86+
library = fidDb.createNewLibrary(libraryFamilyName, libraryVersion, libraryVariant,
87+
getGhidraVersion(), languageId, language.getVersion(),
88+
language.getMinorVersion(), compilerSpec.getCompilerSpecID());
89+
}
90+
else {
91+
library =
92+
askChoice("FID libraries", "Choose FID library", libraries, libraries.get(0));
93+
}
94+
95+
boolean disableNamespaceStripping =
96+
askYesNo("Namespace stripping",
97+
"Do you want to disable namespace stripping?");
98+
99+
long offset = function.getEntryPoint().getOffset();
100+
101+
boolean hasTerminator = FidServiceLibraryIngest.findTerminator(function, monitor);
102+
103+
DomainFile domainFile = getCurrentProgram().getDomainFile();
104+
105+
fidDb.createNewFunction(library, hashFunction,
106+
function.getName(disableNamespaceStripping), offset, domainFile.getName(),
107+
hasTerminator);
108+
109+
fidDb.saveDatabase("Saving", monitor);
110+
}
111+
finally {
112+
fidDb.close();
113+
}
114+
}
115+
}

Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/service/FidServiceLibraryIngest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
import ghidra.util.exception.VersionException;
3838
import ghidra.util.task.TaskMonitor;
3939

40-
class FidServiceLibraryIngest {
40+
public class FidServiceLibraryIngest {
4141
private static final int MAXIMUM_NUMBER_OF_NAME_RESOLUTION_RELATIONS = 12;
4242

4343
private FidDB fidDb; // The database being populated
@@ -523,7 +523,7 @@ private void resolveNamedRelations() throws CancelledException {
523523
* @return if a terminating flow was found in the function body
524524
* @throws CancelledException if the user cancels
525525
*/
526-
private static boolean findTerminator(Function function, TaskMonitor monitor)
526+
public static boolean findTerminator(Function function, TaskMonitor monitor)
527527
throws CancelledException {
528528
boolean retFound = false;
529529
AddressSetView body = function.getBody();

0 commit comments

Comments
 (0)