首页
社区
课程
招聘
[原创]某加固签名校验研究
发表于: 1天前 1044

[原创]某加固签名校验研究

1天前
1044

之前我们讨论了去除签名校验的方法,无法去除最新的某60加固,始终是我心中的大山。我心有不甘,想看看这加固的签名校验的强度,去体会移动安全开发工程师在代码里书写的智慧与浪漫。于是就有了这篇文章。

基础知识的文章请看之前的文章--→https://bbs.kanxue.com/thread-285647.htm

我认为良好的环境是分析提高效率的关键

在频繁的使用ida 对app进行分析调试,经常会打开,可以编写一份脚本快速打开ida的server

这里面的 ida9.1 是你的ida server。还有frida 快速启动脚本

将“hluda-server-16.2.1-android-arm64” 修改为 你自己的的server就好了

这里我分析的环境是 piexl 5,Android 12 的版本。

样本是 6月最新的加固。

准备好你的ida , frida 基本环境,与我一起分析吧!

现在最新的加固样本的so文件是加密状态,我们要先进行初步的dump获取基本的符号信息,现在的符号信息空空如也。

这里使用frida dump 再修复

再使用SoFixer64 进行修复

8e7K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6r3z5p5I4q4c8W2c8Q4x3V1k6e0L8@1k6A6P5r3g2J5i4K6u0r3M7X3g2D9k6h3q4K6k6i4x3`.

这样就具备了基本的so 信息符号了

在最新的加固样本里面 外壳的so 似乎都用的c++代码编译了,对抗了之前所有的文章的地方

按照之前的文章和方法几乎 无法 将 内部so 进行dump 。

这里我再想 实现linker的步骤里面是无法脱离 dlopen这个函数的,我尝试搜索相关的引用,发现并不是linker 的预连接逻辑

而这个方法里面调用了线程相关的函数

pthread_rwlock_rdlock

那么我就要大胆的猜测,它是不是通过线程来进行通信,来实现linker的!

我引用信号相关的函数 kill

发现了之前 预连接的方法里面了? 是不是很巧妙?(其实是千疮百孔的调试分析得到的!)

那就使用我之前文章里面的脱壳脚本,进行脱壳

然后 按照我之前的文章内容 修复就可以了

https://bbs.kanxue.com/thread-285539.htm

加固样本 里面普遍使用 自己实现的svc 指令来进行 系统函数的调用。

比如: openat 调用

它的实现方式很有趣: 先mmap 一块可运行的内存,在把加密的svc代码解密放进去,再调用函数

这样做的好处是 直接断绝了——通过内存扫描的形式,对svc指令的hook!

在java 层

对包路径 进行两次不同的方法进行获取

调用了常规的签名信息,进行 hashcode

java层的强度 似乎不太高,我建议构造binder 通讯ams

native的强度还是可以的!

svc openat打开包

readklinkat 读取包路径

fstat 读取包的权限

都是以svc的方式实现的

这里反调试是我最大的困惑,也是最精彩的地方。

它是怎样实现反调试的呢?

经典 status 文件里面的 trace pid 的值 和 state 进程状态

在status 里面 还检测了 NoNewPrivs , 这个值很有意思! 你可以百度或者ai问一下!

通过fork 子进程 来进行 测试ptrace ,wait 来校验 进程信号是否被 调试

fork 的子进程与父进程通过管道 通讯 ,子进程调用 excel 函数 cat /proc/self/status ,观察 进程名 是否正确?

这里还对 /proc 的文件进行 mmap 查看它的error 值 ,如果我们替换了 就会成功 ! error 的值为0

我使用的lspant 的hook 来对java 进行 hook ,hook点在我上一篇文章有提到。

这里我有两种方案 一种是

优点: hook 比较简单就能实现, 也是大多数 多开app 使用方案

缺点: 稳定性差,遇到基于信号的检测就完了!还有就是对于低版本的内核 有很多功能实现不了!

优点: ptrace hook 的稳定性 对比上一个好,而且有很好的项目可以学习 proot , 有兴趣可以看我之前的proot 分析

缺点: 必须处理反调试检测

我的选择是 ptrace的方案,这里有很多资料可以学习。

这里的方案 来自 proot 和abyss

deaK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6H3M7X3!0G2N6q4)9J5k6r3#2W2i4K6u0r3M7s2u0G2L8%4b7`.

