1、前言

最近App Store审核被拒,2. 5 Performance: Software Requirements,Guideline 2.5.2 - Performance - Software Requirements,遇到这样的问题,回信问苹果,肯定得不到答案,苹果就是礼貌的回复。经过一个星期的重复被拒,只能自己找问题,热更新问题,苹果拒审信一直长这样:

....
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(), respondsToSelector:, performSelector:, method_exchangeImplementations(),

然后在 「iOS」热更新审核被拒的解决方法 文章中,找到可以打印下第三方的.a文件看看,看有没有 dlopen(), dlsym(),命令行:

nm -u libwechaat.a >> xxx.txt

注:nm -u path:Display only undefined symbols。更多 nm 命令可查看我之前总结的文章 Mac查看文件内容常用的命令小结

2、定位和查到问题

找到了方向,就是利用 nm 命令查到所有第三方的 .a / .framework是否有相关的方法。

但是如果一个一个库用nm命令去查找,效率非常低,而且每一个库的目录不一样,所以,想到用sehll脚本,整个工程遍历全部的文件,查到到库的,然后打印出来!这才是万利的方法啊!!

3、shell 编程

这里思路大家应该也想到,就是遍历目录,一个一个文件判断,问题的关键出来了!就是怎么判断一个文件是不是.a.framework

其实,可以利用 file 打印当前读取的文件的类型,如果是 Mach-O 类型,就是库文件。比如终端执行 file libWeChatSDK.a 会打印如下:

libWeChatSDK.a: Mach-O universal binary with 5 architectures: [i386:current ar archive] [arm64]
libWeChatSDK.a (for architecture i386): current ar archive
libWeChatSDK.a (for architecture armv7):    current ar archive
libWeChatSDK.a (for architecture armv7s):   current ar archive
libWeChatSDK.a (for architecture x86_64):   current ar archive
libWeChatSDK.a (for architecture arm64):    current ar archive

然后用管道 grep 查找 'Mach-O' 关键字,如果存在,就执行 nm -u file_path 查看所有的方法,最后通过 grep -E 'dlopen|method_exchangeImplementations|performSelector|respondsToSelector|dlsym' 查找包含匹配 dlopen method_exchangeImplementations performSelector respondsToSelector dlsym 其中一个关键字就算包含,最后打印出包含的字段和路径。

最后,在终端执行脚本 sh nm_find.sh 就会得到下面的检查结果,非常的方便和高效!

================================================Enter project path: /Users/HTC/Desktop/ThirdSDK
-----------------------------/Users/HTC/Desktop/ThirdSDK/Adjust/Adjust-4.12.3/AdjustSdk.framework/AdjustSdk
包含字段:
U _dlsym-----------------------------/Users/HTC/Desktop/ThirdSDK/Chartboost/Chartboost-v6.0.1/Chartboost.framework/Chartboost
包含字段:
U _method_exchangeImplementations U _dlopen U _dlsym-----------------------------/Users/HTC/Desktop/ThirdSDK/Facebook/Facebook/FBSDKCoreKit.framework/FBSDKCoreKit
包含字段:
U _dlopen U _dlsym-----------------------------/Users/HTC/Desktop/ThirdSDK/Firebase/Crashlytics/Crashlytics.framework/submit
包含字段:
_class_respondsToSelector _dlsym
20180916-nm-show-lists.png

4、源代码

具体的代码,也可参考我的Github代码:

  • iHTCboy/iShell: Shell脚本编程技巧,总结一些常用的提高效率的方法。
#!/bin/bash# 定义用到的变量
project_path=""# 定义读取输入字符的函数
function getProjectPath() {# 输出换行,方便查看echo "================================================"# 监听输入并且赋值给变量read -p " Enter project path: " project_path# 如果为空值,从新监听if test -z "$project_path"; thengetProjectPathelseread_dir ${project_path}fi
}function read_dir(){for file in `ls $1`       #注意此处这是两个反引号,表示运行系统命令doif [ -d $1"/"$file ]  #注意此处之间一定要加上空格,否则会报错thenread_dir $1"/"$fileelse#在此处处理文件即可file_path="$1/$file"if `file ${file_path} | grep -q 'Mach-O'` ; thenfind_world=$(echo `nm -u ${file_path} | grep -E 'dlopen|method_exchangeImplementations|performSelector|respondsToSelector|dlsym'`)# -n 字符串    字符串的长度不为零则为真if [ -n "$find_world" ] ; thenecho '-----------------------------\n'echo ${file_path}echo '包含字段:'echo ${find_world}echo '\n'fififidone
}   #读取第一个参数
getProjectPathecho "------- end processing -------"

5、总结

最后,我们把这个脚本输出的全部内容截图,和这些第三方SDK的相关官网链接贴到回信中,告诉苹果审核员,我们应用不存在非法使用热更新 such as dlopen(), dlsym(), respondsToSelector:, performSelector:, method_exchangeImplementations() 等方法,最后苹果就通过了审核!!!

通过 nm 命令和 shell脚本,又让效率提升了n倍,和前面几篇技巧一样,大家应该能感受到shell脚本编程的魅力,希望大家能举一反三,授鱼不如授渔!生活工作中结合 sehll 脚本,提高效率和自动化,珍爱时间不是梦!

后续有更多技巧,会继续给大家分享,期待~

