美文网首页
十一、Tweak(二)

十一、Tweak(二)

作者: Lovell_ | 来源:发表于2018-12-10 18:48 被阅读51次

    需求一:去掉《段友app》首页的广告

    思路:从数据源(dataSource)入手,把广告数据删除

    大致步骤:

    1. APP脱壳导出头文件;
    2. 目标cell->tableView->dataSource->adMode->init方法返回nil。
      用Reveal找到广告cell,从Reveal中拿到该cell对应的TableView的内存地址,再用MJTool打印出该TableView的数据源对象#0x1460cf800.dataSource,在数据源对象(或其父类)中找到数据源(是个可变数组),打印出来看看(#0x14689de00.feeds#0x14689de00->_feeds),确定是数据源,再找出哪个是广告数据模型(疑是DYFeedAdert),hook掉里面adView的set方法,这是方法之一;
    3. 创建Tweak项目,编写代码,编译打包安装;
    记录一些调试的技巧:打印
    1. 打印内存中属性或变量中的数据:通过Reveal或MJTool拿到对象的内存地址,用->来访问打印,结果显示在终端中;
    2. 打印方法中参数的值:NSLog(@"arg1: %@", arg1),在方法中打印形参的数据,结果显示在控制台中;
    3. 如果当前类没有注意查看父类中是否有;
    4. %c()的使用,生成一个class对象。
      使用场景:需要使用到原有代码中存在的类。
    if ([cell isKindOfClass:%c(DYFeedAdertCell)]){ }
    替代:
    if ([cell isKindOfClass:[DYFeedAdertCell class]]){ }
    

    而不建议Tweak中声明再使用DYFeedAdertCell,这样会覆盖掉原有的类:

    @interface DYFeedAdertCell : UITableViewCell
    @end
    @implementation DYFeedAdertCell
    @end
    
    1. 给特定的view设置背景颜色,便于调试、区别。
    思路总结

    一、从数据源入手:
    1.1 找到广告数据模型,其init方法返回nil;(本次使用的方法,此法有可能报错,如果数组添加nil没做处理的话)

    1.1.1 方法

    %hook DYFeedAdert
    - (void)setAdView:(id)arg1{
        arg1 = nil;
        %orig;
    }
    %end
    

    1.1.2 方法

    %hook GDTNativeExpressAdView
    - (id)initWithSize:(struct CGSize)arg1 positionId:(id)arg2 threadId:(id)arg3 traceId:(id)arg4 {
        return nil;
    }
    %end
    



    1.2 找到广告数据模型,从数据源中删除掉,好处是不会产生数组添加nil报错的问题

    因为方法未声明报的错:方法名没有找到,方法找不到

    Tweak.xm:39:32: error: instance method '-feeds' not found (return type defaults to 'id') [-Werror,-Wobjc-method-access]
            NSMutableArray *array = [self feeds];
                                          ^~~~~
    Tweak.xm:33:32: note: receiver is instance of class declared here
    @class DYFeedAdertCell; @class DYFeedsViewController; 
                                   ^
    1 error generated.
    

    解决方法:声明下

    // 此用来声明方法
    @interface MJMethodSet
    -(id)feeds;
    @end
    

    Tweak代码:hook numberOfRowsInSection:方法,在刷新数据之前,从数据源中移除广告数据。

    %hook DYFeedsViewController
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
        NSMutableArray *dataList = [self feeds];
        NSMutableArray *adArray = [NSMutableArray array];
        for (int i = 0; i < [dataList count]; ++i)
        {
            id mode = dataList[i];
            if ([mode isKindOfClass:%c(DYFeedAdert)])
            {
                [adArray addObject:mode];
            }
        }
        [dataList removeObjectsInArray:adArray];
        return %orig;
    }
    %end
    

    1.3

    二、从cell高度入手
    2.1 如果是广告cell,高度设置为1;

    @interface MJMethodSet
    // 用来声明方法
    -(id)feeds;
    @end
    
    %hook DYFeedsViewController
    // 从cell高度入手
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        NSMutableArray *dataList = [self feeds];
        for (int i = 0; i < [dataList count]; ++i)
        {
            id mode = dataList[i];
            if ([mode isKindOfClass:%c(DYFeedAdert)])
            {
                return 1;
            }
        }
        return %orig;
    }
    %end
    

    实际情况这样写,app会卡,而且突然回到广告cell。

    最好的方法是网络请求数据下来后,把广告数据删掉,这个会面会做到。

    需求二:删掉刷新按钮

    %hook DYHomeRefreshButton
    - (id)init {
        return nil;
    }
    %end
    

    搞定。

    相关文章

      网友评论

          本文标题:十一、Tweak(二)

          本文链接:https://www.haomeiwen.com/subject/ziizcqtx.html