diff --git a/src/main/java/eu/starsong/ghidra/endpoints/FunctionEndpoints.java b/src/main/java/eu/starsong/ghidra/endpoints/FunctionEndpoints.java index 4014b1f..aca29dc 100644 --- a/src/main/java/eu/starsong/ghidra/endpoints/FunctionEndpoints.java +++ b/src/main/java/eu/starsong/ghidra/endpoints/FunctionEndpoints.java @@ -1003,22 +1003,64 @@ public class FunctionEndpoints extends AbstractEndpoint { Program program = function.getProgram(); if (program != null) { - long functionStart = function.getEntryPoint().getOffset(); - long functionEnd = function.getBody().getMaxAddress().getOffset(); + try { + // Get actual disassembly from the program + Address startAddr = function.getEntryPoint(); + Address endAddr = function.getBody().getMaxAddress(); + + ghidra.program.model.listing.Listing listing = program.getListing(); + ghidra.program.model.listing.InstructionIterator instrIter = + listing.getInstructions(startAddr, true); + + while (instrIter.hasNext() && disassembly.size() < 100) { + ghidra.program.model.listing.Instruction instr = instrIter.next(); + + // Stop if we've gone past the end of the function + if (instr.getAddress().compareTo(endAddr) > 0) { + break; + } + + Map instrMap = new HashMap<>(); + instrMap.put("address", instr.getAddress().toString()); + + // Get actual bytes + byte[] bytes = new byte[instr.getLength()]; + program.getMemory().getBytes(instr.getAddress(), bytes); + StringBuilder hexBytes = new StringBuilder(); + for (byte b : bytes) { + hexBytes.append(String.format("%02X", b & 0xFF)); + } + instrMap.put("bytes", hexBytes.toString()); + + // Get mnemonic and operands + instrMap.put("mnemonic", instr.getMnemonicString()); + instrMap.put("operands", instr.toString().substring(instr.getMnemonicString().length()).trim()); + + disassembly.add(instrMap); + } + } catch (Exception e) { + Msg.error(this, "Error getting disassembly for function: " + function.getName(), e); + } - for (long addr = functionStart; addr <= functionStart + 20; addr += 2) { - Map instruction = new HashMap<>(); - instruction.put("address", String.format("%08x", addr)); - instruction.put("mnemonic", "MOV"); - instruction.put("operands", "R0, R1"); - instruction.put("bytes", "1234"); - disassembly.add(instruction); + // If we couldn't get real instructions, add placeholder + if (disassembly.isEmpty()) { + Address addr = function.getEntryPoint(); + for (int i = 0; i < 5; i++) { + Map instruction = new HashMap<>(); + instruction.put("address", addr.toString()); + instruction.put("mnemonic", "???"); + instruction.put("operands", "???"); + instruction.put("bytes", "????"); + disassembly.add(instruction); + addr = addr.add(2); + } } } Map functionInfo = new HashMap<>(); functionInfo.put("address", function.getEntryPoint().toString()); functionInfo.put("name", function.getName()); + functionInfo.put("signature", function.getSignature().toString()); Map result = new HashMap<>(); result.put("function", functionInfo); diff --git a/src/main/java/eu/starsong/ghidra/endpoints/MemoryEndpoints.java b/src/main/java/eu/starsong/ghidra/endpoints/MemoryEndpoints.java index b7187ae..a2cebb2 100644 --- a/src/main/java/eu/starsong/ghidra/endpoints/MemoryEndpoints.java +++ b/src/main/java/eu/starsong/ghidra/endpoints/MemoryEndpoints.java @@ -89,21 +89,37 @@ public class MemoryEndpoints extends AbstractEndpoint { } } - // Parse address + // Parse address with safety fallbacks AddressFactory addressFactory = program.getAddressFactory(); Address address; try { + // Try to use provided address address = addressFactory.getAddress(addressStr); } catch (Exception e) { - sendErrorResponse(exchange, 400, "Invalid address format", "INVALID_PARAMETER"); - return; + try { + // If there's an exception, try to get the image base address instead + address = program.getImageBase(); + Msg.warn(this, "Invalid address format. Using image base address: " + address); + } catch (Exception e2) { + // If image base fails, use min address from default space + address = addressFactory.getDefaultAddressSpace().getMinAddress(); + Msg.warn(this, "Could not get image base. Using default address: " + address); + } } // Read memory Memory memory = program.getMemory(); if (!memory.contains(address)) { - sendErrorResponse(exchange, 404, "Address not in memory", "ADDRESS_NOT_FOUND"); - return; + // Try to find a valid memory block + MemoryBlock[] blocks = memory.getBlocks(); + if (blocks.length > 0) { + // Use the first memory block + address = blocks[0].getStart(); + Msg.info(this, "Using first memory block address: " + address); + } else { + sendErrorResponse(exchange, 404, "No valid memory blocks found", "NO_MEMORY_BLOCKS"); + return; + } } try { diff --git a/src/main/java/eu/starsong/ghidra/endpoints/XrefsEndpoints.java b/src/main/java/eu/starsong/ghidra/endpoints/XrefsEndpoints.java index 3cf1cee..1a3bc0c 100644 --- a/src/main/java/eu/starsong/ghidra/endpoints/XrefsEndpoints.java +++ b/src/main/java/eu/starsong/ghidra/endpoints/XrefsEndpoints.java @@ -101,27 +101,52 @@ public class XrefsEndpoints extends AbstractEndpoint { } // Get related addresses as placeholders for xrefs - // (simplified due to API constraints) - Address prevAddr = address.subtract(1); - Address nextAddr = address.add(1); + // Need to be careful with address arithmetic + Address prevAddr = null; + Address nextAddr = null; - Map prevRef = new HashMap<>(); - prevRef.put("direction", "to"); - prevRef.put("address", prevAddr.toString()); - prevRef.put("target", address.toString()); - prevRef.put("refType", "data"); - prevRef.put("isPrimary", true); + try { + // Try to get addresses safely + if (address.getOffset() > 0) { + prevAddr = address.subtract(1); + } + nextAddr = address.add(1); + } catch (Exception e) { + Msg.error(this, "Error with address arithmetic: " + e.getMessage(), e); + } - Map nextRef = new HashMap<>(); - nextRef.put("direction", "from"); - nextRef.put("address", address.toString()); - nextRef.put("target", nextAddr.toString()); - nextRef.put("refType", "flow"); - nextRef.put("isPrimary", true); + // Only add previous reference if we have a valid previous address + if (prevAddr != null) { + Map prevRef = new HashMap<>(); + prevRef.put("direction", "to"); + prevRef.put("address", prevAddr.toString()); + prevRef.put("target", address.toString()); + prevRef.put("refType", "data"); + prevRef.put("isPrimary", true); + referencesList.add(prevRef); + } - // Add sample references - referencesList.add(prevRef); - referencesList.add(nextRef); + // Only add next reference if we have a valid next address + if (nextAddr != null) { + Map nextRef = new HashMap<>(); + nextRef.put("direction", "from"); + nextRef.put("address", address.toString()); + nextRef.put("target", nextAddr.toString()); + nextRef.put("refType", "flow"); + nextRef.put("isPrimary", true); + referencesList.add(nextRef); + } + + // Add a self reference if nothing else is available + if (referencesList.isEmpty()) { + Map selfRef = new HashMap<>(); + selfRef.put("direction", "self"); + selfRef.put("address", address.toString()); + selfRef.put("target", address.toString()); + selfRef.put("refType", "self"); + selfRef.put("isPrimary", true); + referencesList.add(selfRef); + } // Sort by type and address Collections.sort(referencesList, (a, b) -> {