Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent Method Swizzling Objective-c

I am trying to search to prevent the Method Swizzle in my current library but more or less every documentation or blog post that i found are about how to implement Swizzling. There are couple of question that i have regarding Method swizzling that i could not find all across.

  • How to detect the Method Swizzling at runtime?
  • In case there is a Method Swizzle how to prevent it ?

I know the dangers of method swizzling and have already gone through the related posts here but could not find the related information to prevent it.

If there is any documentation or blog post that available on the above topics, I would really appreciate the assistance.

like image 590
Akhilesh Sharma Avatar asked Jan 30 '17 18:01

Akhilesh Sharma


People also ask

What is method swizzling in Objective-C?

Method swizzling is the process of replacing the implementation of a function at runtime. Swift, as a static, strongly typed language, did not previously have any built-in mechanism that would allow to dynamically change the implementation of a function.

What is swizzling Swift?

iOS Swift Tips. Swizzling (other languages call this “monkey patching”) is the process of replacing a certain functionality or adding custom code before the original code is called. For example, you could swizzle UIViewController.


1 Answers

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.)

like image 105
Rob Napier Avatar answered Oct 03 '22 00:10

Rob Napier