实战的对象
我平时没事喜欢看小说,一般都是起点的小说,但基本上都是看免费的盗版小说,但是盗版小说的app很多,起初追书神器是不错的app,更新快而且及时,后来改了模式,只有一个源而且所谓的正版源需要扣除币,这种情况下我选择了另一个app,叫笔趣阁app,但这个名字的app在AppStore有很多版本,我选择的是Deborah Carpenter开发的版本,目标版本4.0
为什么要hook这个app呢?其实原本这个app的广告只是在书的列表页面,也就算了,如果你不小心退出后台,或者切换程序,回来后都要等好几秒的视频广告,实在忍无可忍
以下只用于学习,不可以用于商业
准备
先看看广告是怎样的
还有一个广告是在退出后台,然后进去的时候出现
我们整理下思路
如果需要去掉广告
那么就要把自己想象成开发者,你广告会怎么添加,以对方的思路去想,然后hook代码,达到去掉广告的效果
我手上的手机是为越狱的iPhone7
所以需要一个脱壳完毕的ipa安装包,先在iPad上运行AppStore版本,脱壳拿到ipa安装包
开干!
新建项目,选择iOS下面的MonkeyApp,由于打算运行在未越狱手机,所以Target App可以不管,其他根据自己正常开发填写就好
项目只能运行在真机上,所以模拟器是不能的,会得到错误提示:
Do not support the simulator, please use the real iPhone Device.
项目的文件结构可以查看官网wiki,有写清楚,前期准备工作需要先把ipa拖进
/项目名/项目名/TargetApp
这里面打开项目点击Build Setting 拉到最后,找到
MONKEYDEV_CLASS_DUMP
改为YES,这个操作上为了可以获取ipa的全部h声明文件,方便可以找到方法名称主要工作在
Logos/项目名Dylib.xm
里面进行准备完成后,插入手机,点击run开始运行
用Reveal进行查看
随便点一个view,可以看到它所属的控制器的名字叫
ShelfViewController
这样我们就定位了控制器的名字,到项目文件夹里面有一个
JWReader_Headers
到文件夹,里面放的就是整个项目的h文件,我用文本编辑器拖入打开,定位打开ShelfViewController
可以看到有很多方法,这个这个思考下到底添加广告的方法在哪里,其实做法有很多,我在里面找不到有添加广告的方法,估计可能是直接在viewdidload方法里面直接初始化,或者在数据加载的时候初始化,这种情况下是无法单独分离出来,但好在我找到了一个属性
@property(nonatomic) BOOL showAd;
我们可以试试这个属性能否起作用,那么在什么时候调用这个属性比较好呢
在用reveal查看的时候发现这个是一个
UICollectionView
所以找下代理方法(int)numberOfSectionsInCollectionView:(id)arg1
这个方法会重复调用,当view刷新的时候也会调用,比较适合拿来用,所以在项目名Dylib.xm
中,我们先清空里面原来的代码,不清空也没关系,写入一下代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 所有属性都需要声明才可以调用,interface的名字随意写,正常情况下为了看清楚都是写当前类的名字
@interface ShelfViewController
@property(nonatomic) BOOL showAd;
@end
// hook的控制器,必须指定要hook哪个服务器,这样才能让编译器知道你要修改的控制器
%hook ShelfViewController
- (int)numberOfSectionsInCollectionView:(id)arg1
{
self.showAd = NO;
return %orig();// %orig这个是调用原代码的方法,比如源代码返回1,那么%orig也是等于1
}
%end写完,就试试吧,插入手机 -> 运行
你会发现广告不见了,那么就证明你猜对了,我们通过修改属性达到了去掉首页广告,那么接下来我们继续,把每次重新打开app都会跳出全屏广告也去掉
其实按照思路,这个也很简单,我们会发现在广告的出现是在我们回到桌面或者切换app后回到app才会出现,所以调用方法就是在AppDelegate里面,我们把AppDelegate的头文件拿出来
按照app的生命周期,我们知道在AppDelegate中有些方法在退出到后台和进入app前会执行,那么我们完全可以hook那些代码,阻止运行,所以我把退出和进入都hook掉,确保不会遗漏
1
2
3
4
5
6
7
8
9%hook AppDelegate
- (void)applicationWillTerminate:(id)arg1{}
- (void)applicationDidBecomeActive:(id)arg1{}
- (void)applicationWillEnterForeground:(id)arg1{}
- (void)applicationDidEnterBackground:(id)arg1{}
- (void)applicationWillResignActive:(id)arg1{}
%end如果方法有返回值,那么一定要返回,你可以直接返回nil,但不能不返回
如果没有返回值,那么直接什么都不写,这样原先方法就会被hook掉,不会被执行原代码
运行一波试试,退出到桌面再回来,嗯,没问题,那么就确定了,这是可以的,完美避过广告,虽然可能有些当法的多余的,但不影响使用.
这样一个简单的hook app就这样完成了,这是最简单的hook程序,还有一些困难的,比如修改源码,修改判断if,这些就需要更多的软件去辅助,比如之前介绍的ida与hopper就是用于观察app源码与修改源码,这部分需要学习汇编代码才可以,逆向可以说简单,也可以说复杂的.
学逆向不是为了去破解别人的app,对我来说,最重要的是为了防止别人破解自己的app,我们从逆向的过程中学习,想象自己的app如果被别人拿去,如何才能不被反编译,不被hook
正向和逆向不会冲突,只要一起学习,才能更好的加深自己对于开发的理解,做出更好的程序.