diff --git a/Ghidra/Configurations/Public_Release/src/global/docs/ChangeHistory.md b/Ghidra/Configurations/Public_Release/src/global/docs/ChangeHistory.md index 223f3bafb1..55bfee889b 100644 --- a/Ghidra/Configurations/Public_Release/src/global/docs/ChangeHistory.md +++ b/Ghidra/Configurations/Public_Release/src/global/docs/ChangeHistory.md @@ -1,3 +1,28 @@ +# Ghidra 12.0.3 Change History (February 2026) + +### New Features +* _Listing_. In order to mitigate possible security risks, auto comments will not longer render annotations in such a way as to make them valid annotation links. Normal comments will continue to work as usual. (GP-6414) + +### Improvements +* _Demangler_. The __Demangler GNU__ analyzer now has a timeout option. (GP-6408) +* _GUI_. Corrected Ghidra GUI to fail-fast in headless environment and avoid stack traces. (GP-6399) +* _Listing_. The `@execute` annotation is no longer supported. (GP-6413) + +### Bugs +* _Data Types_. Corrected multi-user merge issues related to non-packed structures which could negatively affect merge results. (GP-6320, Issue #8776) +* _Debugger_. Fixed a `NullPointerException` that could occur upon closing the Debugger. (GP-6376) +* _Debugger:Breakpoints_. Fixed an issue where restarting a target (e.g., the `run` command from GDB's CLI) caused duplicate breakpoint entries and GUI glitches. (GP-6027) +* _Decompiler_. Fixed _"PTRSUB off of non structured pointer type"_ exceptions caused by `void *` data-type. (GP-6388, Issue #8887) +* _Decompiler_. Fixed source of _"Forced merge caused intersection"_ exceptions when decompiling optimized string copies. (GP-6393, Issue #8651) +* _Multi-User_. Revised Ghidra Server self-signed certificate generation to include all associated FQDNs and IP addresses as subject alternative names. This will address the forced hostname check imposed with the release of JDK 21.0.10. To benefit from this change the Ghidra Server will need to be upgraded to this release. A client-side workaround is to set the following JVM property within `support/launch.properties` by adding the line: `VMARGS=-Djdk.rmi.ssl.client.enableEndpointIdentification=false`. (GP-6426, Issue #8940) +* _Processors_. Fixed bug in AARCH64 `sha1h` instruction to shift instead of rotate bits. (GP-4501, Issue #6398) +* _Processors_. Fixed 80251 disassembly errors for instructions referencing the SPX register. (GP-5905, Issue #8395) +* _Processors_. Fixed disassembly of MIPS16e2 `lui` instruction to only parse on extended words. (GP-6419) +* _Search_. Fixed a memory leak in the `Find References...` action. (GP-6395, Issue #8921) + +### Notable API Changes +* _Data Types_. (GP-6320) Structure offset-based insert methods `Structure.insertAtOffset` will now skip forward over existing zero-length components at the insert offset before performing insert of new component. + # Ghidra 12.0.2 Change History (January 2026) ### New Features diff --git a/Ghidra/Features/GhidraServer/src/main/java/ghidra/server/remote/GhidraServer.java b/Ghidra/Features/GhidraServer/src/main/java/ghidra/server/remote/GhidraServer.java index 70839d598f..90421f4b4b 100644 --- a/Ghidra/Features/GhidraServer/src/main/java/ghidra/server/remote/GhidraServer.java +++ b/Ghidra/Features/GhidraServer/src/main/java/ghidra/server/remote/GhidraServer.java @@ -25,8 +25,7 @@ import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.*; import java.security.cert.CertificateException; -import java.util.Enumeration; -import java.util.List; +import java.util.*; import javax.rmi.ssl.SslRMIClientSocketFactory; import javax.rmi.ssl.SslRMIServerSocketFactory; @@ -752,11 +751,49 @@ public class GhidraServer extends UnicastRemoteObject implements GhidraServerHan // Ensure that remote access hostname is properly set for RMI registration String hostname = initRemoteAccessHostname(); - if (DefaultKeyManagerFactory.getPreferredKeyStore() == null) { + log.info("Ghidra Server " + Application.getApplicationVersion()); + log.info(" Server remote access address: " + hostname); + if (bindAddress == null) { + log.info(" Server listening on all interfaces"); + } + else { + log.info(" Server listening on interface: " + bindAddress.getHostAddress()); + } + + String preferredKeyStore = DefaultKeyManagerFactory.getPreferredKeyStore(); + if (preferredKeyStore == null) { + // keystore has not been identified - use self-signed certificate + log.info(" Generating self-signed certificate..."); + log.info(" Subject Alternative Names:"); + log.info(" " + hostname); + DefaultKeyManagerFactory.setDefaultIdentity(new X500Principal("CN=GhidraServer")); DefaultKeyManagerFactory.addSubjectAlternativeName(hostname); + + // Collect alternate hostnames for inclusion in certificate + Set altNames = new TreeSet<>(); + Enumeration nets = NetworkInterface.getNetworkInterfaces(); + while (nets.hasMoreElements()) { + NetworkInterface netint = nets.nextElement(); + Enumeration addrs = netint.getInetAddresses(); + while (addrs.hasMoreElements()) { + InetAddress addr = addrs.nextElement(); + altNames.add(addr.getHostAddress()); + altNames.add(addr.getHostName()); + altNames.add(addr.getCanonicalHostName()); + } + } + altNames.remove(hostname); + for (String name : altNames) { + log.info(" " + name); + DefaultKeyManagerFactory.addSubjectAlternativeName(name); + } } + else { + log.info(" Using server certificate keystore: " + preferredKeyStore); + } + if (!DefaultKeyManagerFactory.initialize()) { log.fatal("Failed to initialize PKI/SSL keystore"); System.exit(0); @@ -769,14 +806,7 @@ public class GhidraServer extends UnicastRemoteObject implements GhidraServerHan // localhost.getCanonicalHostName() + ":" + classSvrPort + "/"; // System.setProperty(RMI_CODEBASE_PROPERTY, codeBaseProp); - log.info("Ghidra Server " + Application.getApplicationVersion()); - log.info(" Server remote access address: " + hostname); - if (bindAddress == null) { - log.info(" Server listening on all interfaces"); - } - else { - log.info(" Server listening on interface: " + bindAddress.getHostAddress()); - } + log.info(" RMI Registry port: " + ServerPortFactory.getRMIRegistryPort()); log.info(" RMI SSL port: " + ServerPortFactory.getRMISSLPort()); log.info(" Block Stream port: " + ServerPortFactory.getStreamPort()); diff --git a/Ghidra/RuntimeScripts/Common/support/launch.properties b/Ghidra/RuntimeScripts/Common/support/launch.properties index 47d8b5d529..42e00fdba8 100644 --- a/Ghidra/RuntimeScripts/Common/support/launch.properties +++ b/Ghidra/RuntimeScripts/Common/support/launch.properties @@ -54,6 +54,13 @@ VMARGS=-Djdk.tls.client.protocols=TLSv1.2,TLSv1.3 # #VMARGS=-Djavax.net.debug=ssl +# When using Java 21.0.10 or later and connecting to an older Ghidra Server (pre-12.0.3) the following +# connection error may occur. +# ... SSLHandshakeException: (certificate_unknown) No matching found +# If unable to upgrade your Ghidra Server this property setting may be uncommented to disable the +# hostname check. +#VMARGS=-Djdk.rmi.ssl.client.enableEndpointIdentification=false + # The following property will limit the number of processor cores that Ghidra # will use for thread pools. If not specified, it will use the default number # of processors returned from Runtime.getRuntime().getAvailableProcessors(). diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/server/remote/ServerTestUtil.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/server/remote/ServerTestUtil.java index 2728663074..5aebdaa0d7 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/server/remote/ServerTestUtil.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/server/remote/ServerTestUtil.java @@ -20,7 +20,7 @@ import java.net.*; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.security.KeyStore.PrivateKeyEntry; -import java.util.ArrayList; +import java.util.*; import java.util.function.Consumer; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -955,7 +955,25 @@ public class ServerTestUtil { TEST_PKI_SERVER_PASSPHRASE + "): " + serverKeystorePath); PKIUtils.createKeyEntry("test-sig", TEST_PKI_SERVER_DN, 2, caEntry, serverKeystoreFile, - "PKCS12", null, TEST_PKI_SERVER_PASSPHRASE.toCharArray()); + "PKCS12", getLocalHostnames(), TEST_PKI_SERVER_PASSPHRASE.toCharArray()); + } + + private static Collection getLocalHostnames() throws SocketException { + + // Collect alternate hostnames for inclusion in certificate + Set altNames = new TreeSet<>(); + Enumeration nets = NetworkInterface.getNetworkInterfaces(); + while (nets.hasMoreElements()) { + NetworkInterface netint = nets.nextElement(); + Enumeration addrs = netint.getInetAddresses(); + while (addrs.hasMoreElements()) { + InetAddress addr = addrs.nextElement(); + altNames.add(addr.getHostAddress()); + altNames.add(addr.getHostName()); + altNames.add(addr.getCanonicalHostName()); + } + } + return altNames; } /**