082K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6A6L8$3k6G2L8h3!0Q4x3V1k6S2j5Y4W2K6M7H3`.`.

包路径 这里的替换,这里可以参考插件化开发技术!

替换loadapk里面application 的sourice 的值就可以了

使用io重定向 修改读取的apk 为原来没有签名打包的apk.

readlink ,fstat 也是修改替换返回值.达到欺骗的效果。

也是对 status stat 这几个目录进行io重定向 主要就是修改 一些文件的值

然后将ptrace的值 返回为0 ,

就基本完成了 对抗! 呼出一口气。

最后,我要感谢

空壳的作者 Tiony.bo 也是我的前辈,感谢你对我插件化开发的指点,以及abyss的开源!

感谢 珍惜Any王麻子本人 等等 大佬关于 ptrace的文章 让我有所启蒙!

参考的链接:

https://bbs.kanxue.com/thread-285339.htm

https://bbs.kanxue.com/thread-273160.htm

https://bbs.kanxue.com/thread-275511.htm

4c0K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6A6L8$3k6G2L8h3!0Q4x3V1k6S2j5Y4W2K6M7H3`.`.

a1aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6H3M7X3!0G2N6q4)9J5k6r3#2W2i4K6u0r3M7s2u0G2L8%4b7`.

#!/bin/bash
# 设置端口转发
if ! adb forward tcp:4567 tcp:4567; then
    echo "[错误] 端口转发失败"
    exit 2
fi
 
echo "IDA服务已在端口4567启动"
# 启动IDA服务
if ! adb shell "su -c 'cd /data/local/tmp && ./ida9.1 -p4567 &'"; then
    echo "[错误] 无法启动IDA服务"
    exit 1
fi
 
# 等待服务初始化
echo "ok..."
#!/bin/bash
# 设置端口转发
if ! adb forward tcp:4567 tcp:4567; then
    echo "[错误] 端口转发失败"
    exit 2
fi
 
echo "IDA服务已在端口4567启动"
# 启动IDA服务
if ! adb shell "su -c 'cd /data/local/tmp && ./ida9.1 -p4567 &'"; then
    echo "[错误] 无法启动IDA服务"
    exit 1
fi
 
# 等待服务初始化
echo "ok..."
#!/bin/bash
adb shell "su -c 'cd /data/local/tmp && ./hluda-server-16.2.1-android-arm64'"
#!/bin/bash
adb shell "su -c 'cd /data/local/tmp && ./hluda-server-16.2.1-android-arm64'"
function dump_so(so_name) {
    var libso = Process.getModuleByName(so_name);
    console.log("[name]:", libso.name);
    console.log("[base]:", libso.base);
    console.log("[size]:", ptr(libso.size));
    console.log("[path]:", libso.path);
    var file_path = "/data/data/"+get_self_process_name()+"/" + libso.name + "_" + libso.base + "_" + ptr(libso.size) + ".so";
    var file_handle = new File(file_path, "wb");
    if (file_handle && file_handle != null) {
        Memory.protect(ptr(libso.base), libso.size, 'rwx');
        var libso_buffer = ptr(libso.base).readByteArray(libso.size);
        file_handle.write(libso_buffer);
        file_handle.flush();
        file_handle.close();
        console.log("[dump]:", file_path);
    }
}
  
function get_self_process_name() {
    var openPtr = Module.getExportByName('libc.so', 'open');
    var open = new NativeFunction(openPtr, 'int', ['pointer', 'int']);
 
    var readPtr = Module.getExportByName("libc.so", "read");
    var read = new NativeFunction(readPtr, "int", ["int", "pointer", "int"]);
 
    var closePtr = Module.getExportByName('libc.so', 'close');
    var close = new NativeFunction(closePtr, 'int', ['int']);
 
    var path = Memory.allocUtf8String("/proc/self/cmdline");
    var fd = open(path, 0);
    if (fd != -1) {
        var buffer = Memory.alloc(0x1000);
 
        var result = read(fd, buffer, 0x1000);
        close(fd);
        result = ptr(buffer).readCString();
        return result;
    }
 
    return "-1";
}
 
 
 
//8.0以下所有的so加载都通过dlopen
function hook_dlopen() {
    var dlopen = Module.findExportByName(null, "dlopen");
    Interceptor.attach(dlopen, {
        onEnter: function (args) {
            this.call_hook = false;
            var so_name = ptr(args[0]).readCString();
            if (so_name.indexOf("libshell-super.2019.so") >= 0) {
                console.log("dlopen:", ptr(args[0]).readCString());
                this.call_hook = true;//dlopen函数找到了
            }
 
        }, onLeave: function (retval) {
            if (this.call_hook) {//dlopen函数找到了就hook so
                inline_hook();
            }
        }
    });
    // 高版本Android系统使用android_dlopen_ext
    var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext");
    Interceptor.attach(android_dlopen_ext, {
        onEnter: function (args) {
            this.call_hook = false;
            var so_name = ptr(args[0]).readCString();
            if (so_name.indexOf("libshell-super.2019.so") >= 0) {
                console.log("android_dlopen_ext:", ptr(args[0]).readCString());
                this.call_hook = true;
            }
 
        }, onLeave: function (retval) {
            if (this.call_hook) {
                inline_hook();
            }
        }
    });
}
function main (){
    Java.perform(
        function(){
        var tart_Name = "libjiagu_64.so"
        dump_so(tart_Name)
        }
    );
}
setImmediate(main)
function dump_so(so_name) {
    var libso = Process.getModuleByName(so_name);
    console.log("[name]:", libso.name);
    console.log("[base]:", libso.base);
    console.log("[size]:", ptr(libso.size));
    console.log("[path]:", libso.path);
    var file_path = "/data/data/"+get_self_process_name()+"/" + libso.name + "_" + libso.base + "_" + ptr(libso.size) + ".so";
    var file_handle = new File(file_path, "wb");
    if (file_handle && file_handle != null) {
        Memory.protect(ptr(libso.base), libso.size, 'rwx');
        var libso_buffer = ptr(libso.base).readByteArray(libso.size);
        file_handle.write(libso_buffer);
        file_handle.flush();
        file_handle.close();
        console.log("[dump]:", file_path);
    }
}
  
function get_self_process_name() {
    var openPtr = Module.getExportByName('libc.so', 'open');
    var open = new NativeFunction(openPtr, 'int', ['pointer', 'int']);
 
    var readPtr = Module.getExportByName("libc.so", "read");
    var read = new NativeFunction(readPtr, "int", ["int", "pointer", "int"]);
 
    var closePtr = Module.getExportByName('libc.so', 'close');
    var close = new NativeFunction(closePtr, 'int', ['int']);
 
    var path = Memory.allocUtf8String("/proc/self/cmdline");
    var fd = open(path, 0);
    if (fd != -1) {
        var buffer = Memory.alloc(0x1000);
 
        var result = read(fd, buffer, 0x1000);
        close(fd);
        result = ptr(buffer).readCString();
        return result;
    }
 
    return "-1";
}
 
 
 
