本文及资源最后更新时间 2021-10-02 by sky995
这次想找个安卓版的飞鸽传书,配合飞秋可以往手机中传剪切板内容或者文件,从谷歌市场上搜索到目前评分较高的软件为
https://play.google.com/store/apps/details?id=com.tj.feige.app
下载运行发现它能在安卓11上使用,同时支持单文件传输,基本满足需求,但是,它里面的谷歌广告着实烦人,鉴于作者已经N年没更新过了,我们就替他更新一下去掉广告功能吧
从apk pure搜索并下载这个apk,将下载好的软件拖入jadx分析,鉴于这个apk的功能和界面都非常简单,我们不妨直接搜索“广告”
哦,原来赚够积分升级为正式版就不用看广告了呢,那么我怎么知道我的积分够不够呢?自然是搜索积分看看了,经搜索发现积分不够会弹出提示,若积分充足会执行另一段代码:
当然,我这里并不打算直接此处的改跳转实现去广告,因为我在我的手机上根本看不到积分相关的UI,这部分功能可能由于api版本过低已经没法运作了,所以我们不妨看看
1
|
a( "正在升级正式版请稍候..." , new e( this ), new f( this )); |
中的传入的另外两个对象都是咋定义的。
观察发现第一个只是让线程暂停了2秒,估计是为了避免读写冲突,第二个就有点意思了,内容如下:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
class f implements l { final /* synthetic */ FeiGeAdManagerUI a; f(FeiGeAdManagerUI feiGeAdManagerUI) { this .a = feiGeAdManagerUI; } @Override // com.tj.feige.app.a.l public void a(Object obj) { int n = this .a.d.n(); int m = this .a.d.m(); a.e = true ; this .a.d.a( "del_ad_flag" , 1 ); this .a.d.a( "del_ad_day" , Integer.valueOf(n)); this .a.d.a( "del_ad_time" , Long.valueOf(System.currentTimeMillis())); FeiGeAdManagerUI.a( this .a, m); e.a( this .a, "恭喜您已经升级成为正式版." ); this .a.finish(); } } |
注意到
this.a.d.a(“del_ad_flag”, 1);
this.a.d.a(“del_ad_day”, Integer.valueOf(n));
this.a.d.a(“del_ad_time”, Long.valueOf(System.currentTimeMillis()));
非常像判断是否删除广告的标记,另外这种设置方式看上去也挺像key-value的,不妨先把this.a.d当成Map<String,Number>类型,那么我们只要找到del_ad_flag出现的位置,并阻止程序将它设置为0就可以了。
将del_ad_flag改为0的代码只有寥寥几行,甚至都是在同一个函数中的:
进入函数,发现如下内容:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
public boolean o() { int i2 = this .i.getInt( "del_ad_flag" , 0 ); String f2 = f( "showAllAd" ); if (ab.a(f2)) { f2 = "0" ; } if (i2 != 1 ) { return "1" .equals(f2); } long currentTimeMillis = System.currentTimeMillis(); long j2 = this .i.getLong( "del_ad_time" , 0 ); if (currentTimeMillis <= ((( long ) this .i.getInt( "del_ad_day" , 0 )) * 86400000 ) + j2) { return currentTimeMillis < j2; } a( "del_ad_flag" , 0 ); a( "del_ad_day" , 0 ); a( "del_ad_time" , 0L); return true ; } |
显然这是一个判断要不要展示广告的函数,那自然是不要了,既然函数在将del_ad_flag设为0后才返回true,那就说明true代表展示广告,false代表不展示,因此,我们让函数在一开头就返回false就行了,也不用管del_ad_flag到底是几,这就方便了不少。
分析完毕,下面我们开始改smail:
用命令 java -jar .\Apktool_2.5.0.jar d ‘.\飞鸽传输 IP Messenger_v2.3.6_apkpure.com.apk’ 将apk解包,根据方法o的限定名 com.tj.feige.app.a.o ,找到对应的 a.smail文件,其中,方法o对应的smail代码如下:
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
.method public o()Z .locals 12 .prologue const -wide/ 16 v10, 0x0 const / 4 v0, 0x1 const / 4 v1, 0x0 .line 627 iget-object v2, p0, Lcom/tj/feige/app/a;->i:Landroid/content/SharedPreferences; const -string v3, "del_ad_flag" invoke- interface {v2, v3, v1}, Landroid/content/SharedPreferences;->getInt(Ljava/lang/String;I)I move-result v3 .line 630 const -string v2, "showAllAd" invoke-direct {p0, v2}, Lcom/tj/feige/app/a;->f(Ljava/lang/String;)Ljava/lang/String; move-result-object v2 .line 631 invoke- static {v2}, Lcom/tj/feige/app/a/ab;->a(Ljava/lang/String;)Z move-result v4 if -eqz v4, :cond_0 .line 632 const -string v2, "0" .line 660 :cond_0 if -ne v3, v0, :cond_3 .line 661 invoke- static {}, Ljava/lang/System;->currentTimeMillis()J move-result-wide v2 .line 665 iget-object v4, p0, Lcom/tj/feige/app/a;->i:Landroid/content/SharedPreferences; const -string v5, "del_ad_time" invoke- interface {v4, v5, v10, v11}, Landroid/content/SharedPreferences;->getLong(Ljava/lang/String;J)J move-result-wide v4 .line 666 iget-object v6, p0, Lcom/tj/feige/app/a;->i:Landroid/content/SharedPreferences; const -string v7, "del_ad_day" invoke- interface {v6, v7, v1}, Landroid/content/SharedPreferences;->getInt(Ljava/lang/String;I)I move-result v6 .line 667 int -to- long v6, v6 const -wide/ 32 v8, 0x5265c00 mul- long /2addr v6, v8 add- long /2addr v6, v4 .line 669 cmp- long v6, v2, v6 if -lez v6, :cond_2 .line 670 const -string v2, "del_ad_flag" invoke- static {v1}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer; move-result-object v3 invoke-virtual {p0, v2, v3}, Lcom/tj/feige/app/a;->a(Ljava/lang/String;Ljava/lang/Object;)V .line 671 const -string v2, "del_ad_day" invoke- static {v1}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer; move-result-object v1 invoke-virtual {p0, v2, v1}, Lcom/tj/feige/app/a;->a(Ljava/lang/String;Ljava/lang/Object;)V .line 672 const -string v1, "del_ad_time" invoke- static {v10, v11}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long; move-result-object v2 invoke-virtual {p0, v1, v2}, Lcom/tj/feige/app/a;->a(Ljava/lang/String;Ljava/lang/Object;)V .line 683 :cond_1 :goto_0 return v0 .line 674 :cond_2 cmp- long v2, v2, v4 if -ltz v2, :cond_1 move v0, v1 .line 677 goto :goto_0 .line 680 :cond_3 const -string v3, "1" invoke-virtual {v3, v2}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z move-result v2 if -nez v2, :cond_1 move v0, v1 .line 683 goto :goto_0 .end method |
我不怎么懂smail的语法,但由于要修改的内容非常简单,还是可以做出猜测的:
整个方法里面只有一个 return v0,表示返回,v0中自然要存放具体的返回值,并且这个值在函数返回前是可以被多次修改的,里面的若干句 move v0, v1 就证明了这点
我们再往上看,
const/4 v0, 0x1
const/4 v1, 0x0
明显声明了两个变量并赋值为整数,也就是说我们的返回值也是在v0或v1中间选一个就可以了,具体要选哪个呢?
前面的分析表明我们应当让函数返回false,因此要选择0x0,为了证明这一点,不妨找到return true;对应的smail代码:
大概看一下smail的流程,可以发现v0的值并没被修改,可见return true就是返回了0x1
因此,为去掉广告,我们只要在函数的开头return false,也就是将return v1放在合适的位置即可,不妨就放在这两个变量刚声明完的地方:
保存文件,用 java -jar .\Apktool_2.5.0.jar b “飞鸽传输 IP Messenger_v2.3.6_apkpure.com” 命令重新打包,然后再用
jarsigner -keystore debug.keystore -storepass pass -signedjar signed.apk ‘.\飞鸽传输 IP Messenger_v2.3.6_apkpure.com.apk’ keyalias
命令为apk签名,卸载掉原版飞哥传输,安装我们的版本,可以发现广告已经全部没有了
附件:
飞哥传输原版+修改版
https://wwa.lanzoui.com/b00oyfaze
密码:bt7h