You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Ability to remove retain/autorelease ARC calls in Objective-C Binaries #5591
There are numerous functions that produce a lot of noise in Objective-C code, examples include:
_objc_retainAutoreleasedReturnValue
_objc_retainAutorelease
These are not often the interesting bits of the function, and it might be helpful if these could be optionally hidden to produce more readable decompilation.
My ARC removal pass works quite well. I'm happy to look at upstreaming it, though I'll need to figure out if it's more painful to rewrite it in C++ or to try to integrate Rust code with the Mach-O / shared cache plug-ins. If it stays in Rust it will need to be reworked to move off my custom instruction matching to directly using the low_level_il types.
There's one remaining rough edge where the resulting HLIL is confusing:
// TODO: Detect calls to `objc_release` that are immediately after a load of a struct field.
// It might be preferable to leave those in place since otherwise the load is left behind.
This shows up as a mystery reference to a struct field:
#7440, first appearing in 5.2.8343-dev, added initial support for this. It is disabled by default since it rewrites IL in a way that changes program semantics. It can be enabled per-function via Obj-C: Remove reference counting calls in the Function Settings context menu or on a wider scale by setting core.function.objectiveC.removeMemoryManagement.
There are two limitations at present:
Only arm64/arm64e are supported.
The variants of objc_retain / objc_release that use a custom calling convention are not removed.
Supporting armv7/x86_64 requires generalizing the IL matching code. Supporting objc_retain_x8 and such requires generalizing the IL rewriting of it.
Closing as fixed since the most common cases are handled in Binary Ninja 5.2. #7660 tracks the cases that are not yet handled (support for x86_64 and runtime functions with custom calling conventions).
Activity
0cyn commentedon Jul 18, 2023
PR Vector35/workflow_objc#52 addresses this, but is blocking on #5563
0cyn commentedon Jun 5, 2025
Workarounds exist for this:
This plugin: https://github.com/bdash/bn-objc-extras/blob/dev/src/remove_memory_management.rs implements a workflow to remove these functions .
This very legacy PR to workflow_objc also implements this: https://github.com/Vector35/workflow_objc/pull/52/files However it is likely outdated and non-functional in current versions of the product.
[-]Clean up retain/autorelease noise[/-][+]Ability to remove retain/autorelease ARC calls in Objective-C Binaries [/+]bdash commentedon Jun 5, 2025
My ARC removal pass works quite well. I'm happy to look at upstreaming it, though I'll need to figure out if it's more painful to rewrite it in C++ or to try to integrate Rust code with the Mach-O / shared cache plug-ins. If it stays in Rust it will need to be reworked to move off my custom instruction matching to directly using the
low_level_iltypes.There's one remaining rough edge where the resulting HLIL is confusing:
This shows up as a mystery reference to a struct field:
If you disable the pass you can see that the code is releasing any existing object before assigning to the field:
This can likely be improved after the fact.
bdash commentedon Oct 20, 2025
#7440, first appearing in 5.2.8343-dev, added initial support for this. It is disabled by default since it rewrites IL in a way that changes program semantics. It can be enabled per-function via
Obj-C: Remove reference counting callsin theFunction Settingscontext menu or on a wider scale by settingcore.function.objectiveC.removeMemoryManagement.There are two limitations at present:
objc_retain/objc_releasethat use a custom calling convention are not removed.Supporting armv7/x86_64 requires generalizing the IL matching code. Supporting
objc_retain_x8and such requires generalizing the IL rewriting of it.bdash commentedon Nov 18, 2025
Closing as fixed since the most common cases are handled in Binary Ninja 5.2. #7660 tracks the cases that are not yet handled (support for x86_64 and runtime functions with custom calling conventions).