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

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 (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 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 (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 (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 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 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 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:

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

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

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:

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.
  • 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 when no model is specified.
  • The decompilation pipeline in 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, 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 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 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 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.

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 →