最近在学习逆向相关的实践+踩坑, 庆哥的视频中一个课程是对于OPlayerLite进行进行广告处理了, 因为是去年的课程App也更新了逻辑, 我沿着先辈的道路把坑撸了一把, mark这场一天一夜的战斗.
分析层级结构
定位目标对象
连接到越狱机(切换到无网络模式, 因为Oplayer lite有网络的时候加载的广告是不同的,不利于分析), 同时点击任意视频,进入到视频播放页面, 我们会看到广告的view,上面有一行文本”Buy the full version to remove ads?”
这时候我们连接到cycript打印下层级:
由于我已去除了过了,又从App Store重新下载, 发现还是没有广告,图片暂时就没哈
其中有引起我们注意的层级是:
其中UILabel: 0x176b1380
中的text属性跟我们看到的ads上是一样的,它的同级view是UIButton, 父view是UIView .
因为咱们要解决的目标是view, 尤为关注是这里的frame.size, 它们都是320 50
, label也是height=50. 把这部分截图保存下来,待会查找的时候需要用到
正向分析设计
划重点: 从正向的开发的角度, 分析它是如何设计的
如果是我开发君, 我的伪代码大概如下
可能其他的逻辑未必跟我符合. 但是一定必然的是, 这个adsView 必须是addSubview上去的,addSubview是UIKit中view的方法, 咱们需要静态分析这个地址, 通过断点来查看它对应的调用者/参数, 从而拿到地址,来定位到OplayerLite
静态分析
从UIKit入手
我们需要用到lldb, 连接到设备, 查看UIKit的存储地址, 然后通过IDA查看addSubview:的静态代码地址.
本地先映射一下 iproxy 1234 1234
, 然后越狱启动debugserver *:1234 -a <pid>
本地连接:
得到了Oplayer lite的偏移地址和UIKit偏移地址
同时我们看到了UIKit的文件地址(可能有的地址是在设备上, 那么你需要拷贝到本地,不想这样子就连一下Xcode,你就会在本地看到它了)
IDA分析UIKit, 并获取addSubview:的地址:
在lldb下断点,记得加上上面看到的偏移,如:
然后进入到播放界面触发断点
体力活查询
因为上面我们讲到[self.palyerView addSubview:adsview]
这里的adsView是作为参数的,所以我们需要Print object r2
漫长的开始 c
和粘贴 po $r2
,一遍持续一遍注意看打印出来的frame,是不是有我们符合的frame=(n,n,320,50)
这可能会很漫长,取决于当前页面子元素数量和人品~
…….
当你发现frame跟我们所看到符合的时候,那么基本就可以确认是它了.同时有个地方要注意:
你需要看到这个地址来自于Oplayer lite才可以, 否则执行以下ni
,执行下一条汇编直到看见它
而第一条指令的地址就是我们要的地址, 减去我们上面的偏移地址,拿到静态代码的地址.
分析目标静态代码
对逻辑静态分析
通过上面拿到的地址, 我们可以看到这里是一个实例方法-[PlayViewController addAds_OnLocalAds]
不是很仔细的看了一遍伪代码,这个方法是被调用来展示view,但是否展示的逻辑并不在这里, 我们需要看谁是它的调用方, 因为删掉之前的断点,重新在-[PlayViewController addAds_OnLocalAds]
这个方法上下断点, 依然加上偏移地址(这里的偏移地址已经是OPlayerlite了).
LR寄存器(R14)可以理解当代码段执行完毕后要回到调用者的地址.
通过LR寄存器得到的值, 我们减去偏移地址,可以得到调用者在静态代码的位置.
依然借助IDA分析, 可以看到msg_send的一些部分是相关的设置方向, frame, getWidth等方法, 而调用的位置就在viewWillAppear:这里.
寻找绕弯的方法
现在, 我们定位到了调用添加广告View的代码块, 继续往上翻,能不能找到帮助我们跳过这里的逻辑呢?
果然, 神器就是神器, 留意左边这根线:
辅助IDA的伪代码,我们还能发现些神马:
这里的两个跳转对应了两个逻辑判断分支, 我在图片中表明了, 逻辑2的情况其实稍加复杂, 但我在逻辑1发现了关键点:
1 if ( !((unsigned int)+[OlimSoftUtility isUpgraded](&OBJC_CLASS___OlimSoftUtility, "isUpgraded", a3) & 0xFF) )
伪代码的意思是+[OlimSoftUtility isUpgraded]
的返回值和 #0xFF 进行了逻辑与的运算, 理解到 #0xFF 是非0类型必为真, 而现在只需要+[OlimSoftUtility isUpgraded]
能返回真即可跳过这段代码. 这个猜想是否正确,毕竟是伪代码,所以需要对汇编部分进行确认:
第一行很容易看出是发送了消息,也就是刚才说的调用了+[OlimSoftUtility isUpgraded]
这个方法, 而第二行, 将第一行+[OlimSoftUtility isUpgraded]
返回值 与 0xFF进行了 TST
指令, 对于目前汇编的底子不硬,通过查询资料得知:
TST 指令对 Rn 中的值和 Operand2 的值按位进行“与”运算。 除了结果会被丢弃以外,这与 ANDS 指令功能相同。
那么就基本能确定结论了:
头文件最终确认
找到class-dump 出的头文件目录:
发现它就是一个类方法,很纯粹.那么也不用太多想法, 试试就试试了.
编写代码
code
让个惊讶的tweak.xm代码:
“当然我这样子处理应该是会引起某些问题了, 但这是目前我分析到的能力”
Makefile代码:
我指定了IP 和 Port, 待会可以在直接调用 make install 进行安装
一些小坑点
没找到dpkg-deb:
dpkg-deb的原名是/opt/theos/bin/dm.pl, 你需要把它的名字改为dpkg-deb,然后执行下面的语句
BundleID最准确的获取方法
cycript 进入到目标APP进程后:
汇编查询
干货, 大全!!!
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0204ic/Cihbjcag.html
效果图
[没什么比实践到的收获有成就感了,它是继续前行的动力之一]