diff --git a/java/ghidra/Decompile.java b/java/ghidra/Decompile.java index 62218730..d3389168 100644 --- a/java/ghidra/Decompile.java +++ b/java/ghidra/Decompile.java @@ -150,16 +150,16 @@ public class Decompile extends GhidraScript { return; } - RecompileConfig.INSTANCE = new RecompileConfig(this); + RemanConfig.INSTANCE = new RemanConfig(this); - if (!new File(RecompileConfig.INSTANCE.outputDir).exists()) { - throw new Exception("Output directory does not exist: " + RecompileConfig.INSTANCE.outputDir); + if (!new File(RemanConfig.INSTANCE.outputDir).exists()) { + throw new Exception("Output directory does not exist: " + RemanConfig.INSTANCE.outputDir); } // Make sure to create output folders - RecompileConfig.INSTANCE.dirDecompFix.mkdirs(); - RecompileConfig.INSTANCE.dirDecompAuto.mkdirs(); - RecompileConfig.INSTANCE.dirDecompRef.mkdirs(); + RemanConfig.INSTANCE.dirDecompFix.mkdirs(); + RemanConfig.INSTANCE.dirDecompAuto.mkdirs(); + RemanConfig.INSTANCE.dirDecompRef.mkdirs(); // buildFunctionBlacklist(); diff --git a/java/ghidra/DumpCurrentFunction.java b/java/ghidra/DumpCurrentFunction.java index ae214c4c..c1987d5a 100644 --- a/java/ghidra/DumpCurrentFunction.java +++ b/java/ghidra/DumpCurrentFunction.java @@ -6,13 +6,13 @@ import ghidra.app.script.GhidraScript; import ghidra.program.model.listing.Function; import re3lib.FunctionDumper; import re3lib.GlobalDumper; -import re3lib.RecompileConfig; +import re3lib.RemanConfig; public class DumpCurrentFunction extends GhidraScript { @Override public void run() throws Exception { - RecompileConfig.INSTANCE = new RecompileConfig(this); - RecompileConfig.INSTANCE.createDirectories(); + RemanConfig.INSTANCE = new RemanConfig(this); + RemanConfig.INSTANCE.createDirectories(); GlobalDumper globalDumper = new GlobalDumper(this); globalDumper.loadGlobalManifest(); @@ -26,7 +26,7 @@ public class DumpCurrentFunction extends GhidraScript { } if (functionDumper.createdFile) - RecompileConfig.INSTANCE.touchCMakeTimestamp(); + RemanConfig.INSTANCE.touchCMakeTimestamp(); globalDumper.dumpGlobals(); globalDumper.saveGlobalManifest(); diff --git a/java/ghidra/DumpCurrentFunctionN.java b/java/ghidra/DumpCurrentFunctionN.java index bb45bef7..e094596d 100644 --- a/java/ghidra/DumpCurrentFunctionN.java +++ b/java/ghidra/DumpCurrentFunctionN.java @@ -12,7 +12,7 @@ import ghidra.program.model.listing.Function; import re3lib.FunctionDumper; import re3lib.GlobalDumper; import re3lib.PCallTracer; -import re3lib.RecompileConfig; +import re3lib.RemanConfig; import re3lib.TypeDumper; public class DumpCurrentFunctionN extends GhidraScript { @@ -43,8 +43,8 @@ public class DumpCurrentFunctionN extends GhidraScript { @Override public void run() throws Exception { - RecompileConfig.INSTANCE = new RecompileConfig(this); - RecompileConfig.INSTANCE.createDirectories(); + RemanConfig.INSTANCE = new RemanConfig(this); + RemanConfig.INSTANCE.createDirectories(); GlobalDumper globalDumper = new GlobalDumper(this); globalDumper.loadGlobalManifest(); diff --git a/java/ghidra/DumpCurrentFunctionRecursive.java b/java/ghidra/DumpCurrentFunctionRecursive.java index 4de46f50..d5e74694 100644 --- a/java/ghidra/DumpCurrentFunctionRecursive.java +++ b/java/ghidra/DumpCurrentFunctionRecursive.java @@ -10,14 +10,14 @@ import ghidra.program.model.listing.Function; import re3lib.FunctionDumper; import re3lib.GlobalDumper; import re3lib.PCallTracer; -import re3lib.RecompileConfig; +import re3lib.RemanConfig; import re3lib.TypeDumper; public class DumpCurrentFunctionRecursive extends GhidraScript { @Override public void run() throws Exception { - RecompileConfig.INSTANCE = new RecompileConfig(this); - RecompileConfig.INSTANCE.createDirectories(); + RemanConfig.INSTANCE = new RemanConfig(this); + RemanConfig.INSTANCE.createDirectories(); GlobalDumper globalDumper = new GlobalDumper(this); globalDumper.loadGlobalManifest(); @@ -65,7 +65,7 @@ public class DumpCurrentFunctionRecursive extends GhidraScript { } if (functionDumper.createdFile) - RecompileConfig.INSTANCE.touchCMakeTimestamp(); + RemanConfig.INSTANCE.touchCMakeTimestamp(); globalDumper.dumpGlobals(); globalDumper.saveGlobalManifest(); diff --git a/java/ghidra/ExportData.java b/java/ghidra/ExportData.java index 38a921eb..d2aff66a 100644 --- a/java/ghidra/ExportData.java +++ b/java/ghidra/ExportData.java @@ -7,7 +7,7 @@ import java.io.FileOutputStream; import java.io.PrintWriter; import ghidra.app.script.GhidraScript; import ghidra.program.model.address.Address; -import re3lib.RecompileConfig; +import re3lib.RemanConfig; public class ExportData extends GhidraScript { @@ -16,16 +16,16 @@ public class ExportData extends GhidraScript { if (currentProgram == null) { return; } - RecompileConfig.INSTANCE = new RecompileConfig(this); + RemanConfig.INSTANCE = new RemanConfig(this); - String dataFile = new File(RecompileConfig.INSTANCE.outputDir, "gh_datasegment.bin").toString(); - String headerFile = new File(RecompileConfig.INSTANCE.outputDir, "gh_datasegment.h").toString(); + String dataFile = new File(RemanConfig.INSTANCE.outputDir, "gh_datasegment.bin").toString(); + String headerFile = new File(RemanConfig.INSTANCE.outputDir, "gh_datasegment.h").toString(); FileOutputStream dataOutputStream = new FileOutputStream(dataFile); PrintWriter headerWriter = new PrintWriter(headerFile, "UTF-8"); - Address startAddr = RecompileConfig.INSTANCE.staticMemoryBlockStart; - Address endAddr = RecompileConfig.INSTANCE.staticMemoryBlockEnd; + Address startAddr = RemanConfig.INSTANCE.staticMemoryBlockStart; + Address endAddr = RemanConfig.INSTANCE.staticMemoryBlockEnd; // Dump all the memory to the bin file int numBytes = (int) endAddr.subtract(startAddr); diff --git a/java/ghidra/SanitizeGlobalSymbols.java b/java/ghidra/SanitizeGlobalSymbols.java index 8f0987b5..5576d44b 100644 --- a/java/ghidra/SanitizeGlobalSymbols.java +++ b/java/ghidra/SanitizeGlobalSymbols.java @@ -4,13 +4,13 @@ import ghidra.app.script.GhidraScript; import re3lib.GlobalDumper; -import re3lib.RecompileConfig; +import re3lib.RemanConfig; public class SanitizeGlobalSymbols extends GhidraScript { @Override public void run() throws Exception { - RecompileConfig.INSTANCE = new RecompileConfig(this); - RecompileConfig.INSTANCE.createDirectories(); + RemanConfig.INSTANCE = new RemanConfig(this); + RemanConfig.INSTANCE.createDirectories(); GlobalDumper globalDumper = new GlobalDumper(this); globalDumper.loadGlobalManifest(); diff --git a/java/ghidra/Test.java b/java/ghidra/Test.java index 997d36c5..08dff27e 100644 --- a/java/ghidra/Test.java +++ b/java/ghidra/Test.java @@ -3,21 +3,7 @@ // @importpackage org.sqlite import ghidra.app.script.GhidraScript; -import ghidra.program.model.address.Address; -import ghidra.program.model.data.DataType; -import ghidra.program.model.data.StandAloneDataTypeManager; -import re3lib.RecompileConfig; - -import java.io.File; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import re3lib.RemanConfig; // SQLite imports import java.sql.Connection; @@ -32,7 +18,7 @@ import org.sqlite.JDBC; public class Test extends GhidraScript { @Override public void run() throws Exception { - RecompileConfig.INSTANCE = new RecompileConfig(this); + RemanConfig.INSTANCE = new RemanConfig(this); java.sql.DriverManager.registerDriver(new JDBC()); @@ -41,7 +27,7 @@ public class Test extends GhidraScript { } private void testSQLite() throws Exception { - String dbPath = "jdbc:sqlite:" + RecompileConfig.INSTANCE.outputDir + "/functions.db"; + String dbPath = "jdbc:sqlite:" + RemanConfig.INSTANCE.outputDir + "/functions.db"; try (Connection conn = DriverManager.getConnection(dbPath)) { println("Connected to SQLite database: " + dbPath); diff --git a/java/ghidra/re3lib/FunctionDatabase.java b/java/ghidra/re3lib/FunctionDatabase.java index 99467ab6..262697a9 100644 --- a/java/ghidra/re3lib/FunctionDatabase.java +++ b/java/ghidra/re3lib/FunctionDatabase.java @@ -38,7 +38,7 @@ public class FunctionDatabase { private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { String addressString = (String) in.readObject(); if (addressString != null) { - address = RecompileConfig.INSTANCE.script.getCurrentProgram().getAddressFactory().getAddress(addressString); + address = RemanConfig.INSTANCE.script.getCurrentProgram().getAddressFactory().getAddress(addressString); } name = (String) in.readObject(); } @@ -63,7 +63,7 @@ public class FunctionDatabase { private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { String addressString = (String) in.readObject(); if (addressString != null) { - address = RecompileConfig.INSTANCE.script.getCurrentProgram().getAddressFactory().getAddress(addressString); + address = RemanConfig.INSTANCE.script.getCurrentProgram().getAddressFactory().getAddress(addressString); } name = (String) in.readObject(); String fileString = (String) in.readObject(); @@ -81,7 +81,7 @@ public class FunctionDatabase { public FunctionDatabase(GhidraScript script) { this.script = script; - file = new File(RecompileConfig.INSTANCE.outputDir, "functions.dat"); + file = new File(RemanConfig.INSTANCE.outputDir, "functions.dat"); } public void load() throws Exception { @@ -237,7 +237,7 @@ public class FunctionDatabase { if (madeAnyChanges) { // Update CMake timestamp - RecompileConfig.INSTANCE.touchCMakeTimestamp(); + RemanConfig.INSTANCE.touchCMakeTimestamp(); globalDumper.dumpGlobals(); globalDumper.saveGlobalManifest(); diff --git a/java/ghidra/re3lib/FunctionDumper.java b/java/ghidra/re3lib/FunctionDumper.java index 8277f1d2..89976256 100644 --- a/java/ghidra/re3lib/FunctionDumper.java +++ b/java/ghidra/re3lib/FunctionDumper.java @@ -58,7 +58,7 @@ public class FunctionDumper { } void initFunctionBlacklist() { - functionAddrBlackList = Utils.loadFunctionBlacklist(RecompileConfig.INSTANCE.functionBlacklistPath); + functionAddrBlackList = Utils.loadFunctionBlacklist(RemanConfig.INSTANCE.functionBlacklistPath); // Build blacklist if not loaded if (functionAddrBlackList == null) { @@ -99,7 +99,7 @@ public class FunctionDumper { } if (modified) { - Utils.saveFunctionBlacklist(functionAddrBlackList, RecompileConfig.INSTANCE.functionBlacklistPath); + Utils.saveFunctionBlacklist(functionAddrBlackList, RemanConfig.INSTANCE.functionBlacklistPath); } } } @@ -107,14 +107,14 @@ public class FunctionDumper { public static boolean isDumpedFix(Function function) { String sanitizedFunctionName = Utils.sanitizeIdentifier(function.getName()); String fileName = sanitizedFunctionName + ".cxx"; - File f0 = new File(RecompileConfig.INSTANCE.dirDecompFix, fileName); + File f0 = new File(RemanConfig.INSTANCE.dirDecompFix, fileName); return f0.exists(); } public static boolean isDumpedAuto(Function function) { String sanitizedFunctionName = Utils.sanitizeIdentifier(function.getName()); String fileName = sanitizedFunctionName + ".cxx"; - File f0 = new File(RecompileConfig.INSTANCE.dirDecompAuto, fileName); + File f0 = new File(RemanConfig.INSTANCE.dirDecompAuto, fileName); return f0.exists(); } @@ -124,19 +124,19 @@ public class FunctionDumper { String fileName = sanitizedFunctionName + ".cxx"; // Remove the stub file, since we now use the decompiled file - File stubFile = new File(RecompileConfig.INSTANCE.dirDecompStub, fileName); + File stubFile = new File(RemanConfig.INSTANCE.dirDecompStub, fileName); if (stubFile.exists()) { script.println("Removing function stub " + stubFile); stubFile.delete(); createdFile = true; } - File f0 = new File(RecompileConfig.INSTANCE.dirDecompFix, fileName); + File f0 = new File(RemanConfig.INSTANCE.dirDecompFix, fileName); if (f0.exists()) { script.println("Func " + function.getName() + " skipped (gh_fix)"); - f0 = new File(RecompileConfig.INSTANCE.dirDecompRef, fileName); + f0 = new File(RemanConfig.INSTANCE.dirDecompRef, fileName); } else { - f0 = new File(RecompileConfig.INSTANCE.dirDecompAuto, fileName); + f0 = new File(RemanConfig.INSTANCE.dirDecompAuto, fileName); if (f0.exists()) { f0.delete(); } else { @@ -148,7 +148,7 @@ public class FunctionDumper { List externalFunctionCalls = new ArrayList<>(); - DecompileResults decompRes = RecompileConfig.INSTANCE.decompCache.getOrInsert(function); + DecompileResults decompRes = RemanConfig.INSTANCE.decompCache.getOrInsert(function); try (PrintWriter writer2 = new PrintWriter(f0, "UTF-8")) { writer2.println("// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!! "); writer2.println(); @@ -291,15 +291,15 @@ public class FunctionDumper { for (Function externalFunction : externalFunctionCalls) { String sanitizedExtFunctionName = Utils.sanitizeIdentifier(externalFunction.getName()); fileName = sanitizedExtFunctionName + ".cxx"; - File f2 = new File(RecompileConfig.INSTANCE.dirDecompFix, fileName); - File f3 = new File(RecompileConfig.INSTANCE.dirDecompAuto, fileName); + File f2 = new File(RemanConfig.INSTANCE.dirDecompFix, fileName); + File f3 = new File(RemanConfig.INSTANCE.dirDecompAuto, fileName); if (f2.exists() || f3.exists()) { // script.println("Skipping external function: " + externalFunction.getName() + // " - " + externalFunction.getEntryPoint()); continue; } - File f4 = new File(RecompileConfig.INSTANCE.dirDecompStub, fileName); + File f4 = new File(RemanConfig.INSTANCE.dirDecompStub, fileName); script.println("Generating function stub for " + externalFunction.getName() + " => " + f4.toString()); try (PrintWriter writer2 = new PrintWriter(f4, "UTF-8")) { diff --git a/java/ghidra/re3lib/GlobalDumper.java b/java/ghidra/re3lib/GlobalDumper.java index 93528b9e..2a8ad130 100644 --- a/java/ghidra/re3lib/GlobalDumper.java +++ b/java/ghidra/re3lib/GlobalDumper.java @@ -25,7 +25,6 @@ import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataTypeManager; import ghidra.program.model.data.DataTypePath; import ghidra.program.model.data.PointerDataType; -import ghidra.program.model.data.Undefined; import ghidra.program.model.listing.Data; import ghidra.program.model.pcode.HighSymbol; import ghidra.program.model.symbol.SourceType; @@ -53,7 +52,7 @@ public class GlobalDumper { public GlobalDumper(GhidraScript script) { this.script = script; - manifestFile = new File(RecompileConfig.INSTANCE.outputDir, "globals.txt"); + manifestFile = new File(RemanConfig.INSTANCE.outputDir, "globals.txt"); } public void removeGlobalManifest() { @@ -108,8 +107,8 @@ public class GlobalDumper { } public void addGlobal(Address addr, HighSymbol sym) throws Exception { - if (addr.compareTo(RecompileConfig.INSTANCE.staticMemoryBlockStart) < 0 - || addr.compareTo(RecompileConfig.INSTANCE.staticMemoryBlockEnd) > 0) { + if (addr.compareTo(RemanConfig.INSTANCE.staticMemoryBlockStart) < 0 + || addr.compareTo(RemanConfig.INSTANCE.staticMemoryBlockEnd) > 0) { throw new Exception("Global address out of range: " + addr); } @@ -162,14 +161,14 @@ public class GlobalDumper { } public void dumpGlobals() throws Exception { - File globalSymbolsListH = new File(RecompileConfig.INSTANCE.outputDir, "gh_global.h"); + File globalSymbolsListH = new File(RemanConfig.INSTANCE.outputDir, "gh_global.h"); PrintWriter hwriter = new PrintWriter(globalSymbolsListH, "UTF-8"); hwriter.println("// AUTO-GENERATED FILE "); Utils.headerGuardPre(hwriter, "GLOBALS"); hwriter.println("#include "); hwriter.println(); - File globalSymbolsListC = new File(RecompileConfig.INSTANCE.outputDir, "gh_global.cxx"); + File globalSymbolsListC = new File(RemanConfig.INSTANCE.outputDir, "gh_global.cxx"); PrintWriter cwriter = new PrintWriter(globalSymbolsListC, "UTF-8"); cwriter.println("// AUTO-GENERATED FILE "); cwriter.println("#include "); diff --git a/java/ghidra/re3lib/PCallTracer.java b/java/ghidra/re3lib/PCallTracer.java index 99ef3fa8..817bd2b7 100644 --- a/java/ghidra/re3lib/PCallTracer.java +++ b/java/ghidra/re3lib/PCallTracer.java @@ -42,7 +42,7 @@ public class PCallTracer { Program program; public PCallTracer() { - this.script = RecompileConfig.INSTANCE.script; + this.script = RemanConfig.INSTANCE.script; this.program = this.script.getCurrentProgram(); // this.decomp = RecompileConfig.INSTANCE.decompCache; } diff --git a/java/ghidra/re3lib/RecompileConfig.java b/java/ghidra/re3lib/RemanConfig.java similarity index 92% rename from java/ghidra/re3lib/RecompileConfig.java rename to java/ghidra/re3lib/RemanConfig.java index 48e6e748..957901c6 100644 --- a/java/ghidra/re3lib/RecompileConfig.java +++ b/java/ghidra/re3lib/RemanConfig.java @@ -10,7 +10,9 @@ import ghidra.program.flatapi.FlatProgramAPI; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; -public class RecompileConfig { +// A general configuration for the reman project +// including all paths, specific addresses and stuff +public class RemanConfig { private static final String RECOMPILE_PREFIX = "game_re"; // Version control project root @@ -24,6 +26,9 @@ public class RecompileConfig { public final Address staticMemoryBlockStart; public final Address staticMemoryBlockEnd; + // The path to the database file + public final File databasePath; + // The automatically decompiled files public final File dirDecompAuto; // The manually decompiled files (will not be overwritten by the auto @@ -48,9 +53,9 @@ public class RecompileConfig { public final GhidraScript script; - public static RecompileConfig INSTANCE; + public static RemanConfig INSTANCE; - public RecompileConfig(GhidraScript script) { + public RemanConfig(GhidraScript script) { staticMemoryBlockStart = script.getCurrentProgram().getAddressFactory().getAddress("00597000"); staticMemoryBlockEnd = script.getCurrentProgram().getAddressFactory().getAddress("00843fff"); diff --git a/java/ghidra/re3lib/TypeDumper.java b/java/ghidra/re3lib/TypeDumper.java index c0593627..5ec63bbb 100644 --- a/java/ghidra/re3lib/TypeDumper.java +++ b/java/ghidra/re3lib/TypeDumper.java @@ -25,15 +25,15 @@ public class TypeDumper { public TypeDumper(GhidraScript script) { this.script = script; currentProgram = script.getCurrentProgram(); - RecompileConfig.INSTANCE = new RecompileConfig(script); + RemanConfig.INSTANCE = new RemanConfig(script); } public void run() throws Exception { ProgramBasedDataTypeManager dtm = currentProgram.getDataTypeManager(); - HashSet typeBlacklist = Utils.loadSimpleBlacklist(RecompileConfig.INSTANCE.typeBlacklistPath); + HashSet typeBlacklist = Utils.loadSimpleBlacklist(RemanConfig.INSTANCE.typeBlacklistPath); HashSet categoryPathBlacklist = Utils - .loadSimpleBlacklist(RecompileConfig.INSTANCE.categoryPathBlacklistPath); + .loadSimpleBlacklist(RemanConfig.INSTANCE.categoryPathBlacklistPath); if (typeBlacklist == null) { script.println("Building struct blacklist from existing data types"); @@ -45,7 +45,7 @@ public class TypeDumper { typeBlacklist.add(dt.getDisplayName()); } } - Utils.saveStructBlacklist(typeBlacklist, RecompileConfig.INSTANCE.typeBlacklistPath); + Utils.saveStructBlacklist(typeBlacklist, RemanConfig.INSTANCE.typeBlacklistPath); } List filteredTypes = new ArrayList<>(); @@ -92,7 +92,7 @@ public class TypeDumper { } } - try (PrintWriter writer = new PrintWriter(new File(RecompileConfig.INSTANCE.outputDir, "gh_types.h"), + try (PrintWriter writer = new PrintWriter(new File(RemanConfig.INSTANCE.outputDir, "gh_types.h"), "UTF-8")) { Utils.headerGuardPre(writer, "STRUCTS"); writer.println("// AUTO-GENERATED FILE "); diff --git a/java/ghidra/re3lib/Utils.java b/java/ghidra/re3lib/Utils.java index e22c1ef7..61bb8443 100644 --- a/java/ghidra/re3lib/Utils.java +++ b/java/ghidra/re3lib/Utils.java @@ -51,7 +51,7 @@ public class Utils { } public static HashSet
loadFunctionBlacklist(String path) { - GhidraScript script = RecompileConfig.INSTANCE.script; + GhidraScript script = RemanConfig.INSTANCE.script; HashSet
fnBlacklist = new HashSet<>(); File blacklistFile = new File(path); try (Scanner scanner = new Scanner(blacklistFile)) { @@ -60,7 +60,7 @@ public class Utils { // Strip comment String line1 = line.split("//")[0].trim(); // Deserialize address - Address addr = RecompileConfig.INSTANCE.currentProgram.getAddressFactory().getAddress(line1); + Address addr = RemanConfig.INSTANCE.currentProgram.getAddressFactory().getAddress(line1); fnBlacklist.add(addr); } script.println("Loaded blacklist with " + fnBlacklist.size() + " entries"); @@ -71,7 +71,7 @@ public class Utils { } public static void saveFunctionBlacklist(HashSet
fnBlacklist, String path) { - GhidraScript script = RecompileConfig.INSTANCE.script; + GhidraScript script = RemanConfig.INSTANCE.script; File blacklistFile = new File(path); try (PrintWriter writer = new PrintWriter(blacklistFile)) { for (Address addr : fnBlacklist) { diff --git a/java/ghidra/readme.md b/java/ghidra/readme.md index 18add8cc..5ea58ba3 100644 --- a/java/ghidra/readme.md +++ b/java/ghidra/readme.md @@ -11,3 +11,63 @@ The decompile database is a sqlite database that contains a list of all files th To generate the database from the current set of files, run the scan_sources script in the /game_re folder. Make sure you have set up the tooling by running the /tooling/setup script. + + +## IDE Notes + +This should work with the redhat java plugin for vscode, you however need to manually add the referenced libraries to the settings, like so: + +```json +{ + "java.project.referencedLibraries": [ + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\Base\\lib\\Base.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\Decompiler\\lib\\Decompiler.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\BSim\\lib\\BSim.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\BSimFeatureVisualizer\\lib\\BSimFeatureVisualizer.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\Base\\lib\\Base.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\BytePatterns\\lib\\BytePatterns.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\ByteViewer\\lib\\ByteViewer.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\CodeCompare\\lib\\CodeCompare.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\DebugUtils\\lib\\DebugUtils.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\Decompiler\\lib\\Decompiler.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\DecompilerDependent\\lib\\DecompilerDependent.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\FileFormats\\lib\\FileFormats.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\FunctionGraph\\lib\\FunctionGraph.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\FunctionGraphDecompilerExtension\\lib\\FunctionGraphDecompilerExtension.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\FunctionID\\lib\\FunctionID.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\GhidraGo\\lib\\GhidraGo.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\GhidraServer\\lib\\GhidraServer.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\GnuDemangler\\lib\\GnuDemangler.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\GraphFunctionCalls\\lib\\GraphFunctionCalls.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\GraphServices\\lib\\GraphServices.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\MicrosoftCodeAnalyzer\\lib\\MicrosoftCodeAnalyzer.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\MicrosoftDemangler\\lib\\MicrosoftDemangler.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\MicrosoftDmang\\lib\\MicrosoftDmang.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\PDB\\lib\\PDB.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\ProgramDiff\\lib\\ProgramDiff.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\ProgramGraph\\lib\\ProgramGraph.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\Python\\lib\\Python.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\Recognizers\\lib\\Recognizers.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\Sarif\\lib\\Sarif.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\SourceCodeLookup\\lib\\SourceCodeLookup.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\SwiftDemangler\\lib\\SwiftDemangler.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\SystemEmulation\\lib\\SystemEmulation.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\VersionTracking\\lib\\VersionTracking.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\VersionTrackingBSim\\lib\\VersionTrackingBSim.jar", + "C:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Features\\WildcardAssembler\\lib\\WildcardAssembler.jar", + "c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\DB\\lib\\DB.jar", + "c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Docking\\lib\\Docking.jar", + "c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Emulation\\lib\\Emulation.jar", + "c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\FileSystem\\lib\\FileSystem.jar", + "c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Generic\\lib\\Generic.jar", + "c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Graph\\lib\\Graph.jar", + "c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Gui\\lib\\Gui.jar", + "c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Help\\lib\\Help.jar", + "c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Project\\lib\\Project.jar", + "c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Pty\\lib\\Pty.jar", + "c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\SoftwareModeling\\lib\\SoftwareModeling.jar", + "c:\\Projects\\ghidra_11.3.2_PUBLIC\\Ghidra\\Framework\\Utility\\lib\\Utility.jar", + "c:\\Projects\\R3\\java\\ghidra\\sqlite-jdbc-3.49.1.0.jar" + ] +} +``` \ No newline at end of file