Apparency

A User Guide

Looking for something specific? The User Guide and FAQ are indexed within the app — open Apparency, click on the Help menu (Command-?), and type in the Search field. Results listed under Help Topics link directly to the appropriate User Guide section or FAQ entry here.

Opening an App in Apparency

general info

There are several ways to open an app using Apparency:

If you don't see the Open With Apparency item in the Services menu or in the Finder context menu, choose Finder > Services > Services Preferences, go to the Development group, and make sure that Open With Apparency is checked. You can also add a keyboard shortcut here, if you wish, but that's not necessary to make the menu item appear.

Whichever method you choose, Apparency opens a new window, showing the app itself, along with any components inside it: Apparency main window

You can actually open any macOS bundle with Apparency, including an app plug-in or a standalone framework. You can also open a “bare” executable file, such as one found in /usr/local/bin. A bare executable can have many of the same attributes as a bundle, and can even have an embedded Info.plist.

Opening a System Component by Name

If you want to examine a system component — that is, a component that is part of macOS itself — Apparency can make it easier to find and open the right one.

Choose File > Open System Component (Cmd-Control-O), and start typing the name of the component — or some portion thereof. Apparency will show the system components that match this name: opening a system component

When you select an item in this list, Apparency will open that component. Or you can continue to refine your search text, until the component you want appears in the list.

You can use this mechanism to find and open the following types of system components:

Of course, there are other types of system components, so this mechanism won't work for everything.

Opening a System Library with a String Literal

The Open System Component mechanism can be helpful if you know the name of the component you want. But sometimes all you have is a string — such as from an alert dialog, a message in the Console log, or perhaps a key found via a defaults(1) command. How can you find the responsible macOS system framework or library?

Choose File > Open System Library with String Literal (Shift-Cmd-Control-O). Type (or paste) the string you have, and Apparency will show the system libraries that reference this string: opening a system library with a string literal

Here we say system libraries, rather than components, because this mechanism finds only system frameworks and dylibs that have been moved into the DYLD shared cache; it won't search macOS executables or XPC services that still exist fully on-disk.

This mechanism searches for the given string in several sections of the __TEXT segment which are marked as containing C string literals — including __cstring (C string literals, and higher-level string types built upon them), __oslogstring (literal format strings sent to the Unified Logging system), __objc_classname (the names of Objective-C classes), and __objc_methname (the names of Objective-C selectors and properties).

This mechanism also searches for the given string in the list of dynamically linked libraries for each system library — that is, it finds the system frameworks or dylibs that use another library matching the given string. (In Mach-O terms, these are the strings from the LC_LOAD_DYLIB commands.) This can be helpful to find where some code of interest is getting invoked.

For each match, Apparency will show the actual string that it found in that system library (or the first such string, if a single library contains multiple matches). Select a match to open that system library in Apparency, after which you can get more information using Component > Show String Literals from Executable, as described here.

Alternatively, you might want to proceed directly to some sort of disassembly of the library, such as analyzing it using the Hopper Disassembler.

Opening a Component from the Terminal using the “appy” Command-Line Tool

If you're working in the Terminal, you might already know the path of the component you want to examine, and would like to open it directly. You can do this with Apparency's command-line tool, called appy.

The appy tool is delivered inside the Apparency application bundle, but consistent with our philosophy that you should decide when and how to install software on your Mac, the app does not try to install the command line tool for you. Choose Help > About the Command-Line Tool for instructions on adding the appy tool to your path.

The appy command line is straightforward: just give it the (possibly relative) path to the component that you want to open in Apparency:

appy Utilities/Grapher.app

Of course, there are other ways to open a file in a specific app, such as with open(1). But in addition to being more succinct, appy also allows you to open system dylibs that have been moved into the DYLD shared cache, and that don't even exist on disk anymore. So you can do something like this:

appy /usr/lib/libxar.1.dylib
and Apparency will open the library, in spite of there being no actual file at that path!
When opening a cached dylib like this, you must provide the canonical path, which is the one known to the DYLD shared cache. This is often a name with some sort of version number embedded, while the “generic” name was a symbolic link. In the example above, we have to use libxar.1.dylib instead of libxar.dylib, because the latter is only a symbolic link (and not even one that still exists). If you don't know the proper canonical path, try using the Open System Component command to search for the library.

Examining the App Structure

The browser, on the left side of the main Apparency window, shows the basic structure of the app: examining app structure

At the top of this view is the app itself. Most apps also contain other components inside them — frameworks, plug-ins, app extensions, Spotlight importers and so on. These components are shown underneath the main app, using a hierarchical view similar to the Finder's List view. If any of the components contain sub-components, use the disclosure button to expand these further.

