arrow-left

All pages
gitbookPowered by GitBook
1 of 17

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Plugins

Open Plugin Architecture

IDA’s functionality can easily be extended by the use of programmable plug-ins. Plugins may be written to automate routine tasks, for example to enhance the analysis of hostile code or to add specific functionality to our disassembler. Plugins should be written in C++. They may be linked to hot keys or menu items and have full access to the IDA database and may examine or modify the program or use I/O functions. Our SDK contains

  • 4 sample plugins

    • a simple “hello world” type plugin.

    • a sample processor extension plugin (adds 2 NEC V20 specific instructions to the 80Ă—86 processor module).

    • a sample pdb file loader ( as used by IDA itself ).

    • a sample executable decryption plugin.

    • a sample graphing plugin.

  • the source code to a 30+ processor modules!

  • the source code to a 20+ loaders

  • header files (almost 19.000 lines of heavily commented documentation to IDA’s exported interface).

  • import libraries for Borland C/C++ (32 & 64 bits), Microsoft Visual C++ 6 (32 & 64 bits), GNU C/C++ (32 & 64 bits), Watcom 11

  • if you received IDA as a download, the SDK download information can be found in the e-mail you have received.

hashtag
Additional free plugins, from Ilfak’s blog:

Extracts unicode strings from an IDA database

stealth

Stealth against anti-debugging tricks

findcrypt

Identifies some frequently used block ciphers

highlighter

Highlights code that has been single stepped through in a debugging session

unispector

Plugin options

The -O command line switch allows the user to pass options to the plugins. A plugin which uses options should call the get_plugin_options() function to get them.

Since there may be many plugins written by independent programmers, each options will have a prefix -O in front of the plugin name.

For example, a plugin named "decomp" should expect its parameters to be in the following format:

        -Odecomp:option1:option2:option3

In this case, get_plugin_options("decomp") will return the "option1:option2:option3" part of the options string.

If there are several -O options in the command line, they will be concatenated with ':' between them.

List of plugins recognizing '-O' switch

This switch is not available in the IDA Home edition.

Conversion option
Objective-C
Lumina
Pdb
Rust
Golang
Swift
hexrays

Rust plugin

The binaries produced by the Rust compiler have some peculiarities which make them difficult to analyze, such as:

  - non-standard calling conventions
  - non-terminated string literals
  - unusual name mangling scheme

By default, Rust plugin is enabled if one of the following condition is true

  - one address is named 'rust_begin_unwind'
  - the string 'rustc-' can be found somewhere in the program
    If the segment '.rodata' exists, the search is limited to this segment

hashtag
String literal analysis

Rust plugin walks to all addresses in segment with name ending in "__const", ".rodata" or ".rdata" and creates string literals on xref

  - on dref, the string literal is set up to the next dref
  - on cref, Rust tries to retrieve length from nearby instructions
    Arm, Risc-V and pc proc module benefit from this

To force the string literal detection:

  idaapi.load_and_run_plugin("rust", 1)

hashtag
Demangling name

Rust plugin also offers the possibility to configure a demangler library for rust. By default the plugin will use the librustdemangle library that is shipped with IDA. You can disable this feature in 'Edit>Plugin>Rust language helper' or specify another library to use.

See cfg/rust.cfg for the possible options

hashtag
List of '-Orust' options

hashtag
Example

This disable the plugin for this session of IDA.

picture_search

picture_search is a plugin that allows you to search for, and inspect pictures that are embedded in the binary.

The key feature of the plugin is the "Search for pictures" action, available in the menu, that will scan the entire binary (or the selection if there is one) for so-called "magic" numbers of well-known image types (PNG, JPEG, ...), and present the results in a tabular fashion:

Note: at this point, pictures have not been decoded yet; the plugin has merely spotted what looks like the start of pictures. Decoding will only happen when triggering any of the following actions.

Double-clicking any row of that list will show the picture directly in IDA. Opening the context menu will reveal even more possibilities: open the picture in the OS's default viewer, save it, jump to its start address...

In addition to this very handy scanning feature, the plugin will add the "Open picture" action to the disassembly listing's context menu when the current position happens to be near data that matches the well-known image types' magic numbers.

