> For the complete documentation index, see [llms.txt](https://docs.hex-rays.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hex-rays.com/add-ons/plugins/concepts/plugins-shipped-with-ida/objective-c-analysis-plugin.md).

# Objective-C Analysis Plugin

The objc plugin performs Objective-C specific analysis on the database.

For an overview of what the plugin can do, see the menu options in **Edit → Other → Objective-C**, or the config options in `objc.cfg`.

## Type Information

The plugin does the bulk of its work at file load time, when it parses all Objective-C type information embedded in the binary, and uses this to create `tinfo_t` structures for all known classes and construct prototypes for all known methods.

This analysis can be invoked manually at any time via **Edit → Other → Objective-C → Reload Objective-C info**.

Or:

```
  idaapi.load_and_run_plugin("objc", 1)
```

You can also disable objc analysis at load time with command line option:

```
  -Oobjc:+l
```

Or check the "Lazy mode" option in **Edit → Other → Objective-C → Objective-C Options...**.

## Decompilation

The plugin will also perform Objective-C analysis during decompilation.

When a function is decompiled, the plugin analyzes any calls to `objc_msgSend`, and uses the arguments to determine if `objc_msgSend` ultimately invokes one of the methods in the current database.

If such a situation is detected, the plugin replaces the call to `objc_msgSend` with a call to the target method, and adds an xref to the method. This is done in the hopes that continued use of the decompiler improves call graphs for Objective-C binaries.

If the target method has type information, then the return type can be used to refine the types of local variables in the pseudocode, which in turn could lead to more method calls being detected, and so on.

You can disable objc analysis in the pseudocode with command line option:

```
  -Oobjc:-h
```

Or uncheck the "Enable decompiler plugin for Objective-C" option in **Edit → Other → Objective-C → Objective-C Options...**.

## Debugging

The objc plugin also provides tools for dynamic analysis.

During debugging, you can analyze objc info for a specific library by right-clicking in the Modules window and selecting "Load debug info".

This operation can also be performed programmatically with:

```
  n = idaapi.netnode()
  n.create("$ objc")
  n.supset(1, "/module/path", 'R')
  idaapi.load_and_run_plugin("objc", 3)
```

If you prefer that objc not perform analysis during "Load debug info" (for example, if DWARF information is already available for a module), you can disable this functionality with command line option:

```
  -Oobjc:-s
```

Or by unchecking the "Enable SIP for Objective-C" option in **Edit → Other → Objective-C → Objective-C Options...**.

## Step Into Message

The plugin also implements a "step into" debugger action for Objective-C.

If you use this action before a call to `objc_msgSend`, objc tries to calculate the address of the method that is being invoked, and breaks at the method address rather than step into the `objc_msgSend` function itself.

You can perform this action with shortcut:

```
  Shift+O
```

Or via the menu option **Debugger → Run until message received**.

Alternatively, do it programmatically with:

```
  idaapi.load_and_run_plugin("objc", 2)
```

This action can be very useful, but you must be careful. When invoked, the action automatically runs to the address of `objc_msgSend`, analyzes its arguments, then continues to the target method.

If there is no subsequent call to `objc_msgSend` in the program, you will lose control of the process. It is best to use this action only when you are sure that IP is in the vicinity of an `objc_msgSend` call.

## NSConcreteStackBlock

The objc plugin can also be used to analyze Apple binaries that make heavy use of blocks: see [Block ABI (Apple)](https://clang.llvm.org/docs/Block-ABI-Apple.html).

The analysis involves identifying NSConcreteStackBlock instances on the stack, and creating a specialized `Block_layout` structure to apply to the function's stack frame.

The end result transforms the following sequence of statements:

```
  loc_BF60:                                 Block_layout_BF60 v1;
    v1 = _NSConcreteStackBlock;             v1.isa        = _NSConcreteStackBlock;
    v2 = 0x...;                             v1.flags      = 0x...;
    v3 = 0;                                 v1.reserved   = 0;
    v4 = __block_invoke;             =>     v1.invoke     = __block_invoke;
    v5 = &__block_descriptor_tmp;           v1.descriptor = &__block_descriptor_tmp;
    v6 = ...                                v1.lvar1      = ...
    v7 = ...                                v1.lvar2      = ...
    ...                                     ...
    func(&v1);                              func(&v1);
```

Already this cleans up the analysis quite a lot, but more importantly this new `Block_layout_BF60` structure will be applied to the prototype of `__block_invoke`, which can heavily improve the pseudocode.

Block analysis can be performed on the database via **Edit → Other → Objective-C → Analyze stack-allocated blocks (entire database)**.

Or programmatically with:

```
  idaapi.load_and_run_plugin("objc", 5)
```

You can also perform block analysis on a specific function via **Edit → Other → Objective-C → Analyze stack-allocated blocks (current function)**.

Or with shortcut:

```
  Ctrl+Shift+S
```

Alternatively, do it programmatically with:

```
  n = idaapi.netnode()
  n.create("$ objc")
  n.altset(1, 0xBF60, 'R') # the address can be any address within the function
  idaapi.load_and_run_plugin("objc", 5)
```

These actions work in both the disassembly and pseudocode windows, but note that you must refresh the pseudocode with F5 for the changes to take full effect.

Also, please note that this feature makes use of the microcode in the Hex-Rays SDK, so you must have the decompiler in order to use it.

## NSConcreteGlobalBlock

Global blocks (i.e. blocks that don't make use of local variables) are much easier to analyze, and simply involve identifying references to `NSConcreteGlobalBlock` in the `__const` segment.

Global blocks are analyzed automatically at load time, but the analysis can be performed manually at any time via **Edit → Other → Objective-C → Re-analyze global block functions**.

Or:

```
  idaapi.load_and_run_plugin("objc", 4)
```

## Command Line

Here's a summary of the command-line arguments that can be passed to objc:

Its features can be enabled or disabled using `+` or `-`, followed by one of the following characters:

```
  v: verbose mode
  s: source info provider
  h: hexrays decompiler analysis
  l: lazy mode
```

For example, `-Oobjc:+v:+l:-s` enables verbose and lazy mode, and disables the objc SIP.

See also

* [Debugger for macOS](/core/debugger/concepts/local-debugging/intel-arm-macos-debugger.md)
* [Remote iOS debugger](/core/debugger/concepts/remote-debugging/remote-ios-debugger.md)
* [DYLD Shared Cache Utils](/add-ons/plugins/concepts/plugins-shipped-with-ida/dyld-shared-cache-utils.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.hex-rays.com/add-ons/plugins/concepts/plugins-shipped-with-ida/objective-c-analysis-plugin.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