Apparency doesn't show all of the individual files inside the app bundle. The Finder is a better tool for navigating files: control-click the app icon and choose Show Package Contents.

Rather, Apparency shows bundles — and bare executables — that are found in specific places within the app, as defined by macOS. For example, macOS requires app extensions to be placed in Contents/PlugIns, so that is one place that Apparency looks. The point is to show components that add to system functionality (as is the case with app extensions, for example), as well as those that are simply part of the app's internal organization (such as frameworks).

By default, Apparency looks for components only in well-defined places, as defined by macOS, rather than examining every file and folder inside the app (which could become quite slow for large apps). However, this may miss components, which sometimes live in other places, such as the Resources folder. If you want Apparency to try harder to find components, when you select the app in the File > Open dialog, check Look for components in de facto “code places” before clicking Open. If the app is already open in Apparency, use File > Re-open with Options to quickly re-open it.

The columns of the browser show some basic information about the app, and any components:

Click on the Name, Kind or Version column title to re-order the components accordingly. This can be useful for an app with a large number of components.

Getting Information About a Component

The info pane, on the right side of the main Apparency window, shows information about the app or other component that is currently selected in the browser: show component info

General Information

In the top part of the info pane, Apparency shows general information about the app or component:

general info

Most of these attributes can be selected, and thus copied. Unfortunately, this can make the cycling attributes, such as Kind, a bit squirrelly to work with. If you single-click, Apparency will still cycle through the different values. If you double- or triple-click, Apparency will instead enter selection mode, with the appropriate select-word or select-all behavior. If you want to get out of selection mode, so that the attribute values cycle again, press the Escape key. Or click on the label for the attribute, instead of the attribute value: this will always cycle the attribute, regardless of selection state.

Document Types and Services Provided

In the middle part of the info pane, Apparency shows a summary of the definitions and services that the app provides to macOS:

document type info

For each of these, Apparency simply shows how many of each type is found (because it is difficult to summarize the contents in any succinct way). To see more information, click the link to Info.plist button button in front of the number: this will show either the Info Property List, with the appropriate property selected and expanded, or for launchd jobs, the Launch Information inspector.

Code Signature, Sandbox and Gatekeeper Info

In the lower part of the info pane, Apparency shows the status of the code signature and other security features:

signature info

Note that you can select more than one component in the browser. When you do this, the info pane will show the information that is identical for all of the selected components. This is a quick way to determine if multiple components support the same processor architectures, or have the same code-signing identity, for example. Any attributes that have different values for one or more of the selected components will show Multiple values instead.

Getting Details About a Component

While the info pane gives you a summary of the selected app or component, there are buttons in the toolbar that allow you to see more details. (Some of these are also available through buttons in the info pane itself; use whichever one is more convenient.)

Show the Code Signature

If the selected app or component was signed, click the Signature toolbar button Signature toolbar button (or use Cmd-Shift-S) to see the actual signing certificate and other details about the verification of the signature (including the applicable Gatekeeper policy, as discussed above). signature and trust dialog

Click the Show Certificate button to examine the certificate that created the signature, and the entire chain up to the Certificate Authority, which is typically the Apple Root CA. Select an individual certificate in the chain, and click the disclosure arrow next to Details to see more information.

You can also export a certificate by dragging the certificate icon (from the lower pane) and dropping it in the Finder. This will give you a DER-format file that you can open with Certificate Assistant, or manipulate with command-line tools like security(1) or openssl(1).

Show the Info Property List

The information property list — or simply, the Info.plist — contains a number of Apple-defined properties. These tell macOS how the app or component works, what it can do, what icon to show, what documents it can handle, and many other things. Apparency extracts a few interesting bits of the Info.plist to show in its info pane — such as the version information, the bundle identifier, and so on — but you may still want to examine the Info.plist in its entirety.

Click the Property List toolbar button Property List toolbar button (or use Cmd-Shift-I) to view the Info.plist file for the selected app or component: Info.plist view

Most of the Info.plist keys have some sort of documentation on Apple's Developer site: to jump directly to that documentation, select a row and click Open Apple Documentation for Key. (If this button is disabled, Apparency doesn't have a direct link for that key, either because the key isn't documented or because we didn't find the documentation to index it.) Alternatively, when you move the pointer over a key name, if a link button link to documentation button appears on the right side, clicking this will also take you to the documentation for that property.

