iOS逆向 一条方法去掉某应用广告
本帖最后由 wstclzy2010 于 2020-6-15 11:14 编辑前言:
本来是打算通过hook自带的”超级会员去广告“开关来查看它自带的去广告的逻辑,可是失败,好像有服务器鉴定,没办法了,只能照普通途径去广告了。
一、所需工具:
[*]frida-ios-dump应用砸壳
[*]class-dump导出应用头文件
[*]reveal查看应用层次结构
[*]hopper反汇编工具(可以不用,比较费时)
[*]debugserver/lldb动态调试工具
二、从界面出发:
得到类TBCAdCriusTableViewCell
查看头文件
```
@interface TBCAdCriusTableViewCell : TBCAdCriusBaseTableViewCell <TBCAdCriusRenderDelegate>
{
_Bool _havaStatDiscardEvent;
CriusContainerView *_container;
TBCFRSBatchDeleteCoverView *_batchDeleteCoverView;
}
+ (double)tableView:(id)arg1 rowHeightForObject:(id)arg2;
- (void).cxx_destruct;
@property(nonatomic) _Bool havaStatDiscardEvent; // @synthesize havaStatDiscardEvent=_havaStatDiscardEvent;
@property(retain, nonatomic) TBCFRSBatchDeleteCoverView *batchDeleteCoverView; // @synthesize batchDeleteCoverView=_batchDeleteCoverView;
@property(retain, nonatomic) CriusContainerView *container; // @synthesize container=_container;
- (void)didSelectCriusObjectOnCell:(long long)arg1;
- (_Bool)adCellIsHighlightedOrSelected;
- (void)adCellDetailButtonDidClickEvent:(id)arg1;
- (void)adCellBottomBarReplyButtonDidClickEvent;
- (void)adCellBottomBarAgreeButtonDidClickEvent:(id)arg1;
- (void)adCellBottomBarShareButtonDidClickEvent:(id)arg1;
- (void)adCellCloseButtonDidClickEvent:(id)arg1;
- (void)commonAdStat:(unsigned long long)arg1;
- (void)commonShowStat;
- (void)didSelectObject:(id)arg1;
- (void)setObject:(id)arg1;
- (void)setCommonBackgroundColor;
- (void)layoutSubviews;
// Remaining properties
@property(readonly, copy) NSString *debugDescription;
@property(readonly, copy) NSString *description;
@property(readonly) unsigned long long hash;
@property(readonly) Class superclass;
@end
```
决定给- (void)layoutSubviews下断点
用hopper查看地址(也可以直接使用shortMethodDescription方法找到地址下断点):
三、动态调试:
(这里的lldb安装了xia0lldb脚本)
```
(lldb) im li -o -f | grep TBClient
0x00000000000c0000 /var/containers/Bundle/Application/BC287342-F5D8-450E-8B9D-7972124D7806/TBClient.app/TBClient(0x00000001000c0000)
(lldb) br s -a '0xc0000+0x1028d00d4'
Breakpoint 1: where = TBClient`___lldb_unnamed_symbol197197$$TBClient, address = 0x00000001029900d4
(lldb) c
Process 5773 resuming
Process 5773 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x00000001029900d4 TBClient`___lldb_unnamed_symbol197197$$TBClient
TBClient`___lldb_unnamed_symbol197197$$TBClient:
->0x1029900d4 <+0>:sub sp, sp, #0x30 ; =0x30
0x1029900d8 <+4>:stp x20, x19,
0x1029900dc <+8>:stp x29, x30,
0x1029900e0 <+12>: add x29, sp, #0x20 ; =0x20
0x1029900e4 <+16>: mov x19, x0
0x1029900e8 <+20>: adrp x8, 12811
0x1029900ec <+24>: ldr x8,
0x1029900f0 <+28>: stp x0, x8,
Target 0: (TBClient) stopped.
```
查看调用栈,栈的顺序是先下后上,先调用的方法或函数在下方,后调用的在上方
```
(lldb) sbt
==========================================xia0LLDB===========================================
BlockSymbolFile Not Set The Block Symbol Json File, Try 'sbt -f'
=============================================================================================
frame #0: TBClient`- + 0
frame #1: UIKit`- + 1200
........
........
frame #23: UIKit`UIApplicationMain + 208
frame #24: TBClient`main + 200
frame #25: libdyld.dylib`start + 4
(lldb) c
```
断点应该下错了,没有找到有用的被调用的方法,回头看看头文件,有个属性CriusContainerView *_container,猜测是广告容器视图,看看它里面有什么方法
```
(lldb) po
<CriusContainerView: 0x105c6f588>:
in CriusContainerView:
Class Methods:
+ (id) currentCriusRender; (0x1029815e4)
Properties:
@property (copy, nonatomic) NSString* clickCommand;(@synthesize clickCommand = _clickCommand;)
@property (nonatomic) BOOL hasSetClickCommand;(@synthesize hasSetClickCommand = _hasSetClickCommand;)
Instance Methods:
- (void) configWithCriusNode:(id)arg1 isNightMode:(unsigned char)arg2 promotionItem:(id)arg3 renderDelegate:(id)arg4; (0x102981794)
- (double) calculateHeightWithCriusData:(id)arg1; (0x1029818ac)
- (void) configWithCriusData:(id)arg1 isNightMode:(unsigned char)arg2 promotionItem:(id)arg3 renderDelegate:(id)arg4; (0x1029816d4)
- (id) clickCommand; (0x102981bc0)
- (void) setClickCommand:(id)arg1; (0x102981bd0)
- (BOOL) hasSetClickCommand; (0x102981bdc)
- (void) setHasSetClickCommand:(BOOL)arg1; (0x102981bec)
- (id) init; (0x10298167c)
- (void) .cxx_destruct; (0x102981bfc)
- (id) hitTest:(struct CGPoint)arg1 withEvent:(id)arg2; (0x102981930)
(UIView ...)
```
有个明显的初始化方法- (id)init,下断点看看:
```
(lldb) b 0x10298167c
Breakpoint 2: where = TBClient`___lldb_unnamed_symbol196763$$TBClient, address = 0x000000010298167c
(lldb) c
Process 5773 resuming
Process 5773 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
frame #0: 0x000000010298167c TBClient`___lldb_unnamed_symbol196763$$TBClient
TBClient`___lldb_unnamed_symbol196763$$TBClient:
->0x10298167c <+0>:sub sp, sp, #0x30 ; =0x30
0x102981680 <+4>:stp x20, x19,
0x102981684 <+8>:stp x29, x30,
0x102981688 <+12>: add x29, sp, #0x20 ; =0x20
0x10298168c <+16>: adrp x8, 12826
0x102981690 <+20>: ldr x8,
0x102981694 <+24>: stp x0, x8,
0x102981698 <+28>: adrp x8, 12608
Target 0: (TBClient) stopped.
```
bt查看调用栈:
```
(lldb) sbt
==========================================xia0LLDB===========================================
BlockSymbolFile Not Set The Block Symbol Json File, Try 'sbt -f'
=============================================================================================
frame #0: TBClient`- + 0
frame #1: TBClient`Maybe c function? Distance:39176 >= 2500 # Symbol:- + 39176
frame #2: TBClient`- + 596
frame #3: TBClient`- + 1528
frame #4: TBClient`- + 272
frame #5: UIKit`- + 688
......
......
frame #22: UIKit`UIApplicationMain + 208
frame #23: TBClient`main + 200
frame #24: libdyld.dylib`start + 4
(lldb) c
```
观察到第一个调用的可能是广告的方法-,看看TBCPluginFrsFeedAd有哪些方法
```
(lldb) po
<TBCPluginFrsFeedAd: 0x105c71ce8>:
in TBCPluginFrsFeedAd:
Class Methods:
+ (id) hostIdentifications; (0x102a43550)
+ (id) identification; (0x102a435bc)
+ (id) pluginInstance; (0x102a435c8)
Properties:
@property (retain, nonatomic) TBPluginItem* item;(@synthesize item = _item;)
@property (retain, nonatomic) TBCFCFrsBannerView* bannerView;(@synthesize bannerView = _bannerView;)
@property (nonatomic) BOOL confirmedPlayVideoUnderWWAN;(@synthesize confirmedPlayVideoUnderWWAN = _confirmedPlayVideoUnderWWAN;)
@property (retain, nonatomic) FMShareUIComponent* component;(@synthesize component = _component;)
@property (retain, nonatomic) id selectedLegoObject;(@synthesize selectedLegoObject = _selectedLegoObject;)
@property (nonatomic) long sectionIndex;(@synthesize sectionIndex = _sectionIndex;)
@property (readonly) unsigned long hash;
@property (readonly) Class superclass;
@property (readonly, copy) NSString* description;
@property (readonly, copy) NSString* debugDescription;
Instance Methods:
- (id) contentForType:(int)arg1; (0x102a47a1c)
- (void) unLoad:(id)arg1; (0x102a43a90)
- (id) processRequest:(id)arg1 fromPlugin:(id)arg2 andParams:(id)arg3; (0x102a43a88)
- (id) tableView:(id)arg1 mapIndexPath:(id)arg2; (0x102a43c08)
- (id) itemClzNames; (0x102a43c24)
- (void) handleLegoEvent:(unsigned long)arg1 cell:(id)arg2 clickArea:(id)arg3 deepLinkType:(long)arg4 extraInfo:(id)arg5; (0x102a46b94)
- (void) setConfirmedPlayVideoUnderWWAN:(BOOL)arg1; (0x102a47b24)
- (void) createForumBannerView:(id)arg1; (0x102a4599c)
- (void) handleAndInsertAds:(id)arg1; (0x102a44a3c)
- (void) handleAds:(id)arg1 adList:(id)arg2 minAdSpace:(long)arg3 firstAdLocate:(long)arg4; (0x102a44c70)
- (long) orientationConvertor:(id)arg1; (0x102a45460)
- (long) sortTypeConvertor:(id)arg1; (0x102a45494)
- (void) statLegoPromotionClick:(id)arg1 deepLinkType:(long)arg2 clickArea:(id)arg3 extInfo:(id)arg4; (0x102a46f04)
- (void) legoCellDidShow:(id)arg1 withObject:(id)arg2; (0x102a46a20)
- (void) reportCloseAdWithExtInfo:(id)arg1 closeReasons:(id)arg2; (0x102a457a0)
- (void) removeAdItem:(id)arg1; (0x102a45510)
- (void) clickPromotionVideoViewUnderWiFi:(id)arg1; (0x102a47188)
- (void) clickPromotionVideoViewUnderWWAN:(id)arg1; (0x102a471f0)
- (void) handleLegoShareClick:(id)arg1 withObject:(id)arg2; (0x102a47438)
- (void) handleLegoLikeClick:(id)arg1 withObject:(id)arg2; (0x102a47868)
- (void) reportAdNoPicDiscard:(id)arg1; (0x102a45834)
- (BOOL) confirmedPlayVideoUnderWWAN; (0x102a47b1c)
- (void) setSelectedLegoObject:(id)arg1; (0x102a47b48)
- (id) selectedLegoObject; (0x102a47b40)
- (void) tbcFrsBannerLoadFinished; (0x102a4688c)
- (void) tbcFrsBannerViewDidClosed; (0x102a46890)
- (BOOL) load:(id)arg1; (0x102a435f0)
- (void) .cxx_destruct; (0x102a47b64)
- (void) tableView:(id)arg1 willDisplayCell:(id)arg2 forRowAtIndexPath:(id)arg3; (0x102a449d4)
- (void) tableView:(id)arg1 didEndDisplayingCell:(id)arg2 forRowAtIndexPath:(id)arg3; (0x102a448a8)
- (double) tableView:(id)arg1 heightForRowAtIndexPath:(id)arg2; (0x102a442d8)
- (void) tableView:(id)arg1 didSelectRowAtIndexPath:(id)arg2; (0x102a44648)
- (long) tableView:(id)arg1 numberOfRowsInSection:(long)arg2; (0x102a442d0)
- (id) tableView:(id)arg1 cellForRowAtIndexPath:(id)arg2; (0x102a43c94)
- (id) item; (0x102a47af4)
- (BOOL) update:(id)arg1; (0x102a43794)
- (void) setItem:(id)arg1; (0x102a47afc)
- (id) component; (0x102a47b2c)
- (void) setComponent:(id)arg1; (0x102a47b34)
- (void) setBannerView:(id)arg1; (0x102a47b10)
- (id) bannerView; (0x102a47b08)
- (void) setSectionIndex:(long)arg1; (0x102a47b5c)
- (long) sectionIndex; (0x102a47b54)
(NSObject ...)
```
猜测- (void) handleAds:(id)arg1 adList:(id)arg2 minAdSpace:(long)arg3 firstAdLocate:(long)arg4是处理广告的方法,下个断点看看:
```
(lldb) b 0x102a44c70
Breakpoint 3: where = TBClient`___lldb_unnamed_symbol200801$$TBClient, address = 0x0000000102a44c70
(lldb) c
Process 5773 resuming
Process 5773 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 3.1
frame #0: 0x0000000102a44c70 TBClient`___lldb_unnamed_symbol200801$$TBClient
TBClient`___lldb_unnamed_symbol200801$$TBClient:
->0x102a44c70 <+0>:sub sp, sp, #0x1e0 ; =0x1e0
0x102a44c74 <+4>:stp x28, x27,
0x102a44c78 <+8>:stp x26, x25,
0x102a44c7c <+12>: stp x24, x23,
0x102a44c80 <+16>: stp x22, x21,
0x102a44c84 <+20>: stp x20, x19,
0x102a44c88 <+24>: stp x29, x30,
0x102a44c8c <+28>: add x29, sp, #0x1d0 ; =0x1d0
Target 0: (TBClient) stopped.
(lldb) x/s $x1
0x1048a9ea6: "handleAds:adList:minAdSpace:firstAdLocate:"
打印第一个参数:
(lldb) po $x2
<TBPluginContextFrs: 0x175a925c0>
打印第二个参数
(lldb) po $x3
<__NSArrayM 0x17645a640>(
<TBCPromotionItem: 0x1310accc0>,
<TBCPromotionItem: 0x12f4e3ea0>,
<TBCPromotionItem: 0x12bd5de10>
)
(lldb) po $x4
6
```
第二个参数为数组,保存的是TBCPromotionItem对象,看起来是激励项目,可能就是广告。将它的值赋为空,再继续运行程序
```
(lldb) expression $x3 = nil
(unsigned long) $101 = 0
(lldb) c
Process 5773 resuming
Process 5773 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 3.1
frame #0: 0x0000000102a44c70 TBClient`___lldb_unnamed_symbol200801$$TBClient
TBClient`___lldb_unnamed_symbol200801$$TBClient:
->0x102a44c70 <+0>:sub sp, sp, #0x1e0 ; =0x1e0
0x102a44c74 <+4>:stp x28, x27,
0x102a44c78 <+8>:stp x26, x25,
0x102a44c7c <+12>: stp x24, x23,
0x102a44c80 <+16>: stp x22, x21,
0x102a44c84 <+20>: stp x20, x19,
0x102a44c88 <+24>: stp x29, x30,
0x102a44c8c <+28>: add x29, sp, #0x1d0 ; =0x1d0
Target 0: (TBClient) stopped.
(lldb) po $x3
<__NSArrayM 0x171c5c4d0>(
<TBCPromotionItem: 0x1316b4fd0>,
<TBCPromotionItem: 0x1355bbf20>,
<TBCPromotionItem: 0x1316cd8a0>
)
(lldb) expression $x3 = nil
(unsigned long) $103 = 0
(lldb) c
```
不再触发断点,且已经看不到feed流广告,说明这个item里包含了feed流广告。再看TBCPromotionItem有什么方法:
```
(lldb) po
<TBCPromotionItem: 0x105c2aa28>:
in TBCPromotionItem:
Class Methods:
+ (BOOL) isPromotionValid:(id)arg1; (0x10132c4ec)
..............
..................
- (void) setRealIndex:(long)arg1; (0x10132cd98)
- (void) setIsPreloadAd:(BOOL)arg1; (0x10132cdb8)
- (id) init; (0x10132bf3c)
```
它也有个初始化方法- (id)init,使用br del删掉前面的所有断点,也给它下个断点,以便验证我的猜想。然后想看看帖子下面的广告在哪个类的,结果点进去就触发了这个断点,也就意味着帖子下方的广告也是调用的TBCPromotionItem:
```
(lldb) b 0x10132bf3c
Breakpoint 6: where = TBClient`___lldb_unnamed_symbol90120$$TBClient, address = 0x000000010132bf3c
(lldb) c
error: Process is running.Use 'process interrupt' to pause execution.
Process 5773 stopped
* thread #100, queue = 'com.tieba.baidu.immq', stop reason = breakpoint 6.1
frame #0: 0x000000010132bf3c TBClient`___lldb_unnamed_symbol90120$$TBClient
TBClient`___lldb_unnamed_symbol90120$$TBClient:
->0x10132bf3c <+0>:sub sp, sp, #0x40 ; =0x40
0x10132bf40 <+4>:stp x22, x21,
0x10132bf44 <+8>:stp x20, x19,
0x10132bf48 <+12>: stp x29, x30,
0x10132bf4c <+16>: add x29, sp, #0x30 ; =0x30
0x10132bf50 <+20>: adrp x8, 18540
0x10132bf54 <+24>: ldr x8,
0x10132bf58 <+28>: stp x0, x8,
Target 0: (TBClient) stopped.
(lldb) x/s $x1
0x1910d9b38: "init"
```
更改返回值为空试试:
```
(lldb) thread return nil
* thread #100, queue = 'com.tieba.baidu.immq', stop reason = breakpoint 6.1
frame #0: 0x00000001015dc180 TBClient`___lldb_unnamed_symbol105441$$TBClient + 2864
TBClient`___lldb_unnamed_symbol105441$$TBClient:
->0x1015dc180 <+2864>: mov x21, x22
0x1015dc184 <+2868>: mov x22, x24
0x1015dc188 <+2872>: mov x24, x26
0x1015dc18c <+2876>: mov x26, x19
0x1015dc190 <+2880>: mov x19, x28
0x1015dc194 <+2884>: mov x28, x0
0x1015dc198 <+2888>: mov x0, x25
0x1015dc19c <+2892>: ldr x1,
(lldb) c
```
帖子下方的广告也没有了。
整理一下:
feed流广告和帖子下方的广告都是在TBCPromotionItem中的,只要干掉里面的一个初始化方法,就能简单的达到去广告的效果
四、编写插件:
```
%hook TBCPromotionItem
- (id)init
{
return nil;
}
%end
```
也就是使用flex3就能达到目的
搞定收工。。。。
插件可在个人cydia源下载:https://wstclzy2010.github.io/repo/ sztxgg 发表于 2020-6-15 20:55
有不越狱可以搞定的方法吗?
如果你问的是不越狱就能安装插件达到去广告的效果的话:注入动态库到app中,重签名App安装即可,但是没有开发者账号签名的应用7天就需要重签否则打不开;如果问的是不越狱调试应用:可以使用monkeydev进行免越狱开发,各种实用工具都可以使用,包括lldb动态调试。 thread return nil
return -- Prematurely return from a stack frame, short-circuiting execution of newer frames and optionally yielding a specified value.Defaults to the exiting the current stack frame.
还能指定 可以返回什么值。 学习了 安卓的还是苹果的 jx1994 发表于 2020-6-13 20:09
安卓的还是苹果的
红色字符显示 IOS.
[iOS 原创] 一条方法去掉某应用广告 看起来好复杂??? 看不懂,头疼中{:301_982:} 大佬教程 看着有点复杂 如果自动就对我们很友好了哈哈哈 现在很多都是通过服务器来判定是否开通会员来推广告了 去广告确实很棒{:1_921:} 非常感谢楼主的分享!!!去掉应用广告使得用户体验大大提升了