mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-26 16:59:37 +08:00
GP-3222: Adds ability to export/serve symbols & types as Volatility ISF
JSON
This commit is contained in:
@@ -1 +0,0 @@
|
||||
MODULE FILE LICENSE: lib/protobuf-java-3.21.8.jar BSD-3-GOOGLE
|
||||
|
||||
@@ -59,7 +59,6 @@ dependencies {
|
||||
}
|
||||
}
|
||||
|
||||
api 'com.google.protobuf:protobuf-java:3.21.8'
|
||||
api project(':Framework-AsyncComm')
|
||||
api project(':Framework-Debugging')
|
||||
api project(':ProposedUtils')
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
##VERSION: 2.0
|
||||
##MODULE IP: BSD-3-GOOGLE
|
||||
Module.manifest||GHIDRA||||END|
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
|
||||
apply from: "${rootProject.projectDir}/gradle/javaProject.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/jacocoProject.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/javaTestProject.gradle"
|
||||
apply from: "${rootProject.projectDir}/gradle/distributableGhidraModule.gradle"
|
||||
|
||||
apply plugin: 'eclipse'
|
||||
eclipse.project.name = 'Debug Debugger-isf'
|
||||
|
||||
configurations {
|
||||
allProtocArtifacts
|
||||
protocArtifact
|
||||
}
|
||||
|
||||
def platform = getCurrentPlatformName()
|
||||
|
||||
dependencies {
|
||||
allProtocArtifacts 'com.google.protobuf:protoc:3.21.8:windows-x86_64@exe'
|
||||
allProtocArtifacts 'com.google.protobuf:protoc:3.21.8:linux-x86_64@exe'
|
||||
allProtocArtifacts 'com.google.protobuf:protoc:3.21.8:linux-aarch_64@exe'
|
||||
allProtocArtifacts 'com.google.protobuf:protoc:3.21.8:osx-x86_64@exe'
|
||||
allProtocArtifacts 'com.google.protobuf:protoc:3.21.8:osx-aarch_64@exe'
|
||||
|
||||
if (isCurrentWindows()) {
|
||||
protocArtifact 'com.google.protobuf:protoc:3.21.8:windows-x86_64@exe'
|
||||
}
|
||||
if (isCurrentLinux()) {
|
||||
if (platform.endsWith("x86_64")) {
|
||||
protocArtifact 'com.google.protobuf:protoc:3.21.8:linux-x86_64@exe'
|
||||
}
|
||||
else {
|
||||
protocArtifact 'com.google.protobuf:protoc:3.21.8:linux-aarch_64@exe'
|
||||
}
|
||||
}
|
||||
if (isCurrentMac()) {
|
||||
if (platform.endsWith("x86_64")) {
|
||||
protocArtifact 'com.google.protobuf:protoc:3.21.8:osx-x86_64@exe'
|
||||
}
|
||||
else {
|
||||
protocArtifact 'com.google.protobuf:protoc:3.21.8:osx-aarch_64@exe'
|
||||
}
|
||||
}
|
||||
|
||||
api project(':Framework-AsyncComm')
|
||||
api project(':Framework-Debugging')
|
||||
api project(':ProposedUtils')
|
||||
|
||||
testImplementation project(path: ':Framework-AsyncComm', configuration: 'testArtifacts')
|
||||
testImplementation project(path: ':Framework-Debugging', configuration: 'testArtifacts')
|
||||
}
|
||||
|
||||
task generateProto {
|
||||
ext.srcdir = file("src/main/proto")
|
||||
ext.src = fileTree(srcdir) {
|
||||
include "**/*.proto"
|
||||
}
|
||||
ext.outdir = file("build/generated/source/proto/main/java")
|
||||
outputs.dir(outdir)
|
||||
inputs.files(src)
|
||||
dependsOn(configurations.protocArtifact)
|
||||
doLast {
|
||||
def exe = configurations.protocArtifact.first()
|
||||
if (!isCurrentWindows()) {
|
||||
exe.setExecutable(true)
|
||||
}
|
||||
exec {
|
||||
commandLine exe, "--java_out=$outdir", "-I$srcdir"
|
||||
args src
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.compileJava.dependsOn(tasks.generateProto)
|
||||
tasks.eclipse.dependsOn(tasks.generateProto)
|
||||
rootProject.tasks.prepDev.dependsOn(tasks.generateProto)
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDir tasks.generateProto.outdir
|
||||
}
|
||||
}
|
||||
}
|
||||
zipSourceSubproject.dependsOn generateProto
|
||||
|
||||
// Include buildable native source in distribution
|
||||
rootProject.assembleDistribution {
|
||||
from (this.project.projectDir.toString()) {
|
||||
include "runISFServer"
|
||||
into { getZipPath(this.project) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
##VERSION: 2.0
|
||||
Module.manifest||GHIDRA||||END|
|
||||
runISFServer||GHIDRA||||END|
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#------------------------------------
|
||||
# Ghidra headless ISF Server launch
|
||||
#------------------------------------
|
||||
|
||||
# Maximum heap memory may be changed if default is inadequate. This will generally be up to 1/4 of
|
||||
# the physical memory available to the OS. Uncomment MAXMEM setting if non-default value is needed.
|
||||
MAXMEM=2G
|
||||
|
||||
# Launch mode can be changed to one of the following: fg, debug, debug-suspend
|
||||
LAUNCH_MODE=fg
|
||||
|
||||
# Set the debug address to listen on.
|
||||
# NOTE: This variable is ignored if not launching in a debugging mode.
|
||||
DEBUG_ADDRESS=127.0.0.1:13002
|
||||
|
||||
# Limit the # of garbage collection and JIT compiler threads in case many headless
|
||||
# instances are run in parallel. By default, Java will assign one thread per core
|
||||
# which does not scale well on servers with many cores.
|
||||
VMARG_LIST="-XX:ParallelGCThreads=2 -XX:CICompilerCount=2 "
|
||||
|
||||
# Resolve symbolic link if present and get the directory this script lives in.
|
||||
# NOTE: "readlink -f" is best but works on Linux only, "readlink" will only work if your PWD
|
||||
# contains the link you are calling (which is the best we can do on macOS), and the "echo" is the
|
||||
# fallback, which doesn't attempt to do anything with links.
|
||||
SCRIPT_FILE="$(readlink -f "$0" 2>/dev/null || readlink "$0" 2>/dev/null || echo "$0")"
|
||||
SCRIPT_DIR="${SCRIPT_FILE%/*}"
|
||||
SUPPORT_DIR="${SCRIPT_DIR}/../../../support"
|
||||
if ! [ -f "${SUPPORT_DIR}/launch.properties" ]; then
|
||||
SUPPORT_DIR="${SCRIPT_DIR}/../../RuntimeScripts/Linux/support"
|
||||
fi
|
||||
|
||||
# Launch ISF Server.
|
||||
# DEBUG_ADDRESS set via environment for launch.sh
|
||||
DEBUG_ADDRESS=${DEBUG_ADDRESS} "${SUPPORT_DIR}"/launch.sh "${LAUNCH_MODE}" jdk Ghidra-ISF "${MAXMEM}" "${VMARG_LIST}" ghidra.dbg.isf.IsfServerLauncher "$@"
|
||||
+305
@@ -0,0 +1,305 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.app.plugin.core.datamgr.actions;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.MenuData;
|
||||
import docking.widgets.OptionDialog;
|
||||
import docking.widgets.filechooser.GhidraFileChooser;
|
||||
import docking.widgets.tree.GTree;
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import ghidra.app.plugin.core.datamgr.DataTypeManagerPlugin;
|
||||
import ghidra.app.plugin.core.datamgr.DataTypesActionContext;
|
||||
import ghidra.app.plugin.core.datamgr.tree.CategoryNode;
|
||||
import ghidra.app.plugin.core.datamgr.tree.DataTypeNode;
|
||||
import ghidra.framework.preferences.Preferences;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.ISF.IsfDataTypeWriter;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.classfinder.ClassSearcher;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.filechooser.ExtensionFileFilter;
|
||||
import ghidra.util.task.*;
|
||||
|
||||
// This action was originally referenced by DataTypeProvider::createLocalActions to support testing.
|
||||
// It may (?) be of general use at some point, but including it in the original location introduces
|
||||
// a dependency on this project, which seems undesirable right now.
|
||||
|
||||
public class ExportToIsfAction extends DockingAction {
|
||||
private static final String LAST_DATA_TYPE_EXPORT_DIRECTORY = "LAST_DATA_TYPE_EXPORT_DIRECTORY";
|
||||
|
||||
private final DataTypeManagerPlugin plugin;
|
||||
|
||||
public ExportToIsfAction(DataTypeManagerPlugin plugin) {
|
||||
super("Export Data Types (ISF)", plugin.getName());
|
||||
this.plugin = plugin;
|
||||
|
||||
setPopupMenuData(new MenuData(new String[] { "Export to ISF..." }, null, "VeryLast"));
|
||||
|
||||
setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
if (!(context instanceof DataTypesActionContext)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object contextObject = context.getContextObject();
|
||||
GTree gtree = (GTree) contextObject;
|
||||
TreePath[] selectionPaths = gtree.getSelectionPaths();
|
||||
for (TreePath path : selectionPaths) {
|
||||
GTreeNode node = (GTreeNode) path.getLastPathComponent();
|
||||
if (!isValidNode(node)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isValidNode(GTreeNode node) {
|
||||
if (node instanceof CategoryNode) {
|
||||
CategoryNode categoryNode = (CategoryNode) node;
|
||||
return categoryNode.isEnabled();
|
||||
}
|
||||
else if (node instanceof DataTypeNode) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
DataTypesActionContext dtActionContext = (DataTypesActionContext) context;
|
||||
GTree gTree = (GTree) dtActionContext.getContextObject();
|
||||
Program program = dtActionContext.getProgram();
|
||||
if (program == null) {
|
||||
Msg.showError(this, gTree, "Archive Export Failed",
|
||||
"A suitable program must be open and activated before\n" +
|
||||
"an archive export may be performed.");
|
||||
return;
|
||||
}
|
||||
if (OptionDialog.showYesNoDialog(gTree, "Confirm Archive Export",
|
||||
"Export selected archive(s) using program " + program.getName() +
|
||||
"'s compiler specification?") != OptionDialog.YES_OPTION) {
|
||||
return;
|
||||
}
|
||||
exportToIsf(gTree, program.getDataTypeManager());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the selection out to a file of the user's choosing. One file will be written for each
|
||||
* DataTypeManager in the selection.
|
||||
*
|
||||
* @param gTree The tree that contains the selected nodes.
|
||||
*/
|
||||
private void exportToIsf(GTree gTree, DataTypeManager programDataTypeMgr) {
|
||||
|
||||
List<Class<? extends AnnotationHandler>> classes =
|
||||
ClassSearcher.getClasses(AnnotationHandler.class);
|
||||
|
||||
List<AnnotationHandler> list = new ArrayList<>();
|
||||
Class<?>[] constructorArgumentTypes = {};
|
||||
for (Class<? extends AnnotationHandler> clazz : classes) {
|
||||
|
||||
if (clazz == DefaultAnnotationHandler.class) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
Constructor<?> constructor = clazz.getConstructor(constructorArgumentTypes);
|
||||
Object obj = constructor.newInstance();
|
||||
list.add(AnnotationHandler.class.cast(obj));
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.showError(this, plugin.getTool().getToolFrame(), "Export Data Types",
|
||||
"Error creating " + clazz.getName() + "\n" + e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
AnnotationHandler handler = null;
|
||||
if (!list.isEmpty()) {
|
||||
list.add(0, new DefaultAnnotationHandler());
|
||||
AnnotationHandlerDialog dlg = new AnnotationHandlerDialog(list);
|
||||
plugin.getTool().showDialog(dlg);
|
||||
if (!dlg.wasSuccessful()) {
|
||||
return;
|
||||
}
|
||||
handler = dlg.getHandler();
|
||||
}
|
||||
else {
|
||||
handler = new DefaultAnnotationHandler();
|
||||
}
|
||||
|
||||
TreePath[] paths = gTree.getSelectionPaths();
|
||||
Map<DataTypeManager, List<DataType>> managersToDataTypesMap = new HashMap<>();
|
||||
|
||||
for (TreePath path : paths) {
|
||||
addToManager(path, managersToDataTypesMap);
|
||||
}
|
||||
|
||||
GhidraFileChooser fileChooser = new GhidraFileChooser(gTree);
|
||||
|
||||
// filter the files if we can
|
||||
String[] fileExtensions = handler.getFileExtensions();
|
||||
if (fileExtensions.length > 0) {
|
||||
fileChooser.setFileFilter(
|
||||
new ExtensionFileFilter(fileExtensions, handler.getLanguageName() + " Files"));
|
||||
}
|
||||
|
||||
Set<Entry<DataTypeManager, List<DataType>>> entrySet = managersToDataTypesMap.entrySet();
|
||||
for (Entry<DataTypeManager, List<DataType>> entry : entrySet) {
|
||||
DataTypeManager dataTypeManager = entry.getKey();
|
||||
File file = getFile(gTree, fileChooser, dataTypeManager, handler);
|
||||
if (file == null) {
|
||||
return; // user cancelled
|
||||
}
|
||||
|
||||
List<DataType> dataTypeList = entry.getValue();
|
||||
new TaskLauncher(
|
||||
new DataTypeWriterTask(gTree, programDataTypeMgr, dataTypeList, file),
|
||||
gTree);
|
||||
}
|
||||
|
||||
fileChooser.dispose();
|
||||
}
|
||||
|
||||
private class DataTypeWriterTask extends Task {
|
||||
|
||||
private final DataTypeManager programDataTypeMgr;
|
||||
private final List<DataType> dataTypeList;
|
||||
private final File file;
|
||||
private final GTree gTree;
|
||||
|
||||
DataTypeWriterTask(GTree gTree, DataTypeManager programDataTypeMgr,
|
||||
List<DataType> dataTypeList, File file) {
|
||||
super("Export Data Types", true, false, true);
|
||||
this.gTree = gTree;
|
||||
this.programDataTypeMgr = programDataTypeMgr;
|
||||
this.dataTypeList = dataTypeList;
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(TaskMonitor monitor) {
|
||||
try {
|
||||
monitor.setMessage("Export to " + file.getName() + "...");
|
||||
IsfDataTypeWriter dataTypeWriter =
|
||||
new IsfDataTypeWriter(programDataTypeMgr, new FileWriter(file));
|
||||
|
||||
try {
|
||||
for (DataType dataType : dataTypeList) {
|
||||
dataTypeWriter.requestType(dataType);
|
||||
}
|
||||
JsonObject object = dataTypeWriter.getRootObject(monitor);
|
||||
dataTypeWriter.write(object);
|
||||
}
|
||||
finally {
|
||||
dataTypeWriter.close();
|
||||
}
|
||||
plugin.getTool()
|
||||
.setStatusInfo(
|
||||
"Successfully exported data type(s) to " + file.getAbsolutePath());
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// user cancelled; ignore
|
||||
}
|
||||
catch (IOException e) {
|
||||
Msg.showError(getClass(), gTree, "Export Data Types Failed",
|
||||
"Error exporting Data Types: " + e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addToManager(TreePath path,
|
||||
Map<DataTypeManager, List<DataType>> managersToDataTypesMap) {
|
||||
Object last = path.getLastPathComponent();
|
||||
if (last instanceof DataTypeNode) {
|
||||
DataTypeNode node = (DataTypeNode) last;
|
||||
DataType dataType = node.getDataType();
|
||||
DataTypeManager dataTypeManager = dataType.getDataTypeManager();
|
||||
|
||||
List<DataType> dataTypeList = managersToDataTypesMap.get(dataTypeManager);
|
||||
if (dataTypeList == null) {
|
||||
dataTypeList = new ArrayList<>();
|
||||
managersToDataTypesMap.put(dataTypeManager, dataTypeList);
|
||||
}
|
||||
|
||||
dataTypeList.add(dataType);
|
||||
}
|
||||
else if (last instanceof CategoryNode) {
|
||||
CategoryNode node = (CategoryNode) last;
|
||||
List<GTreeNode> children = node.getChildren();
|
||||
for (GTreeNode cnode : children) {
|
||||
addToManager(cnode.getTreePath(), managersToDataTypesMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private File getFile(GTree gTree, GhidraFileChooser fileChooser,
|
||||
DataTypeManager dataTypeManager, AnnotationHandler handler) {
|
||||
|
||||
fileChooser.setTitle("Select File For Export: " + dataTypeManager.getName());
|
||||
fileChooser.setSelectedFile(null);
|
||||
|
||||
String defaultExtendsionSuffix = ".json";
|
||||
|
||||
String lastDirSelected = Preferences.getProperty(LAST_DATA_TYPE_EXPORT_DIRECTORY);
|
||||
if (lastDirSelected != null) {
|
||||
File file = new File(lastDirSelected);
|
||||
if (file.exists()) {
|
||||
fileChooser.setCurrentDirectory(file);
|
||||
}
|
||||
}
|
||||
|
||||
fileChooser.rescanCurrentDirectory(); // pick up any recently added archives
|
||||
File currentDirectory = fileChooser.getCurrentDirectory();
|
||||
File newFile =
|
||||
new File(currentDirectory, dataTypeManager.getName() + defaultExtendsionSuffix);
|
||||
fileChooser.setSelectedFile(newFile);
|
||||
|
||||
// show the chooser
|
||||
File file = fileChooser.getSelectedFile();
|
||||
if (file == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (file.exists()) {
|
||||
if (OptionDialog.showYesNoDialog(gTree, "Overwrite Existing File?",
|
||||
"Do you want to overwrite the existing file \"" + file.getAbsolutePath() +
|
||||
"\"?") == OptionDialog.OPTION_TWO) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// save the directory off for the next export
|
||||
Preferences.setProperty(LAST_DATA_TYPE_EXPORT_DIRECTORY, file.getAbsolutePath());
|
||||
|
||||
return file;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.dbg.isf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import ghidra.async.AsyncUtils;
|
||||
import ghidra.dbg.isf.protocol.Isf;
|
||||
import ghidra.dbg.isf.protocol.Isf.ErrorCode;
|
||||
import ghidra.dbg.isf.protocol.Isf.RootMessage;
|
||||
import ghidra.program.model.data.DataTypeManager;
|
||||
import ghidra.program.model.data.ISF.IsfDataTypeWriter;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class IsfClientHandler {
|
||||
protected static final boolean LOG_ERROR_REPLY_STACKS = false;
|
||||
|
||||
protected final static AtomicInteger sequencer = new AtomicInteger();
|
||||
|
||||
protected static <T> T errorSendNotify(Throwable e) {
|
||||
Msg.error(IsfClientHandler.class, "Could not send notification: " + e);
|
||||
return null;
|
||||
}
|
||||
|
||||
private IsfServer server;
|
||||
|
||||
// Keeps strong references and tells level of subscription
|
||||
|
||||
public IsfClientHandler(IsfServer server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
protected Isf.RootMessage buildError(Isf.RootMessage req, ErrorCode code, String message) {
|
||||
return Isf.RootMessage.newBuilder()
|
||||
.setSequence(req.getSequence())
|
||||
.setErrorReply(Isf.ErrorReply.newBuilder().setCode(code).setMessage(message))
|
||||
.build();
|
||||
}
|
||||
|
||||
protected RootMessage replyError(Isf.RootMessage req, Throwable e) {
|
||||
Throwable t = AsyncUtils.unwrapThrowable(e);
|
||||
if (LOG_ERROR_REPLY_STACKS) {
|
||||
Msg.debug(this, "Error caused by request " + req, e);
|
||||
}
|
||||
else {
|
||||
Msg.debug(this, "Error caused by request " + req + ": " + e);
|
||||
}
|
||||
if (t instanceof UnsupportedOperationException) {
|
||||
return buildError(req, ErrorCode.EC_NOT_SUPPORTED, t.getMessage());
|
||||
}
|
||||
return buildError(req, ErrorCode.EC_UNKNOWN, "Unknown server-side error");
|
||||
}
|
||||
|
||||
protected String getVersion() {
|
||||
return "V1";
|
||||
}
|
||||
|
||||
protected RootMessage processMessage(Isf.RootMessage msg) throws IOException {
|
||||
switch (msg.getMsgCase()) {
|
||||
case PING_REQUEST:
|
||||
return processPing(msg.getSequence(), msg.getPingRequest());
|
||||
case FULL_EXPORT_REQUEST:
|
||||
return processFullExport(msg.getSequence(), msg.getFullExportRequest());
|
||||
case LOOK_TYPE_REQUEST:
|
||||
return processLookType(msg.getSequence(), msg.getLookTypeRequest());
|
||||
case LOOK_SYMBOL_REQUEST:
|
||||
return processLookSym(msg.getSequence(), msg.getLookSymbolRequest());
|
||||
case LOOK_ADDRESS_REQUEST:
|
||||
return processLookAddr(msg.getSequence(), msg.getLookAddressRequest());
|
||||
case ENUM_TYPES_REQUEST:
|
||||
return processEnumTypes(msg.getSequence(), msg.getEnumTypesRequest());
|
||||
case ENUM_SYMBOLS_REQUEST:
|
||||
return processEnumSyms(msg.getSequence(), msg.getEnumSymbolsRequest());
|
||||
default:
|
||||
throw new IsfErrorException(Isf.ErrorCode.EC_BAD_REQUEST,
|
||||
"Unrecognized request: " + msg.getMsgCase());
|
||||
}
|
||||
}
|
||||
|
||||
protected RootMessage processPing(int seqno, Isf.PingRequest req) {
|
||||
return Isf.RootMessage.newBuilder()
|
||||
.setSequence(seqno)
|
||||
.setPingReply(Isf.PingReply.newBuilder().setContent(req.getContent()))
|
||||
.build();
|
||||
}
|
||||
|
||||
protected RootMessage processFullExport(int seqno, Isf.FullExportRequest req)
|
||||
throws IOException {
|
||||
String data = fullExport(req.getNs());
|
||||
return Isf.RootMessage.newBuilder()
|
||||
.setSequence(seqno)
|
||||
.setFullExportReply(Isf.FullExportReply.newBuilder()
|
||||
.setValue(data))
|
||||
.build();
|
||||
}
|
||||
|
||||
private String fullExport(String ns) throws IOException {
|
||||
IsfDataTypeWriter isfWriter = createDataTypeWriter(server.getDataTypeManager(ns));
|
||||
return writeFrom(isfWriter);
|
||||
}
|
||||
|
||||
protected RootMessage processLookType(int seqno, Isf.LookTypeRequest req) throws IOException {
|
||||
String data = lookType(req.getNs(), req.getKey());
|
||||
return Isf.RootMessage.newBuilder()
|
||||
.setSequence(seqno)
|
||||
.setLookTypeReply(Isf.LookTypeReply.newBuilder()
|
||||
.setValue(data))
|
||||
.build();
|
||||
}
|
||||
|
||||
private String lookType(String ns, String key) throws IOException {
|
||||
IsfDataTypeWriter isfWriter = createDataTypeWriter(server.getDataTypeManager(ns));
|
||||
isfWriter.setSkipSymbols(true);
|
||||
isfWriter.requestType(key);
|
||||
return writeFrom(isfWriter);
|
||||
}
|
||||
|
||||
protected RootMessage processLookSym(int seqno, Isf.LookSymRequest req) throws IOException {
|
||||
String data = lookSym(req.getNs(), req.getKey());
|
||||
return Isf.RootMessage.newBuilder()
|
||||
.setSequence(seqno)
|
||||
.setLookSymbolReply(Isf.LookSymReply.newBuilder()
|
||||
.setValue(data))
|
||||
.build();
|
||||
}
|
||||
|
||||
private String lookSym(String ns, String key) throws IOException {
|
||||
IsfDataTypeWriter isfWriter = createDataTypeWriter(server.getDataTypeManager(ns));
|
||||
isfWriter.setSkipTypes(true);
|
||||
isfWriter.requestSymbol(key);
|
||||
return writeFrom(isfWriter);
|
||||
}
|
||||
|
||||
protected RootMessage processLookAddr(int seqno, Isf.LookAddrRequest req) throws IOException {
|
||||
String data = lookAddr(req.getNs(), req.getKey());
|
||||
return Isf.RootMessage.newBuilder()
|
||||
.setSequence(seqno)
|
||||
.setLookAddressReply(Isf.LookAddrReply.newBuilder()
|
||||
.setValue(data))
|
||||
.build();
|
||||
}
|
||||
|
||||
private String lookAddr(String ns, String key) throws IOException {
|
||||
IsfDataTypeWriter isfWriter = createDataTypeWriter(server.getDataTypeManager(ns));
|
||||
isfWriter.setSkipTypes(true);
|
||||
isfWriter.requestAddress(key);
|
||||
return writeFrom(isfWriter);
|
||||
}
|
||||
|
||||
protected RootMessage processEnumTypes(int seqno, Isf.EnumTypesRequest req) throws IOException {
|
||||
String data = enumTypes(req.getNs());
|
||||
return Isf.RootMessage.newBuilder()
|
||||
.setSequence(seqno)
|
||||
.setEnumTypesReply(Isf.EnumTypesReply.newBuilder()
|
||||
.setValue(data))
|
||||
.build();
|
||||
}
|
||||
|
||||
private String enumTypes(String ns) throws IOException {
|
||||
IsfDataTypeWriter isfWriter = createDataTypeWriter(server.getDataTypeManager(ns));
|
||||
isfWriter.setSkipSymbols(true);
|
||||
return writeFrom(isfWriter);
|
||||
}
|
||||
|
||||
protected RootMessage processEnumSyms(int seqno, Isf.EnumSymsRequest req) throws IOException {
|
||||
String data = enumSyms(req.getNs());
|
||||
return Isf.RootMessage.newBuilder()
|
||||
.setSequence(seqno)
|
||||
.setEnumSymbolsReply(Isf.EnumSymsReply.newBuilder()
|
||||
.setValue(data))
|
||||
.build();
|
||||
}
|
||||
|
||||
private String enumSyms(String ns) throws IOException {
|
||||
IsfDataTypeWriter isfWriter = createDataTypeWriter(server.getDataTypeManager(ns));
|
||||
isfWriter.setSkipTypes(true);
|
||||
return writeFrom(isfWriter);
|
||||
}
|
||||
|
||||
private IsfDataTypeWriter createDataTypeWriter(DataTypeManager dtm) throws IOException {
|
||||
StringWriter out = new StringWriter();
|
||||
return new IsfDataTypeWriter(dtm, out);
|
||||
}
|
||||
|
||||
private String writeFrom(IsfDataTypeWriter dataTypeWriter) throws IOException {
|
||||
try {
|
||||
JsonObject object =
|
||||
dataTypeWriter.getRootObject(TaskMonitor.DUMMY);
|
||||
dataTypeWriter.write(object);
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// NOTHING
|
||||
}
|
||||
finally {
|
||||
dataTypeWriter.close();
|
||||
}
|
||||
return dataTypeWriter.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.dbg.isf;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.Socket;
|
||||
|
||||
import com.google.protobuf.AbstractMessage;
|
||||
|
||||
import ghidra.dbg.isf.protocol.Isf.RootMessage;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
public class IsfConnectionHandler extends Thread {
|
||||
|
||||
private Socket socket;
|
||||
private IsfClientHandler handler;
|
||||
|
||||
public IsfConnectionHandler(Socket socket, IsfClientHandler handler) {
|
||||
this.socket = socket;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Msg.info(this, "Handler started...");
|
||||
InputStream inputStream = socket.getInputStream();
|
||||
while (!socket.isClosed()) {
|
||||
RootMessage root = RootMessage.parseDelimitedFrom(inputStream);
|
||||
if (root != null) {
|
||||
AbstractMessage msg = handler.processMessage(root);
|
||||
OutputStream out = socket.getOutputStream();
|
||||
msg.writeDelimitedTo(out);
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
Msg.error(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.dbg.isf;
|
||||
|
||||
import ghidra.dbg.isf.protocol.Isf.ErrorCode;
|
||||
|
||||
public class IsfErrorException extends RuntimeException {
|
||||
private ErrorCode code;
|
||||
|
||||
public IsfErrorException(ErrorCode code, String message) {
|
||||
super(code + ": " + message);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public ErrorCode getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.dbg.isf;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import db.DBConstants;
|
||||
import db.DBHandle;
|
||||
import generic.test.AbstractGTest;
|
||||
import ghidra.GhidraApplicationLayout;
|
||||
import ghidra.GhidraTestApplicationLayout;
|
||||
import ghidra.base.project.GhidraProject;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.GhidraApplicationConfiguration;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.framework.model.ProjectData;
|
||||
import ghidra.framework.store.db.PackedDatabase;
|
||||
import ghidra.program.database.ProgramDB;
|
||||
import ghidra.program.model.data.DataTypeManager;
|
||||
import ghidra.program.model.data.FileDataTypeManager;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.VersionException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class IsfServer extends Thread {
|
||||
private ServerSocket server;
|
||||
|
||||
private boolean running = false;
|
||||
private GhidraProject project;
|
||||
private int port = 54321;
|
||||
private IsfClientHandler handler;
|
||||
|
||||
private Map<String, DataTypeManager> managers = new HashMap<>();
|
||||
|
||||
public IsfServer(GhidraProject project, int port) {
|
||||
this.project = project;
|
||||
this.port = port;
|
||||
handler = new IsfClientHandler(this);
|
||||
}
|
||||
|
||||
public void startServer() {
|
||||
try {
|
||||
server = new ServerSocket(port);
|
||||
this.start();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException("Could not start server");
|
||||
}
|
||||
}
|
||||
|
||||
public void stopServer() {
|
||||
running = false;
|
||||
this.interrupt();
|
||||
for (DataTypeManager m : managers.values()) {
|
||||
m.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
running = true;
|
||||
while (running) {
|
||||
try {
|
||||
Msg.info(this, "Listening for a connection...");
|
||||
|
||||
Socket socket = server.accept();
|
||||
socket.setTcpNoDelay(true);
|
||||
|
||||
Msg.info(this, "Connected - starting handler...");
|
||||
IsfConnectionHandler connectionHandler = new IsfConnectionHandler(socket, handler);
|
||||
connectionHandler.start();
|
||||
}
|
||||
catch (IOException e) {
|
||||
Msg.error(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DataTypeManager getDataTypeManager(String ns) {
|
||||
synchronized (managers) {
|
||||
if (managers.containsKey(ns)) {
|
||||
return managers.get(ns);
|
||||
}
|
||||
try {
|
||||
DataTypeManager dtm;
|
||||
if (ns.endsWith(".gdt")) {
|
||||
dtm = openAsArchive(ns);
|
||||
}
|
||||
else if (ns.endsWith(".gzf")) {
|
||||
dtm = openAsDatabase(ns);
|
||||
}
|
||||
else {
|
||||
dtm = openAsDomainFile(ns);
|
||||
}
|
||||
managers.put(ns, dtm);
|
||||
return dtm;
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.error(this, ns + " undefined namespace (should be .gdt, .gzf, or domain file)");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DataTypeManager openAsDomainFile(String ns) throws Exception {
|
||||
ProjectData projectData = project.getProjectData();
|
||||
DomainFile df = projectData.getFile(ns);
|
||||
Program program = (Program) df.getDomainObject(this, false, false, TaskMonitor.DUMMY);
|
||||
return program.getDataTypeManager();
|
||||
}
|
||||
|
||||
private DataTypeManager openAsArchive(String ns) throws Exception {
|
||||
File gdt = new File(ns);
|
||||
return FileDataTypeManager.openFileArchive(gdt, false);
|
||||
}
|
||||
|
||||
private DataTypeManager openAsDatabase(String ns) throws Exception {
|
||||
File gzf = new File(ns);
|
||||
TaskMonitor dummy = TaskMonitor.DUMMY;
|
||||
PackedDatabase db = PackedDatabase.getPackedDatabase(gzf, dummy);
|
||||
DBHandle dbh = db.openForUpdate(dummy);
|
||||
ProgramDB p = null;
|
||||
try {
|
||||
p = new ProgramDB(dbh, DBConstants.UPDATE, dummy, this);
|
||||
}
|
||||
catch (VersionException e) {
|
||||
if (!e.isUpgradable()) {
|
||||
throw new RuntimeException(p + " uses an older version and is not upgradable.");
|
||||
}
|
||||
}
|
||||
finally {
|
||||
dbh.close();
|
||||
}
|
||||
|
||||
dbh = db.openForUpdate(dummy);
|
||||
p = new ProgramDB(dbh, DBConstants.UPGRADE, dummy, this);
|
||||
|
||||
if (!p.isChanged()) {
|
||||
throw new RuntimeException(p + " uses an older version and was not upgraded.");
|
||||
}
|
||||
|
||||
return p.getListing().getDataTypeManager();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws FileNotFoundException, IOException {
|
||||
GhidraApplicationLayout layout = new GhidraTestApplicationLayout(
|
||||
new File(AbstractGTest.getTestDirectoryPath()));
|
||||
GhidraApplicationConfiguration config = new GhidraApplicationConfiguration();
|
||||
config.setShowSplashScreen(false);
|
||||
Application.initializeApplication(layout, config);
|
||||
|
||||
IsfServer server = new IsfServer(null, 54321);
|
||||
server.startServer();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.dbg.isf;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.GhidraApplicationLayout;
|
||||
import ghidra.GhidraLaunchable;
|
||||
import ghidra.base.project.GhidraProject;
|
||||
import ghidra.framework.*;
|
||||
import ghidra.framework.model.ProjectLocator;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
// To be run using runISFServer
|
||||
|
||||
public class IsfServerLauncher implements GhidraLaunchable {
|
||||
|
||||
private GhidraProject project = null;
|
||||
private IsfServer server;
|
||||
private int port;
|
||||
|
||||
@Override
|
||||
public void launch(GhidraApplicationLayout layout, String[] args) throws Exception {
|
||||
|
||||
ApplicationConfiguration config = new HeadlessGhidraApplicationConfiguration();
|
||||
if (!Application.isInitialized()) {
|
||||
Application.initializeApplication(layout, config);
|
||||
}
|
||||
|
||||
GhidraProject proj = parseArgs(args);
|
||||
server = new IsfServer(proj, port);
|
||||
server.startServer();
|
||||
}
|
||||
|
||||
GhidraProject parseArgs(String[] args) throws IOException {
|
||||
if (args != null && args.length < 1) {
|
||||
usage();
|
||||
return null;
|
||||
}
|
||||
port = Integer.parseInt(args[0]);
|
||||
if (args.length > 1) {
|
||||
String projectLocation = args[1];
|
||||
String projectName = args[2];
|
||||
|
||||
File dir = new File(projectLocation);
|
||||
if (dir.exists()) {
|
||||
ProjectLocator locator = new ProjectLocator(dir.getAbsolutePath(), projectName);
|
||||
|
||||
if (locator.getProjectDir().exists()) {
|
||||
project = GhidraProject.openProject(projectLocation, projectName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return project;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
server.stopServer();
|
||||
if (project != null) {
|
||||
project.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void usage() {
|
||||
Msg.error(this, "Usage: runISFServer <port> <project_location> <project_name> ");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import ghidra.program.model.data.BuiltInDataType;
|
||||
|
||||
public class IsfBuiltIn implements IsfObject {
|
||||
|
||||
public Integer size;
|
||||
public Boolean signed;
|
||||
public String kind;
|
||||
public String endian;
|
||||
|
||||
public IsfBuiltIn(BuiltInDataType builtin) {
|
||||
size = IsfUtilities.getLength(builtin);
|
||||
signed = IsfUtilities.getSigned(builtin);
|
||||
kind = IsfUtilities.getBuiltInKind(builtin);
|
||||
endian = IsfUtilities.getEndianness(builtin);
|
||||
}
|
||||
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import ghidra.program.model.data.DataTypeComponent;
|
||||
import ghidra.program.model.data.ISF.IsfDataTypeWriter.Exclude;
|
||||
|
||||
public class IsfComponent implements IsfObject {
|
||||
|
||||
public Integer offset;
|
||||
public IsfObject type;
|
||||
|
||||
@Exclude
|
||||
public int ordinal;
|
||||
@Exclude
|
||||
public int length;
|
||||
@Exclude
|
||||
public String field_name;
|
||||
@Exclude
|
||||
public String comment;
|
||||
|
||||
public IsfComponent(DataTypeComponent component, IsfObject typeObj) {
|
||||
offset = component.getOffset();
|
||||
type = typeObj;
|
||||
|
||||
field_name = component.getFieldName();
|
||||
ordinal = component.getOrdinal();
|
||||
length = component.getLength();
|
||||
comment = component.getComment();
|
||||
}
|
||||
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.ISF.IsfDataTypeWriter.Exclude;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class IsfComposite implements IsfObject {
|
||||
|
||||
public String kind;
|
||||
public Integer size;
|
||||
public JsonObject fields;
|
||||
|
||||
@Exclude
|
||||
public int alignment;
|
||||
|
||||
public IsfComposite(Composite composite, IsfDataTypeWriter writer, TaskMonitor monitor) {
|
||||
size = composite.getLength();
|
||||
kind = composite instanceof Structure ? "struct" : "union";
|
||||
alignment = composite.getAlignment();
|
||||
|
||||
DataTypeComponent[] components = composite.getComponents();
|
||||
Map<String, DataTypeComponent> comps = new HashMap<>();
|
||||
for (DataTypeComponent component : components) {
|
||||
String key = component.getFieldName();
|
||||
if (key == null) {
|
||||
key = component.getDefaultFieldName();
|
||||
}
|
||||
comps.put(key, component);
|
||||
}
|
||||
ArrayList<String> keylist = new ArrayList<>(comps.keySet());
|
||||
Collections.sort(keylist);
|
||||
|
||||
fields = new JsonObject();
|
||||
for (String key : keylist) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
|
||||
DataTypeComponent component = comps.get(key);
|
||||
IsfObject type = writer.getObjectTypeDeclaration(component);
|
||||
IsfComponent cobj = new IsfComponent(component, type);
|
||||
fields.add(key, writer.getTree(cobj));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import ghidra.program.model.data.Array;
|
||||
|
||||
public class IsfDataTypeArray implements IsfObject {
|
||||
|
||||
public String kind;
|
||||
public Integer count;
|
||||
public IsfObject subtype;
|
||||
|
||||
public IsfDataTypeArray(Array arr, IsfObject typeObj) {
|
||||
kind = IsfUtilities.getKind(arr);
|
||||
count = arr.getNumElements();
|
||||
subtype = typeObj;
|
||||
}
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import ghidra.program.model.data.BitFieldDataType;
|
||||
import ghidra.program.model.data.ISF.IsfDataTypeWriter.Exclude;
|
||||
|
||||
public class IsfDataTypeBitField implements IsfObject {
|
||||
|
||||
public String kind;
|
||||
public Integer bit_length;
|
||||
public Integer bit_position;
|
||||
public IsfObject type;
|
||||
|
||||
@Exclude
|
||||
public Integer bit_offset;
|
||||
@Exclude
|
||||
private int storage_size;
|
||||
|
||||
public IsfDataTypeBitField(BitFieldDataType bf, int componentOffset, IsfObject typeObj) {
|
||||
kind = IsfUtilities.getKind(bf);
|
||||
bit_length = bf.getBitSize();
|
||||
bit_offset = bf.getBitOffset();
|
||||
bit_position = componentOffset % 4 * 8 + bit_offset;
|
||||
type = typeObj;
|
||||
|
||||
storage_size = bf.getStorageSize();
|
||||
}
|
||||
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import ghidra.program.model.data.DataType;
|
||||
|
||||
public class IsfDataTypeDefault implements IsfObject {
|
||||
|
||||
public String kind;
|
||||
public String name;
|
||||
|
||||
public IsfDataTypeDefault(DataType dt) {
|
||||
kind = IsfUtilities.getKind(dt);
|
||||
name = dt.getName();
|
||||
}
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
public class IsfDataTypeNull implements IsfObject {
|
||||
|
||||
public String kind;
|
||||
public String name;
|
||||
|
||||
public IsfDataTypeNull() {
|
||||
kind = "base";
|
||||
name = "void";
|
||||
}
|
||||
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import ghidra.program.model.data.DataType;
|
||||
|
||||
public class IsfDataTypeTypeDef implements IsfObject {
|
||||
|
||||
public String kind;
|
||||
public IsfObject subtype;
|
||||
|
||||
public IsfDataTypeTypeDef(DataType dt, IsfObject typeObj) {
|
||||
kind = IsfUtilities.getKind(dt);
|
||||
subtype = typeObj;
|
||||
}
|
||||
|
||||
}
|
||||
+629
File diff suppressed because it is too large
Load Diff
+32
@@ -0,0 +1,32 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import ghidra.program.model.data.Dynamic;
|
||||
|
||||
public class IsfDynamicComponent implements IsfObject {
|
||||
|
||||
public String kind;
|
||||
public Integer count;
|
||||
public IsfObject subtype;
|
||||
|
||||
public IsfDynamicComponent(Dynamic dynamicType, IsfObject type, int elementCnt) {
|
||||
kind = "array";
|
||||
subtype = type;
|
||||
count = elementCnt;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import ghidra.program.model.data.Enum;
|
||||
|
||||
public class IsfEnum implements IsfObject {
|
||||
|
||||
public Integer size;
|
||||
public String base;
|
||||
public JsonObject constants = new JsonObject();
|
||||
|
||||
public IsfEnum(Enum enumm) {
|
||||
size = enumm.getLength();
|
||||
base = "int";
|
||||
String[] names = enumm.getNames();
|
||||
for (int j = 0; j < names.length; j++) {
|
||||
constants.addProperty(names[j], enumm.getValue(names[j]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
public class IsfFunction implements IsfObject {
|
||||
|
||||
public String kind;
|
||||
|
||||
public IsfFunction() {
|
||||
kind = "function";
|
||||
}
|
||||
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.FunctionDefinition;
|
||||
|
||||
public class IsfFunctionPointer implements IsfObject {
|
||||
|
||||
public String kind;
|
||||
public IsfObject subtype;
|
||||
|
||||
public IsfFunctionPointer(FunctionDefinition def, DataType dt) {
|
||||
kind = "pointer";
|
||||
subtype = new IsfFunction();
|
||||
//TODO?
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
|
||||
public class IsfLinuxOS implements IsfObject {
|
||||
|
||||
public JsonArray symbols = new JsonArray();
|
||||
public JsonArray types = new JsonArray();
|
||||
|
||||
public IsfLinuxOS(Gson gson, Map<String, String> metaData) {
|
||||
IsfLinuxProgram pgm = new IsfLinuxProgram(metaData);
|
||||
symbols.add(gson.toJsonTree(pgm));
|
||||
types.add(gson.toJsonTree(pgm));
|
||||
}
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class IsfLinuxProgram implements IsfObject {
|
||||
|
||||
public String kind;
|
||||
public String name;
|
||||
public String hash_type;
|
||||
public String hash_value;
|
||||
|
||||
public IsfLinuxProgram(Map<String, String> metaData) {
|
||||
kind = "dwarf";
|
||||
name = metaData.get("Program Name");
|
||||
hash_type = "sha256";
|
||||
hash_value = metaData.get("Executable SHA256");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
public interface IsfObject {
|
||||
|
||||
// EMPTY by design
|
||||
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import ghidra.program.model.listing.Program;
|
||||
|
||||
public class IsfProducer implements IsfObject {
|
||||
|
||||
public String datetime;
|
||||
public String name;
|
||||
public String version;
|
||||
|
||||
public IsfProducer(Program program) {
|
||||
Map<String, String> metaData = program.getMetadata();
|
||||
Date creationDate = program.getCreationDate();
|
||||
SimpleDateFormat dataFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS");
|
||||
|
||||
datetime = dataFormat.format(creationDate);
|
||||
name = "Ghidra";
|
||||
version = metaData.get(Program.CREATED_WITH_GHIDRA_VERSION);
|
||||
}
|
||||
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import ghidra.program.model.data.DataType;
|
||||
|
||||
public class IsfTypedObject implements IsfObject {
|
||||
|
||||
public String kind;
|
||||
public Integer size;
|
||||
public IsfObject type;
|
||||
|
||||
public IsfTypedObject(DataType dt, IsfObject typeObj) {
|
||||
kind = IsfUtilities.getKind(dt);
|
||||
size = dt.getLength();
|
||||
type = typeObj;
|
||||
}
|
||||
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import ghidra.program.model.data.BuiltInDataType;
|
||||
import ghidra.program.model.data.TypeDef;
|
||||
|
||||
public class IsfTypedefBase implements IsfObject {
|
||||
|
||||
public Integer size;
|
||||
public String kind;
|
||||
public Boolean signed;
|
||||
public String endian;
|
||||
|
||||
public IsfTypedefBase(TypeDef typeDef) {
|
||||
BuiltInDataType builtin = (BuiltInDataType) typeDef.getBaseDataType();
|
||||
size = typeDef.getLength();
|
||||
kind = IsfUtilities.getBuiltInKind(builtin);
|
||||
signed = IsfUtilities.getSigned(typeDef);
|
||||
endian = IsfUtilities.getEndianness(typeDef);
|
||||
}
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import ghidra.program.model.data.TypeDef;
|
||||
|
||||
public class IsfTypedefIntegral implements IsfObject {
|
||||
|
||||
public Integer size;
|
||||
|
||||
public IsfTypedefIntegral(TypeDef td) {
|
||||
size = td.getLength();
|
||||
}
|
||||
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import ghidra.program.model.data.PointerDataType;
|
||||
|
||||
public class IsfTypedefPointer implements IsfObject {
|
||||
|
||||
public Integer size;
|
||||
public Boolean signed;
|
||||
public String kind;
|
||||
public String endian;
|
||||
|
||||
public IsfTypedefPointer() {
|
||||
PointerDataType ptr = new PointerDataType();
|
||||
size = ptr.getLength();
|
||||
signed = false; //IsfUtilities.getSigned(ptr);
|
||||
kind = IsfUtilities.getBuiltInKind(ptr);
|
||||
endian = IsfUtilities.getEndianness(ptr);
|
||||
}
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.TypeDef;
|
||||
|
||||
public class IsfTypedefUser implements IsfObject {
|
||||
|
||||
public Integer size;
|
||||
public String kind;
|
||||
public IsfObject type;
|
||||
|
||||
public IsfTypedefUser(TypeDef typeDef, IsfObject typeObj) {
|
||||
DataType baseType = typeDef.getBaseDataType();
|
||||
size = typeDef.getLength();
|
||||
kind = IsfUtilities.getKind(baseType);
|
||||
type = typeObj;
|
||||
}
|
||||
|
||||
}
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.Enum;
|
||||
|
||||
public class IsfUtilities {
|
||||
|
||||
// list of Ghidra built-in type names which correspond to C primitive types
|
||||
private static String[] INTEGRAL_TYPES = { "char", "short", "int", "long", "long long",
|
||||
"__int64", "float", "double", "long double", "void" };
|
||||
|
||||
private static String[] INTEGRAL_MODIFIERS =
|
||||
{ "signed", "unsigned", "const", "static", "volatile", "mutable", };
|
||||
|
||||
public static boolean isIntegral(String typedefName, String basetypeName) {
|
||||
for (String type : INTEGRAL_TYPES) {
|
||||
if (typedefName.equals(type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
boolean endsWithIntegralType = false;
|
||||
for (String type : INTEGRAL_TYPES) {
|
||||
if (typedefName.endsWith(" " + type)) {
|
||||
endsWithIntegralType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
boolean containsIntegralModifier = false;
|
||||
for (String modifier : INTEGRAL_MODIFIERS) {
|
||||
if (typedefName.indexOf(modifier + " ") >= 0 ||
|
||||
typedefName.indexOf(" " + modifier) >= 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (endsWithIntegralType && containsIntegralModifier) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typedefName.endsWith(" " + basetypeName)) {
|
||||
return containsIntegralModifier;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static DataType getBaseDataType(DataType dt) {
|
||||
while (dt != null) {
|
||||
if (dt instanceof Array) {
|
||||
Array array = (Array) dt;
|
||||
dt = array.getDataType();
|
||||
}
|
||||
else if (dt instanceof Pointer) {
|
||||
Pointer pointer = (Pointer) dt;
|
||||
dt = pointer.getDataType();
|
||||
}
|
||||
else if (dt instanceof BitFieldDataType) {
|
||||
BitFieldDataType bitfieldDt = (BitFieldDataType) dt;
|
||||
dt = bitfieldDt.getBaseDataType();
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
|
||||
public static DataType getArrayBaseType(Array arrayDt) {
|
||||
DataType dataType = arrayDt.getDataType();
|
||||
while (dataType instanceof Array) {
|
||||
dataType = ((Array) dataType).getDataType();
|
||||
}
|
||||
return dataType;
|
||||
}
|
||||
|
||||
public static DataType getPointerBaseDataType(Pointer p) {
|
||||
DataType dt = p.getDataType();
|
||||
while (dt instanceof Pointer) {
|
||||
dt = ((Pointer) dt).getDataType();
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
|
||||
public static String getKind(DataType dt) {
|
||||
if (dt instanceof Array) {
|
||||
return "array";
|
||||
}
|
||||
if (dt instanceof Structure) {
|
||||
return "struct";
|
||||
}
|
||||
if (dt instanceof Union) {
|
||||
return "union";
|
||||
}
|
||||
if (dt instanceof BuiltInDataType) {
|
||||
return "base";
|
||||
}
|
||||
if (dt instanceof Pointer) {
|
||||
return "pointer";
|
||||
}
|
||||
if (dt instanceof Enum) {
|
||||
return "enum";
|
||||
}
|
||||
if (dt instanceof TypeDef) {
|
||||
return "base"; //"typedef";
|
||||
}
|
||||
if (dt instanceof FunctionDefinition) {
|
||||
return "function";
|
||||
}
|
||||
if (dt instanceof BitFieldDataType) {
|
||||
return "bitfield";
|
||||
}
|
||||
if (dt instanceof DefaultDataType) {
|
||||
return "base";
|
||||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
public static String getBuiltInKind(BuiltInDataType dt) {
|
||||
if (dt instanceof AbstractIntegerDataType) {
|
||||
return dt.getLength() == 1 ? "char" : "int";
|
||||
}
|
||||
if (dt instanceof AbstractFloatDataType) {
|
||||
return "float";
|
||||
}
|
||||
if (dt instanceof AbstractComplexDataType) {
|
||||
return "complex";
|
||||
}
|
||||
if (dt instanceof AbstractStringDataType) {
|
||||
return "char"; // "string";
|
||||
}
|
||||
if (dt instanceof PointerDataType) {
|
||||
return "void"; //"pointer";
|
||||
}
|
||||
if (dt instanceof VoidDataType) {
|
||||
return "void";
|
||||
}
|
||||
if (dt instanceof Undefined) {
|
||||
return "void";
|
||||
}
|
||||
return "char";
|
||||
}
|
||||
|
||||
public static boolean isBaseDataType(DataType dt) {
|
||||
if (dt instanceof AbstractIntegerDataType) {
|
||||
return true;
|
||||
}
|
||||
if (dt instanceof AbstractFloatDataType) {
|
||||
return true;
|
||||
}
|
||||
if (dt instanceof AbstractComplexDataType) {
|
||||
return true;
|
||||
}
|
||||
if (dt instanceof AbstractStringDataType) {
|
||||
return true;
|
||||
}
|
||||
if (dt instanceof Pointer) {
|
||||
return true;
|
||||
}
|
||||
if (dt instanceof VoidDataType) {
|
||||
return true;
|
||||
}
|
||||
if (dt instanceof Undefined) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Integer getLength(DataType dt) {
|
||||
return dt.getLength();
|
||||
}
|
||||
|
||||
public static Boolean getSigned(DataType dt) {
|
||||
return dt.getDataOrganization().isSignedChar();
|
||||
}
|
||||
|
||||
public static String getEndianness(DataType dt) {
|
||||
return dt.getDataOrganization().isBigEndian() ? "big" : "little";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class IsfWinOS implements IsfObject {
|
||||
|
||||
public IsfWinPE pe;
|
||||
public IsfWinPDB pdb;
|
||||
|
||||
public IsfWinOS(Map<String, String> metaData) {
|
||||
pe = new IsfWinPE(metaData);
|
||||
pdb = new IsfWinPDB(metaData);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class IsfWinPDB implements IsfObject {
|
||||
|
||||
public String GUID;
|
||||
public Integer age;
|
||||
public String database;
|
||||
public Integer machine_type;
|
||||
|
||||
public IsfWinPDB(Map<String, String> metaData) {
|
||||
GUID = metaData.get("PDB GUID");
|
||||
age = Integer.valueOf(metaData.get("PDB Age"));
|
||||
database = metaData.get("PDB File");
|
||||
machine_type = 0; //metaData.get("PDB Version")); //?
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
package ghidra.program.model.data.ISF;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class IsfWinPE implements IsfObject {
|
||||
|
||||
public Integer build;
|
||||
public Integer major;
|
||||
public Integer minor;
|
||||
public Integer revision;
|
||||
|
||||
public IsfWinPE(Map<String, String> metaData) {
|
||||
String data = metaData.get("PE Property[ProductVersion]");
|
||||
String[] quad = data.split("\\.");
|
||||
build = Integer.valueOf(quad[3]);
|
||||
major = Integer.valueOf(quad[0]);
|
||||
minor = Integer.valueOf(quad[1]);
|
||||
revision = Integer.valueOf(quad[2]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
syntax = "proto3";
|
||||
package ghidra.dbg.isf.protocol;
|
||||
|
||||
enum ErrorCode {
|
||||
EC_UNKNOWN = 0;
|
||||
EC_BAD_REQUEST = 1;
|
||||
EC_NOT_SUPPORTED = 2;
|
||||
}
|
||||
|
||||
// For testing: cause the server to report an unrecognized request error
|
||||
message ErrorRequest {
|
||||
}
|
||||
|
||||
message ErrorReply {
|
||||
ErrorCode code = 1;
|
||||
string message = 2;
|
||||
}
|
||||
|
||||
message PingRequest {
|
||||
string content = 1;
|
||||
}
|
||||
|
||||
message PingReply {
|
||||
string content = 1;
|
||||
}
|
||||
|
||||
message FullExportRequest {
|
||||
string ns = 1;
|
||||
}
|
||||
|
||||
message FullExportReply {
|
||||
string value = 1;
|
||||
}
|
||||
|
||||
message LookAddrRequest {
|
||||
string ns = 1;
|
||||
string key = 2;
|
||||
}
|
||||
|
||||
message LookAddrReply {
|
||||
string value = 1;
|
||||
}
|
||||
|
||||
message LookTypeRequest {
|
||||
string ns = 1;
|
||||
string key = 2;
|
||||
}
|
||||
|
||||
message LookTypeReply {
|
||||
string value = 1;
|
||||
}
|
||||
|
||||
message EnumTypesRequest {
|
||||
string ns = 1;
|
||||
}
|
||||
|
||||
message EnumTypesReply {
|
||||
string ns = 1;
|
||||
string value = 2;
|
||||
}
|
||||
|
||||
|
||||
message LookSymRequest {
|
||||
string ns = 1;
|
||||
string key = 2;
|
||||
}
|
||||
|
||||
message LookSymReply {
|
||||
string value = 1;
|
||||
}
|
||||
|
||||
message EnumSymsRequest {
|
||||
string ns = 1;
|
||||
}
|
||||
|
||||
message EnumSymsReply {
|
||||
string value = 1;
|
||||
}
|
||||
|
||||
|
||||
message RootAddedEvent {
|
||||
}
|
||||
|
||||
|
||||
message RootMessage {
|
||||
int32 sequence = 1;
|
||||
|
||||
oneof msg {
|
||||
ErrorRequest error_request = 100;
|
||||
ErrorReply error_reply = 200;
|
||||
|
||||
PingRequest ping_request = 101;
|
||||
PingReply ping_reply = 201;
|
||||
|
||||
FullExportRequest full_export_request = 102;
|
||||
FullExportReply full_export_reply = 202;
|
||||
|
||||
LookTypeRequest look_type_request = 103;
|
||||
LookTypeReply look_type_reply = 203;
|
||||
|
||||
LookSymRequest look_symbol_request = 104;
|
||||
LookSymReply look_symbol_reply = 204;
|
||||
|
||||
LookAddrRequest look_address_request = 105;
|
||||
LookAddrReply look_address_reply = 205;
|
||||
|
||||
EnumTypesRequest enum_types_request = 106;
|
||||
EnumTypesReply enum_types_reply = 206;
|
||||
|
||||
EnumSymsRequest enum_symbols_request = 107;
|
||||
EnumSymsReply enum_symbols_reply = 207;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
MODULE FILE LICENSE: lib/protobuf-java-3.21.8.jar BSD-3-GOOGLE
|
||||
|
||||
@@ -22,6 +22,7 @@ apply plugin: 'eclipse'
|
||||
eclipse.project.name = 'Debug Framework-AsyncComm'
|
||||
|
||||
dependencies {
|
||||
api 'com.google.protobuf:protobuf-java:3.21.8'
|
||||
api project(':Generic')
|
||||
api project(':Graph')
|
||||
api project(':ProposedUtils')
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
##VERSION: 2.0
|
||||
##MODULE IP: BSD-3-GOOGLE
|
||||
Module.manifest||GHIDRA||||END|
|
||||
|
||||
Reference in New Issue
Block a user