Last active
September 8, 2026 00:45
-
-
Save n0kovo/d8a2ff95065bdd48d2967b19b3a26961 to your computer and use it in GitHub Desktop.
Allow debugging binaries on macOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env zsh | |
| _dbgsign_ents() { # $1 = target, $2 = output plist, uses $ents | |
| print -u2 -- "\nCleaning quarantine and extracting entitlements for: $1" | |
| codesign -d --entitlements - --xml "$1" > "$2" | |
| if [[ ! -s $2 ]] || ! /usr/libexec/PlistBuddy -c Print "$2"; then | |
| print -r -- '<?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/></plist>' > "$2" | |
| fi | |
| local e | |
| for e in $ents; do | |
| /usr/libexec/PlistBuddy -c "Add :$e bool true" "$2" \ | |
| || /usr/libexec/PlistBuddy -c "Set :$e true" "$2" | |
| done | |
| } | |
| emulate -L zsh | |
| setopt local_options null_glob | |
| local app=${1:A} id=${2:--} ent rc=0 | |
| [[ -e $app ]] || { print -u2 "dbgsign: not found: $1"; return 1 } | |
| print -u2 -- "Stripping extended attributes from $app" | |
| xattr -cr "$app" | |
| find "$app" -name '._*' -type f -delete # AppleDouble stragglers | |
| local -a ents=( | |
| com.apple.security.get-task-allow | |
| com.apple.security.cs.allow-dyld-environment-variables | |
| com.apple.security.cs.disable-library-validation | |
| com.apple.security.cs.allow-unsigned-executable-memory | |
| ) | |
| if [[ ! -d $app ]]; then | |
| # plain Mach-O | |
| print -u2 -- "Signing plain Mach-O: $app" | |
| ent=$(mktemp) | |
| _dbgsign_ents "$app" "$ent" | |
| print -u2 -- "codesign (plain Mach-O): $app" | |
| codesign -f -s "$id" --entitlements "$ent" "$app" | |
| rc=$? | |
| rm -f "$ent" | |
| (( rc )) && print -u2 -- "Failed signing $app" | |
| return $rc | |
| fi | |
| # every loose Mach-O anywhere in the tree | |
| local f | |
| for f in "$app"/**/*(.N); do | |
| [[ $(file -b --mime-type "$f") == application/x-mach-binary ]] || continue | |
| codesign -f -s "$id" "$f" || { print -u2 -- "Failed to sign $f"; return 1; } | |
| done | |
| # nested bundles, deepest first | |
| local -a bundles=( "$app"/**/*.(framework|app|xpc|appex|prefpane|mdimporter|component|bundle|kext|lproj|dsym|aplibrary|plugin|xcodeproj|systemextension|playground|qlgenerator)(/N) ) | |
| local b v | |
| for b in ${(Oa)bundles}; do | |
| if [[ -d $b/Versions ]]; then | |
| # versioned framework | |
| for v in $b/Versions/*(/N); do | |
| [[ ${v:t} == Current ]] && continue | |
| print -u2 -- " Signing framework version: $v" | |
| codesign -f -s "$id" "$v" || { print -u2 -- "Failed to sign $v"; return 1; } | |
| done | |
| else | |
| ent=$(mktemp) | |
| _dbgsign_ents "$b" "$ent" | |
| codesign -f -s "$id" --entitlements "$ent" "$b" || { | |
| print -u2 -- "Failed to sign $b" | |
| rm -f "$ent" | |
| return 1 | |
| } | |
| rm -f "$ent" | |
| fi | |
| done | |
| # outer bundle | |
| print -u2 -- "Signing outer bundle: $app" | |
| ent=$(mktemp) | |
| _dbgsign_ents "$app" "$ent" | |
| codesign -f -s "$id" --entitlements "$ent" "$app" | |
| rc=$? | |
| rm -f "$ent" | |
| (( rc )) && { print -u2 -- "Failed signing outer bundle $app"; return $rc; } | |
| print -u2 -- "Verifying signed bundle: $app" | |
| codesign -vvv --deep --strict "$app" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment