Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect if any external libraries are calling [UIDevice currentDevice] uniqueIdentifier]?

So, since Apple is now rejecting apps that access UDID, on our company's current project, we need to eliminate all APIs that make a call to this property:

[[UIDevice currentDevice] uniqueIdentifier]

We have eliminated all the calls in our own code, but need to be sure that the many external libraries we are using are not making calls to this property.

What is the most reliable method for determining if a library is calling on this property?

Thank you in advance!

like image 375
Colin Basnett Avatar asked Mar 25 '13 20:03

Colin Basnett


3 Answers

Aside from using otx (which seems to have gotten flaky) one option is to set a symbolic breakpoint on that method and then run the app for a while and see if you hit it.

Configuring a symbolic breakpoint for that method would look like this:

enter image description here

If you ever hit that breakpoint, you can find out who called it by opening the debugger console and typing bt. In this case the call came from my application:didFinishLaunchingWithOptions: but it works no matter who called it:

(lldb) bt
* thread #1: tid = 0x1c03, 0x001f4690 UIKit`-[UIDevice uniqueIdentifier], stop reason = breakpoint 1.1
frame #0: 0x001f4690 UIKit`-[UIDevice uniqueIdentifier]
frame #1: 0x0000212e MyApp`-[AppDelegate application:didFinishLaunchingWithOptions:](self=0x0747fcb0, _cmd=0x005aec21, application=0x08366300, launchOptions=0x00000000) + 702 at AppDelegate.m:37
frame #2: 0x00015157 UIKit`-[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 266
frame #3: 0x00015747 UIKit`-[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1248
frame #4: 0x0001694b UIKit`-[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 805
frame #5: 0x00027cb5 UIKit`-[UIApplication handleEvent:withNewEvent:] + 1022
frame #6: 0x00028beb UIKit`-[UIApplication sendEvent:] + 85
frame #7: 0x0001a698 UIKit`_UIApplicationHandleEvent + 9874
frame #8: 0x01f01df9 GraphicsServices`_PurpleEventCallback + 339
frame #9: 0x01f01ad0 GraphicsServices`PurpleEventCallback + 46
frame #10: 0x01f1bbf5 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
frame #11: 0x01f1b962 CoreFoundation`__CFRunLoopDoSource1 + 146
frame #12: 0x01f4cbb6 CoreFoundation`__CFRunLoopRun + 2118
frame #13: 0x01f4bf44 CoreFoundation`CFRunLoopRunSpecific + 276
frame #14: 0x01f4be1b CoreFoundation`CFRunLoopRunInMode + 123
frame #15: 0x0001617a UIKit`-[UIApplication _run] + 774
frame #16: 0x00017ffc UIKit`UIApplicationMain + 1211
frame #17: 0x00001d42 MyApp`main(argc=1, argv=0xbffff3f8) + 130 at main.m:16
like image 80
Tom Harrington Avatar answered Nov 03 '22 22:11

Tom Harrington


To expand on Quinn's answer:

  • strings lists all the symbols in a compiled object or library, in order of first appearance per class. If you see uniqueIdentifier in the output, it's possible that they're calling some other method with that name. But if you see currentDevice in the output immediately followed by uniqueIdentifier, then they're almost certainly calling [[UIDevice currentDevice] uniqueIdentifier]. It's possible that the two lines would not be sequential, if the library is calling currentDevice earlier in the file.
  • otool -ov lists all the classes, methods, and imports in the library. If it lists uniqueIdentifier, that likely means the library is defining its own method with that name. Look at the reference in context. At the bottom of each class you'll see a section like Contents of (__DATA,__objc_classrefs) section that lists the imports. If _OBJC_CLASS_$_UIDevice is listed among the imports for the class you found referencing uniqueIdentifier, then there's a good chance that class is calling -[UIDevice uniqueIdentifier].
  • The output of nm is similar to otool for this purpose. Specifically, it won't show you calls to uniqueIdentifier, but it will show you what classes import UIDevice.
like image 30
Christopher Pickslay Avatar answered Nov 03 '22 22:11

Christopher Pickslay


It can be difficult to reliably determine if a closed-source library is actually calling a method, but there are some ways you can see if they might be:

  • Using strings to see if "uniqueIdentifier" appears in the library, regardless of how it's used:

    $ strings libFoo.a | grep uniqueIdentifier

  • Using nm or otool (see this answer)

  • Using otx (see this answer)

These approaches can help turn up potential invocations that setting a breakpoint may miss.

like image 35
Quinn Taylor Avatar answered Nov 03 '22 23:11

Quinn Taylor