8977b6a4a0ec881bab7f6a942e87c8a7.png

作者丨帕巴拉
来源丨掘金
链接:

https://juejin.im/post/5e8083d06fb9a03c621663df

964c5c6d85ee2aa552b4e3edb10d38f7.png

前言

最近在做的一件事情,从代码层面分析下各家小程序(微信、头条、支付宝、百度)的启动性能,探究各家小程序的实现细节和差异。具体步骤如下:

1、越狱砸壳获取ipa

2、搭建调试壳工程

3、注入callTrace分析代码

4、hook小程序开始调用入口以及渲染完成入口, 加上callTrace逻辑,统计主线程和js线程方法调用栈以及方法耗时

5、增加callTrace 可视化界面入口

当前的进展如下

1、微信、百度已完成,微信的分析工程已上传到github:CallTraceForWeChat。

2、由于本人在百度做小程序相关的工作,故百度的分析工程无法提供,但是原理都是一样的。

3、支付宝当前,已完成1 2 3 5步骤,第4步只做了主线程。代码已上传到github:AliPayForDebug

4、头条未开始。

5、关于callTrace,可以查看CallTraceForWeChatreadme的介绍。

支付宝为什么只做了一半,原因呢是因为支付宝做了很多复杂的反调试防护,给我的分析工作增加了不少障碍。目前为止也没有很好的完成支付宝的反反调试工作。因此这里写一篇文章记录下反反调试支付宝的过程踩过的坑,分享给大家,希望能帮到遇到同样问题的小伙伴。

关于反调试&反反调试

• 反调试与绕过的奇淫技巧1

• 反调试:请移步 iOS 反调试2

• 反反调试:请移步AloneMonkey-关于反调试&反反调试那些事3

• lldb调试原理以及ptrace反调试和汇编调用系统方法:iOS安全防护系列之ptrace反调试与汇编调用系统方法详解4

反反调试支付宝详细过程

越狱&砸壳

越狱

1、下载安装checkra1n

2、checkra1n无法打开,提示“您应该将它移到废纸篓”, 终端执行以下命令

    codesign -f -s - --deep /Applications/checkra1n.app
sudo xattr -r -d com.apple.quarantine
sudo xattr -r -d com.apple.quarantine /Applications/checkra1n.app

也可参考Mac 版爱思助手无法打开,提示“您应该将它移到废纸篓”如何解决?5

3、按提示操作越狱

砸壳

1、我使用的是frida-ios-dump,详细使用步骤可以看作者的githubfrida-ios-dump, 遇到的问题如下

• 更新fria一直卡住

○ 终端先设置代理再执行命令
       export https_proxy=你的代理如http://xxx.xxx.com:9999
export http_proxy=你的代理
sudo pip install -r requirements.txt --upgrade

2、ssh连接手机失败

• 确保在一个局域网
• 重新安装openssl openssh,还不行再重新操作一次越狱

调试壳工程搭建

• 我使用的是MonkeyDev,安装使用请移步原作者的github

• 重要提醒1:在iOS13手机上报如下错时, 除了按照作者文档提到的步骤,还需要删除 AlipayWallet.app 包里的 com.apple.WatchPlaceholder 文件夹,再删除 DerivedData 重新run。

aba468101882245356e095322935e43b.png

反反调试详细步骤

iOS12

MONKEYDEV_DEFAUTL_BUNDLEID=YES

1、开始run时,app直接闪退,控制台log如下

2020-03-28 19:06:15.395011+0800 AlipayWallet[12252:1974005] [AntiAntiDebug] - dlsym get ptrace symbol
2020-03-28 19:06:15.395125+0800 AlipayWallet[12252:1974005] [AntiAntiDebug] - ptrace request is PT_DENY_ATTACH
2020-03-28 19:06:15.701070+0800 AlipayWallet[12252:1974265] [NetworkInfo] Signal strength query returned

2、MonkeyDev已经集成了 AntiAntiDebug ,为什么没生效,因为默认没替换sysctl, 这里打开注释

da8888e54c84335fdbb70ea472883bfc.png

3、打开注释后,还是被杀,log如下