//8.0以下所有的so加载都通过dlopen
function hook_dlopen() {
    var dlopen = Module.findExportByName(null, "dlopen");
    Interceptor.attach(dlopen, {
        onEnter: function (args) {
            this.call_hook = false;
            var so_name = ptr(args[0]).readCString();
            if (so_name.indexOf("libshell-super.2019.so") >= 0) {
                console.log("dlopen:", ptr(args[0]).readCString());
                this.call_hook = true;//dlopen函数找到了
            }
 
        }, onLeave: function (retval) {
            if (this.call_hook) {//dlopen函数找到了就hook so
                inline_hook();
            }
        }
    });
    // 高版本Android系统使用android_dlopen_ext
    var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext");
    Interceptor.attach(android_dlopen_ext, {
        onEnter: function (args) {
            this.call_hook = false;
            var so_name = ptr(args[0]).readCString();
            if (so_name.indexOf("libshell-super.2019.so") >= 0) {
                console.log("android_dlopen_ext:", ptr(args[0]).readCString());
                this.call_hook = true;
            }
 
        }, onLeave: function (retval) {
            if (this.call_hook) {
                inline_hook();
            }
        }
    });
}
function main (){
    Java.perform(
        function(){
        var tart_Name = "libjiagu_64.so"
        dump_so(tart_Name)
        }
    );
}
setImmediate(main)
function my_hook_dlopen(soName = '') {
 
    Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"),
        {
            onEnter: function (args) {
                var pathptr = args[0];
                if (pathptr !== undefined && pathptr != null) {
                    var path = ptr(pathptr).readCString();
                    if (path.indexOf(soName) >= 0) {
                        this.is_can_hook = true;
                    }
                }
            },
            onLeave: function (retval) {
                if (this.is_can_hook) {
                    hook();
                }
            }
        }
    );
}
function addr_in_so(addr){
    var process_Obj_Module_Arr = Process.enumerateModules();
    for(var i = 0; i < process_Obj_Module_Arr.length; i++) {
        if(addr>process_Obj_Module_Arr[i].base && addr<process_Obj_Module_Arr[i].base.add(process_Obj_Module_Arr[i].size)){
            console.log(addr.toString(16),"is in",process_Obj_Module_Arr[i].name,"offset: 0x"+(addr-process_Obj_Module_Arr[i].base).toString(16));
        }
    }
}
 
//console.log('RegisterNatives called from:\\n' + Thread.backtrace(this.context, Backtracer.FUZZY).map(DebugSymbol.fromAddress).join('\\n') + '\\n');
function hook_addr(){
    var module = Process.findModuleByName("libjiagu_64.so");
    Interceptor.attach(module.base.add(0x5E6C), {
        // fd, buff, len
        onEnter: function (args) {
            console.log(hexdump(args[0], {
              offset: 0,// 相对偏移
              length: 0x38*0x6+0x20,//dump 的大小
              header: true,
              ansi: true
            }));
            console.log(args[1])
            console.log(args[2])
            console.log(`base = ${module.base}`)
        },
        onLeave: function (ret) {
        }
    });
}
 
 
function hook() {
    console.log("hook fun dump so body");
    // 获取libjiagu_64.so模块的基地址
    var libjiagu = Process.getModuleByName("libjiagu_64.so");
    if (!libjiagu) {
        console.error("未能找到libjiagu_64.so模块");
        return;
    }
 
    var soinfo;
 
    var module = Process.findModuleByName("libjiagu_64.so");
    Interceptor.attach(module.base.add(0xB6D8), {
        // fd, buff, len
 
        onEnter: function (args) {
            console.log("hook B6D8 method ! ");
            soinfo = args[0];
            console.log("soinfo:",soinfo);
 
 
            var base = ptr(soinfo.add(0x190)).readPointer();
            var ph = ptr(soinfo.add(0xE8)).readPointer();
            var phnum = ptr(soinfo.add(0xF8)).readLong();
            var rela = ptr(soinfo.add(0x130)).readPointer();
            //var relasz = 0x1823;
            var plt_rela = ptr(soinfo.add(0x120)).readPointer();
            //var plt_relasz =0x101;
            var size = (base).add(0x28).readLong();
 
 
            var dymagic =  ptr(soinfo.add(0x100)).readPointer();
            var dy_size =0x290;
 
            console.log("base:",base);
 
            console.log("so size:",size);
            console.log("ph:",ph);
            console.log("phnum:",phnum);
            console.log("rela:",rela);
            console.log("plt_rela:",plt_rela);
            console.log(hexdump((ptr(dymagic)), {
                offset: 0,// 相对偏移
                length: dy_size,//dump 的大小
                header: true,
                ansi: true
              }));
 
 
            console.log("elf in ori offset: ",ptr(Number(base) -Number(module.base)))
 
 
 
            dump_so_body(base,size,"so.so_0x12b000");
            dump_so_body(ph,phnum*0x38,"ph.so");
            dump_so_body(rela,0x25080,"rela_0x25080.so");  // 0x8
            dump_so_body(plt_rela,0x1818,"plt_rela_0x1818.so");  // 0x2
            dump_so_body(dymagic,dy_size,"dymagic.so");
            
 
            // dump_so_body(ptr(base).readPointer(),size,"so.so");
            // dump_so_body(ptr(ph).readPointer(),ptr(phnum).readLong()*0x20,"ph.so");
            // dump_so_body
            
        },
        onLeave: function (ret) {
            var relasz = ptr(soinfo.add(0x138)).readPointer();
            console.log("relasz:",relasz);
 
            var plt_relasz = ptr(soinfo.add(0x128)).readPointer();
            console.log("plt_relasz:",plt_relasz);
        }
    });
 
 
    
 
    
}
 
 
setImmediate(my_hook_dlopen,"libjiagu");
 
