iOS逆向之移除Oplayer lite广告

iOS逆向之移除Oplayer lite广告

一、环境要求:

1、iPod touch6: iOS10.3.1(已经越狱)

2、Xcode安装MonkeyDev

3、OPlayer Lite.ipa(Window PP助手获取)【非必须】

二、lldb调试定位

1、直接在app store上下载Oplayer lite播放神器,为了方便调试,最好将设备设置成语言英文,后面会用到!

2、通过ssh连接越狱设备

ssh [email protected]

3、关闭设备上的其他进程,最好只保留Oplayer lite,通过以下命令获取设备上所有运行的进程,只查看目标进程:

iPod:~ root# ps aux | grep OPlayer
mobile    6593   3.6  6.5  1384832  66024   ??  Ss    5:27PM   0:20.84 /var/containers/Bundle/Application/AAAB1B0F-A9A6-455C-BE5B-8E0230A75252/OPlayer Lite.app/OPlayer Lite
root      6607   0.0  0.0   624224      8 s000  R+    5:29PM   0:00.00 grep OPlayer

4、根据教程iOS10.3.1 砸壳之路使用两种方式进行应用砸壳,这里笔者就不详述了。

笔者通过第一种静态方式结果如下:

iPod:~ root# Clutch -i
Installed apps:
1:   快拍 - Snapchat 
2:   优酷视频-世界杯赛事全程高清直播 
3:   央视影音 
4:   A4 Player 
5:   可可英语-英语听力口语训练神器 
6:   VPN Plus Privacy Protector 
7:   搜狐视频-法医秦明1、2两季独家连播 
8:   微博 
9:   腾讯视频 
10:  Shazam 音乐神搜 
11:  OPlayer Lite - media player 
12:  VPN - Super Unlimited Proxy 
13:  天天快报 - 腾讯兴趣阅读平台 
iPod:~ root# Clutch -d 11
Zipping OPlayer Lite.app
Error: Could not obtain mach port, either the process is dead (codesign error?) or entitlements were not properly signed!

Error: Failed to dump  with arch arm64

