1.最近看这款模拟定位软件比较火,打算拿来用用,结果发现好多功能居然需要购买VIP才能用,最可恶的是,还tm不是永久的,这能忍?
2.还是和之前一样先来探探它的深浅,上NP管理器,查看一下,发现使用了360加固
3.这次脱壳就不上frida-dexdump了,怪麻烦的,直接用大佬给的Lsposed插件Fundex,勾选作用域后,给Fundex,root权限后设置目录,就可以开始脱壳了
4.设置好目录后,直接启动Fake Location就可以脱壳了,进入app后,多点几下,然后adb shell进入到目录:/data/data/com.lerist.fakelocation/里就可以看到我们脱壳下的dex文件了
5.将这些文件打包后,丢进jadx里进行反编译,接下来,我们开始分析。
6.我们直接上算法助手,不得不说,算法助手还是非常好用的,用法之前也说过,先勾选作用域,然后在算法助手里选择Fake Location,因为这个试用专业版这块属于是控件文本。
7.所以,我们在算法助手里勾选UI里的控件文本赋值记录功能后,重新启动Fake Location,点击一下刚才出现试用专业版的功能点。
8.然后我们在算法助手里,查看Fake Location的日志记录,找到带有试用专业版的日志进行分析。
9.根据日志,我们一个一个去jadx里去看,我们搜索第一个,发现可以搜到,进去看看。
10.看上去是一个按钮,先用frida梭一把,试试水
Java.perform(function () {
console.log("启动");
let Snackbar = Java.use("com.google.android.material.snackbar.Snackbar");
Snackbar["u0560"].implementation = function (charSequence, onClickListener) {
console.log(`Snackbar.m9312 is called: charSequence=${charSequence}, onClickListener=${onClickListener}`);
this["u0560"](charSequence, onClickListener);
};
});
11.经过测试,确实调用这个地方了,不过经过仔细分析源码,发现这就是一个配置按钮的方法。
12.我们需要找的是判断是否为专业版地方的源码,正常来说,软件肯定是要先判断是否是专业版,然后再根据结果来判断是否显示"试用专业版",因此我们得继续根据堆栈往上找
13.在jadx里接着找下一个方法,定位到方法后,大概的看一下,又是一个配置视图,Toast的地方,我们继续看下一个方法。
14.不知道为啥,搜不到这个方法,尝试先搜索这个方法的类来试试。
15.运气不错,类名搜索到了。
16.点进去看看有没有这个方法,运气不错,定位到了这个方法。
17.定位到这个方法之后,我们在代码中看到了刚才见过的m185XX开头的这些字符(m18501,m18503),点进去看看,发现这就是刚才定位过的地方
18.我们回头再看这块的代码逻辑,是个if语句,如果不xxx就执行m18503,我们在上面已经知道了,m1850x的位置是一个配置视图,弹toast的地方,再然后堆栈就到了会弹出"试用专业版"的地方。
textView3.setText(fragmentActivity2.getString(i3));
if (!C4921.m18343()) {
C5360.m18503(c5336.getView());
return;
}
19.知道了上面的逻辑,我们就知道了关键点,在于if语句括号里的东西,点进去看看它是啥情况?
20.点进去之后,看到这个m18343是个boolean值,让我们先hook一下看看
Java.perform(function () {
console.log("启动");
let C4921 = Java.use("u0D5F.u0560");
C4921["u052A"].implementation = function () {
console.log(`C4921.m18343 is called`);
let result = this["u052A"]();
console.log(`C4921.m18343 result=${result}`);
return result;
};
});
21.当我们hook之后,发现这个m18343的值是false,那这就简单了,我们直接把返回值改成true试试
Java.perform(function () {
console.log("启动");
let C4921 = Java.use("u0D5F.u0560");
C4921["u052A"].implementation = function () {
console.log(`C4921.m18343 is called`);
let result = this["u052A"]();
console.log(`C4921.m18343 result=${result}`);
return true;
};
});
22.好,奇迹发生了,之前我们没办法使用的专业版功能,现在可以用了,说明我们已经成功破解了它
23.然后我发现一个问题,当frida脚本断开的时候,刚破解的东西也就失效了,那我们还是和之前一样,再写个xposed插件,有些东西已经再开发助手破解-续中写过了,这里就不再赘述了,xposed的关键代码如下:
import android.util.Log;
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;
public class Hookmain implements IXposedHookLoadPackage {
public String tag = "hook_lsposed";
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if (loadPackageParam.packageName.equals("com.lerist.fakelocation")){
Log.d(tag,"Fake Location已選中");
Class ActivityThread = XposedHelpers.findClass("android.app.ActivityThread", loadPackageParam.classLoader);
XposedBridge.hookAllMethods(ActivityThread, "performLaunchActivity", new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
XposedHelpers.findAndHookMethod("ൟ.ՠ", loadPackageParam.classLoader, "Ԫ", new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
param.setResult(true);
}
});
}
});
}
}
}
app下载地址:http://fakeloc.cc/app
原文始发于微信公众号(Flower Sec):Fake Location 1.3.5 BATE版破解分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论