function dump_so_body(addr, size, body_name) {
   
    var file_path = "/data/data/"+get_self_process_name()+"/" +body_name + "_" + addr + "_" + size + ".body";
    var file_handle = new File(file_path, "wb");
    if (file_handle && file_handle != null) {
        Memory.protect(addr,size, 'rwx');
        var libso_buffer = ptr(addr).readByteArray(size);
        file_handle.write(libso_buffer);
        file_handle.flush();
        file_handle.close();
        console.log("[dump]:", file_path);
    }
}
 
function get_self_process_name() {
    var openPtr = Module.getExportByName('libc.so', 'open');
    var open = new NativeFunction(openPtr, 'int', ['pointer', 'int']);
 
    var readPtr = Module.getExportByName("libc.so", "read");
    var read = new NativeFunction(readPtr, "int", ["int", "pointer", "int"]);
 
    var closePtr = Module.getExportByName('libc.so', 'close');
    var close = new NativeFunction(closePtr, 'int', ['int']);
 
    var path = Memory.allocUtf8String("/proc/self/cmdline");
    var fd = open(path, 0);
    if (fd != -1) {
        var buffer = Memory.alloc(0x1000);
 
        var result = read(fd, buffer, 0x1000);
        close(fd);
        result = ptr(buffer).readCString();
        return result;
    }
 
    return "-1";
}
function my_hook_dlopen(soName = '') {
 
    Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"),
        {
            onEnter: function (args) {
                var pathptr = args[0];
                if (pathptr !== undefined && pathptr != null) {
                    var path = ptr(pathptr).readCString();
                    if (path.indexOf(soName) >= 0) {
                        this.is_can_hook = true;
                    }
                }
            },
            onLeave: function (retval) {
                if (this.is_can_hook) {
                    hook();
                }
            }
        }
    );
}
function addr_in_so(addr){
    var process_Obj_Module_Arr = Process.enumerateModules();
    for(var i = 0; i < process_Obj_Module_Arr.length; i++) {
        if(addr>process_Obj_Module_Arr[i].base && addr<process_Obj_Module_Arr[i].base.add(process_Obj_Module_Arr[i].size)){
            console.log(addr.toString(16),"is in",process_Obj_Module_Arr[i].name,"offset: 0x"+(addr-process_Obj_Module_Arr[i].base).toString(16));
        }
    }
}
 
