前几天一个使用我们公司iOS sdk的用户跟我说他们app审核被拒了,原因是包含了dlopen(),dlsym()的函数。 审核的理由原文:
This code, combined with a remote resource, can facilitate significant changes to your app’s behavior compared to when it was initially reviewed for the App Store. While you may not be using this functionality currently, it has the potential to load private frameworks, private methods, and enable future feature changes. This includes any code which passes arbitrary parameters to dynamic methods such as dlopen(), dlsym(), respondsToSelector:, performSelector:, method_exchangeImplementations(), and running remote scripts in order to change app behavior and/or call SPI, based on the contents of the downloaded script. Even if the remote resource is not intentionally malicious, it could easily be hijacked via a Man In The Middle (MiTM) attack, which can pose a serious security vulnerability to users of your app.
查了下dlopen和dlsym的用处,发现是可以动态加载库文件,意味着可以不通过app store审核更新代码,这个肯定是苹果不允许的。不过我记得热更新被禁止是去年的事了,而我们公司sdk的第三方库基本没有动过,这会突然拒绝了一个用户的审核,而其他使用的用户并没有反馈,有点看不懂苹果的审核机制。
不过,既然已经被拒了,问题还是要解决,需要找到是哪个库中包含了这些函数。网上查了下,发现可以通过nm命令来查看动态和静态库中的符号。
这里使用
nm -u libxxx.a » xxx.txt
将sdk中使用的库都查看一遍后,发现OpenSSL的libcrypto.a中确实有这两个函数。
也可以看到是在dso_dlfcn文件中,于是去OpenSSL源码中查找这个文件,看看这个函数是在什么情况下编译到静态库中。
果然在这个文件中,然后看文件结构,发现这个文件在crypto文件夹中的dso文件夹下,猜测dso可能是crypto库的一个模块。
经过网上查资料,发现dso就是一个动态加载的功能模块,在OpenSSL中,使用编译参数no-dso就可以禁用这个模块。
于是使用OpenSSL-for-iPhone的编译脚本,在编译时增加参数,重新编译静态库。
CONFIG_OPTIONS=”no-dso” ./build-libssl.sh
重新编译后再次查看符号,发现已经没有dlopen和dlsym了。替换了静态库后,重新编译好sdk,提供给用户,过了几天用户反馈审核通过,问题解决。