0x10ca47a20, domain=1, instance=2>2020-03-29 00:44:38.089052+0800 AlipayWallet[13454:2074728] [NetworkInfo] Signal strength query returned error: Error Domain=NSPOSIXErrorDomain Code=13 "Permission denied", descriptor: 0x10c9dad30, domain=1, instance=1>2020-03-29 00:44:38.089937+0800 AlipayWallet[13454:2074728] [NetworkInfo] Signal strength query returned error: Error Domain=NSPOSIXErrorDomain Code=13 "Permission denied", descriptor: 0x10c9d9860, domain=1, instance=2>2020-03-29 00:44:52.923884+0800 AlipayWallet[13454:2074898] [NetworkInfo] Signal strength query returned error: Error Domain=NSPOSIXErrorDomain Code=13 "Permission denied", descriptor: 0x10ce07310, domain=1, instance=1>2020-03-29 00:44:52.925006+0800 AlipayWallet[13454:2074898] [NetworkInfo] Signal strength query returned error: Error Domain=NSPOSIXErrorDomain Code=13 "Permission denied", descriptor: 0x10ce07380, domain=1, instance=2>
Message from debugger: Terminated due to signal 5

4、添加符号断点exit,module:libsystem_c.dylib, 看看哪里退出的

○ 没有断住

5、断点my_sysctl方法,可以看到+[AAAPBootStartPoint load]会去调用sysctl

27c7d67f97d8dba500a92a741b771575.png

6、+[AAAPBootStartPoint load]做了什么?可以看到用c函数enable_crash_reporter_service去启动crash上报服务,这个服务里有反调试的逻辑?

○ [AAAPBootStartPoint load]
void __cdecl +[AAAPBootStartPoint load](AAAPBootStartPoint_meta *self, SEL a2)
{
__int64 v2; // x0
__int64 v3; // x0

v2 = MPStartupTimeMarkAppStartPoint((__int64)self); CACurrentMediaTime(v2);
v3 = enable_crash_reporter_service();
CACurrentMediaTime(v3);
MPStartupTimeSetRangeCost("crashinit");
}

7、看了伪代码并没有反调试逻辑,先替换 +[AAAPBootStartPoint load]load 方法为空实现, 顺利进入首页。why?

8、尝试AntiDebugBypass, 也没有生效。

9、接着就是加入我的业务逻辑,主线程已实现,效果如下

f35e637851279e575831c0b49695bc73.png

c494549024245cd86edc2d9de54c8fd1.png

小结

针对iOS12设备,完成以下3步就可以正常调试了

1、配置MONKEYDEV_DEFAUTL_BUNDLEID=YES
2、打开 rebind_symbols((struct rebinding[1]){{"sysctl", my_sysctl, (void*)&orig_sysctl}},1); 注释
3、替换 [AAAPBootStartPoint load] 为空实现

iOS13

MONKEYDEV_DEFAUTL_BUNDLEID=YES

• 在iOS13手机上报如下错 An unknown error has occurred. Domain: com.apple.dt.MobileDeviceErrorDomain Code: -402620415

d64f4e88d0a67b5441eff4a060be63fc.png

此路不通 ?

MONKEYDEV_DEFAUTL_BUNDLEID=NO

1、 可以安装到手机,但是启动闪退

控制台log如下

242a4f77eace1bfddef4254929e9c5db.png

  • 触发my_sysctl的调用栈如下

5b614ef3a8ab732addafcc232389eef0.png

iOS13 替换load不生效

2、是plcrashreporter引起的吗?先替换下enableCrashReporterAndReturnError为空实现

3、替换后 [APDataCenterInterface setDefaultCryptKey:] 会调用exit()直接退出

cce725afedeb7d7ccfc5b4f8df6575f0.png

从伪代码里可以看到取getExtraData, 取到的字符串长度不是32就直接退出了,用lldb调试下,也确实如此。原因是我修改了bundleid, datacenter-default这个值的计算应该是和bundleid绑定的。

  (lldb) po [SecurityGuardManager getInstance]
<SecurityGuardManager: 0x10d365fb0>

(lldb) po [[SecurityGuardManager getInstance] getStaticDataStoreComp]
<SecurityGuardStaticDataStore: 0x11440a9d0>

(lldb) po [[[SecurityGuardManager getInstance] getStaticDataStoreComp] getExtraData:@"datacenter-default"]
nil
(lldb)

