Avoiding method swizzling is simple; use functions rather than methods (i.e. do things the old-fashioned way without objects, in C++, or at least in Core Foundation). But if you're using the ObjC runtime, you can be swizzled.
You can in principle detect swizzling by caching all your IMP
pointers, for example using class_getMethodImplementation
in something like +load
or maybe a C++ constructor on a global variable (which get run before main()
), and then re-checking all your IMP
pointers at various times to make sure they haven't changed.
That probably wouldn't be too hard, but it's difficult to imagine what all of this would achieve. If someone has your framework binary, it wouldn't be a major effort to to patch it to remove your check. Somewhere in the source code, there's got to be a if (swizzled) { ... }
, and that's going to translate into a branch-if conditional instruction in the assembly. You stick a debugger on the system, wait for the branch to "ah! we're swizzled" to occur, note the point where it happens, and patch that byte to be "branch-if-not" or just add an unconditional jump.
Slowing that attack down, even a little, requires substantial obfuscation. There are techniques (that mostly don't work that well), but they only work by being kept secret. That's the difference between obfuscation and security.
Short answer is you really can't achieve this in any stable way. That means you either need a team devoted to constantly coming up with new, more advanced obfuscations and updating them regularly as new attacks emerge (i.e. how a company like Blizzard or Apple prevent hacking), or you'll need to find a way not to need this.
Simplest answer? Work mostly in C++ and use ObjC classes as little as possible (which will prevent swizzling, but not reverse engineering or patching). Or accept that swizzling is not avoidable.
(BTW, if there were even a "I'm willing to do whatever it takes" answer to this question, then Apple would just use that technique to make jailbreaking impossible. The fact that iPhones get jailbroken regularly suggests the difficulty of the problem.)