zoukankan      html  css  js  c++  java
  • 快手,快影 iOSApp反调试

    快手,快影的App保护用的是同一套代码,反调试也很容易,下面请看过程。

    >作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:761407670 进群密码‘博客’,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!

    1.快手App去反调试

    直接frida砸壳,然后创建MonkeyDev工程,并在antiAntiDebug.m文件的相关函数下断点,然后运行。

    App运行起来后,将在my_dlsym函数断下来,然后bt打印调用栈:

    然后在栈1地址处下断, 即: b 0x00000001054c3430,按C运行。 在0x00000001054c3430 处断下来之后, 修改返回值 x0 = 0 ,即: register write $x0 0

    在汇编55行:

    nop该行指令,然后运行即可,命令如下: memory write -s 4 0x1028c09f4 0xd503201f

    2.快影App去反调试

    砸壳快影,然后创建MonkeyDev工程, 运行,闪退。 看下日志,打印如下: [AntiAntiDebug] - dlsym get ptrace symbol [AntiAntiDebug] - ptrace request is PT_DENY_ATTACH 在antiAntiDebug的my_ptrace和my_dlsym处下断点。

    去反调试 函数1:0x000000010265c920,
    汇编55行: nop掉改行汇编指令即可正常运行,命令如下:
    memory write -s 4 0x102e089f4 0xd503201f

    2.1 快影App sign的计算逻辑

    首先通过IDA静态分析,我们得到如下关键方法:

    id __cdecl +[KSMWPassportSecurityTools hmac:withKeyData:](KSMWPassportSecurityTools_meta *self, SEL a2, id a3, id a4)
    {
      id v4; // x19
      id v5; // x20
      __int64 v6; // x21
      __int64 v7; // x1
      __int64 v8; // x22
      void *v9; // x0
      const char *v10; // x20
      void *v11; // x19
      void *v12; // x21
      void *v13; // x19
      size_t v14; // x0
      char v16; // [xsp+8h] [xbp-48h]
      v4 = a4;
      v5 = a3;
      v6 = objc_retain(a3, a2);
      v8 = objc_retain(v4, v7);
      v9 = (void *)objc_retainAutorelease(v5);
      v10 = (const char *)objc_msgSend(v9, "cStringUsingEncoding:", 4LL);
      objc_release(v6);
      v11 = (void *)objc_retainAutorelease(v4);
      v12 = objc_msgSend(v11, "bytes");
      v13 = objc_msgSend(v11, "length");
      objc_release(v8);
      v14 = strlen(v10);
      CCHmac(2LL, v12, v13, v10, v14, &v16);   // 2 = kCCHmacAlgSHA256
      return (id)objc_msgSend(&OBJC_CLASS___NSData, "dataWithBytes:length:", &v16, 32LL);
    }
    
    复制代码

    其完整的sign计算逻辑为:

    [KSMWPassportSecurityTools createSignWithStringNonce:ssecurity:longValue: value]
        |
        +[KSMWPassportSecurityTools hmac:withKeyData:] = resultData
            |
            CCHmac(2LL, 0, 0, x3, 101, resultBuf); 
        |
        data = bswap32(value)
        |
        [data appendData: resultData]
        |
        [KSMWPassportSecurityTools base64Encode:]
    
    
    复制代码

    于是对[KSMWPassportSecurityTools createSignWithStringNonce:ssecurity:longValue: value]方法下断,然后点击获取验证码,其调用栈如下:

    thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 18.1
    frame #0: 0x0000000101856fb0 KwaiYDelux`+[KSMWPassportSecurityTools createSignWithStringNonce:ssecurity:longValue:]
    frame #1: 0x0000000101856c30 KwaiYDelux`+[KSMWPassportSecurityTools signOnURLPath:method:requestParams:] + 364
    frame #2: 0x0000000101855910 KwaiYDelux`-[KSMWNetworkOperation url:method:parameters:cookies:completionHandler:] + 212
    frame #3: 0x0000000101863a14 KwaiYDelux`-[KWPassportAPI POST:bodyParams:completionHandler:] + 280
    frame #4: 0x00000001018607f8 KwaiYDelux`-[KWPassportAPI requestSMSCode:countryCode:type:completion:] + 412
    frame #5: 0x000000010185f25c KwaiYDelux`-[KWPassport requestSMSCode:countryCode:type:completion:] + 132
    frame #6: 0x00000001026799dc KwaiYDelux`-[KWAccountChannelService_Imp sendSMSWithRequest:handler:] + 264
    frame #7: 0x000000018deea800 CoreFoundation`__invoking___ + 144
    frame #8: 0x000000018ddcc3c0 CoreFoundation`-[NSInvocation invoke] + 292
    frame #9: 0x000000010259659c KwaiYDelux`___lldb_unnamed_symbol58737$$KwaiYDelux + 1180
    frame #10: 0x000000010817e7fc Flutter`__45-[FlutterMethodChannel setMethodCallHandler:]_block_invoke + 116
    frame #11: 0x000000010811d6d0 Flutter`flutter::PlatformViewIOS::HandlePlatformMessage(fml::RefPtr<flutter::PlatformMessage>) + 680
    frame #12: 0x0000000108170048 Flutter`std::__1::__function::__func<flutter::Shell::OnEngineHandlePlatformMessage(fml::RefPtr<flutter::PlatformMessage>)::$_32, std::__1::allocator<flutter::Shell::OnEngineHandlePlatformMessage(fml::RefPtr<flutter::PlatformMessage>)::$_32>, void ()>::operator()() + 80
    frame #13: 0x000000010812a988 Flutter`fml::MessageLoopImpl::FlushTasks(fml::FlushType) + 96
    frame #14: 0x000000010812ef0c Flutter`fml::MessageLoopDarwin::OnTimerFire(__CFRunLoopTimer*, fml::MessageLoopDarwin*) + 32
    frame #15: 0x000000018de75554 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 28
    frame #16: 0x000000018de75284 CoreFoundation`__CFRunLoopDoTimer + 864
    frame #17: 0x000000018de74ab8 CoreFoundation`__CFRunLoopDoTimers + 248
    frame #18: 0x000000018de6fa08 CoreFoundation`__CFRunLoopRun + 1844
    frame #19: 0x000000018de6efb4 CoreFoundation`CFRunLoopRunSpecific + 436
    frame #20: 0x000000019007079c GraphicsServices`GSEventRunModal + 104
    frame #21: 0x00000001ba6d0c38 UIKitCore`UIApplicationMain + 212
    frame #22: 0x0000000100e0c028 KwaiYDelux`___lldb_unnamed_symbol1343$$KwaiYDelux + 100
    frame #23: 0x000000018d9328e0 libdyld.dylib`start + 4
    
    复制代码

    调用+[KSMWPassportSecurityTools hmac:withKeyData:]
    其中hmac=POST&/pass/ky/sms/code&countryCode=+86&phone=ZTSP__R2oN18L5Ilx8weM__ZTSP&type=395&8951850021377611294
    data = 空

    汇编50行,调用 CCHmac(2LL, 0, 0, x3, 101, resultBuf); // 2 = kCCHmacAlgSHA256, CC_SHA256_DIGEST_LENGTH = 32, 即加密返回长度=32

    (lldb) x/50xg $x3, 长度=101, 即=POST&/pass/ky/sms/code&countryCode=+86&phone=ZTSP__R2oN18L5Ilx8weM__ZTSP&type=395&8951850021377611294

    内存数据如下:

    0x2823ace91: 0x61702f2654534f50 0x6d732f796b2f7373      
    0x2823acea1: 0x632665646f632f73 0x6f437972746e756f      
    0x2823aceb1: 0x702636382b3d6564 0x53545a3d656e6f68      
    0x2823acec1: 0x314e6f32525f5f50 0x7738786c49354c38
    0x2823aced1: 0x5053545a5f5f4d65 0x39333d6570797426
    0x2823acee1: 0x3538313539382635 0x3637373331323030
    0x2823acef1: 0x0000003439323131 0x0000000000000000
    0x2823acf01: 0x0000000000000000 0x0000000000000000
    复制代码

    (lldb) x/50xg $x5 -> 加密结果

    0x16f1290c8: 0x35da8aa020e5bd2f 0xf6fc50b2b2c85841
    0x16f1290d8: 0x2e00c9df95a02ada 0x17325b620c1cd33f
    复制代码

    将data<7c3b5c2a 5ec9161e> append 加密结果,得到:

    <7c3b5c2a 5ec9161e 2fbde520 a08ada35 4158c8b2 b250fcf6 da2aa095 dfc9002e 3fd31c0c 625b3217>
    复制代码

    然后调用 [KSMWPassportSecurityTools base64Encode:], 传入上面的data。 得到:
    fDtcKl7JFh4vveUgoIraNUFYyLKyUPz22iqgld/JAC4/0xwMYlsyFw==

    这就是最终的sign,可以通过抓包进行对比。

    由于快影App 大部分业务界面都是flutter开发的,目前还没有能力进行逆向,flutter页面的接口请求也没有走Native,没办法进行抓包。

    wireshark只能抓到https加密包,它的本质就是把经过网卡的数据包复制一份,而不是像charles在手机系统上起一个代理服务器,对App的网络请求进行代理请求。

    据网上说,可以通过代理(fan qiang)工具进行代理,然后再使用charles进行抓包。

    >作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:761407670 进群密码‘博客’,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!
    作者:倒影cc
    链接:https://juejin.im/post/5ee59de76fb9a047f558d8ed

  • 相关阅读:
    485串口接线
    mvc3 升级mvc5
    VB连接ACCESS数据库,使用 LIKE 通配符问题
    VB6 读写西门子PLC
    可用的 .net core 支持 RSA 私钥加密工具类
    解决 Win7 远程桌面 已停止工作的问题
    解决 WinForm 重写 CreateParams 隐藏窗口以后的显示问题
    解决安装 .net framework 发生 extracting files error 问题
    CentOS7 安装配置笔记
    通过特殊处理 Resize 事件解决 WinForm 加载时闪烁问题的一个方法
  • 原文地址:https://www.cnblogs.com/IOSkf/p/13376458.html
Copyright © 2011-2022 走看看