美文网首页
iOS逆向之Hopper进阶

iOS逆向之Hopper进阶

作者: 大宝来巡山 | 来源:发表于2019-04-02 09:32 被阅读0次

    线上发现了一个bug,需要用自产的热补丁对 Bugly 的一个方法进行替换,改变返回值

    /**

    *  App 是否发生了连续闪退

    *  如果启动SDK 且 5秒内 闪退,且次数达到 3次 则判定为连续闪退

    *

    *  @return 是否连续闪退

    */+ (BOOL)isAppCrashedOnStartUpExceedTheLimit;

    可是重试了很多次发现热补丁都没生效。。。

    后面发现我们调用该 Bugly 方法过早,热补丁又生效过迟,所以热补丁一直失效!

    没办法直接拦截[Bugly isAppCrashedOnStartUpExceedTheLimit]返回YES。 那我们只能在闪退次数累加的时候进行拦截了,不让它次数累加起来

    按照 bugly的注释 次数累加是在应用闪退的时候进行的,这个时候我们热补丁已经加载,可以发挥作用了。 可是我们怎么知道 Bugly 怎么累加闪退次数的呢?

    Hopper 登场

    之前有简略介绍过 Hopper 逆向的使用,但是找不到文章了。。。

    找个项目=> Bugly SDK 丢进去 => 编译,由于是debug包,所以可以不用脱壳,直接找到生成的 app 文件,拖到 hopper 工程窗口中

    等 Hopper 解析完,直接输入 Bugly 方法名,找到对应实现的汇编段, 点击 右上角的if(b)f(x)按钮。 hopper 会自动帮我们解析为 OC 代码。

    其实可以看到 Bugly 只是个壳,具体逻辑是在BLYSDKManager类中实现的, 我们继续跟进

    然后发现[BLYSDKManager isAppCrashedOnStartUpExceedTheLimit]也是个壳, 是直接返回crashedOverFlow方法值。

    分析 crashedOverFlow 实现,发现其实是个 get 方法, 直接返回了 bool 类型的 _crashedOverFlow 变量,BLYSDKManager 也实现了该变量的 set 方法。

    所以我们重点就变为了,哪里调用setCrashedOverFlow:方法??

    看上图,其实直接搜关键字是搜不到调用方的,这个时候需要用到strings tab。

    这个 strings 表示搜文本区

    因为 OC 以发消息的方式进行方法调用,方法名都会以 strings的方式在常量区内。  后续的 XREF 表示引用到该变量的地方, 可直接点击跳转。

    我们跟过去看看

    发现只有在-[BLYSDKManager startWithAppId:developmentDevice:config:]+249这一个地方调用了该方法

    我们过去看看该方法的实现

    发现 Bugly 内部的次数累加是放在NSUserDefaults里面的。  key 名也找到了。 条件确实是 超过3次,就设置闪退标示位 为true

    但是哪里对这个值进行累加呢?

    所以我们需要找哪里使用了这个com.tencent.bugly.exitedonstartUplimitkey字符串

    方法1: 直接读汇编,名字太明显了

    方法2: 还是通过 strings tab 进行搜索

    引用区太长 直接通过代码来看吧

    0000000100eff3f8dq0x0000000100f58d60; @"com.tencent.bugly.exitedonstartUplimitkey", XREF=-[BLYSDKManager startWithAppId:developmentDevice:config:]+202,-[BLYSDKManager startWithAppId:developmentDevice:config:]_block_invoke+49,-[BLYAnalyticsManager willTerminateHandler]+72

    可以看到 就3个地方有用到该变量。。 我们排查量就小了

    [BLYAnalyticsManager willTerminateHandler]是把累加次数重置0,可以排除    看方法名,应该是收到 系统willTerminate通知的时候调用,就是应用被正常终止时会调用

    -[BLYSDKManager startWithAppId:developmentDevice:config:]+202,-[BLYSDKManager startWithAppId:developmentDevice:config:]_block_invoke+49,

    有两个区域引用,一个在 block 内,内部逻辑是 重置为0, 可以排除。

    外部区域也有两个地方使用,一个 get,一个 set, 那真正累加的代码就是set那块的逻辑了

    后面就是还原 bugly 内部逻辑了, OC 伪代码

    - (void) startWithAppId:developmentDevice:config: {intcount = [NSUserDefaultsintegerForKey:@"LimitKey"];if(count >=3) {// 累加次数 大等于3,就设置连续闪退成立// isAppCrashedOnStartUpExceedTheLimit 方法返回 YES[selfsetCrashedOverFlow:YES];    }// 对闪退次数进行累加, 并保存回 NSUserDefaultscount +=1;    [NSUserDefaultssetInteger:count forKey:@"LimitKey"];// 如果5秒后 程序还在执行,把闪退次数 重置为 0dispatch_after(5, ^{        [NSUserDefaultssetInteger:0forKey:@"LimitKey"];    });    ...}

    其实可以看到 bugly 整个累加的逻辑,现有的热补丁是没法插手的。。。

    而且 bugly 并不是在闪退的时候对次数进行累加,而是在一启动的时候就累加,只是 5秒后 或者 系统调用了 willTerminate 通知, 然后把次数重置为 0。

    整体逻辑符合 bugly 自己的注释。。。

    题外话

    怎么判断是 5秒 过后?

    dispatch_time(0x0,0x12a05f200)0x12a05f200=5000000000#define DISPATCH_TIME_NOW (0ull)#define NSEC_PER_SEC 1000000000ulldispatch_time(DISPATCH_TIME_NOW, (int64_t)(5*NSEC_PER_SEC)

    参考链接:https://www.jianshu.com/p/384dc5bc1cb4

    需要企业签的,联系QQ:807224386     微信:wx807224386

    相关文章

      网友评论

          本文标题:iOS逆向之Hopper进阶

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