# How the AI Decompiler Selects and Handles Objective‑C and Swift Decompilation with Different Models in IPSW

> Discover how the IPSW AI decompiler selects and handles Objective‑C and Swift decompilation using different LLM models and auto‑detection for seamless code analysis.

- Repository: [blacktop/ipsw](https://github.com/blacktop/ipsw)
- Tags: deep-dive
- Published: 2026-02-26

---

**The IPSW AI decompiler selects the target language via the `--dec-lang` flag or auto‑detection heuristics, then chooses the LLM provider and model through `--dec-llm` and `--dec-model`, falling back to interactive selection when no model is specified.**

The `blacktop/ipsw` toolkit provides an AI‑powered decompiler that transforms assembly into readable Objective‑C, Swift, or C code. Understanding how the AI decompiler selects and handles decompilation for ObjC and Swift with different models is essential for reverse engineers who need precise control over output language and LLM performance.

## Language Selection and Auto‑Detection Logic

### The `--dec-lang` Flag and Heuristic Detection

The decompiler determines the target language through the `--dec-lang` CLI flag or automatic content analysis. In [`pkg/disass/prompt.go`](https://github.com/blacktop/ipsw/blob/main/pkg/disass/prompt.go) (lines 25‑63), the `GetPrompt` function normalizes user input—converting `swift` to `Swift` and `objc` to `Objective‑C`—and applies a heuristic when no flag is provided. If the assembly contains the substring `swift_`, the decompiler assumes Swift; if it contains `_objc_`, it selects Objective‑C; otherwise, it defaults to C.

### Lexer Mapping for Syntax Highlighting

Once the language is determined, the system maps it to a Chroma lexer for optional colorization. The `GetPrompt` function returns the appropriate lexer identifier—`swift`, `objc`, or `c`—which [`internal/commands/disass/disass.go`](https://github.com/blacktop/ipsw/blob/main/internal/commands/disass/disass.go) later uses with `quick.Highlight` to apply the user‑specified theme when `cfg.Color` is enabled.

## Model Selection and Provider Configuration

### The `--dec-llm` and `--dec-model` Flags

The decompiler supports multiple LLM providers controlled by the `--dec-llm` flag (default: `copilot`), including Copilot, OpenAI, Anthropic, and Ollama. The `--dec-model` flag specifies the exact model name, such as `GPT‑4` or `Claude 3.5 Sonnet`. These values are parsed in [`cmd/ipsw/cmd/macho/macho_disass.go`](https://github.com/blacktop/ipsw/blob/main/cmd/ipsw/cmd/macho/macho_disass.go) (lines 57‑58) and bound to Viper configuration keys, then retrieved in lines 73‑88 to populate the `dcmd.Config` struct passed to the decompiler.

### Interactive Model Selection

When `--dec-model` is omitted, the decompiler initiates an interactive selection flow. In [`internal/commands/disass/disass.go`](https://github.com/blacktop/ipsw/blob/main/internal/commands/disass/disass.go) (lines 44‑88), the `ai.NewAI` function creates a provider‑specific client. If `cfg.Model` is empty, the client queries the provider’s available models via `llm.Models()`, sorts the results, and either auto‑selects a single default model or launches an interactive `survey.Select` prompt for the user to choose from the provider’s catalog.

## The Decompilation Execution Flow

### Building the Configuration

The decompilation process begins in [`macho_disass.go`](https://github.com/blacktop/ipsw/blob/main/macho_disass.go) where CLI flags are converted into a structured configuration. The code constructs a `dcmd.Config` instance containing the language, LLM provider, model name, colorization preferences, and theme settings. This configuration object serves as the single source of truth for the entire decompilation pipeline.

### Prompt Construction and Language Enforcement

The `dcmd.Decompile` function invokes `disass.GetPrompt` from [`pkg/disass/prompt.go`](https://github.com/blacktop/ipsw/blob/main/pkg/disass/prompt.go) to generate the LLM prompt. This function embeds the assembly code and explicitly instructs the model to output only the selected language’s code block. The prompt template enforces the language constraint, ensuring that even if the assembly contains mixed ObjC and Swift symbols, the output adheres to the user’s selection or the auto‑detected heuristic.

### LLM Client Initialization and Inference

With the prompt prepared, [`internal/commands/disass/disass.go`](https://github.com/blacktop/ipsw/blob/main/internal/commands/disass/disass.go) initializes the LLM client via `ai.NewAI`. The client uses the provider‑specific implementation to authenticate and establish a connection. The `llm.Chat()` method transmits the prompt to the selected model and returns the raw decompiled code string. If colorization is enabled, the output passes through `quick.Highlight` using the lexer determined earlier, producing syntax‑highlighted terminal output.

## Practical Examples

The following commands demonstrate how to leverage the AI decompiler with different language and model configurations.

Decompile a Swift function using the default Copilot provider and interactive model selection:

```bash
ipsw macho disass MyApp --symbol "_mySwiftFunc" --dec --dec-lang Swift

```

Force Objective‑C output with OpenAI and explicitly select GPT‑4:

```bash
ipsw macho disass MyApp --symbol "_objcMethod" \
    --dec --dec-lang ObjC \
    --dec-llm openai --dec-model "GPT-4"

```

Use a local Ollama instance with a specific model for Swift decompilation:

```bash
ipsw dsc disass dyld_shared_cache --vaddr 0x1234 --dec \
    --dec-lang Swift --dec-llm ollama --dec-model "codellama:34b"

```

## Summary

- The AI decompiler selects the target language via the `--dec-lang` flag or auto‑detects it using `swift_` and `_objc_` heuristics in [`pkg/disass/prompt.go`](https://github.com/blacktop/ipsw/blob/main/pkg/disass/prompt.go).
- Language choice determines the Chroma lexer for syntax highlighting and constrains the LLM prompt to output only the specified language.
- Model selection flows through `--dec-llm` (provider) and `--dec-model` (specific model), with fallback to interactive selection in [`internal/commands/disass/disass.go`](https://github.com/blacktop/ipsw/blob/main/internal/commands/disass/disass.go) when no model is specified.
- The decompilation pipeline in [`cmd/ipsw/cmd/macho/macho_disass.go`](https://github.com/blacktop/ipsw/blob/main/cmd/ipsw/cmd/macho/macho_disass.go) orchestrates configuration building, prompt generation, LLM inference, and optional colorization.

## Frequently Asked Questions

### How does the decompiler automatically detect the programming language?

The decompiler inspects the assembly code for characteristic substrings. In [`pkg/disass/prompt.go`](https://github.com/blacktop/ipsw/blob/main/pkg/disass/prompt.go), the `GetPrompt` function searches for `swift_` to identify Swift code and `_objc_` to identify Objective‑C. If neither pattern matches, it defaults to C. This heuristic runs automatically when the `--dec-lang` flag is omitted.

### Can I use a local LLM instead of cloud providers like OpenAI or Copilot?

Yes. The `--dec-llm` flag supports `ollama` as a provider, allowing you to run decompilation against local models. Specify the model name with `--dec-model` (for example, `codellama:34b`). The [`internal/commands/disass/disass.go`](https://github.com/blacktop/ipsw/blob/main/internal/commands/disass/disass.go) file handles the Ollama client initialization the same way it manages cloud providers.

### What happens if I do not specify a model with `--dec-model`?

When `--dec-model` is omitted, the decompiler enters interactive mode. The `ai.NewAI` function in [`internal/commands/disass/disass.go`](https://github.com/blacktop/ipsw/blob/main/internal/commands/disass/disass.go) queries the selected provider for its available models via `llm.Models()`. If only one model exists, it auto‑selects that model; otherwise, it presents an interactive `survey.Select` prompt for you to choose from the provider’s catalog.

### Does the language selection affect the LLM prompt itself?

Yes. The `GetPrompt` function in [`pkg/disass/prompt.go`](https://github.com/blacktop/ipsw/blob/main/pkg/disass/prompt.go) constructs a template that explicitly instructs the LLM to produce output only in the selected language. This constraint ensures that even when decompiling assembly that contains mixed Objective‑C and Swift runtime calls, the model returns a single, consistent language block matching your `--dec-lang` selection or the auto‑detected heuristic.