Plugins Shipped with IDA

IDA natively is shipped with repository of plugins, that are inside your IDA folder. You do not need to install them separately, but in this section you'll find guides on how to use their basic features.

List of plugins shipped with IDA:

Plugin Contest

Analyzing software in general and reverse-engineering in specifically are difficult. It is challenging even with a first-class tool like IDA: quite frequently, the limitations of the tool reveal themselves. That's why IDA can be programmed in multiple ways: with the built-in scriptable language, with Python 3, and plugins in C/C++.

hashtag
Plugin contest in a nutshell:

  • Create an innovative and useful extension of our products and win the contest!

Three cash prizes are on the stake: The first place is 3000 USD, the second place is 2000 USD, and the third place is 1000 USD.

  • Who can participate: all IDA license holders.

  • Want to know more? Check our contest rules

    Golang
  • dscu

  • Objective-C analysis

  • picture_search

  • gooMBA

  • IDAClang

  • Rust
    Swift
      - on  : enable rust plugin for this session of IDA
      - off : disable rust plugin for this session of IDA
                     [Address]         |[Format]
            .noptrdata:0000000000511620|GIF89a
            .noptrdata:00000000005133E0|PNG
            .noptrdata:0000000000517460|JPEG
            .noptrdata:000000000051ADA0|BMP
    "Search"arrow-up-right
      -Orust:off

    DWARF plugin

    hashtag
    DWARF plugin

    The DWARF plugin will search for DWARF-encoded debug information either in the input file, or a "companion" file (using a strategy similar to that of GDB), when some is found, will extract the following:

      - type information
      - function names, prototypes, local variables
      - global variables names & types

    In addition, the DWARF plugin provides source-level debugging.

    hashtag
    Dialog box

    'cfg/dwarf.cfg' file presents in details all the options

    hashtag
    List of '-Odwarf' options

    Golang plugin

    Golang binaries are by default statically linked and full of metadata therefore a lot can be gained from annotating a Golang binary's contents using recovered metadata.

    hashtag
    Detection

    The golang plugin's analysis only happens by default if the input file is detected as a Golang file. There are multiple mechanisms in place to detect that:

     - if a Golang startup signature matches the entry point (PC-only)
     - if the Golang plugin detects a Golang-specific segment name
     - if the elf loader finds a "Go" note in the input file
     - on PE files: if certain Golang symbol names or a Go build id signature is found

    hashtag
    Analysis

    The metadata parsed by the golang plugin falls under two main categories:

    The package paths of functions and types are used to create folders. This analysis will occur upon `ev_newfile` (when a new file has been loaded) if Golang has been detected.

    hashtag
    Actions

    This action is useful to force a full search of the binary for Golang metadata. It will first attempt to parse a pclntab at the current address, if this is unsuccessful it will perform a full search of the binary for the pclntab's signature and parse it if found. In addition, it will also attempt to locate and parse the type information.

    hashtag
    Calling Conventions

    Golang has its own calling convention(s), denoted in IDA as `__golang`. In fact, Golang has two different calling conventions: a stack-based CC (abi0) and a newer register-based CC (abiinternal). The version of Golang and thus which calling convention to use will be automatically inferred from metadata structures; It is also controllable through the `force_regabi` command line option.

    hashtag
    List of `-Ogolang` options

    Command line options take precedence over config file options.

    See cfg/golang.cfg for available configuration options.

    hashtag
    Examples

    forcing analysis and register-based calling convention

    disabling the plugin

    Swift plugin

    hashtag
    Demangling

    The swift plugin uses libSwiftDemangle to demangle Swift names. Note that IDA already had a built-in swift demangler, but it was becoming difficult to maintain. In the long-term we hope to fully deprecate IDA's custom swift demangler in favor of libSwiftDemangle.

    However, the new approach still hasn't been fully integrated into IDA, so there may be times when IDA's old swift demangler produces more desirable results.

    'cfg/swift.cfg' file presents all the options

    '-Oswift' command line switches can be used to enable or disable some plugin options.

    hashtag
    List of options

    hashtag
    Examples

    Do not group functions into folders.

    Patfind plugin

    hashtag
    Patfind plugin

    Patfind plugin makes it possible to automatically find functions in binary files.

    It relies on bit pattern definitions for typical function starts and function ends.

    Those bit patterns are defined in XML files, based on Ghidra's function patterns format. A collection of bit pattern files is provided for the commonly used CPU architectures.

    It is possible to add new architectures by simply adding a new XML file, just like the other XML files.

    It's also possible to add, remove or change existing patterns for better matching.

    hashtag
    Configuration

    'cfg/patfind.cfg' file presents all the options

    The config file also contains the documentation on how to use or change the XML pattern files.

    If desired, new XML files can be added to the 'cfg/ghidra_patterns/' directory.

    '-Opatfind' command line switches can be used to select the type of run differently for this session of IDA.

    hashtag
    List of options

    hashtag
    Examples

    Borland RTTI descriptors plugin

    hashtag
    Borland RTTI descriptors plugin

    This plugin allows you to create/delete/view Borland RTTI descriptors.

    These descriptors appear in programs written on BCC++ or Borland C++ Builder or Borland Delphi.

    The plugin is available for 32 bits binaries for PE or OMF format.

    FLIRT Signature Bundle

    hashtag
    FLIRT Signature Bundle

    With FLIRT Signature Bundle, designed to be used with (aka FLIRT Signature Manager), you can analyze thousands of signatures and bulk apply them to your binary.

    The bundle contains signatures for modern languages like Golang and Rust, as well as updates for classic compilers. The latest version of the FLIRT Signature Bundle can be downloaded from under SDK and utilities.

    Flirt Signature Bundles will be regularly updated and released independently whenever there is a new compiler, language, or library release.

    hashtag
    Released versions

    hashtag
    2024/09/12 FLIRT Signature Bundle

    Golang

    • Versions: stable versions from 1.10.0 to 1.23

    • Operating Systems: Linux, Windows, MacOS

    • Architectures: arm64 (Windows, Linux, MacOS), arm (Windows, Linux, MacOS), x86 (Windows, Linux) , x86-64 (Windows, Linux)

    C/C++

    • Windows (MSVC):

      • Architectures: arm, arm64, i386, amd64

      • Packages: ATL, CTL, MFC, Windows SDK 10, Windows SDK 11

    • Linux:

      • Distribution: Ubuntu & Debian

      • Architectures: i386, amd64, arm64, armhf, armel, arm, s390x, mips64el, mipsel, mips, ppc64el

      • Packages: libc6, libselinux1, libpcre2, libidn2, libssl, zlib1g, lib32z1, libunistring, libcurl4-gnutls, libcurl4-nss, libcurl4-openssl, libnghttp2, libidn2, librtmp, libssh, libssh-gcrypt, libpsl, libldap, libzstd, libbrotli, libgnutls28, nettle, libgmp, comerr, libsasl2, libbrotli, libtasn1-6, libkeyutils, libffi, uuid, libprotobuf, heimdal-multidev, musl, libplib, libsdl1.2-bundle (libsdl-console, libsdl-sge, libsdl1.2, libsdl-ocaml, libsdl-image1.2, libsdl-kitchensink, libsdl-mixer1.2, libsdl-net1.2, libsdl-sound1.2, libsdl-ttf2.0, libsdl1.2-compat, libsdl-gfx1.2, libsdl-pango), libsdl2-bundle (libsdl2, libsdl2-gfx, libsdl2-image, libsdl2-mixer, libsdl2-net, libsdl2-ttf) Rust

    • Versions 1.77 to 1.81

      • Architectures: arm64, arm, x86, x86-64

      • Operating Systems: Linux, Windows, MacOS

      • Compilers: GCC, LLVM, MSVC

    IDA Feeds
    My Hex-Rays portalarrow-up-right
      Global name               : create global names based on DWARF informations
      Functions                 : Create functions based on DWARF informations
      Use function bounds       : Uses DWARF to determine functions boundaries
      Types (uncheck for speed) : Create types, needed for Apply calling
                                  convention or Function prototype are definitive
      Apply calling convention  : DWARF will try and guess the calling convention
                                  instead of using platform default calling
                                  convention. Needed for Allow __usercall
      Allow __usercall          : If DWARF detects __usercall, allow to use it. If
                                  not allowed, the default calling convention for
                                  the platform will be used
      Function prototypes are definitive: Decompiler will not try to change the
                                         prototype if set. Use this with caution
      Import file names/line numbers: Import all information
      - <demangler_path> : use specific libSwiftDemangle library
      - -d : use the built-in IDA swift demangler (legacy)
      - +d : use libSwiftDemangle swift demangler
      - -m : don't present metadata in nice way
      - +m : present metadata in nice way
      - -e : don't import enumeration types
      - +e : import enumeration types
      - -s : don't import structure types
      - +s : import structure types
      - -v : don't set variable type based on mangled names
      - +v : set variable type based on mangled names
      - -f : don't set function prototype based on mangled names
      - +f : set function prototype based on mangled names
      - -g : don't group functions in folders corresponding to modules
      - +g : group functions in folders corresponding to modules
      autorun=0 : don't automatically search for bit pattern
      autorun=1 : search for bit pattern only on binary like files
      autorun=2 : search for bit pattern on any input file
    hashtag
    Dialog box

    hashtag
    Configuration

     - off : disable the plugin for the current session
     - import_lnnums=1 : import file name and line number into idb
     - function information (e.g. name, package, range) retrieved from the pclntab
     - type information (e.g. name, package, layout, size) retrieved from the typelinks table
      `golang:detect_and_parse` (Edit>Other)
      force                         try to force the analysis
                                    (no detection step needed)
      off                           disable the plugin
      no_rtypes                     do not import any types
      rname_len2                    force the reflect type name format to go1.17
                                    and later (varint encoding: 1-10 bytes)
      rname_len1                    force the reflect type name format to before
                                    go1.17 (2 bytes)
      import_lnnums                 recover file names & line numbers from pclntab
      no_func_end_from_pcval_tabs   do not derive a function's end from pclntab
                                    metadata
      force_regabi[=on|=off]        override calling convention version
                                     `=off`: will force the stack-based CC
                                     `=on`/no value: will force
                                     the register-based CC
      -Ogolang:force:force_regabi
      -Ogolang:off
      -Oswift:-g
      -Oswift:/tmp/libSwiftDemangle_custom.dylib
      -Opatfind:autorun=0
      - List RTTI descriptors      : Displays the list of recognized RTTI
                                     descriptors. IDA automatically recognizes
                                     most descriptors. The list will include only
                                     the descriptors specified by the 'RTTI type'
                                     radiobuttons. You can also delete any
                                     descriptor from list.
      - List RTTI problems        :  Displays the list of problematic RTTI
                                     descriptors. The list will include only the
                                     descriptors specified by the 'RTTI type'
                                     radiobuttons. You can also delete any
                                     descriptor from list.
      - Delete list of descriptors : Delete the whole list of RTTI descriptors.
      - Delete list of problems    : Delete the whole list of problematic RTTI
                                     descriptors.
      - Create C++ descriptor      : Manually invoke creation of a C++ descriptor
                                     at the current cursor location.
      - Create Pascal descriptor   : Manually invoke creation of a Pascal
                                     descriptor at the current cursor location.
      - Create Pascal or C++ descriptor : Manually invoke creation of a Pascal or
                                          C++ descriptor at the current cursor
                                          location. This action tries to create a
                                          Pascal descriptor. If it fails, then it
                                          tries to create a C++ descriptor.
    
      - RTTI type radiobutton group : Controls which descriptors will appear in
                                      the displayed lists.
                                      Options are :
                                        * Include C++
                                        * Include Pascal
                                        * Include both
    
       - Create recursive : If this option is set, then IDA tries to create
                            descriptors recursively: if a created descriptor
                            refers to another unknown descriptor, then it will be
                            created and so on.

    IDA Feeds

    hashtag
    IDA Feeds

    Starting with IDA 9.0, we introduced IDA Feeds (aka FLIRT Signature Manager), the tool designed to ease the application of new signatures through updatable libraries, (known as IDA FLIRT Signature Bundles), shipped alongside other IDA plugins just out-of-the-box.

    hashtag
    What is IDA Feeds?

    Ida Feeds helps you identify which signatures to apply when analyzing binary files, especially when you don't know which static libraries were linked to them. Rather than manually applying signatures, IDA Feeds automatically scans and applies many signatures in seconds. Just open the signature folder, allow IDA to scan and find the possible matches, and then bulk apply the suggested signatures.

    IDA Feeds uses the , which are going to be regularly updated and released to keep you up to date with the newest recognizable signatures.

    hashtag
    IDA Feeds configuration and setup

    The proper configuration of the plugin is required to start using IDA Feeds and make it visible in the plugins list under Edit -> Plugins submenu.

    hashtag
    Prerequisites

    • idalib configured properly (check and )

    • Downloaded the latest IDA FLIRT Signature Bundle. You can get it from our under SDK and utilities.

    hashtag
    Install and activate your virtual environment

    We recommend using IDA Feeds from within your Python virtual environment (venv). To do so, ensure you have created and activated your virtual environment before proceeding.

    hashtag
    Linux & macOS

    1. Create a Python virtual environment at your preferred location

      Replace ~/.idapro/venv with your path.

    2. Activate your virtual environment

    hashtag
    Windows

    1. Create a Python virtual environment at your preferred location

      Replace .idapro\venv with your path.

    2. Activate your virtual environment

    hashtag
    Installing requirements/dependencies

    Install requirements for Python modules from within your virtual environment.

    1. Navigate to the plugin/ida_feeds folder within the IDA Pro installation directory and install the requirements.

    1. Create symbolic link (optional)

    Linux & OSX

    Windows

    After successfully performing these steps, IDA Feeds plugin should be visible in the Edit -> Plugins submenu and ready to try.

    hashtag
    How to use IDA Feeds?

    To use IDA Feeds, you need to first.

    1. Go to the Edit -> Plugins -> IDA Feeds. IDA Feeds will open in a new Signature Tools subview.

    2. In the Signature Tools window, click Open signatures folder and select the folder with the downloaded FLIRT signature bundle (1), or leave the preloaded signatures already provided with your IDA instance.

    1. Select all or chosen signature files, and then click Run multi-core analysis (2).

    2. Check the results and click Apply signatures to bulk apply (3) correct matches.

    How to write your own plugin?

    Do you want to create custom plugins and wonder where to start? Check our tutorials based on the language of your choice:

    Create plugins with C++ SDK

    Create plugins with IDAPython

    FLIRT Signature Bundles
    idalib installation
    activation steps
    Download Center in My Hex-Rays portalarrow-up-right
    configure the plugin
    `python -m venv ~/.idapro/venv`
    source ~/.idapro/venv/bin/activate
    python -m venv %YOURPROFILE%\.idapro\venv
    
    %YOURPROFILE%\.idapro\venv\Scripts\activate
    
    python3 -m pip install -r requirements.txt
    ln -s $(pwd) $HOME/.idapro/plugins/ida_feeds
    mklink /D "%APPDATA%\Hex-Rays\IDA Pro\plugins\ida_feeds" "%cd%"

    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 bulk of the plugin's work is done at file load time, when it will parse all Objective-C type information embedded in the binary, and use 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 with:

      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:

    Decompilation

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

    When a function is decompiled, the plugin will analyze any calls to objc_msgSend, and use the arguments to determine if objc_msgSend will ultimately invoke one of the methods in the current database.

    If such a situation is detected, the plugin will replace the call to objc_msgSend with a call to the target method, and add an xref to the method. This is done in the hopes that continued use of the decompiler will improve 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:

    Or uncheck the "Enable decompiler plugin for Objective-C" option in:

    Debugging

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

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

    Or by unchecking the "Enable SIP for Objective-C" option in:

    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 will try to calculate the address of method that is being invoked, and break at the method address rather than step into the objc_msgSend function itself.

    You can perform this action with shortcut:

    Or via the menu option:

    Or programmatically with:

    This action can be very useful, but you must be careful. When invoked, the action will automatically run to the address of objc_msgSend, analyze its arguments, then continue 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:

    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:

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

    Or programmatically with:

    You can also perform block analysis on a specific function:

    Or with shortcut:

    Or programmatically:

    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 hexrays 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 with:

    Or:

    Command Line

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

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

    For example, -Oobjc:+v:+l:-s will enable verbose and lazy mode, and will disable the objc SIP.

    See also

    DYLD Shared Cache Utils

    This plugin (nicknamed "dscu" for brevity) is essentially just an extension of the Mach-O loader. It allows you to manually load modules from a dyldcache that were not loaded when first opening the cache in IDA (the plugin is only activated after using the "single module" option for a dyldcache).

    For a quick overview of the dscu functionality, see menu File>Load file>DYLD Shared Cache Utils.

    hashtag
    Loading Modules

    There are a few ways to manually load a module from the cache:

    1) Use File>Load file>DYLD Shared Cache Utils>Load module... and choose which module to load

    https://clang.llvm.org/docs/Block-ABI-Apple.htmlarrow-up-right
    Debugger for macOS
    Remote iOS debugger
    DYLD Shared Cache Utils

    2) Right-click on an unmapped address in the disassembly, and select 'Load module <module name>'

    3) Programatically:

    hashtag
    Loading Sections

    dscu also allows you to load a subset of a given module.

    Any section from any of the dyldcache's submodules can be loaded individually. This is especially useful when analyzing Objective-C code, since often times it is convenient to only load Objective-C info from a given module without loading all of its code.

    For example, if you see a pointer to a selector string that has not been loaded:

    Right-click on "0x1AECFF7F9" and dscu will provide you with two options:

    The UIKitCore module is huge, so perhaps you don't want to load the entire thing, but still want to clean up the disassembly. If you choose "Load UIKitCore:__objc_methname", dscu will load only these selector strings into the database:

    This operation is much faster, and still provides a lot of benefit to the analysis.

    Sections can also be loaded via:

    or programmatically with:

    See also

    • Objective-C Analysis Plugin

    • Debugger for macOS

    • Remote iOS debugger

      Edit>Other>Objective-C>Objective-C Options...
      -Oobjc:-h
      Edit>Other>Objective-C>Objective-C Options...
      n = idaapi.netnode()
      n.create("$ objc")
      n.supset(1, "/module/path", 'R')
      idaapi.load_and_run_plugin("objc", 3)
      -Oobjc:-s
      Edit>Other>Objective-C>Objective-C Options...
      Shift+O
      Debugger>Run until message received
      idaapi.load_and_run_plugin("objc", 2)
      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);
      Edit>Other>Objective-C>Analyze stack-allocated blocks (entire database)
      idaapi.load_and_run_plugin("objc", 5)
      Edit>Other>Objective-C>Analyze stack-allocated blocks (current function)
      Ctrl+Shift+S
      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)
      Edit>Other>Objective-C>Re-analyze global block functions
      idaapi.load_and_run_plugin("objc", 4)
      v: verbose mode
      s: source info provider
      h: hexrays decompiler analysis
      l: lazy mode
      n = idaapi.netnode()
      n.create("$ dscu")
      n.supset(2, "/usr/lib/libobjc.A.dylib")
      idaapi.load_and_run_plugin("dscu", 1)
      ADRP  X8, #0x1AECFF7F9@PAGE
      ADD   X1, X8, #0x1AECFF7F9@PAGEOFF ; SEL
      MOV   X0, X21 ; id
      BL    _objc_msgSend_0
      Load UIKitCore:__objc_methname
      Load UIKitCore
      ADRP  X8, #sel_alloc@PAGE ; "alloc"
      ADD   X1, X8, #sel_alloc@PAGEOFF ; SEL
      MOV   X0, X21 ; id
      BL    _objc_msgSend_0
      File>Load file>DYLD Shared Cache Utils>Load section...
      node = idaapi.netnode()
      node.create("$ dscu")
      node.altset(3, 0x1AECFF7F9) # address can be any address in the section
      idaapi.load_and_run_plugin("dscu", 2)