macOS - Useful commands
File extensions
Renaming a set of files
$ find . -name "*.old" -exec bash -c 'mv "$1" "${1%.old}".new' - '{}' \;
Shell scripts
It is important to add the extension ".sh" since, during the signing process, Xcode assumes that files with no extension are binaries. Thus it will both fail checking the "hardened code" and signing them.
Monitor files used by an application
Activity Monitor.app, found in the /Applications/Utilities folder.
- click on the Process Name in the list,
- hit the "Inspect" button on the toolbar.
There are three tabs in the resulting window: Memory, Statistics, Open Files and Ports.
- the "Open Files and Ports" tab will show all the open files being used by the process.
Libraries
TYPE
otool -hv aLibrary
.so, compiled with -shared e
.dylib, using -dynamiclib
shared
static
DEPENDENCIES -(only part of the answer)
otool -L myBinary
CAUTION: applying the command to each framework shows a lot more frameworks. otool must be used recursively to provide the whole answer.
TEAM ID
Hardening option: com.apple.security.cs.disable-library-validation
codesign -dv --verbose=4 /opt/X11/lib/libXinerama.1.dylib 2>&1 | grep TeamIdentifier
TeamIdentifier=NA574AWV7E
RUNPATH SEARCH PATHS - @rpath
https://blog.krzyzanowskim.com/2018/12/05/rpath-what/
@rpath - "Runpath Search Paths" i.e. dynamic linking
@executable_path/Frameworks - resolves to the absolute path of the executable
@loader_path/../Frameworks - resolves with directory containing the Mach-O binary containing the load command
Xcode: LD_RUNPATH_SEARCH_PATH or -rpath
Typical error
dyld: Library not loaded: @rpath/Allthethings.framework/Allthethings
Checking rpath
$ otool -l myApp.app/Contents/MacOS/binary
Load command 48
cmd LC_RPATH
cmdsize 48
path @executable_path/../Frameworks (offset 12)
install_name_tool
This tool changes dynamic shared library install names and manipulate Runpaths.
To add new path:
install_name_tool -add_rpath @executable_path/../private/libs binaryFile my_Mac-O_Binary
To delete added path (we can only delete path added with -add_rpath):
install_name_tool -delete_rpath @executable_path/../private/libs binaryFile my_Mac-O_Binary
To change the existing path:
install_name_tool -rpath @executable_path/../Frameworks @executable_path/../private/libs my_Mac-O_Binary
To change the dependent shared library install name:
install_name_tool -change /usr/local/lib/libAquaIntLib.dylib "@executable_path/../Frameworks/libAquaIntLib.dylib" "FreeWRL.app/Contents/MacOS/FreeWRL" my_Mac-O_Binary
<https://wincent.com/wiki/%40executable_path%2C_%40load_path_and_%40rpath>
@executable_path
for frameworks embedded inside applications, because it allows you to specify the location of the framework relative to the application’s executable
@loader_path
for frameworks embedded inside plug-ins --> location of the framework relative to the plug-in’s code (plug-ins may not actually know where they are going to be installed, relative to the application, so knowing @executable_path doesn’t help us in this case)
@rpath
instructs the dynamic linker to search a list of paths in order to locate the frameworks
Check the result with both
otool -L myBinary
otool -l myBinary
Verifying binary hardening
Hardening a binary
codesign --options runtime --timestamp --sign "Developer ID Application: YOUR NAME (TEAM_ID)" /path/to/bundle.app
Checking a binary
codesign --display --verbose <filepath>
The (runtime) flag in the "CodeDirectory" line indicates that your application is hardened.
par ex: CodeDirectory v=20500 size=89426 flags=0x10000(runtime) hashes=2786+5 location=embedded
spctl -a -t open --context context:primary-signature -v /path/to/bundle
Signature, entitlements and notarization
List of certificates
security find-identity -p codesigning
Bundle status
codesign -dvvv HelloCodeSign.app
Missing entitlements?
codesign -d --entitlements :- Winteracter
Executable=/Applications/TestAlert3-Xcode.app/Contents/MacOS/Winteracter
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/> <--- This shows that the entitlement is missing
</plist>
List of entitlements
codesign -d -v --entitlements :- myAppName.app
Removing signature ?
codesign --remove-signature HelloCodeSign.app
Notarization
spctl -a -vvv -t install myArchive.dmg
myArchive.dmg: accepted
source=Notarized Developer ID
origin=Developer ID Application: INSTITUT MAX VON LAUE - PAUL LANGEVIN (P65398CN49)
Min macOS version
The minimum macOS supported must be set within each of the binaries, i.e. Load command 9 (LC_VERSION_MIN_MACOSX) or Load command 10 (LC_BUILD_VERSION) must be present.
Ifort compiler prior to OneAPI
ifort link: -mmacosx-version-min=10.10 (10.9 is the minimum)
The OneApi ifort automatically sets LC_BUILD_VERSION instead.
Testing which SDK you can use
ls /Library/Developer/CommandLineTools/SDKs
MacOSX.sdk MacOSX10.15.sdk MacOSX11.1.sdk MacOSX11.3.sdk MacOSX11.sdk MacOSX12.1.sdk MacOSX12.sdk
Checking it:
otool -l <library or binary> | grep -E -Rwi -B1 -A3 'MIN_MACOS|minos'
otool -l <library or binary> | grep -E -Rwi -B1 -A3 'LC_VERSION_MIN_MACOSX|minos'
Load command 9
cmd LC_VERSION_MIN_MACOSX
cmdsize 16
version 10.7
sdk 10.8
vtool -show-build <executable> <-- for executables only not for libraries
Load command 10
cmd LC_BUILD_VERSION
cmdsize 32
platform MACOS
minos 10.16
sdk 12.1
ntools 1
tool LD
version 711.0
ICNS - Preparing an icon
The App Store needs an icon in the form of a .icns file containing two icon sizes: 512x512 and 1024x1024
Create these two files:
icon_512x512.png
icon_512x512@2x.png
Place them in a folder:
myApp.iconset
Merge the above .icns into a single .icns file with the command:
iconutil -c icns myApp.iconset
This will create myApp.icns the content of which can be checked with Preview.app
Info.plist - binary to XML
Strangely enough a mere "cp" command on a Info.plist file will convert it from XML to binary.
To convert it back to XML
plutil -convert xml1 myBinary.plist
To convert from XML to bianry
plutil -convert binary1 myXML.plist
Checking an installer
sudo installer -store -package myApp.pkg -target /
Mimics what Gatekeeper does to check your app
codesign --verify --deep --strict --verbose=2 Foo.app
Caution: this was true in the past but Quinn the Eskimo (Apple developer forum) warned that Apple being under attack there is no longer a command line that mimics the whole Gatekeeper process. In other words, Apple no longer reveales its defense lines.
Removing GateKeeper blocking
"sudo xattr -dr com.apple.quarantine /path/to/myAppName.app"
Checking quarantine
xattr -l /path/to/application/myAppName.app
Removing quarantine
xattr -d com.apple.quarantine /path/to/myAppName.app
“APPNAME” is damaged and can’t be opened. You should move it to the Trash.
xattr -d -r com.apple.quarantine /path/to/myAppName.app
Last update: AF 16 Décember 2020