快手,快影 iOS App反调试

作者 | 倒影cc
来源 | 掘金,点击阅读原文查看作者更多文章

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

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进行抓包。


https://mp.weixin.qq.com/s/Dxbmg0WnZ8qXKViGi9Psow

【JS】625- Axios 如何缓存请求数据?

发布于:1天以前  |  7次阅读  |  详细内容 »

iOS中触摸事件的传递和响应分析

发布于:7天以前  |  33次阅读  |  详细内容 »

iOS中触摸事件的传递和响应分析

发布于:12天以前  |  37次阅读  |  详细内容 »

探索M1: 安装iOS版本微信/微信读书

发布于:1月以前  |  104次阅读  |  详细内容 »

iOS 稳定性问题治理:卡死崩溃监控原理及最佳实践

发布于:1月以前  |  98次阅读  |  详细内容 »

2021 给 iOS 开发者的一些建议

发布于:1月以前  |  177次阅读  |  详细内容 »

iOS 优化篇 - 启动优化之Clang插桩实现二进制重排

发布于:2月以前  |  182次阅读  |  详细内容 »

抖音品质建设 - iOS启动优化《实战篇》

发布于:2月以前  |  171次阅读  |  详细内容 »

iOS APP 图标版本化

在我们的项目开发过程中,需要频繁打包给测试人员去测试,有时候我们都不知道测试机上安装的版本是否是最新的,这样会造成很多不必要的麻烦和成本。因此我们需要将buildNumber以水印的方式打在APPIcon上,可以很直观的知道当前是哪一个版本。

发布于:2月以前  |  186次阅读  |  详细内容 »

如何实现一个HTTP请求库——axios源码阅读与分析

在前端开发过程中,我们经常会遇到需要发送异步请求的情况。而使用一个功能齐全,接口完善的HTTP请求库,能够在很大程度上减少我们的开发成本,提高我们的开发效率。

发布于:2月以前  |  189次阅读  |  详细内容 »

老司机 iOS 周报 #144 | 2021-01-14

发布于:2月以前  |  227次阅读  |  详细内容 »

快手,快影 iOS App反调试

发布于:3月以前  |  220次阅读  |  详细内容 »

优酷iOS插件化页面架构方法

随着业务不停地迭代,优酷 APP 用于分发视频资源的 UI 控件越写越多,也越来越复杂,并且同时相似相近的代码也非常多。

发布于:5月以前  |  317次阅读  |  详细内容 »

iOS中的内嵌汇编

写一篇在iOS上使用汇编的文章的想法在脑袋里面停留了很久了,但是迟迟没有动手。虽然早前在做启动耗时优化的工作中,也做过通过拦截objc_msgSend并插入汇编指令来统计方法调用耗时的工作,但也只仅此而已。刚好最近的时间项目在做安全加固,需要写更多的汇编来提高安全性(文章内汇编使用指令集为ARM64),也就有了本文

发布于:5月以前  |  339次阅读  |  详细内容 »

77.9K 的 Axios 项目有哪些值得借鉴的地方

Axios 是一个基于 Promise 的 HTTP 客户端,同时支持浏览器和 Node.js 环境。它是一个优秀的 HTTP 客户端,被广泛地应用在大量的 Web 项目中。

发布于:5月以前  |  308次阅读  |  详细内容 »

不会吧,这也行?iOS后台锁屏监听摇一摇

一般情况下,出于省电、权限、合理性等因素考虑,给人的感觉是很多奇怪的需求安卓可以实现,但是iOS就无法实现!今天要介绍的需求也有这种感觉,就是“当 APP 处于后台或锁屏状态时,依旧可以监听到摇一摇,进而触发某些功能,比如:语音播报”。

发布于:5月以前  |  461次阅读  |  详细内容 »

iOS 稳定性:App 被终止的原因

本次 session 主要内容如下: 介绍了后台应用终止的常见原因,并提供了一些优化建议 介绍了 MetricsKit 提供的在代码中获取诊断和性能数据的方法 介绍了 Xcode Metrics Ogranizer 提供的关于线上用户性能数据的可视化报告

发布于:5月以前  |  694次阅读  |  详细内容 »

优酷iOS插件化页面架构方法

随着业务不停地迭代,优酷 APP 用于分发视频资源的 UI 控件越写越多,也越来越复杂,并且同时相似相近的代码也非常多。

发布于:5月以前  |  455次阅读  |  详细内容 »

Vue中Axios的封装和API接口的管理

在vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,它是基于promise的http库,可运行在浏览器端和node.js中。他有很多优秀的特性,例如拦截请求和响应、取消请求、转换json、客户端防御XSRF等。所以我们的尤大大也是果断放弃了对其官方库vue-resource的维护,直接推荐我们使用axios库。如果还对axios不了解的,可以移步axios文档。

发布于:5月以前  |  432次阅读  |  详细内容 »

iOS 持续集成:更完备的 App Store Connect API

时隔两年 App Store Connect API 有了更新,WWDC 2018 推出了 App Store Connect API ,用于自动化一些 App Store Connect 后台操作。这次更新包含了 app 元数据相关的API,补上了原来缺失的重要一环, 使得几乎可以通过 App Store Connect API 完成 App Store Connect 上的所有操作。今后开发、证书配置、用户管理、测试、发布全流程都可以通过 API 完成。

发布于:5月以前  |  539次阅读  |  详细内容 »

最多阅读

快速配置 Sign In with Apple 1年以前  |  4051次阅读
使用 GPUImage 实现一个简单相机 1年以前  |  2754次阅读
开篇 关于iOS越狱开发 2年以前  |  2690次阅读
APP适配iOS11 2年以前  |  2687次阅读
在越狱的iPhone设置上使用lldb调试 2年以前  |  2591次阅读
给数组NSMutableArray排序 2年以前  |  2589次阅读
App Store 审核指南[2017年最新版本] 2年以前  |  2510次阅读
所有iPhone设备尺寸汇总 2年以前  |  2433次阅读
UITableViewCell高亮效果实现 2年以前  |  2412次阅读
使用ssh访问越狱iPhone的两种方式 2年以前  |  2339次阅读
关于Xcode不能打印崩溃日志 2年以前  |  2232次阅读
使用ssh 访问越狱iPhone的两种方式 2年以前  |  2123次阅读
UIDevice的简单使用 2年以前  |  1896次阅读
为对象添加一个释放时触发的block 2年以前  |  1881次阅读
使用最高权限操作iPhone手机 2年以前  |  1864次阅读