如何检测是不是有任何外部库正在调用 [UIDevice currentDevice] uniqueIdentifier]?

Posted

技术标签:

【中文标题】如何检测是不是有任何外部库正在调用 [UIDevice currentDevice] uniqueIdentifier]?【英文标题】:How to detect if any external libraries are calling [UIDevice currentDevice] uniqueIdentifier]?如何检测是否有任何外部库正在调用 [UIDevice currentDevice] uniqueIdentifier]? 【发布时间】:2013-03-25 20:00:26 【问题描述】:

所以,since Apple is now rejecting apps that access UDID,在我们公司当前的项目中,我们需要消除所有调用该属性的 API:

[[UIDevice currentDevice] uniqueIdentifier]

我们已经消除了我们自己代码中的所有调用,但需要确保我们使用的许多外部库没有调用此属性。

确定库是否调用此属性的最可靠方法是什么?

提前谢谢你!

【问题讨论】:

外部库是开源的吗? 大部分库不是开源的。 查看这个答案:***.com/a/9894190/440060 检查这个答案,我从 Apple ***.com/questions/16449182/…得到的提示 【参考方案1】:

除了使用otx(它似乎变得不稳定)之外,一个选择是在该方法上设置一个符号断点,然后运行应用程序一段时间,看看你是否点击它。

为该方法配置符号断点如下所示:

如果您遇到过该断点,您可以通过打开调试器控制台并输入bt 来找出是谁调用了它。在这种情况下,电话来自我的application:didFinishLaunchingWithOptions:,但无论是谁拨打的电话都有效:

(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

【讨论】:

谢谢你,做得很好!我想,唯一的问题是它只能在它实际调用该函数时才能捕获它,而不是在它有潜在调用它的情况下。 +1 非常感谢!通过帮助我们找到我们错过的图书馆,它可能为我们节省了 1 周的时间!【参考方案2】:

扩展 Quinn 的答案:

strings 列出编译对象或库中的所有符号,按每个类的第一次出现顺序。如果您在输出中看到uniqueIdentifier,则他们可能正在调用具有该名称的其他方法。但是,如果您在输出中看到currentDevice,紧接着是uniqueIdentifier,那么他们几乎肯定会调用[[UIDevice currentDevice] uniqueIdentifier]。如果库在文件的前面调用currentDevice,则这两行可能不是连续的。 otool -ov 列出了库中的所有类、方法和导入。如果它列出了uniqueIdentifier,这可能意味着该库正在使用该名称定义自己的方法。在上下文中查看参考。在每个类的底部,您会看到类似Contents of (__DATA,__objc_clas-s-refs) section 的部分,其中列出了导入。如果_OBJC_CLASS_$_UIDevice 列在您发现引用uniqueIdentifier 的类的导入中,那么该类很可能正在调用-[UIDevice uniqueIdentifier]nm 的输出类似于otool 用于此目的。具体来说,它不会显示对 uniqueIdentifier 的调用,但会显示哪些类导入了 UIDevice

【讨论】:

【参考方案3】:

很难可靠地确定一个闭源库是否真的在调用一个方法,但有一些方法可以让您查看它们是否可能

使用strings查看“uniqueIdentifier”是否出现在库中,不管它是如何使用的:

$ strings libFoo.a | grep uniqueIdentifier

使用nm 或otool(参见this answer)

使用otx(见this answer)

这些方法可以帮助发现设置断点可能会错过的潜在调用。

【讨论】:

以上是关于如何检测是不是有任何外部库正在调用 [UIDevice currentDevice] uniqueIdentifier]?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Android 库项目转换为外部 JAR?

如何检测外部显示器是不是在镜像中或通过命令扩展?

检测是不是使用外部 JavaScript 文件创建了 html 元素

Apache Thrift 是不是允许任何两种语言之间的外部函数调用?

iOS 是不是提供任何功能来检测外部屏幕是“硬连线”电视输出/HDMI 还是“网络”Airplay 显示器/设备?

使用 cmake 构建外部库