Locus Pro v3.20 修改方法
目标
- 解决国内无法动态下载so文件导致无法启动的问题
- 使用Apk的全部功能
使用工具
apktools
这里不详细介绍apktools的用法。需要注意的一点是:因为Locus的代码在混淆过程中使用了不可见utf-8字符,apktools工具(实际使用的android的自带的资源打包工具aapt)无法把解开的资源重新打包,所以在解包时建议需要使用-r参数。
修改步骤
- 解除签名校验
Android apk都需要进行证书签名。Locus在代码中检查了签名证书的hash值,来判断apk是不是被二次打包。
目前Locus内部检查了3个证书的hash值
0x1a222754
-0x100cbe4d
-0x53ad97d7
用全文查找工具,在smali代码中寻找包含上述字符串的文件。v3.20.1中是o/aoj.3.smali。
找到如下
1 | invoke-virtual {v0}, Landroid/content/pm/Signature;->hashCode()I |
把上述代码修改为
1 | invoke-virtual {v0}, Landroid/content/pm/Signature;->hashCode()I |
因为三个证书任何一个匹配即可,所以这里修改一处即可以了。
修改so库的加载方式
因为Locus会动态更新so库。所以代码中使用了从App包中加载so库的方式。
locus 动态加载了两个库: “libproj”和”libjsqlite”。
用全文搜索工具搜索”proj”和“jsqlite”。为了更容易的找到目标,搜索时记得不要忘记引号。
比如搜索字符串”jsqlite”,找到文件jsqlite/Database.smali。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47.method static constructor <clinit>()V
.locals 5
.line 1122
const-string v3, "proj"
.line 1134
const-string v0, "lib"
:try_start_0
invoke-static {v0, v3}, Lo/Ὶ;->ᐝ(Ljava/lang/String;Ljava/lang/String;)Ljava/io/File;
move-result-object v4
.line 1135
invoke-static {v4}, Lo/ﮋ;->ˌ(Ljava/io/File;)Z
move-result v0
if-eqz v0, :cond_0
.line 1136
invoke-virtual {v4}, Ljava/io/File;->getAbsolutePath()Ljava/lang/String;
move-result-object v0
invoke-static {v0}, Ljava/lang/System;->load(Ljava/lang/String;)V
goto :goto_0
.line 1138
:cond_0
invoke-static {v3}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
.line 2128
:goto_0
const-string v3, "jsqlite"
.line 2134
const-string v0, "lib"
省略部分代码
......
.line 959
return-void
.end method现在修改为直接从apk包中加载。
1
2
3
4
5
6
7
8
9
10
11.method static constructor <clinit>()V
.locals 5
.line 1122
const-string v0, "proj"
invoke-static {v0}, Ljava/lang/System;->load(Ljava/lang/String;)V
const-string v0, "jsqlite"
invoke-static {v0}, Ljava/lang/System;->load(Ljava/lang/String;)V
.line 959
return-void
.end method这里需要注意,不要忘记修改临时变量(v0, v1),使调用保持一致。
不要忘了搜索”proj”, 做相应处理。
寻找启动时下载so文件的地方
全文搜索”_libraries.conf”字符串,找到相应文件。v3.20.1里面该文件名不可见utf-8字符o/Ὶ.1.smali。
3.19以前的版本,这个文件和加载libproj.so和libjsqlite.so的文件是同一个文件。
3.20开始,分布到3个文件当中了。
找到包涵”_libraries.conf”的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31.method public static ᵊ()Z
.locals 11
.line 1047
new-instance v4, Ljava/io/File;
invoke-static {}, Lo/aly;->getContext()Landroid/content/Context;
move-result-object v0
invoke-virtual {v0}, Landroid/content/Context;->getFilesDir()Ljava/io/File;
move-result-object v0
const-string v1, "_libraries.conf"
invoke-direct {v4, v0, v1}, Ljava/io/File;-><init>(Ljava/io/File;Ljava/lang/String;)V
.line 1048
invoke-virtual {v4}, Ljava/io/File;->exists()Z
这里省略了部分代码
......
.line 1104
invoke-static {v4}, Lo/ﮋ;->゙(Ljava/io/File;)Z
.line 1107
const/4 v0, 0x1
return v0
.end method修改为:
1
2
3
4
5.method public static ᵊ()Z
.locals 11
const/4 v0, 0x1
return v0
.end method隐藏数据下载界面
进入smali/com/asamm/locus/core/目录
打开所有StartScreen$开头的smali文件。
在里面查找字符串”public ʽ(ZZ)Z”(不包含引号)。
在找到的文件里面,寻找public ʽ(ZZ)Z调用了上一步修改的函数方法的文件。
v3.20.1版本中找到的方法如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73.method public ʽ(ZZ)Z
.locals 2
.line 1405
if-eqz p1, :cond_0
.line 1406
const/4 v0, 0x1
return v0
.line 1410
:cond_0
invoke-static {}, Lo/Ὶ;->ᵊ()Z
move-result v0
if-nez v0, :cond_1
.line 1411
const/4 v0, 0x1
return v0
.line 1415
:cond_1
if-eqz p2, :cond_2
invoke-static {}, Lo/arq;->alG()Z
move-result v0
if-eqz v0, :cond_2
invoke-static {}, Lcom/asamm/locus/core/StartScreen;->fT()Lcom/asamm/locus/core/StartScreen$ˏ;
move-result-object v0
invoke-virtual {v0}, Lcom/asamm/locus/core/StartScreen$ˏ;->gd()I
move-result v0
const/16 v1, 0xa
if-ge v0, v1, :cond_2
.line 1417
const/4 v0, 0x1
return v0
.line 1421
:cond_2
const-string v0, "com.asamm.locus.utils.Const"
invoke-static {v0}, Lo/anE;->ˋ(Ljava/lang/String;)Ljava/lang/Class;
move-result-object v0
const-string v1, "cKz"
invoke-virtual {v0, v1}, Ljava/lang/Class;->getField(Ljava/lang/String;)Ljava/lang/reflect/Field;
move-result-object v0
const/4 v1, 0x0
invoke-virtual {v0, v1}, Ljava/lang/reflect/Field;->getBoolean(Ljava/lang/Object;)Z
move-result v0
return v0
.end method注意第10行(不包含空行)
1
invoke-static {}, Lo/Ὶ;->ᵊ()Z
如果幸运的话,上一步找到的文件的文件名是可见的utf-8字符,这里更容易确认。
把上述方法中的
1
const/4 v0, 0x1
修改为
1
const/4 v0, 0x0
替换so文件
把v3.20.1修改版本中的so文件替换到新版本中覆盖。删除lib下的armeabi、mips和x86目录。因为我们没有这3类CPU对应的so文件。所以修改版,在这3类CPU下面是不能运行的。
修改libmacore.so
本文不作讨论。直接使用旧修改版本中的替换即可。
至此,修改工作完成。