EDR based on Apple Endpoint Security Framework capable of monitoring/authorizing events and protecting processes via injection against memory corruption exploits
Based on my Bachelor's thesis
- Protect apps by injecting a dylib that hooks system APIs and checks the call context to identify potential RCE
- Subscribe to ES events and show them in the UI
- Deny access to processes/files based on custom rules
The only external dependency is the keystone assembler, which can be installed with brew install keystone.
You also need the Endpoint Security entitlement granted from Apple.
Other than that, it should build directly in Xcode after resolving SPM dependencies (SQLite).
The project has been updated with a minimum deployment target of macOS 26 Tahoe, but it should work on macOS 13 and greater.
The EDR contains three main components: Integrator (UI), Extension (ES client), libinject (the library that gets injected).
The Extension subscribes to process creation authorization callbacks and checks the bundle identifier against known ones. Because detections that involve process injection should be as accurate as possible, extensive testing must be done to ensure the injected process is compatible with the detections, so we cannot perform the injection on any process on the system.
The EXEC authorization event is fired before the application's entrypoint is called. This allows us to modify the Mach headers and redirect the entrypoint to a small code region, which loads our library and jumps to the original entrypoint.
The library hooks configured API functions, redirecting code execution to a dispatcher that checks the call context against a number of detections. If everything is fine, the function continues executing as normal. If an anomaly is detected, the process is immediately killed.
A detection example is checking the return address of the functions. A normal function returns to the text segment. It is not normal behavior to return, for example, on the stack, but it's a common behavior when an attacker exploits a memory corruption vulnerability (e.g., stack-based buffer overflow).
All components communicate via XPC. The Extension checks the identity of the client and exposes different functions depending on whether it's the Integrator or an injected app.
The test application includes two versions of calling a function: a non-malicious normal call, and a malicious one invoked from shellcode call. Only the malicious one triggers an EDR detection.





