Ok, it seems the following rule works for the normal exit:
RULE JVM Exit
DO System.out.println("Got it!")
Yes, you are right that you can attach a rule to Shutdown.runHooks() to execute actions at shutdown. However, you may want to consider some alternatives to this since runHooks does not always get called.
If you want to intercept all JVM exits and also see the shutdown status you probably want to attach a rule to java.lang.Shutdown.exit(int) and/or java.lang.Shutdown.halt(int). Note that Shutdown is package public so these methods will not be called directly from application code. Also, Shutdown.exit(int) calls Shutdown.halt(int) so you might just want to attach a single rule to halt().
You could also attach a rule to the exit(int) and halt(int) methods of java.lang.Runtime. These are the public APIs which call the corresponding methods of Shutdown after performing a security check. This will guarantee to trap all shutdown operations which are initiated from Java.
The other method you might need to consider attaching a rule to is Shutdown.shutdown(). In the Sun JVM this is called from native code when the virtual machine identifies that all remaining threads are daemons. So, a call to this method indicates that all application threads have exited.