Skip to content

Commit

Permalink
improve install process
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-hunhoff committed Feb 1, 2024
1 parent cae4588 commit d010512
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 55 deletions.
7 changes: 3 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ jobs:
python-version: ${{ matrix.python-version }}
- name: Configure temp folder
run: mkdir ../tmp
- name: Install Python Jep
- name: Install Python requirements
run: |
pip install numpy
pip install jep==4.2.0
pip install -r util/requirements.txt
pip install -r data/python/tests/requirements.txt
python -c "import importlib.util;import pathlib;print(pathlib.Path(importlib.util.find_spec('jep').origin).parent)"
- name: Download dependencies Linux/macOS
if : ${{ matrix.os != 'windows-latest' }}
Expand Down Expand Up @@ -73,7 +73,6 @@ jobs:
run: python util/ghidrathon_configure.py ../tmp/ghidra/ghidra_PUBLIC -d
- name: Run tests
run: |
pip install packaging
../tmp/ghidra/ghidra_PUBLIC/support/analyzeHeadless ${{ github.workspace }}/../tmp/ghidra test -Import ${{ github.workspace }}/../tmp/ghidra/ghidra_PUBLIC/GPL/DemanglerGnu/os/linux_x86_64/demangler_gnu_v2_24 -PostScript ${{ github.workspace }}/data/python/tests/hello.py -PostScript ${{ github.workspace }}/data/python/tests/runall.py > ../tmp/log.txt
- name: Check tests
run: |
Expand Down
93 changes: 43 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,65 @@

