首页
社区
课程
招聘
[原创]虚拟相机vcamera v18破解
发表于: 2025-10-14 10:54 1796

[原创]虚拟相机vcamera v18破解

2025-10-14 10:54
1796

之前破解过作者一个版本的虚拟相机在b站发过视频

视频链接:
我破解的之前的版本也有人破解过
链接地址:108K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2U0L8X3u0D9L8$3N6K6i4K6u0W2j5$3!0E0i4K6u0r3M7X3g2$3k6i4u0U0j5#2)9J5c8Y4m8Q4x3V1j5I4y4K6V1J5x3U0j5K6y4#2)9J5k6h3S2@1L8h3H3`.
最近有客户找我破解同一个作者的另外一个版本的虚拟相机,索性研究一下
先查壳,邦邦免费加固,比较简单,只是对frida的简单检测,上面的链接已经对邦邦免费版的加固和检测做了非常详细的分析,用到了ebpf等各种工具
用frida先hook一下,有崩溃的迹象,可能是脚步注入太早,或者hook现成的时候地址无法访问,通过纠正脚本的到frida的hook代码

setTimeout(() => {
    if (!Java.available) {
        console.log("[系统] Java环境未就绪,跳过Hook执行");
        return;
    }

    // 调用栈打印函数 - 确保能正常执行
    function showSafeStacks() {
        try {
            const stackTrace = Java.use("java.lang.Thread").currentThread().getStackTrace();
            if (stackTrace && stackTrace.length > 0) {
                console.log("调用栈:");
                const maxDepth = Math.min(stackTrace.length, 50);
                for (let i = 0; i < maxDepth; i++) {
                    const elem = stackTrace[i];
                    console.log(`  ${elem.getClassName()}.${elem.getMethodName()}:${elem.getLineNumber()}`);
                }
            }
        } catch (e) {
            console.log("调用栈打印失败: " + e.message);
        }
    }

    Java.perform(() => {
        console.log("[系统] 开始执行Hook逻辑...");

        // Hook f1.g.a 方法


        // Hook d1.g.b 方法(修复NumberFormatException问题)
        try {
            const D1GHookClass = Java.use("d1.g");
            console.log("[d1.g] 成功获取类引用");

            const d1TargetMethod = D1GHookClass["b"].overloads.find(m => m.argumentTypes.length === 1);
            if (d1TargetMethod) {
                d1TargetMethod.implementation = function(str) {
                    console.log("[d1.g.b] 被调用");

                    try {
                        console.log(`[参数] 值: ${str || 'null'}`);
                    } catch (e) {
                        console.log("[参数] 获取失败: " + e.message);
                    }

                    showSafeStacks();

                    try {
                        // 使用int范围内的数值,避免NumberFormatException
                        // 数组长度保持与原始方法一致(此处为2个元素)
                        const newResult = Java.array('java.lang.String', [
                            "2147483647",  // int类型最大值,确保可被Integer.parseInt解析
                            Math.floor(Date.now() / 1000).toString()  // 10位时间戳
                            // 如需3个元素,取消下面一行的注释
                            // "激活成功"
                        ]);

                        // 打印修改后的返回值
                        console.log(`[返回值] 修改后的数组(长度:${newResult.length})内容:`);
                        for (let i = 0; i < newResult.length; i++) {
                            console.log(`  第${i+1}个元素: ${newResult[i]}`);
                        }

                        return newResult;
                    } catch (e) {
                        console.log("[d1.g.b] 调用失败: " + e.message);
                        throw e;
                    }
                };
                console.log("[d1.g] b方法Hook安装完成");
            } else {
                console.log("[d1.g] 未找到符合条件的b方法");
            }
        } catch (e) {
            console.log("[d1.g] 处理出错: " + e.message);
        }

        // Hook java.lang.Integer 类方法


        // Hook java.lang.Long 类方法(处理大整数)


        console.log("[系统] 所有Hook安装完成");
    });
}, 8000);

总的来说,注入的时间延迟了一下,就解决了注入崩溃的问题
hook他激活的过程拿到了激活返回的数据,他需要请求服务器验证拿到激活的时间戳

然后通过计算时间的差值,来给用户使用时间。
这个虚拟相机还请求了root权限,不然没有版本跨进程通讯,
总的来说这个相机有启动了三个进程
一是相机app的主进程,主进程是java层和c++层的跨进程通讯
二是主进程通过java层在命令行运行二进制可执行文件vcmplay 传入参数来启动第二个进程,这个进程主要负责相机vcmpaly主进程和注入系统相机相机服务的libvc.so进程跨进程通讯,通讯的主要方式是ibinder,
三是注入系统服务的相机cameraserver的so文件。
如果应用root权限获取不到,或者网络问题,会出现进程启动失败的问题

这个相机需要激活码才能激活使用,通过分析java层,把他的界面全部hook了出来
激活需要请求服务器拿到验证信息

拿到的数据全是加密的
通过分析vcmplay二进制可执行文件可得到 请求的数据是rsa加密,秘钥通过stackplz的ebpf工具定位到了加密秘钥是128位的
还要说一句
这个应用很狡猾他把vcmplay加了一个so后缀,让人以为是so文件,需要加载到java的内存其实他是另外一个进程。
我hook相机服务cameraserver内的libvc.so发现frida一 attach相机服务就崩溃,不知道是不是检测,分析了很长时间,偶然发现vcmplay一次死掉的时机,竟然能hook了 怀疑可能是vcmplay的进程对cameraserve进程进行了检测
我用ida对vcmpay进程进行调试,发现他还有反调试,扫了一下proc/self/status内的tracepid来确定有没有被调试,而且更恐怖的是他发现反调试不是程序崩溃,他竟然通过root权限删除了安卓系统内的重要文件,然后手机重启进入双清状态,必须初始化系统才能进系统,手机内的所有东西都没了。我通过kernelpatch编写内核hook模块kpm过掉了反调试

大体的逻辑都弄清楚了,估计破解也是不容易的。
以后待续吧......


[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

收藏
免费 2
支持
分享
最新回复 (3)
雪    币: 3432
活跃值: (9180)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
.KK
2
拿权限删东西有点骚啊
2025-10-14 12:57
0
雪    币: 426
活跃值: (1380)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
6666
2025-11-15 13:43
0
雪    币: 182
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
删文件过分了
2025-12-4 13:28
0
游客
登录 | 注册 方可回帖
返回