带着《iOS应用逆向与安全》,我还在路上…
一直想写篇文章把书里面的某个章节拿出来给大家分享一下,然后顺便推荐下我的新书,但最近一直没有腾出时间来做这件事。后面自己也想了想,如果只是单纯的把书里面的内容拷贝过来然后加个购买链接的话,感觉也不是很好。其实这类的技术文章论坛、网上都有很多很多,你多看一篇或者会有自己的思考,或许只是已阅,我希望这篇文章带给你的不只是一个技术点,还有一点小道理。
学习之路
在这个互联网的时代,学习真的是一件非常容易的事情,网上有很多的资料和前人的总结,可以让我们少走很多弯路。但是随之的问题也来了,东西太多,资料太杂找不到属于自己的路。其实一开始我们都是小白,只想跟着前人的脚印在这条路上越走越远,然后尽量能够为后面的人留下自己的脚印。然后当你开始走的时候,发现大家的脚印和方向都不一样,你该跟谁走?
所以学习的开始,应该先想好规划好自己的路线,把大方向变成小方向,根据自己的规划然后借鉴别人的走法走出属于自己的路。切忌上来一顿操作,然后在各种岔路口迷茫浪费时间。在学习过程中,一定不能浮躁,要放低自己的心态。
- 不能浮躁,很多人一上来就急于求成,然后遇到各种问题的时候又不知从何下手,可能最后你浪费的大把的时间解决了问题,但你还是不知道这是为什么,所以不如放慢步伐,一步一步来。
- 放低心态,应该感谢那些编写文章和提供工具的人,而不是遇到问题的时候把问题甩到别人头上。
另外提到问问题的事,之前有人说过问别人问题的时候,别人都不回答之类的。其实这种情况一般会有三个原因:
- 别人确实在忙,没有时间回答。
- 自己问的问题是完全没有经过思考的问题。
- 问问题的时候完全没有上下文,别人要追问好几个问题才知道你要干嘛。
而且每个人的时间都是宝贵的,有人帮助你回答问题自然要感谢,没人回答也不应该去埋怨谁,而是尝试自己去解决。一开始的时候都会问出小白问题,但是不是遇到什么问题的时候想也不想就丢出来给别人,然后也没有个上下文啥的。自己先思考一番后,实在找不到答案再去问别人。
每个人都应该好好看看提问的智慧
还有就是总会想为什么别人这么优秀,都是“大佬”,其实并没有什么大佬,或者说每个人都是大佬,只是在不同领域不同方向别人比你多花那么一点点时间和多那么一点经验,换一个领域我们都是小白。或者你有没有想过,你在做什么事情的时候总是想着推迟一点点再想,晚一点点再做,或者每一点点就是现在的你和优秀的你之间的一点点差距。
最后用四个“带着”说下我自己的方法吧:
- 带着目标动手学习
- 带着疑问寻找答案
- 带着想法寻求实现
- 带着思维融入工作
选择之路
在埋头走路的时候,可以一鼓作气无惧前行,但是如果觉得自己走偏的时候,或者停下来查看前进方向的时候,总会有太多的顾虑和选择。其实我们技术人也是一样,成长到一定阶段的时候就会面临各种选择,比如:我应该继续深入这个方向研究,还是扩充下自己各个方面的能力。我应该转管理路线还是继续从事技术研究。我应该学习现在热门的机器学习、人工智能这些东西吗,不学会不会跟不上市场需求。我该不该换个工作环境,应该选择哪一个公司等等。
每当需要抉择的时候,不管是自己还是身边的人都会有各种不同的声音,有说深入技术才有自己的优势,也有说要跟上技术的潮流不然会被淘汰之类的。不管怎么说,在选择之前我们都不确定自己会不会是在对的路上,但是自己也需要结合自身的情况作出合理的决定,不要因为决定让自己彷徨不前。我一直坚信我选择的每条路都是对的,当然也非常感谢在路上给我给予我帮助和机会的人。
其实选择也是成长的一个过程,在选择的过程中更加认清自己,有得到也有失去,但最终都是你人生路上的一道美丽的风景。不要害怕自己做错了决定,有错误也有磨炼都是一种经历,一旦决定了就要勇敢的走下去。
其实我自己做视频或写书,都是在成长路上抓住了别人提供的一些机会,同时也是给自己的一个机会。一个事情,就如做视频来说,一开始会想很多,要自己准备资料、制作PPT、录制、确定剪辑效果等等这些东西没人教你,你不知道你会不会做的好,自己能不能cover住,但是不做的话永远也不会知道,同时自己也失去了一个机会。做过后就算自己做的不够完美,也会收获一些经验知道自己还有哪些问题,这些都是不可多得的东西。
回到新书
最后还是提一下我的新书吧,一开始也只是和朋友聊到可以写本书,然后他认识出版社的人可以给我推荐一下,我一开始也犹豫了许久,最后还是决定去做了,原因有三:
- 自己之前也写过一些文章,但是很零散也没有系统性,可以通过写书做一个系统性的总结。
- 自己也是从小白走过来的,有系统性的东西和路线对自己的学习帮助很大,也可以帮助下后面学习的人。
- 这也是一个挑战,没有经验,想要写好很难,但是能够去尝试做的话,并且还能做的还可以的话,对自己也是一份收获。
写书其实是一个很枯燥的过程,你需要去深入理解、去梳理结构、整理文字,其实以我的能力来说,并不能够做到很好,但还是尽力去做了,写的时间也不是很长,从去年年中到10月就完稿了,然后就是等待出版社的一系列流程,所以可能很多东西都没有做到很好。
我对整个书的大体构思是这样的,因为从我自己学习或者是别人遇到的一些问题来看,最大的问题是:
- 自己没有系统的学习路线,都是走到哪算哪。
- 只掌握表面的东西,对内部原理不了解,导致遇到问题不知从何下手。
- 同一个东西不同人的思维方式差很大,这也是知识面决定了策略。
所以我的书主要分为如下几个方面:
- 新手能够快速上手,有工具使用和原理的介绍。
- 有经验的人可以更加深入,从原理、语言、结构各个方面去掌握和理解。
- 可以补充不同层面的知识点、包括正向开发、逆向分析技巧、安全防护等等。
说到思维方式的话,举个简单的例子,不久前在论坛看到一篇去广告的文章:《逆向世界杯直播App 央视影音-iOS客户端》。其实需求很简单就是“去掉广告”,但是具体实现的思路,一百个人可能有99种方法。
在继续阅读下文之前,希望你能自己先针对这个问题思考一下,如果是你你会怎么做,有哪些思路?
这里说下我自己的想法,当然文章里面提供的思路和切入点也是非常好的。首先接到这个需求的时候不着急下手,先思考下可选的方案:
- 找到对应的Controller或者View使用
logify.pl
打印方法调用日志。 - class-dump头文件从类名或方法名中根据一些关键字比如Ad,找找线索。
- 使用frida或者其它的动态函数调用跟踪工具看看调用流程。
- 还原符号,使用LLDB对类的所有方法断点看调用。
- 直接从Malloc stack看View对象是在哪里生成的。
这里选择第4和5个方案简单演示一下。
首先下载App,然后使用frida-ios-dump把解密的ipa提取出来:
➜ frida-ios-dump git:(3.x) ✗ ./dump.py 央视影音
Start the target app 央视影音
Dumping 央视影音 to /var/folders/h3/8n169g610_g69k50z7g_q4gc0000gp/T
start dump /var/containers/Bundle/Application/EF1D9293-1894-490D-B01D-5C21A71A2AFF/Cbox.app/Cbox
Cbox.fid: 100%|████████████████████████████| 38.6M/38.6M [00:13<00:00, 3.02MB/s]
start dump /private/var/containers/Bundle/Application/EF1D9293-1894-490D-B01D-5C21A71A2AFF/Cbox.app/Frameworks/PI_VRRender.framework/PI_VRRender
PI_VRRender.fid: 100%|███████████████████████| 136k/136k [00:00<00:00, 1.18MB/s]
start dump /private/var/containers/Bundle/Application/EF1D9293-1894-490D-B01D-5C21A71A2AFF/Cbox.app/Frameworks/PI_MediaCore.framework/PI_MediaCore
PI_MediaCore.fid: 100%|████████████████████| 1.14M/1.14M [00:00<00:00, 4.74MB/s]
start dump /private/var/containers/Bundle/Application/EF1D9293-1894-490D-B01D-5C21A71A2AFF/Cbox.app/Frameworks/PI_iLiveBase.framework/PI_iLiveBase
PI_iLiveBase.fid: 100%|██████████████████████| 252k/252k [00:00<00:00, 3.10MB/s]
start dump /private/var/containers/Bundle/Application/EF1D9293-1894-490D-B01D-5C21A71A2AFF/Cbox.app/Frameworks/PSLogUpload.framework/PSLogUpload
PSLogUpload.fid: 100%|███████████████████████| 462k/462k [00:00<00:00, 3.73MB/s]
zhanghao-button-denglu.png: 121MB [00:25, 4.91MB/s]
0.00B [00:00, ?B/s]Generating "央视影音.ipa"
然后创建MonkeyDev工程,将解密后的ipa放到TargetApp目录下面运行,出现了如下的错误:
/Users/monkey/Desktop/CBox/CBox/TargetApp/Cbox.app/Frameworks/PSLStreaming.framework/PSLStreaming
This file is encrypted! please use https://github.com/AloneMonkey/frida-ios-dump to decrypt!
这个是因为应用启动的时候这个framework并没有加载起来,可以等加载的时候再dump或者不影响的话先删了,顺便在Build Settings
里面设置MONKEYDEV_RESTORE_SYMBOL
为YES
,方便后面设置符号断点。
重新运行点击世界杯
,然后点击一个直播后使用Xcode查看界面结构找到对应的广告View如下:
然后在LLDB使用如下命令对类的方法下断点:
(lldb) br set -r \[CNAdPlayerView .*\]
Breakpoint 1: 80 locations.
然后重新进入直播可以看到断点断到如下位置:
这是这个View的初始化,同时在调用栈上面看到了-[CNVideoPlayer setupAdNeedPlay]
这个设置是否显示广告的函数,使用下面的命令找到这个函数在文件的偏移然后打开Hopper看一下,这里的0x1002ec3e4就是点击这个函数在Xcode里面看到的地址:
(lldb) image lookup -a 0x1002ec3e4
Address: Cbox[0x00000001002183e4] (Cbox.__TEXT.__text + 2169700)
Summary: Cbox`-[CNVideoPlayer setupAdNeedPlay]
这就很明显可以看到是-[CNVPConfig adEnabled]
在控制的广告是否显示了,编写代码搞定:
CHDeclareClass(CNVPConfig)
CHOptimizedMethod0(self, BOOL, CNVPConfig, adEnabled) {
return NO;
}
CHConstructor{
CHLoadLateClass(CNVPConfig);
CHClassHook0(CNVPConfig, adEnabled);
}
再来看看第5个方案,点击Edit Scheme
选择Diagnostics
勾选Malloc Stack
:
然后重新运行找到View的对象地址(和上面查看View结构一样),然后点击Debug Memory Graph
搜索这个对象,找到这个View的对象后在右侧可以看到这个对象的Malloc Stack
:
同样可以快速定位到-[CNVideoPlayer setupAdNeedPlay]
这个函数从而找到突破口。
所以说学习逆向,更多的是需要把自己掌握的知识能够结合起来并灵活运用,而要做到这一步首先需要自己把需要的理论基础知识有一个系统的掌握和吸收,然后在遇到问题的时候从不同的角度通过不同的方法去尝试和解决它。
硬广
上面就是我在写书的一些经历以及对整本书的一个知识组成和安排,另外上面提到的一些基础、理论、原理以及分析的技巧都会在书本里面讲解到,可以让大家对逆向有一个系统的更深层次的认知和掌握。
最后是时候亮出购买地址了:
京东: https://item.jd.com/12361729.html
天猫: https://detail.tmall.com/item.htm?id=570691214072
很高兴能在今年让这本书和大家见面,并且分享给大家,2018我还在路上,你呢?