Ghidrathon is a Ghidra extension that adds Python 3 scripting capabilities to Ghidra. Why? Ghidra natively supports scripting in Java and Jython. Unfortunately, many open-source analysis tools, like [capa](https://github.com/mandiant/capa), [Unicorn Engine](https://github.com/unicorn-engine/unicorn), [angr](https://github.com/angr/angr), etc., are written in Python 3 making it difficult, and in some cases, impossible to use these tools in Ghidra. More so the security community has released several great plugins for other SRE frameworks like IDA Pro and Binary Ninja, but again, because many of these plugins use Python 3 it is difficult to port them to Ghidra. Ghidrathon helps you use existing and develop new Python 3 tooling in Ghidra and script Ghidra using modern Python in a way that tightly integrates with Ghidra's UI.

![example](./data/ghidrathon_interp.png)

Check out:

- The overview in our first [Ghidrathon blog post](https://www.mandiant.com/resources/blog/ghidrathon-snaking-ghidra-python-3-scripting)

Ghidrathon replaces the existing Python 2.7 extension implemented via Jython. This includes the interactive interpreter window, integration with the Ghidra Script Manager, and script execution in Ghidra headless mode.

## Python 3 Interpreter Window
## Installing Ghidrathon

### Requirements
Tool | Version |Source |
|---|---|---|
| Ghidrathon | `>= 4.0.0` | https://github.com/mandiant/Ghidrathon/releases |
| Python | `>= 3.8.0` | https://www.python.org/downloads |
| Jep | `== 4.2.0` | https://pypi.org/project/jep |
| Ghidra | `>= 10.3.2` | https://github.com/NationalSecurityAgency/ghidra/releases |
| Java | `>= 17.0.0` | https://adoptium.net/temurin/releases |

Use the following steps to install Ghidrathon to your Ghidra environment:

1. Download and unzip the latest Ghidrathon [release](https://github.com/mandiant/Ghidrathon/releases)
2. Execute the following commands using the Python interpreter that you'd like to use with Ghidrathon:
```
$ python -m pip install -r requirements.txt
$ python ghidrathon_configure.py <absolute_path_to_ghidra_install_dir>
```
3. Install the Ghidrathon extension (`.zip`) into Ghidra:
* Using Ghidra's UI:
* Navigate to `File > Install Extensions...`
* Click the green `+` button
* Navigate to the Ghidrathon extension (`.zip`)
* Click `Ok`
* Using a limited environment:
* Extract the Ghidrathon extension (`.zip`) to `<absolute_path_to_ghidra_install_dir>\Ghidra\Extensions`

### Switching Python Interpreters

You can switch Ghidrathon to use a different Python interpreter by running `ghidrathon_configure.py` using the new Python interpreter.

### Python Virtual Environments

Ghidrathon supports Python virtual environments. **To use a Python virtual environment, complete step `1` from within your virtual environment.** Do the same when running `ghidrathon_configure.py` to switch the Ghidrathon to use a different interpreter.

## Using Ghidrathon

### Python 3 Interpreter Window

The interpreter window provides interactive access to your Python 3 interpreter. Click "Window" and select "Ghidrathon" to open the interpreter window.

![example](./data/ghidrathon_interp.png)

## Ghidra Script Manager Integration
### Ghidra Script Manager Integration

Ghidrathon integrates directly with the Ghidra Script Manager enabling you to create, edit, and execute Python 3 scripts within Ghidra. Click "Create New Script" and select "Python 3" to create a new Python 3 script. Click "Run Script" or "Run Editors's Script" to execute your Python 3 script and check the Ghidra Console window for script output.

![example](./data/ghidrathon_script.png)

## Ghidra Headless Mode
### Ghidra Headless Mode

Ghidrathon helps you execute Python 3 scripts in Ghidra headless mode. Execute the `analyzeHeadless` script located in your Ghidra installation folder, specify your Python 3 script, and check the console window for script output.

Expand All @@ -39,17 +79,6 @@ Function _start @ 0x101060: 1 blocks, 13 instructions
Function deregister_tm_clones @ 0x101090: 4 blocks, 9 instructions
Function register_tm_clones @ 0x1010c0: 4 blocks, 14 instructions
Function __do_global_dtors_aux @ 0x101100: 5 blocks, 14 instructions
Function frame_dummy @ 0x101140: 1 blocks, 2 instructions
Function main @ 0x101149: 1 blocks, 9 instructions
Function __libc_csu_init @ 0x101170: 4 blocks, 34 instructions
Function __libc_csu_fini @ 0x1011e0: 1 blocks, 2 instructions
Function _fini @ 0x1011e8: 1 blocks, 4 instructions
Function _ITM_deregisterTMCloneTable @ 0x105000: 0 blocks, 0 instructions
Function printf @ 0x105008: 0 blocks, 0 instructions
Function __libc_start_main @ 0x105010: 0 blocks, 0 instructions
Function __gmon_start__ @ 0x105018: 0 blocks, 0 instructions
Function _ITM_registerTMCloneTable @ 0x105020: 0 blocks, 0 instructions
Function __cxa_finalize @ 0x105028: 0 blocks, 0 instructions
[...]
INFO REPORT: Post-analysis succeeded for file: /example.o (HeadlessAnalyzer)
INFO REPORT: Save succeeded for processed file: /example.o (HeadlessAnalyzer)
Expand All @@ -75,42 +104,6 @@ Ghidrathon links your local Python installation to Ghidra using the open-source

For more information on how Jep works to embed Python in Java see their documentation [here](https://github.com/ninia/jep/wiki/How-Jep-Works).

## Installing Ghidrathon

### Requirements
Tool | Version |Source |
|---|---|---|
| Ghidrathon | `>= 4.0.0` | https://github.com/mandiant/Ghidrathon/releases |
| Python | `>= 3.8.0` | https://www.python.org/downloads |
| Jep | `== 4.2.0` | https://pypi.org/project/jep |
| Ghidra | `>= 10.3.2` | https://github.com/NationalSecurityAgency/ghidra/releases |
| Java | `>= 17.0.0` | https://adoptium.net/temurin/releases |

Use the following steps to install Ghidrathon to your Ghidra environment:

1. Download and unzip the latest Ghidrathon [release](https://github.com/mandiant/Ghidrathon/releases)
2. Execute the following commands using the Python interpreter that you'd like to use with Ghidrathon:
```
$ python -m pip install jep==4.2.0
$ python ghidrathon_configure.py <absolute_path_to_ghidra_install_dir>
```
3. Install the Ghidrathon extension (`.zip`) into Ghidra:
* Using Ghidra's UI:
* Navigate to `File > Install Extensions...`
* Click the green `+` button
* Navigate to the Ghidrathon extension (`.zip`)
* Click `Ok`
* Using a limited environment:
* Extract the Ghidrathon extension (`.zip`) to `<absolute_path_to_ghidra_install_dir>\Ghidra\Extensions`

### Switching Python Interpreters

You can switch Ghidrathon to use a different Python interpreter by running `ghidrathon_configure.py` using the new Python interpreter.

### Python Virtual Environments

Ghidrathon supports Python virtual environments. **To use a Python virtual environment, complete step `1` from within your virtual environment.** Do the same when running `ghidrathon_configure.py` to switch the Ghidrathon to use a different interpreter.

## Considerations

Ghidrathon uses the open-source library [Jep](https://github.com/ninia/jep) which uses the Java Native Interface (JNI) to embed Python in the JVM. The Ghidra developers advise against JNI in Ghidra for reasons discussed [here](https://github.com/NationalSecurityAgency/ghidra/issues/175).
2 changes: 2 additions & 0 deletions data/python/tests/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
numpy==1.26.3
packaging==23.2.0
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,28 @@ private GhidrathonInterpreter(GhidrathonConfig config) throws JepException, IOEx

// we must configure jep.MainInterpreter once before creating our first jep.SharedInterpreter
if (jepMainInterpreterInitialized.get() == false) {
Msg.info(GhidrathonInterpreter.class, "Configuring jep.MainInterpreter.");

configureJepMainInterpreter();
jepMainInterpreterInitialized.set(true);
}

// we must set JepConfig once before creating the first jep.SharedInterpreter
if (jepConfigInitialized.get() == false) {
Msg.info(GhidrathonInterpreter.class, "Configuring jep.JepConfig.");
setJepConfig();
jepConfigInitialized.set(true);
}

Msg.info(GhidrathonInterpreter.class, "Creating new jep.SharedInterpreter.");

// create new Jep SharedInterpreter instance
jep_ = new jep.SharedInterpreter();

// we must configure Python sys module AFTER the first jep.SharedInterpreter is created
if (jepPythonSysModuleInitialized.get() == false) {
Msg.info(GhidrathonInterpreter.class, "Configuring Python sys module.");

jep_.eval(
String.format("import sys;sys.executable=sys._base_executable=r\"%s\"", this.pythonFile));
// site module configures other necessary sys vars, e.g. sys.prefix, using sys.executable
Expand Down Expand Up @@ -301,7 +308,7 @@ private void configureJepMainInterpreter() throws JepException, FileNotFoundExce

// we can't auto import the site module becuase we are running an embedded Python interpreter
config.setNoSiteFlag(1);
config.setIgnoreEnvironmentFlag(1);
// config.setIgnoreEnvironmentFlag(1);

MainInterpreter.setInitParams(config);
} catch (IllegalStateException e) {
Expand Down
1 change: 1 addition & 0 deletions util/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
jep==4.2.0

0 comments on commit d010512

Please sign in to comment.