Kaige Tan

25 papers A* 1Journal 17Unranked 7
YearRankTypeTitle / Venue / Authors
2025 A* conf
ICRA
Xuezhi Niu, Kaige Tan, Didem Gürdür Broo, Lei Feng
2025 J jnl
Appl. Soft Comput.
Kaige Tan, Xuezhi Niu, Qinglei Ji, Lei Feng, Martin Törngren
2025 conf
ECC
Tong Zhao, Kaige Tan, Lei Feng
2024 conf
ITSC
Tong Liu, Kaige Tan, Wenyao Zhu, Peigen Chen, Lei Feng
2024 conf
ISoLA (3)
Rong Gu, Kaige Tan, Andreas Holck Høeg-Petersen, Lei Feng, Kim Guldstrand Larsen
2024 J jnl
CoRR
Rong Gu, Kaige Tan, Andreas Holck Høeg-Petersen, Lei Feng, Kim Guldstrand Larsen
2024 J jnl
IEEE Trans. Intell. Veh.
Tong Liu, Kaige Tan, Wenyao Zhu, Lei Feng
2024 J jnl
IEEE Trans. Ind. Electron.
Kaige Tan, Qinglei Ji, Lei Feng, Martin Törngren
2024 J jnl
CoRR
Xuezhi Niu, Kaige Tan, Lei Feng
2024 J jnl
CoRR
Kaige Tan, Xuezhi Niu, Qinglei Ji, Lei Feng, Martin Törngren
2023 J jnl
Inf. Sci.
Junjun Yang, Kaige Tan, Lei Feng, ZhiWu Li
2023 conf
CASE
Kaige Tan, Lei Feng, Martin Törngren
2023 J jnl
Softw. Qual. J.
Qunying Song, Kaige Tan, Per Runeson, Stefan Persson
2023 J jnl
IEEE Trans. Software Eng.
Xinhai Zhang, Jianbo Tao, Kaige Tan, Martin Törngren, José Manuel Gaspar Sánchez, Muhammad Rusyadi Ramli, Xin Tao, Magnus Gyllenhammar, Franz Wotawa, Naveen Mohan, Mihai Nica, Hermann Felbinger
2023 conf
AIM
Tong Liu, Kaige Tan, Wenyao Zhu, Lei Feng
2023 J jnl
IEEE Access
Junjun Yang, Kaige Tan, Lei Feng, Ahmed M. El-Sherbeeny, ZhiWu Li
2022 conf
CASE
Tong Liu, Wenyao Zhu, Kaige Tan, Mingwei Liu, Lei Feng
2022 J jnl
IEEE Trans. Veh. Technol.
Kaige Tan, Lei Feng, György Dán, Martin Törngren
2022 J jnl
ACM Trans. Cyber Phys. Syst.
José Manuel Gaspar Sánchez, Nils Jörgensen, Martin Törngren, Rafia Inam, Andrii Berezovskyi, Lei Feng, Elena Fersman, Muhammad Rusyadi Ramli, Kaige Tan
2022 J jnl
IEEE Robotics Autom. Lett.
Kaige Tan, Qinglei Ji, Lei Feng, Martin Törngren
2022 J jnl
Robotics Comput. Integr. Manuf.
Qinglei Ji, Shuo Fu, Kaige Tan, Seshagopalan Thorapalli Muralidharan, Karin Lagrelius, David Danelia, Georgios Andrikopoulos, Xi Vincent Wang, Lihui Wang, Lei Feng
2021 conf
AITest
Qunying Song, Kaige Tan, Per Runeson, Stefan Persson
2021 J jnl
CoRR
José Manuel Gaspar Sánchez, Nils Jörgensen, Martin Törngren, Rafia Inam, Andrii Berezovskyi, Lei Feng, Elena Fersman, Muhammad Rusyadi Ramli, Kaige Tan
2021 J jnl
CoRR
Xinhai Zhang, Jianbo Tao, Kaige Tan, Martin Törngren, José Manuel Gaspar Sánchez, Muhammad Rusyadi Ramli, Xin Tao, Magnus Gyllenhammar, Franz Wotawa, Naveen Mohan, Mihai Nica, Hermann Felbinger
2018 J jnl
CoRR
Xiaogang Cheng, Bin Yang, Kaige Tan, Erik Isaksson, Liren Li, Anders Hedman, Thomas Olofsson, Haibo Li
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 "";
        }
    }
}