GhidrOllama
A Ghidra script that enables the analysis of selected functions and instructions using Large Language Models (LLMs). It aims to make reverse-engineering more efficient by using Ollama's API directly within Ghidra.
Install / Use
/learn @lr-m/GhidrOllamaREADME
Ollama API interaction Ghidra script for LLM-assisted reverse-engineering.
</div>What is this?
This script interacts with Ollama's API to interact with Large Language Models (LLMs). It utilizes the Ollama API to perform various reverse engineering tasks without leaving Ghidra. It supports both local and remote instances of Ollama. This script is inspired by GptHidra.
Supported Models
This script supports any model that Ollama supports
Ollama also recently added support for any model available on HuggingFace in GGUF format, for example:
ollama run hf.co/arcee-ai/SuperNova-Medius-GGUF
Prerequisites
Ollama Setup
Feel free to replace llama3.1:8b with any of the Ollama-compatible models
curl -fsSL https://ollama.com/install.sh | sh
ollama run llama3.1:8b
Now you should be good to go, localhost:11434 should be ready to handle requests
Note: This script also supports remote instances, set the IP address and port during first configuration.
What can it do?
- Explain the function that is currently in the decompiler window
- Suggest a name for the current function, will automatically name the function if this has been enabled
- Rewrite current function with recommended comments
- Completely rewrite the current function, trying to improve function/parameter/variable names and also add comments
- User can ask a question about a function
- Find bugs/suggest potential vulnerabilities in current function (more just to make sure you've covered everything, some suggestions are dumb as it doesn't have the context)
- Use a modified version of this LeafBlowerLeafFunctions.py Ghidra Script to automate analysis of potential 'leaf' functions such as strcpy, memcpy, strlen, etc in binaries with stripped symbols, auto rename if this is enabled
- Explain the single assembly instruction that is currently selected in the listing window
- Explain multiple assembly instructions that are currently selected in the listing window
- General prompt entry for asking questions (rather than having to Google, good for simple stuff)
Configuration Options
The following config options are available, and can be configured on first run:
- Server IP : If using remote instance, set to IP of remote instance, otherwise enter
localhost - Port : If your instance is on a different port, change it here - default is
11434 - Scheme : Select
httporhttpsdepending on how your instance is configured - Model : Select the model you wish to use for analysis, you can change this at any point
- Project-specific prompt : Used to give some additional context to the model if this is required
- Response Comments : Some options store the responses as a comment at the top of the function, this can be enabled/disabled here
- Auto-renaming : Some options try and automatically rename functions based on the responses, this can be enabled/disabled here
Options 11 & 12 can be used to adjust settings after first-run.
Usage
- Place the GhidrOllama.py script and the ghidrollama_utils directory in your Ghidra script directory (usually
~/ghidra_scripts). - Find a function/instruction you want to feed to the LLM
- Run the script from the Script Manager window
- If this is the first time running the script, complete the initial configuration (this can be changed later)
- Select how you want to function/instruction to be analysed
- Wait until the output is printed to the console (wait time varies depending on model and specifications of host)
Ways to Run
Going into the script window to run this script every time is inconvenient, the script can easily be run in the following ways:
- Keybinding: The default keybinding for this script is Q
- Toolbar: A small icon on the toolbar can be clicked to run the script
Keybinding
To enable, once you have added your script into the list of Ghidra script directories, locate the script in the list. Right click the result, and select "Assign key binding". If it prompts for a key, enter q.