//console.log('RegisterNatives called from:\\n' + Thread.backtrace(this.context, Backtracer.FUZZY).map(DebugSymbol.fromAddress).join('\\n') + '\\n');
function hook_addr(){
    var module = Process.findModuleByName("libjiagu_64.so");
    Interceptor.attach(module.base.add(0x5E6C), {
        // fd, buff, len
        onEnter: function (args) {
            console.log(hexdump(args[0], {
              offset: 0,// 相对偏移
              length: 0x38*0x6+0x20,//dump 的大小
              header: true,
              ansi: true
            }));
            console.log(args[1])
            console.log(args[2])
            console.log(`base = ${module.base}`)
        },
        onLeave: function (ret) {
        }
    });

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 1天前 被逆天而行编辑 ,原因:
上传的附件:
收藏
免费 61
支持
分享
最新回复 (43)
雪    币: 3245
活跃值: (4058)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
2

提供的为 样本 一个原版 一个去签名了的

样本支持 安卓9 到14 

最后于 1天前 被逆天而行编辑 ,原因:
1天前
0
雪    币: 2320
活跃值: (2779)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
学习学习
1天前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
360加固去签我会
1天前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
测试还是不行,会闪退
1天前
0
雪    币: 39
活跃值: (395)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
看看学习
1天前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
感谢分享
1天前
0
雪    币: 4
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
感谢分享
1天前
0
雪    币: 439
活跃值: (1943)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
9
感谢分享
1天前
0
雪    币: 526
活跃值: (575)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
感谢分享,学习了
1天前
0
雪    币: 13
活跃值: (280)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
感谢分享
1天前
0
雪    币: 688
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
6
1天前
0
雪    币: 375
活跃值: (2736)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
13
666
1天前
0
雪    币: 480
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
图片没了 可以补一下吗佬
1天前
0
雪    币: 3245
活跃值: (4058)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
15
软件君子 图片没了 可以补一下吗佬

1天前
0
雪    币: 3245
活跃值: (4058)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
16
mb_kgsesxqm 测试还是不行,会闪退
可能不太兼容 高版本手机吧
1天前
0
雪    币: 480
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
17
过签名思路和我一样 我用的是基于 bpf + sigation 的方式 但是在替换包路径的时候总是闪退
1天前
0
雪    币: 3245
活跃值: (4058)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
18
软件君子 过签名思路和我一样 我用的是基于 bpf + sigation 的方式 但是在替换包路径的时候总是闪退
这种方式 hook  稳定性比较差,还有存在有些过不了的情况,例如在java 里面通过 fd 读取zip ,你替换了 也会有失败的情况
1天前
0
雪    币: 480
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
io重定向 /data/app/~~CBhL9khBHYFlgO9LJEDUOA==/com.lerist.fakelocation-XchxK8PlNrmJH2XU1PMmjQ==/base.apk
然后当 readlink的时候传入真正的fd

但是只要替换这个路径就会闪退 不是其他调用没过掉
1天前
0
雪    币: 3245
活跃值: (4058)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
20
fakelocation  这个app 有自己的校验
1天前
0
雪    币: 27
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21
1
1天前
0
雪    币: 1545
活跃值: (2708)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
22
6666
1天前
0
雪    币: 155
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
23

我测试了3个手机android14-15 鸿蒙 全部闪退

最后于 1天前 被深山老琳编辑 ,原因:
1天前
0
雪    币: 3245
活跃值: (4058)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
24
深山老琳 我测试了3个手机android14-15 鸿蒙 全部闪退
我魔改的lspatch 老板本 是不支持 的  
1天前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
25
楼主自己有测试过吗,是啥系统正常运行的,我这边都闪退
1天前
0
游客
登录 | 注册 方可回帖
返回