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

简介: 1、前言最近App Store审核被拒,2. 5 Performance: Software Requirements,Guideline 2.5.2 - Performance - Software Requirements,遇到这样的问题,回信问苹果,肯定得不到答案,苹果就是礼貌的回复。

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

img_a0b19b2c0a02501147f7d30d5cddcfd7.png
20180916-nm-show-lists.png

4、源代码

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

#!/bin/bash

# 定义用到的变量
project_path=""

# 定义读取输入字符的函数
function getProjectPath() {
    # 输出换行,方便查看
    echo "================================================"
    # 监听输入并且赋值给变量
    read -p " Enter project path: " project_path
    # 如果为空值,从新监听
    if test -z "$project_path"; then
        getProjectPath
    else
        read_dir ${project_path}
    fi
}

function read_dir(){
    for file in `ls $1`       #注意此处这是两个反引号,表示运行系统命令
    do
        if [ -d $1"/"$file ]  #注意此处之间一定要加上空格,否则会报错
        then
            read_dir $1"/"$file
        else
            #在此处处理文件即可
            file_path="$1/$file"
            if `file ${file_path} | grep -q 'Mach-O'` ; then
                find_world=$(echo `nm -u ${file_path} | grep -E 'dlopen|method_exchangeImplementations|performSelector|respondsToSelector|dlsym'`)
                # -n 字符串    字符串的长度不为零则为真
                if [ -n "$find_world" ] ; then
                    echo '-----------------------------\n'
                    echo ${file_path}
                    echo '包含字段:'
                    echo ${find_world}
                    echo '\n'
                fi
            fi
        fi
    done
}   

#读取第一个参数
getProjectPath

echo "------- end processing -------"

5、总结

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

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

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

参考


  • 如有疑问,欢迎在评论区一起讨论!
  • 如有不正确的地方,欢迎指导!


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

目录
相关文章
|
1月前
|
Web App开发 Java Linux
Linux之Shell基本命令篇
Linux之Shell基本命令篇
Linux之Shell基本命令篇
|
1月前
|
Shell Linux UED
|
2月前
|
Unix Linux Shell
【Shell 编程指南 日期命令】Date命令:显示与设置系统时间和日期
【Shell 编程指南 日期命令】Date命令:显示与设置系统时间和日期
55 0
|
2月前
|
安全 Shell Linux
【Shell 命令集合 系统管理 】Linux 锁定终端 vlock命令 使用指南
【Shell 命令集合 系统管理 】Linux 锁定终端 vlock命令 使用指南
37 1
|
2月前
|
缓存 Shell Linux
【Shell 命令集合 链接器(linker)工具】Linux ld命令 将目标文件与库链接为可执行文件或库文件
【Shell 命令集合 链接器(linker)工具】Linux ld命令 将目标文件与库链接为可执行文件或库文件
44 0
|
2月前
|
监控 Shell Linux
【Shell 命令集合 系统管理 】Linux 显示当前登录到系统的用户信息 who命令 使用指南
【Shell 命令集合 系统管理 】Linux 显示当前登录到系统的用户信息 who命令 使用指南
142 45
|
2月前
|
监控 Shell Linux
【Shell 命令集合 系统管理 】Linux 显示目前登入系统的用户信息 w命令 使用指南
【Shell 命令集合 系统管理 】Linux 显示目前登入系统的用户信息 w命令 使用指南
48 2
|
2天前
|
Shell 程序员 数据安全/隐私保护
shell 脚本 if-else判断 和流程控制 (基本语法|基础命令)
shell 脚本 if-else判断 和流程控制 (基本语法|基础命令)
|
14天前
|
网络协议 Unix Shell
第十一章 Shell常用命令与工具(二)
第十一章 Shell常用命令与工具(二)
|
14天前
|
移动开发 Shell Linux
第十一章 Shell常用命令与工具(一)
第十一章 Shell常用命令与工具(一)