2018-08-06 17:36:20.796 Clutch[6610:278690] failed operation :(
2018-08-06 17:36:20.796 Clutch[6610:278690] application {name = 'NSOperationQueue 0x1004be080'}
Error: Failed to dump 

2018-08-06 17:36:20.797 Clutch[6610:278690] failed operation :(
2018-08-06 17:36:20.797 Clutch[6610:278690] application {name = 'NSOperationQueue 0x1004be080'}
ASLR slide: 0x100020000
Dumping  (arm64)
Patched cryptid (64bit segment)
Writing new checksum
Zipping OPlayer WatchKit Extension.appex
FAILED: 
Finished dumping com.olimsoft.oplayer.lite in 20.9 seconds

很遗憾失败了,其原因自行百度。。。

所以最好通过动态砸壳来解决,若是大佬能通过Clutch方式解决,请私信me!!!

5、查看广告存在的位置

iPod:~ root# cycript -p 6593          
cy# [[UIApp keyWindow] recursiveDescription].toString()

`; layer = >
   | >
   |    | >
   |    |    | >
   |    |    |    | >
   |    |    |    | >
   |    |    |    |    |  (layer)
   |    |    |    |    |    |  (layer)
   |    |    |    |    |    |    |  (layer)
   |    |    |    |    |    |  (layer)
   |    |    |    |    |    |  (layer)
   |    |    | >
   |    |    | >
   |    |    | >
   |    |    | >
   |    |    |    | >
   |    |    |    |    | >
   |    |    |    | >
   |    |    | >
   |    |    |    | >
   |    |    |    |    | >
   |    |    |    |    | ; value: 3.000000>
   |    |    |    |    |    | >
   |    |    |    |    |    |    | >
   |    |    |    |    |    | >
   |    |    |    |    |    | >
   |    |    |    |    | >
   |    |    |    | >
   |    |    |    | >
   |    |    |    | >
   |    |    |    |    | >
   |    |    |    | >
   |    |    |    |    | >
   |    |    | >
   |    |    |    | >
   |    |    |    |    | >
   |    |    |    | >
   |    |    |    |    | >
   |    |    |    | >
   |    |    |    |    | >
   |    |    |    | >
   |    |    |    |    | >
   |    |    |    | >
   |    |    |    |    | >
   |    |    |    | >
   |    |    |    |    | >
   |    |    |    |    |    | >
   |    |    |    |    |    | >
   |    |    |    |    | ; value: 0.000000>
   |    |    |    |    |    | >
   |    |    |    |    |    |    | >
   |    |    |    |    |    | >
   |    |    |    |    |    | >
   |    |    |    | >
   |    |    |    |    | >
   |    |    |    | 

这里需要说明的是,[[UIApp keyWindow] recursiveDescription].toString()是查看当前页面的所有view。稍微仔细点的同学就会主要到,每次进入播放界面时,界面上方都有一个banner,内容是Buy the full version to remove ads?.所以简单的方式是,通过搜索关键字查找控件。可得到如下结果:

我们可以在后面进行lldb调试的时候,根据这个为依据进行查找调试。

5、利用debugserver结合LLDB调试app

debugserver *:1234 -a "OPlayer Lite"

6、新建终端LLDB连接App

lldb
process connect connect://172.20.128.176:1234

7、接下来查看偏移地址

image list -o -f
[  0] 0x000000000005c000 /var/containers/Bundle/Application/AAAB1B0F-A9A6-455C-BE5B-8E0230A75252/OPlayer Lite.app/OPlayer Lite(0x000000010005c000)

......

[  7] 0x0000000000350000 /Users/weihua/Library/Developer/Xcode/iOS DeviceSupport/10.3.1 (14E304)/Symbols/System/Library/Frameworks/UIKit.framework/UIKit

通过hopper v4分析addSubview在UIKit框架的偏移地址:
addSubview:0x0000000187775d24

通过image list -o -f分析UIKit框架在模块中加载的的起始偏移地址:
UIKit: 0x0000000000350000

设置断点:

br s -a 0x0000000000350000+0x0000000187775d24
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000187ac5d24 UIKit`-[UIView(Hierarchy) addSubview:]
UIKit`-[UIView(Hierarchy) addSubview:]:
->  0x187ac5d24 <+0>:  stp    x24, x23, [sp, #-0x40]!
    0x187ac5d28 <+4>:  stp    x22, x21, [sp, #0x10]
    0x187ac5d2c <+8>:  stp    x20, x19, [sp, #0x20]
    0x187ac5d30 <+12>: stp    x29, x30, [sp, #0x30]
Target 0: (OPlayer Lite) stopped.
(lldb) po $x2
>

(lldb) c
Process 432 resuming
Process 432 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000187ac5d24 UIKit`-[UIView(Hierarchy) addSubview:]
UIKit`-[UIView(Hierarchy) addSubview:]:
->  0x187ac5d24 <+0>:  stp    x24, x23, [sp, #-0x40]!
    0x187ac5d28 <+4>:  stp    x22, x21, [sp, #0x10]
    0x187ac5d2c <+8>:  stp    x20, x19, [sp, #0x20]
    0x187ac5d30 <+12>: stp    x29, x30, [sp, #0x30]
Target 0: (OPlayer Lite) stopped.
(lldb) po $x2
>

......
......
......

(lldb) po $x2
>

(lldb) c
Process 432 resuming
Process 432 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000187ac5d24 UIKit`-[UIView(Hierarchy) addSubview:]
UIKit`-[UIView(Hierarchy) addSubview:]:
->  0x187ac5d24 <+0>:  stp    x24, x23, [sp, #-0x40]!
    0x187ac5d28 <+4>:  stp    x22, x21, [sp, #0x10]
    0x187ac5d2c <+8>:  stp    x20, x19, [sp, #0x20]
    0x187ac5d30 <+12>: stp    x29, x30, [sp, #0x30]
Target 0: (OPlayer Lite) stopped.
(lldb) po $x2
>

(lldb) c
Process 432 resuming
Process 432 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000187ac5d24 UIKit`-[UIView(Hierarchy) addSubview:]
UIKit`-[UIView(Hierarchy) addSubview:]:
->  0x187ac5d24 <+0>:  stp    x24, x23, [sp, #-0x40]!
    0x187ac5d28 <+4>:  stp    x22, x21, [sp, #0x10]
    0x187ac5d2c <+8>:  stp    x20, x19, [sp, #0x20]
    0x187ac5d30 <+12>: stp    x29, x30, [sp, #0x30]
Target 0: (OPlayer Lite) stopped.
(lldb) po $x2
>

到此为止找到了相关控件,然后通过ni命令往回追溯目标模块调用时的起始地址。

(lldb) ni
Process 432 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = instruction step over
    frame #0: 0x0000000187ac5d28 UIKit`-[UIView(Hierarchy) addSubview:] + 4
UIKit`-[UIView(Hierarchy) addSubview:]:
->  0x187ac5d28 <+4>:  stp    x22, x21, [sp, #0x10]
    0x187ac5d2c <+8>:  stp    x20, x19, [sp, #0x20]
    0x187ac5d30 <+12>: stp    x29, x30, [sp, #0x30]
    0x187ac5d34 <+16>: add    x29, sp, #0x30            ; =0x30 
Target 0: (OPlayer Lite) stopped.
(lldb)  
Process 432 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = instruction step over
    frame #0: 0x0000000187ac5d2c UIKit`-[UIView(Hierarchy) addSubview:] + 8
UIKit`-[UIView(Hierarchy) addSubview:]:
->  0x187ac5d2c <+8>:  stp    x20, x19, [sp, #0x20]
    0x187ac5d30 <+12>: stp    x29, x30, [sp, #0x30]
    0x187ac5d34 <+16>: add    x29, sp, #0x30            ; =0x30 
    0x187ac5d38 <+20>: mov    x20, x0
Target 0: (OPlayer Lite) stopped.
(lldb)  
(lldb) 
error: invalid thread
Process 432 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = instruction step over
    frame #0: 0x0000000187ac5d30 UIKit`-[UIView(Hierarchy) addSubview:] + 12
UIKit`-[UIView(Hierarchy) addSubview:]:
->  0x187ac5d30 <+12>: stp    x29, x30, [sp, #0x30]
    0x187ac5d34 <+16>: add    x29, sp, #0x30            ; =0x30 
    0x187ac5d38 <+20>: mov    x20, x0
    0x187ac5d3c <+24>: mov    x0, x2
Target 0: (OPlayer Lite) stopped.
(lldb)  
 
 ........
 
 
Process 432 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = instruction step over
    frame #0: 0x0000000187ac6074 UIKit`-[UIView(Hierarchy) addSubview:] + 848
UIKit`-[UIView(Hierarchy) addSubview:]:
->  0x187ac6074 <+848>: b      0x180414250               ; objc_release

UIKit`-[UIView(Internal) _addSubview:positioned:relativeTo:]:
    0x187ac6078 <+0>:   stp    x28, x27, [sp, #-0x60]!
    0x187ac607c <+4>:   stp    x26, x25, [sp, #0x10]
    0x187ac6080 <+8>:   stp    x24, x23, [sp, #0x20]
Target 0: (OPlayer Lite) stopped.
(lldb)  
Process 432 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = instruction step over
    frame #0: 0x00000001003d01f8 OPlayer Lite`_mh_execute_header + 3621368
OPlayer Lite`_mh_execute_header:
->  0x1003d01f8 <+3621368>: adrp   x8, 5089
    0x1003d01fc <+3621372>: ldr    x20, [x8, #0x630]
    0x1003d0200 <+3621376>: mov    x0, x19
    0x1003d0204 <+3621380>: mov    x1, x20
Target 0: (OPlayer Lite) stopped.
(lldb)  
Process 432 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = instruction step over
    frame #0: 0x00000001003d01fc OPlayer Lite`_mh_execute_header + 3621372
OPlayer Lite`_mh_execute_header:
->  0x1003d01fc <+3621372>: ldr    x20, [x8, #0x630]
    0x1003d0200 <+3621376>: mov    x0, x19
    0x1003d0204 <+3621380>: mov    x1, x20
    0x1003d0208 <+3621384>: bl     0x10106f28c               ; symbol stub for: objc_msgSend
Target 0: (OPlayer Lite) stopped.

由结果看来,OPlayer Lite模块起始基地址为0x1003d01f8
然后通过减去OPlayer Lite偏移地址0x000000000005c000,

(lldb) p/x 0x1003d01f8-0x000000000005c000
(long) $74 = 0x00000001003741f8

然后把0x00000001003741f8放入已经打开的Hopper Disassembler v4中,用快捷键G进行查找,结果如下:

iOS逆向之移除Oplayer lite广告_第1张图片
01.png

这里我们进行更加结果进行猜测,addAds_OnLocalAds很有可能是我们需要查找的结果。接下来,我们对其进行进行断点调试,先找到addAds_OnLocalAds的地址:

iOS逆向之移除Oplayer lite广告_第2张图片
02.png

地址为:0x000000010037c518

(lldb) p/x 0x000000010037c518+0x000000000005c000
(long) $76 = 0x00000001003d8518

可能此时设备卡顿不动,继续运行,并且移除所有命令:

(lldb) c
Process 432 resuming
(lldb) br del
About to delete all breakpoints, do you want to do that?: [Y/n] y
All breakpoints removed. (1 breakpoint)

重新设置断点,即addAds_OnLocalAds处设置断点:

br s -a 0x00000001003d8518

然后返回上一界面,重新播放视频,此时命令行输出:

* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
    frame #0: 0x00000001003d8518 OPlayer Lite`_mh_execute_header + 3654936
OPlayer Lite`_mh_execute_header:
->  0x1003d8518 <+3654936>: stp    d9, d8, [sp, #-0x50]!
    0x1003d851c <+3654940>: stp    x24, x23, [sp, #0x10]
    0x1003d8520 <+3654944>: stp    x22, x21, [sp, #0x20]
    0x1003d8524 <+3654948>: stp    x20, x19, [sp, #0x30]
Target 0: (OPlayer Lite) stopped.
(lldb)  

接下来获取名称及地址:

(lldb) p (char*)$x1
(char *) $78 = 0x0000000101454c97 "addAds_OnLocalAds"

方法执行完以后应该返回的地址

(lldb) p/x $lr
(unsigned long) $83 = 0x00000001003d01f8
(lldb) p/x 0x00000001003d01f8-0x000000000005c000
(long) $84 = 0x00000001003741f8

0x00000001003741f8是我们需要的地址,根据这个地址可以在Hopper V4中进行跳转:

iOS逆向之移除Oplayer lite广告_第3张图片
03.png

在上图中,找了方法addAds_OnLocalAds方法,说明位置正确,然后根据汇编指令cbnz,可知这一处是一个判断语句。

最关键的信息是,我们还看到了在一个"PlayViewController"控制器中存在一个'localAdView'的成员变量。

同时继续往上继续查找,可以找到该方法是在[PlayViewController viewWillAppear:]中调用的,如下图:

iOS逆向之移除Oplayer lite广告_第4张图片
04.png

接下来,我们进行确认。

通过class-dump的方式获取头文件。这里不说具体原因了,命令如下:

class-dump OPlayer_Lite.decrypted -H -o header

然后在header文件夹中可以进行确认。

OK,到此为止,我们已经找到了 广告加载的界面的了。我们需要通过工程来进行最后的实现。

三、MonkeyDev调试定位

这里为了简单,我采用了MonkeyDev来实现,当然也可以通过 Theos 的方式,笔者亲测成功!!!

关于如何安装MonkeyDev,请移步MonkeyDev安装教程及简介。

需要说明的是,MonkeyDev的好处就是能通过界面调试app,定位控件,当然如果安装了Reveal那就更加简单,iOS上面的界面调试神器。但是
MonkeyDev需要已经破解了ipa,这里可以通过Window上的PP助手获取。

首先新建工程,命名Oplayerlite.其它的也不多了,直接贴关键代码。

iOS逆向之移除Oplayer lite广告_第5张图片
07.png

然后运行工程,发现之前的 'Buy the full version to remove ads?' 相关的UIView已经没了,但是又出现了新的广告,以下截图来自Reveal,Xcode也可以。

iOS逆向之移除Oplayer lite广告_第6张图片
08.png

然后在PlayViewController中找到了相关的调用GADBannerView *gAdView;,然后通过头文件查找GADBannerView,结果找到了如下调用函数:

iOS逆向之移除Oplayer lite广告_第7张图片
09.png

此时抱着怀疑的态度试了修改工程中OplayerliteDylib.xm内容如下:

// See http://iphonedevwiki.net/index.php/Logos

#import 

@interface PlayViewController

@property(strong, nonatomic) UIView *localAdView;

@end

%hook PlayViewController

- (void)viewWillAppear:(BOOL)arg1
{
    self.localAdView = [[UIView alloc]initWithFrame:CGRectZero];
    %orig;
}

%end


%hook GADBannerView

- (void)setFrame:(struct CGRect)arg1
{
    NSLog(@"__%s__",__func__);
}

%end

然后run一下,结果居然成功了。

OK,恭喜,到此为止真的实现了Oplayer lite播放时移除广告的功能。

四、打包安装App至非越狱

后面,我想这如何将此app安装的到非越狱的设备上。

iOS逆向之移除Oplayer lite广告_第8张图片
10.png

将此app进行到处,放入Payload文件中压缩,重命名为.ipa的文件。此时可能还无法进行安装,需要最后一步操作,进行ipa重签名。
具体请参考iOS重签名操作

你可能感兴趣的:(iOS逆向之移除Oplayer lite广告)