Skip to content

Commit

Permalink
add jshell interpreter (#19)
Browse files Browse the repository at this point in the history
Adds a basic Java interpreter implemented using JShell. This interpreter
is intended to be similar in functionality to the Jython interpreter
included with Ghidra, but more useful for developing and testing Java
scripts.
  • Loading branch information
goatshriek authored Jul 19, 2022
1 parent ad8193d commit 1e11541
Show file tree
Hide file tree
Showing 21 changed files with 839 additions and 66 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## [1.3.0] - 2022-07-18
### Added
- JShell interactive interpreter


## [1.2.0] - 2022-06-11
### Changed
- Upgrade to JRuby 9.3.4.0 (Ruby 2.6.8)
Expand Down
24 changes: 14 additions & 10 deletions NOTICE
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
Ruby Dragon
Copyright 2021 Joel E. Anderson
Copyright 2021-2022 Joel E. Anderson

The JRuby binary included in the lib folder is Copyright (c) 2007-2018 The JRuby
project and covered by a tri EPL 2.0/GPL 2/LGPL 2.1 license. For the source code
of the project, refer to the project repository at
https://github.com/jruby/jruby. The full terms of the license can be found at
The JRuby project is Copyright (c) 2007-2018 The JRuby project and covered by a
tri EPL 2.0/GPL 2/LGPL 2.1 license. For the source code of the project, refer
to the project repository at https://github.com/jruby/jruby. The full terms of
the license can be found at
https://github.com/jruby/jruby/blob/master/COPYING.

The Java log included in the src/main/resources/images folder is Copyright (c)
Oracle.

The Kotlin logo included in the src/main/resources/images folder is
Copyright (c) Kotlin Foundation. Kotlin is covered under the Apache 2.0 license.
For more details on the language and its resources, see https://kotlinlang.org/.
For the full terms of the license included with Kotlin, see
https://github.com/JetBrains/kotlin/blob/master/license/LICENSE.txt.

The Clojure binary included in the lib folder is from the Clojure project,
Copyright (c) Rich Hickey. All rights reserved. It is covered by the EPL 1.0
license. For the source code of the project, refer to the project repository at
https://github.com/clojure/clojure. The full terms of the license can be found
at https://github.com/clojure/clojure/blob/master/epl-v10.html.
The Clojure logo included in the src/main/resources/images folder is from the
Clojure project, Copyright (c) Rich Hickey. All rights reserved. Clojure is
covered by the EPL 1.0 license. For the source code of the project, refer to
the project repository at https://github.com/clojure/clojure. The full terms
of the license can be found at
https://github.com/clojure/clojure/blob/master/epl-v10.html.

31 changes: 26 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
[![build](https://github.com/goatshriek/ruby-dragon/actions/workflows/build.yml/badge.svg)](https://github.com/goatshriek/ruby-dragon/actions/workflows/build.yml)
[![Apache 2.0 License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

Ruby, Kotlin, and Clojure support for Ghidra, both interactive and scripting.
Ruby, Kotlin, JShell, and Clojure support for Ghidra, both interactive and
scripting.


## Installation
Expand All @@ -17,9 +18,10 @@ You will then need to activate the plugin before using it. You might get
prompted to do this next time you open the CodeBrowser tool, in which case you
can simply select OK. Otherwise, you can manually activate it by opening the
CodeBrowser tool, going to `File->Configure...`, and selecting the `RubyDragon`
plugin for Ruby, the `KotlinDragon` plugin for Kotlin, and the `ClojureDragon`
plugin for Clojure. They should appear in the `Ghidra Core` listing, but you
can check the `Configure All Plugins` option if you aren't able to find them.
plugin for Ruby, the `KotlinDragon` plugin for Kotlin, the `JShellDragon` plugin
for the Java interpreter, and the `ClojureDragon` plugin for Clojure. They
should appear in the `Ghidra Core` listing, but you can check the `Configure All
Plugins` option if you aren't able to find them.

If you need to remove a language plugin, you can do so by unchecking the box in
the configuration dialog in the CodeBrowser tool. If you want to remove the
Expand All @@ -34,7 +36,7 @@ development.
## Ruby Usage
Once the RubyDragon plugin is enabled, you will be able to open an interactive
Ruby session from the CodeBrowser tool by going to `Window->Ruby`. This is a
tandard IRB session provided by JRuby.
standard IRB session provided by JRuby.

The same environmental variables provided in Java and Python scripts are also
available in this session, as the following global variables:
Expand Down Expand Up @@ -84,6 +86,25 @@ currentSelection
Kotlin scripts use a `kts` extension as they are interpreted as scripts rather
than being compiled to java first.


## JShell Usage
The JShell plugin provides an interactive Java interpreter by JShell, a Java
REPL included in Java. It provides the same built in variables that are
available in Java scripts:

```
currentAddress
currentHighlight
currentLocation
currentProgram
currentSelection
```

This interpreter is especially handy when writing Java scripts, as it allows you
to iteratively test snippets of code from the script without needing to do any
sort of conversion to other languages like Python or Kotlin.


## Clojure Usage
Clojure follows the same patterns as the other languages, being provided in the
`ClojureDragon` plugin and reachable from the `Window->Clojure` menu option.
Expand Down
8 changes: 1 addition & 7 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,7 @@ or want to make a suggestion, please submit an issue on the project's
[Github page](https://github.com/goatshriek/ruby-dragon).


## 1.2.0
* [ADD] **JShell Support**
JShell is an obvious feature to add, giving parity to Python and Java in both
scripts and interactive options.


## 1.3.0
## 1.4.0
* [ADD] **Groovy Language Bindings**
While initially aimed at Ruby, this project is ultimately aimed at making a
variety of JVM-based languages available to Ghidra users. Groovy is an easy
Expand Down
1 change: 1 addition & 0 deletions src/main/help/help/TOC_Source.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
<tocref id="Ghidra Functionality">
<tocref id="Scripting">
<tocdef id="Clojure Interpreter" sortgroup="z" text="Clojure Interpreter" target="help/topics/rubydragon/clojure.html" />
<tocdef id="JShell Interpreter" sortgroup="z" text="JShell Interpreter" target="help/topics/rubydragon/jshell.html" />
<tocdef id="Kotlin Interpreter" sortgroup="z" text="Kotlin Interpreter" target="help/topics/rubydragon/kotlin.html" />
<tocdef id="Ruby Interpreter" sortgroup="z" text="Ruby Interpreter" target="help/topics/rubydragon/ruby.html" />
</tocref>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
85 changes: 85 additions & 0 deletions src/main/help/help/topics/rubydragon/jshell.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<HTML>
<HEAD>
<META name="generator" content=
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
<META http-equiv="Content-Language" content="en-us">
<META http-equiv="Content-Type" content="text/html; charset=windows-1252">
<META name="GENERATOR" content="Microsoft FrontPage 4.0">
<META name="ProgId" content="FrontPage.Editor.Document">

<TITLE>JShell Interpreter</TITLE>
<LINK rel="stylesheet" type="text/css" href="../../shared/Frontpage.css">
</HEAD>

<BODY>
<H1><a name="JShell"></a>JShell Interpreter</H1>

<P>
Ruby Dragon adds an interactive Java shell to Ghidra for use in script
development and running snippets of Java.
</P>

<P>
This is accomplished using JShell, which is included in Java.
</P>

<H2>Environment</H2>
<BLOCKQUOTE>
<P>
The JShell interactive interpreter runs as a simple Java REPL.

The same variables that are available in Ghidra's Java and Python
environments are also available in the JShell interpreter as global
variables:
</P>

<PRE>
currentAddress
currentHighlight
currentLocation
currentProgram
currentSelection
</PRE>
</BLOCKQUOTE>

<H2>Copy/Paste</H2>
<BLOCKQUOTE>
<P>
Copy and paste from within the JShell interpreter should work as expected
for your given environment:
<UL>
<LI><B>Windows:</B>&nbsp;&nbsp;CTRL+C / CTRL+V</LI>
<LI><B>Linux:</B>&nbsp;&nbsp;CTRL+C / CTRL+V</LI>
<LI><B>OS X:</B>&nbsp;&nbsp;COMMAND+C / COMMAND+V</LI>
</UL>
</P>
</BLOCKQUOTE>

<H2><A name="Clear_Interpreter"></A>Clear <IMG border="0" src="images/erase16.png"></H2>
<BLOCKQUOTE>
<P>
This command clears the interpreter's display. Its effect is purely visual.
It does not affect the state of the interpreter in any way.
</P>
</BLOCKQUOTE>

<H2><A name="Interrupt_Interpreter"></A>Interrupt <IMG border="0" src="images/dialog-cancel.png"></H2>
<BLOCKQUOTE>
<P>
This command issues a stop action to the interpreter, which can be used to interrupt
long running commands or loops.
</P>
</BLOCKQUOTE>

<H2><A name="Reset_Interpreter"></A>Reset <IMG border="0" src="images/reload3.png"></H2>
<BLOCKQUOTE>
<P>
This command resets the interpreter, which clears the display and resets all state.
</P>
</BLOCKQUOTE>

<P align="left" class="providedbyplugin">Provided by: <I>RubyDragon</I></P>
</BODY>
</HTML>
15 changes: 15 additions & 0 deletions src/main/java/rubydragon/DragonPlugin.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package rubydragon;

import java.util.List;

import javax.swing.ImageIcon;

import ghidra.app.plugin.ProgramPlugin;
import ghidra.app.plugin.core.console.CodeCompletion;
import ghidra.app.plugin.core.interpreter.InterpreterConnection;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.listing.Program;
Expand Down Expand Up @@ -35,6 +38,18 @@ public DragonPlugin(PluginTool tool, String name) {
this.name = name;
}

/**
* Get a list of completions for the given command prefix.
*
* @param cmd The command to try to complete.
*
* @return A list of possible code completions.
*/
@Override
public List<CodeCompletion> getCompletions(String cmd) {
return getInterpreter().getCompletions(cmd);
}

/**
* The icon for this plugin.
*/
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/rubydragon/GhidraInterpreter.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.List;

import ghidra.app.plugin.core.console.CodeCompletion;
import ghidra.app.plugin.core.interpreter.InterpreterConsole;
import ghidra.app.script.GhidraScript;
import ghidra.app.script.GhidraState;
Expand Down Expand Up @@ -63,6 +65,15 @@ public void loadState(GhidraState state) {
updateAddress(state.getCurrentAddress());
}

/**
* Get a list of completions for the given command prefix.
*
* @param cmd The command to try to complete.
*
* @return A list of possible code completions.
*/
public abstract List<CodeCompletion> getCompletions(String cmd);

/**
* Runs the given script with the arguments and state provided.
*
Expand Down
15 changes: 0 additions & 15 deletions src/main/java/rubydragon/clojure/ClojureDragonPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,8 @@

package rubydragon.clojure;

import java.util.ArrayList;
import java.util.List;

import ghidra.app.CorePluginPackage;
import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.core.console.CodeCompletion;
import ghidra.app.plugin.core.interpreter.InterpreterConnection;
import ghidra.app.plugin.core.interpreter.InterpreterConsole;
import ghidra.app.plugin.core.interpreter.InterpreterPanelService;
Expand Down Expand Up @@ -72,17 +68,6 @@ protected void dispose() {
super.dispose();
}

/**
* Get a list of completions for the given command prefix.
*
* Currently not implemented, and will always return an empty list.
*/
@Override
public List<CodeCompletion> getCompletions(String cmd) {
// TODO currently just an empty list, need to actually implement
return new ArrayList<CodeCompletion>();
}

/**
* Gives the clojure interpreter currently in use.
*
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/rubydragon/clojure/ClojureGhidraInterpreter.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

import clojure.lang.LineNumberingPushbackReader;
import clojure.lang.Namespace;
import clojure.lang.RT;
import clojure.lang.Symbol;
import clojure.lang.Var;
import generic.jar.ResourceFile;
import ghidra.app.plugin.core.console.CodeCompletion;
import ghidra.app.plugin.core.interpreter.InterpreterConsole;
import ghidra.app.script.GhidraScript;
import ghidra.app.script.GhidraState;
Expand Down Expand Up @@ -98,6 +100,19 @@ public void dispose() {
// do nothing
}

/**
* Get a list of completions for the given command prefix.
*
* Currently not implemented, and will always return an empty list.
*
* @param cmd The beginning of a command to try to complete.
*
* @return A list of possible code completions.
*/
public List<CodeCompletion> getCompletions(String cmd) {
return new ArrayList<CodeCompletion>();
}

/**
* Runs the given script with the arguments and state provided.
*
Expand Down
Loading

0 comments on commit 1e11541

Please sign in to comment.