参考

  • shell技巧1 - 生成ipa文件 | iHTCboy's blog
  • Shell 教程 | 菜鸟教程
  • Mac查看文件内容常用的命令小结 | iHTCboy's blog
  • 如有疑问,欢迎在评论区一起讨论!
  • 如有不正确的地方,欢迎指导!

注:本文首发于 iHTCboy's blog,如若转载,请注来源

shell技巧4 - nm命令解决AppStore2.5.2被拒问题相关推荐

  1. Linux课程---7、shell技巧(获取帮助命令)

    Linux课程---7.shell技巧(获取帮助命令) 一.总结 一句话总结: ls --help:简单手册 man ls:内容手册 1.tab补全? 命令+tab:加快敲命令敲文件目录的速度,多敲几 ...

  2. adb shell查看进程提示grep不是内部命令或外部命令解决办法

    1.根据包名查看进程命令adb shell  ps|grep  com.ott.android.TMC(包名) 直接输入会提示grep不是内部命令或外部命令解决办法,解决办法加上引号adb shell ...

  3. shell 知:外部命令

    文章目录 1. 介绍 2. 外部过滤器,程序和命令 2.1. 基本命令 2.1.1. ls 2.1.2. cat,tac 2.1.3. rev 2.1.4. cp 2.1.5. mv 2.1.6. r ...

  4. linux默认csh修改命令,Solaris中默认Shell的修改以及命令行补全的设置

    Solaris中默认Shell的修改以及命令行补全的设置 发布时间:2008-02-18 00:01:41来源:红联作者:qtsmy Solaris10 x86虽然可以跑起来,但有很多方面都用这和以前 ...

  5. cmd无法加载命令解决方法

    情况:在Windows Terminal无法使用nrm命令 解决方法如下: 使用管理员权限打开power shell 输入set-ExecutionPolicy RemoteSigned,输入y,回车

  6. Linux - nm命令

    这里的nm命令指的是GNU Linux版本,Ubuntu20.04,是name的缩写. nm是一个命令行工具,用来列出object文件.库文件或可执行文件中的符号列表(name list, the s ...

  7. android+art模式死机,ADB命令解决切换ART模式后reboot无法进入系统循环卡屏教程

    相信作为原生Android 4.4的一项特色功能,不少同学都会想要体验一下原汁原味ART模式吧.据说在ART模式下Android将不再卡顿,丝丝顺滑的流畅度直逼iOS.当然也有不少同学在把手机切换到A ...

  8. ldd命令 ubuntu_ldd命令,查看依赖的动态库信息 nm命令可以列出一个函数库文件中的符号表...

    ldd命令的作用是查看程序依赖的动态链接库信息.使用nm命令也可以获取库函数的信息:nm命令可以列出一个函数库文件中的符号表,它对静态的库函数和共享的库函数都能起作用. Linux动态库的默认搜索路径 ...

  9. Java 调用Shell脚本执行 SCP命令提示Authorized users only. All activity may be monitored and reported.

    近期做了个小项目主要是关于数据处理这方面的. 在Java后端调用服务器上Shell脚本,而Shell脚本执行时一条Scp执行结果的提示报 Authorized users only. All acti ...

最新文章

  1. CSS(2 )-- CSS样式大全
  2. 音乐与现代计算机技术,计算机技术在音乐教学中应用与研究.doc
  3. 【Linux】 -bash-4.2#问题和Cannot allocate memory
  4. angular1x初始与架构演进(四)gulp配置+OcLazyLoad中资源MD5时间轴更新
  5. 吾解——HTTP(超文本传输协议)
  6. imessage_如何在iPhone和iPad上的iMessage组中提及某人
  7. lombok var_使用var,Lombok和Fluxtion轻松处理事件
  8. 如何使用git命令行上传项目到github
  9. python tornado websocket_Python Tornado实现WEB服务器Socket服务器共存并实现交互的方法...
  10. 【java】Java 原子性、有序性与Happens-Before
  11. 编辑实测:迅捷PDF转换器怎么将PDF转换成JPG
  12. axure sketch 对比_对比平台--Axure和Sketch之间的区别
  13. abb机器人goto指令用法_abb机器人编程指令,机器人编程的程序指令
  14. 图像检索:基于内容的图像检索技术
  15. 草枯树荣,让生命活得云淡风轻
  16. 爬虫第六式:链家房源爬取
  17. 2019CSUST集训队选拔赛题解(二)
  18. python 文件夹拷贝
  19. 揭秘三端型肖特基二极管检测好坏的方法
  20. 20162316刘诚昊 实验五-数据结构综合应用

热门文章

  1. 在广告文案中的最有诱惑力的十个词
  2. 已经开工三天的软件测试工程师:被女足和谷爱凌感动到了
  3. chrome浏览器替换code.jquery.com CDN的加速URL
  4. FaceNet 人脸比对框架 部署+测试
  5. 华大HC32L130 SPI和GPIO模拟驱动NF-03和NF-01-s模块(SI24R1方案,兼容NRF24L01)
  6. android手机怎么取电池,荣耀V8后盖怎么打开 华为荣耀V8手机后盖拆解与更换电池图文教程...
  7. 新的时间处理工具joda
  8. 游戏编辑器制作(8)
  9. Unity Playing模式下鼠标点击放置预制体
  10. 使用单线程还是多线程的问题