Toolbar
To enable the toolbar icon, locate the script in the script manager, and click the tick box in the first column (the In Toolbar column). The GhidrOllama icon should appear in the toolbar.
![]()
Notes
- It is worth noting that the analysis will only be as good as the model, this script basically just bridges the models and Ghidra
- The better the model (more parameters, slower) the more comprehensive and correct the analysis will be (most of the time!)
- If you want a quick overview of a function, llama3.1:8b is quick and gives a decent analysis
- Be careful with large functions and low-context models, if the function is too big for the context window, the model will respond with complete gibberish (if it responds at all)
Function Analysis Examples
Below is an implementation of strchr() as seen in Ghidra decompile window with stripped symbols:
char * FUN_801a7490(char *param_1,char param_2)
{
char cVar1;
char *pcVar2;
cVar1 = *param_1;
if (cVar1 == '\0') {
pcVar2 = (char *)0x0;
}
else {
pcVar2 = (char *)0x0;
do {
if (param_2 == cVar1) {
pcVar2 = param_1;
}
param_1 = param_1 + 1;
cVar1 = *param_1;
} while (cVar1 != '\0');
}
if (param_2 != '\0') {
param_1 = pcVar2;
}
return param_1;
}
The following analysis was performed using the llama3.1:8b model.
Option 1 - Function Summary
Interesting function! As a reverse engineer assistant, I'll break down what this code does and provide some insights.
Function Signature
char * FUN_801a7490(char *param_1,char param_2)The function takes two parameters:
param_1: a pointer to a character array ( likely a string)param_2: a single characterFunction Body
The function does the following:
- It checks if the first character of
param_1(cVar1) is\0. If it is, thenpcVar2is set to(char *)0x0, which is essentially NULL.- If
cVar1is not\0, it enters a loop where:
- It checks if the character
param_2matches the current character inparam_1(cVar1). If they match, thenpcVar2is set to the address ofparam_1.- The pointer
param_1is incremented by one to point to the next character in the string.- The loop continues until the end of the string is reached (i.e.,
cVar1becomes\0).
- If
param_2is not null, then the function returns the address stored inpcVar2.Insights
Based on this code, it appears to be searching for a character (
param_2) within a string (param_1). The search stops as soon as it finds the first occurrence of that character.The
if (param_2 != '\0') { param_1 = pcVar2; }statement suggests that ifparam_2is found in the string, the function returns a pointer to that location within the string. If not, it still returns a valid pointer ( likely pointing to the beginning of the string).
Option 2 - Function Naming
GhidrOllama renamed the function to find_char_in_string
Option 3 - Add Comments
Here is the modified function with additional comments to explain its behavior:
char * FUN_801a7490(char *param_1, char param_2) { // Initialize a character variable (cVar1) to hold the first character of param_1. char cVar1; // Initialize a pointer variable (pcVar2) to point to null initially. char *pcVar2; // Assign the first character of param_1 to cVar1. This will be used as a starting point for searching in the string. cVar1 = *param_1; // Check if the input string (param_1) is empty ('\0'). if (cVar1 == '\0') { // If it's empty, set pcVar2 to null, effectively indicating that no match was found. pcVar2 = (char *)0x0; } else { // Initialize pcVar2 to null, which will be updated later if a match is found. pcVar2 = (char *)0x0; // Loop through the string param_1 until we reach its end ('\0'). do { // Check if the current character (cVar1) matches the input parameter (param_2). if (param_2 == cVar1) { // If it's a match, update pcVar2 to point to the beginning of param_1, effectively returning its address. pcVar2 = param_1; } // Move on to the next character in param_1 by incrementing its pointer (param_1 = param_1 + 1). param_1 = param_1 + 1; // Update cVar1 to hold the new current character. cVar1 = *param_1; } while (cVar1 != '\0'); } // Check if a match was found by verifying that param_2 is not null ('\0'). if (param_2 != '\0') { // If it's not null, update param_1 to point to the matched string in pcVar2. param_1 = pcVar2; } // Return the address of the matched string or an empty string if no match was found. return param_1; }This function appears to be searching for a single character (param_2) within a string (param_1). It returns the address of the matched string, or null if no match is found. If the input string is empty, it returns null immediately.
Option 4 - Rewrite Function
Here is the rewritten function with more descriptive names and comments:
/** * Find the index of a given character in a string. * * @param str T
