实现功能:
1.解锁vip(vip有效期会持续递增)
2.禁止app向服务器获取配置(屏蔽更新)
3.允许使用所有功能
4.禁止模拟定位模块通过系统向验证服务器发送socket校验key和token(详见https://www.52pojie.cn/forum.php?mod=redirect&goto=findpost&ptid=1988024&pid=51912215)
需要注意的点
模块作用域已经自动选了fakelocation和系统,不需要特殊设置。
- 这个模块有界面,最开始是为了显示修改系统hosts后验证服务器的连通性,后来尝试hook了模拟定位模块后就不需要显示给用户了(但是懒得重新生成了),所以不需要关心界面上显示”验证服务是否联通“
- 由于hook了注入到系统的模拟定位模块,在fakelocation app上点击“开始模拟”后有部分机型上会卡死,只能尝试重启手机了
- 这个lsp模块适配的是国内版带360加固的fakelocation 1.3.2.2版本(包名com.lerist.fakelocation,和play版不一样),play版的无法使用,非1.3.2.2版本的无法使用。现在作者的github已经把旧版本撤了,可能需要到第三方下载站去下载1.3.2.2版本。1.3.2.2版本好像只支持到安卓13,再往上的安卓版本就不用试了。
- 这个lsp模块没有动和fakelocation功能有关的代码,如果出现某个功能在启用模块后不能用,先检查一下没有启用模块的时候使用是否正常。之前反馈的相关问题大概率还是fakelocation自己的原因。
核心代码
package com.example.hello;
import android.content.Context;
import android.util.Base64;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
/* loaded from: classes3.dex */
public class hook implements IXposedHookLoadPackage {
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if (loadPackageParam.packageName.equals("android")) {
XposedHelpers.findAndHookMethod(ClassLoader.class, "loadClass", new Object[]{String.class, new XC_MethodHook() { // from class: com.example.hello.hook.1
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
if (param.hasThrowable()) {
return;
}
final Class<?> cls = (Class) param.getResult();
if (cls.getClassLoader().toString().contains("/data/fakeloc/libfakeloc.so")) {
XposedBridge.log("hook libfakeloc.so");
new Thread(new Runnable() { // from class: com.example.hello.hook.1.1
@Override // java.lang.Runnable
public void run() {
try {
Thread.sleep(3500L);
XposedBridge.log("start");
XposedHelpers.findAndHookMethod("com.lerist.inject.utils.ޏ", cls.getClassLoader(), "އ", new Object[]{new XC_MethodHook() { // from class: com.example.hello.hook.1.1.1
protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param2) throws Throwable {
super.beforeHookedMethod(param2);
}
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param2) throws Throwable {
param2.setResult(true);
}
}});
XposedHelpers.findAndHookMethod("com.lerist.inject.utils.ބ", cls.getClassLoader(), "ރ", new Object[]{String.class, Integer.TYPE, new XC_MethodHook() { // from class: com.example.hello.hook.1.1.2
protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param2) throws Throwable {
param2.args[0] = "114.114.114.114";
}
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param2) throws Throwable {
super.afterHookedMethod(param2);
}
}});
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
}});
}
if (loadPackageParam.packageName.equals("com.lerist.fakelocation")) {
XposedBridge.log("开始hook....");
XposedHelpers.findAndHookMethod("com.stub.StubApp", loadPackageParam.classLoader, "attachBaseContext", new Object[]{Context.class, new XC_MethodHook() { // from class: com.example.hello.hook.2
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Context context = (Context) param.args[0];
ClassLoader classLoader = context.getClassLoader();
XposedHelpers.findAndHookMethod("ކ.ޖ$֏", classLoader, "ށ", new Object[]{String.class, new XC_MethodHook() { // from class: com.example.hello.hook.2.1
protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param2) throws Throwable {
param2.args[0] = "114.114.114.114";
}
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param2) throws Throwable {
super.afterHookedMethod(param2);
}
}});
final Class<?> JSONClass = XposedHelpers.findClass("com.alibaba.fastjson.JSON", classLoader);
XposedHelpers.findAndHookMethod("ށ.ރ.ށ.ހ.ށ.ؠ", classLoader, "֏", new Object[]{String.class, Class.class, new XC_MethodHook() { // from class: com.example.hello.hook.2.2
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param2) throws Throwable {
if (param2.args[0] == "key_userinfo") {
long proindate = System.currentTimeMillis() + 200000000;
long tokenTime = System.currentTimeMillis() + 500000000;
String key = "1#" + Long.toString(proindate) + "#" + Long.toString(tokenTime) + "#T";
String data = "{\"key\":\"" + hook.desEncryptECB(key, "Lerist.T") + "\",\"loginName\":\"Lerist\",\"loginTime\":0,\"loginType\":\"email\",\"proindate\":" + Long.toString(proindate) + ",\"stability\":0,\"token\":\"T\",\"type\":1}";
param2.setResult(XposedHelpers.callStaticMethod(JSONClass, "parseObject", new Object[]{data, param2.args[1]}));
return;
}
super.afterHookedMethod(param2);
}
}});
XposedHelpers.findAndHookMethod("ށ.ރ.ށ.ހ.ށ.ؠ", classLoader, "ނ", new Object[]{Context.class, new XC_MethodHook() { // from class: com.example.hello.hook.2.3
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param2) throws Throwable {
param2.setResult(false);
}
}});
XposedHelpers.findAndHookMethod("ށ.ރ.ؠ.ހ.ؠ", classLoader, "ށ", new Object[]{String.class, new XC_MethodHook() { // from class: com.example.hello.hook.2.4
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param2) throws Throwable {
param2.setResult(true);
}
}});
XposedHelpers.findAndHookMethod("ށ.ރ.ؠ.ހ.ؠ", classLoader, "ؠ", new Object[]{new XC_MethodHook() { // from class: com.example.hello.hook.2.5
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param2) throws Throwable {
param2.setResult((Object) null);
}
}});
XposedHelpers.findAndHookMethod("ށ.ރ.ؠ.ؠ.֏", classLoader, "ޅ", new Object[]{new XC_MethodHook() { // from class: com.example.hello.hook.2.6
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param2) throws Throwable {
param2.setResult(true);
}
}});
}
}});
}
}
public static String string2Unicode(String string) {
StringBuffer unicode = new StringBuffer();
for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
if (c < ' ' || c > '~') {
String tmp = Integer.toHexString(c);
if (tmp.length() >= 4) {
unicode.append("\\u" + Integer.toHexString(c));
} else if (tmp.length() == 3) {
unicode.append("\\u0" + Integer.toHexString(c));
} else if (tmp.length() == 2) {
unicode.append("\\u00" + Integer.toHexString(c));
} else if (tmp.length() == 1) {
unicode.append("\\u000" + Integer.toHexString(c));
} else if (tmp.length() == 3) {
unicode.append("\\u0000");
}
} else {
unicode.append(c);
}
}
return unicode.toString();
}
public static String desEncryptECB(String content, String key) {
try {
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
cipher.init(1, secretKey);
byte[] result = cipher.doFinal(content.getBytes());
return Base64.encodeToString(result, 0);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String desECBDecrypt(byte[] data, String key) throws Exception {
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
cipher.init(2, secretKey);
byte[] encryptedData = Base64.decode(data, 0);
byte[] decryptedData = cipher.doFinal(encryptedData);
return new String(decryptedData);
}
}