-
-
Save kim4apple/c09e57a9fdca4f6af6d90bbe11708304 to your computer and use it in GitHub Desktop.
This script can patch macOS 10.12.2 amfid daemon on memory to allow arbitrary entitlements in Developer ID signed binaries.
This file contains 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 python3 | |
'''amfid_patch.py - Pedro José Pereira Vieito © 2016 | |
This script can patch macOS 10.12.2 amfid daemon on memory | |
to allow arbitrary entitlements in Developer ID signed binaries. | |
Killing amfid will make the patch disapear: | |
$ sudo kill -9 `pgrep amfid` | |
You must run the script as a root (sudo) and with SIP disabled. | |
You can get the PyMach Python module from here: | |
PyMach: https://github.com/pvieito/PyMach | |
Usage: | |
amfid_patch.py [-h] | |
Options: | |
-h, --help Show this help | |
''' | |
import mach | |
import sys | |
import os | |
import binascii | |
from subprocess import check_output | |
from docopt import docopt | |
from distutils.util import strtobool | |
args = docopt(__doc__) | |
def get_pid(name): | |
try: | |
output = check_output(["pgrep", name]) | |
return int(output) | |
except: | |
return None | |
def patch_mem(task, address, original_mem, patched_mem): | |
print("Patch Address:", hex(address)) | |
patch_len = len(patched_mem) | |
mem = mach.vm_read(task, address, patch_len) | |
if mem == original_mem: | |
print("Correct process version!") | |
print("Patch:", binascii.hexlify(mem).decode(), "->", | |
binascii.hexlify(patched_mem).decode()) | |
if strtobool(input('Continue patching? ')): | |
print("Patching amfid...") | |
mach.vm_protect(task, address, patch_len, 7) | |
mach.vm_write(task, address, patched_mem) | |
mem = mach.vm_read(amfid_task, address, patch_len) | |
if patched_mem == mem: | |
print("🎉 Patch Successfull!") | |
else: | |
print("Not patched :(") | |
else: | |
exit(0) | |
elif mem == patched_mem: | |
print("🎉 Already patched!") | |
else: | |
print("Memory:", binascii.hexlify(mem).decode(), "vs.", | |
binascii.hexlify(original_mem).decode()) | |
print("Incorrect version of process or ASRL Offset") | |
if os.getuid() != 0: | |
print("This script should run as root.") | |
exit(0) | |
amfid_pid = get_pid("amfid") | |
if not amfid_pid: | |
print("Error: amfid not running, start some app to reload amfid") | |
exit(0) | |
try: | |
amfid_task = mach.task_for_pid(amfid_pid) | |
asrl_offset = mach.vm_asrl_offset(amfid_pid) | |
if asrl_offset: | |
print("PID:", amfid_pid) | |
asrl_offset = 0x0000000100000000 + asrl_offset | |
print("ASRL Offset:", hex(asrl_offset)) | |
else: | |
print("Error getting the ASRL Offset") | |
exit(0) | |
# Convert `test r14, r14; je` -> `mov r14, r15; jno` | |
# So it always jump and r14 becomes 0 | |
patch_mem(amfid_task, asrl_offset + 0x347D, | |
b"\x45\x85\xF6\x0F\x84", b"\x4D\x89\xFE\x0F\x81") | |
except SystemError as error: | |
print("Memory not accessible probably due to System Integrity Protection.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment