James S. Sulzer

26 papers A* 1Journal 11Unranked 14
YearRankTypeTitle / Venue / Authors
2025 conf
ICORR
Dana L. Lorenz, William Kozak, Braedon Harris, Kyle Eaton, Amoagh Gopinath, Keven Hernandez, James S. Sulzer
2025 conf
ICORR
Ricardo Siu, Dana L. Lorenz, Jake Stahl, Mark Waschak, Donald Johnson, Juliet Zakel, Aiko Thompson, David Cunningham, James S. Sulzer
2020 conf
BioRob
Chungmin Han, David Ress, Aurora I. Ramos-Nuñez, Natasha de la Rosa, Sheng Li, James S. Sulzer
2020 conf
EMBC
Chungmin Han, David Ress, Aurora I. Ramos-Nuñez, Natasha de la Rosa, Sheng Li, James S. Sulzer
2019 J jnl
NeuroImage
Ethan Oblak, James S. Sulzer, Jarrod A. Lewis-Peacock
2019 conf
ICORR
Sung Yul Shin, James S. Sulzer
2019 conf
EMBC
Laura F. Santoso, Faiz Baqai, Mary Gwozdz, Justina Lange, Matthew G. Rosenberger, James S. Sulzer, David Paydarfar
2019 A* conf
ICRA
Ana C. de Oliveira, Kevin Warburton, James S. Sulzer, Ashish D. Deshpande
2019 conf
ICORR
Tunc Akbas, James S. Sulzer
2019 conf
ICORR
Jeonghwan Lee, Sung Yul Shin, Gaurav Ghorpade, Tunc Akbas, James S. Sulzer
2019 J jnl
NeuroImage
Uwe Herwig, Lutz Jäncke, Sigrid Scherpiet, H. Scheerer, J. Kohlberg, S. Opialla, A. Preuss, Vivian Roger Steiger, James S. Sulzer, Steffi Weidt, Philipp Stämpfli, Michael Rufer, Erich Seifritz, Annette B. Brühl
2018 J jnl
NeuroImage
Julio Duenas, James S. Sulzer, Philipp Stämpfli, Marie-Claude Hepp-Reymond, Spyros Sreejanth Kollias, Erich Seifritz, Roger Gassert
2017 conf
EMBC
Chungmin Han, Ethan Oblak, Larry Abraham, Paul Ferrari, Mark H. McManis, David M. Schnyer, James S. Sulzer
2017 J jnl
IEEE Trans. Biomed. Eng.
Michael R. Tucker, Camila Shirota, Olivier Lambercy, James S. Sulzer, Roger Gassert
2017 J jnl
PLoS Comput. Biol.
Ethan Oblak, Jarrod A. Lewis-Peacock, James S. Sulzer
2016 J jnl
IEEE Trans. Haptics
Bogdan Vigaru, James S. Sulzer, Roger Gassert
2016 J jnl
NeuroImage
Kirsten Emmert, Rotem Kopel, James S. Sulzer, Annette B. Brühl, Brian D. Berman, David E. J. Linden, Silvina G. Horovitz, Markus Breimhorst, Andrea Caria, Sabine Frank, Stephen J. Johnston, Zhi-ying Long, Christian Paret, Fabien Robineau, Ralf Veit, Andreas J. Bartsch, Christian F. Beckmann, Dimitri Van De Ville, Sven Haller
2013 conf
ICORR
James S. Sulzer, Julio Duenas, Philipp Stämpfli, Marie-Claude Hepp-Reymond, Spyros S. Kollias, Erich Seifritz, Roger Gassert
2013 conf
ICORR
Michael R. Tucker, Adrian Moser, Olivier Lambercy, James S. Sulzer, Roger Gassert
2013 J jnl
NeuroImage
James S. Sulzer, Ranganatha Sitaram, Maria Laura Blefari, Spyros S. Kollias, Niels Birbaumer, Klaas Enno Stephan, Andreas R. Luft, Roger Gassert
2013 J jnl
NeuroImage
James S. Sulzer, Sven Haller, Frank Scharnowski, Nikolaus Weiskopf, Niels Birbaumer, Maria Laura Blefari, Annette B. Brühl, Leonardo G. Cohen, R. Christopher DeCharms, Roger Gassert, Rainer Goebel, Uwe Herwig, Stephen LaConte, David E. J. Linden, Andreas R. Luft, Erich Seifritz, Ranganatha Sitaram
2011 conf
EMBC
James S. Sulzer, Vikram S. Chib, Marie-Claude Hepp-Reymond, Spyros S. Kollias, Roger Gassert
2009 J jnl
IEEE Trans. Robotics
James S. Sulzer, Ronald A. Roiz, Michael A. Peshkin, James L. Patton
2008 J jnl
IEEE Robotics Autom. Mag.
James S. Sulzer, Michael A. Peshkin, James L. Patton
2007 conf
WHC
James S. Sulzer, Arsalan Salamat, Vikram S. Chib, J. Edward Colgate
2006 conf
EMBC
James S. Sulzer, Michael A. Peshkin, James L. Patton
redb/extractors/decompiler/_archive/GhidraDecompilerScript-latest.java
← Index redb/extractors/decompiler/_archive/GhidraDecompilerScript-latest.java java
import ghidra.app.script.GhidraScript;
import ghidra.program.model.listing.*;
import ghidra.app.decompiler.*;
import ghidra.program.model.block.*;
import ghidra.program.model.symbol.*;
import ghidra.program.model.pcode.*;
import ghidra.program.model.address.*;
import org.json.JSONObject;
import org.json.JSONArray;
import java.security.MessageDigest;
import java.nio.charset.StandardCharsets;

public class GhidraDecompilerScript extends GhidraScript {
    private DecompInterface decompInterface;
    private BasicBlockModel basicBlockModel;
    
    @Override
    public void run() throws Exception {
        // Get binary hash and filepath from arguments
        String[] args = getScriptArgs();
        if (args.length < 2) {
            System.err.println("{\"error\": \"Both SHA256 and filepath arguments are required\"}");
            return;
        }
        String sha256 = args[0];
        String filepath = args[1];

        // Initialize analysis components
        setupDecompiler();
        basicBlockModel = new BasicBlockModel(currentProgram);

        // Create the main JSON object for output
        JSONObject output = new JSONObject();
        output.put("sha256", sha256);
        output.put("decompiled", new JSONArray());
        output.put("disassembled", new JSONArray());
        output.put("cfg", new JSONArray());

        // Process all functions
        FunctionIterator functions = currentProgram.getFunctionManager().getFunctions(true);
        for (Function function : functions) {
            processFunction(function, output);
        }

        // Output the final JSON to stdout
        System.out.println(output.toString());
    }

    private void setupDecompiler() {
        decompInterface = new DecompInterface();
        DecompileOptions options = new DecompileOptions();
        decompInterface.setOptions(options);
        decompInterface.openProgram(currentProgram);
    }

    private void processFunction(Function function, JSONObject output) {
        Address entry = function.getEntryPoint();
        String functionName = function.getName();
        String functionAddress = entry.toString();

        // Process decompiled code
        processDecompiledCode(function, output.getJSONArray("decompiled"), 
                            functionName, functionAddress);

        // Process disassembled code
        processDisassembledCode(function, output.getJSONArray("disassembled"), 
                              functionName, functionAddress);

        // Process CFG
        processCFG(function, output.getJSONArray("cfg"), functionAddress);
    }

    private void processDecompiledCode(Function function, JSONArray decompArray, 
                                     String functionName, String functionAddress) {
        DecompileResults results = decompInterface.decompileFunction(function, 30, monitor);
        if (results.decompileCompleted()) {
            String decompiledCode = results.getDecompiledFunction().getC();
            String contentHash = calculateHash(decompiledCode);

            JSONObject functionObj = new JSONObject();
            functionObj.put("decompiled_content_hash", contentHash);
            functionObj.put("decompiled_function_name", functionName);
            functionObj.put("decompiled_function_address", functionAddress);
            functionObj.put("decompiled_function", decompiledCode);
            
            decompArray.put(functionObj);
        }
    }

