去除OplayerLite广告提示-越狱机

最近在学习逆向相关的实践+踩坑, 庆哥的视频中一个课程是对于OPlayerLite进行进行广告处理了, 因为是去年的课程App也更新了逻辑, 我沿着先辈的道路把坑撸了一把, mark这场一天一夜的战斗.

分析层级结构

定位目标对象

连接到越狱机(切换到无网络模式, 因为Oplayer lite有网络的时候加载的广告是不同的,不利于分析), 同时点击任意视频,进入到视频播放页面, 我们会看到广告的view,上面有一行文本”Buy the full version to remove ads?”
这时候我们连接到cycript打印下层级:

1
UIApp.keyWindow.recursiveDescription().toString()


由于我已去除了过了,又从App Store重新下载, 发现还是没有广告,图片暂时就没哈
其中有引起我们注意的层级是:

1
2
3
4
| | | <UIView: 0x17501dc0; frame = (0 0; 320 50); layer = <CALayer: 0x177a8eb0>>
| | | | <UIButton: 0x17778a30; frame = (0 0; 320 50); opaque = NO; layer = <CALayer: 0x177a8d80>>
| | | | | <UIImageView: 0x17630de0; frame = (0 0; 320 50); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x17630ec0>>
| | | | <UILabel: 0x176b1380; frame = (60 0; 260 50); text = 'Buy the full version to r...'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x1762fc70>>

其中UILabel: 0x176b1380中的text属性跟我们看到的ads上是一样的,它的同级view是UIButton, 父view是UIView .
因为咱们要解决的目标是view, 尤为关注是这里的frame.size, 它们都是320 50, label也是height=50. 把这部分截图保存下来,待会查找的时候需要用到

正向分析设计

划重点: 从正向的开发的角度, 分析它是如何设计的

如果是我开发君, 我的伪代码大概如下

1
2
3
4
if (!payBuyFullViersion) {
AdsView *adsview = [[AdsView alloc] init];
[self.palyerView addSubview:adsview]
}

可能其他的逻辑未必跟我符合. 但是一定必然的是, 这个adsView 必须是addSubview上去的,addSubview是UIKit中view的方法, 咱们需要静态分析这个地址, 通过断点来查看它对应的调用者/参数, 从而拿到地址,来定位到OplayerLite

静态分析

从UIKit入手

我们需要用到lldb, 连接到设备, 查看UIKit的存储地址, 然后通过IDA查看addSubview:的静态代码地址.
本地先映射一下 iproxy 1234 1234 , 然后越狱启动debugserver *:1234 -a <pid>

本地连接:

1
im list -o -f


得到了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了).

1
2
3
br s -a '0x00052000+0x002A49F8'
#断点触发后, 打印lr寄存器的值
p/x $lr

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]能返回真即可跳过这段代码. 这个猜想是否正确,毕竟是伪代码,所以需要对汇编部分进行确认:

1
2
__text:0029D2F8 BLX.W _objc_msgSend ; +[OlimSoftUtility isUpgraded]
__text:0029D2FC TST.W R0, #0xFF

第一行很容易看出是发送了消息,也就是刚才说的调用了+[OlimSoftUtility isUpgraded]这个方法, 而第二行, 将第一行+[OlimSoftUtility isUpgraded] 返回值 与 0xFF进行了 TST指令, 对于目前汇编的底子不硬,通过查询资料得知:

TST 指令对 Rn 中的值和 Operand2 的值按位进行“与”运算。 除了结果会被丢弃以外,这与 ANDS 指令功能相同。

那么就基本能确定结论了:

1
2
3
4
if ( ([OlimSoftUtility isUpgraded] && 0xFF) == NO ) {
// 添加广告
}
// 0xFF 固定为YES

头文件最终确认

找到class-dump 出的头文件目录:

1
grep -rn "isUpgraded" ./headers



发现它就是一个类方法,很纯粹.那么也不用太多想法, 试试就试试了.

编写代码

code

让个惊讶的tweak.xm代码:
“当然我这样子处理应该是会引起某些问题了, 但这是目前我分析到的能力”

1
2
3
4
5
6
7
8
9
%hook OlimSoftUtility
+ (BOOL)isUpgraded {
%log;
// NSLog(@"replace this method!!!!!!!!!!!!!!!!!!!");
return YES;
}
%end

Makefile代码:
我指定了IP 和 Port, 待会可以在直接调用 make install 进行安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
export THEOS_DEVICE_IP=localhost
export THEOS_DEVICE_PORT=2222
export ARCHS=armv7
export TARGET=iphone:clang:latest:8.0
export THEOS_MAKE_PATH=/opt/theos/makefiles
export THEOS=/opt/theos
include $(THEOS)/makefiles/common.mk
TWEAK_NAME = removeOplayerAds
removeOplayerAds_FILES = Tweak.xm
include $(THEOS_MAKE_PATH)/tweak.mk
after-install::
install.exec "killall -9 SpringBoard"

一些小坑点

没找到dpkg-deb:

dpkg-deb的原名是/opt/theos/bin/dm.pl, 你需要把它的名字改为dpkg-deb,然后执行下面的语句

1
2
3
4
5
6
➜ removeoplayerads make package
==> Error: /Applications/Xcode.app/Contents/Developer/usr/bin/make package requires dpkg-deb.
make: *** [internal-package-check] Error 1
### 决绝方法
➜ removeoplayerads sudo perl -i -pe 'y|\r||d' /opt/theos/bin/dpkg-deb
Password:

BundleID最准确的获取方法

cycript 进入到目标APP进程后:

1
[[NSBundle mainBundle] bundleIdentifier]

汇编查询

干货, 大全!!!
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0204ic/Cihbjcag.html

效果图

[没什么比实践到的收获有成就感了,它是继续前行的动力之一]

© 2020 In 'flight of thought' All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero