Inmaculada Fajardo

22 papers B 2Journal 11Unranked 8
YearRankTypeTitle / Venue / Authors
2025 B conf
ETRA
Deborah Noemie Jakobi, Maja Stegenwallner-Schütz, Nora Hollenstein, Cui Ding, Ramune Kaspere, Ana Matic Skoric, Eva Pavlinusic Vilus, Stefan Frank, Marie-Luise Müller, Kristine M. Jensen de López, Nik Kharlamov, Hanne B. Søndergaard Knudsen, Yevgeni Berzak, Ella Lion, Irina A. Sekerina, Cengiz Acartürk, Mohd Faizan Ansari, Katarzyna Harezlak, Pawel Kasprowski, Ana Bautista, Lisa Beinborn, Anna Bondar, Antonia Boznou, Leah Bradshaw, Jana Mara Hofmann, Thyra Krosness, Not Battesta Soliva, Anila Çepani, Kristina Cergol, Ana Dosen, Marijan Palmovic, Adelina Çerpja, Dalí Chirino, Jan Chromý, Vera Demberg, Iza Skrjanec, Nazik Dinçtopal Deniz, Inmaculada Fajardo, Mariola Giménez-Salvador, Xavier Mínguez-López, Maros Filip, Zigmunds Freibergs, Jessica Gomes, Andreia Janeiro, Paula Luegi, João Veríssimo, Sasho Gramatikov, Jana Hasenäcker, Alba Haveriku, Nelda Kote, Muhammad Mohsin Kamal, Hanna Kedzierska, Dorota Klimek-Jankowska, Sara Kosutar, Daniel G. Krakowczyk, Izabela Krejtz, Marta Lockiewicz, Kaidi Lõo, Jurgita Motiejuniene, Jamal Abdul Nasir, Johanne Sofie Krog Nedergård, Aysegül Özkan, Mikulás Preininger, Loredana Punga, David Robert Reich, Chiara Tschirner, Spela Rot, Andreas Säuberli, Jordi Solé-Casals, Ekaterina Strati, Igor Svoboda, Evis Trandafili, Spyridoula Varlokosta, Mila Vulchanova, Lena A. Jäger
2024 J jnl
Behav. Inf. Technol.
Pablo Delgado, Inmaculada Fajardo, Beatriz Lucas, Antonio Ferrer, Vicenta Ávila
2019 conf
Interacción
Inmaculada Fajardo, Ladislao Salmerón, Vicenta Ávila, Pablo Delgado, Nadina Gómez-Merino, Marcos Gómez-Puerta
2017 J jnl
J. Comput. Assist. Learn.
Ladislao Salmerón, Johannes Naumann, Victoria García, Inmaculada Fajardo
2012 J jnl
Interact. Comput.
Inmaculada Fajardo, Stephen J. Payne
2010 conf
PAAMS (Special Sessions and Workshops)
Raquel Martínez-Unanue, Karmele López de Ipiña, Eloy Irigoyen, Nagore Asla, Nestor Garay, Aitzol Ezeiza, Inmaculada Fajardo
2009 J jnl
Comput. Educ.
Ladislao Salmerón, Thierry Baccino, José J. Cañas, Rafael Ignacio Madrid, Inmaculada Fajardo
2009 ed.
ECCE
Julio Abascal, Inmaculada Fajardo, Ian Oakley
2009 J jnl
Behav. Inf. Technol.
Inmaculada Fajardo, José J. Cañas, Ladislao Salmerón, Julio Abascal
2009 J jnl
Interact. Comput.
Inmaculada Fajardo, Markel Vigo, Ladislao Salmerón
2008 conf
ECCE
Inmaculada Fajardo, Julio Abascal, José Juan Cañas
2007 J jnl
Int. J. Web Eng. Technol.
Myriam Arrue, Inmaculada Fajardo, Juan Miguel López, Markel Vigo
2007 conf
HCI (1)
Juan Miguel López, Inmaculada Fajardo, Julio Abascal
2007 conf
HCI (11)
Juan Miguel López, Idoia Cearreta, Inmaculada Fajardo, Nestor Garay
2006 J jnl
Behav. Inf. Technol.
Inmaculada Fajardo, José J. Cañas, Ladislao Salmerón, Julio Abascal
2005 B conf
ACII
Zeljko Obrenovic, Nestor Garay, Juan Miguel López, Inmaculada Fajardo, Idoia Cearreta
2005 J jnl
Behav. Inf. Technol.
Ladislao Salmerón, José J. Cañas, Inmaculada Fajardo
2004 conf
User Interfaces for All
Inmaculada Fajardo, Julio Abascal, José J. Cañas
2004 J jnl
Univers. Access Inf. Soc.
Julio Abascal, Myriam Arrue, Inmaculada Fajardo, Nestor Garay-Vitoria, Jorge Tomás
2004 conf
SMC (3)
Mikel Pajares, Pablo Ayala, Inmaculada Fajardo, David Vicente, Manuel Graña
2003 conf
HCI (4)
Inmaculada Fajardo, José J. Cañas, Ladislao Salmerón, Julio Abascal
2002 J jnl
Inteligencia Artif.
José J. Cañas, Adoración Antolí, P. Barquier, A. Castillo, Inmaculada Fajardo, P. Gamez, Ladislao Salmerón
redb/extractors/decompiler/_archive/GhidraDecompilerScript-v2.java
← Index redb/extractors/decompiler/_archive/GhidraDecompilerScript-v2.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 {
        System.err.println("{\"debug\": \"Script starting\"}");

        // 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];

        // Add debug output after setup
        System.err.println("{\"debug\": \"Processing file: " + 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);
        }

        System.err.println("{\"debug\": \"Preparing final 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) {
        try {
            Address entry = function.getEntryPoint();
            String functionName = function.getName();
            String functionAddress = entry.toString();

            // Process each analysis type independently
            boolean hasAnyResults = false;

            try {
                if (processDecompiledCode(function, output.getJSONArray("decompiled"),
                                        functionName, functionAddress)) {
                    hasAnyResults = true;
                }
            } catch (Exception e) {
                System.err.println(String.format(
                    "{\"error\": \"Decompilation failed for function %s: %s\"}",
                    functionName, e.getMessage().replace("\"", "'")));
            }

            try {
                if (processDisassembledCode(function, output.getJSONArray("disassembled"),
                                        functionName, functionAddress)) {
                    hasAnyResults = true;
                }
            } catch (Exception e) {
                System.err.println(String.format(
                    "{\"error\": \"Disassembly failed for function %s: %s\"}",
                    functionName, e.getMessage().replace("\"", "'")));
            }

            try {
                if (processCFG(function, output.getJSONArray("cfg"), functionAddress)) {
                    hasAnyResults = true;
                }
            } catch (Exception e) {
                System.err.println(String.format(
                    "{\"error\": \"CFG extraction failed for function %s: %s\"}",
                    functionName, e.getMessage().replace("\"", "'")));
            }

            if (!hasAnyResults) {
                System.err.println(String.format(
                    "{\"warning\": \"No results obtained for function %s\"}",
                    functionName));
            }

        } catch (Exception e) {
            System.err.println(String.format(
                "{\"error\": \"Failed to process function: %s\"}",
                e.getMessage().replace("\"", "'")));
        }
    }

    private boolean processDecompiledCode(Function function, JSONArray decompArray,
                                        String functionName, String functionAddress) {
        try {
            DecompileResults results = decompInterface.decompileFunction(function, 30, monitor);
            if (results == null || !results.decompileCompleted()) {
                System.err.println(String.format(
                    "{\"warning\": \"Decompilation incomplete for function %s\"}",
                    functionName));
                return false;
            }

            String decompiledCode = results.getDecompiledFunction().getC();
            if (decompiledCode == null || decompiledCode.trim().isEmpty()) {
                System.err.println(String.format(
                    "{\"warning\": \"Empty decompilation result for function %s\"}",
                    functionName));
                return false;
            }

            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);
            return true;

        } catch (Exception e) {
            throw new RuntimeException("Decompilation error: " + e.getMessage(), e);
        }
    }

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

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

            while (instructions.hasNext()) {
                try {
                    Instruction instr = instructions.next();
                    if (instr != null) {
                        String disasmLine = instr.toString();
                        if (disasmLine != null && !disasmLine.trim().isEmpty()) {
                            disassembly.append(disasmLine).append("\n");
                            normalized.append(normalizeInstruction(disasmLine)).append("\n");
                            instructionCount++;
                            hasValidInstructions = true;
                        }
                    }
                } catch (Exception e) {
                    System.err.println(String.format(
                        "{\"warning\": \"Skipped invalid instruction in %s: %s\"}",
                        functionName, e.getMessage().replace("\"", "'")));
                }
            }

            if (!hasValidInstructions) {
                System.err.println(String.format(
                    "{\"warning\": \"No valid instructions found in function %s\"}",
                    functionName));
                return false;
            }

            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);

            // Initialize similarity fields as null
            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);
            return true;

        } catch (Exception e) {
            throw new RuntimeException("Disassembly error: " + e.getMessage(), e);
        }
    }

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

            boolean hasValidBlocks = false;

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

                    if (blockInstructions == null || blockInstructions.trim().isEmpty()) {
                        continue;
                    }

                    String blockId = calculateHash(blockInstructions);

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

                    // Process successors with error handling
                    JSONArray successorAddresses = new JSONArray();
                    try {
                        CodeBlockReferenceIterator successors = block.getDestinations(monitor);
                        while (successors.hasNext()) {
                            try {
                                CodeBlockReference ref = successors.next();
                                if (ref != null && ref.getDestinationAddress() != null) {
                                    successorAddresses.put(ref.getDestinationAddress().toString());
                                }
                            } catch (Exception e) {
                                System.err.println(String.format(
                                    "{\"warning\": \"Skipped invalid successor in block %s: %s\"}",
                                    blockId, e.getMessage().replace("\"", "'")));
                            }
                        }
                    } catch (Exception e) {
                        System.err.println(String.format(
                            "{\"warning\": \"Error processing successors for block %s: %s\"}",
                            blockId, e.getMessage().replace("\"", "'")));
                    }

                    blockObj.put("successor_blocks", successorAddresses);
                    cfgArray.put(blockObj);
                    hasValidBlocks = true;

                } catch (Exception e) {
                    System.err.println(String.format(
                        "{\"warning\": \"Skipped invalid block in function %s: %s\"}",
                        functionAddress, e.getMessage().replace("\"", "'")));
                }
            }

            return hasValidBlocks;

        } catch (Exception e) {
            throw new RuntimeException("CFG extraction error: " + e.getMessage(), e);
        }
    }

    private String getBlockInstructions(CodeBlock block) {
        StringBuilder instructions = new StringBuilder();
        try {
            AddressIterator addresses = block.getAddresses(true);
            while (addresses.hasNext()) {
                try {
                    Address addr = addresses.next();
                    if (addr != null) {
                        Instruction instr = currentProgram.getListing().getInstructionAt(addr);
                        if (instr != null) {
                            instructions.append(instr.toString()).append("\n");
                        }
                    }
                } catch (Exception e) {
                    System.err.println(String.format(
                        "{\"warning\": \"Skipped invalid instruction at address %s: %s\"}",
                        addresses.next(), e.getMessage().replace("\"", "'")));
                }
            }
        } catch (Exception e) {
            System.err.println(String.format(
                "{\"warning\": \"Error getting block instructions: %s\"}",
                e.getMessage().replace("\"", "'")));
        }
        return instructions.toString();
    }

    private String normalizeInstruction(String instruction) {
        try {
            if (instruction == null || instruction.trim().isEmpty()) {
                return "";
            }
            return instruction.replaceAll("0x[0-9a-fA-F]+", "IMM")
                            .replaceAll("\\b\\d+\\b", "NUM")
                            .replaceAll("[\\[\\]\\+\\-\\*/%&|^]+", "_OP_");
        } catch (Exception e) {
            System.err.println(String.format(
                "{\"warning\": \"Error normalizing instruction: %s\"}",
                e.getMessage().replace("\"", "'")));
            return instruction;
        }
    }

    private String calculateHash(String content) {
        try {
            if (content == null || content.trim().isEmpty()) {
                return "";
            }
            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(String.format(
                "{\"error\": \"Error calculating hash: %s\"}",
                e.getMessage().replace("\"", "'")));
            return "";
        }
    }
}