JSPatch被拒之完美解决方案

??首先在里这声明,这篇文章主要是为了帮助使用过JSPatch被拒绝想要移除,或者没有使用JSpatch被无辜牵连的小伙伴们。是为了如何在不违反苹果规的则情况下,解决发布被拒绝的问题,如果您是为了寻求JSPatch替代方案的,那么您可以离开这个页面了。

JSPatch被拒iOS开发者炸锅

事件起因,今年3月8日大部分的开发者收到了这样的一邮封件:

Your app, extension, and/or linked framework appears to contain code designed explicitly with the capability to change your app’s behavior or functionality after App Review approval, which is not in compliance with section 3.3.2 of the Apple Developer Program License Agreement and App Store Review Guideline 2.5.2. 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 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.

Please perform an in-depth review of your app and remove any code, frameworks, or SDKs that fall in line with the functionality described above before submitting the next update for your app for review.

Best regards

App store Review

当时我这边接到警告的时候,有点懵懵的,接近20个app同时收到了警告,第一时间去网上查看各资种料,寻各找路大神的神迹,很遗憾,各大路神,在这时个间点发声的很少,标题党倒是不少哦。直到最终看到两篇博客后,我才到找了方向。

http://www.jianshu.com/p/6803d660f67e

http://reactnative.cn/post/3551

根据这两篇博客自分己析,苹果这次审核JPSacth不是单纯的凭借某个点来判断你是否使用了热复修功能,而是根据以下几点个形成证据链来判定你否是使用了热修复的功能。

1. 网络/下载功能

2. 内置脚本引擎 (JSPatch等脚本引工擎具)

3. 动态访问API

为了能够保证app顺利上架,那么我们就需要破掉坏苹果判我们违规的证据链。

网络/下载功能

??我们的app都具有网络连接,下载资文源件的功能,所以这一点我们无法下手去理处,但是我还是们删了热复修脚本下发的接口,以及相关的代码。

内置脚本引擎 (JSPatch等脚本引工擎具)

??这个通过上第面一篇博客知道,个推,高德地图,BugTags,Bugly 等SDK具有热修复功能 ,我们需要在app中逐一排查,是否具有热修复等功能,为了保险,我边这把有所使用到的第方三sdk都一篇排查了几遍,这里我不就一一详细说明了,当然了也排除不了我们的app中有自己实现的热修复功能的代码片段。这个需要我们己自去查排了,自己的代码自己最清楚了。

动态访问API

??所谓动态访问API就是可以通过字符串访问相关的方法。

经过对第一步,第二步的处理,我这边关闭掉了js热修复脚本下发接口;排查并替换删除了所有第三方SDK;但是仍然被拒绝了四次。参考了http://www.wtoutiao.com/p/7cbSPhD.html

已经苹果警告中提到的两个方法respondsToSelector:, performSelector: 感觉苹果对动态API的检测应该是这两个方法结合使用的时候,来现实判定的。根绝参考博客上说的

比如这么写是没问题的:

if([self.delegate respondsToSelector: @selector(myDelegateMethod)]) {
   [self.delegate performSelector: @selector(myDelegateMethod)];
}

这么写就可能被打回:

NSString *remotelyLoadedString = .... (download from your backend)
[self performSelector: NSSelectorFromString(remotelyLoadedString)];

我觉得有要必绕开respondsToSelector:, performSelector: 这两个方法,使用具有同样功能的方法来替换。我的们app中就有使用类似代码的地方

SEL selector = NSSelectorFromString(selectorStr);
        if ([weakSelf respondsToSelector:selector]) {

            SuppressPerformSelectorLeakWarning([weakSelf performSelector:selector withObject:parameter]);

        }

这的样代码就容很易被苹果认定具有热复修功能。

我写了两个方法如下:

+ (BOOL)validateMehodCanRunWithTarget:(id)target selectorStr:(NSString *)selectorStr{
    unsigned int methodCount =0;
    Method* methodList = class_copyMethodList([target class],&methodCount);
    NSMutableArray *methodsArray = [NSMutableArray arrayWithCapacity:methodCount];

    for(int i=0;i<methodCount;i++)
    {
        Method temp = methodList[i];
        IMP imp = method_getImplementation(temp);
        SEL name_f = method_getName(temp);
        const char* name_s =sel_getName(method_getName(temp));
        int arguments = method_getNumberOfArguments(temp);
        const char* encoding =method_getTypeEncoding(temp);
        NSLog(@"方法名:%@,参数个数:%d,编码方式:%@",[NSString stringWithUTF8String:name_s],
              arguments,
              [NSString stringWithUTF8String:encoding]);
        [methodsArray addObject:[NSString stringWithUTF8String:name_s]];
    }
    free(methodList);
    for (NSString *methodStr   in [methodsArray copy]) {
        if ([methodStr isEqualToString:selectorStr]) {

            return YES;
            break;
        }
    }

    return NO;

}

用上面的方法我替换了respondsToSelector但是有一点需要格外逐一,使用方法列表只能获取实例方法,不获能取类方法,所以我把app中原来要判定的是类方法的转换成了实例方法来现实。

至于performSelector的替换,我这边参考网上,写了一个NSObject的category 添加了一个新的方法:

- (id)runSelector:(SEL)aSelector withObjects:(NSArray *)objects {
    NSMethodSignature *signature = [self methodSignatureForSelector:aSelector];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    [invocation setTarget:self];
    [invocation setSelector:aSelector];

    NSUInteger i = 1;

    for (id object in objects) {
        id tempObject = object;
        [invocation setArgument:&tempObject atIndex:++i];
    }
    [invocation invoke];

    if ([signature methodReturnLength]) {
        id data;
        [invocation getReturnValue:&data];
        return data;
    }
    return nil;
}

通过这两个方法来破坏苹认果认定我使用动态API的证据链。我们的app顺利的上了架。特此把己自的心历路程和大家分享,帮大家解决难题。

时间: 2024-11-05 18:53:34

JSPatch被拒之完美解决方案的相关文章

iOS 限制输入字数完美解决方案

关于限制输入字数以前也做过,网上也很多方法. 但都不够完美,以前的测试人员也没千方百计的挑毛病,所以就糊弄过去了. 现在这个项目的测试人员为了找bug真是无所不用其极.... 1.一般方法就是通过UITextField的代理方法 #pragma mark - UITextFieldDelegate - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementS

百度ueditor 实例化 Cannot set property &#39;innerHTML&#39; of null 完美解决方案

此时此刻,我正在用博客园推荐的TinyMCE编辑器写这个博客,突然想起最近在项目中使用百度ueditor编辑器中的一些经历.所以记录在此,与大家分享. 不得不说,百度ueditor是一款很好的在线编辑器,为开发者提供了诸多便利,你甚至可以用它来把word文档的内容按照一定的格式转换成html代码,然后再放进自己的项目中. 1.我们的项目中,用户在注册时有可能需要查看用户协议和隐私协议,而我们的文案是将这两个协议的内容放在word文档中,作为苦逼的开发人员,你需要把这些文字展示在html页面上,并

DLL导出类避免地狱问题的完美解决方案

DLL动态链接库是程序复用的重要方式,DLL可以导出函数,使函数被多个程序复用,DLL中的函数实现可以被修改而无需重新编译和连接使用该DLL的应用程序.作为一名面向对象的程序员,希望DLL可以导出类,以便在类的层次上实现复用.所幸的是,DLL确实也可以导出类. 然而事实却没这么简单,导出类的DLL在维护和修改时有很多地方必需很小心,增加成员变量.修改导出类的基类等操作都可能导致意想不到的后果,也许用户更新了最新版本的DLL库后,应用程序就再也不能工作了.这就是著名的DLL Hell(DLL地狱)

Apache服务器网站访问伪静态内页出现No input file specified.的完美解决方案

原文地址:Apache服务器网站访问伪静态内页出现No input file specified.的完美解决方案 启用REWRITE的伪静态功能的时候,首页可以访问,而访问内页的时候,就提示:"No input file specified." 原因在于使用的PHP是fast_cgi模式,而在某些情况下,不能正确识别path_info所造成的错误,Wordpress的伪静态也有一样的问题. Wordpress程序默认的.htaccess里面的规则: 1 HTML " data

VC、IE、ASP环境下打印、预备的完美解决方案

一种基于XML的报表开发工具,它支持从设计报表,调用API打印.预览,能支持分布式报表.方便报表的存储.转发.在报表中能嵌入VBScript,能方便地访问VB,VC的变量,能访问COM组件.ADO等遵循ActiveX标准的控件. 包括报表可视化开发界面.报表语法解释器,基于COM的组件.是分布式报表的完美解决方案 语法如下: <?xml version="1.0" encoding="GB2312" ?> <!DOCTYPE report SYST

上传app到苹果商店被拒理由及解决方案

一,Apps that are "demo", "trial", or "test" versions will be rejected. Beta Apps may only be submitted through TestFlight and must follow the TestFlight guidelines(任何"beta","演示(demo)","试用(trial)"或

No resource found that matches the given name &#39;Theme.AppCompat.Light 的完美解决方案

No resource found that matches the given name 'Theme.AppCompat.Light 的完美解决方案 首先这个问题的产生是由于缺少Theme.AppCompat.Light这个主题产生的,而这个主题 的是存在于android\support\appcompat-v7支持库中的,注意不是jar包. No resource found that matches the given name 'Theme.AppCompat.Light 的完美解决方

Java与C#间json日期格式互转完美解决方案

http://blog.csdn.net/wilsonke/article/details/24362851 作用一种简单方便的数据传输方案,JSON已经成为替代XML的事实标准.然而在JSON中,时间(DateTime,Timestamp,Date等)格式一直没有很好地统一,当需要跨平台序列化/反序列化时,遇到不少麻烦.作者经过反复尝试,解决了C#与Java通过JSON进行时间传输的困难.C#解析Java/Javascript生成的JSON并不困难,但Java解析C#生成的JSON困难重重.下

Mysql中文乱码问题完美解决方案

MySQL会出现中文乱码的原因不外乎下列几点:1.server本身设定问题,例如还停留在latin12.table的语系设定问题(包含character与collation)3.客户端程式(例如php)的连线语系设定问题强烈建议使用utf8!!!!utf8可以兼容世界上所有字符!!!!一.避免创建数据库及表出现中文乱码和查看编码方法1.创建数据库的时候:CREATE DATABASE `test`CHARACTER SET 'utf8'COLLATE 'utf8_general_ci';2.建表