How to Integrate and Use the AI-Powered Decompiler with OpenAI or Ollama

To integrate and use the AI-powered decompiler with OpenAI or Ollama, export your API key or start a local Ollama server, then run ipsw macho disass --dec --dec-llm <provider> --dec-model <model> to convert ARM64 assembly into C, Objective-C, or Swift pseudocode.

The blacktop/ipsw toolkit ships with an AI-powered decompiler that transforms disassembled ARM64 binaries into high-level source representations using Large Language Models (LLMs). Through a generic abstraction layer in internal/ai/ai.go, the tool supports multiple providers while maintaining a consistent interface for prompt generation and response handling. This guide walks through the exact integration steps for both OpenAI and Ollama backends, referencing the specific source files and configuration structures that power the feature.

Architecture Overview

The decompiler architecture centers on the AI interface defined in internal/ai/ai.go. This interface normalizes interactions across different LLM backends, allowing the core logic to remain provider-agnostic.

The factory function ai.NewAI() instantiates concrete implementations based on the normalized provider string. Two primary providers ship with the codebase:

When you run the macho disass command with decompilation enabled, the tool chains these components: CLI flags populate a disass.Config struct, which feeds into ai.Config, ultimately calling the provider's Chat() method after prompt generation via disass.GetPrompt.

Prerequisites and Provider Setup

OpenAI Requirements

Before using OpenAI models, export your API key:

export OPENAI_API_KEY=sk-...

The openai.NewOpenAI constructor in internal/ai/openai/openai.go reads this environment variable during client initialization. If the variable is missing, the CLI returns a "failed to create llm client" error.

Ollama Requirements

For local inference, start the Ollama server (default endpoint http://localhost:11434):

ollama serve &

Pull a compatible model such as codellama:7b or gemma2:2b:

ollama pull codellama:7b

The ollama.NewOllama implementation validates available models against the local server's model list before executing chat requests.

Step-by-Step CLI Integration

Decompiling with OpenAI

Run the decompiler against a Mach-O binary or IPA:

ipsw macho disass MyApp.ipa \
  --dec \
  --dec-llm openai \
  --dec-model "gpt-4o-mini" \
  --dec-lang c \
  --dec-temp 0.2 \
  --dec-top-p 0.1

The --dec flag triggers decompilation mode. The --dec-llm parameter maps to the Provider field in ai.Config, while --dec-model specifies the exact model identifier. Temperature and top-p values control output randomness via the Temperature and TopP fields in internal/commands/disass/disass.go.

Decompiling with Ollama

For local processing without API costs:

ipsw macho disass MyApp.ipa \
  --dec \
  --dec-llm ollama \
  --dec-model "codellama:7b" \
  --dec-lang swift \
  --dec-temp 0.3 \
  --dec-top-p 0.9

Because Ollama runs locally, no API key is required. The provider automatically queries ollama.List() to confirm the model exists before sending the prompt built by disass.GetPrompt.

Caching and Output Configuration

The decompiler implements an optional SQLite-backed caching layer in internal/db/ai. By default, successful LLM responses are cached to avoid redundant API calls. To bypass caching during iterative testing, append the --dec-nocache flag.

For readability, combine --dec with --color and --dec-theme (e.g., nord, github) to syntax-highlight the generated pseudocode using Chroma.

Programmatic Integration

You can invoke the decompiler directly from Go without shelling out to the CLI. Import the command package and construct a configuration:

import (
    "context"
    dcmd "github.com/blacktop/ipsw/internal/commands/disass"
)

func decompile(asm string) (string, error) {
    cfg := &dcmd.Config{
        UUID:        "analysis-run-1",
        LLM:         "openai",      // or "ollama"
        Model:       "gpt-4o-mini", // empty string prompts interactive selection
        Language:    "c",
        Temperature: 0.2,
        TopP:        0.1,
    }
    
    // GetPrompt generates the syntax-highlighted assembly context
    prompt, _, err := dcmd.GetPrompt(asm, cfg.Language)
    if err != nil {
        return "", err
    }
    cfg.Prompt = prompt
    
    return dcmd.Decompile(asm, cfg)
}

This mirrors the CLI workflow: create an ai.Config, instantiate the provider via ai.NewAI(), and execute Chat() with the formatted prompt.

Summary

  • The AI-powered decompiler resides in blacktop/ipsw and supports both cloud (OpenAI) and local (Ollama) LLM providers through the internal/ai abstraction layer.
  • OpenAI integration requires the OPENAI_API_KEY environment variable and uses the client in internal/ai/openai/openai.go.
  • Ollama integration requires a running local server at localhost:11434 and uses the client in internal/ai/ollama/ollama.go.
  • Invoke decompilation via ipsw macho disass --dec --dec-llm <provider> --dec-model <model>, with optional caching control and syntax highlighting.
  • For custom workflows, import internal/commands/disass and call dcmd.Decompile() directly with an appropriate Config struct.

Frequently Asked Questions

What environment variables are required for the OpenAI provider?

The OpenAI provider requires the OPENAI_API_KEY environment variable to be set to a valid OpenAI API secret key. The client initialization in internal/ai/openai/openai.go reads this variable; if absent, the tool exits with a "failed to create llm client" error.

Can I use the decompiler without an internet connection?

Yes, when using the Ollama provider. Since Ollama runs models locally on your machine (default endpoint http://localhost:11434), you can decompile binaries completely offline after pulling the desired model via ollama pull.

How does the caching mechanism work?

Unless you specify --dec-nocache, the decompiler stores LLM request-response pairs in a SQLite database managed by internal/db/ai. Before making an API call, the tool checks this cache using a hash of the prompt, returning the stored result immediately if found to reduce costs and latency.

Which model names are supported?

You can use any model available to your chosen provider. For OpenAI, valid examples include gpt-4o-mini, gpt-4o, or gpt-4-turbo. For Ollama, use names exactly as shown by ollama list, such as codellama:7b, gemma2:2b, or llama3.1:8b. If you omit --dec-model, the CLI interactively prompts you to select from available models.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →