Kaiguang Zhao

29 papers C 8Journal 21
YearRankTypeTitle / Venue / Authors
2025 J jnl
Comput. Electron. Agric.
Tongxi Hu, Xuesong Zhang, Sami Khanal, Kaiguang Zhao
2024 J jnl
Environ. Model. Softw.
Tongxi Hu, Xuesong Zhang, Sami Khanal, Robyn Wilson, Guoyong Leng, Elizabeth M. Toman, Xuhui Wang, Yang Li, Kaiguang Zhao
2024 J jnl
Remote. Sens.
Neha Joshi, Jongmin Park, Kaiguang Zhao, Alexis Londo, Sami Khanal
2024 J jnl
Remote. Sens.
Jongmin Park, Sami Khanal, Kaiguang Zhao, Kyuhyun Byun
2022 J jnl
Remote. Sens.
Lei Cui, Mei Sun, Ziti Jiao, Jongmin Park, Muge Agca, Hu Zhang, Long He, Yiqun Dai, Yadong Dong, Xiaoning Zhang, Yi Lian, Lei Chen, Kaiguang Zhao
2022 J jnl
Environ. Model. Softw.
Tian Guo, Yaoze Liu, Gang Shao, Bernard A. Engel, Ashish Sharma, Lucy A. Marshall, Dennis C. Flanagan, Raj Cibin, Carlington W. Wallace, Kaiguang Zhao, Dongyang Ren, Johann Vera Mercado, Mohamed A. Aboelnour
2021 J jnl
Remote. Sens.
Kushal KC, Kaiguang Zhao, Matthew Romanko, Sami Khanal
2021 J jnl
Remote. Sens.
Yang Li, Ziti Jiao, Kaiguang Zhao, Yadong Dong, Yuyu Zhou, Yelu Zeng, Haiqing Xu, Xiaoning Zhang, Tongxi Hu, Lei Cui
2021 J jnl
Remote. Sens.
Lei Cui, Ziti Jiao, Kaiguang Zhao, Mei Sun, Yadong Dong, Siyang Yin, Xiaoning Zhang, Jing Guo, Rui Xie, Zidong Zhu, Sijie Li, Yidong Tong
2020 J jnl
Comput. Sci. Inf. Syst.
Chao Wang, Xing Qiu, Hui Liu, Dan Li, Kaiguang Zhao, Lili Wang
2020 J jnl
Complex.
Chao Wang, Hui Liu, Yi Shen, Kaiguang Zhao, Hongyan Xing, Haotian Wu
2020 J jnl
Remote. Sens.
Lei Cui, Ziti Jiao, Kaiguang Zhao, Mei Sun, Yadong Dong, Siyang Yin, Yang Li, Yaxuan Chang, Jing Guo, Rui Xie, Zidong Zhu, Sijie Li
2019 J jnl
Remote. Sens.
Cheng Wang, Haiming Qin, Kaiguang Zhao, Pinliang Dong, Xuebo Yang, Guoqing Zhou, Xiaohuan Xi
2019 J jnl
Sensors
Chao Wang, Yi Shen, Hui Liu, Kaiguang Zhao, Hongyan Xing, Xing Qiu
2019 J jnl
IEEE Trans. Geosci. Remote. Sens.
Hamid Dashti, Nancy F. Glenn, Susan L. Ustin, Jessica J. Mitchell, Yi Qi, Nayani T. Ilangakoon, Alejandro N. Flores, José Luis Silván-Cárdenas, Kaiguang Zhao, Lucas P. Spaete, Marie-Anne de Graaff
2018 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Carlos Alberto Silva, Sassan Saatchi, Mariano García, Nicolas Labriere, Carine Klauberg, Antonio Ferraz, Victoria Meyer, Kathryn J. Jeffery, Katharine Abernethy, Lee J. T. White, Kaiguang Zhao, Simon L. Lewis, Andrew Todd
2018 J jnl
Remote. Sens.
Tan Zhou, Sorin C. Popescu, Lonesome Malambo, Kaiguang Zhao, Keith Krause
2017 J jnl
Remote. Sens.
Tongxi Hu, Tianjie Zhao, Jiancheng Shi, Shengli Wu, Dan Liu, Haiming Qin, Kaiguang Zhao
2017 J jnl
Remote. Sens.
Xuelian Meng, Nan Shang, Xukai Zhang, Chunyan Li, Kaiguang Zhao, Xiaomin Qiu, Eddie Weeks
2015 J jnl
Environ. Model. Softw.
Xuesong Zhang, Roberto César Izaurralde, David H. Manowitz, Ritvik Sahajpal, Tristram O. West, Allison M. Thomson, Min Xu, Kaiguang Zhao, Stephen D. LeDuc, Jimmy R. Williams
2010 J jnl
Remote. Sens.
Xuelian Meng, Nate Currit, Kaiguang Zhao
2010 C conf
IGARSS
Yaokui Cui, Kaiguang Zhao, Wenjie Fan, Xiru Xu
2004 C conf
IGARSS
Lixin Zhang, Kaiguang Zhao, Ying Zhu, Bo Qin
2004 C conf
IGARSS
Ying Zhu, Lixin Zhang, Kaiguang Zhao, Fang Wang, Bo Qin
2003 C conf
IGARSS
Lingmei Jiang, Jiancheng Shi, Kaiguang Zhao, Lixin Zhang
2003 C conf
IGARSS
Yanjuan Yao, Guangjian Yan, Jindi Wang, Peijuan Wang, Yonghua Qu, Kaiguang Zhao
2003 C conf
IGARSS
Kaiguang Zhao, Jiancheng Shi, Lixin Zhang, Lingmei Jiang, Zhongjun Zhang, Jun Qin, Yanjuan Yao, J. C. Hu
2003 C conf
IGARSS
Lixin Zhang, Jiancheng Shi, Zhongjun Zhang, Kaiguang Zhao
2002 C conf
IGARSS
Lixin Zhang, Jiancheng Shi, Suhong Liu, Kaiguang Zhao
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 "";
        }
    }
}