439769201b905c5b610e06aac5d9fbd7.png

4、替换getExtraData: 的实现,返回一个长度为32的字符串, 可以正常进入支付宝了,但是无法登陆,还是无法调试,心好累,难道要放弃iOS13吗?

781597732b4b1e4c7e36e250625d03b2.png

5、我的目的是要调试小程序相关的功能,不登陆也没有关系,所以只要hook调强制登陆的逻辑就可以进入首页了。

• 通过view debuger 找到登陆页面的vc

 Printing description of $16:
0x10e0f0a00>

• 通过memory graph 找到vc创建的调用栈,可以看到登录的逻辑是在下面触发的

-[DFMicroApplicationManager doStartApplication:params:launchMode:]

0b7bc3014f0a9e16ef8e1d9432921e60.png

-[DFMicroApplicationManager doStartApplication:params:launchMode:] 伪代码,1700多行,可以想象业务是多么的复杂。

• 在伪代码里搜索 login 关键字,就能看到调登陆的入口 -[DFMicroApplicationManager loginOperation] ,替换这个方法返回nil,还是强制登陆了,没有效果。

• 还有一个关键字 shouldHoldLoginApp ,替换返回YES,直接黑屏了

• 替换login---此路不通

• 再回到登陆页,打印当前的vc,可以看到有2个ViewController,其中登陆aluNavigationController是被present出来的,因此只要调用下dismissViewControllerAnimated就可以退出登陆VC


(lldb) pvc
, state: disappeared, view: not in the window
| , state: disappeared, view: not in the window
| | , state: disappeared, view: not in the window
| | | , state: disappeared, view: not in the window
| | , state: disappeared, view: (view not loaded)
| | , state: disappeared, view: (view not loaded)
| | , state: disappeared, view: not in the window
| | , state: disappeared, view: (view not loaded)
+ , state: appeared, view: , presented with: <_uifullscreenpresentationcontroller>
| | , state: appeared, view:
(lldb)

• 我在登陆按钮点击的时候dissMiss登录VC, 顺利进入支付宝首页

• 虽然进了首页,但是小程序还是打不开,网络请求发送失败

42c43f9b24e26fe36dc00f64dcfb3b7d.png

因为修改了bundleid, 尝试去恢复bundleid,首先重写NSBundle bundleIdentifier,返回固定值com.alipay.iphoneclient,然后重写infoDictionary, 写死CFBundleIdentifier的值,抓包看,所有发出的请求都请求成功了,但是小程序还是无法打开。

小结

虽然顺利进入了支付宝首页,但是小程序功能还是不可用,我决定暂时放弃iOS13了 , 支付宝针对bundleid做了特殊的防护逻辑,后续再慢慢研究。

总结

我日常工作也调试过很多家的app, 基本上自动化反反调试工具都能攻破,相比支付宝,他们的防护手段还是常规操作。

对比微信和支付宝的防护可以看到支付宝的防护手段是从入口切断调试;微信没有做这种调试入口的防护,但是发现你在调试时会封你登陆的微信账户。

2种防护都会消耗掉反调试者的大量时间和精力,没有耐心的基本就放弃了。

逆向之路,路漫漫其修远兮,继续加油吧。

参考:

[1]http://iosre.com/t/topic/9351 
[2]https://www.jianshu.com/p/f1f254166cd5 
[3]http://bbs.iosre.com/t/topic/8179 
[4]https://www.jianshu.com/p/ebdfb0a25c85 
[5]https://www.i4.cn/news_detail_39414.html

a122f6d28c51714454084f2330663d9e.png

近期精彩内容推荐:  

8b620aee1900e363d0e9fdef5cef96f1.png 我错了,我被跳槽后的高薪冲昏了头脑

8b620aee1900e363d0e9fdef5cef96f1.png 我和面试官关于操作系统的一场对弈!

8b620aee1900e363d0e9fdef5cef96f1.png 牛逼!完美解密Redis与秒杀系统!!

8b620aee1900e363d0e9fdef5cef96f1.png 3行代码,搞定AI自动抠图

045b5d3ce8327b332f91fc9880f5f704.png

6e892767823dbe058bcd084c950b48dd.png

在看点这里bebaa230cd0158a8fccffbff0982de2f.gif好文分享给更多人↓↓

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