    private void processDisassembledCode(Function function, JSONArray disasmArray, 
                                       String functionName, String functionAddress) {
        try {
            StringBuilder disassembly = new StringBuilder();
            StringBuilder normalized = new StringBuilder();
            int instructionCount = 0;

            Listing listing = currentProgram.getListing();
            AddressSetView functionBody = function.getBody();
            InstructionIterator instructions = listing.getInstructions(functionBody, true);

            while (instructions.hasNext()) {
                try {
                    Instruction instr = instructions.next();
                    String disasmLine = instr.toString();
                    disassembly.append(disasmLine).append("\n");
                    normalized.append(normalizeInstruction(disasmLine)).append("\n");
                    instructionCount++;
                } catch (Exception e) {
                    System.err.println("Error processing instruction in " + functionName + ": " + e.getMessage());
                }
            }

            String disassembledCode = disassembly.toString();
            String contentHash = calculateHash(disassembledCode);

            JSONObject functionObj = new JSONObject();
            functionObj.put("disassembled_content_hash", contentHash);
            functionObj.put("disassembled_function_name", functionName);
            functionObj.put("disassembled_function_address", functionAddress);
            functionObj.put("disassembled_function", disassembledCode);
            functionObj.put("normalized_disassembly", normalized.toString());
            functionObj.put("instruction_count", instructionCount);

            // Set similarity-related fields to null for now
            functionObj.put("minhash_signature", JSONObject.NULL);
            functionObj.put("opcode_frequency_vector", JSONObject.NULL);
            functionObj.put("api_calls_vector", JSONObject.NULL);
            functionObj.put("instruction_embedding", JSONObject.NULL);

            disasmArray.put(functionObj);
        } catch (Exception e) {
            System.err.println("Error processing disassembly for " + functionName + ": " + e.getMessage());
        }
    }

    private void processCFG(Function function, JSONArray cfgArray, String functionAddress) {
        try {
            CodeBlockIterator blocks = basicBlockModel.getCodeBlocksContaining(
                function.getBody(), monitor);

            while (blocks.hasNext()) {
                CodeBlock block = blocks.next();
                String blockInstructions = getBlockInstructions(block);
                String blockId = calculateHash(blockInstructions);

                JSONObject blockObj = new JSONObject();
                blockObj.put("block_id", blockId);
                blockObj.put("function_address", functionAddress);
                blockObj.put("block_instructions", blockInstructions);

                // Get successor blocks
                CodeBlockReferenceIterator successors = block.getDestinations(monitor);
                JSONArray successorAddresses = new JSONArray();
                while (successors.hasNext()) {
                    CodeBlockReference ref = successors.next();
                    successorAddresses.put(ref.getDestinationAddress().toString());
                }
                blockObj.put("successor_blocks", successorAddresses);

                cfgArray.put(blockObj);
            }
        } catch (Exception e) {
            System.err.println("{\"error\": \"Error processing CFG: " + 
                             e.getMessage().replace("\"", "'") + "\"}");
        }
    }

    private String normalizeInstruction(String instruction) {
        return instruction.replaceAll("0x[0-9a-fA-F]+", "IMM")
                        .replaceAll("\\b\\d+\\b", "NUM");
    }

    private String getBlockInstructions(CodeBlock block) {
        StringBuilder instructions = new StringBuilder();
        AddressIterator addresses = block.getAddresses(true);
        while (addresses.hasNext()) {
            Address addr = addresses.next();
            Instruction instr = currentProgram.getListing().getInstructionAt(addr);
            if (instr != null) {
                instructions.append(instr.toString()).append("\n");
            }
        }
        return instructions.toString();
    }

    private String calculateHash(String content) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(content.getBytes(StandardCharsets.UTF_8));
            StringBuilder hexString = new StringBuilder();
            for (byte b : hash) {
                hexString.append(String.format("%02x", b));
            }
            return hexString.toString();
        } catch (Exception e) {
            System.err.println("{\"error\": \"Error calculating hash\"}");
            return "";
        }
    }
}