If you're looking for a particular key or value, click in the search field (or use Cmd-F) and type the text you want to find. Apparency will show only the rows that match, or for arrays or dictionaries, the rows that contain matches. Click the search options button search options button to choose between searching keys and values, or to restrict the way that text matches. Click the cancel button cancel search button to return to viewing the unfiltered Info.plist.

Show the Entitlements

The entitlements of an app or component enumerate specific capabilities that the component requires to do its work. macOS grants (or denies) these capabilities to the app or component, based on the entitlements and (sometimes) other restrictions. Entitlements take several forms:

Click the Entitlements toolbar button Entitlements toolbar button (or use Cmd-Shift-E) to view the entitlements for the selected app or component: entitlements view

As described above for the Info.plist, documentation links to Apple's Developer site are available for some entitlement keys.

Likewise, you can use the search field to filter entitlements on specific key or value text.

If the selected app has a provisioning profile, as discussed below, there will be an additional entitlements view provisioning column header column that shows whether each entitlement is allowed by the profile. See here for a description of each possible entitlement provisioning status.
Apparency can also show a “merged” view of all entitlements requested by all of the components of an app. This can be helpful to get an overall sense of what the app will do, especially when creating a Privacy Preferences Policy Control (PPPC) Profile. Use File > Show Entitlements for All Executables (Cmd-Control-A) to view the merged entitlements: these are explained further in the FAQ.

Show Executable Information

Apparency can show details about the executable file associated with an app or component. Click the Executable toolbar button Executable toolbar button (or use Cmd-Shift-X) to view this information for the selected component. (If the button is disabled, the component either doesn't contain an executable — i.e. the component contains resources but no code — or the executable is not a native Mach-O type, which is possible but atypical.) executable view

The information shown for an executable is mostly of the sort you would otherwise need the otool(1) or objdump(1) tools to access:

Show Launch Information

macOS has various features that control how and when a specific app or component might be launched. For example, Gatekeeper decides if the component can launch; launchd(8) often does the actual launching, based on some trigger or other event; and launch constraints restrict what is allowed to perform or trigger the launch.

Apparency gathers this launch-related information into a single inspector. Select a component and click the Launch toolbar button Launch toolbar button (or use Cmd-Shift-L). launch info view

In this inspector, you'll find the following launch-related information:

Show String Literals from an Executable

Occasionally — such as when attempting to reverse engineer a component — you might want to see the fixed strings of text that are almost always embedded in an executable. These are known as string literals, and they can give you clues about what the executable does and how it works, even before you resort to disassembly.

Traditionally, the way to get at the string literals from an executable is to use the strings(1) command, which on macOS is installed with Xcode or the Developer Command-Line Tools.

Apparency provides a similar — but not identical — mechanism: the Strings Literal inspector. Simply select a component, and choose Component > Show String Literals from Executable (Shift-Option-Cmd-X). Apparency will extract the string literals from the executable, and shows them in a list with 3 columns: string literals inspector

Apparency allows you to narrow down the strings list in a couple of ways. You can change the All Sections pop-up to show only strings from the selected section. Or you can search the strings for something specific — such as part of a Console log message, or a key from running the defaults(1) command. By default, Apparency shows all strings that contain the entered text, but you can click the search options button search options button to change the way that the text matches. Click the cancel button cancel search button to return to viewing all strings.

Apparency is much less aggressive than strings(1) about finding strings. As noted above, it restricts itself to very specific sections, which are declared to contain (NULL-terminated) C-style strings, and even then considers only a subset of those sections. strings(1) searches every section of every segment (except __TEXT,__text, where executable code lives, unless you use the -a option). strings(1) also finds anything that “looks like” a string — that is, four or more “printable” characters, whether in NULL-terminated format or not. This obviously finds many more strings, at the cost of giving you more data to plow through.
You can use Show String Literals from Executable on any component that has an executable — even if it is a system framework or dylib that has been moved into the DYLD shared cache, and therefore has no standalone file on disk. This is something that you can't really do with strings(1).

Show App Store Receipt

An app installed from the App Store usually has an embedded receipt file. This receipt is signed by Apple, and can be used by the app to verify that it was actually purchased by the current user (or by another user sharing the same computer). The receipt can be inspected to see additional App Store and purchase information.

Click the Receipt toolbar button Receipt toolbar button (or use Cmd-Shift-T) to view the App Store receipt for the selected app: App Store receipt view

The information shown for an App Store receipt is as follows:

Show Provisioning Profile

Certain apps — depending on their capabilities and how they're distributed — will have an embedded provisioning profile. This is essentially “permission” from Apple for

The provisioning profile must be signed by Apple, which allows Apple to restrict what an app can do and where it can run — even if the app itself is signed by a third-party developer and distributed outside of the App Store.

Generally, the developer creates a provisioning profile through the Apple Developer Program website (or allows Xcode to do so automatically). Some capabilities are allowed routinely — without, one assumes, any human intervention. Other capabilities — such as Endpoint Security extensions or DriverKit drivers — are subject to an Apple approval process. Either way, the app can't use these capabilities without a matching, Apple-signed provisioning profile.

The provisioning profile scheme originated on iOS, where the specification of devices is more meaningful: this is the mechanism by which an iOS app can be installed directly onto a limited number of registered test devices (without going through the App Store). It's possible to use a provisioning profile on macOS to limit an app to running on specific Macs, but this is probably far less common.

Note that not all macOS apps have or require a provisioning profile. If an app doesn't use any of the restricted capabilities, it doesn't need a provisioning profile. Also, an app from the App Store is automatically trusted to use the capabilities found in its entitlements — presumably since these were vetted through App Review before the app was posted on the App Store. Likewise, Apple's own apps — those built into macOS or distributed from the Apple website — don't require provisioning.

macOS enforces the provisioning rules when you open an app: if the app is not from Apple or from the App Store, and if it uses any restricted capabilities, it must have a matching, Apple-signed provisioning profile. If the profile is missing, is invalid or lacks the required capabilities, the app will crash immediately.

With that background, click the Provisioning toolbar button Provisioning toolbar button (or use Cmd-Shift-P) to view the provisioning profile for the selected app: provisioning profile view

The information shown for a provisioning profile is as follows:

Examining Components in Other Apps

If you want to examine a component beyond what Apparency shows, there are a few ways that Apparency tries to make this easier.

In the Finder

Occasionally, you may want to see a specific component in the Finder; for example, to look at the individual files that it contains. You can do this easily from Apparency: select the component in the browser, and click the Show in Finder toolbar button Show in Finder toolbar button (or use Cmd-Shift-R).

In the Terminal

Alternatively, if you want to examine a component in the Terminal, you can select it and choose Edit > Copy Path for Component (Cmd-Shift-C). Then you can paste that path into the Terminal, or wherever.

If you want to show — or copy the path to — the main executable, instead of the component itself, hold down Option while doing the above.

Previewing with Quick Look

Sometimes, a component has a kind that will yield an illuminating Quick Look preview. Select the the component and choose Component > Quick Look Component (Cmd-Y) — or just press the spacebar, as in the Finder.

This is probably mostly useful when the component is actually some sort of script (Bash or Python or what have you), and thus will produce its source text upon previewing. Apps might bundle scripts for various reasons, but note that you might need to enable searching in de facto “code places” in order to see such scripts as components in Apparency (since they tend to live in Resources directories).

If you have any other Quick Look Preview extensions installed, you might get useful previews for other kinds of components. Of course, for most kinds of components — applications, executables and standard bundles like frameworks — the Quick Look preview will be generated by Apparency itself, and isn't going to tell you anything new!

Analyzing an Executable in the Hopper Disassembler

If you're trying to reverse engineer a component, you might want to disassemble its executable. Apparency provides a convenient way to automatically start analysis using the Hopper Disassembler.

Assuming that you already have Hopper installed, select the component in Apparency and choose Component > Analyze Executable Using Hopper Disassembler.

Apparency will use AppleScript to tell Hopper to start the analysis. (The first time you use this command, macOS may ask if you want to allow Apparency to control Hopper; you'll need to allow the access for this to work.) Apparency will tell Hopper to analyze the architecture matching the current system, and to use the default Mach-O analysis options. If the executable was moved into the DYLD shared cache, Apparency will tell Hopper to open the cache, and to select the correct library from that cache.

Either way, Hopper should begin the analysis without any further interaction. Note that Hopper does still display the usual dialogs, but the AppleScript should automate through them. It might appear that Hopper has paused, especially on the DYLD Shared Cache dialog, but give it a couple seconds and it should continue.

If you want to disassemble a different architecture, or to change the analysis options, hold down the Option key and choose Component > Load Executable in Hopper Disassembler instead. Apparency will still pass off the proper executable path — and deal with any DYLD shared cache configuration — but Hopper will stop to let you configure analysis options.
Hopper's open executable AppleScript command is pretty powerful, but the documentation is a bit sparse, so we'll mention a couple things we learned when implementing this:

First, the “hopperv4” command-line tool also works by sending AppleScript to the app, so you can learn a lot by seeing how it translates arguments into AppleScript. There is a (hidden) --debug-script option that you can add to have it print that AppleScript. (Yes, we did load Hopper into Hopper; how could we not?)

Second, in order to automate the selection of a library from the DYLD shared cache, you need to specify the path to the cache itself as the executable to load, and then specify the loader as DYLD_ONE (and not DYLDLoader). Finally, you give it a string that matches the entry in the file table (or at least a unique prefix therein). For example:

open executable "/System/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e"
   with options [{loader name:"DYLD_ONE", selected_string:"libxar.1.dylib"}, {loader name:"Mach-O"}]

Apparency actually formats the exact string that Hopper would show for the library, since there are some places where the macOS and iOS (Catalyst) worlds use the same framework names.

Finding App Containers

If an app uses the App Sandbox, it is not allowed to read or write arbitrary files within your home folder — it gets permission only for files that you pick through an Open or Save dialog, or to files or folders declared in its entitlements. Otherwise, it is expected to work totally within its app container.

For each sandboxed app (or other sandboxed component), macOS creates an app container under your Library > Containers folder. The container folder is named after the app's bundle identifier, and within its Data subfolder, contains a structure much like a normal home folder — macOS actually tells the app that this is your home folder.

What actually winds up in this container depends on the app. Preference settings almost always wind up here (instead of in the normal Library > Preferences folder). A “document-based” app — that is, an app which offers File > Open and File > Save, such as Pages or Keynote — will still put files where you tell it (not inside the app container). But a so-called “shoebox” app — one that handles content more abstractly than at the file level, like Photos or Notes — may use the app container more substantively (although often the canonical content might be stored in iCloud).

Anyway, most of the time you can ignore the app container, but especially when debugging an issue, it can be helpful to inspect it. Apparency tries to make this a bit easier by helping you find the app container: select the app or other component, and click the Show Container toolbar button Show Container toolbar button (or use Cmd-Shift-A).

Alternatively, if you want to examine the container in the Terminal, you can select the component and choose Edit > Copy Path for App Container (Cmd-Shift-K).

Note that individual components other than the top-level app might also have their own app containers. For example, the app might contain a Share Extension or a Quick Look Preview Extension, and these are required to be sandboxed also. Any such sandboxed component will have a separate app container.
Because Apparency itself is sandboxed, it can't access other app's containers — or indeed, anything outside of its own app container. As such, it doesn't really know if the selected component's app container exists, only that the component is sandboxed and where the app container would be. It asks the Finder to show where the app container would be, but it is possible there will be nothing there, since macOS doesn't create the app container until the component is first used.

Finding Shared App Group Containers

Because different sandboxed apps have different app containers, two apps — even two apps in a suite from the same developer — can't share data in their respective app containers. Indeed, even an app and another component within that same app — such as a Share Extension — can't share data in the app container.

Apple's answer to this problem is the app group container. This is a secondary container that can be accessed by two or more components, as long as they are from the same developer. The developer defines a group container identifier through the Apple Developer Program website (or through Xcode), and allows individual apps or components to use that group container via the com.apple.security.application-groups entitlement. A single group container can be shared amongst any number of components, and a component can have access to any number of group containers: this is all up to the developer to decide.

macOS creates group containers under your Library > Group Containers folder. Each group container folder is typically named with the developer's Apple-issued team ID, following by the developer-chosen group identifier. (Apple apps tend not to follow this pattern, using a group. prefix, or none at all.) Unlike the app container, the structure of the group container is not standardized, so the developer can organize it in whatever way they choose. (However, if the group container is used to share preferences, you will likely find a Library > Preferences folder inside.)

As with the app container, you can use Apparency to find a group container. Select the app or other component, and use Component > Show Group Container X in Finder. (The choices in the Component menu will depend on the selected component and what groups it has access to; if you don't see any Show Group Container items, there are no groups for that component.) Alternatively, to examine the group container in the Terminal, use Edit > Copy Path for Group Container X.

Using From Quick Look

Apparency provides a Quick Look Preview extension, which adds a bit more information to the standard macOS preview for apps.

The Apparency preview works in any normal Quick Look context. For example, if you open a Finder window to your Applications folder and choose View > as Gallery or View > Show Preview, you'll get an enhanced preview for the selected app: Quick Look preview

Apparency tries to fit the preview into the space available for it — although macOS makes us guess about this, so you may need to resize the preview pane to see some information.

Note that the information in the Quick Look preview is only for the top-level app that you select; it doesn't consider any components within it. Click the Open With Apparency button to quickly open the app in Apparency, where you can see all the details.